P28 gives the P27 trap core something asynchronous to do. It adds a machine
timer source, a top-level external interrupt input, mie/mip, and the
mstatus.MIE / mstatus.MPIE stack needed for interrupt entry and mret.
Status: RTL pass. Directed machine-mode interrupt tests pass, and the scoped ACT4/Sail
rv32i/Ibatch still passes withPASS=39 FAIL=0 NOT RUN=0. Hardening and official privileged tests are NOT RUN for this rung.
The Result
Run it:
make -C projects/28_rv32i_machine_interrupts/test
Result: PASS
| test | result |
|---|---|
| CSR read/write and immediate set | PASS |
ecall trap and mret resume | PASS |
illegal-instruction trap and mret resume | PASS |
ebreak trap and mret resume | PASS |
| misaligned load trap | PASS |
| misaligned store trap | PASS |
| masked timer interrupt stays pending | PASS |
timer interrupt and mret resume | PASS |
| external interrupt handler | PASS |
ACT4/Sail rv32i/I: PASS=39 FAIL=0 NOT RUN=0
Harden status: NOT RUN
What Changed
The new interrupt substrate is intentionally small:
| piece | behavior |
|---|---|
mie | writable MTIE and MEIE bits |
mip | read-only MTIP and MEIP pending bits |
mstatus | MIE clears on trap entry, old MIE saves into MPIE; mret restores it |
| timer | local 32-bit counter plus compare register |
| external IRQ | one synchronized top-level interrupt input |
| trap cause | machine timer 0x8000_0007, machine external 0x8000_000b |
The timer controls live at custom CSR addresses 0x7c0 and 0x7c1. That is
a teaching shortcut, not a standard RISC-V platform model. In real systems,
mtime and mtimecmp are normally memory-mapped registers. P29 should move
this toward a normal MMIO map.
What This Proves
P27 proved that software can handle exceptions. P28 proves that hardware event sources can enter the same trap path:
- a pending timer interrupt remains visible in
mipwhile globally masked; - enabling
mstatus.MIEandmie.MTIEvectors tomtvec; - trap entry records the interrupt
mcause; mstatusstacksMIEintoMPIE;- a handler can disable the timer, rewrite
mepc, and return withmret; - a top-level external IRQ can trigger the machine external interrupt path.
The scoped ACT4/Sail run matters because these changes touch fetch and trap
entry. The base integer batch still passes: PASS=39 FAIL=0 NOT RUN=0.
Scope
Still unsupported: supervisor mode, vectored mtvec, delegation CSRs, satp,
an MMU, standard memory-mapped CLINT-style timer registers, nested interrupt
policy beyond the simple MIE/MPIE stack, and official privileged
architecture tests.
So the honest label is narrow: PASS for directed interrupt RTL tests,
PASS for scoped ACT4/Sail rv32i/I, NOT RUN for hardening, and NOT RUN
for privileged compliance.