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 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.{HgatpMode, PrivMode, SatpMode, VirtMode} 12import xiangshan.backend.fu.NewCSR._ 13import xiangshan.AddrTransType 14 15 16class SretEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase { 17 // Todo: write sstatus instead of mstatus 18 val mstatus = ValidIO((new MstatusBundle).addInEvent(_.SIE, _.SPIE, _.SPP, _.MPRV, _.MDT, _.SDT)) 19 val hstatus = ValidIO((new HstatusBundle).addInEvent(_.SPV)) 20 val vsstatus = ValidIO((new SstatusBundle).addInEvent(_.SIE, _.SPIE, _.SPP)) 21 val targetPc = ValidIO(new TargetPCBundle) 22} 23 24class SretEventSDTOutput extends Bundle with EventOutputBase { 25 val vsstatus = ValidIO((new SstatusBundle).addInEvent(_.SDT)) 26} 27 28class SretEventInput extends Bundle { 29 val privState = Input(new PrivState) 30 val mstatus = Input(new MstatusBundle) 31 val hstatus = Input(new HstatusBundle) 32 val vsstatus = Input(new SstatusBundle) 33 val sepc = Input(new Epc()) 34 val vsepc = Input(new Epc()) 35 val satp = Input(new SatpBundle) 36 val vsatp = Input(new SatpBundle) 37 val hgatp = Input(new HgatpBundle) 38} 39 40class SretEventModule(implicit p: Parameters) extends Module with CSREventBase { 41 val in = IO(new SretEventInput) 42 val out = IO(new SretEventOutput) 43 44 val outSDT = IO(new SretEventSDTOutput) 45 46 private val satp = in.satp 47 private val vsatp = in.vsatp 48 private val hgatp = in.hgatp 49 private val nextPrivState = out.privState.bits 50 51 private val instrAddrTransType = AddrTransType( 52 bare = (!nextPrivState.isVirtual && satp.MODE === SatpMode.Bare) || 53 (nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Bare), 54 sv39 = !nextPrivState.isVirtual && satp.MODE === SatpMode.Sv39 || 55 nextPrivState.isVirtual && vsatp.MODE === SatpMode.Sv39, 56 sv48 = !nextPrivState.isVirtual && satp.MODE === SatpMode.Sv48 || 57 nextPrivState.isVirtual && vsatp.MODE === SatpMode.Sv48, 58 sv39x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv39x4, 59 sv48x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv48x4 60 ) 61 62 private val sretInM = in.privState.isModeM 63 private val sretInHS = in.privState.isModeHS 64 private val sretInHSorM = sretInM || sretInHS 65 private val sretInVS = in.privState.isModeVS 66 67 private val xepc = Mux1H(Seq( 68 sretInHSorM -> in.sepc, 69 sretInVS -> in.vsepc, 70 )).asUInt 71 72 73 private val outPrivState = Wire(new PrivState) 74 outPrivState.PRVM := Mux1H(Seq( 75 // SPP is not PrivMode enum type, so asUInt 76 sretInHSorM -> in.mstatus.SPP.asUInt, 77 sretInVS -> in.vsstatus.SPP.asUInt, 78 )) 79 outPrivState.V := Mux1H(Seq( 80 sretInHSorM -> in.hstatus.SPV, 81 sretInVS -> in.privState.V, // keep 82 )) 83 84 private val sretToVU = outPrivState.isModeVU 85 private val sretToVS = outPrivState.isModeVS 86 private val sretToU = outPrivState.isModeHU 87 88 out := DontCare 89 outSDT := DontCare 90 91 out.privState.valid := valid 92 out.targetPc .valid := valid 93 94 out.privState.bits := outPrivState 95 96 // hstatus 97 out.hstatus.valid := valid && sretInHSorM 98 out.hstatus.bits.SPV := VirtMode.Off 99 100 // sstatus 101 out.mstatus.valid := valid && sretInHSorM 102 out.mstatus.bits.SPP := PrivMode.U.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width 103 out.mstatus.bits.SIE := in.mstatus.SPIE 104 out.mstatus.bits.SPIE := 1.U 105 out.mstatus.bits.MPRV := 0.U // sret will always leave M mode 106 out.mstatus.bits.MDT := Mux(sretInM, 0.U, in.mstatus.MDT.asBool) // when execute return in M mode, set MDT 0 107 out.mstatus.bits.SDT := MuxCase(in.mstatus.SDT.asBool, Seq( 108 sretInHS -> 0.U, // sret will alway leave M mode 109 (sretInM && (sretToU || sretToVS || sretToVU)) -> 0.U 110 )) 111 112 113 // vsstatus 114 out.vsstatus.valid := valid && sretInVS 115 out.vsstatus.bits.SPP := PrivMode.U.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width 116 out.vsstatus.bits.SIE := in.vsstatus.SPIE 117 out.vsstatus.bits.SPIE := 1.U 118 119 outSDT.vsstatus.valid := valid && (sretToVU || sretInVS) // clear SDT when return to VU or sret in vs 120 outSDT.vsstatus.bits.SDT := 0.U 121 122 out.targetPc.bits.pc := xepc 123 out.targetPc.bits.raiseIPF := instrAddrTransType.checkPageFault(xepc) 124 out.targetPc.bits.raiseIAF := instrAddrTransType.checkAccessFault(xepc) 125 out.targetPc.bits.raiseIGPF := instrAddrTransType.checkGuestPageFault(xepc) 126 127 // for better verilog 128 dontTouch(sretInHSorM) 129 dontTouch(sretInVS) 130} 131 132trait SretEventSinkBundle extends EventSinkBundle { self: CSRModule[_ <: CSRBundle] => 133 val retFromS = IO(Flipped(new SretEventOutput)) 134 135 addUpdateBundleInCSREnumType(retFromS.getBundleByName(self.modName.toLowerCase())) 136 137 reconnectReg() 138} 139 140trait SretEventSDTSinkBundle extends EventSinkBundle { self: CSRModule[_ <: CSRBundle] => 141 val retFromSSDT = IO(Flipped(new SretEventSDTOutput)) 142 143 addUpdateBundleInCSREnumType(retFromSSDT.getBundleByName(self.modName.toLowerCase())) 144 145 reconnectReg() 146} 147 148