xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/TrapEntryHSEvent.scala (revision 21e8685b69102452bb454870742496551ca56ad2)
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