Question: How are pending interrupts undelegated to S-mode handled when mstatus.SIE is unset?
Sherwin-Yong opened this issue · 5 comments
In this issue, https://github.com/riscv/riscv-isa-manual/issues/1393, mentioned that
The global interrupt enables, like mstatus.SIE, have no interaction with delegation. Delegation occurs anyway. Since interrupts are globally disabled for S-mode, any interrupts delegated to S-mode simply won't be taken while in S-mode.
In the spec, https://github.com/riscv/riscv-isa-manual/blob/main/src/machine.adoc, said that
When a hart is executing in privilege mode x, interrupts are globally enabled when xIE=1 and globally disabled when xIE=0. Interrupts for lower-privilege modes, w<x, are always globally disabled regardless of the setting of any global wIE bit for the lower-privilege mode. Interrupts for higher-privilege modes, y>x, are always globally enabled regardless of the setting of the global yIE bit for the higher-privilege mode. Higher-privilege-level code can use separate per-interrupt enable bits to disable selected higher-privilege-mode interrupts before ceding control to a lower-privilege mode.
But in Spike code, https://github.com/riscv-software-src/riscv-isa-sim/blob/1b1a333763eae2e74dbf38b39d9adab39c4bed7c/riscv/processor.cc#L664
void processor_t::take_interrupt(reg_t pending_interrupts)
{
// Do nothing if no pending interrupts
if (!pending_interrupts) {
return;
}
// Exit WFI if there are any pending interrupts
in_wfi = false;
// M-ints have higher priority over HS-ints and VS-ints
const reg_t mie = get_field(state.mstatus->read(), MSTATUS_MIE);
const reg_t m_enabled = state.prv < PRV_M || (state.prv == PRV_M && mie);
reg_t enabled_interrupts = pending_interrupts & ~state.mideleg->read() & -m_enabled;
...
The pending_interrupts
masked by state.mideleg
, controlled by the m_enabled
.
It seems that interrupts undelegated to S-mode controlled by the mstatus.MIE
, not the mstatus.SIE
.
Pending supervisor interrupts undelegated to S-mode are not controlled by the mstatus.SIE
?
These makes confusion about this situation:
- disable the
mstatus.SIE
, enable themstatus.MIE
- disable interrupt delegation for supervisor software interrupts
mideleg = 0x0
- mark a supervisor software interrupt to be pending
mip = 0x2
What should happen?
If an interrupt is not delegated to S-mode, then SIE is irrelevant. Only MIE is relevant.
If an interrupt is not delegated to S-mode, then SIE is irrelevant. Only MIE is relevant.
Thanks for reply.
If an interrupt is not delegated to S-mode, the current executing privilege mode is also irrelevant?
All interrupts which are not delegated to S-mode, use the MIE as the global interrupt-enable bit, ignoring the current privilege mode.
Is that right?
If a pending-and-enabled interrupt is not delegated to S-mode, there are two cases:
- If the mode is M, the interrupt will be taken if
mstatus
.MIE=1 - If the mode is less than M, the interrupt will be taken regardless of
mstatus
.MIE.
Thanks a lot, that answers my question.
You're welcome!