From 95ee54728395b038bfdb85e31cebf072be583065 Mon Sep 17 00:00:00 2001 From: good-circle Date: Thu, 17 Sep 2026 17:10:03 +0800 Subject: [PATCH] CSR: write tval according to the trap target privilege Page-fault and misaligned traps wrote mtval/stval from the privilege at the fault, so an S-mode exception that was not delegated still updated stval. Write the register of the privilege that takes the trap: medeleg(cause) && privilegeMode < M selects stval, otherwise mtval. --- src/main/scala/nutcore/backend/fu/CSR.scala | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/main/scala/nutcore/backend/fu/CSR.scala b/src/main/scala/nutcore/backend/fu/CSR.scala index cd90c1c0..30ae1a53 100644 --- a/src/main/scala/nutcore/backend/fu/CSR.scala +++ b/src/main/scala/nutcore/backend/fu/CSR.scala @@ -584,18 +584,27 @@ class CSR(implicit val p: NutCoreConfig) extends NutCoreModule with HasCSRConst{ when(hasInstrPageFault || hasLoadPageFault || hasStorePageFault){ val tval = Mux(hasInstrPageFault, Mux(io.cfIn.crossPageIPFFix, SignExt((io.cfIn.pc + 2.U)(VAddrBits-1,0), XLEN), SignExt(io.cfIn.pc(VAddrBits-1,0), XLEN)), SignExt(dmemPagefaultAddr, XLEN)) - when(privilegeMode === ModeM){ - mtval := tval - }.otherwise{ + val pfCause = Mux(hasInstrPageFault, instrPageFault.U, Mux(hasLoadPageFault, loadPageFault.U, storePageFault.U)) + val pfDelegS = medeleg(pfCause) && (privilegeMode < ModeM) + when(pfDelegS){ stval := tval + }.otherwise{ + mtval := tval } Debug("[PF] %d: ipf %b tval %x := addr %x pc %x privilegeMode %x\n", GTimer(), hasInstrPageFault, tval, SignExt(dmemPagefaultAddr, XLEN), io.cfIn.pc, privilegeMode) } when(hasLoadAddrMisaligned || hasStoreAddrMisaligned) { - mtval := SignExt(dmemAddrMisalignedAddr, XLEN) - Debug("[ML] %d: addr %x pc %x privilegeMode %x\n", GTimer(), SignExt(dmemAddrMisalignedAddr, XLEN), io.cfIn.pc, privilegeMode) + val misalignTval = SignExt(dmemAddrMisalignedAddr, XLEN) + val maCause = Mux(hasLoadAddrMisaligned, loadAddrMisaligned.U, storeAddrMisaligned.U) + val maDelegS = medeleg(maCause) && (privilegeMode < ModeM) + when(maDelegS){ + stval := misalignTval + }.otherwise{ + mtval := misalignTval + } + Debug("[ML] %d: addr %x pc %x privilegeMode %x\n", GTimer(), misalignTval, io.cfIn.pc, privilegeMode) } // Exception and Intr