riscv/riscv-isa-manual

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:

  1. disable the mstatus.SIE, enable the mstatus.MIE
  2. disable interrupt delegation for supervisor software interrupts mideleg = 0x0
  3. 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!