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