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)) 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 SretEventInput extends Bundle { 25 val privState = Input(new PrivState) 26 val sstatus = Input(new SstatusBundle) 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 sretInHSorM = in.privState.isModeM || in.privState.isModeHS 57 private val sretInVS = in.privState.isModeVS 58 59 private val xepc = Mux1H(Seq( 60 sretInHSorM -> in.sepc, 61 sretInVS -> in.vsepc, 62 )).asUInt 63 64 out := DontCare 65 66 out.privState.valid := valid 67 out.targetPc .valid := valid 68 69 out.privState.bits.PRVM := Mux1H(Seq( 70 // SPP is not PrivMode enum type, so asUInt 71 sretInHSorM -> in.sstatus.SPP.asUInt, 72 sretInVS -> in.vsstatus.SPP.asUInt, 73 )) 74 out.privState.bits.V := Mux1H(Seq( 75 sretInHSorM -> in.hstatus.SPV, 76 sretInVS -> in.privState.V, // keep 77 )) 78 79 // hstatus 80 out.hstatus.valid := valid && sretInHSorM 81 out.hstatus.bits.SPV := VirtMode.Off 82 83 // sstatus 84 out.mstatus.valid := valid && sretInHSorM 85 out.mstatus.bits.SPP := PrivMode.U.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width 86 out.mstatus.bits.SIE := in.sstatus.SPIE 87 out.mstatus.bits.SPIE := 1.U 88 out.mstatus.bits.MPRV := 0.U // sret will always leave M mode 89 90 // vsstatus 91 out.vsstatus.valid := valid && sretInVS 92 out.vsstatus.bits.SPP := PrivMode.U.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width 93 out.vsstatus.bits.SIE := in.vsstatus.SPIE 94 out.vsstatus.bits.SPIE := 1.U 95 96 out.targetPc.bits.pc := xepc 97 out.targetPc.bits.raiseIPF := instrAddrTransType.checkPageFault(xepc) 98 out.targetPc.bits.raiseIAF := instrAddrTransType.checkAccessFault(xepc) 99 out.targetPc.bits.raiseIGPF := instrAddrTransType.checkGuestPageFault(xepc) 100 101 // for better verilog 102 dontTouch(sretInHSorM) 103 dontTouch(sretInVS) 104} 105 106trait SretEventSinkBundle extends EventSinkBundle { self: CSRModule[_ <: CSRBundle] => 107 val retFromS = IO(Flipped(new SretEventOutput)) 108 109 addUpdateBundleInCSREnumType(retFromS.getBundleByName(self.modName.toLowerCase())) 110 111 reconnectReg() 112} 113