From 7eb726d57fafcfdc6bb3d773c313c98841e2cf65 Mon Sep 17 00:00:00 2001 From: Ville Juven Date: Mon, 24 Jan 2022 10:00:48 +0200 Subject: [PATCH] Add proper user/kernel space linker scripts for knsh target The old implementation used the default ld.script for the kernel side which did not obey the memory.ld limits whatsoever. Also, provide the user space addresses from the linker script to get rid of the pre-processor macros that define (incorrect) default values for the user space composition. --- arch/risc-v/src/mpfs/mpfs_userspace.c | 66 +++++----- .../mpfs/common/kernel/mpfs_userspace.c | 4 - .../risc-v/mpfs/icicle/configs/knsh/defconfig | 13 +- boards/risc-v/mpfs/icicle/scripts/Make.defs | 16 ++- .../mpfs/icicle/scripts/kernel-space.ld | 113 ++++++++++++++++++ boards/risc-v/mpfs/icicle/scripts/memory.ld | 11 +- .../risc-v/mpfs/icicle/scripts/user-space.ld | 2 +- 7 files changed, 172 insertions(+), 53 deletions(-) create mode 100755 boards/risc-v/mpfs/icicle/scripts/kernel-space.ld diff --git a/arch/risc-v/src/mpfs/mpfs_userspace.c b/arch/risc-v/src/mpfs/mpfs_userspace.c index eb3c5cd16d..138fcc5017 100755 --- a/arch/risc-v/src/mpfs/mpfs_userspace.c +++ b/arch/risc-v/src/mpfs/mpfs_userspace.c @@ -38,26 +38,19 @@ * Pre-processor Definitions ****************************************************************************/ -/* Configuration ************************************************************/ - -/* TODO: get user space mem layout info from ld script or Configuration ? */ - -#ifndef CONFIG_NUTTX_USERSPACE_SIZE -# define CONFIG_NUTTX_USERSPACE_SIZE (0x00100000) -#endif - -#ifndef CONFIG_NUTTX_USERSPACE_RAM_START -# define CONFIG_NUTTX_USERSPACE_RAM_START (0x00100000) -#endif - -#ifndef CONFIG_NUTTX_USERSPACE_RAM_SIZE -# define CONFIG_NUTTX_USERSPACE_RAM_SIZE (0x00100000) -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern uintptr_t __uflash_start; +extern uintptr_t __uflash_size; +extern uintptr_t __usram_start; +extern uintptr_t __usram_size; + /**************************************************************************** * Name: mpfs_userspace * @@ -104,24 +97,35 @@ void mpfs_userspace(void) } /* Configure the PMP to permit user-space access to its ROM and RAM. - * Now this is done by simply adding the whole memory area to PMP. - * 1. no access for the 1st 4KB - * 2. "RX" for the left space until 1MB - * 3. "RW" for the user RAM area - * TODO: more accurate memory size control. + * + * Note: PMP by default revokes access, thus if different privilege modes + * are in use (mstatus.mprv is set), the the user space _must_ be granted + * access here, otherwise an exception will fire when the user space task + * is started. + * + * Note: according to the Polarfire reference manual, address bits [1:0] + * are not considered (due to 4 octet alignment), so strictly they don't + * have to be cleared here. + * + * Note: do not trust the stext / etc sections to be correctly aligned + * here, they should be but it is simpler and safer to handle the user + * region as a whole + * + * Access is currently granted by simply adding each userspace memory area + * to PMP, without further granularity. + * + * "RX" for the user progmem + * "RW" for the user RAM area + * */ - riscv_config_pmp_region(0, PMPCFG_A_NAPOT, - 0, - 0x1000); + riscv_config_pmp_region(0, PMPCFG_A_NAPOT | PMPCFG_X | PMPCFG_R, + (uintptr_t)&__uflash_start, + (uintptr_t)&__uflash_size); - riscv_config_pmp_region(1, PMPCFG_A_TOR | PMPCFG_X | PMPCFG_R, - 0 + CONFIG_NUTTX_USERSPACE_SIZE, - 0); - - riscv_config_pmp_region(2, PMPCFG_A_NAPOT | PMPCFG_W | PMPCFG_R, - CONFIG_NUTTX_USERSPACE_RAM_START, - CONFIG_NUTTX_USERSPACE_RAM_SIZE); + riscv_config_pmp_region(1, PMPCFG_A_NAPOT | PMPCFG_W | PMPCFG_R, + (uintptr_t)&__usram_start, + (uintptr_t)&__usram_size); } #endif /* CONFIG_BUILD_PROTECTED */ diff --git a/boards/risc-v/mpfs/common/kernel/mpfs_userspace.c b/boards/risc-v/mpfs/common/kernel/mpfs_userspace.c index 8860ed53ae..0186bbde92 100755 --- a/boards/risc-v/mpfs/common/kernel/mpfs_userspace.c +++ b/boards/risc-v/mpfs/common/kernel/mpfs_userspace.c @@ -43,10 +43,6 @@ # error "CONFIG_NUTTX_USERSPACE not defined" #endif -#if CONFIG_NUTTX_USERSPACE != 0x00001000 -# error "CONFIG_NUTTX_USERSPACE must match the value in memory.ld" -#endif - /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/boards/risc-v/mpfs/icicle/configs/knsh/defconfig b/boards/risc-v/mpfs/icicle/configs/knsh/defconfig index deaffc98b8..cc39b5a96d 100644 --- a/boards/risc-v/mpfs/icicle/configs/knsh/defconfig +++ b/boards/risc-v/mpfs/icicle/configs/knsh/defconfig @@ -11,16 +11,14 @@ CONFIG_ARCH="risc-v" CONFIG_ARCH_BOARD="icicle" CONFIG_ARCH_BOARD_ICICLE_MPFS=y CONFIG_ARCH_CHIP="mpfs" +CONFIG_ARCH_CHIP_MPFS250T_FCVG484=y CONFIG_ARCH_CHIP_MPFS=y CONFIG_ARCH_INTERRUPTSTACK=2048 CONFIG_ARCH_RISCV=y CONFIG_ARCH_STACKDUMP=y CONFIG_ARCH_USE_MPU=y -CONFIG_BUILD_PROTECTED=y -CONFIG_SYS_RESERVED=9 -CONFIG_PASS1_BUILDIR="boards/risc-v/mpfs/common/kernel" -CONFIG_NUTTX_USERSPACE=0x80040000 CONFIG_BOARD_LOOPSPERMSEC=54000 +CONFIG_BUILD_PROTECTED=y CONFIG_BUILTIN=y CONFIG_DEBUG_ASSERTIONS=y CONFIG_DEBUG_ERROR=y @@ -54,9 +52,11 @@ CONFIG_NSH_DISABLE_RMDIR=y CONFIG_NSH_DISABLE_UMOUNT=y CONFIG_NSH_LINELEN=160 CONFIG_NSH_STRERROR=y +CONFIG_NUTTX_USERSPACE=0x80040000 +CONFIG_PASS1_BUILDIR="boards/risc-v/mpfs/common/kernel" CONFIG_PREALLOC_TIMERS=4 -CONFIG_RAM_SIZE=1048576 -CONFIG_RAM_START=0x80200000 +CONFIG_RAM_SIZE=262144 +CONFIG_RAM_START=0x80080000 CONFIG_RAW_BINARY=y CONFIG_READLINE_CMD_HISTORY=y CONFIG_READLINE_TABCOMPLETION=y @@ -73,6 +73,7 @@ CONFIG_SYSTEM_CLE_CMD_HISTORY=y CONFIG_SYSTEM_COLOR_CLE=y CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_TIME64=y +CONFIG_SYS_RESERVED=9 CONFIG_TASK_NAME_SIZE=20 CONFIG_TESTING_GETPRIME=y CONFIG_TESTING_OSTEST=y diff --git a/boards/risc-v/mpfs/icicle/scripts/Make.defs b/boards/risc-v/mpfs/icicle/scripts/Make.defs index 26f1cc3c0b..48261fb733 100755 --- a/boards/risc-v/mpfs/icicle/scripts/Make.defs +++ b/boards/risc-v/mpfs/icicle/scripts/Make.defs @@ -23,20 +23,32 @@ include $(TOPDIR)/tools/Config.mk include $(TOPDIR)/tools/mpfs/Config.mk include $(TOPDIR)/arch/risc-v/src/common/Toolchain.defs +LDMEMORY = +ARCHSCRIPT = + ifeq ($(CONFIG_MPFS_BOOTLOADER),y) ifeq ($(CONFIG_MPFS_OPENSBI),y) LDSCRIPT = ld-envm-opensbi.script else LDSCRIPT = ld-envm.script endif +else ifeq ($(CONFIG_BUILD_PROTECTED),y) + LDMEMORY = memory.ld + LDSCRIPT = kernel-space.ld else LDSCRIPT = ld.script endif ifeq ($(CONFIG_CYGWIN_WINTOOL),y) - ARCHSCRIPT = -T "${shell cygpath -w $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)}" + ifneq ($(LDMEMORY),) + ARCHSCRIPT += -T "${shell cygpath -w $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDMEMORY)}" + endif + ARCHSCRIPT += -T "${shell cygpath -w $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)}" else - ARCHSCRIPT = -T$(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT) + ifneq ($(LDMEMORY),) + ARCHSCRIPT += -T$(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDMEMORY) + endif + ARCHSCRIPT += -T$(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT) endif ifeq ($(CONFIG_DEBUG_SYMBOLS),y) diff --git a/boards/risc-v/mpfs/icicle/scripts/kernel-space.ld b/boards/risc-v/mpfs/icicle/scripts/kernel-space.ld new file mode 100755 index 0000000000..f4da5051df --- /dev/null +++ b/boards/risc-v/mpfs/icicle/scripts/kernel-space.ld @@ -0,0 +1,113 @@ +/**************************************************************************** + * boards/risc-v/mpfs/icicle/scripts/ld.script + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/* NOTE: This depends on the memory.ld script having been included prior to + * this script. + */ + +OUTPUT_ARCH("riscv") + +/* Provide these so there is no need for using config files for this */ + +__uflash_start = ORIGIN(uflash); +__uflash_size = LENGTH(uflash); +__usram_start = ORIGIN(usram); +__usram_size = LENGTH(usram); + +/* Provide the kernel boundaries as well */ + +__kflash_start = ORIGIN(kflash); +__kflash_size = LENGTH(kflash); +__ksram_start = ORIGIN(ksram); +__ksram_size = LENGTH(ksram); + +ENTRY(_stext) +EXTERN(_vectors) +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.* .srodata .srodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > kflash + + .init_section : ALIGN(4) { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > kflash + + _eronly = ABSOLUTE(.); + + .data : ALIGN(4) { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.d.*) + *(.gnu.linkonce.s.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > ksram AT > kflash + + PROVIDE(__global_pointer$ = _sdata + ((_edata - _sdata) / 2)); + + .bss : ALIGN(4) { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.sbss .sbss.*) + *(.gnu.linkonce.b.*) + *(.gnu.linkonce.sb.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > ksram + + /* Stack top */ + .stack_top : { + . = ALIGN(32); + _default_stack_limit = ABSOLUTE(.); + } > ksram + + /* Stabs debugging sections. */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/risc-v/mpfs/icicle/scripts/memory.ld b/boards/risc-v/mpfs/icicle/scripts/memory.ld index 3b38cc4bbc..890ba735ba 100755 --- a/boards/risc-v/mpfs/icicle/scripts/memory.ld +++ b/boards/risc-v/mpfs/icicle/scripts/memory.ld @@ -18,18 +18,11 @@ * ****************************************************************************/ -/* Reg Access Start addr End addr Size - * QEMU CPU w/ cache 0x00000000 - 0x003fffff : 4MB - * QEMU CPU w/o cache 0x1f000000 - 0x1f01ffff : 128KB - */ - MEMORY { kflash (rx) : ORIGIN = 0x80000000, LENGTH = 256K /* w/ cache */ uflash (rx) : ORIGIN = 0x80040000, LENGTH = 256K /* w/ cache */ - xflash (rx) : ORIGIN = 0x80080000, LENGTH = 256K /* w/o cache */ - ksram (rwx) : ORIGIN = 0x800C0000, LENGTH = 256K /* w/ cache */ - usram (rwx) : ORIGIN = 0x80100000, LENGTH = 256K /* w/ cache */ - xsram (rwx) : ORIGIN = 0x80140000, LENGTH = 256K /* w/o cache */ + ksram (rwx) : ORIGIN = 0x80080000, LENGTH = 256K /* w/ cache */ + usram (rwx) : ORIGIN = 0x800C0000, LENGTH = 256K /* w/ cache */ } diff --git a/boards/risc-v/mpfs/icicle/scripts/user-space.ld b/boards/risc-v/mpfs/icicle/scripts/user-space.ld index 0e1204971c..1b3aa8bfe2 100755 --- a/boards/risc-v/mpfs/icicle/scripts/user-space.ld +++ b/boards/risc-v/mpfs/icicle/scripts/user-space.ld @@ -45,7 +45,7 @@ SECTIONS *(.text .text.*) *(.fixup) *(.gnu.warning) - *(.rodata .rodata.*) + *(.rodata .rodata.* .srodata .srodata.*) *(.gnu.linkonce.t.*) *(.glue_7) *(.glue_7t)