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} 7237d4cfdSXuan Huimport xiangshan.ExceptionNO._ 8237d4cfdSXuan Huimport xiangshan.backend.fu.NewCSR.CSRBundles.{CauseBundle, OneFieldBundle, PrivState} 9237d4cfdSXuan Huimport xiangshan.backend.fu.NewCSR.CSRConfig.{VaddrMaxWidth, XLEN} 10c1b28b66STang Haojinimport xiangshan.backend.fu.NewCSR.CSRDefines.{HgatpMode, SatpMode} 11237d4cfdSXuan Huimport xiangshan.backend.fu.NewCSR._ 12c1b28b66STang Haojinimport xiangshan.AddrTransType 13237d4cfdSXuan Hu 14237d4cfdSXuan Hu 15237d4cfdSXuan Huclass TrapEntryVSEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase { 16237d4cfdSXuan Hu 176808b803SZehao Liu val vsstatus = ValidIO((new SstatusBundle ).addInEvent(_.SPP, _.SPIE, _.SIE, _.SDT)) 18260a087dSXuan Hu val vsepc = ValidIO((new Epc ).addInEvent(_.epc)) 19237d4cfdSXuan Hu val vscause = ValidIO((new CauseBundle ).addInEvent(_.Interrupt, _.ExceptionCode)) 20237d4cfdSXuan Hu val vstval = ValidIO((new OneFieldBundle).addInEvent(_.ALL)) 21c1b28b66STang Haojin val targetPc = ValidIO(new TargetPCBundle) 22237d4cfdSXuan Hu} 23237d4cfdSXuan Hu 24237d4cfdSXuan Huclass TrapEntryVSEventModule(implicit val p: Parameters) extends Module with CSREventBase { 25237d4cfdSXuan Hu val in = IO(new TrapEntryEventInput) 26237d4cfdSXuan Hu val out = IO(new TrapEntryVSEventOutput) 27237d4cfdSXuan Hu 28237d4cfdSXuan Hu when (valid) { 29237d4cfdSXuan Hu assert(in.privState.isVirtual, "The mode must be VU or VS when entry VS mode") 30237d4cfdSXuan Hu } 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 3973e616deSXuan Hu private val trapCode = in.causeNO.ExceptionCode.asUInt 40237d4cfdSXuan Hu private val isException = !in.causeNO.Interrupt.asBool 41237d4cfdSXuan Hu private val isInterrupt = in.causeNO.Interrupt.asBool 429205730dSsinceforYy private val virtualInterruptIsHvictlInject = in.virtualInterruptIsHvictlInject 439205730dSsinceforYy private val hvictlIID = in.hvictlIID 44237d4cfdSXuan Hu 459205730dSsinceforYy when(valid && isInterrupt && !virtualInterruptIsHvictlInject) { 4673e616deSXuan Hu assert( 4737e0d55eSsinceforYy (InterruptNO.getVS ++ InterruptNO.getLocal).map(_.U === trapCode).reduce(_ || _), 4873e616deSXuan Hu "The VS mode can only handle VSEI, VSTI, VSSI and local interrupts" 4973e616deSXuan Hu ) 5073e616deSXuan Hu } 5173e616deSXuan Hu 5273e616deSXuan Hu private val highPrioTrapNO = Mux( 5356f793a7Slewislzh InterruptNO.getVS.map(_.U === trapCode).reduce(_ || _) && isInterrupt, 5473e616deSXuan Hu trapCode - 1.U, // map VSSIP, VSTIP, VSEIP to SSIP, STIP, SEIP 5573e616deSXuan Hu trapCode, 5673e616deSXuan Hu ) 5773e616deSXuan Hu 58260a087dSXuan Hu private val trapPC = genTrapVA( 59260a087dSXuan Hu iMode, 60260a087dSXuan Hu satp, 61260a087dSXuan Hu vsatp, 62260a087dSXuan Hu hgatp, 63260a087dSXuan Hu in.trapPc, 64260a087dSXuan Hu ) 65260a087dSXuan Hu 66db6cfb5aSHaoyuan Feng private val trapMemVA = in.memExceptionVAddr 67db6cfb5aSHaoyuan Feng 68db6cfb5aSHaoyuan Feng private val trapMemGPA = in.memExceptionGPAddr 69237d4cfdSXuan Hu 7092c61038SXuan Hu private val trapInst = Mux(in.trapInst.valid, in.trapInst.bits, 0.U) 7192c61038SXuan Hu 72237d4cfdSXuan Hu private val fetchIsVirt = current.iMode.isVirtual 73237d4cfdSXuan Hu private val memIsVirt = current.dMode.isVirtual 74237d4cfdSXuan Hu 75237d4cfdSXuan Hu private val isFetchExcp = isException && Seq(/*EX_IAM, */ EX_IAF, EX_IPF).map(_.U === highPrioTrapNO).reduce(_ || _) 76237d4cfdSXuan Hu private val isMemExcp = isException && Seq(EX_LAM, EX_LAF, EX_SAM, EX_SAF, EX_LPF, EX_SPF).map(_.U === highPrioTrapNO).reduce(_ || _) 77237d4cfdSXuan Hu private val isBpExcp = isException && EX_BP.U === highPrioTrapNO 78fe52823cSXuan Hu private val isFetchBkpt = isBpExcp && in.isFetchBkpt 79fe52823cSXuan Hu private val isMemBkpt = isBpExcp && !in.isFetchBkpt 80237d4cfdSXuan Hu private val fetchCrossPage = in.isCrossPageIPF 81c1b28b66STang Haojin private val isFetchMalAddr = in.isFetchMalAddr 82*21e8685bSZhaoyang You private val isFetchMalAddrExcp = isException && isFetchMalAddr 83e0bc5040Slewislzh private val isIllegalInst = isException && (EX_II.U === highPrioTrapNO || EX_VI.U === highPrioTrapNO) 84237d4cfdSXuan Hu 85237d4cfdSXuan Hu // Software breakpoint exceptions are permitted to write either 0 or the pc to xtval 86237d4cfdSXuan Hu // We fill pc here 87fe52823cSXuan Hu private val tvalFillPc = isFetchExcp && !fetchCrossPage || isFetchBkpt 88237d4cfdSXuan Hu private val tvalFillPcPlus2 = isFetchExcp && fetchCrossPage 89be29197cSchengguanghui private val tvalFillMemVaddr = isMemExcp || isMemBkpt 90237d4cfdSXuan Hu private val tvalFillGVA = 91fe52823cSXuan Hu (isFetchExcp || isFetchBkpt) && fetchIsVirt || 92fe52823cSXuan Hu (isMemExcp || isMemBkpt) && memIsVirt 93fa16cf81Slewislzh private val tvalFillInst = isIllegalInst 94237d4cfdSXuan Hu 95237d4cfdSXuan Hu private val tval = Mux1H(Seq( 96cfa16394Schengguanghui tvalFillPc -> trapPC, 97cfa16394Schengguanghui tvalFillPcPlus2 -> (trapPC + 2.U), 98cfa16394Schengguanghui tvalFillMemVaddr -> trapMemVA, 99cfa16394Schengguanghui tvalFillInst -> trapInst, 100237d4cfdSXuan Hu )) 101237d4cfdSXuan Hu 102c1b28b66STang Haojin private val instrAddrTransType = AddrTransType( 103c1b28b66STang Haojin bare = vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Bare, 104c1b28b66STang Haojin sv39 = vsatp.MODE === SatpMode.Sv39, 105c1b28b66STang Haojin sv48 = vsatp.MODE === SatpMode.Sv48, 106c1b28b66STang Haojin sv39x4 = vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv39x4, 107c1b28b66STang Haojin sv48x4 = vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv48x4 108c1b28b66STang Haojin ) 109c1b28b66STang Haojin 110237d4cfdSXuan Hu out := DontCare 111237d4cfdSXuan Hu 112237d4cfdSXuan Hu out.privState.valid := valid 113237d4cfdSXuan Hu 114237d4cfdSXuan Hu out.vsstatus .valid := valid 115237d4cfdSXuan Hu out.vsepc .valid := valid 116237d4cfdSXuan Hu out.vscause .valid := valid 117237d4cfdSXuan Hu out.vstval .valid := valid 1180c2ba7aeSXuan Hu out.targetPc .valid := valid 119237d4cfdSXuan Hu 120237d4cfdSXuan Hu out.privState.bits := PrivState.ModeVS 121237d4cfdSXuan Hu // vsstatus 122237d4cfdSXuan Hu out.vsstatus.bits.SPP := current.privState.PRVM.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width 123237d4cfdSXuan Hu out.vsstatus.bits.SPIE := current.vsstatus.SIE 124237d4cfdSXuan Hu out.vsstatus.bits.SIE := 0.U 1256808b803SZehao Liu out.vsstatus.bits.SDT := in.henvcfg.DTE.asBool // when DTE open set SDT to 1, else SDT is readonly 0 126237d4cfdSXuan Hu // SPVP is not PrivMode enum type, so asUInt and shrink the width 127c1b28b66STang Haojin out.vsepc.bits.epc := Mux(isFetchMalAddr, in.fetchMalTval(63, 1), trapPC(63, 1)) 128237d4cfdSXuan Hu out.vscause.bits.Interrupt := isInterrupt 1299205730dSsinceforYy out.vscause.bits.ExceptionCode := Mux(virtualInterruptIsHvictlInject, hvictlIID, highPrioTrapNO) 130*21e8685bSZhaoyang You out.vstval.bits.ALL := Mux(isFetchMalAddrExcp, in.fetchMalTval, tval) 131c1b28b66STang Haojin out.targetPc.bits.pc := in.pcFromXtvec 132c1b28b66STang Haojin out.targetPc.bits.raiseIPF := instrAddrTransType.checkPageFault(in.pcFromXtvec) 133c1b28b66STang Haojin out.targetPc.bits.raiseIAF := instrAddrTransType.checkAccessFault(in.pcFromXtvec) 134c1b28b66STang Haojin out.targetPc.bits.raiseIGPF := instrAddrTransType.checkGuestPageFault(in.pcFromXtvec) 135237d4cfdSXuan Hu 136237d4cfdSXuan Hu dontTouch(tvalFillGVA) 137237d4cfdSXuan Hu} 138237d4cfdSXuan Hu 139cb36ac0fSXuan Hutrait TrapEntryVSEventSinkBundle extends EventSinkBundle { self: CSRModule[_ <: CSRBundle] => 140237d4cfdSXuan Hu val trapToVS = IO(Flipped(new TrapEntryVSEventOutput)) 141237d4cfdSXuan Hu 142cb36ac0fSXuan Hu addUpdateBundleInCSREnumType(trapToVS.getBundleByName(self.modName.toLowerCase())) 143237d4cfdSXuan Hu 144cb36ac0fSXuan Hu reconnectReg() 145237d4cfdSXuan Hu} 146