1237d4cfdSXuan Hupackage xiangshan.backend.fu.NewCSR.CSREvents 2237d4cfdSXuan Hu 3237d4cfdSXuan Huimport chisel3._ 4237d4cfdSXuan Huimport chisel3.util._ 5237d4cfdSXuan Huimport org.chipsalliance.cde.config.Parameters 6237d4cfdSXuan Huimport utility.{SignExt, ZeroExt} 7f60da58cSXuan Huimport xiangshan.ExceptionNO 8237d4cfdSXuan Huimport xiangshan.backend.fu.NewCSR.CSRBundles.{CauseBundle, OneFieldBundle, PrivState} 9237d4cfdSXuan Huimport xiangshan.backend.fu.NewCSR.CSRConfig.{VaddrMaxWidth, XLEN} 10237d4cfdSXuan Huimport xiangshan.backend.fu.NewCSR.CSRDefines.SatpMode 11237d4cfdSXuan Huimport xiangshan.backend.fu.NewCSR._ 12c1b28b66STang Haojinimport xiangshan.AddrTransType 13237d4cfdSXuan Hu 14237d4cfdSXuan Hu 15237d4cfdSXuan Huclass TrapEntryHSEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase { 16237d4cfdSXuan Hu 17237d4cfdSXuan Hu // Todo: use sstatus instead of mstatus 186808b803SZehao Liu val mstatus = ValidIO((new MstatusBundle ).addInEvent(_.SPP, _.SPIE, _.SIE, _.SDT)) 19237d4cfdSXuan Hu val hstatus = ValidIO((new HstatusBundle ).addInEvent(_.SPV, _.SPVP, _.GVA)) 20260a087dSXuan Hu val sepc = ValidIO((new Epc ).addInEvent(_.epc)) 21237d4cfdSXuan Hu val scause = ValidIO((new CauseBundle ).addInEvent(_.Interrupt, _.ExceptionCode)) 22237d4cfdSXuan Hu val stval = ValidIO((new OneFieldBundle).addInEvent(_.ALL)) 23237d4cfdSXuan Hu val htval = ValidIO((new OneFieldBundle).addInEvent(_.ALL)) 24237d4cfdSXuan Hu val htinst = ValidIO((new OneFieldBundle).addInEvent(_.ALL)) 25c1b28b66STang Haojin val targetPc = ValidIO(new TargetPCBundle) 26237d4cfdSXuan Hu} 27237d4cfdSXuan Hu 28237d4cfdSXuan Huclass TrapEntryHSEventModule(implicit val p: Parameters) extends Module with CSREventBase { 29237d4cfdSXuan Hu val in = IO(new TrapEntryEventInput) 30237d4cfdSXuan Hu val out = IO(new TrapEntryHSEventOutput) 31237d4cfdSXuan Hu 32237d4cfdSXuan Hu private val current = in 33260a087dSXuan Hu private val iMode = current.iMode 34260a087dSXuan Hu private val dMode = current.dMode 35260a087dSXuan Hu private val satp = current.satp 36260a087dSXuan Hu private val vsatp = current.vsatp 37260a087dSXuan Hu private val hgatp = current.hgatp 38237d4cfdSXuan Hu 39237d4cfdSXuan Hu private val highPrioTrapNO = in.causeNO.ExceptionCode.asUInt 40237d4cfdSXuan Hu private val isException = !in.causeNO.Interrupt.asBool 41237d4cfdSXuan Hu private val isInterrupt = in.causeNO.Interrupt.asBool 42237d4cfdSXuan Hu 43260a087dSXuan Hu private val trapPC = genTrapVA( 44260a087dSXuan Hu iMode, 45260a087dSXuan Hu satp, 46260a087dSXuan Hu vsatp, 47260a087dSXuan Hu hgatp, 48260a087dSXuan Hu in.trapPc, 49260a087dSXuan Hu ) 50260a087dSXuan Hu 51dd980d61SXu, Zefan private val trapPCGPA = in.trapPcGPA 52bfac3305Speixiaokun 53db6cfb5aSHaoyuan Feng private val trapMemVA = in.memExceptionVAddr 54260a087dSXuan Hu 55db6cfb5aSHaoyuan Feng private val trapMemGPA = in.memExceptionGPAddr 56237d4cfdSXuan Hu 5792c61038SXuan Hu private val trapInst = Mux(in.trapInst.valid, in.trapInst.bits, 0.U) 5892c61038SXuan Hu 59237d4cfdSXuan Hu private val fetchIsVirt = current.iMode.isVirtual 60237d4cfdSXuan Hu private val memIsVirt = current.dMode.isVirtual 61237d4cfdSXuan Hu 62f60da58cSXuan Hu private val isFetchExcp = isException && ExceptionNO.getFetchFault.map(_.U === highPrioTrapNO).reduce(_ || _) 63f60da58cSXuan Hu private val isMemExcp = isException && (ExceptionNO.getLoadFault ++ ExceptionNO.getStoreFault).map(_.U === highPrioTrapNO).reduce(_ || _) 64f60da58cSXuan Hu private val isBpExcp = isException && ExceptionNO.EX_BP.U === highPrioTrapNO 65fe52823cSXuan Hu private val isFetchBkpt = isBpExcp && in.isFetchBkpt 66fe52823cSXuan Hu private val isMemBkpt = isBpExcp && !in.isFetchBkpt 67f60da58cSXuan Hu private val isHlsExcp = isException && in.isHls 68237d4cfdSXuan Hu private val fetchCrossPage = in.isCrossPageIPF 69c1b28b66STang Haojin private val isFetchMalAddr = in.isFetchMalAddr 70*21e8685bSZhaoyang You private val isFetchMalAddrExcp = isException && isFetchMalAddr 71e0bc5040Slewislzh private val isIllegalInst = isException && (ExceptionNO.EX_II.U === highPrioTrapNO || ExceptionNO.EX_VI.U === highPrioTrapNO) 72237d4cfdSXuan Hu 73bfac3305Speixiaokun private val isLSGuestExcp = isException && ExceptionNO.getLSGuestPageFault.map(_.U === highPrioTrapNO).reduce(_ || _) 74bfac3305Speixiaokun private val isFetchGuestExcp = isException && ExceptionNO.EX_IGPF.U === highPrioTrapNO 75237d4cfdSXuan Hu // Software breakpoint exceptions are permitted to write either 0 or the pc to xtval 76237d4cfdSXuan Hu // We fill pc here 77fe52823cSXuan Hu private val tvalFillPc = (isFetchExcp || isFetchGuestExcp) && !fetchCrossPage || isFetchBkpt 78bfac3305Speixiaokun private val tvalFillPcPlus2 = (isFetchExcp || isFetchGuestExcp) && fetchCrossPage 79fe52823cSXuan Hu private val tvalFillMemVaddr = isMemExcp || isMemBkpt 80f60da58cSXuan Hu private val tvalFillGVA = 81f60da58cSXuan Hu isHlsExcp && isMemExcp || 82bfac3305Speixiaokun isLSGuestExcp|| isFetchGuestExcp || 83fe52823cSXuan Hu (isFetchExcp || isFetchBkpt) && fetchIsVirt || 84fe52823cSXuan Hu (isMemExcp || isMemBkpt) && memIsVirt 85fa16cf81Slewislzh private val tvalFillInst = isIllegalInst 86237d4cfdSXuan Hu 87237d4cfdSXuan Hu private val tval = Mux1H(Seq( 88237d4cfdSXuan Hu (tvalFillPc ) -> trapPC, 89237d4cfdSXuan Hu (tvalFillPcPlus2 ) -> (trapPC + 2.U), 90cfa16394Schengguanghui (tvalFillMemVaddr || isLSGuestExcp ) -> trapMemVA, 9192c61038SXuan Hu (tvalFillInst ) -> trapInst, 92237d4cfdSXuan Hu )) 93237d4cfdSXuan Hu 94bfac3305Speixiaokun private val tval2 = Mux1H(Seq( 95c1b28b66STang Haojin (isFetchGuestExcp && isFetchMalAddr ) -> in.fetchMalTval, 96c1b28b66STang Haojin (isFetchGuestExcp && !isFetchMalAddr && !fetchCrossPage) -> trapPCGPA, 97c1b28b66STang Haojin (isFetchGuestExcp && !isFetchMalAddr && fetchCrossPage ) -> (trapPCGPA + 2.U), 98bfac3305Speixiaokun (isLSGuestExcp ) -> trapMemGPA, 99bfac3305Speixiaokun )) 100237d4cfdSXuan Hu 101c1b28b66STang Haojin private val instrAddrTransType = AddrTransType( 102c1b28b66STang Haojin bare = satp.MODE === SatpMode.Bare, 103c1b28b66STang Haojin sv39 = satp.MODE === SatpMode.Sv39, 104c1b28b66STang Haojin sv48 = satp.MODE === SatpMode.Sv48, 105c1b28b66STang Haojin sv39x4 = false.B, 106c1b28b66STang Haojin sv48x4 = false.B 107c1b28b66STang Haojin ) 108c1b28b66STang Haojin 109237d4cfdSXuan Hu out := DontCare 110237d4cfdSXuan Hu 111237d4cfdSXuan Hu out.privState.valid := valid 112237d4cfdSXuan Hu out.mstatus .valid := valid 113237d4cfdSXuan Hu out.hstatus .valid := valid 114237d4cfdSXuan Hu out.sepc .valid := valid 115237d4cfdSXuan Hu out.scause .valid := valid 116237d4cfdSXuan Hu out.stval .valid := valid 117237d4cfdSXuan Hu out.htval .valid := valid 1183fcb681eSXuan Hu out.htinst .valid := valid 1190c2ba7aeSXuan Hu out.targetPc .valid := valid 120237d4cfdSXuan Hu 121237d4cfdSXuan Hu out.privState.bits := PrivState.ModeHS 122237d4cfdSXuan Hu // mstatus 123237d4cfdSXuan Hu out.mstatus.bits.SPP := current.privState.PRVM.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width 124237d4cfdSXuan Hu out.mstatus.bits.SPIE := current.sstatus.SIE 125237d4cfdSXuan Hu out.mstatus.bits.SIE := 0.U 1266808b803SZehao Liu out.mstatus.bits.SDT := in.menvcfg.DTE.asBool // when DTE open set SDT to 1, else SDT is readonly 0 127237d4cfdSXuan Hu // hstatus 128237d4cfdSXuan Hu out.hstatus.bits.SPV := current.privState.V 129237d4cfdSXuan Hu // SPVP is not PrivMode enum type, so asUInt and shrink the width 130237d4cfdSXuan Hu out.hstatus.bits.SPVP := Mux(!current.privState.isVirtual, in.hstatus.SPVP.asUInt, current.privState.PRVM.asUInt(0, 0)) 131237d4cfdSXuan Hu out.hstatus.bits.GVA := tvalFillGVA 132c1b28b66STang Haojin out.sepc.bits.epc := Mux(isFetchMalAddr, in.fetchMalTval(63, 1), trapPC(63, 1)) 133237d4cfdSXuan Hu out.scause.bits.Interrupt := isInterrupt 134237d4cfdSXuan Hu out.scause.bits.ExceptionCode := highPrioTrapNO 135*21e8685bSZhaoyang You out.stval.bits.ALL := Mux(isFetchMalAddrExcp, in.fetchMalTval, tval) 136bcd1ace8SXuan Hu out.htval.bits.ALL := tval2 >> 2 137ad415ae0SXiaokun-Pei out.htinst.bits.ALL := Mux(isFetchGuestExcp && in.trapIsForVSnonLeafPTE || isLSGuestExcp && in.memExceptionIsForVSnonLeafPTE, 0x3000.U, 0.U) 138c1b28b66STang Haojin out.targetPc.bits.pc := in.pcFromXtvec 139c1b28b66STang Haojin out.targetPc.bits.raiseIPF := instrAddrTransType.checkPageFault(in.pcFromXtvec) 140c1b28b66STang Haojin out.targetPc.bits.raiseIAF := instrAddrTransType.checkAccessFault(in.pcFromXtvec) 141c1b28b66STang Haojin out.targetPc.bits.raiseIGPF := false.B 142237d4cfdSXuan Hu 143bfac3305Speixiaokun dontTouch(isLSGuestExcp) 144237d4cfdSXuan Hu dontTouch(tvalFillGVA) 145237d4cfdSXuan Hu} 146237d4cfdSXuan Hu 147cb36ac0fSXuan Hutrait TrapEntryHSEventSinkBundle extends EventSinkBundle { self: CSRModule[_ <: CSRBundle] => 148237d4cfdSXuan Hu val trapToHS = IO(Flipped(new TrapEntryHSEventOutput)) 149237d4cfdSXuan Hu 150cb36ac0fSXuan Hu addUpdateBundleInCSREnumType(trapToHS.getBundleByName(self.modName.toLowerCase())) 151237d4cfdSXuan Hu 152cb36ac0fSXuan Hu reconnectReg() 153237d4cfdSXuan Hu} 154