From 8191eb1eda2f53803585f82084a8aa7e1dd31c93 Mon Sep 17 00:00:00 2001 From: zhouzhou_code <2031145985@qq.com> Date: Wed, 26 Aug 2026 01:50:53 +0800 Subject: [PATCH 1/2] refactor(riscv): split caller and callee context macros Signed-off-by: zhouzhou_code <2031145985@qq.com> --- portable/GCC/RISC-V/portContext.h | 140 +++++++++++++++++------------- 1 file changed, 80 insertions(+), 60 deletions(-) diff --git a/portable/GCC/RISC-V/portContext.h b/portable/GCC/RISC-V/portContext.h index 0869a82b6ce..0ccca69a3cf 100644 --- a/portable/GCC/RISC-V/portContext.h +++ b/portable/GCC/RISC-V/portContext.h @@ -270,38 +270,48 @@ add sp, sp, -( 2 * portWORD_SIZE ) .endm /*-----------------------------------------------------------*/ - .macro portcontextSAVE_CONTEXT_INTERNAL -addi sp, sp, -portCONTEXT_SIZE -store_x x1, 2 * portWORD_SIZE( sp ) -store_x x5, 3 * portWORD_SIZE( sp ) -store_x x6, 4 * portWORD_SIZE( sp ) -store_x x7, 5 * portWORD_SIZE( sp ) -store_x x8, 6 * portWORD_SIZE( sp ) -store_x x9, 7 * portWORD_SIZE( sp ) -store_x x10, 8 * portWORD_SIZE( sp ) -store_x x11, 9 * portWORD_SIZE( sp ) -store_x x12, 10 * portWORD_SIZE( sp ) -store_x x13, 11 * portWORD_SIZE( sp ) -store_x x14, 12 * portWORD_SIZE( sp ) -store_x x15, 13 * portWORD_SIZE( sp ) + .macro portcontextSAVE_CALLER_REGISTERS frame +store_x x1, 2 * portWORD_SIZE( \frame ) +store_x x5, 3 * portWORD_SIZE( \frame ) +store_x x6, 4 * portWORD_SIZE( \frame ) +store_x x7, 5 * portWORD_SIZE( \frame ) +store_x x10, 8 * portWORD_SIZE( \frame ) +store_x x11, 9 * portWORD_SIZE( \frame ) +store_x x12, 10 * portWORD_SIZE( \frame ) +store_x x13, 11 * portWORD_SIZE( \frame ) +store_x x14, 12 * portWORD_SIZE( \frame ) +store_x x15, 13 * portWORD_SIZE( \frame ) +#ifndef __riscv_32e + store_x x16, 14 * portWORD_SIZE( \frame ) + store_x x17, 15 * portWORD_SIZE( \frame ) + store_x x28, 26 * portWORD_SIZE( \frame ) + store_x x29, 27 * portWORD_SIZE( \frame ) + store_x x30, 28 * portWORD_SIZE( \frame ) + store_x x31, 29 * portWORD_SIZE( \frame ) +#endif /* ifndef __riscv_32e */ + .endm + + .macro portcontextSAVE_CALLEE_REGISTERS frame +store_x x8, 6 * portWORD_SIZE( \frame ) +store_x x9, 7 * portWORD_SIZE( \frame ) #ifndef __riscv_32e - store_x x16, 14 * portWORD_SIZE( sp ) - store_x x17, 15 * portWORD_SIZE( sp ) - store_x x18, 16 * portWORD_SIZE( sp ) - store_x x19, 17 * portWORD_SIZE( sp ) - store_x x20, 18 * portWORD_SIZE( sp ) - store_x x21, 19 * portWORD_SIZE( sp ) - store_x x22, 20 * portWORD_SIZE( sp ) - store_x x23, 21 * portWORD_SIZE( sp ) - store_x x24, 22 * portWORD_SIZE( sp ) - store_x x25, 23 * portWORD_SIZE( sp ) - store_x x26, 24 * portWORD_SIZE( sp ) - store_x x27, 25 * portWORD_SIZE( sp ) - store_x x28, 26 * portWORD_SIZE( sp ) - store_x x29, 27 * portWORD_SIZE( sp ) - store_x x30, 28 * portWORD_SIZE( sp ) - store_x x31, 29 * portWORD_SIZE( sp ) + store_x x18, 16 * portWORD_SIZE( \frame ) + store_x x19, 17 * portWORD_SIZE( \frame ) + store_x x20, 18 * portWORD_SIZE( \frame ) + store_x x21, 19 * portWORD_SIZE( \frame ) + store_x x22, 20 * portWORD_SIZE( \frame ) + store_x x23, 21 * portWORD_SIZE( \frame ) + store_x x24, 22 * portWORD_SIZE( \frame ) + store_x x25, 23 * portWORD_SIZE( \frame ) + store_x x26, 24 * portWORD_SIZE( \frame ) + store_x x27, 25 * portWORD_SIZE( \frame ) #endif /* ifndef __riscv_32e */ + .endm + + .macro portcontextSAVE_CONTEXT_INTERNAL +addi sp, sp, -portCONTEXT_SIZE +portcontextSAVE_CALLER_REGISTERS sp +portcontextSAVE_CALLEE_REGISTERS sp load_x t0, xCriticalNesting /* Load the value of xCriticalNesting into t0. */ store_x t0, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Store the critical nesting value to the stack. */ @@ -388,6 +398,44 @@ load_x sp, xISRStackTop /* Switch to ISR stack. */ .endm /*-----------------------------------------------------------*/ + .macro portcontextRESTORE_CALLER_REGISTERS frame +load_x x1, 2 * portWORD_SIZE( \frame ) +load_x x5, 3 * portWORD_SIZE( \frame ) +load_x x6, 4 * portWORD_SIZE( \frame ) +load_x x7, 5 * portWORD_SIZE( \frame ) +load_x x10, 8 * portWORD_SIZE( \frame ) +load_x x11, 9 * portWORD_SIZE( \frame ) +load_x x12, 10 * portWORD_SIZE( \frame ) +load_x x13, 11 * portWORD_SIZE( \frame ) +load_x x14, 12 * portWORD_SIZE( \frame ) +load_x x15, 13 * portWORD_SIZE( \frame ) +#ifndef __riscv_32e + load_x x16, 14 * portWORD_SIZE( \frame ) + load_x x17, 15 * portWORD_SIZE( \frame ) + load_x x28, 26 * portWORD_SIZE( \frame ) + load_x x29, 27 * portWORD_SIZE( \frame ) + load_x x30, 28 * portWORD_SIZE( \frame ) + load_x x31, 29 * portWORD_SIZE( \frame ) +#endif + .endm + + .macro portcontextRESTORE_CALLEE_REGISTERS frame +load_x x8, 6 * portWORD_SIZE( \frame ) +load_x x9, 7 * portWORD_SIZE( \frame ) +#ifndef __riscv_32e + load_x x18, 16 * portWORD_SIZE( \frame ) + load_x x19, 17 * portWORD_SIZE( \frame ) + load_x x20, 18 * portWORD_SIZE( \frame ) + load_x x21, 19 * portWORD_SIZE( \frame ) + load_x x22, 20 * portWORD_SIZE( \frame ) + load_x x23, 21 * portWORD_SIZE( \frame ) + load_x x24, 22 * portWORD_SIZE( \frame ) + load_x x25, 23 * portWORD_SIZE( \frame ) + load_x x26, 24 * portWORD_SIZE( \frame ) + load_x x27, 25 * portWORD_SIZE( \frame ) +#endif + .endm + .macro portcontextRESTORE_CONTEXT load_x t1, pxCurrentTCB /* Load pxCurrentTCB. */ load_x sp, 0 ( t1 ) /* Read sp from first TCB member. */ @@ -429,36 +477,8 @@ load_x t0, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Obtain xCritical load_x t1, pxCriticalNesting /* Load the address of xCriticalNesting into t1. */ store_x t0, 0 ( t1 ) /* Restore the critical nesting value for this task. */ -load_x x1, 2 * portWORD_SIZE( sp ) -load_x x5, 3 * portWORD_SIZE( sp ) -load_x x6, 4 * portWORD_SIZE( sp ) -load_x x7, 5 * portWORD_SIZE( sp ) -load_x x8, 6 * portWORD_SIZE( sp ) -load_x x9, 7 * portWORD_SIZE( sp ) -load_x x10, 8 * portWORD_SIZE( sp ) -load_x x11, 9 * portWORD_SIZE( sp ) -load_x x12, 10 * portWORD_SIZE( sp ) -load_x x13, 11 * portWORD_SIZE( sp ) -load_x x14, 12 * portWORD_SIZE( sp ) -load_x x15, 13 * portWORD_SIZE( sp ) -#ifndef __riscv_32e - load_x x16, 14 * portWORD_SIZE( sp ) - load_x x17, 15 * portWORD_SIZE( sp ) - load_x x18, 16 * portWORD_SIZE( sp ) - load_x x19, 17 * portWORD_SIZE( sp ) - load_x x20, 18 * portWORD_SIZE( sp ) - load_x x21, 19 * portWORD_SIZE( sp ) - load_x x22, 20 * portWORD_SIZE( sp ) - load_x x23, 21 * portWORD_SIZE( sp ) - load_x x24, 22 * portWORD_SIZE( sp ) - load_x x25, 23 * portWORD_SIZE( sp ) - load_x x26, 24 * portWORD_SIZE( sp ) - load_x x27, 25 * portWORD_SIZE( sp ) - load_x x28, 26 * portWORD_SIZE( sp ) - load_x x29, 27 * portWORD_SIZE( sp ) - load_x x30, 28 * portWORD_SIZE( sp ) - load_x x31, 29 * portWORD_SIZE( sp ) -#endif /* ifndef __riscv_32e */ +portcontextRESTORE_CALLEE_REGISTERS sp +portcontextRESTORE_CALLER_REGISTERS sp addi sp, sp, portCONTEXT_SIZE mret From ef308b3f7cdac10af24e4165e5ab8217513ccf90 Mon Sep 17 00:00:00 2001 From: zhouzhou_code <2031145985@qq.com> Date: Wed, 26 Aug 2026 01:57:40 +0800 Subject: [PATCH 2/2] perf(riscv): defer callee save on no-switch timer IRQ Signed-off-by: zhouzhou_code <2031145985@qq.com> --- portable/GCC/RISC-V/portASM.S | 9 ++- portable/GCC/RISC-V/portContext.h | 114 ++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 3 deletions(-) diff --git a/portable/GCC/RISC-V/portASM.S b/portable/GCC/RISC-V/portASM.S index 9d36d78f929..577d69dc9fa 100644 --- a/portable/GCC/RISC-V/portASM.S +++ b/portable/GCC/RISC-V/portASM.S @@ -338,13 +338,16 @@ freertos_risc_v_interrupt_handler: /*-----------------------------------------------------------*/ .section .text.freertos_risc_v_mtimer_interrupt_handler +.align 2 freertos_risc_v_mtimer_interrupt_handler: - portcontextSAVE_INTERRUPT_CONTEXT + portcontextSAVE_TIMER_CALLER_CONTEXT portUPDATE_MTIMER_COMPARE_REGISTER call xTaskIncrementTick - beqz a0, exit_without_context_switch /* Don't switch context if incrementing tick didn't unblock a task. */ + bnez a0, mtimer_context_switch + portcontextRESTORE_TIMER_CALLER_CONTEXT +mtimer_context_switch: + portcontextSAVE_DEFERRED_TASK_STATE call vTaskSwitchContext -exit_without_context_switch: portcontextRESTORE_CONTEXT /*-----------------------------------------------------------*/ diff --git a/portable/GCC/RISC-V/portContext.h b/portable/GCC/RISC-V/portContext.h index 0ccca69a3cf..a0642135d63 100644 --- a/portable/GCC/RISC-V/portContext.h +++ b/portable/GCC/RISC-V/portContext.h @@ -64,6 +64,10 @@ #define portCRITICAL_NESTING_OFFSET 30 #endif +/* Keep the ISR stack aligned to the RISC-V ABI while reserving metadata used + * by the machine-timer fast path. */ +#define portISR_STACK_METADATA_SIZE 16 + #if ( configENABLE_FPU == 1 ) /* Bit [14:13] in the mstatus encode the status of FPU state which is one of * the following values: @@ -379,6 +383,116 @@ store_x sp, 0 ( t0 ) /* Write sp to first TCB member. */ .endm /*-----------------------------------------------------------*/ + .macro portcontextSAVE_TIMER_CALLER_CONTEXT +addi sp, sp, -portCONTEXT_SIZE +portcontextSAVE_CALLER_REGISTERS sp + +/* Keep the fixed integer frame base available after variable-length optional + * contexts have been saved by recording it in per-hart ISR stack metadata. */ +load_x t0, xISRStackTop +addi t0, t0, -portISR_STACK_METADATA_SIZE +store_x sp, 0( t0 ) + +#if( configENABLE_FPU == 1 ) + csrr t0, mstatus + srl t1, t0, MSTATUS_FS_OFFSET + andi t1, t1, 3 + addi t2, x0, 3 + bne t1, t2, 7f + portcontexSAVE_FPU_CONTEXT +7: +#endif + +#if( configENABLE_VPU == 1 ) + csrr t0, mstatus + srl t1, t0, MSTATUS_VS_OFFSET + andi t1, t1, 3 + addi t2, x0, 3 + bne t1, t2, 8f + portcontexSAVE_VPU_CONTEXT +8: +#endif + +csrr t0, mstatus +store_x t0, 1 * portWORD_SIZE( sp ) +portasmSAVE_ADDITIONAL_REGISTERS + +#if( configENABLE_FPU == 1 ) + srl t1, t0, MSTATUS_FS_OFFSET + andi t1, t1, 3 + addi t2, x0, 3 + bne t1, t2, 9f + li t1, ~MSTATUS_FS_MASK + and t0, t0, t1 + li t1, MSTATUS_FS_CLEAN + or t0, t0, t1 + csrw mstatus, t0 +9: +#endif + +#if( configENABLE_VPU == 1 ) + srl t1, t0, MSTATUS_VS_OFFSET + andi t1, t1, 3 + addi t2, x0, 3 + bne t1, t2, 10f + li t1, ~MSTATUS_VS_MASK + and t0, t0, t1 + li t1, MSTATUS_VS_CLEAN + or t0, t0, t1 + csrw mstatus, t0 +10: +#endif + +csrr t0, mepc +store_x t0, 0 * portWORD_SIZE( sp ) +load_x t0, pxCurrentTCB +store_x sp, 0( t0 ) +load_x sp, xISRStackTop +addi sp, sp, -portISR_STACK_METADATA_SIZE + .endm + + .macro portcontextSAVE_DEFERRED_TASK_STATE +load_x t1, 0( sp ) +portcontextSAVE_CALLEE_REGISTERS t1 +load_x t0, xCriticalNesting +store_x t0, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( t1 ) + .endm + + .macro portcontextRESTORE_TIMER_CALLER_CONTEXT +load_x t1, pxCurrentTCB +load_x sp, 0( t1 ) +load_x t0, 0 * portWORD_SIZE( sp ) +csrw mepc, t0 + +portasmRESTORE_ADDITIONAL_REGISTERS + +load_x t3, 1 * portWORD_SIZE( sp ) +csrw mstatus, t3 + +#if( configENABLE_VPU == 1 ) + srl t1, t3, MSTATUS_VS_OFFSET + andi t1, t1, 3 + addi t2, x0, 3 + bne t1, t2, 11f + portcontextRESTORE_VPU_CONTEXT +11: +#endif + +#if( configENABLE_FPU == 1 ) + srl t1, t3, MSTATUS_FS_OFFSET + andi t1, t1, 3 + addi t2, x0, 3 + bne t1, t2, 12f + portcontextRESTORE_FPU_CONTEXT +12: +#endif + +portcontextRESTORE_CALLER_REGISTERS sp +addi sp, sp, portCONTEXT_SIZE +mret + .endm +/*-----------------------------------------------------------*/ + .macro portcontextSAVE_EXCEPTION_CONTEXT portcontextSAVE_CONTEXT_INTERNAL csrr a0, mcause