diff --git a/arch/risc-v/src/k210/k210_cpuidlestack.c b/arch/risc-v/src/k210/k210_cpuidlestack.c index 1c59e18716..fa86480435 100644 --- a/arch/risc-v/src/k210/k210_cpuidlestack.c +++ b/arch/risc-v/src/k210/k210_cpuidlestack.c @@ -30,9 +30,22 @@ #include #include "riscv_internal.h" +#include "k210_memorymap.h" #ifdef CONFIG_SMP +#define SMP_STACK_MASK 7 +#define SMP_STACK_SIZE ((CONFIG_SMP_IDLETHREAD_STACKSIZE + 7) & ~7) +#define STACK_ISALIGNED(a) ((uintptr_t)(a) & ~SMP_STACK_MASK) + +#if CONFIG_SMP_NCPUS > 1 +static FAR const uintptr_t g_cpu_stackalloc[CONFIG_SMP_NCPUS] = +{ + 0 + , K210_IDLESTACK1_BASE +}; +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -83,7 +96,19 @@ int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size) { #if CONFIG_SMP_NCPUS > 1 - up_create_stack(tcb, stack_size, TCB_FLAG_TTYPE_KERNEL); + uintptr_t stack_alloc; + + DEBUGASSERT(cpu > 0 && cpu < CONFIG_SMP_NCPUS && tcb != NULL && + stack_size <= SMP_STACK_SIZE); + + /* Get the top of the stack */ + + stack_alloc = (uintptr_t)g_cpu_stackalloc[cpu]; + DEBUGASSERT(stack_alloc != 0 && STACK_ISALIGNED(stack_alloc)); + + tcb->adj_stack_size = SMP_STACK_SIZE; + tcb->stack_alloc_ptr = (FAR void *)stack_alloc; + tcb->stack_base_ptr = tcb->stack_alloc_ptr; #endif return OK; } diff --git a/arch/risc-v/src/k210/k210_head.S b/arch/risc-v/src/k210/k210_head.S index 0a5f8ba3f9..e05bee4bfc 100644 --- a/arch/risc-v/src/k210/k210_head.S +++ b/arch/risc-v/src/k210/k210_head.S @@ -26,6 +26,8 @@ #include #include "chip.h" +#include "k210_memorymap.h" +#include "riscv_internal.h" /**************************************************************************** * Public Symbols @@ -53,6 +55,12 @@ __start: j 2f 1: la sp, K210_IDLESTACK1_TOP + + /* In case of single CPU config, stop here */ + +#if !(defined CONFIG_SMP) || (CONFIG_SMP_NCPUS == 1) + wfi +#endif 2: /* Disable all interrupts (i.e. timer, external) in mie */ @@ -64,6 +72,25 @@ __start: la t0, __trap_vec csrw mtvec, t0 +#ifdef CONFIG_STACK_COLORATION + /* t0 = start of IDLE stack; t1 = top of the stack; t2 = coloration */ + + bnez a0, 3f /* a0: hartid */ + la t0, K210_IDLESTACK0_BASE + j 4f +3: + la t0, K210_IDLESTACK1_BASE +4: + + mv t1, sp + li t2, STACK_COLOR + +5: + sw t2, 0(t0) + addi t0, t0, 4 + bne t0, t1, 5b +#endif + /* Jump to __k210_start with mhartid */ j __k210_start diff --git a/arch/risc-v/src/k210/k210_memorymap.h b/arch/risc-v/src/k210/k210_memorymap.h index 22dc10c1ed..18365f4832 100644 --- a/arch/risc-v/src/k210/k210_memorymap.h +++ b/arch/risc-v/src/k210/k210_memorymap.h @@ -38,14 +38,22 @@ /* Idle thread stack starts from _ebss */ #ifndef __ASSEMBLY__ -#define K210_IDLESTACK_BASE (uintptr_t)&_ebss +extern uintptr_t *_default_stack_limit; +#define K210_IDLESTACK_BASE (uintptr_t)&_default_stack_limit #else -#define K210_IDLESTACK_BASE _ebss +#define K210_IDLESTACK_BASE _default_stack_limit #endif -#define K210_IDLESTACK0_TOP (K210_IDLESTACK_BASE + CONFIG_IDLETHREAD_STACKSIZE) -#define K210_IDLESTACK1_TOP (K210_IDLESTACK0_TOP + CONFIG_IDLETHREAD_STACKSIZE) +#define K210_IDLESTACK0_BASE (K210_IDLESTACK_BASE) +#define K210_IDLESTACK0_TOP (K210_IDLESTACK0_BASE + CONFIG_IDLETHREAD_STACKSIZE) +#define K210_IDLESTACK1_BASE (K210_IDLESTACK0_TOP) +#define K210_IDLESTACK1_TOP (K210_IDLESTACK1_BASE + CONFIG_IDLETHREAD_STACKSIZE) + +#if defined(CONFIG_SMP) && (CONFIG_SMP_NCPUS > 1) #define K210_IDLESTACK_TOP (K210_IDLESTACK1_TOP) +#else +#define K210_IDLESTACK_TOP (K210_IDLESTACK0_TOP) +#endif #endif /* _ARCH_RISCV_SRC_K210_K210_MEMORYMAP_H */