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 targetPc = ValidIO(UInt(VaddrMaxWidth.W)) 22 23 def getBundleByName(name: String): Valid[CSRBundle] = { 24 name match { 25 case "mstatus" => this.mstatus 26 case "mepc" => this.mepc 27 case "mcause" => this.mcause 28 case "mtval" => this.mtval 29 case "mtval2" => this.mtval2 30 case "mtinst" => this.mtinst 31 } 32 } 33} 34 35class TrapEntryMEventModule(implicit val p: Parameters) extends Module with CSREventBase { 36 val in = IO(new TrapEntryEventInput) 37 val out = IO(new TrapEntryMEventOutput) 38 39 private val current = in 40 private val iMode = current.iMode 41 private val dMode = current.dMode 42 private val satp = current.satp 43 private val vsatp = current.vsatp 44 private val hgatp = current.hgatp 45 46 private val highPrioTrapNO = in.causeNO.ExceptionCode.asUInt 47 private val isException = !in.causeNO.Interrupt.asBool 48 private val isInterrupt = in.causeNO.Interrupt.asBool 49 50 private val trapPC = genTrapVA( 51 iMode, 52 satp, 53 vsatp, 54 hgatp, 55 in.trapPc, 56 ) 57 58 private val trapMemVA = genTrapVA( 59 dMode, 60 satp, 61 vsatp, 62 hgatp, 63 in.memExceptionVAddr, 64 ) 65 66 private val trapMemGPA = SignExt(in.memExceptionGPAddr, XLEN) 67 68 private val fetchIsVirt = iMode.isVirtual 69 private val memIsVirt = dMode.isVirtual 70 71 private val isFetchExcp = isException && Seq(/*EX_IAM, */ EX_IAF, EX_IPF).map(_.U === highPrioTrapNO).reduce(_ || _) 72 private val isMemExcp = isException && Seq(EX_LAM, EX_LAF, EX_SAM, EX_SAF, EX_LPF, EX_SPF).map(_.U === highPrioTrapNO).reduce(_ || _) 73 private val isBpExcp = isException && EX_BP.U === highPrioTrapNO 74 private val fetchCrossPage = in.isCrossPageIPF 75 76 private val isGuestExcp = isException && Seq(EX_IGPF, EX_LGPF, EX_SGPF).map(_.U === highPrioTrapNO).reduce(_ || _) 77 // Software breakpoint exceptions are permitted to write either 0 or the pc to xtval 78 // We fill pc here 79 private val tvalFillPc = isFetchExcp && !fetchCrossPage || isBpExcp 80 private val tvalFillPcPlus2 = isFetchExcp && fetchCrossPage 81 private val tvalFillMemVaddr = isMemExcp 82 private val tvalFillGVA = isGuestExcp || 83 (isFetchExcp || isBpExcp) && fetchIsVirt || 84 isMemExcp && memIsVirt 85 86 private val tval = Mux1H(Seq( 87 (tvalFillPc ) -> trapPC, 88 (tvalFillPcPlus2 ) -> (trapPC + 2.U), 89 (tvalFillMemVaddr && !memIsVirt ) -> trapMemVA, 90 (tvalFillMemVaddr && memIsVirt ) -> trapMemVA, 91 (isGuestExcp ) -> trapMemVA, 92 )) 93 94 private val tval2 = Mux(isGuestExcp, trapMemGPA, 0.U) 95 96 out := DontCare 97 98 out.privState.valid := valid 99 out.mstatus .valid := valid 100 out.mepc .valid := valid 101 out.mcause .valid := valid 102 out.mtval .valid := valid 103 out.mtval2 .valid := valid 104 out.targetPc .valid := valid 105 106 out.privState.bits := PrivState.ModeM 107 out.mstatus.bits.MPV := current.privState.V 108 out.mstatus.bits.MPP := current.privState.PRVM 109 out.mstatus.bits.GVA := tvalFillGVA 110 out.mstatus.bits.MPIE := current.mstatus.MIE 111 out.mstatus.bits.MIE := 0.U 112 out.mepc.bits.epc := trapPC(VaddrMaxWidth - 1, 1) 113 out.mcause.bits.Interrupt := isInterrupt 114 out.mcause.bits.ExceptionCode := highPrioTrapNO 115 out.mtval.bits.ALL := tval 116 out.mtval2.bits.ALL := tval2 117 out.mtinst.bits.ALL := 0.U 118 out.targetPc.bits := in.pcFromXtvec 119 120 dontTouch(isGuestExcp) 121 dontTouch(tvalFillGVA) 122} 123 124trait TrapEntryMEventSinkBundle { self: CSRModule[_] => 125 val trapToM = IO(Flipped(new TrapEntryMEventOutput)) 126 127 private val updateBundle: ValidIO[CSRBundle] = trapToM.getBundleByName(self.modName.toLowerCase()) 128 129 (reg.asInstanceOf[CSRBundle].getFields zip updateBundle.bits.getFields).foreach { case (sink, source) => 130 if (updateBundle.bits.eventFields.contains(source)) { 131 when(updateBundle.valid) { 132 sink := source 133 } 134 } 135 } 136} 137