xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/SretEvent.scala (revision 1bc48dd1fa0af361fd194c65bad3b86349ec2903)
1package xiangshan.backend.fu.NewCSR.CSREvents
2
3import chisel3._
4import chisel3.util._
5import org.chipsalliance.cde.config.Parameters
6import utility.{SignExt, ZeroExt}
7import xiangshan.ExceptionNO
8import xiangshan.ExceptionNO._
9import xiangshan.backend.fu.NewCSR.CSRBundles.{CauseBundle, OneFieldBundle, PrivState}
10import xiangshan.backend.fu.NewCSR.CSRConfig.{VaddrMaxWidth, XLEN}
11import xiangshan.backend.fu.NewCSR.CSRDefines.{HgatpMode, PrivMode, SatpMode, VirtMode}
12import xiangshan.backend.fu.NewCSR._
13import xiangshan.AddrTransType
14
15
16class SretEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase {
17  // Todo: write sstatus instead of mstatus
18  val mstatus = ValidIO((new MstatusBundle).addInEvent(_.SIE, _.SPIE, _.SPP, _.MPRV))
19  val hstatus = ValidIO((new HstatusBundle).addInEvent(_.SPV))
20  val vsstatus = ValidIO((new SstatusBundle).addInEvent(_.SIE, _.SPIE, _.SPP))
21  val targetPc = ValidIO(new TargetPCBundle)
22}
23
24class SretEventInput extends Bundle {
25  val privState = Input(new PrivState)
26  val sstatus   = Input(new SstatusBundle)
27  val hstatus   = Input(new HstatusBundle)
28  val vsstatus  = Input(new SstatusBundle)
29  val sepc      = Input(new Epc())
30  val vsepc     = Input(new Epc())
31  val satp      = Input(new SatpBundle)
32  val vsatp     = Input(new SatpBundle)
33  val hgatp     = Input(new HgatpBundle)
34}
35
36class SretEventModule(implicit p: Parameters) extends Module with CSREventBase {
37  val in = IO(new SretEventInput)
38  val out = IO(new SretEventOutput)
39
40  private val satp = in.satp
41  private val vsatp = in.vsatp
42  private val hgatp = in.hgatp
43  private val nextPrivState = out.privState.bits
44
45  private val instrAddrTransType = AddrTransType(
46    bare = (!nextPrivState.isVirtual && satp.MODE === SatpMode.Bare) ||
47           (nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Bare),
48    sv39 = !nextPrivState.isVirtual && satp.MODE === SatpMode.Sv39 ||
49           nextPrivState.isVirtual && vsatp.MODE === SatpMode.Sv39,
50    sv48 = !nextPrivState.isVirtual && satp.MODE === SatpMode.Sv48 ||
51           nextPrivState.isVirtual && vsatp.MODE === SatpMode.Sv48,
52    sv39x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv39x4,
53    sv48x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv48x4
54  )
55
56  private val sretInHSorM = in.privState.isModeM || in.privState.isModeHS
57  private val sretInVS    = in.privState.isModeVS
58
59  private val xepc = Mux1H(Seq(
60    sretInHSorM -> in.sepc,
61    sretInVS    -> in.vsepc,
62  )).asUInt
63
64  out := DontCare
65
66  out.privState.valid := valid
67  out.targetPc .valid := valid
68
69  out.privState.bits.PRVM     := Mux1H(Seq(
70    // SPP is not PrivMode enum type, so asUInt
71    sretInHSorM -> in.sstatus.SPP.asUInt,
72    sretInVS    -> in.vsstatus.SPP.asUInt,
73  ))
74  out.privState.bits.V        := Mux1H(Seq(
75    sretInHSorM -> in.hstatus.SPV,
76    sretInVS    -> in.privState.V, // keep
77  ))
78
79  // hstatus
80  out.hstatus.valid           := valid && sretInHSorM
81  out.hstatus.bits.SPV        := VirtMode.Off
82
83  // sstatus
84  out.mstatus.valid           := valid && sretInHSorM
85  out.mstatus.bits.SPP        := PrivMode.U.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width
86  out.mstatus.bits.SIE        := in.sstatus.SPIE
87  out.mstatus.bits.SPIE       := 1.U
88  out.mstatus.bits.MPRV       := 0.U // sret will always leave M mode
89
90  // vsstatus
91  out.vsstatus.valid          := valid && sretInVS
92  out.vsstatus.bits.SPP       := PrivMode.U.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width
93  out.vsstatus.bits.SIE       := in.vsstatus.SPIE
94  out.vsstatus.bits.SPIE      := 1.U
95
96  out.targetPc.bits.pc        := xepc
97  out.targetPc.bits.raiseIPF  := instrAddrTransType.checkPageFault(xepc)
98  out.targetPc.bits.raiseIAF  := instrAddrTransType.checkAccessFault(xepc)
99  out.targetPc.bits.raiseIGPF := instrAddrTransType.checkGuestPageFault(xepc)
100
101  // for better verilog
102  dontTouch(sretInHSorM)
103  dontTouch(sretInVS)
104}
105
106trait SretEventSinkBundle extends EventSinkBundle { self: CSRModule[_ <: CSRBundle] =>
107  val retFromS = IO(Flipped(new SretEventOutput))
108
109  addUpdateBundleInCSREnumType(retFromS.getBundleByName(self.modName.toLowerCase()))
110
111  reconnectReg()
112}
113