From a751b11ae755be85ef2b74c2951705b349cc1eb2 Mon Sep 17 00:00:00 2001 From: chengguanghui Date: Mon, 11 Nov 2024 18:19:27 +0800 Subject: [PATCH] fix(dcsr): debug support critical error state * support nmip, cetrig, extcause fileds in dcsr. * critical error state enter dmode when dcsr.cetrig assert. --- .../scala/xiangshan/backend/Backend.scala | 10 +++-- .../scala/xiangshan/backend/CtrlBlock.scala | 3 +- src/main/scala/xiangshan/backend/fu/CSR.scala | 1 + .../fu/NewCSR/CSREvents/TrapEntryDEvent.scala | 39 +++++++++--------- .../xiangshan/backend/fu/NewCSR/Debug.scala | 22 ++++++---- .../backend/fu/NewCSR/DebugLevel.scala | 11 ++++- .../xiangshan/backend/fu/NewCSR/NewCSR.scala | 40 ++++++++++++------- .../xiangshan/backend/fu/wrapper/CSR.scala | 3 ++ .../scala/xiangshan/backend/rob/Rob.scala | 7 ++-- .../xiangshan/backend/rob/RobBundles.scala | 1 + 10 files changed, 87 insertions(+), 50 deletions(-) diff --git a/src/main/scala/xiangshan/backend/Backend.scala b/src/main/scala/xiangshan/backend/Backend.scala index b0cad552de..8f777af9e0 100644 --- a/src/main/scala/xiangshan/backend/Backend.scala +++ b/src/main/scala/xiangshan/backend/Backend.scala @@ -232,6 +232,8 @@ class BackendInlinedImp(override val wrapper: BackendInlined)(implicit p: Parame private val vlFromVfIsZero = vfExuBlock.io.vlIsZero.get private val vlFromVfIsVlmax = vfExuBlock.io.vlIsVlmax.get + private val backendCriticalError = Wire(Bool()) + ctrlBlock.io.intIQValidNumVec := intScheduler.io.intIQValidNumVec ctrlBlock.io.fpIQValidNumVec := fpScheduler.io.fpIQValidNumVec ctrlBlock.io.fromTop.hartId := io.fromTop.hartId @@ -247,6 +249,7 @@ class BackendInlinedImp(override val wrapper: BackendInlined)(implicit p: Parame ctrlBlock.io.robio.csr.trapTarget := intExuBlock.io.csrio.get.trapTarget ctrlBlock.io.robio.csr.isXRet := intExuBlock.io.csrio.get.isXRet ctrlBlock.io.robio.csr.wfiEvent := intExuBlock.io.csrio.get.wfi_event + ctrlBlock.io.robio.csr.criticalErrorState := intExuBlock.io.csrio.get.criticalErrorState ctrlBlock.io.robio.lsq <> io.mem.robLsqIO ctrlBlock.io.robio.lsTopdownInfo <> io.mem.lsTopdownInfo ctrlBlock.io.robio.debug_ls <> io.mem.debugLS @@ -454,6 +457,7 @@ class BackendInlinedImp(override val wrapper: BackendInlined)(implicit p: Parame csrin.clintTime.bits := RegEnable(io.fromTop.clintTime.bits, io.fromTop.clintTime.valid) csrin.trapInstInfo := ctrlBlock.io.toCSR.trapInstInfo csrin.fromVecExcpMod.busy := vecExcpMod.o.status.busy + csrin.criticalErrorState := backendCriticalError private val csrio = intExuBlock.io.csrio.get csrio.hartId := io.fromTop.hartId @@ -820,11 +824,9 @@ class BackendInlinedImp(override val wrapper: BackendInlined)(implicit p: Parame } // expand to collect frontend/memblock/L2 critical errors - val backendCriticalError = criticalErrors.map(_._2).reduce(_ || _) - - ctrlBlock.io.robio.criticalError := backendCriticalError - io.toTop.cpuCriticalError := backendCriticalError + backendCriticalError := criticalErrors.map(_._2).reduce(_ || _) + io.toTop.cpuCriticalError := csrio.criticalErrorState } class BackendMemIO(implicit p: Parameters, params: BackendParams) extends XSBundle { diff --git a/src/main/scala/xiangshan/backend/CtrlBlock.scala b/src/main/scala/xiangshan/backend/CtrlBlock.scala index d75b8712c6..1c8202315e 100644 --- a/src/main/scala/xiangshan/backend/CtrlBlock.scala +++ b/src/main/scala/xiangshan/backend/CtrlBlock.scala @@ -617,7 +617,7 @@ class CtrlBlockImp( rob.io.debug_ls := io.robio.debug_ls rob.io.debugHeadLsIssue := io.robio.robHeadLsIssue rob.io.lsTopdownInfo := io.robio.lsTopdownInfo - rob.io.criticalError := io.robio.criticalError + rob.io.csr.criticalErrorState := io.robio.csr.criticalErrorState rob.io.debugEnqLsq := io.debugEnqLsq io.robio.robDeqPtr := rob.io.robDeqPtr @@ -731,7 +731,6 @@ class CtrlBlockIO()(implicit p: Parameters, params: BackendParams) extends XSBun val vtype = Output(ValidIO(VType())) val hasVsetvl = Output(Bool()) } - val criticalError = Input(Bool()) // store event difftest information val storeDebugInfo = Vec(EnsbufferWidth, new Bundle { diff --git a/src/main/scala/xiangshan/backend/fu/CSR.scala b/src/main/scala/xiangshan/backend/fu/CSR.scala index c828166f97..4554cbddee 100644 --- a/src/main/scala/xiangshan/backend/fu/CSR.scala +++ b/src/main/scala/xiangshan/backend/fu/CSR.scala @@ -85,6 +85,7 @@ class CSRFileIO(implicit p: Parameters) extends XSBundle { val hartId = Input(UInt(hartIdLen.W)) // output (for func === CSROpType.jmp) val perf = Input(new PerfCounterIO) + val criticalErrorState = Output(Bool()) val isPerfCnt = Output(Bool()) // to FPU val fpu = Flipped(new FpuCsrIO) diff --git a/src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/TrapEntryDEvent.scala b/src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/TrapEntryDEvent.scala index 9f0c528845..e8dee70914 100644 --- a/src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/TrapEntryDEvent.scala +++ b/src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/TrapEntryDEvent.scala @@ -22,13 +22,14 @@ class TrapEntryDEventOutput extends Bundle with EventUpdatePrivStateOutput with } class TrapEntryDEventInput(implicit override val p: Parameters) extends TrapEntryEventInput{ - val hasTrap = Input(Bool()) - val debugMode = Input(Bool()) - val hasDebugIntr = Input(Bool()) - val triggerEnterDebugMode = Input(Bool()) - val hasDebugEbreakException = Input(Bool()) - val hasSingleStep = Input(Bool()) - val breakPoint = Input(Bool()) + val hasTrap = Input(Bool()) + val debugMode = Input(Bool()) + val hasDebugIntr = Input(Bool()) + val triggerEnterDebugMode = Input(Bool()) + val hasDebugEbreakException = Input(Bool()) + val hasSingleStep = Input(Bool()) + val breakPoint = Input(Bool()) + val criticalErrorStateEnterDebug = Input(Bool()) } class TrapEntryDEventModule(implicit val p: Parameters) extends Module with CSREventBase with DebugMMIO { @@ -41,20 +42,22 @@ class TrapEntryDEventModule(implicit val p: Parameters) extends Module with CSRE private val vsatp = current.vsatp private val hgatp = current.hgatp - private val hasTrap = in.hasTrap - private val debugMode = in.debugMode - private val hasDebugIntr = in.hasDebugIntr - private val breakPoint = in.breakPoint - private val triggerEnterDebugMode = in.triggerEnterDebugMode - private val hasDebugEbreakException = in.hasDebugEbreakException - private val hasSingleStep = in.hasSingleStep + private val hasTrap = in.hasTrap + private val debugMode = in.debugMode + private val hasDebugIntr = in.hasDebugIntr + private val breakPoint = in.breakPoint + private val triggerEnterDebugMode = in.triggerEnterDebugMode + private val hasDebugEbreakException = in.hasDebugEbreakException + private val hasSingleStep = in.hasSingleStep + private val criticalErrorStateEnterDebug = in.criticalErrorStateEnterDebug private val hasExceptionInDmode = debugMode && hasTrap val causeIntr = DcsrCause.Haltreq.asUInt - val causeExp = MuxCase(0.U, Seq( - triggerEnterDebugMode -> DcsrCause.Trigger.asUInt, - hasDebugEbreakException -> DcsrCause.Ebreak.asUInt, - hasSingleStep -> DcsrCause.Step.asUInt + val causeExp = MuxCase(DcsrCause.None.asUInt, Seq( + criticalErrorStateEnterDebug -> DcsrCause.Other.asUInt, + triggerEnterDebugMode -> DcsrCause.Trigger.asUInt, + hasDebugEbreakException -> DcsrCause.Ebreak.asUInt, + hasSingleStep -> DcsrCause.Step.asUInt )) private val trapPC = genTrapVA( diff --git a/src/main/scala/xiangshan/backend/fu/NewCSR/Debug.scala b/src/main/scala/xiangshan/backend/fu/NewCSR/Debug.scala index 5dfa0233ec..8a2e833579 100644 --- a/src/main/scala/xiangshan/backend/fu/NewCSR/Debug.scala +++ b/src/main/scala/xiangshan/backend/fu/NewCSR/Debug.scala @@ -38,6 +38,7 @@ class Debug(implicit val p: Parameters) extends Module with HasXSParameter { * 2. ebreak inst in nonDmode * 3. trigger fire in nonDmode * 4. single step(debug module set dcsr.step before hart resume) + * 5. critical error state(when dcsr.cetrig assert) */ // debug_intr val hasIntr = hasTrap && trapIsInterrupt @@ -68,7 +69,11 @@ class Debug(implicit val p: Parameters) extends Module with HasXSParameter { // debug_exception_single val hasSingleStep = hasExp && singleStep - val hasDebugException = hasDebugEbreakException || triggerEnterDebugMode || hasSingleStep + + // critical error state + val criticalErrorStateEnterDebug = trapInfo.bits.criticalErrorState && dcsr.CETRIG.asBool + + val hasDebugException = hasDebugEbreakException || triggerEnterDebugMode || hasSingleStep || criticalErrorStateEnterDebug val hasDebugTrap = hasDebugException || hasDebugIntr val tselect1H = UIntToOH(tselect.asUInt, TriggerNum).asBools @@ -126,12 +131,13 @@ class Debug(implicit val p: Parameters) extends Module with HasXSParameter { io.out.triggerFrontendChange := frontendTriggerUpdate io.out.newTriggerChainIsLegal := newTriggerChainIsLegal - io.out.hasDebugTrap := hasDebugTrap - io.out.hasDebugIntr := hasDebugIntr - io.out.hasSingleStep := hasSingleStep - io.out.triggerEnterDebugMode := triggerEnterDebugMode - io.out.hasDebugEbreakException := hasDebugEbreakException - io.out.breakPoint := breakPoint + io.out.hasDebugTrap := hasDebugTrap + io.out.hasDebugIntr := hasDebugIntr + io.out.hasSingleStep := hasSingleStep + io.out.triggerEnterDebugMode := triggerEnterDebugMode + io.out.hasDebugEbreakException := hasDebugEbreakException + io.out.breakPoint := breakPoint + io.out.criticalErrorStateEnterDebug := criticalErrorStateEnterDebug } class DebugIO(implicit val p: Parameters) extends Bundle with HasXSParameter { @@ -142,6 +148,7 @@ class DebugIO(implicit val p: Parameters) extends Bundle with HasXSParameter { val isInterrupt = Bool() val singleStep = Bool() val trigger = TriggerAction() + val criticalErrorState = Bool() }) val privState = new PrivState @@ -172,6 +179,7 @@ class DebugIO(implicit val p: Parameters) extends Bundle with HasXSParameter { val triggerEnterDebugMode = Bool() val hasDebugEbreakException = Bool() val breakPoint = Bool() + val criticalErrorStateEnterDebug = Bool() }) } diff --git a/src/main/scala/xiangshan/backend/fu/NewCSR/DebugLevel.scala b/src/main/scala/xiangshan/backend/fu/NewCSR/DebugLevel.scala index 0ecafee823..2c7cb6c056 100644 --- a/src/main/scala/xiangshan/backend/fu/NewCSR/DebugLevel.scala +++ b/src/main/scala/xiangshan/backend/fu/NewCSR/DebugLevel.scala @@ -56,7 +56,11 @@ trait DebugLevel { self: NewCSR => val tinfo = Module(new CSRModule("Tinfo", new TinfoBundle)) .setAddr(CSRs.tinfo) - val dcsr = Module(new CSRModule("Dcsr", new DcsrBundle) with TrapEntryDEventSinkBundle with DretEventSinkBundle) + val dcsr = Module(new CSRModule("Dcsr", new DcsrBundle) with TrapEntryDEventSinkBundle with DretEventSinkBundle with HasNmipBundle { + when(nmip){ + reg.NMIP := nmip + } + }) .setAddr(CSRs.dcsr) val dpc = Module(new CSRModule("Dpc", new Epc) with TrapEntryDEventSinkBundle) @@ -307,6 +311,7 @@ object DcsrCause extends CSREnum with ROApply { val Step = Value(4.U) val Resethaltreq = Value(5.U) val Group = Value(6.U) + val Other = Value(7.U) } trait HasTdataSink { self: CSRModule[_] => @@ -320,6 +325,10 @@ trait HasdebugModeBundle { self: CSRModule[_] => val chainable = IO(Input(Bool())) } +trait HasNmipBundle { self: CSRModule[_] => + val nmip = IO(Input(Bool())) +} + /** * debug Module MMIO Addr */ diff --git a/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala b/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala index 94ccbba45f..b8f23efc9c 100644 --- a/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala +++ b/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala @@ -124,6 +124,7 @@ class NewCSR(implicit val p: Parameters) extends Module val fromTop = Input(new Bundle { val hartId = UInt(hartIdLen.W) val clintTime = Input(ValidIO(UInt(64.W))) + val criticalErrorState = Input(Bool()) }) val in = Flipped(DecoupledIO(new NewCSRInput)) val trapInst = Input(ValidIO(UInt(InstWidth.W))) @@ -189,6 +190,7 @@ class NewCSR(implicit val p: Parameters) extends Module val instrAddrTransType = new AddrTransType // custom val custom = new CSRCustomState + val criticalErrorState = Bool() }) // tlb val tlb = Output(new Bundle { @@ -263,6 +265,9 @@ class NewCSR(implicit val p: Parameters) extends Module val debugModeStopCount = RegNext(debugModeStopCountNext) val unprivCountUpdate = !debugModeStopCount && debugModeStopCountNext + val criticalErrorStateInCSR = Wire(Bool()) + val criticalErrorState = RegEnable(true.B, false.B, io.fromTop.criticalErrorState || criticalErrorStateInCSR) + private val privState = Wire(new PrivState) privState.PRVM := PRVM privState.V := V @@ -356,6 +361,9 @@ class NewCSR(implicit val p: Parameters) extends Module intrMod.io.in.mnstatusNMIE := mnstatus.regOut.NMIE.asBool intrMod.io.in.nmi := nmip.asUInt.orR intrMod.io.in.nmiVec := nmip.asUInt + intrMod.io.in.debugMode := debugMode + intrMod.io.in.debugIntr := debugIntr + intrMod.io.in.dcsr := dcsr.regOut when(intrMod.io.out.nmi && intrMod.io.out.interruptVec.valid) { nmip.NMI_31 := nmip.NMI_31 & !intrMod.io.out.interruptVec.bits(NonMaskableIRNO.NMI_31).asBool @@ -386,6 +394,7 @@ class NewCSR(implicit val p: Parameters) extends Module trapHandleMod.io.in.stvec := stvec.regOut trapHandleMod.io.in.vstvec := vstvec.regOut trapHandleMod.io.in.virtualInterruptIsHvictlInject := virtualInterruptIsHvictlInject + trapHandleMod.io.in.trapInfo.bits.singleStep := hasTrap && !trapIsInterrupt && singleStep val entryPrivState = trapHandleMod.io.out.entryPrivState val entryDebugMode = WireInit(false.B) @@ -688,6 +697,11 @@ class NewCSR(implicit val p: Parameters) extends Module m.unprivCountUpdate := unprivCountUpdate case _ => } + mod match { + case m: HasNmipBundle => + m.nmip := nmip.asUInt.orR + case _ => + } } csrMods.foreach { mod => @@ -1043,6 +1057,7 @@ class NewCSR(implicit val p: Parameters) extends Module debugMod.io.in.trapInfo.bits.isInterrupt := trapIsInterrupt debugMod.io.in.trapInfo.bits.trigger := trigger debugMod.io.in.trapInfo.bits.singleStep := singleStep + debugMod.io.in.trapInfo.bits.criticalErrorState := criticalErrorState debugMod.io.in.privState := privState debugMod.io.in.debugMode := debugMode debugMod.io.in.dcsr := dcsr.regOut @@ -1057,20 +1072,15 @@ class NewCSR(implicit val p: Parameters) extends Module entryDebugMode := debugMod.io.out.hasDebugTrap && !debugMode - trapEntryDEvent.valid := entryDebugMode - trapEntryDEvent.in.hasDebugIntr := debugMod.io.out.hasDebugIntr - trapEntryDEvent.in.debugMode := debugMode - trapEntryDEvent.in.hasTrap := hasTrap - trapEntryDEvent.in.hasSingleStep := debugMod.io.out.hasSingleStep - trapEntryDEvent.in.triggerEnterDebugMode := debugMod.io.out.triggerEnterDebugMode - trapEntryDEvent.in.hasDebugEbreakException := debugMod.io.out.hasDebugEbreakException - trapEntryDEvent.in.breakPoint := debugMod.io.out.breakPoint - - trapHandleMod.io.in.trapInfo.bits.singleStep := debugMod.io.out.hasSingleStep - - intrMod.io.in.debugMode := debugMode - intrMod.io.in.debugIntr := debugIntr - intrMod.io.in.dcsr := dcsr.regOut + trapEntryDEvent.valid := entryDebugMode + trapEntryDEvent.in.hasDebugIntr := debugMod.io.out.hasDebugIntr + trapEntryDEvent.in.debugMode := debugMode + trapEntryDEvent.in.hasTrap := hasTrap + trapEntryDEvent.in.hasSingleStep := debugMod.io.out.hasSingleStep + trapEntryDEvent.in.triggerEnterDebugMode := debugMod.io.out.triggerEnterDebugMode + trapEntryDEvent.in.hasDebugEbreakException := debugMod.io.out.hasDebugEbreakException + trapEntryDEvent.in.breakPoint := debugMod.io.out.breakPoint + trapEntryDEvent.in.criticalErrorStateEnterDebug := debugMod.io.out.criticalErrorStateEnterDebug tdata1RegVec.foreach { mod => mod match { @@ -1308,10 +1318,12 @@ class NewCSR(implicit val p: Parameters) extends Module ) io.distributedWenLegal := wenLegal + io.status.criticalErrorState := criticalErrorState && !dcsr.regOut.CETRIG.asBool val criticalErrors = Seq( ("csr_dbltrp_inMN", !mnstatus.regOut.NMIE && hasTrap && !entryDebugMode), ) + criticalErrorStateInCSR := criticalErrors.map(criticalError => criticalError._2).reduce(_ || _).asBool generateCriticalErrors() // Always instantiate basic difftest modules. diff --git a/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala b/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala index 17d2def8e6..88d59b0a9c 100644 --- a/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala +++ b/src/main/scala/xiangshan/backend/fu/wrapper/CSR.scala @@ -162,6 +162,7 @@ class CSR(cfg: FuConfig)(implicit p: Parameters) extends FuncUnit(cfg) csrMod.io.fromTop.hartId := io.csrin.get.hartId csrMod.io.fromTop.clintTime := io.csrin.get.clintTime + csrMod.io.fromTop.criticalErrorState := io.csrin.get.criticalErrorState private val csrModOutValid = csrMod.io.out.valid private val csrModOut = csrMod.io.out.bits @@ -358,6 +359,7 @@ class CSR(cfg: FuConfig)(implicit p: Parameters) extends FuncUnit(cfg) } csrOut.instrAddrTransType := csrMod.io.status.instrAddrTransType + csrOut.criticalErrorState := csrMod.io.status.criticalErrorState csrToDecode := csrMod.io.toDecode } @@ -365,6 +367,7 @@ class CSR(cfg: FuConfig)(implicit p: Parameters) extends FuncUnit(cfg) class CSRInput(implicit p: Parameters) extends XSBundle with HasSoCParameter{ val hartId = Input(UInt(8.W)) val msiInfo = Input(ValidIO(new MsiInfoBundle)) + val criticalErrorState = Input(Bool()) val clintTime = Input(ValidIO(UInt(64.W))) val trapInstInfo = Input(ValidIO(new TrapInstInfo)) val fromVecExcpMod = Input(new Bundle { diff --git a/src/main/scala/xiangshan/backend/rob/Rob.scala b/src/main/scala/xiangshan/backend/rob/Rob.scala index cdb9f99670..a38b0c730e 100644 --- a/src/main/scala/xiangshan/backend/rob/Rob.scala +++ b/src/main/scala/xiangshan/backend/rob/Rob.scala @@ -99,7 +99,6 @@ class RobImp(override val wrapper: Rob)(implicit p: Parameters, params: BackendP val logicPhyRegMap = Vec(RabCommitWidth, ValidIO(new RegWriteFromRab)) val excpInfo = ValidIO(new VecExcpInfo) }) - val criticalError = Input(Bool()) val debug_ls = Flipped(new DebugLSIO) val debugRobHead = Output(new DynInst) val debugEnqLsq = Input(new LsqEnqIO) @@ -719,7 +718,7 @@ class RobImp(override val wrapper: Rob)(implicit p: Parameters, params: BackendP val deqFlushBlock = deqFlushBlockCounter(0) val deqHasCommitted = io.commits.isCommit && io.commits.commitValid(0) val deqHitRedirectReg = RegNext(io.redirect.valid && io.redirect.bits.robIdx === deqPtr) - val criticalErrorState = RegEnable(true.B, false.B, io.criticalError) + val criticalErrorState = io.csr.criticalErrorState when(deqNeedFlush && deqHitRedirectReg){ deqFlushBlockCounter := "b111".U }.otherwise{ @@ -1492,9 +1491,9 @@ class RobImp(override val wrapper: Rob)(implicit p: Parameters, params: BackendP } val diffCriticalErrorEvent = DifftestModule(new DiffCriticalErrorEvent) - diffCriticalErrorEvent.valid := io.criticalError && !RegNext(io.criticalError) + diffCriticalErrorEvent.valid := criticalErrorState && !RegNext(criticalErrorState) diffCriticalErrorEvent.coreid := io.hartId - diffCriticalErrorEvent.criticalError := io.criticalError + diffCriticalErrorEvent.criticalError := criticalErrorState } //store evetn difftest information diff --git a/src/main/scala/xiangshan/backend/rob/RobBundles.scala b/src/main/scala/xiangshan/backend/rob/RobBundles.scala index 15b10b4bec..ac1dc82b76 100644 --- a/src/main/scala/xiangshan/backend/rob/RobBundles.scala +++ b/src/main/scala/xiangshan/backend/rob/RobBundles.scala @@ -216,6 +216,7 @@ class RobCSRIO(implicit p: Parameters) extends XSBundle { val trapTarget = Input(new TargetPCBundle) val isXRet = Input(Bool()) val wfiEvent = Input(Bool()) + val criticalErrorState = Input(Bool()) val fflags = Output(Valid(UInt(5.W))) val vxsat = Output(Valid(Bool()))