Reading this: groups.riscv.org, I'm not sure all the interruptions are delegated.
Traps never transition from a more-privileged mode to a less-privileged mode. For example, if M-mode has delegated illegal instruction exceptions to S-mode, and M-mode software later executes an illegal instruction, the trap is taken in M-mode, rather than being delegated to S-mode.
What's the rationale to support delegating M-mode interrupts in mideleg? Wouldn't it be a moot point delegating e.g., M-mode external interrupts to S mode, since if it's an M-mode interrupt, only M-mode can handle it? I do notice that the mideleg register is WARL, and indeed Qemu always hard-wires the M-mode interrupt delegation bits in mideleg to 0. Would real hardware behave the same way?
Yeah, you’ve effectively answered your own question: implementations generally hard-wire those bits to 0, and so there is no support in practice for delegating those interrupts.
Reading more attentively kernelvec.S
, start.c
and trap.c
, we can see that :
- Only Machine timer is set
- Machine timer handler generates a S interruption
- The
devintr()
do not handle Software timer interrupt (code 0x8000 0000 000 0005
, see scause
definition, page 55 from The RISC-V Instruction Set Manual)
I think that the OS wouldn't work if the mtvec
was not called.
So mtvec
is well called, but the instruction w_mideleg(0xffff);
could be replaced by w_mideleg(0xff0f);
with the same effect I think.