1237d4cfdSXuan Hupackage xiangshan.backend.fu.NewCSR.CSREvents 2237d4cfdSXuan Hu 3237d4cfdSXuan Huimport chisel3._ 4237d4cfdSXuan Huimport chisel3.util._ 5237d4cfdSXuan Huimport org.chipsalliance.cde.config.Parameters 6260a087dSXuan Huimport utility.SignExt 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._ 11c1b28b66STang Haojinimport xiangshan.AddrTransType 12237d4cfdSXuan Hu 13237d4cfdSXuan Hu 14237d4cfdSXuan Huclass TrapEntryMEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase { 15237d4cfdSXuan Hu 166808b803SZehao Liu val mstatus = ValidIO((new MstatusBundle ).addInEvent(_.MPV, _.MPP, _.GVA, _.MPIE, _.MIE, _.MDT)) 17260a087dSXuan Hu val mepc = ValidIO((new Epc ).addInEvent(_.epc)) 18237d4cfdSXuan Hu val mcause = ValidIO((new CauseBundle ).addInEvent(_.Interrupt, _.ExceptionCode)) 19237d4cfdSXuan Hu val mtval = ValidIO((new OneFieldBundle).addInEvent(_.ALL)) 20237d4cfdSXuan Hu val mtval2 = ValidIO((new OneFieldBundle).addInEvent(_.ALL)) 21237d4cfdSXuan Hu val mtinst = ValidIO((new OneFieldBundle).addInEvent(_.ALL)) 22c1b28b66STang Haojin val targetPc = ValidIO(new TargetPCBundle) 23237d4cfdSXuan Hu} 24237d4cfdSXuan Hu 25237d4cfdSXuan Huclass TrapEntryMEventModule(implicit val p: Parameters) extends Module with CSREventBase { 26237d4cfdSXuan Hu val in = IO(new TrapEntryEventInput) 27237d4cfdSXuan Hu val out = IO(new TrapEntryMEventOutput) 28237d4cfdSXuan Hu 29237d4cfdSXuan Hu private val current = in 30260a087dSXuan Hu private val iMode = current.iMode 31260a087dSXuan Hu private val dMode = current.dMode 32260a087dSXuan Hu private val satp = current.satp 33260a087dSXuan Hu private val vsatp = current.vsatp 34260a087dSXuan Hu private val hgatp = current.hgatp 356808b803SZehao Liu private val isDTExcp = current.hasDTExcp 36237d4cfdSXuan Hu 37237d4cfdSXuan Hu private val highPrioTrapNO = in.causeNO.ExceptionCode.asUInt 38237d4cfdSXuan Hu private val isException = !in.causeNO.Interrupt.asBool 39237d4cfdSXuan Hu private val isInterrupt = in.causeNO.Interrupt.asBool 40237d4cfdSXuan Hu 41260a087dSXuan Hu private val trapPC = genTrapVA( 42260a087dSXuan Hu iMode, 43260a087dSXuan Hu satp, 44260a087dSXuan Hu vsatp, 45260a087dSXuan Hu hgatp, 46260a087dSXuan Hu in.trapPc, 47260a087dSXuan Hu ) 48237d4cfdSXuan Hu 49dd980d61SXu, Zefan private val trapPCGPA = in.trapPcGPA 50bfac3305Speixiaokun 51db6cfb5aSHaoyuan Feng private val trapMemVA = in.memExceptionVAddr 52260a087dSXuan Hu 53db6cfb5aSHaoyuan Feng private val trapMemGPA = in.memExceptionGPAddr 54260a087dSXuan Hu 5592c61038SXuan Hu private val trapInst = Mux(in.trapInst.valid, in.trapInst.bits, 0.U) 5692c61038SXuan Hu 57260a087dSXuan Hu private val fetchIsVirt = iMode.isVirtual 58260a087dSXuan Hu private val memIsVirt = dMode.isVirtual 59237d4cfdSXuan Hu 60f60da58cSXuan Hu private val isFetchExcp = isException && ExceptionNO.getFetchFault.map(_.U === highPrioTrapNO).reduce(_ || _) 61f60da58cSXuan Hu private val isMemExcp = isException && (ExceptionNO.getLoadFault ++ ExceptionNO.getStoreFault).map(_.U === highPrioTrapNO).reduce(_ || _) 62f60da58cSXuan Hu private val isBpExcp = isException && ExceptionNO.EX_BP.U === highPrioTrapNO 63fe52823cSXuan Hu private val isFetchBkpt = isBpExcp && in.isFetchBkpt 64fe52823cSXuan Hu private val isMemBkpt = isBpExcp && !in.isFetchBkpt 65f60da58cSXuan Hu private val isHlsExcp = isException && in.isHls 66237d4cfdSXuan Hu private val fetchCrossPage = in.isCrossPageIPF 67c1b28b66STang Haojin private val isFetchMalAddr = in.isFetchMalAddr 68*21e8685bSZhaoyang You private val isFetchMalAddrExcp = isException && isFetchMalAddr 69e0bc5040Slewislzh private val isIllegalInst = isException && (ExceptionNO.EX_II.U === highPrioTrapNO || ExceptionNO.EX_VI.U === highPrioTrapNO) 70237d4cfdSXuan Hu 71bfac3305Speixiaokun private val isLSGuestExcp = isException && ExceptionNO.getLSGuestPageFault.map(_.U === highPrioTrapNO).reduce(_ || _) 72bfac3305Speixiaokun private val isFetchGuestExcp = isException && ExceptionNO.EX_IGPF.U === highPrioTrapNO 73237d4cfdSXuan Hu // Software breakpoint exceptions are permitted to write either 0 or the pc to xtval 74237d4cfdSXuan Hu // We fill pc here 75fe52823cSXuan Hu private val tvalFillPc = (isFetchExcp || isFetchGuestExcp) && !fetchCrossPage || isFetchBkpt 76bfac3305Speixiaokun private val tvalFillPcPlus2 = (isFetchExcp || isFetchGuestExcp) && fetchCrossPage 77fe52823cSXuan Hu private val tvalFillMemVaddr = isMemExcp || isMemBkpt 78f60da58cSXuan Hu private val tvalFillGVA = 79f60da58cSXuan Hu isHlsExcp && isMemExcp || 80bfac3305Speixiaokun isLSGuestExcp|| isFetchGuestExcp || 81fe52823cSXuan Hu (isFetchExcp || isFetchBkpt) && fetchIsVirt || 82fe52823cSXuan Hu (isMemExcp || isMemBkpt) && memIsVirt 83fa16cf81Slewislzh private val tvalFillInst = isIllegalInst 84237d4cfdSXuan Hu 85237d4cfdSXuan Hu private val tval = Mux1H(Seq( 86237d4cfdSXuan Hu (tvalFillPc ) -> trapPC, 87237d4cfdSXuan Hu (tvalFillPcPlus2 ) -> (trapPC + 2.U), 88cfa16394Schengguanghui (tvalFillMemVaddr || isLSGuestExcp ) -> trapMemVA, 8992c61038SXuan Hu (tvalFillInst ) -> trapInst, 90237d4cfdSXuan Hu )) 91237d4cfdSXuan Hu 92bfac3305Speixiaokun private val tval2 = Mux1H(Seq( 93c1b28b66STang Haojin (isFetchGuestExcp && isFetchMalAddr ) -> in.fetchMalTval, 94c1b28b66STang Haojin (isFetchGuestExcp && !isFetchMalAddr && !fetchCrossPage) -> trapPCGPA, 95c1b28b66STang Haojin (isFetchGuestExcp && !isFetchMalAddr && fetchCrossPage ) -> (trapPCGPA + 2.U), 96bfac3305Speixiaokun (isLSGuestExcp ) -> trapMemGPA, 97bfac3305Speixiaokun )) 98237d4cfdSXuan Hu 996808b803SZehao Liu private val precause = Cat(isInterrupt, highPrioTrapNO) 1006808b803SZehao Liu 101237d4cfdSXuan Hu out := DontCare 102237d4cfdSXuan Hu 103237d4cfdSXuan Hu out.privState.valid := valid 104237d4cfdSXuan Hu out.mstatus .valid := valid 105237d4cfdSXuan Hu out.mepc .valid := valid 106237d4cfdSXuan Hu out.mcause .valid := valid 107237d4cfdSXuan Hu out.mtval .valid := valid 108237d4cfdSXuan Hu out.mtval2 .valid := valid 109eab0a692SXuan Hu out.mtinst .valid := valid 1100c2ba7aeSXuan Hu out.targetPc .valid := valid 111237d4cfdSXuan Hu 112237d4cfdSXuan Hu out.privState.bits := PrivState.ModeM 113237d4cfdSXuan Hu out.mstatus.bits.MPV := current.privState.V 114237d4cfdSXuan Hu out.mstatus.bits.MPP := current.privState.PRVM 115237d4cfdSXuan Hu out.mstatus.bits.GVA := tvalFillGVA 116237d4cfdSXuan Hu out.mstatus.bits.MPIE := current.mstatus.MIE 117237d4cfdSXuan Hu out.mstatus.bits.MIE := 0.U 1186808b803SZehao Liu out.mstatus.bits.MDT := 1.U 119c1b28b66STang Haojin out.mepc.bits.epc := Mux(isFetchMalAddr, in.fetchMalTval(63, 1), trapPC(63, 1)) 120237d4cfdSXuan Hu out.mcause.bits.Interrupt := isInterrupt 1216808b803SZehao Liu out.mcause.bits.ExceptionCode := Mux(isDTExcp, ExceptionNO.EX_DT.U, highPrioTrapNO) 122*21e8685bSZhaoyang You out.mtval.bits.ALL := Mux(isFetchMalAddrExcp, in.fetchMalTval, tval) 1236808b803SZehao Liu out.mtval2.bits.ALL := Mux(isDTExcp, precause, tval2 >> 2) 124ad415ae0SXiaokun-Pei out.mtinst.bits.ALL := Mux(isFetchGuestExcp && in.trapIsForVSnonLeafPTE || isLSGuestExcp && in.memExceptionIsForVSnonLeafPTE, 0x3000.U, 0.U) 125c1b28b66STang Haojin out.targetPc.bits.pc := in.pcFromXtvec 126c1b28b66STang Haojin out.targetPc.bits.raiseIPF := false.B 127c1b28b66STang Haojin out.targetPc.bits.raiseIAF := AddrTransType(bare = true).checkAccessFault(in.pcFromXtvec) 128c1b28b66STang Haojin out.targetPc.bits.raiseIGPF := false.B 129237d4cfdSXuan Hu 130bfac3305Speixiaokun dontTouch(isLSGuestExcp) 131237d4cfdSXuan Hu dontTouch(tvalFillGVA) 132237d4cfdSXuan Hu} 133237d4cfdSXuan Hu 134cb36ac0fSXuan Hutrait TrapEntryMEventSinkBundle extends EventSinkBundle { self: CSRModule[_ <: CSRBundle] => 135237d4cfdSXuan Hu val trapToM = IO(Flipped(new TrapEntryMEventOutput)) 136237d4cfdSXuan Hu 137cb36ac0fSXuan Hu addUpdateBundleInCSREnumType(trapToM.getBundleByName(self.modName.toLowerCase())) 138237d4cfdSXuan Hu 139cb36ac0fSXuan Hu reconnectReg() 140237d4cfdSXuan Hu} 141