2

In start.c/timerinit(), timervec be written into mtvec. But I don't know why this is needed? As before timerinit(), all interrupts & exceptions are already delegated to supervisor-mode via code:

  w_medeleg(0xffff);
  w_mideleg(0xffff);
  w_sie(r_sie() | SIE_SEIE | SIE_STIE | SIE_SSIE);

Base on my understanding handler in mtvec will not be invoked.

Mathieu
  • 8,840
  • 7
  • 32
  • 45
Shaq Xu
  • 21
  • 1

1 Answers1

1

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.

Mathieu
  • 8,840
  • 7
  • 32
  • 45