I'm writing an operating system (supervisor mode) in Rust for RISC-V in my free time. I'm trying to handle trap now.
I'm trapping correctly in direct mode, but when executing the sret
instruction, I'm going directly back to my trap handler, without going back to the address stored in sepc
.
Here my trap handler code (yes, I do not save any register for now):
csrr a0, sepc
csrr a1, scause
addi a0, a0, 4
csrw sepc, a0
sret
My reasoning is as follows:
sepc
contain the address of where the trap occurred so we add it +4 to jump to the next one when we go back.- If I did any real work I would need to read
scause
so put the value ina1
. sret
should get back to the code running before the trap.
After sret
when we immediately go back to the trap handler, scause
value is the same as the first time.
I'm writing to 0x0 to test my trap_handler and scause
value is 7 which makes sense (see Table 4.2 - page 56).
What's going on?