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._ 11 12 13class TrapEntryMEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase { 14 15 val mstatus = ValidIO((new MstatusBundle ).addInEvent(_.MPV, _.MPP, _.GVA, _.MPIE, _.MIE)) 16 val mepc = ValidIO((new Epc ).addInEvent(_.epc)) 17 val mcause = ValidIO((new CauseBundle ).addInEvent(_.Interrupt, _.ExceptionCode)) 18 val mtval = ValidIO((new OneFieldBundle).addInEvent(_.ALL)) 19 val mtval2 = ValidIO((new OneFieldBundle).addInEvent(_.ALL)) 20 val mtinst = ValidIO((new OneFieldBundle).addInEvent(_.ALL)) 21 val tcontrol = ValidIO((new TcontrolBundle).addInEvent(_.MPTE, _.MTE)) 22 val targetPc = ValidIO(UInt(VaddrMaxWidth.W)) 23 24 def getBundleByName(name: String): Valid[CSRBundle] = { 25 name match { 26 case "mstatus" => this.mstatus 27 case "mepc" => this.mepc 28 case "mcause" => this.mcause 29 case "mtval" => this.mtval 30 case "mtval2" => this.mtval2 31 case "mtinst" => this.mtinst 32 case "tcontrol" => this.tcontrol 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 private val iMode = current.iMode 43 private val dMode = current.dMode 44 private val satp = current.satp 45 private val vsatp = current.vsatp 46 private val hgatp = current.hgatp 47 48 private val highPrioTrapNO = in.causeNO.ExceptionCode.asUInt 49 private val isException = !in.causeNO.Interrupt.asBool 50 private val isInterrupt = in.causeNO.Interrupt.asBool 51 52 private val trapPC = genTrapVA( 53 iMode, 54 satp, 55 vsatp, 56 hgatp, 57 in.trapPc, 58 ) 59 60 private val trapMemVA = genTrapVA( 61 dMode, 62 satp, 63 vsatp, 64 hgatp, 65 in.memExceptionVAddr, 66 ) 67 68 private val trapMemGPA = SignExt(in.memExceptionGPAddr, XLEN) 69 70 private val fetchIsVirt = iMode.isVirtual 71 private val memIsVirt = dMode.isVirtual 72 73 private val isFetchExcp = isException && ExceptionNO.getFetchFault.map(_.U === highPrioTrapNO).reduce(_ || _) 74 private val isMemExcp = isException && (ExceptionNO.getLoadFault ++ ExceptionNO.getStoreFault).map(_.U === highPrioTrapNO).reduce(_ || _) 75 private val isBpExcp = isException && ExceptionNO.EX_BP.U === highPrioTrapNO 76 private val isHlsExcp = isException && in.isHls 77 private val fetchCrossPage = in.isCrossPageIPF 78 79 private val isGuestExcp = isException && ExceptionNO.getGuestPageFault.map(_.U === highPrioTrapNO).reduce(_ || _) 80 // Software breakpoint exceptions are permitted to write either 0 or the pc to xtval 81 // We fill pc here 82 private val tvalFillPc = isFetchExcp && !fetchCrossPage || isBpExcp 83 private val tvalFillPcPlus2 = isFetchExcp && fetchCrossPage 84 private val tvalFillMemVaddr = isMemExcp 85 private val tvalFillGVA = 86 isHlsExcp && isMemExcp || 87 isGuestExcp || 88 (isFetchExcp || isBpExcp) && fetchIsVirt || 89 isMemExcp && memIsVirt 90 91 private val tval = Mux1H(Seq( 92 (tvalFillPc ) -> trapPC, 93 (tvalFillPcPlus2 ) -> (trapPC + 2.U), 94 (tvalFillMemVaddr && !memIsVirt ) -> trapMemVA, 95 (tvalFillMemVaddr && memIsVirt ) -> trapMemVA, 96 (isGuestExcp ) -> trapMemVA, 97 )) 98 99 private val tval2 = Mux(isGuestExcp, trapMemGPA, 0.U) 100 101 out := DontCare 102 103 out.privState.valid := valid 104 out.mstatus .valid := valid 105 out.mepc .valid := valid 106 out.mcause .valid := valid 107 out.mtval .valid := valid 108 out.mtval2 .valid := valid 109 out.tcontrol .valid := valid 110 out.targetPc .valid := valid 111 112 out.privState.bits := PrivState.ModeM 113 out.mstatus.bits.MPV := current.privState.V 114 out.mstatus.bits.MPP := current.privState.PRVM 115 out.mstatus.bits.GVA := tvalFillGVA 116 out.mstatus.bits.MPIE := current.mstatus.MIE 117 out.mstatus.bits.MIE := 0.U 118 out.mepc.bits.epc := trapPC(VaddrMaxWidth - 1, 1) 119 out.mcause.bits.Interrupt := isInterrupt 120 out.mcause.bits.ExceptionCode := highPrioTrapNO 121 out.mtval.bits.ALL := tval 122 out.mtval2.bits.ALL := tval2 >> 2 123 out.mtinst.bits.ALL := 0.U 124 out.tcontrol.bits.MPTE := in.tcontrol.MTE 125 out.tcontrol.bits.MTE := 0.U 126 out.targetPc.bits := in.pcFromXtvec 127 128 dontTouch(isGuestExcp) 129 dontTouch(tvalFillGVA) 130} 131 132trait TrapEntryMEventSinkBundle { self: CSRModule[_] => 133 val trapToM = IO(Flipped(new TrapEntryMEventOutput)) 134 135 private val updateBundle: ValidIO[CSRBundle] = trapToM.getBundleByName(self.modName.toLowerCase()) 136 137 (reg.asInstanceOf[CSRBundle].getFields zip updateBundle.bits.getFields).foreach { case (sink, source) => 138 if (updateBundle.bits.eventFields.contains(source)) { 139 when(updateBundle.valid) { 140 sink := source 141 } 142 } 143 } 144} 145