From a33313413d6b7ab097dbea47d410e65fe6d1ed05 Mon Sep 17 00:00:00 2001 From: Inochi Amaoto Date: Sun, 14 Apr 2024 18:40:44 +0800 Subject: [PATCH] arch/risc-v: introduce dynamic stack allocation. It is misleading to allocate stack from static array and heap, make all stack allocated from heap area. Signed-off-by: Inochi Amaoto --- arch/risc-v/src/bl602/bl602_head.S | 4 +- arch/risc-v/src/bl602/bl602_start.c | 10 +++-- arch/risc-v/src/bl808/bl808_head.S | 34 ++------------- arch/risc-v/src/bl808/bl808_memorymap.h | 3 -- arch/risc-v/src/bl808/bl808_start.c | 19 +++++---- arch/risc-v/src/c906/c906_memorymap.h | 2 +- arch/risc-v/src/c906/c906_start.c | 4 ++ .../src/common/espressif/esp_memorymap.h | 4 +- arch/risc-v/src/common/espressif/esp_start.c | 6 ++- .../src/common/riscv_common_memorymap.h | 3 +- arch/risc-v/src/common/riscv_cpuidlestack.c | 12 ++---- arch/risc-v/src/common/riscv_initialstate.c | 5 +-- arch/risc-v/src/common/riscv_internal.h | 12 ++++++ arch/risc-v/src/common/riscv_macros.S | 42 +++++++++++++++++++ .../src/esp32c3-legacy/esp32c3_memorymap.h | 4 +- .../risc-v/src/esp32c3-legacy/esp32c3_start.c | 6 ++- arch/risc-v/src/fe310/fe310_memorymap.h | 2 +- arch/risc-v/src/fe310/fe310_start.c | 4 ++ arch/risc-v/src/hpm6000/hpm_memorymap.h | 2 +- arch/risc-v/src/hpm6000/hpm_start.c | 4 ++ arch/risc-v/src/hpm6750/hpm6750_memorymap.h | 2 +- arch/risc-v/src/hpm6750/hpm6750_start.c | 4 ++ arch/risc-v/src/jh7110/jh7110_head.S | 34 ++------------- arch/risc-v/src/jh7110/jh7110_memorymap.h | 3 -- arch/risc-v/src/jh7110/jh7110_start.c | 9 +++- arch/risc-v/src/k210/k210_head.S | 34 ++------------- arch/risc-v/src/k210/k210_memorymap.h | 1 - arch/risc-v/src/k210/k210_start.c | 7 +++- arch/risc-v/src/k230/k230_head.S | 34 ++------------- arch/risc-v/src/k230/k230_memorymap.h | 3 -- arch/risc-v/src/k230/k230_start.c | 7 +++- arch/risc-v/src/litex/litex_memorymap.h | 3 +- arch/risc-v/src/litex/litex_start.c | 4 ++ arch/risc-v/src/mpfs/mpfs_memorymap.h | 2 +- arch/risc-v/src/mpfs/mpfs_start.c | 4 ++ arch/risc-v/src/qemu-rv/qemu_rv_head.S | 41 ++---------------- arch/risc-v/src/qemu-rv/qemu_rv_memorymap.h | 3 -- arch/risc-v/src/qemu-rv/qemu_rv_start.c | 7 +++- arch/risc-v/src/rv32m1/rv32m1_memorymap.h | 4 +- arch/risc-v/src/rv32m1/rv32m1_start.c | 4 ++ boards/risc-v/bl808/ox64/scripts/ld.script | 1 + boards/risc-v/jh7110/star64/scripts/ld.script | 1 + boards/risc-v/k210/maix-bit/scripts/ld.script | 2 +- .../k210/maix-bit/scripts/user-space.ld | 2 +- .../k230/canmv230/scripts/ld-flat.script | 1 + .../risc-v/qemu-rv/rv-virt/scripts/ld.script | 1 + 46 files changed, 181 insertions(+), 219 deletions(-) diff --git a/arch/risc-v/src/bl602/bl602_head.S b/arch/risc-v/src/bl602/bl602_head.S index 9ca2fffb30..e7ddd79d5c 100644 --- a/arch/risc-v/src/bl602/bl602_head.S +++ b/arch/risc-v/src/bl602/bl602_head.S @@ -25,6 +25,8 @@ #include #include +#include "riscv_internal.h" + .section .init .globl bl602_start .globl __start @@ -47,7 +49,7 @@ bl602_start: la sp, g_idle_stack add s11, sp, zero - li t0, CONFIG_IDLETHREAD_STACKSIZE + li t0, SMP_STACK_SIZE add sp, sp, t0 andi sp, sp, ~0xF diff --git a/arch/risc-v/src/bl602/bl602_start.c b/arch/risc-v/src/bl602/bl602_start.c index e50f77bd86..17029162ca 100644 --- a/arch/risc-v/src/bl602/bl602_start.c +++ b/arch/risc-v/src/bl602/bl602_start.c @@ -52,8 +52,6 @@ #define showprogress(c) #endif -#define BL602_IDLESTACK_SIZE (CONFIG_IDLETHREAD_STACKSIZE) - /**************************************************************************** * Private Data ****************************************************************************/ @@ -68,7 +66,7 @@ * address. */ -uint8_t g_idle_stack[BL602_IDLESTACK_SIZE] +uint8_t g_idle_stack[SMP_STACK_SIZE] locate_data(".noinit_idle_stack"); /* Dont change the name of variable, since we refer this @@ -167,7 +165,11 @@ void bfl_main(void) /* Configure IDLE stack */ - g_idle_topstack = ((uint32_t)g_idle_stack + BL602_IDLESTACK_SIZE); + g_idle_topstack = ((uint32_t)g_idle_stack + SMP_STACK_SIZE); + + /* Setup base stack */ + + riscv_set_basestack((uintptr_t)g_idle_stack, SMP_STACK_SIZE); /* Configure the UART so we can get debug output */ diff --git a/arch/risc-v/src/bl808/bl808_head.S b/arch/risc-v/src/bl808/bl808_head.S index 6fdbf3b422..090fd91252 100644 --- a/arch/risc-v/src/bl808/bl808_head.S +++ b/arch/risc-v/src/bl808/bl808_head.S @@ -29,6 +29,7 @@ #include "chip.h" #include "riscv_internal.h" +#include "riscv_macros.S" /**************************************************************************** * Public Symbols @@ -68,13 +69,6 @@ __start: real_start: - /* Set stack pointer to the idle thread stack */ - - bnez a0, 1f - la sp, BL808_IDLESTACK_TOP - j 2f -1: - /* Load the number of CPUs that the kernel supports */ #ifdef CONFIG_SMP @@ -90,30 +84,8 @@ real_start: wfi 3: - /* Get start address of idle stack array */ - - la t0, g_cpux_idlestack - - /* Get idle stack offset */ - - li t1, SMP_STACK_SIZE - mul t1, t1, a0 - - /* Load idle stack top to sp */ - - add sp, t0, t1 - - /* - * sp (stack top) = sp (stack top) - XCPTCONTEXT_SIZE - * - * Note: Reserve some space used by up_initial_state since we are already - * running and using the per CPU idle stack. - */ - - li t0, -STACK_ALIGN_UP(XCPTCONTEXT_SIZE) - add sp, sp, t0 - -2: + /* Set stack pointer to the idle thread stack */ + riscv_set_inital_sp BL808_IDLESTACK_BASE, SMP_STACK_SIZE, a0 /* Disable all interrupts (i.e. timer, external) in sie */ diff --git a/arch/risc-v/src/bl808/bl808_memorymap.h b/arch/risc-v/src/bl808/bl808_memorymap.h index 7dff2e7795..d820cc412c 100644 --- a/arch/risc-v/src/bl808/bl808_memorymap.h +++ b/arch/risc-v/src/bl808/bl808_memorymap.h @@ -39,7 +39,4 @@ #define BL808_IDLESTACK_BASE _ebss #endif -#define BL808_IDLESTACK_SIZE (CONFIG_IDLETHREAD_STACKSIZE & ~3) -#define BL808_IDLESTACK_TOP (BL808_IDLESTACK_BASE + BL808_IDLESTACK_SIZE) - #endif /* __ARCH_RISCV_SRC_BL808_BL808_MEMORYMAP_H */ diff --git a/arch/risc-v/src/bl808/bl808_start.c b/arch/risc-v/src/bl808/bl808_start.c index 53ad612673..b96cf2d7f8 100644 --- a/arch/risc-v/src/bl808/bl808_start.c +++ b/arch/risc-v/src/bl808/bl808_start.c @@ -59,10 +59,11 @@ extern void __trap_vec(void); ****************************************************************************/ /* NOTE: g_idle_topstack needs to point the top of the idle stack - * for CPU0 and this value is used in up_initial_state() + * for last CPU and this value is used in up_initial_state() */ -uintptr_t g_idle_topstack = BL808_IDLESTACK_TOP; +uintptr_t g_idle_topstack = BL808_IDLESTACK_BASE + + SMP_STACK_SIZE * CONFIG_SMP_NCPUS; /**************************************************************************** * Private Functions @@ -113,7 +114,7 @@ static void bl808_copy_overlap(uint8_t *dest, const uint8_t *src, static void bl808_copy_ramdisk(void) { const char *header = "-rom1fs-"; - const uint8_t *limit = (uint8_t *)BL808_IDLESTACK_TOP + (256 * 1024); + const uint8_t *limit = (uint8_t *)g_idle_topstack + (256 * 1024); uint8_t *ramdisk_addr = NULL; uint8_t *addr; uint32_t size; @@ -122,9 +123,9 @@ static void bl808_copy_ramdisk(void) * Limit search to 256 KB after Idle Stack Top. */ - binfo("_edata=%p, _sbss=%p, _ebss=%p, BL808_IDLESTACK_TOP=%p\n", + binfo("_edata=%p, _sbss=%p, _ebss=%p, idlestack_top=%p\n", (void *)_edata, (void *)_sbss, (void *)_ebss, - (void *)BL808_IDLESTACK_TOP); + (void *)g_idle_topstack); for (addr = _edata; addr < limit; addr++) { if (memcmp(addr, header, strlen(header)) == 0) @@ -145,9 +146,9 @@ static void bl808_copy_ramdisk(void) /* RAM Disk must be after Idle Stack, to prevent overwriting */ - if (ramdisk_addr <= (uint8_t *)BL808_IDLESTACK_TOP) + if (ramdisk_addr <= (uint8_t *)g_idle_topstack) { - const size_t pad = (size_t)BL808_IDLESTACK_TOP - (size_t)ramdisk_addr; + const size_t pad = (size_t)g_idle_topstack - (size_t)ramdisk_addr; _err("RAM Disk must be after Idle Stack. Increase initrd padding " "by %ul bytes.", pad); PANIC(); @@ -273,6 +274,10 @@ void bl808_start(int mhartid) bl808_clear_bss(); + /* Setup base stack */ + + riscv_set_basestack(BL808_IDLESTACK_BASE, SMP_STACK_SIZE); + /* Copy the RAM Disk */ bl808_copy_ramdisk(); diff --git a/arch/risc-v/src/c906/c906_memorymap.h b/arch/risc-v/src/c906/c906_memorymap.h index 4f7a01254e..8ee10abee2 100644 --- a/arch/risc-v/src/c906/c906_memorymap.h +++ b/arch/risc-v/src/c906/c906_memorymap.h @@ -44,7 +44,7 @@ #define C906_IDLESTACK_BASE _ebss #endif -#define C906_IDLESTACK0_TOP (C906_IDLESTACK_BASE + CONFIG_IDLETHREAD_STACKSIZE) +#define C906_IDLESTACK0_TOP (C906_IDLESTACK_BASE + SMP_STACK_SIZE) #define C906_IDLESTACK_TOP (C906_IDLESTACK0_TOP) #endif /* __ARCH_RISCV_SRC_C906_C906_MEMORYMAP_H */ diff --git a/arch/risc-v/src/c906/c906_start.c b/arch/risc-v/src/c906/c906_start.c index 9ac201fa03..8b7dd53c44 100644 --- a/arch/risc-v/src/c906/c906_start.c +++ b/arch/risc-v/src/c906/c906_start.c @@ -91,6 +91,10 @@ void __c906_start(uint32_t mhartid) *dest++ = 0; } + /* Setup base stack */ + + riscv_set_basestack(C906_IDLESTACK_BASE, SMP_STACK_SIZE); + /* Move the initialized data section from his temporary holding spot in * FLASH into the correct place in SRAM. The correct place in SRAM is * give by _sdata and _edata. The temporary location is in FLASH at the diff --git a/arch/risc-v/src/common/espressif/esp_memorymap.h b/arch/risc-v/src/common/espressif/esp_memorymap.h index e8d78b1bd4..7465e18329 100644 --- a/arch/risc-v/src/common/espressif/esp_memorymap.h +++ b/arch/risc-v/src/common/espressif/esp_memorymap.h @@ -27,6 +27,8 @@ #include +#include "riscv_common_memorymap.h" + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -39,6 +41,6 @@ #define ESP_IDLESTACK_BASE g_idlestack #endif -#define ESP_IDLESTACK_TOP (ESP_IDLESTACK_BASE + CONFIG_IDLETHREAD_STACKSIZE) +#define ESP_IDLESTACK_TOP (ESP_IDLESTACK_BASE + SMP_STACK_SIZE) #endif /* __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_MEMORYMAP_H */ diff --git a/arch/risc-v/src/common/espressif/esp_start.c b/arch/risc-v/src/common/espressif/esp_start.c index cbb45fcc8e..da2a1dab5d 100644 --- a/arch/risc-v/src/common/espressif/esp_start.c +++ b/arch/risc-v/src/common/espressif/esp_start.c @@ -176,7 +176,7 @@ HDR_ATTR static void (*_entry_point)(void) = __start; /* Address of the IDLE thread */ -uint8_t g_idlestack[CONFIG_IDLETHREAD_STACKSIZE] +uint8_t g_idlestack[SMP_STACK_SIZE] aligned_data(16) locate_data(".noinit"); uintptr_t g_idle_topstack = ESP_IDLESTACK_TOP; @@ -459,6 +459,10 @@ void __esp_start(void) *dest++ = 0; } + /* Setup base stack */ + + riscv_set_basestack(ESP_IDLESTACK_BASE, SMP_STACK_SIZE); + /* Setup the syscall table needed by the ROM code */ esp_setup_syscall_table(); diff --git a/arch/risc-v/src/common/riscv_common_memorymap.h b/arch/risc-v/src/common/riscv_common_memorymap.h index af737244c9..c80382d0e0 100644 --- a/arch/risc-v/src/common/riscv_common_memorymap.h +++ b/arch/risc-v/src/common/riscv_common_memorymap.h @@ -67,8 +67,7 @@ EXTERN uintptr_t g_idle_topstack; /* Address of per-cpu idle stack base */ -EXTERN uint8_t aligned_data(16) -g_cpux_idlestack[CONFIG_SMP_NCPUS - 1][SMP_STACK_SIZE]; +EXTERN const uint8_t *g_cpux_idlestack[CONFIG_SMP_NCPUS]; /* Address of the saved user stack pointer */ diff --git a/arch/risc-v/src/common/riscv_cpuidlestack.c b/arch/risc-v/src/common/riscv_cpuidlestack.c index e31402a0e1..0358a3464e 100644 --- a/arch/risc-v/src/common/riscv_cpuidlestack.c +++ b/arch/risc-v/src/common/riscv_cpuidlestack.c @@ -43,18 +43,12 @@ * Private Data ****************************************************************************/ -/* Note: - * 1. QEMU-RV supports up to 8 cores currently. - * 2. RISC-V requires a 16-byte stack alignment. - */ - -uint8_t aligned_data(16) -g_cpux_idlestack[CONFIG_SMP_NCPUS - 1][SMP_STACK_SIZE]; - /**************************************************************************** * Public Data ****************************************************************************/ +const uint8_t *g_cpux_idlestack[CONFIG_SMP_NCPUS]; + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -112,7 +106,7 @@ int up_cpu_idlestack(int cpu, struct tcb_s *tcb, size_t stack_size) /* Get the top of the stack */ - stack_alloc = (uintptr_t)g_cpux_idlestack[cpu - 1]; + stack_alloc = (uintptr_t)g_cpux_idlestack[cpu]; DEBUGASSERT(stack_alloc != 0 && STACK_ISALIGNED(stack_alloc)); tcb->adj_stack_size = SMP_STACK_SIZE; diff --git a/arch/risc-v/src/common/riscv_initialstate.c b/arch/risc-v/src/common/riscv_initialstate.c index 475bea69a4..0fd258404a 100644 --- a/arch/risc-v/src/common/riscv_initialstate.c +++ b/arch/risc-v/src/common/riscv_initialstate.c @@ -97,10 +97,9 @@ void up_initial_state(struct tcb_s *tcb) if (tcb->pid == IDLE_PROCESS_ID) { - tcb->stack_alloc_ptr = (void *)(g_idle_topstack - - CONFIG_IDLETHREAD_STACKSIZE); + tcb->stack_alloc_ptr = (void *)g_cpux_idlestack[riscv_mhartid()]; tcb->stack_base_ptr = tcb->stack_alloc_ptr; - tcb->adj_stack_size = CONFIG_IDLETHREAD_STACKSIZE; + tcb->adj_stack_size = SMP_STACK_SIZE; #ifdef CONFIG_STACK_COLORATION /* If stack debug is enabled, then fill the stack with a diff --git a/arch/risc-v/src/common/riscv_internal.h b/arch/risc-v/src/common/riscv_internal.h index 68e3c5c8af..e21e7ebedc 100644 --- a/arch/risc-v/src/common/riscv_internal.h +++ b/arch/risc-v/src/common/riscv_internal.h @@ -294,6 +294,18 @@ int riscv_check_pmp_access(uintptr_t attr, uintptr_t base, uintptr_t size); int riscv_configured_pmp_regions(void); int riscv_next_free_pmp_region(void); +/* RISC-V Memorymap Config **************************************************/ + +static inline void riscv_set_basestack(uintptr_t base, uintptr_t size) +{ + unsigned int i; + + for (i = 0; i < CONFIG_SMP_NCPUS; i++) + { + g_cpux_idlestack[i] = (const uint8_t *)(base + size * i); + } +} + /* RISC-V SBI wrappers ******************************************************/ #ifdef CONFIG_ARCH_USE_S_MODE diff --git a/arch/risc-v/src/common/riscv_macros.S b/arch/risc-v/src/common/riscv_macros.S index 46e8ac490b..62e7f9902a 100644 --- a/arch/risc-v/src/common/riscv_macros.S +++ b/arch/risc-v/src/common/riscv_macros.S @@ -364,3 +364,45 @@ csrr \out, CSR_MHARTID #endif .endm + +/**************************************************************************** + * Name: riscv_set_inital_sp + * + * Description: + * Set inital sp for riscv core. This function should be only called + * when initing. + * + * sp (stack top) = sp base + idle stack size * hart id + * sp (stack base) = sp (stack top) + idle stack size * - XCPTCONTEXT_SIZE + * + * Note: The XCPTCONTEXT_SIZE byte after stack base is reserved for + * up_initial_state since we are already running and using + * the per CPU idle stack. + * + * TODO: Support non-zero boot hart. + * + * Parameter: + * base - Pointer to where the stack is allocated (e.g. _ebss) + * size - Stack size for pre cpu to allocate + * size - Hart id register of this hart (Usually a0) + * + ****************************************************************************/ +.macro riscv_set_inital_sp base, size, hartid + la t0, \base + li t1, \size + mul t1, \hartid, t1 + add t0, t0, t1 + + /* ensure the last XCPTCONTEXT_SIZE is reserved for non boot CPU */ + + bnez \hartid, 998f + li t1, STACK_ALIGN_DOWN(\size) + j 999f + +998: + li t1, STACK_ALIGN_DOWN(\size - XCPTCONTEXT_SIZE) + +999: + add t0, t0, t1 + mv sp, t0 +.endm diff --git a/arch/risc-v/src/esp32c3-legacy/esp32c3_memorymap.h b/arch/risc-v/src/esp32c3-legacy/esp32c3_memorymap.h index 59fa8b5e96..0dcc1b77ff 100644 --- a/arch/risc-v/src/esp32c3-legacy/esp32c3_memorymap.h +++ b/arch/risc-v/src/esp32c3-legacy/esp32c3_memorymap.h @@ -25,6 +25,8 @@ * Included Files ****************************************************************************/ +#include "riscv_common_memorymap.h" + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -37,6 +39,6 @@ #define ESP32C3_IDLESTACK_BASE g_idlestack #endif -#define ESP32C3_IDLESTACK_TOP (ESP32C3_IDLESTACK_BASE + CONFIG_IDLETHREAD_STACKSIZE) +#define ESP32C3_IDLESTACK_TOP (ESP32C3_IDLESTACK_BASE + SMP_STACK_SIZE) #endif /* __ARCH_RISCV_SRC_ESP32C3_LEGACY_ESP32C3_MEMORYMAP_H */ diff --git a/arch/risc-v/src/esp32c3-legacy/esp32c3_start.c b/arch/risc-v/src/esp32c3-legacy/esp32c3_start.c index c1c58b7ba1..74b5e37577 100644 --- a/arch/risc-v/src/esp32c3-legacy/esp32c3_start.c +++ b/arch/risc-v/src/esp32c3-legacy/esp32c3_start.c @@ -129,7 +129,7 @@ HDR_ATTR static void (*_entry_point)(void) = __start; /* Address of the IDLE thread */ -uint8_t g_idlestack[CONFIG_IDLETHREAD_STACKSIZE] +uint8_t g_idlestack[SMP_STACK_SIZE] aligned_data(16) locate_data(".noinit"); uintptr_t g_idle_topstack = ESP32C3_IDLESTACK_TOP; @@ -294,6 +294,10 @@ void __esp32c3_start(void) *dest++ = 0; } + /* Setup base stack */ + + riscv_set_basestack(ESP32C3_IDLESTACK_BASE, SMP_STACK_SIZE); + /* Setup the syscall table needed by the ROM code */ setup_syscall_table(); diff --git a/arch/risc-v/src/fe310/fe310_memorymap.h b/arch/risc-v/src/fe310/fe310_memorymap.h index f7495cf03d..6bf30e6364 100644 --- a/arch/risc-v/src/fe310/fe310_memorymap.h +++ b/arch/risc-v/src/fe310/fe310_memorymap.h @@ -45,6 +45,6 @@ #define FE310_IDLESTACK_BASE _ebss #endif -#define FE310_IDLESTACK_TOP (FE310_IDLESTACK_BASE + CONFIG_IDLETHREAD_STACKSIZE) +#define FE310_IDLESTACK_TOP (FE310_IDLESTACK_BASE + SMP_STACK_SIZE) #endif /* __ARCH_RISCV_SRC_FE310_FE310_MEMORYMAP_H */ diff --git a/arch/risc-v/src/fe310/fe310_start.c b/arch/risc-v/src/fe310/fe310_start.c index d22be0f97f..279ce82d0f 100644 --- a/arch/risc-v/src/fe310/fe310_start.c +++ b/arch/risc-v/src/fe310/fe310_start.c @@ -81,6 +81,10 @@ void __fe310_start(void) *dest++ = 0; } + /* Setup base stack */ + + riscv_set_basestack(FE310_IDLESTACK_BASE, SMP_STACK_SIZE); + /* Move the initialized data section from his temporary holding spot in * FLASH into the correct place in SRAM. The correct place in SRAM is * give by _sdata and _edata. The temporary location is in FLASH at the diff --git a/arch/risc-v/src/hpm6000/hpm_memorymap.h b/arch/risc-v/src/hpm6000/hpm_memorymap.h index 381c67c030..9d42acaad8 100644 --- a/arch/risc-v/src/hpm6000/hpm_memorymap.h +++ b/arch/risc-v/src/hpm6000/hpm_memorymap.h @@ -45,6 +45,6 @@ #define HPM_IDLESTACK_BASE _ebss #endif -#define HPM_IDLESTACK_TOP (HPM_IDLESTACK_BASE + CONFIG_IDLETHREAD_STACKSIZE) +#define HPM_IDLESTACK_TOP (HPM_IDLESTACK_BASE + SMP_STACK_SIZE) #endif /* __ARCH_RISCV_SRC_HPM6000_HPM_MEMORYMAP_H */ diff --git a/arch/risc-v/src/hpm6000/hpm_start.c b/arch/risc-v/src/hpm6000/hpm_start.c index 15b532a7a4..d368b9027a 100644 --- a/arch/risc-v/src/hpm6000/hpm_start.c +++ b/arch/risc-v/src/hpm6000/hpm_start.c @@ -76,6 +76,10 @@ void __hpm_start(void) *dest++ = 0; } + /* Setup base stack */ + + riscv_set_basestack(HPM_IDLESTACK_BASE, CONFIG_IDLETHREAD_STACKSIZE); + /* Move the initialized data section from his temporary holding spot in * FLASH into the correct place in SRAM. The correct place in SRAM is * give by _sdata and _edata. The temporary location is in FLASH at the diff --git a/arch/risc-v/src/hpm6750/hpm6750_memorymap.h b/arch/risc-v/src/hpm6750/hpm6750_memorymap.h index 56ecf64388..b9c960589c 100644 --- a/arch/risc-v/src/hpm6750/hpm6750_memorymap.h +++ b/arch/risc-v/src/hpm6750/hpm6750_memorymap.h @@ -45,6 +45,6 @@ #define HPM6750_IDLESTACK_BASE _ebss #endif -#define HPM6750_IDLESTACK_TOP (HPM6750_IDLESTACK_BASE + CONFIG_IDLETHREAD_STACKSIZE) +#define HPM6750_IDLESTACK_TOP (HPM6750_IDLESTACK_BASE + SMP_STACK_SIZE) #endif /* __ARCH_RISCV_SRC_HPM6750_HPM6750_MEMORYMAP_H */ diff --git a/arch/risc-v/src/hpm6750/hpm6750_start.c b/arch/risc-v/src/hpm6750/hpm6750_start.c index 1a7f530a4f..a751c8cf4f 100644 --- a/arch/risc-v/src/hpm6750/hpm6750_start.c +++ b/arch/risc-v/src/hpm6750/hpm6750_start.c @@ -76,6 +76,10 @@ void __hpm6750_start(void) *dest++ = 0; } + /* Setup base stack */ + + riscv_set_basestack(HPM6750_IDLESTACK_BASE, SMP_STACK_SIZE); + /* Move the initialized data section from his temporary holding spot in * FLASH into the correct place in SRAM. The correct place in SRAM is * give by _sdata and _edata. The temporary location is in FLASH at the diff --git a/arch/risc-v/src/jh7110/jh7110_head.S b/arch/risc-v/src/jh7110/jh7110_head.S index 00a4386361..151195c200 100644 --- a/arch/risc-v/src/jh7110/jh7110_head.S +++ b/arch/risc-v/src/jh7110/jh7110_head.S @@ -29,6 +29,7 @@ #include "chip.h" #include "riscv_internal.h" +#include "riscv_macros.S" /**************************************************************************** * Public Symbols @@ -74,13 +75,6 @@ real_start: addi a0, a0, -1 - /* Set stack pointer to the idle thread stack */ - - bnez a0, 1f - la sp, JH7110_IDLESTACK_TOP - j 2f -1: - /* Load the number of CPUs that the kernel supports */ #ifdef CONFIG_SMP @@ -96,30 +90,8 @@ real_start: wfi 3: - /* Get start address of idle stack array */ - - la t0, g_cpux_idlestack - - /* Get idle stack offset */ - - li t1, SMP_STACK_SIZE - mul t1, t1, a0 - - /* Load idle stack top to sp */ - - add sp, t0, t1 - - /* - * sp (stack top) = sp (stack top) - XCPTCONTEXT_SIZE - * - * Note: Reserve some space used by up_initial_state since we are already - * running and using the per CPU idle stack. - */ - - li t0, -STACK_ALIGN_UP(XCPTCONTEXT_SIZE) - add sp, sp, t0 - -2: + /* Set stack pointer to the idle thread stack */ + riscv_set_inital_sp JH7110_IDLESTACK_BASE, SMP_STACK_SIZE, a0 /* Disable all interrupts (i.e. timer, external) in sie */ diff --git a/arch/risc-v/src/jh7110/jh7110_memorymap.h b/arch/risc-v/src/jh7110/jh7110_memorymap.h index d922e3c4a8..02724605e5 100644 --- a/arch/risc-v/src/jh7110/jh7110_memorymap.h +++ b/arch/risc-v/src/jh7110/jh7110_memorymap.h @@ -39,7 +39,4 @@ #define JH7110_IDLESTACK_BASE _ebss #endif -#define JH7110_IDLESTACK_SIZE (CONFIG_IDLETHREAD_STACKSIZE & ~3) -#define JH7110_IDLESTACK_TOP (JH7110_IDLESTACK_BASE + JH7110_IDLESTACK_SIZE) - #endif /* __ARCH_RISCV_SRC_JH7110_JH7110_MEMORYMAP_H */ diff --git a/arch/risc-v/src/jh7110/jh7110_start.c b/arch/risc-v/src/jh7110/jh7110_start.c index a4c3fbdfb1..1dac2fdf53 100644 --- a/arch/risc-v/src/jh7110/jh7110_start.c +++ b/arch/risc-v/src/jh7110/jh7110_start.c @@ -53,10 +53,11 @@ extern void __trap_vec(void); ****************************************************************************/ /* NOTE: g_idle_topstack needs to point the top of the idle stack - * for CPU0 and this value is used in up_initial_state() + * for last CPU and this value is used in up_initial_state() */ -uintptr_t g_idle_topstack = JH7110_IDLESTACK_TOP; +uintptr_t g_idle_topstack = JH7110_IDLESTACK_BASE + + SMP_STACK_SIZE * CONFIG_SMP_NCPUS; /**************************************************************************** * Public Functions @@ -139,6 +140,10 @@ void jh7110_start(int mhartid) { jh7110_clear_bss(); + /* Setup base stack */ + + riscv_set_basestack(JH7110_IDLESTACK_BASE, SMP_STACK_SIZE); + /* Initialize the per CPU areas */ riscv_percpu_add_hart(mhartid); diff --git a/arch/risc-v/src/k210/k210_head.S b/arch/risc-v/src/k210/k210_head.S index 948d92cff2..53101c079b 100644 --- a/arch/risc-v/src/k210/k210_head.S +++ b/arch/risc-v/src/k210/k210_head.S @@ -28,6 +28,7 @@ #include "chip.h" #include "k210_memorymap.h" #include "riscv_internal.h" +#include "riscv_macros.S" /**************************************************************************** * Public Symbols @@ -46,44 +47,17 @@ __start: csrr a0, CSR_MHARTID - /* Set stack pointer to the idle thread stack */ - - bnez a0, 1f - la sp, K210_IDLESTACK0_TOP - j 2f -1: - /* In case of single CPU config, stop here */ #if !defined(CONFIG_SMP) || (CONFIG_SMP_NCPUS == 1) + beqz a0, 2f csrw CSR_MIE, zero wfi #endif - /* Get start address of idle stack array */ - - la t0, g_cpux_idlestack - - /* Get idle stack offset */ - - li t1, SMP_STACK_SIZE - mul t1, t1, a0 - - /* Load idle stack top to sp */ - - add sp, t0, t1 - - /* - * sp (stack top) = sp (stack top) - XCPTCONTEXT_SIZE - * - * Note: Reserve some space used by up_initial_state since we are already - * running and using the per CPU idle stack. - */ - - li t0, -STACK_ALIGN_UP(XCPTCONTEXT_SIZE) - add sp, sp, t0 - 2: + /* Set stack pointer to the idle thread stack */ + riscv_set_inital_sp K210_IDLESTACK_BASE, SMP_STACK_SIZE, a0 /* Disable all interrupts (i.e. timer, external) in mie */ diff --git a/arch/risc-v/src/k210/k210_memorymap.h b/arch/risc-v/src/k210/k210_memorymap.h index 9027742f48..68f73bf8c2 100644 --- a/arch/risc-v/src/k210/k210_memorymap.h +++ b/arch/risc-v/src/k210/k210_memorymap.h @@ -45,6 +45,5 @@ #endif #define K210_IDLESTACK0_BASE (K210_IDLESTACK_BASE) -#define K210_IDLESTACK0_TOP (K210_IDLESTACK0_BASE + CONFIG_IDLETHREAD_STACKSIZE) #endif /* __ARCH_RISCV_SRC_K210_K210_MEMORYMAP_H */ diff --git a/arch/risc-v/src/k210/k210_start.c b/arch/risc-v/src/k210/k210_start.c index c52eb6b4aa..b85525abf0 100644 --- a/arch/risc-v/src/k210/k210_start.c +++ b/arch/risc-v/src/k210/k210_start.c @@ -52,7 +52,8 @@ * for CPU0 and this value is used in up_initial_state() */ -uintptr_t g_idle_topstack = K210_IDLESTACK0_TOP; +uintptr_t g_idle_topstack = K210_IDLESTACK_BASE + + SMP_STACK_SIZE * CONFIG_SMP_NCPUS; /**************************************************************************** * Public Functions @@ -85,6 +86,10 @@ void __k210_start(uint32_t mhartid) *dest++ = 0; } + /* Setup base stack */ + + riscv_set_basestack(K210_IDLESTACK_BASE, SMP_STACK_SIZE); + /* Move the initialized data section from his temporary holding spot in * FLASH into the correct place in SRAM. The correct place in SRAM is * give by _sdata and _edata. The temporary location is in FLASH at the diff --git a/arch/risc-v/src/k230/k230_head.S b/arch/risc-v/src/k230/k230_head.S index 468e030c9e..2673779ceb 100644 --- a/arch/risc-v/src/k230/k230_head.S +++ b/arch/risc-v/src/k230/k230_head.S @@ -30,6 +30,7 @@ #include "chip.h" #include "riscv_internal.h" +#include "riscv_macros.S" /**************************************************************************** * Public Symbols @@ -64,13 +65,6 @@ __start: csrr a0, CSR_MHARTID #endif - /* Set stack pointer to the idle thread stack */ - - bnez a0, 1f - la sp, K230_IDLESTACK_TOP - j 2f -1: - /* Load the number of CPUs that the kernel supports */ #ifdef CONFIG_SMP @@ -86,30 +80,8 @@ __start: wfi 3: - /* Get start address of idle stack array */ - - la t0, g_cpux_idlestack - - /* Get idle stack offset */ - - li t1, SMP_STACK_SIZE - mul t1, t1, a0 - - /* Load idle stack top to sp */ - - add sp, t0, t1 - - /* - * sp (stack top) = sp (stack top) - XCPTCONTEXT_SIZE - * - * Note: Reserve some space used by up_initial_state since we are already - * running and using the per CPU idle stack. - */ - - li t0, -STACK_ALIGN_UP(XCPTCONTEXT_SIZE) - add sp, sp, t0 - -2: + /* Set stack pointer to the idle thread stack */ + riscv_set_inital_sp K230_IDLESTACK_BASE, SMP_STACK_SIZE, a0 /* Disable all interrupts (i.e. timer, external) */ diff --git a/arch/risc-v/src/k230/k230_memorymap.h b/arch/risc-v/src/k230/k230_memorymap.h index 2932691b61..a8701d8616 100644 --- a/arch/risc-v/src/k230/k230_memorymap.h +++ b/arch/risc-v/src/k230/k230_memorymap.h @@ -39,7 +39,4 @@ #define K230_IDLESTACK_BASE _ebss #endif -#define K230_IDLESTACK_SIZE (CONFIG_IDLETHREAD_STACKSIZE & ~3) -#define K230_IDLESTACK_TOP (K230_IDLESTACK_BASE + K230_IDLESTACK_SIZE) - #endif /* __ARCH_RISCV_SRC_K230_K230_MEMORYMAP_H */ diff --git a/arch/risc-v/src/k230/k230_start.c b/arch/risc-v/src/k230/k230_start.c index 954f31bc74..aa56852270 100644 --- a/arch/risc-v/src/k230/k230_start.c +++ b/arch/risc-v/src/k230/k230_start.c @@ -102,10 +102,11 @@ static void k230_copy_init_data(void) ****************************************************************************/ /* NOTE: g_idle_topstack needs to point the top of the idle stack - * for CPU0 and this value is used in up_initial_state() + * for last CPU and this value is used in up_initial_state() */ -uintptr_t g_idle_topstack = K230_IDLESTACK_TOP; +uintptr_t g_idle_topstack = K230_IDLESTACK_BASE + + SMP_STACK_SIZE * CONFIG_SMP_NCPUS; /**************************************************************************** * Public Functions @@ -121,6 +122,8 @@ void k230_start(int mhartid, const char *dtb) { k230_clear_bss(); + riscv_set_basestack(K230_IDLESTACK_BASE, SMP_STACK_SIZE); + #ifdef CONFIG_RISCV_PERCPU_SCRATCH riscv_percpu_add_hart(mhartid); #else diff --git a/arch/risc-v/src/litex/litex_memorymap.h b/arch/risc-v/src/litex/litex_memorymap.h index bd1a8b2307..3ef63e03c5 100644 --- a/arch/risc-v/src/litex/litex_memorymap.h +++ b/arch/risc-v/src/litex/litex_memorymap.h @@ -25,6 +25,7 @@ * Included Files ****************************************************************************/ +#include "riscv_common_memorymap.h" #include "hardware/litex_memorymap.h" #include "hardware/litex_uart.h" #include "hardware/litex_clint.h" @@ -42,6 +43,6 @@ #define LITEX_IDLESTACK_BASE _ebss #endif -#define LITEX_IDLESTACK_TOP (LITEX_IDLESTACK_BASE + CONFIG_IDLETHREAD_STACKSIZE) +#define LITEX_IDLESTACK_TOP (LITEX_IDLESTACK_BASE + SMP_STACK_SIZE) #endif /* __ARCH_RISCV_SRC_LITEX_LITEX_MEMORYMAP_H */ diff --git a/arch/risc-v/src/litex/litex_start.c b/arch/risc-v/src/litex/litex_start.c index 0d0f5135aa..00f33769c1 100644 --- a/arch/risc-v/src/litex/litex_start.c +++ b/arch/risc-v/src/litex/litex_start.c @@ -93,6 +93,10 @@ void __litex_start(int hart_index, const void * fdt, int arg) *dest++ = 0; } + /* Setup base stack */ + + riscv_set_basestack(LITEX_IDLESTACK_BASE, SMP_STACK_SIZE); + /* Move the initialized data section from his temporary holding spot in * FLASH into the correct place in SRAM. The correct place in SRAM is * give by _sdata and _edata. The temporary location is in FLASH at the diff --git a/arch/risc-v/src/mpfs/mpfs_memorymap.h b/arch/risc-v/src/mpfs/mpfs_memorymap.h index 75aa5c0bd7..b937b50c2b 100644 --- a/arch/risc-v/src/mpfs/mpfs_memorymap.h +++ b/arch/risc-v/src/mpfs/mpfs_memorymap.h @@ -44,7 +44,7 @@ #define MPFS_IDLESTACK_BASE _ebss #endif -#define MPFS_IDLESTACK_SIZE (CONFIG_IDLETHREAD_STACKSIZE & ~15) +#define MPFS_IDLESTACK_SIZE SMP_STACK_SIZE #define MPFS_IDLESTACK0_TOP (MPFS_IDLESTACK_BASE + MPFS_IDLESTACK_SIZE) diff --git a/arch/risc-v/src/mpfs/mpfs_start.c b/arch/risc-v/src/mpfs/mpfs_start.c index 8fabae1e0e..eae7c5399b 100644 --- a/arch/risc-v/src/mpfs/mpfs_start.c +++ b/arch/risc-v/src/mpfs/mpfs_start.c @@ -98,6 +98,10 @@ void __mpfs_start(uint64_t mhartid) *dest++ = 0; } + /* Setup base stack */ + + riscv_set_basestack(MPFS_IDLESTACK_BASE, MPFS_IDLESTACK_SIZE); + /* Move the initialized data section from his temporary holding spot in * FLASH into the correct place in SRAM. The correct place in SRAM is * give by _sdata and _edata. The temporary location is in FLASH at the diff --git a/arch/risc-v/src/qemu-rv/qemu_rv_head.S b/arch/risc-v/src/qemu-rv/qemu_rv_head.S index 073d85022a..80f3500b4c 100644 --- a/arch/risc-v/src/qemu-rv/qemu_rv_head.S +++ b/arch/risc-v/src/qemu-rv/qemu_rv_head.S @@ -29,6 +29,7 @@ #include "chip.h" #include "riscv_internal.h" +#include "riscv_macros.S" /**************************************************************************** * Public Symbols @@ -46,52 +47,18 @@ __start: csrr a0, CSR_MHARTID - /* Set stack pointer to the idle thread stack */ - - bnez a0, 1f - la sp, QEMU_RV_IDLESTACK_TOP - j 2f -1: - /* Load the number of CPUs that the kernel supports */ - -#ifdef CONFIG_SMP li t1, CONFIG_SMP_NCPUS -#else - li t1, 1 -#endif /* If a0 (mhartid) >= t1 (the number of CPUs), stop here */ - blt a0, t1, 3f + blt a0, t1, 2f csrw CSR_MIE, zero wfi -3: - /* Get start address of idle stack array */ - - la t0, g_cpux_idlestack - - /* Get idle stack offset */ - - li t1, SMP_STACK_SIZE - mul t1, t1, a0 - - /* Load idle stack top to sp */ - - add sp, t0, t1 - - /* - * sp (stack top) = sp (stack top) - XCPTCONTEXT_SIZE - * - * Note: Reserve some space used by up_initial_state since we are already - * running and using the per CPU idle stack. - */ - - li t0, -STACK_ALIGN_UP(XCPTCONTEXT_SIZE) - add sp, sp, t0 - 2: + /* Set stack pointer to the idle thread stack */ + riscv_set_inital_sp QEMU_RV_IDLESTACK_BASE, SMP_STACK_SIZE, a0 /* Disable all interrupts (i.e. timer, external) in mie */ diff --git a/arch/risc-v/src/qemu-rv/qemu_rv_memorymap.h b/arch/risc-v/src/qemu-rv/qemu_rv_memorymap.h index 9be4569ab6..1ce406701a 100644 --- a/arch/risc-v/src/qemu-rv/qemu_rv_memorymap.h +++ b/arch/risc-v/src/qemu-rv/qemu_rv_memorymap.h @@ -39,7 +39,4 @@ #define QEMU_RV_IDLESTACK_BASE _ebss #endif -#define QEMU_RV_IDLESTACK_SIZE (CONFIG_IDLETHREAD_STACKSIZE & ~3) -#define QEMU_RV_IDLESTACK_TOP (QEMU_RV_IDLESTACK_BASE + QEMU_RV_IDLESTACK_SIZE) - #endif /* __ARCH_RISCV_SRC_QEMU_RV_QEMU_RV_MEMORYMAP_H */ diff --git a/arch/risc-v/src/qemu-rv/qemu_rv_start.c b/arch/risc-v/src/qemu-rv/qemu_rv_start.c index 5c1d90ab7a..199be05f28 100644 --- a/arch/risc-v/src/qemu-rv/qemu_rv_start.c +++ b/arch/risc-v/src/qemu-rv/qemu_rv_start.c @@ -87,10 +87,11 @@ void qemu_rv_clear_bss(void) ****************************************************************************/ /* NOTE: g_idle_topstack needs to point the top of the idle stack - * for CPU0 and this value is used in up_initial_state() + * for last CPU and this value is used in up_initial_state() */ -uintptr_t g_idle_topstack = QEMU_RV_IDLESTACK_TOP; +uintptr_t g_idle_topstack = QEMU_RV_IDLESTACK_BASE + + SMP_STACK_SIZE * CONFIG_SMP_NCPUS; /**************************************************************************** * Public Functions @@ -118,6 +119,8 @@ void qemu_rv_start(int mhartid, const char *dtb) #ifndef CONFIG_BUILD_KERNEL qemu_rv_clear_bss(); + riscv_set_basestack(QEMU_RV_IDLESTACK_BASE, SMP_STACK_SIZE); + #ifdef CONFIG_RISCV_PERCPU_SCRATCH riscv_percpu_add_hart(mhartid); #endif diff --git a/arch/risc-v/src/rv32m1/rv32m1_memorymap.h b/arch/risc-v/src/rv32m1/rv32m1_memorymap.h index 28e2b6d89b..1f8612e334 100644 --- a/arch/risc-v/src/rv32m1/rv32m1_memorymap.h +++ b/arch/risc-v/src/rv32m1/rv32m1_memorymap.h @@ -25,6 +25,8 @@ * Included Files ****************************************************************************/ +#include "riscv_internal.h" + #include "hardware/rv32m1_memorymap.h" /**************************************************************************** @@ -39,7 +41,7 @@ #define RV32M1_IDLESTACK_BASE _ebss #endif -#define RV32M1_IDLESTACK_SIZE (CONFIG_IDLETHREAD_STACKSIZE & ~3) +#define RV32M1_IDLESTACK_SIZE SMP_STACK_SIZE #define RV32M1_IDLESTACK_TOP (RV32M1_IDLESTACK_BASE + RV32M1_IDLESTACK_SIZE) #endif /* __ARCH_RISCV_SRC_RV32M1_RV32M1_MEMORYMAP_H */ diff --git a/arch/risc-v/src/rv32m1/rv32m1_start.c b/arch/risc-v/src/rv32m1/rv32m1_start.c index 895290e247..fb9c6ef996 100644 --- a/arch/risc-v/src/rv32m1/rv32m1_start.c +++ b/arch/risc-v/src/rv32m1/rv32m1_start.c @@ -113,6 +113,10 @@ void __rv32m1_start(void) *dest++ = 0; } + /* Setup base stack */ + + riscv_set_basestack(RV32M1_IDLESTACK_BASE, RV32M1_IDLESTACK_TOP); + /* Move the initialized data section from his temporary holding spot in * FLASH into the correct place in SRAM. The correct place in SRAM is * give by _sdata and _edata. The temporary location is in FLASH at the diff --git a/boards/risc-v/bl808/ox64/scripts/ld.script b/boards/risc-v/bl808/ox64/scripts/ld.script index 94f115dd79..e47b594ff0 100644 --- a/boards/risc-v/bl808/ox64/scripts/ld.script +++ b/boards/risc-v/bl808/ox64/scripts/ld.script @@ -116,6 +116,7 @@ SECTIONS *(.sbss.*) *(.gnu.linkonce.b*) *(COMMON) + . = ALIGN(32); _ebss = . ; } > ksram diff --git a/boards/risc-v/jh7110/star64/scripts/ld.script b/boards/risc-v/jh7110/star64/scripts/ld.script index 2bb18a5663..4d9190a937 100644 --- a/boards/risc-v/jh7110/star64/scripts/ld.script +++ b/boards/risc-v/jh7110/star64/scripts/ld.script @@ -116,6 +116,7 @@ SECTIONS *(.sbss.*) *(.gnu.linkonce.b*) *(COMMON) + . = ALIGN(32); _ebss = . ; } > ksram diff --git a/boards/risc-v/k210/maix-bit/scripts/ld.script b/boards/risc-v/k210/maix-bit/scripts/ld.script index 44370ae567..282206762d 100644 --- a/boards/risc-v/k210/maix-bit/scripts/ld.script +++ b/boards/risc-v/k210/maix-bit/scripts/ld.script @@ -81,7 +81,7 @@ SECTIONS *(.gnu.linkonce.b.*) *(.gnu.linkonce.sb.*) *(COMMON) - . = ALIGN(8); + . = ALIGN(32); _ebss = ABSOLUTE(.); } > sram diff --git a/boards/risc-v/k210/maix-bit/scripts/user-space.ld b/boards/risc-v/k210/maix-bit/scripts/user-space.ld index d51266a3a6..206b7e5beb 100644 --- a/boards/risc-v/k210/maix-bit/scripts/user-space.ld +++ b/boards/risc-v/k210/maix-bit/scripts/user-space.ld @@ -75,7 +75,7 @@ SECTIONS *(.sbss .sbss.*) *(.gnu.linkonce.b.*) *(COMMON) - . = ALIGN(8); + . = ALIGN(32); _ebss = ABSOLUTE(.); } > usram diff --git a/boards/risc-v/k230/canmv230/scripts/ld-flat.script b/boards/risc-v/k230/canmv230/scripts/ld-flat.script index 1f1dba29b4..3e340ddfaa 100644 --- a/boards/risc-v/k230/canmv230/scripts/ld-flat.script +++ b/boards/risc-v/k230/canmv230/scripts/ld-flat.script @@ -114,6 +114,7 @@ SECTIONS *(.sbss.*) *(.gnu.linkonce.b*) *(COMMON) + . = ALIGN(32); _ebss = . ; } diff --git a/boards/risc-v/qemu-rv/rv-virt/scripts/ld.script b/boards/risc-v/qemu-rv/rv-virt/scripts/ld.script index f2a6326ad8..95d38cf3a9 100644 --- a/boards/risc-v/qemu-rv/rv-virt/scripts/ld.script +++ b/boards/risc-v/qemu-rv/rv-virt/scripts/ld.script @@ -108,6 +108,7 @@ SECTIONS *(.sbss.*) *(.gnu.linkonce.b*) *(COMMON) + . = ALIGN(32); _ebss = . ; }