A base-architecture NMI (ch. II·3) clobbers mepc and mcause — land one inside a trap handler and the interrupted context is gone. Smrnmi smrnmi Resumable NMIs: parallel save set mnscratch/mnepc/mncause/mnstatus (MNPP/MNPV/MNPELP/NMIE) + MNRET. RNMI inputs outrank everything and ignore MIE; NMIE resets 0, is software-settable but never clearable (no nesting); NMIE=0 disables all interrupts, suppresses MPRV, and redirects M-mode exceptions to a separate RNMI exception vector. defined in ch. II·8 — open in glossary gives NMIs their own save set and return instruction, making hardware-error handling resumable.
The parallel state: mnscratch (0x740), mnepc (0x741 — same WARL
/bit-masking rules as mepc, including for MNRET’s implicit read),
mncause (0x742 — MSB set + cause code for interrupts, or MSB clear +
exception code when delivering an Smdbltrp double trap), and mnstatus:
mnstatus (0x744) — Figure 9
Operation
| What happens | |
|---|---|
| Signal | rnmi inputs to the hart: higher priority than every interrupt/exception, immune to mstatus.MIE |
| Entry | mnepc ← PC, mncause ← type, MNPP/MNPV ← context, NMIE ← 0; jump to the implementation-defined RNMI interrupt handler in M-mode |
| Fault inside the window | Exception in M-mode with NMIE=0 → normal actions but PC ← the separate RNMI EXCEPTION handler address |
| Return | MNRET (M-only): PC ← mnepc, mode ← MNPP/MNPV, NMIE ← 1; MPRV ← 0 if leaving M; ELP ← yLPE ∧ MNPELP (Zicfilp) |
| Non-interaction | MRET/SRET neither depend on nor modify NMIE; WFI treats NMIE as a global enable (i.e., unaffected by it) |
Hardware Designer Notes
Think of Smrnmi as a two-entry shadow of your trap unit: four CSRs, two vectors, one return instruction. It becomes load-bearing when you add RAS features (ECC machine-check reporting) or Smdbltrp — for a v1 Linux core it’s an optional stub with mnstatus.NMIE the only bit DV must remember resets to zero.
Minimal Linux-boot hart MUST
- Give rnmi inputs priority over everything, unmaskable by MIE
- Reset NMIE to 0 and make it set-only from software
- Redirect M-mode exceptions to the RNMI exception vector while NMIE=0
- Suppress MPRV effects while NMIE=0
MAY simplify / trap-and-emulate
- Point the RNMI exception vector at mtvec
- Report all RNMI causes as 0 (undistinguished) in mncause
- Skip Smrnmi entirely on a first Linux core — base NMIs (or none) are still conformant
Check yourself — resumable NMIs
1.Why can't a base-architecture NMI generally resume the interrupted work?
2.Software wants to briefly mask RNMIs around a critical section. Can it?
3.An exception occurs in M-mode while mnstatus.NMIE=0 (inside the RNMI handler). What happens?
4.What does MNRET restore and set?