xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/HypervisorLevel.scala (revision 211d620b07edb797ba35b635d24fef4e7294bae2)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import freechips.rocketchip.rocket.CSRs
6import org.chipsalliance.cde.config.Parameters
7import utility.ZeroExt
8import xiangshan.backend.fu.NewCSR.CSRBundles._
9import xiangshan.backend.fu.NewCSR.CSRConfig._
10import xiangshan.backend.fu.NewCSR.CSRDefines.{CSRROField => RO, CSRRWField => RW, _}
11import xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._
12import xiangshan.backend.fu.NewCSR.CSREvents.{SretEventSinkBundle, TrapEntryHSEventSinkBundle}
13import xiangshan.backend.fu.NewCSR.CSRFunc._
14import xiangshan.backend.fu.NewCSR.ChiselRecordForField._
15
16import scala.collection.immutable.SeqMap
17
18trait HypervisorLevel { self: NewCSR =>
19
20  val hstatus = Module(new HstatusModule)
21    .setAddr(CSRs.hstatus)
22
23  val hedeleg = Module(new CSRModule("Hedeleg", new HedelegBundle))
24    .setAddr(CSRs.hedeleg)
25
26  val hideleg = Module(new CSRModule("Hideleg", new HidelegBundle))
27    .setAddr(CSRs.hideleg)
28
29  val hie = Module(new CSRModule("Hie", new HieBundle)
30    with HasIpIeBundle
31    with HypervisorBundle
32  {
33    val toMie = IO(new HieToMie)
34
35    val mieIsAlias = mideleg
36
37    bundle.getFields.map(_.lsb).foreach { num =>
38      val wtMie  = toMie.getByNum(num)
39      wtMie.specifyField(
40        _.valid := wen && mieIsAlias(num) && wtMie.bits.isRW.B,
41        _.bits  := wen && mieIsAlias(num) && wtMie.bits.isRW.B &< wdata(num),
42      )
43
44      regOut(num) := mieIsAlias(num) && wtMie.bits.isRW.B &< mie(num)
45    }
46  })
47    .setAddr(CSRs.hie)
48
49  val htimedelta = Module(new CSRModule("Htimedelta"))
50    .setAddr(CSRs.htimedelta)
51
52  val hcounteren = Module(new CSRModule("Hcounteren", new Counteren))
53    .setAddr(CSRs.hcounteren)
54
55  val hgeie = Module(new CSRModule("Hgeie", new HgeieBundle))
56    .setAddr(CSRs.hgeie)
57
58  val hvien = Module(new CSRModule("Hvien", new HvienBundle))
59    .setAddr(CSRs.hvien)
60
61  val hvictl = Module(new CSRModule("Hvictl", new HvictlBundle))
62    .setAddr(CSRs.hvictl)
63
64  val henvcfg = Module(new CSRModule("Henvcfg", new HEnvCfg) with HasHypervisorEnvBundle {
65    when(!menvcfg.STCE) {
66      regOut.STCE := 0.U
67    }
68    when(!menvcfg.PBMTE) {
69      regOut.PBMTE := 0.U
70    }
71    when(!menvcfg.DTE) {
72      regOut.DTE := 0.U
73    }
74  }).setAddr(CSRs.henvcfg)
75
76  val htval = Module(new CSRModule("Htval", new XtvalBundle) with TrapEntryHSEventSinkBundle)
77    .setAddr(CSRs.htval)
78
79  val hip = Module(new CSRModule("Hip", new HipBundle)
80    with HypervisorBundle
81    with HasExternalInterruptBundle
82    with HasIpIeBundle
83  {
84    val toHvip = IO(new HipToHvip)
85
86    // hip.VSEIP is read-only alias of mip.VSEIP, mip.VSEIP := hvip.VSEIP|hgeip(VGEIN)|platIR.VSEIP
87    // hip.VSTIP is read-only alias of mip.VSTIP, mip.VSTIP := hvip.VSTIP|time+htimedelta>=vstimecmp
88    // hip.SGEIP is read-only alias of mip.SGEIP, mip.SGEIP := |(hgeip&hgeie)
89    regOut.VSTIP := mip.VSTIP
90    regOut.VSEIP := mip.VSEIP
91    regOut.SGEIP := mip.SGEIP
92
93    // hip.VSSIP is alias of hvip.VSSIP, writable
94    toHvip.VSSIP.valid := wen
95    toHvip.VSSIP.bits  := wdata.VSSIP
96    regOut.VSSIP := this.hvip.VSSIP
97    // vsip.SSIP is alias of hip.VSSIP, so vsip.SSIP is alias of hvip.VSSIP.
98    // vsip.SSIP write throuth to hvip.VSSIP
99  })
100    .setAddr(CSRs.hip)
101
102  val hvip = Module(new CSRModule("Hvip", new HvipBundle) {
103    val fromMip  = IO(Flipped(new MipToHvip))
104    val fromHip  = IO(Flipped(new HipToHvip))
105    val fromVSip = IO(Flipped(new VSipToHvip))
106
107    when (fromMip.VSSIP.valid || fromHip.VSSIP.valid || fromVSip.VSSIP.valid) {
108      reg.VSSIP := Mux1H(Seq(
109        fromMip.VSSIP.valid -> fromMip.VSSIP.bits,
110        fromHip.VSSIP.valid -> fromHip.VSSIP.bits,
111        fromVSip.VSSIP.valid -> fromVSip.VSSIP.bits,
112      ))
113    }
114
115    reg.getLocal zip fromVSip.getLocal foreach { case (rLCIP, vsipLCIP) =>
116      // sip should assert valid when hideleg=0 && hvien=1
117      when(vsipLCIP.valid) {
118        rLCIP := vsipLCIP.bits
119      }
120    }
121  })
122    .setAddr(CSRs.hvip)
123
124  val hviprio1 = Module(new CSRModule("Hviprio1", new Hviprio1Bundle))
125    .setAddr(CSRs.hviprio1)
126
127  val hviprio2 = Module(new CSRModule("Hviprio2", new Hviprio2Bundle))
128    .setAddr(CSRs.hviprio2)
129
130  val htinst = Module(new CSRModule("Htinst", new XtinstBundle) with TrapEntryHSEventSinkBundle)
131    .setAddr(CSRs.htinst)
132
133  val hgatp = Module(new CSRModule("Hgatp", new HgatpBundle) {
134    // Ref: 13.2.10. Hypervisor Guest Address Translation and Protection Register (hgatp)
135    // A write to hgatp with an unsupported MODE value is not ignored as it is for satp. Instead, the fields of
136    // hgatp are WARL in the normal way, when so indicated.
137
138    // The length of ppn is 44 bits.
139    // make PPN[1:0] read-only zero.
140    val ppnMask = ZeroExt((Fill(PPNLength - 2, 1.U(1.W)) ## 0.U(2.W)).take(PAddrBits - PageOffsetWidth), PPNLength)
141
142    when (wen) {
143      reg.VMID := wdata.VMID
144      reg.PPN  := wdata.PPN & ppnMask
145      when (wdata.MODE.isLegal) {
146        reg.MODE := wdata.MODE
147      }.otherwise {
148        reg.MODE := reg.MODE
149      }
150    }.otherwise {
151      reg := reg
152    }
153  })
154    .setAddr(CSRs.hgatp)
155
156  val hgeip = Module(new CSRModule("Hgeip", new HgeipBundle) with HasAIABundle {
157    regOut.ip := aiaToCSR.vseip
158  })
159    .setAddr(CSRs.hgeip)
160
161  val hstateen0 = Module(new CSRModule("Hstateen", new HstateenBundle0) with HasStateen0Bundle {
162    // For every bit in an mstateen CSR that is zero (whether read-only zero or set to zero), the same bit
163    // appears as read-only zero in the matching hstateen and sstateen CSRs.
164    regOut := reg.asUInt & fromMstateen0.asUInt
165  }).setAddr(CSRs.hstateen0)
166
167  val hypervisorCSRMods: Seq[CSRModule[_]] = Seq(
168    hstatus,
169    hedeleg,
170    hideleg,
171    hie,
172    htimedelta,
173    hcounteren,
174    hgeie,
175    hvien,
176    hvictl,
177    henvcfg,
178    htval,
179    hip,
180    hvip,
181    hviprio1,
182    hviprio2,
183    htinst,
184    hgatp,
185    hgeip,
186    hstateen0,
187  )
188
189  val hypervisorCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from(
190    hypervisorCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator
191  )
192
193  val hypervisorCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
194    hypervisorCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator
195  )
196}
197
198class HstatusBundle extends CSRBundle {
199
200  val VSBE  = RO(5).withReset(0.U)
201  val GVA   = RW(6)
202  val SPV   = VirtMode(7)
203  val SPVP  = RW(8)
204  val HU    = RW(9)
205  val VGEIN = HstatusVgeinField(17, 12, wNoFilter, rNoFilter).withReset(0.U)
206  val VTVM  = RW(20).withReset(0.U)
207  val VTW   = RW(21).withReset(0.U)
208  val VTSR  = RW(22).withReset(0.U)
209  val VSXL  = XLENField(33, 32).withReset(XLENField.XLEN64)
210
211}
212
213object HstatusVgeinField extends CSREnum with WLRLApply {
214  override def isLegal(enumeration: CSREnumType): Bool = enumeration.asUInt <= GEILEN.U
215}
216
217class HstatusModule(implicit p: Parameters) extends CSRModule("Hstatus", new HstatusBundle)
218  with SretEventSinkBundle
219  with TrapEntryHSEventSinkBundle
220
221class HvipBundle extends InterruptPendingBundle {
222  // VSSIP, VSTIP, VSEIP, localIP is writable
223  this.getVS.foreach(_.setRW().withReset(0.U))
224  this.getLocal.foreach(_.setRW().withReset(0.U))
225}
226
227class HieBundle extends InterruptEnableBundle {
228  // All bits in hie are RO, since all registers implemented in mie.
229}
230
231class HipBundle extends InterruptPendingBundle {
232  this.VSSIP.setRW().withReset(0.U) // aliasRW of mip.VSSIP when mideleg=1.
233  this.VSTIP.setRO().withReset(0.U) // aliasRO of mip.VSTIP when mideleg=1. (hvip.VSTIP | PLIC.VSTIP)
234  this.VSEIP.setRO().withReset(0.U) // aliasRO of mip.VSEIP when mideleg=1. (hvip.VSEIP | hgeip(hstatus.VGEIN) | PLIC.VSEIP)
235  this.SGEIP.setRO().withReset(0.U) // aliasRO of mip.SGEIP (|(hgeip & hegie))
236}
237
238class HvienBundle extends InterruptEnableBundle {
239  // Ref: riscv interrupt spec - 6.3.2 Virtual interrupts for VS level
240  // Bits 12:0 of hvien are reserved and must be read-only zeros.
241  // For interrupt numbers 13–63, implementations may freely choose which bits of hvien are writable
242  // and which bits are read-only zero or one.
243  this.getLocal.foreach(_.setRW().withReset(0.U))
244
245}
246
247class HgeieBundle extends CSRBundle {
248  val ie = RW(GEILEN, 1).withReset(0.U)
249  // bit 0 is read only 0
250}
251
252class HgeipBundle extends CSRBundle {
253  val ip = RO(GEILEN, 1)
254  // bit 0 is read only 0
255}
256
257class HedelegBundle extends ExceptionBundle {
258  this.getALL.foreach(_.setRW().withReset(0.U))
259  // The default configs are RW
260  this.EX_HSCALL.setRO().withReset(0.U)
261  this.EX_VSCALL.setRO().withReset(0.U)
262  this.EX_MCALL .setRO().withReset(0.U)
263  this.EX_IGPF  .setRO().withReset(0.U)
264  this.EX_LGPF  .setRO().withReset(0.U)
265  this.EX_VI    .setRO().withReset(0.U)
266  this.EX_SGPF  .setRO().withReset(0.U)
267  this.EX_DBLTRP.setRO().withReset(0.U) // double trap is not delegatable
268}
269
270class HidelegBundle extends InterruptBundle {
271  this.getALL.foreach(_.setRW().withReset(0.U))
272  // default RW
273  this.SSI .setRO().withReset(0.U)
274  this.MSI .setRO().withReset(0.U)
275  this.STI .setRO().withReset(0.U)
276  this.MTI .setRO().withReset(0.U)
277  this.SEI .setRO().withReset(0.U)
278  this.MEI .setRO().withReset(0.U)
279  this.SGEI.setRO().withReset(0.U)
280  this.getLocal.foreach(_.setRO().withReset(0.U))
281  this.LCOFI.setRW().withReset(0.U)
282}
283
284class HipToHvip extends Bundle {
285  val VSSIP = ValidIO(RW(0))
286}
287
288class SipToHvip extends ToAliasIpLocalPart {
289
290}
291
292class HieToMie extends IeValidBundle {
293  this.getVS.foreach(_.bits.setRW())
294  this.SGEIE.bits.setRW()
295}
296
297class HvictlBundle extends CSRBundle {
298  // Virtual Trap Interrupt control
299  val VTI = RW(30).withReset(0.U)
300  // WARL in AIA spec.
301  // RW, since we support max width of IID
302  val IID = RW(15 + HIIDWidth, 16).withReset(0.U)
303  // determines the interrupt’s presumed default priority order relative to a (virtual) supervisor external interrupt (SEI), major identity 9
304  // 0 = interrupt has higher default priority than an SEI
305  // 1 = interrupt has lower default priority than an SEI
306  // When hvictl.IID = 9, DPR is ignored.
307  // Todo: sort the interrupt specified by hvictl with DPR
308  val DPR = RW(9).withReset(0.U)
309  val IPRIOM = RW(8).withReset(0.U)
310  val IPRIO = RW(7, 0).withReset(0.U)
311}
312
313class Hviprio1Bundle extends CSRBundle {
314  val PrioSSI = RW(15,  8).withReset(0.U)
315  val PrioSTI = RW(31, 24).withReset(0.U)
316  val PrioCOI = RW(47, 40).withReset(0.U)
317  val Prio14  = RO(55, 48).withReset(0.U)
318  val Prio15  = RO(63, 56).withReset(0.U)
319}
320
321class Hviprio2Bundle extends CSRBundle {
322  val Prio16 = RO(7, 0).withReset(0.U)
323  val Prio17 = RO(15, 8).withReset(0.U)
324  val Prio18 = RO(23, 16).withReset(0.U)
325  val Prio19 = RO(31, 24).withReset(0.U)
326  val Prio20 = RO(39, 32).withReset(0.U)
327  val Prio21 = RO(47, 40).withReset(0.U)
328  val Prio22 = RO(55, 48).withReset(0.U)
329  val Prio23 = RO(63, 56).withReset(0.U)
330}
331
332class HgatpBundle extends CSRBundle {
333  val MODE = HgatpMode(63, 60, wNoFilter).withReset(HgatpMode.Bare)
334  // WARL in privileged spec.
335  // RW, since we support max width of VMID
336  val VMID = RW(44 - 1 + VMIDLEN, 44).withReset(0.U)
337  val PPN = RW(43, 0).withReset(0.U)
338}
339
340class HEnvCfg extends EnvCfg {
341  if (CSRConfig.EXT_SSTC) {
342    this.STCE.setRW().withReset(1.U)
343  }
344  this.PBMTE.setRW().withReset(0.U)
345  if (CSRConfig.EXT_DBLTRP) {
346    // software write envcfg to open ssdbltrp if need
347    // set 0 to pass ci
348    this.DTE.setRW().withReset(0.U)
349  }
350}
351
352trait HypervisorBundle { self: CSRModule[_] =>
353  val hstatus = IO(Input(new HstatusBundle))
354}
355
356trait HasHypervisorEnvBundle { self: CSRModule[_] =>
357  val menvcfg = IO(Input(new MEnvCfg))
358}