diff options
Diffstat (limited to 'core/riscv-rv32i/init.S')
-rw-r--r-- | core/riscv-rv32i/init.S | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/core/riscv-rv32i/init.S b/core/riscv-rv32i/init.S index de98846686..dedd7a644f 100644 --- a/core/riscv-rv32i/init.S +++ b/core/riscv-rv32i/init.S @@ -147,18 +147,35 @@ __irq_isr: fsw ft2, -19*4(sp) fsw ft1, -18*4(sp) fsw ft0, -17*4(sp) + /* + * Note: we never execute on this stack frame, so it does not need to + * be 16-byte aligned. + */ addi sp, sp, -37*4 #else + /* + * Note: we never execute on this stack frame, so it does not need to + * be 16-byte aligned. + */ addi sp, sp, -16*4 #endif - /* save sp to scratch register */ + /* Save sp to scratch register */ csrw mscratch, sp - /* switch to system stack if we are called from process stack */ + /* Load top of system stack address into t0 for comparison */ la t0, stack_end - /* no chagne sp if sp < end of system stack */ - bltu sp, t0, __no_adjust_sp + /* + * Switch to system stack (which is in lower memory than task stack) + * if we are not already operating with the system stack + */ + bltu sp, t0, __sp_16byte_aligned mv sp, t0 -__no_adjust_sp: +__sp_16byte_aligned: + /* + * This ensures sp is 16-byte aligned. This only applies to when there + * is an interrupt before tasks start. Otherwise stack_end is already + * 16-byte aligned. + */ + andi sp, sp, -16 /* read exception cause */ csrr t0, mcause /* isolate exception cause */ @@ -388,7 +405,16 @@ _data_end: _data_lma_start: .long __data_lma_start -/* Reserve space for system stack */ +/* + * Reserve space for system stack. + * + * Main routine and ISR will share this space before tasks start. + * This space is then dedicated to ISRs after tasks start. + * + * NOTE: Location of system stack (.bss.system_stack) must be less than + * tasks stacks (task_stacks@.bss) and scratchpad for first context switch + * (scratchpad[]@.bss.task_scratchpad). + */ .section .bss.system_stack stack_start: .space CONFIG_STACK_SIZE, 0 |