Context switch on RISC-V

Hi, I am writing a context switch example and I want to know if all the registers need to be saved when switching between tasks or not?

It depends on your design, usually you should save all callee-saved register, you can find more details in linux :stuck_out_tongue:

1 Like

If it is synchronous, i.e. a syscall, then you save the saved registers along with ra and sp. If it is asynchronous, i.e. an exception, then you save all registers except x0. In the linux kernel, you can see this in
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/riscv/kernel/entry.S?h=v5.7-rc5
where save_context is for an exception and switch_to is for a context switch. The linux kernel doesn’t use FP registers, so it doesn’t need to save them when it is entered. They are handled separately for a context switch.

You can also see examples in glibc for the swapcontext, getcontext, and makecontext library functions.
https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/riscv/swapcontext.S;h=53480a085c3418b5ba84ba115785f40f3c19ad89;hb=HEAD
getcontext and makecontext are in different files in the same dir.

2 Likes

Another example of context switch of tasks:

1 Like

Yes, you have to manually save and restore all registers, and handle all interrupts/exceptions details, including dispatching to the handlers.

The RISC-V architecture is not optimised for context switches, like, for example the Cortex-M architecture, which directly calls C/C++ handlers, and delegates the context switching to a single PendSV handler:

1 Like