perf(riscv): defer callee save on no-switch timer IRQ

Signed-off-by: zhouzhou_code <2031145985@qq.com>
This commit is contained in:
zhouzhou_code 2026-08-26 01:57:40 +08:00
parent 8191eb1eda
commit ef308b3f7c
2 changed files with 120 additions and 3 deletions

View file

@ -338,13 +338,16 @@ freertos_risc_v_interrupt_handler:
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
.section .text.freertos_risc_v_mtimer_interrupt_handler .section .text.freertos_risc_v_mtimer_interrupt_handler
.align 2
freertos_risc_v_mtimer_interrupt_handler: freertos_risc_v_mtimer_interrupt_handler:
portcontextSAVE_INTERRUPT_CONTEXT portcontextSAVE_TIMER_CALLER_CONTEXT
portUPDATE_MTIMER_COMPARE_REGISTER portUPDATE_MTIMER_COMPARE_REGISTER
call xTaskIncrementTick 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 call vTaskSwitchContext
exit_without_context_switch:
portcontextRESTORE_CONTEXT portcontextRESTORE_CONTEXT
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View file

@ -64,6 +64,10 @@
#define portCRITICAL_NESTING_OFFSET 30 #define portCRITICAL_NESTING_OFFSET 30
#endif #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 ) #if ( configENABLE_FPU == 1 )
/* Bit [14:13] in the mstatus encode the status of FPU state which is one of /* Bit [14:13] in the mstatus encode the status of FPU state which is one of
* the following values: * the following values:
@ -379,6 +383,116 @@ store_x sp, 0 ( t0 ) /* Write sp to first TCB member. */
.endm .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 .macro portcontextSAVE_EXCEPTION_CONTEXT
portcontextSAVE_CONTEXT_INTERNAL portcontextSAVE_CONTEXT_INTERNAL
csrr a0, mcause csrr a0, mcause