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 override def getBundleByName(name: String): ValidIO[CSRBundle] = { 24 name match { 25 case "mstatus" => this.mstatus 26 case "hstatus" => this.hstatus 27 case "vsstatus" => this.vsstatus 28 } 29 } 30} 31 32class SretEventInput extends Bundle { 33 val privState = Input(new PrivState) 34 val sstatus = Input(new SstatusBundle) 35 val hstatus = Input(new HstatusBundle) 36 val vsstatus = Input(new SstatusBundle) 37 val sepc = Input(new Epc()) 38 val vsepc = Input(new Epc()) 39 val satp = Input(new SatpBundle) 40 val vsatp = Input(new SatpBundle) 41 val hgatp = Input(new HgatpBundle) 42} 43 44class SretEventModule(implicit p: Parameters) extends Module with CSREventBase { 45 val in = IO(new SretEventInput) 46 val out = IO(new SretEventOutput) 47 48 private val satp = in.satp 49 private val vsatp = in.vsatp 50 private val hgatp = in.hgatp 51 private val nextPrivState = out.privState.bits 52 53 private val instrAddrTransType = AddrTransType( 54 bare = (!nextPrivState.isVirtual && satp.MODE === SatpMode.Bare) || 55 (nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Bare), 56 sv39 = !nextPrivState.isVirtual && satp.MODE === SatpMode.Sv39 || 57 nextPrivState.isVirtual && vsatp.MODE === SatpMode.Sv39, 58 sv48 = !nextPrivState.isVirtual && satp.MODE === SatpMode.Sv48 || 59 nextPrivState.isVirtual && vsatp.MODE === SatpMode.Sv48, 60 sv39x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv39x4, 61 sv48x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv48x4 62 ) 63 64 private val sretInHSorM = in.privState.isModeM || in.privState.isModeHS 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 out := DontCare 73 74 out.privState.valid := valid 75 out.targetPc .valid := valid 76 77 out.privState.bits.PRVM := Mux1H(Seq( 78 // SPP is not PrivMode enum type, so asUInt 79 sretInHSorM -> in.sstatus.SPP.asUInt, 80 sretInVS -> in.vsstatus.SPP.asUInt, 81 )) 82 out.privState.bits.V := Mux1H(Seq( 83 sretInHSorM -> in.hstatus.SPV, 84 sretInVS -> in.privState.V, // keep 85 )) 86 87 // hstatus 88 out.hstatus.valid := valid && sretInHSorM 89 out.hstatus.bits.SPV := VirtMode.Off 90 91 // sstatus 92 out.mstatus.valid := valid && sretInHSorM 93 out.mstatus.bits.SPP := PrivMode.U.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width 94 out.mstatus.bits.SIE := in.sstatus.SPIE 95 out.mstatus.bits.SPIE := 1.U 96 out.mstatus.bits.MPRV := 0.U // sret will always leave M mode 97 98 // vsstatus 99 out.vsstatus.valid := valid && sretInVS 100 out.vsstatus.bits.SPP := PrivMode.U.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width 101 out.vsstatus.bits.SIE := in.vsstatus.SPIE 102 out.vsstatus.bits.SPIE := 1.U 103 104 out.targetPc.bits.pc := xepc 105 out.targetPc.bits.raiseIPF := instrAddrTransType.checkPageFault(xepc) 106 out.targetPc.bits.raiseIAF := instrAddrTransType.checkAccessFault(xepc) 107 out.targetPc.bits.raiseIGPF := instrAddrTransType.checkGuestPageFault(xepc) 108 109 // for better verilog 110 dontTouch(sretInHSorM) 111 dontTouch(sretInVS) 112} 113 114trait SretEventSinkBundle { self: CSRModule[_] => 115 val retFromS = IO(Flipped(new SretEventOutput)) 116 117 private val updateBundle: ValidIO[CSRBundle] = retFromS.getBundleByName(self.modName.toLowerCase()) 118 119 (reg.asInstanceOf[CSRBundle].getFields zip updateBundle.bits.getFields).foreach { case (sink, source) => 120 if (updateBundle.bits.eventFields.contains(source)) { 121 when(updateBundle.valid) { 122 sink := source 123 } 124 } 125 } 126} 127