1237d4cfdSXuan Hupackage xiangshan.backend.fu.NewCSR.CSREvents 2237d4cfdSXuan Hu 3237d4cfdSXuan Huimport chisel3._ 4237d4cfdSXuan Huimport chisel3.util._ 5c1b28b66STang Haojinimport org.chipsalliance.cde.config.Parameters 6237d4cfdSXuan Huimport utility.{SignExt, ZeroExt} 7237d4cfdSXuan Huimport xiangshan.ExceptionNO 8237d4cfdSXuan Huimport xiangshan.ExceptionNO._ 9237d4cfdSXuan Huimport xiangshan.backend.fu.NewCSR.CSRBundles.{CauseBundle, OneFieldBundle, PrivState} 10237d4cfdSXuan Huimport xiangshan.backend.fu.NewCSR.CSRConfig.{VaddrMaxWidth, XLEN} 11c1b28b66STang Haojinimport xiangshan.backend.fu.NewCSR.CSRDefines.{HgatpMode, PrivMode, SatpMode, VirtMode} 12237d4cfdSXuan Huimport xiangshan.backend.fu.NewCSR._ 13c1b28b66STang Haojinimport xiangshan.AddrTransType 14237d4cfdSXuan Hu 15237d4cfdSXuan Hu 16237d4cfdSXuan Huclass SretEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase { 17237d4cfdSXuan Hu // Todo: write sstatus instead of mstatus 186808b803SZehao Liu val mstatus = ValidIO((new MstatusBundle).addInEvent(_.SIE, _.SPIE, _.SPP, _.MPRV, _.MDT, _.SDT)) 19237d4cfdSXuan Hu val hstatus = ValidIO((new HstatusBundle).addInEvent(_.SPV)) 20*eca6983fSZehao Liu val vsstatus = ValidIO((new SstatusBundle).addInEvent(_.SIE, _.SPIE, _.SPP)) 21c1b28b66STang Haojin val targetPc = ValidIO(new TargetPCBundle) 22237d4cfdSXuan Hu} 23237d4cfdSXuan Hu 24*eca6983fSZehao Liuclass SretEventSDTOutput extends Bundle with EventOutputBase { 25*eca6983fSZehao Liu val vsstatus = ValidIO((new SstatusBundle).addInEvent(_.SDT)) 26*eca6983fSZehao Liu} 27*eca6983fSZehao Liu 28237d4cfdSXuan Huclass SretEventInput extends Bundle { 29237d4cfdSXuan Hu val privState = Input(new PrivState) 306808b803SZehao Liu val mstatus = Input(new MstatusBundle) 31237d4cfdSXuan Hu val hstatus = Input(new HstatusBundle) 32237d4cfdSXuan Hu val vsstatus = Input(new SstatusBundle) 33237d4cfdSXuan Hu val sepc = Input(new Epc()) 34237d4cfdSXuan Hu val vsepc = Input(new Epc()) 35c1b28b66STang Haojin val satp = Input(new SatpBundle) 36c1b28b66STang Haojin val vsatp = Input(new SatpBundle) 37c1b28b66STang Haojin val hgatp = Input(new HgatpBundle) 38237d4cfdSXuan Hu} 39237d4cfdSXuan Hu 40c1b28b66STang Haojinclass SretEventModule(implicit p: Parameters) extends Module with CSREventBase { 41237d4cfdSXuan Hu val in = IO(new SretEventInput) 42237d4cfdSXuan Hu val out = IO(new SretEventOutput) 43237d4cfdSXuan Hu 44*eca6983fSZehao Liu val outSDT = IO(new SretEventSDTOutput) 45*eca6983fSZehao Liu 46c1b28b66STang Haojin private val satp = in.satp 47c1b28b66STang Haojin private val vsatp = in.vsatp 48c1b28b66STang Haojin private val hgatp = in.hgatp 49c1b28b66STang Haojin private val nextPrivState = out.privState.bits 50c1b28b66STang Haojin 51c1b28b66STang Haojin private val instrAddrTransType = AddrTransType( 52c1b28b66STang Haojin bare = (!nextPrivState.isVirtual && satp.MODE === SatpMode.Bare) || 53c1b28b66STang Haojin (nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Bare), 54c1b28b66STang Haojin sv39 = !nextPrivState.isVirtual && satp.MODE === SatpMode.Sv39 || 55c1b28b66STang Haojin nextPrivState.isVirtual && vsatp.MODE === SatpMode.Sv39, 56c1b28b66STang Haojin sv48 = !nextPrivState.isVirtual && satp.MODE === SatpMode.Sv48 || 57c1b28b66STang Haojin nextPrivState.isVirtual && vsatp.MODE === SatpMode.Sv48, 58c1b28b66STang Haojin sv39x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv39x4, 59c1b28b66STang Haojin sv48x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv48x4 60c1b28b66STang Haojin ) 61c1b28b66STang Haojin 626808b803SZehao Liu private val sretInM = in.privState.isModeM 636808b803SZehao Liu private val sretInHS = in.privState.isModeHS 646808b803SZehao Liu private val sretInHSorM = sretInM || sretInHS 65c1b28b66STang Haojin private val sretInVS = in.privState.isModeVS 66c1b28b66STang Haojin 67c1b28b66STang Haojin private val xepc = Mux1H(Seq( 68c1b28b66STang Haojin sretInHSorM -> in.sepc, 69c1b28b66STang Haojin sretInVS -> in.vsepc, 70c1b28b66STang Haojin )).asUInt 71237d4cfdSXuan Hu 726808b803SZehao Liu 736808b803SZehao Liu private val outPrivState = Wire(new PrivState) 746808b803SZehao Liu outPrivState.PRVM := Mux1H(Seq( 756808b803SZehao Liu // SPP is not PrivMode enum type, so asUInt 766808b803SZehao Liu sretInHSorM -> in.mstatus.SPP.asUInt, 776808b803SZehao Liu sretInVS -> in.vsstatus.SPP.asUInt, 786808b803SZehao Liu )) 796808b803SZehao Liu outPrivState.V := Mux1H(Seq( 806808b803SZehao Liu sretInHSorM -> in.hstatus.SPV, 816808b803SZehao Liu sretInVS -> in.privState.V, // keep 826808b803SZehao Liu )) 836808b803SZehao Liu 846808b803SZehao Liu private val sretToVU = outPrivState.isModeVU 856808b803SZehao Liu private val sretToVS = outPrivState.isModeVS 866808b803SZehao Liu private val sretToU = outPrivState.isModeHU 876808b803SZehao Liu 88237d4cfdSXuan Hu out := DontCare 89*eca6983fSZehao Liu outSDT := DontCare 90237d4cfdSXuan Hu 91237d4cfdSXuan Hu out.privState.valid := valid 92237d4cfdSXuan Hu out.targetPc .valid := valid 93237d4cfdSXuan Hu 946808b803SZehao Liu out.privState.bits := outPrivState 95237d4cfdSXuan Hu 96237d4cfdSXuan Hu // hstatus 97237d4cfdSXuan Hu out.hstatus.valid := valid && sretInHSorM 98237d4cfdSXuan Hu out.hstatus.bits.SPV := VirtMode.Off 99237d4cfdSXuan Hu 100237d4cfdSXuan Hu // sstatus 101237d4cfdSXuan Hu out.mstatus.valid := valid && sretInHSorM 102237d4cfdSXuan Hu out.mstatus.bits.SPP := PrivMode.U.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width 1036808b803SZehao Liu out.mstatus.bits.SIE := in.mstatus.SPIE 104237d4cfdSXuan Hu out.mstatus.bits.SPIE := 1.U 105237d4cfdSXuan Hu out.mstatus.bits.MPRV := 0.U // sret will always leave M mode 1066808b803SZehao Liu out.mstatus.bits.MDT := Mux(sretInM, 0.U, in.mstatus.MDT.asBool) // when execute return in M mode, set MDT 0 1076808b803SZehao Liu out.mstatus.bits.SDT := MuxCase(in.mstatus.SDT.asBool, Seq( 1086808b803SZehao Liu sretInHS -> 0.U, // sret will alway leave M mode 1096808b803SZehao Liu (sretInM && (sretToU || sretToVS || sretToVU)) -> 0.U 1106808b803SZehao Liu )) 1116808b803SZehao Liu 112237d4cfdSXuan Hu 113237d4cfdSXuan Hu // vsstatus 114237d4cfdSXuan Hu out.vsstatus.valid := valid && sretInVS 115237d4cfdSXuan Hu out.vsstatus.bits.SPP := PrivMode.U.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width 116237d4cfdSXuan Hu out.vsstatus.bits.SIE := in.vsstatus.SPIE 117237d4cfdSXuan Hu out.vsstatus.bits.SPIE := 1.U 118*eca6983fSZehao Liu 119*eca6983fSZehao Liu outSDT.vsstatus.valid := valid && (sretToVU || sretInVS) // clear SDT when return to VU or sret in vs 120*eca6983fSZehao Liu outSDT.vsstatus.bits.SDT := 0.U 121237d4cfdSXuan Hu 122c1b28b66STang Haojin out.targetPc.bits.pc := xepc 123c1b28b66STang Haojin out.targetPc.bits.raiseIPF := instrAddrTransType.checkPageFault(xepc) 124c1b28b66STang Haojin out.targetPc.bits.raiseIAF := instrAddrTransType.checkAccessFault(xepc) 125c1b28b66STang Haojin out.targetPc.bits.raiseIGPF := instrAddrTransType.checkGuestPageFault(xepc) 126237d4cfdSXuan Hu 127237d4cfdSXuan Hu // for better verilog 128237d4cfdSXuan Hu dontTouch(sretInHSorM) 129237d4cfdSXuan Hu dontTouch(sretInVS) 130237d4cfdSXuan Hu} 131237d4cfdSXuan Hu 132cb36ac0fSXuan Hutrait SretEventSinkBundle extends EventSinkBundle { self: CSRModule[_ <: CSRBundle] => 133237d4cfdSXuan Hu val retFromS = IO(Flipped(new SretEventOutput)) 134237d4cfdSXuan Hu 135cb36ac0fSXuan Hu addUpdateBundleInCSREnumType(retFromS.getBundleByName(self.modName.toLowerCase())) 136237d4cfdSXuan Hu 137cb36ac0fSXuan Hu reconnectReg() 138237d4cfdSXuan Hu} 139*eca6983fSZehao Liu 140*eca6983fSZehao Liutrait SretEventSDTSinkBundle extends EventSinkBundle { self: CSRModule[_ <: CSRBundle] => 141*eca6983fSZehao Liu val retFromSSDT = IO(Flipped(new SretEventSDTOutput)) 142*eca6983fSZehao Liu 143*eca6983fSZehao Liu addUpdateBundleInCSREnumType(retFromSSDT.getBundleByName(self.modName.toLowerCase())) 144*eca6983fSZehao Liu 145*eca6983fSZehao Liu reconnectReg() 146*eca6983fSZehao Liu} 147*eca6983fSZehao Liu 148