1package xiangshan.backend.fu.NewCSR.CSREvents 2 3import chisel3._ 4import chisel3.util._ 5import org.chipsalliance.cde.config.Parameters 6import utility.SignExt 7import xiangshan.ExceptionNO 8import xiangshan.backend.fu.NewCSR.CSRBundles.{CauseBundle, OneFieldBundle, PrivState} 9import xiangshan.backend.fu.NewCSR.CSRConfig.{VaddrMaxWidth, XLEN} 10import xiangshan.backend.fu.NewCSR._ 11import xiangshan.AddrTransType 12 13 14class TrapEntryMEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase { 15 16 val mstatus = ValidIO((new MstatusBundle ).addInEvent(_.MPV, _.MPP, _.GVA, _.MPIE, _.MIE, _.MDT)) 17 val mepc = ValidIO((new Epc ).addInEvent(_.epc)) 18 val mcause = ValidIO((new CauseBundle ).addInEvent(_.Interrupt, _.ExceptionCode)) 19 val mtval = ValidIO((new OneFieldBundle).addInEvent(_.ALL)) 20 val mtval2 = ValidIO((new OneFieldBundle).addInEvent(_.ALL)) 21 val mtinst = ValidIO((new OneFieldBundle).addInEvent(_.ALL)) 22 val targetPc = ValidIO(new TargetPCBundle) 23} 24 25class TrapEntryMEventModule(implicit val p: Parameters) extends Module with CSREventBase { 26 val in = IO(new TrapEntryEventInput) 27 val out = IO(new TrapEntryMEventOutput) 28 29 private val current = in 30 private val iMode = current.iMode 31 private val dMode = current.dMode 32 private val satp = current.satp 33 private val vsatp = current.vsatp 34 private val hgatp = current.hgatp 35 private val isDTExcp = current.hasDTExcp 36 37 private val highPrioTrapNO = in.causeNO.ExceptionCode.asUInt 38 private val isException = !in.causeNO.Interrupt.asBool 39 private val isInterrupt = in.causeNO.Interrupt.asBool 40 41 private val trapPC = genTrapVA( 42 iMode, 43 satp, 44 vsatp, 45 hgatp, 46 in.trapPc, 47 ) 48 49 private val trapPCGPA = SignExt(in.trapPcGPA, XLEN) 50 51 private val trapMemVA = in.memExceptionVAddr 52 53 private val trapMemGPA = in.memExceptionGPAddr 54 55 private val trapInst = Mux(in.trapInst.valid, in.trapInst.bits, 0.U) 56 57 private val fetchIsVirt = iMode.isVirtual 58 private val memIsVirt = dMode.isVirtual 59 60 private val isFetchExcp = isException && ExceptionNO.getFetchFault.map(_.U === highPrioTrapNO).reduce(_ || _) 61 private val isMemExcp = isException && (ExceptionNO.getLoadFault ++ ExceptionNO.getStoreFault).map(_.U === highPrioTrapNO).reduce(_ || _) 62 private val isBpExcp = isException && ExceptionNO.EX_BP.U === highPrioTrapNO 63 private val isFetchBkpt = isBpExcp && in.isFetchBkpt 64 private val isMemBkpt = isBpExcp && !in.isFetchBkpt 65 private val isHlsExcp = isException && in.isHls 66 private val fetchCrossPage = in.isCrossPageIPF 67 private val isFetchMalAddr = in.isFetchMalAddr 68 private val isIllegalInst = isException && (ExceptionNO.EX_II.U === highPrioTrapNO || ExceptionNO.EX_VI.U === highPrioTrapNO) 69 70 private val isLSGuestExcp = isException && ExceptionNO.getLSGuestPageFault.map(_.U === highPrioTrapNO).reduce(_ || _) 71 private val isFetchGuestExcp = isException && ExceptionNO.EX_IGPF.U === highPrioTrapNO 72 // Software breakpoint exceptions are permitted to write either 0 or the pc to xtval 73 // We fill pc here 74 private val tvalFillPc = (isFetchExcp || isFetchGuestExcp) && !fetchCrossPage || isFetchBkpt 75 private val tvalFillPcPlus2 = (isFetchExcp || isFetchGuestExcp) && fetchCrossPage 76 private val tvalFillMemVaddr = isMemExcp || isMemBkpt 77 private val tvalFillGVA = 78 isHlsExcp && isMemExcp || 79 isLSGuestExcp|| isFetchGuestExcp || 80 (isFetchExcp || isFetchBkpt) && fetchIsVirt || 81 (isMemExcp || isMemBkpt) && memIsVirt 82 private val tvalFillInst = isIllegalInst 83 84 private val tval = Mux1H(Seq( 85 (tvalFillPc ) -> trapPC, 86 (tvalFillPcPlus2 ) -> (trapPC + 2.U), 87 (tvalFillMemVaddr && !memIsVirt ) -> trapMemVA, 88 (tvalFillMemVaddr && memIsVirt ) -> trapMemVA, 89 (isLSGuestExcp ) -> trapMemVA, 90 (tvalFillInst ) -> trapInst, 91 )) 92 93 private val tval2 = Mux1H(Seq( 94 (isFetchGuestExcp && isFetchMalAddr ) -> in.fetchMalTval, 95 (isFetchGuestExcp && !isFetchMalAddr && !fetchCrossPage) -> trapPCGPA, 96 (isFetchGuestExcp && !isFetchMalAddr && fetchCrossPage ) -> (trapPCGPA + 2.U), 97 (isLSGuestExcp ) -> trapMemGPA, 98 )) 99 100 private val precause = Cat(isInterrupt, highPrioTrapNO) 101 102 out := DontCare 103 104 out.privState.valid := valid 105 out.mstatus .valid := valid 106 out.mepc .valid := valid 107 out.mcause .valid := valid 108 out.mtval .valid := valid 109 out.mtval2 .valid := valid 110 out.mtinst .valid := valid 111 out.targetPc .valid := valid 112 113 out.privState.bits := PrivState.ModeM 114 out.mstatus.bits.MPV := current.privState.V 115 out.mstatus.bits.MPP := current.privState.PRVM 116 out.mstatus.bits.GVA := tvalFillGVA 117 out.mstatus.bits.MPIE := current.mstatus.MIE 118 out.mstatus.bits.MIE := 0.U 119 out.mstatus.bits.MDT := 1.U 120 out.mepc.bits.epc := Mux(isFetchMalAddr, in.fetchMalTval(63, 1), trapPC(63, 1)) 121 out.mcause.bits.Interrupt := isInterrupt 122 out.mcause.bits.ExceptionCode := Mux(isDTExcp, ExceptionNO.EX_DT.U, highPrioTrapNO) 123 out.mtval.bits.ALL := Mux(isFetchMalAddr, in.fetchMalTval, tval) 124 out.mtval2.bits.ALL := Mux(isDTExcp, precause, tval2 >> 2) 125 out.mtinst.bits.ALL := Mux(isFetchGuestExcp && in.trapIsForVSnonLeafPTE || isLSGuestExcp && in.memExceptionIsForVSnonLeafPTE, 0x3000.U, 0.U) 126 out.targetPc.bits.pc := in.pcFromXtvec 127 out.targetPc.bits.raiseIPF := false.B 128 out.targetPc.bits.raiseIAF := AddrTransType(bare = true).checkAccessFault(in.pcFromXtvec) 129 out.targetPc.bits.raiseIGPF := false.B 130 131 dontTouch(isLSGuestExcp) 132 dontTouch(tvalFillGVA) 133} 134 135trait TrapEntryMEventSinkBundle extends EventSinkBundle { self: CSRModule[_ <: CSRBundle] => 136 val trapToM = IO(Flipped(new TrapEntryMEventOutput)) 137 138 addUpdateBundleInCSREnumType(trapToM.getBundleByName(self.modName.toLowerCase())) 139 140 reconnectReg() 141} 142