xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/VirtualSupervisorLevel.scala (revision a37e0a1f6cf8ad05137574a379cf2775ab390c20)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import utility.SignExt
6import xiangshan.backend.fu.NewCSR.CSRBundles._
7import xiangshan.backend.fu.NewCSR.CSRDefines.{
8  CSRRWField => RW,
9  CSRROField => RO,
10  CSRWLRLField => WLRL,
11  CSRWARLField => WARL,
12  _
13}
14import xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast.CSREnumTypeToUInt
15import xiangshan.backend.fu.NewCSR.CSREvents.{SretEventSinkBundle, TrapEntryVSEventSinkBundle}
16
17import scala.collection.immutable.SeqMap
18
19trait VirtualSupervisorLevel { self: NewCSR with SupervisorLevel with HypervisorLevel =>
20
21  val vsstatus = Module(
22    new CSRModule("VSstatus", new SstatusBundle)
23      with SretEventSinkBundle
24      with TrapEntryVSEventSinkBundle
25  )
26    .setAddr(0x200)
27
28  val vsie = Module(new CSRModule("VSie", new VSie) with HypervisorBundle {
29    val toHie = IO(new VSieToHie)
30    // read alias of hie is here, write alias will be in hie
31    regOut.SEIE := Mux(hideleg.VSEI.asUInt === 0.U, 0.U, hie.VSEIE.asUInt)
32    regOut.STIE := Mux(hideleg.VSTI.asUInt === 0.U, 0.U, hie.VSTIE.asUInt)
33    regOut.SSIE := Mux(hideleg.VSSI.asUInt === 0.U, 0.U, hie.VSSIE.asUInt)
34
35    toHie.SEIE.valid := wen && hideleg.VSEI.asUInt.asBool
36    toHie.STIE.valid := wen && hideleg.VSTI.asUInt.asBool
37    toHie.SSIE.valid := wen && hideleg.VSSI.asUInt.asBool
38    toHie.SEIE.bits := wdata.SEIE
39    toHie.STIE.bits := wdata.STIE
40    toHie.SSIE.bits := wdata.SSIE
41  }).setAddr(0x204)
42
43  hie.fromVSie := vsie.toHie
44
45  val vstvec = Module(new CSRModule("VStvec", new XtvecBundle))
46    .setAddr(0x205)
47
48  val vsscratch = Module(new CSRModule("VSscratch"))
49    .setAddr(0x240)
50
51  val vsepc = Module(
52    new CSRModule("VSepc", new Epc)
53      with TrapEntryVSEventSinkBundle
54    {
55      rdata := SignExt(Cat(reg.epc.asUInt, 0.U(1.W)), XLEN)
56    }
57  )
58    .setAddr(0x241)
59
60  val vscause = Module(
61    new CSRModule("VScause", new CauseBundle)
62      with TrapEntryVSEventSinkBundle
63  )
64    .setAddr(0x242)
65
66  // Todo: shrink the width of vstval to the maximum width Virtual Address
67  val vstval = Module(
68    new CSRModule("VStval")
69      with TrapEntryVSEventSinkBundle
70  )
71    .setAddr(0x243)
72
73  val vsip = Module(new CSRModule("VSip", new VSip) with HypervisorBundle {
74    val toHip = IO(new VSipToHip)
75    // read alias of hip is here, write alias will be in hvip
76    // hip.VSEIP is read-only zero when hideleg.VSEI=0, alias if hip.VSEIP when hideleg.VSEI=1
77    regOut.SEIP := Mux(hideleg.VSEI.asUInt === 0.U, 0.U, hip.VSEIP.asUInt)
78    // hip.VSTIP is read-only zero when hideleg.VSTI=0, alias if hip.VSTIP when hideleg.VSTI=1
79    regOut.STIP := Mux(hideleg.VSTI.asUInt === 0.U, 0.U, hip.VSTIP.asUInt)
80    // hip.VSSIP is read-only zero when hideleg.VSSI=0, alias (writable) of the same bit in hvip, when hideleg.VSSI=1
81    regOut.SSIP := Mux(hideleg.VSSI.asUInt === 0.U, 0.U, hip.VSSIP.asUInt)
82
83    toHip.SEIP.valid := wen && hideleg.VSEI.asUInt.asBool
84    toHip.STIP.valid := wen && hideleg.VSTI.asUInt.asBool
85    toHip.SSIP.valid := wen && hideleg.VSSI.asUInt.asBool
86    toHip.SEIP.bits := wdata.SEIP
87    toHip.STIP.bits := wdata.STIP
88    toHip.SSIP.bits := wdata.SSIP
89  }).setAddr(0x244)
90
91  hip.fromVSip := vsip.toHip
92
93  val vstimecmp = Module(new CSRModule("VStimecmp"))
94    .setAddr(0x24D)
95
96  val vsatp = Module(new CSRModule("VSatp", new SatpBundle) {
97    // Ref: 13.2.18. Virtual Supervisor Address Translation and Protection Register (vsatp)
98    // When V=0, a write to vsatp with an unsupported MODE value is either ignored as it is for satp, or the
99    // fields of vsatp are treated as WARL in the normal way.
100    // However, when V=1, a write to satp with an unsupported MODE value is ignored and no write to vsatp is effected.
101    // if satp is written with an unsupported MODE, the entire write has no effect; no fields in satp are modified.
102    //
103    // We treat all circumstances as if V=1. That is if vsatp is written with an unsupported MODE,
104    // the entire write has no effect; no fields in satp are modified.
105    when(wen) {
106      when (wdata.MODE.isLegal) {
107        reg := wdata
108      }
109    }.otherwise {
110      reg := reg
111    }
112  }).setAddr(0x280)
113
114  val virtualSupervisorCSRMods = Seq(
115    vsstatus,
116    vsie,
117    vstvec,
118    vsscratch,
119    vsepc,
120    vscause,
121    vstval,
122    vsip,
123    vstimecmp,
124    vsatp,
125  )
126
127  virtualSupervisorCSRMods.foreach(mod =>
128    require(mod.addr > 0, s"The address of ${mod.modName} has not been set, you can use setAddr(CSRAddr) to set it."))
129
130  val virtualSupervisorCSRMap = SeqMap.from(
131    virtualSupervisorCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata)))
132  )
133
134  val virtualSupervisorCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
135    virtualSupervisorCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt))
136  )
137
138  import freechips.rocketchip.rocket.CSRs
139
140  val sMapVS = SeqMap(
141    CSRs.sstatus  -> CSRs.vsstatus,
142    CSRs.sie      -> CSRs.vsie,
143    CSRs.stvec    -> CSRs.vstvec,
144    CSRs.sscratch -> CSRs.vsscratch,
145    CSRs.sepc     -> CSRs.vsepc,
146    CSRs.scause   -> CSRs.vscause,
147    CSRs.stval    -> CSRs.vstval,
148    CSRs.sip      -> CSRs.vsip,
149    CSRs.stimecmp -> CSRs.vstimecmp,
150    CSRs.siselect -> CSRs.vsiselect,
151    CSRs.sireg    -> CSRs.vsireg,
152    CSRs.stopei   -> CSRs.vstopei,
153    CSRs.satp     -> CSRs.vsatp,
154    CSRs.stopi    -> CSRs.vstopi,
155  )
156
157  val vsMapS: SeqMap[Int, Int] = SeqMap.from(sMapVS.map(x => (x._2 -> x._1)))
158}
159
160class VSip extends InterruptPendingBundle {
161  this.getM.foreach(_.setRO())
162  this.getVS.foreach(_.setRO())
163  this.getSOC.foreach(_.setRO())
164  // 13.2.12. Virtual Supervisor Interrupt Registers (vsip and vsie)
165  // When bit 10 of hideleg is zero, vsip.SEIP is read-only zeros.
166  // Else, vsip.SEIP is alias of hip.VSEIP
167  this.SEIP
168  // When bit 6 of hideleg is zero, vsip.STIP is read-only zeros.
169  // Else, vsip.STIP is alias of hip.VSTIP
170  this.STIP
171  // When bit 2 of hideleg is zero, vsip.SSIP is read-only zeros.
172  // Else, vsip.SSIP is alias of hip.VSSIP
173  this.SEIP
174}
175
176class VSie extends InterruptEnableBundle {
177  this.getM.foreach(_.setRO())
178  this.getVS.foreach(_.setRO())
179  this.getSOC.foreach(_.setRO())
180  // 13.2.12. Virtual Supervisor Interrupt Registers (vsip and vsie)
181  // When bit 10 of hideleg is zero, vsip.SEIE is read-only zeros.
182  // Else, vsip.SEIE is alias of hip.VSEIE
183  this.SSIE
184  // When bit 6 of hideleg is zero, vsip.STIE is read-only zeros.
185  // Else, vsip.STIE is alias of hip.VSTIE
186  this.STIE
187  // When bit 2 of hideleg is zero, vsip.SSIE is read-only zeros.
188  // Else, vsip.SSIE is alias of hip.VSSIE
189  this.SEIE
190}
191
192class VSieToHie extends Bundle {
193  val SSIE: ValidIO[CSREnumType] = ValidIO(RW(0))
194  val STIE: ValidIO[CSREnumType] = ValidIO(RW(0))
195  val SEIE: ValidIO[CSREnumType] = ValidIO(RW(0))
196}
197
198class VSipToHip extends Bundle {
199  val SSIP = ValidIO(RW(0))
200  val STIP = ValidIO(RW(0))
201  val SEIP = ValidIO(RW(0))
202}
203