xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/HypervisorLevel.scala (revision 61f6ab5120b5bb17a7521f82f29d73cbf664db1f)
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", new CSRBundle {
50    val VALUE = RW(63, 0)
51  }))
52    .setAddr(CSRs.htimedelta)
53
54  val hcounteren = Module(new CSRModule("Hcounteren", new Counteren))
55    .setAddr(CSRs.hcounteren)
56
57  val hgeie = Module(new CSRModule("Hgeie", new HgeieBundle))
58    .setAddr(CSRs.hgeie)
59
60  val hvien = Module(new CSRModule("Hvien", new HvienBundle))
61    .setAddr(CSRs.hvien)
62
63  val hvictl = Module(new CSRModule("Hvictl", new HvictlBundle))
64    .setAddr(CSRs.hvictl)
65
66  val henvcfg = Module(new CSRModule("Henvcfg", new HEnvCfg) with HasHypervisorEnvBundle {
67    when (!menvcfg.STCE.asBool && !privState.isModeM && accessStimecmp) {
68      regOut.STCE := 0.U
69    }
70  })
71    .setAddr(CSRs.henvcfg)
72
73  val htval = Module(new CSRModule("Htval", new CSRBundle {
74    val ALL = RW(63, 0)
75  }) with TrapEntryHSEventSinkBundle)
76    .setAddr(CSRs.htval)
77
78  val hip = Module(new CSRModule("Hip", new HipBundle)
79    with HypervisorBundle
80    with HasExternalInterruptBundle
81    with HasIpIeBundle
82  {
83    val toHvip = IO(new HipToHvip)
84
85    // hip.VSEIP is read-only alias of mip.VSEIP, mip.VSEIP := hvip.VSEIP|hgeip(VGEIN)|platIR.VSEIP
86    // hip.VSTIP is read-only alias of mip.VSTIP, mip.VSTIP := hvip.VSTIP|time+htimedelta>=vstimecmp
87    // hip.SGEIP is read-only alias of mip.SGEIP, mip.SGEIP := |(hgeip&hgeie)
88    regOut.VSTIP := mip.VSTIP
89    regOut.VSEIP := mip.VSEIP
90    regOut.SGEIP := mip.SGEIP
91
92    // hip.VSSIP is alias of hvip.VSSIP, writable
93    toHvip.VSSIP.valid := wen
94    toHvip.VSSIP.bits  := wdata.VSSIP
95    regOut.VSSIP := hvip.VSSIP
96    // vsip.SSIP is alias of hip.VSSIP, so vsip.SSIP is alias of hvip.VSSIP.
97    // vsip.SSIP write throuth to hvip.VSSIP
98  })
99    .setAddr(CSRs.hip)
100
101  val hvip = Module(new CSRModule("Hvip", new HvipBundle) {
102    val fromMip  = IO(Flipped(new MipToHvip))
103    val fromHip  = IO(Flipped(new HipToHvip))
104    val fromVSip = IO(Flipped(new VSipToHvip))
105
106    when (fromMip.VSSIP.valid || fromHip.VSSIP.valid || fromVSip.VSSIP.valid) {
107      reg.VSSIP := Mux1H(Seq(
108        fromMip.VSSIP.valid -> fromMip.VSSIP.bits,
109        fromHip.VSSIP.valid -> fromHip.VSSIP.bits,
110        fromVSip.VSSIP.valid -> fromVSip.VSSIP.bits,
111      ))
112    }
113
114    reg.getLocal zip fromVSip.getLocal foreach { case (rLCIP, vsipLCIP) =>
115      // sip should assert valid when hideleg=0 && hvien=1
116      when(vsipLCIP.valid) {
117        rLCIP := vsipLCIP.bits
118      }
119    }
120  })
121    .setAddr(CSRs.hvip)
122
123  val hviprio1 = Module(new CSRModule("Hviprio1", new Hviprio1Bundle))
124    .setAddr(CSRs.hviprio1)
125
126  val hviprio2 = Module(new CSRModule("Hviprio2", new Hviprio2Bundle))
127    .setAddr(CSRs.hviprio2)
128
129  val htinst = Module(new CSRModule("Htinst", new CSRBundle {
130    val ALL = RW(63, 0)
131  }) with TrapEntryHSEventSinkBundle)
132    .setAddr(CSRs.htinst)
133
134  val hgatp = Module(new CSRModule("Hgatp", new HgatpBundle) {
135    // Ref: 13.2.10. Hypervisor Guest Address Translation and Protection Register (hgatp)
136    // A write to hgatp with an unsupported MODE value is not ignored as it is for satp. Instead, the fields of
137    // hgatp are WARL in the normal way, when so indicated.
138
139    // The length of ppn is 44 bits.
140    // make PPN[1:0] read-only zero.
141    val ppnMask = ZeroExt((Fill(PPNLength - 2, 1.U(1.W)) ## 0.U(2.W)).take(PAddrBits - PageOffsetWidth), PPNLength)
142
143    when (wen) {
144      reg.VMID := wdata.VMID
145      reg.PPN  := wdata.PPN & ppnMask
146      when (wdata.MODE.isLegal) {
147        reg.MODE := wdata.MODE
148      }.otherwise {
149        reg.MODE := reg.MODE
150      }
151    }.otherwise {
152      reg := reg
153    }
154  })
155    .setAddr(CSRs.hgatp)
156
157  val hgeip = Module(new CSRModule("Hgeip", new HgeipBundle) with HasAIABundle {
158    regOut.ip := aiaToCSR.vseip
159  })
160    .setAddr(CSRs.hgeip)
161
162  val hstateen0 = Module(new CSRModule("Hstateen", new HstateenBundle0) with HasStateen0Bundle {
163    // For every bit in an mstateen CSR that is zero (whether read-only zero or set to zero), the same bit
164    // appears as read-only zero in the matching hstateen and sstateen CSRs.
165    regOut := reg.asUInt & fromMstateen0.asUInt
166  }).setAddr(CSRs.hstateen0)
167
168  val hypervisorCSRMods: Seq[CSRModule[_]] = Seq(
169    hstatus,
170    hedeleg,
171    hideleg,
172    hie,
173    htimedelta,
174    hcounteren,
175    hgeie,
176    hvien,
177    hvictl,
178    henvcfg,
179    htval,
180    hip,
181    hvip,
182    hviprio1,
183    hviprio2,
184    htinst,
185    hgatp,
186    hgeip,
187    hstateen0,
188  )
189
190  val hypervisorCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from(
191    hypervisorCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator
192  )
193
194  val hypervisorCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
195    hypervisorCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator
196  )
197}
198
199class HstatusBundle extends CSRBundle {
200
201  val VSBE  = RO(5).withReset(0.U)
202  val GVA   = RW(6)
203  val SPV   = VirtMode(7)
204  val SPVP  = RW(8)
205  val HU    = RW(9)
206  val VGEIN = HstatusVgeinField(17, 12, wNoFilter, rNoFilter)
207  val VTVM  = RW(20)
208  val VTW   = RW(21)
209  val VTSR  = RW(22)
210  val VSXL  = XLENField(33, 32).withReset(XLENField.XLEN64)
211
212}
213
214object HstatusVgeinField extends CSREnum with WLRLApply {
215  override def isLegal(enum: CSREnumType): Bool = enum.asUInt <= GEILEN.U
216}
217
218class HstatusModule(implicit p: Parameters) extends CSRModule("Hstatus", new HstatusBundle)
219  with SretEventSinkBundle
220  with TrapEntryHSEventSinkBundle
221
222class HvipBundle extends InterruptPendingBundle {
223  // VSSIP, VSTIP, VSEIP, localIP is writable
224  this.getVS.foreach(_.setRW().withReset(0.U))
225  this.getLocal.foreach(_.setRW().withReset(0.U))
226}
227
228class HieBundle extends InterruptEnableBundle {
229  // All bits in hie are RO, since all registers implemented in mie.
230}
231
232class HipBundle extends InterruptPendingBundle {
233  this.VSSIP.setRW().withReset(0.U) // aliasRW of mip.VSSIP when mideleg=1.
234  this.VSTIP.setRO().withReset(0.U) // aliasRO of mip.VSTIP when mideleg=1. (hvip.VSTIP | PLIC.VSTIP)
235  this.VSEIP.setRO().withReset(0.U) // aliasRO of mip.VSEIP when mideleg=1. (hvip.VSEIP | hgeip(hstatus.VGEIN) | PLIC.VSEIP)
236  this.SGEIP.setRO().withReset(0.U) // aliasRO of mip.SGEIP (|(hgeip & hegie))
237}
238
239class HvienBundle extends InterruptEnableBundle {
240  // Ref: riscv interrupt spec - 6.3.2 Virtual interrupts for VS level
241  // Bits 12:0 of hvien are reserved and must be read-only zeros.
242  // For interrupt numbers 13–63, implementations may freely choose which bits of hvien are writable
243  // and which bits are read-only zero or one.
244  this.getLocal.foreach(_.setRW().withReset(0.U))
245
246}
247
248class HgeieBundle extends CSRBundle {
249  val ie = RW(GEILEN, 1)
250  // bit 0 is read only 0
251}
252
253class HgeipBundle extends CSRBundle {
254  val ip = RO(GEILEN, 1)
255  // bit 0 is read only 0
256}
257
258class HedelegBundle extends ExceptionBundle {
259  this.getALL.foreach(_.setRW().withReset(0.U))
260  // The default configs are RW
261  this.EX_HSCALL.setRO().withReset(0.U)
262  this.EX_VSCALL.setRO().withReset(0.U)
263  this.EX_MCALL .setRO().withReset(0.U)
264  this.EX_IGPF  .setRO().withReset(0.U)
265  this.EX_LGPF  .setRO().withReset(0.U)
266  this.EX_VI    .setRO().withReset(0.U)
267  this.EX_SGPF  .setRO().withReset(0.U)
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)
337  val PPN = RW(43, 0)
338}
339
340class HEnvCfg extends EnvCfg {
341  if (CSRConfig.EXT_SSTC) {
342    this.STCE.setRW().withReset(1.U)
343  }
344}
345
346trait HypervisorBundle { self: CSRModule[_] =>
347  val hstatus = IO(Input(new HstatusBundle))
348}
349
350trait HasHypervisorEnvBundle { self: CSRModule[_] =>
351  val menvcfg = IO(Input(new MEnvCfg))
352  val privState = IO(Input(new PrivState))
353  val accessStimecmp = IO(Input(Bool()))
354}