1package xiangshan.backend.fu.NewCSR.CSREvents 2 3import chisel3._ 4import chisel3.util._ 5import org.chipsalliance.cde.config.Parameters 6import utility.{SignExt, ZeroExt} 7import xiangshan.{ExceptionNO, HasXSParameter} 8import xiangshan.ExceptionNO._ 9import xiangshan.backend.fu.NewCSR.CSRBundles.{CauseBundle, OneFieldBundle, PrivState} 10import xiangshan.backend.fu.NewCSR.CSRConfig.{VaddrMaxWidth, XLEN} 11import xiangshan.backend.fu.NewCSR.CSRDefines.SatpMode 12import xiangshan.backend.fu.NewCSR._ 13 14 15class TrapEntryMEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase { 16 17 val mstatus = ValidIO((new MstatusBundle ).addInEvent(_.MPV, _.MPP, _.GVA, _.MPIE, _.MIE)) 18 val mepc = ValidIO((new Epc ).addInEvent(_.ALL)) 19 val mcause = ValidIO((new CauseBundle ).addInEvent(_.Interrupt, _.ExceptionCode)) 20 val mtval = ValidIO((new OneFieldBundle).addInEvent(_.ALL)) 21 val mtval2 = ValidIO((new OneFieldBundle).addInEvent(_.ALL)) 22 val mtinst = ValidIO((new OneFieldBundle).addInEvent(_.ALL)) 23 val targetPc = ValidIO(UInt(VaddrMaxWidth.W)) 24 25 def getBundleByName(name: String): Valid[CSRBundle] = { 26 name match { 27 case "mstatus" => this.mstatus 28 case "mepc" => this.mepc 29 case "mcause" => this.mcause 30 case "mtval" => this.mtval 31 case "mtval2" => this.mtval2 32 case "mtinst" => this.mtinst 33 } 34 } 35} 36 37class TrapEntryMEventModule(implicit val p: Parameters) extends Module with CSREventBase { 38 val in = IO(new TrapEntryEventInput) 39 val out = IO(new TrapEntryMEventOutput) 40 41 private val current = in 42 43 private val highPrioTrapNO = in.causeNO.ExceptionCode.asUInt 44 private val isException = !in.causeNO.Interrupt.asBool 45 private val isInterrupt = in.causeNO.Interrupt.asBool 46 47 private val trapPC = Wire(UInt(XLEN.W)) 48 private val trapMemVA = SignExt(in.memExceptionVAddr, XLEN) 49 private val trapMemGPA = SignExt(in.memExceptionGPAddr, XLEN) 50 private val ivmHS = !current.iMode.isModeHS && current.satp.MODE =/= SatpMode.Bare 51 private val ivmVS = !current.iMode.isModeVS && current.vsatp.MODE =/= SatpMode.Bare 52 // When enable virtual memory, the higher bit should fill with the msb of address of Sv39/Sv48/Sv57 53 trapPC := Mux(ivmHS || ivmVS, SignExt(in.trapPc, XLEN), ZeroExt(in.trapPc, XLEN)) 54 55 private val fetchIsVirt = current.iMode.isVirtual 56 private val memIsVirt = current.dMode.isVirtual 57 58 private val isFetchExcp = isException && Seq(/*EX_IAM, */ EX_IAF, EX_IPF).map(_.U === highPrioTrapNO).reduce(_ || _) 59 private val isMemExcp = isException && Seq(EX_LAM, EX_LAF, EX_SAM, EX_SAF, EX_LPF, EX_SPF).map(_.U === highPrioTrapNO).reduce(_ || _) 60 private val isBpExcp = isException && EX_BP.U === highPrioTrapNO 61 private val fetchCrossPage = in.isCrossPageIPF 62 63 private val isGuestExcp = isException && Seq(EX_IGPF, EX_LGPF, EX_SGPF).map(_.U === highPrioTrapNO).reduce(_ || _) 64 // Software breakpoint exceptions are permitted to write either 0 or the pc to xtval 65 // We fill pc here 66 private val tvalFillPc = isFetchExcp && !fetchCrossPage || isBpExcp 67 private val tvalFillPcPlus2 = isFetchExcp && fetchCrossPage 68 private val tvalFillMemVaddr = isMemExcp 69 private val tvalFillGVA = isGuestExcp || 70 (isFetchExcp || isBpExcp) && fetchIsVirt || 71 isMemExcp && memIsVirt 72 73 private val tval = Mux1H(Seq( 74 (tvalFillPc ) -> trapPC, 75 (tvalFillPcPlus2 ) -> (trapPC + 2.U), 76 (tvalFillMemVaddr && !memIsVirt ) -> trapMemVA, 77 (tvalFillMemVaddr && memIsVirt ) -> trapMemVA, 78 (isGuestExcp ) -> trapMemVA, 79 )) 80 81 private val tval2 = Mux(isGuestExcp, trapMemGPA, 0.U) 82 83 out := DontCare 84 85 out.privState.valid := valid 86 out.mstatus .valid := valid 87 out.mepc .valid := valid 88 out.mcause .valid := valid 89 out.mtval .valid := valid 90 out.mtval2 .valid := valid 91 out.targetPc .valid := valid 92 93 out.privState.bits := PrivState.ModeM 94 out.mstatus.bits.MPV := current.privState.V 95 out.mstatus.bits.MPP := current.privState.PRVM 96 out.mstatus.bits.GVA := tvalFillGVA 97 out.mstatus.bits.MPIE := current.mstatus.MIE 98 out.mstatus.bits.MIE := 0.U 99 out.mepc.bits.ALL := trapPC(trapPC.getWidth - 1, 1) 100 out.mcause.bits.Interrupt := isInterrupt 101 out.mcause.bits.ExceptionCode := highPrioTrapNO 102 out.mtval.bits.ALL := tval 103 out.mtval2.bits.ALL := tval2 104 out.mtinst.bits.ALL := 0.U 105 out.targetPc.bits := in.pcFromXtvec 106 107 dontTouch(isGuestExcp) 108 dontTouch(tvalFillGVA) 109} 110 111trait TrapEntryMEventSinkBundle { self: CSRModule[_] => 112 val trapToM = IO(Flipped(new TrapEntryMEventOutput)) 113 114 private val updateBundle: ValidIO[CSRBundle] = trapToM.getBundleByName(self.modName.toLowerCase()) 115 116 (reg.asInstanceOf[CSRBundle].getFields zip updateBundle.bits.getFields).foreach { case (sink, source) => 117 if (updateBundle.bits.eventFields.contains(source)) { 118 when(updateBundle.valid) { 119 sink := source 120 } 121 } 122 } 123} 124