Browse Source

Respect interrupt priorities even when not delegated

The spec says that e.g. MEI takes priority over SEI.  We got this right in
the common case that SEI is delegated to S-mode, but we reversed it in the
undelegated case.

The destination privilege was correct, so this wasn't much of a problem,
but it is technically noncompliant.

Resolves #288
static-link
Andrew Waterman 7 years ago
parent
commit
496c59d064
  1. 22
      riscv/processor.cc

22
riscv/processor.cc

@ -191,15 +191,19 @@ void processor_t::take_interrupt(reg_t pending_interrupts)
// nonstandard interrupts have highest priority
if (enabled_interrupts >> IRQ_M_EXT)
enabled_interrupts = enabled_interrupts >> IRQ_M_EXT << IRQ_M_EXT;
// external interrupts have next-highest priority
else if (enabled_interrupts & (MIP_MEIP | MIP_SEIP))
enabled_interrupts = enabled_interrupts & (MIP_MEIP | MIP_SEIP);
// software interrupts have next-highest priority
else if (enabled_interrupts & (MIP_MSIP | MIP_SSIP))
enabled_interrupts = enabled_interrupts & (MIP_MSIP | MIP_SSIP);
// timer interrupts have next-highest priority
else if (enabled_interrupts & (MIP_MTIP | MIP_STIP))
enabled_interrupts = enabled_interrupts & (MIP_MTIP | MIP_STIP);
// standard interrupt priority is MEI, MSI, MTI, SEI, SSI, STI
else if (enabled_interrupts & MIP_MEIP)
enabled_interrupts = MIP_MEIP;
else if (enabled_interrupts & MIP_MSIP)
enabled_interrupts = MIP_MSIP;
else if (enabled_interrupts & MIP_MTIP)
enabled_interrupts = MIP_MTIP;
else if (enabled_interrupts & MIP_SEIP)
enabled_interrupts = MIP_SEIP;
else if (enabled_interrupts & MIP_SSIP)
enabled_interrupts = MIP_SSIP;
else if (enabled_interrupts & MIP_STIP)
enabled_interrupts = MIP_STIP;
else
abort();

Loading…
Cancel
Save