Skip to content

Defer RISC-V callee-saved registers on no-switch timer interrupts - #1482

Open
mingshun-zhou wants to merge 3 commits into
FreeRTOS:mainfrom
mingshun-zhou:feat/riscv-mtimer-deferred-callee-save
Open

mingshun-zhou wants to merge 3 commits into
FreeRTOS:mainfrom
mingshun-zhou:feat/riscv-mtimer-deferred-callee-save

Conversation

@mingshun-zhou

@mingshun-zhou mingshun-zhou commented Aug 26, 2026 •

Copy link
Copy Markdown

Description

The dedicated RISC-V machine-timer handler currently saves and restores the
complete integer context even when xTaskIncrementTick() returns pdFALSE.
The called C code must preserve s0-s11 according to the RISC-V ABI, so those
registers do not need to be written to the task stack when execution returns to
the interrupted task.

This change keeps the existing task-frame layout and optional-context behavior,
but splits integer context handling into caller-saved and callee-saved parts:

  1. Save caller-saved registers on machine-timer entry.
  2. If no context switch is required, restore only those registers and return.
  3. If a context switch is required, save s0-s11 into their reserved frame
    slots before calling vTaskSwitchContext().

FPU, VPU, and chip-specific additional contexts retain their existing save and
restore semantics. Other interrupt, exception, unified-trap, and yield paths
continue to save the complete context.

For RV64, the no-switch path avoids 12 stores and 12 loads, reducing stack
traffic by 192 bytes per tick.

Test Steps

A standalone QEMU virt M-mode test uses different sentinel values in
s0-s11 for two equal-priority tasks and checks them after 2,000 timer ticks.
The following configurations passed against the current main branch:

  • no switch
  • task switch on every tick
  • FPU, with and without task switching
  • VPU, with and without task switching
  • synthetic chip-specific additional context
  • FPU + VPU + additional context + task switching

The modified portASM.S was also assembled successfully for RV32 (ilp32)
and RV64 (lp64d). Disassembly confirms that the pdFALSE path contains no
s0-s11 stores or loads and that the pdTRUE path stores all twelve registers
before vTaskSwitchContext().

The same implementation was previously validated on a JH7110/U74 in M-mode:

  • baseline and optimized single-task and two-task tests passed 1,000,000 ticks
  • 10,000 no-switch entry samples: median 59 -> 50 cycles; mean 155.281 ->
    144.746 cycles
  • P99 and maximum did not improve

Checklist:

  • I have tested my changes. No regression in existing tests.
  • I have modified and/or added unit-tests to cover the code changes in this Pull Request. (The standalone architecture test is maintained outside this kernel-only repository.)

Related Issue

Closes #1464

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Signed-off-by: zhouzhou_code <2031145985@qq.com>
Signed-off-by: zhouzhou_code <2031145985@qq.com>
@sonarqubecloud

Copy link
Copy Markdown

@mingshun-zhou
mingshun-zhou marked this pull request as ready for review August 26, 2026 06:38
@mingshun-zhou

Copy link
Copy Markdown
Author

Hi maintainers, just a gentle follow-up on this focused RISC-V timer-path optimization. The change has been validated on both QEMU and JH7110 hardware, and I am happy to rebase or adjust the approach if needed. Would someone be available to take a look?

@mingshun-zhou

Copy link
Copy Markdown
Author

@aggarg, thank you again for offering to take a look in the FreeRTOS forum. I wanted to follow up here in case this PR needs to be routed to another RISC-V reviewer. Please let me know if you would like me to rebase, add any tests, or adjust the approach.

@aggarg

aggarg commented Nov 12, 2026

Copy link
Copy Markdown
Member

@mingshun-zhou Apologies for missing it. I will do it soon and get back if I need anything from you. Apologies again!

@sonarqubecloud

Copy link
Copy Markdown

@mingshun-zhou

Copy link
Copy Markdown
Author

No worries at all — thanks for taking a look and updating the branch! I’ll keep an eye out for any feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] Defer RISC-V callee-saved register handling on no-switch timer interrupts

2 participants