ROOT-CAUSE ANALYSIS · ~90M-CYCLE OS BOOT CASE STUDY
The mip CSR Read-Modify-Write Livelock
Per RISC-V Privileged Spec §3.1.9, reading mip[9] (SEIP) returns mip_q[9] | irq_seip_i, whereas CSRRS/CSRRC read-modify-write (RMW) operations on mip (0x344) must source only the software-writable mip_q[9] flip-flop.
In the earlier RTL, feeding mip_val directly into the RMW ALU caused a subtle livelock under Linux: while PLIC UART (irq_seip_i) was active, SBI firmware executing csrc mip, (1 << 5) to clear STIP inadvertently read irq_seip_i = 1 and wrote 1 back into the mip_q[9] latch. Even after PLIC cleared the interrupt, SEIP stayed permanently latched at 1, trapping the kernel inside an infinite plic_handle_irq loop.
wire [63:0] rmw_csr_val = (p0_sys_csr_addr_i == 12'h344)
? {mip_val[63:10], mip_q[9], mip_val[8:0]}
: old_csr_val;