xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/HypervisorLevel.scala (revision 26033c52423227b765eaa12b5d2a2a1dd983ff14)
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))
158    .setAddr(CSRs.hgeip)
159
160  val hstateen0 = Module(new CSRModule("Hstateen", new HstateenBundle0) with HasStateen0Bundle {
161    // For every bit in an mstateen CSR that is zero (whether read-only zero or set to zero), the same bit
162    // appears as read-only zero in the matching hstateen and sstateen CSRs.
163    regOut := reg.asUInt & fromMstateen0.asUInt
164  }).setAddr(CSRs.hstateen0)
165
166  val hypervisorCSRMods: Seq[CSRModule[_]] = Seq(
167    hstatus,
168    hedeleg,
169    hideleg,
170    hie,
171    htimedelta,
172    hcounteren,
173    hgeie,
174    hvien,
175    hvictl,
176    henvcfg,
177    htval,
178    hip,
179    hvip,
180    hviprio1,
181    hviprio2,
182    htinst,
183    hgatp,
184    hgeip,
185    hstateen0,
186  )
187
188  val hypervisorCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from(
189    hypervisorCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator
190  )
191
192  val hypervisorCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
193    hypervisorCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator
194  )
195}
196
197class HstatusBundle extends CSRBundle {
198
199  val VSBE  = RO(5).withReset(0.U)
200  val GVA   = RW(6)
201  val SPV   = VirtMode(7)
202  val SPVP  = RW(8)
203  val HU    = RW(9)
204  val VGEIN = HstatusVgeinField(17, 12, wNoFilter, rNoFilter)
205  val VTVM  = RW(20)
206  val VTW   = RW(21)
207  val VTSR  = RW(22)
208  val VSXL  = XLENField(33, 32).withReset(XLENField.XLEN64)
209
210}
211
212object HstatusVgeinField extends CSREnum with WLRLApply {
213  override def isLegal(enum: CSREnumType): Bool = enum.asUInt <= GEILEN.U
214}
215
216class HstatusModule(implicit p: Parameters) extends CSRModule("Hstatus", new HstatusBundle)
217  with SretEventSinkBundle
218  with TrapEntryHSEventSinkBundle
219
220class HvipBundle extends InterruptPendingBundle {
221  // VSSIP, VSTIP, VSEIP, localIP is writable
222  this.getVS.foreach(_.setRW().withReset(0.U))
223  this.getLocal.foreach(_.setRW().withReset(0.U))
224}
225
226class HieBundle extends InterruptEnableBundle {
227  // All bits in hie are RO, since all registers implemented in mie.
228}
229
230class HipBundle extends InterruptPendingBundle {
231  this.VSSIP.setRW().withReset(0.U) // aliasRW of mip.VSSIP when mideleg=1.
232  this.VSTIP.setRO().withReset(0.U) // aliasRO of mip.VSTIP when mideleg=1. (hvip.VSTIP | PLIC.VSTIP)
233  this.VSEIP.setRO().withReset(0.U) // aliasRO of mip.VSEIP when mideleg=1. (hvip.VSEIP | hgeip(hstatus.VGEIN) | PLIC.VSEIP)
234  this.SGEIP.setRO().withReset(0.U) // aliasRO of mip.SGEIP (|(hgeip & hegie))
235}
236
237class HvienBundle extends InterruptEnableBundle {
238  // Ref: riscv interrupt spec - 6.3.2 Virtual interrupts for VS level
239  // Bits 12:0 of hvien are reserved and must be read-only zeros.
240  // For interrupt numbers 13–63, implementations may freely choose which bits of hvien are writable
241  // and which bits are read-only zero or one.
242  this.getLocal.foreach(_.setRW().withReset(0.U))
243
244}
245
246class HgeieBundle extends CSRBundle {
247  val ie = RW(GEILEN, 1)
248  // bit 0 is read only 0
249}
250
251class HgeipBundle extends CSRBundle {
252  val ip = RO(GEILEN, 1)
253  // bit 0 is read only 0
254}
255
256class HedelegBundle extends ExceptionBundle {
257  this.getALL.foreach(_.setRW().withReset(0.U))
258  // The default configs are RW
259  this.EX_HSCALL.setRO().withReset(0.U)
260  this.EX_VSCALL.setRO().withReset(0.U)
261  this.EX_MCALL .setRO().withReset(0.U)
262  this.EX_IGPF  .setRO().withReset(0.U)
263  this.EX_LGPF  .setRO().withReset(0.U)
264  this.EX_VI    .setRO().withReset(0.U)
265  this.EX_SGPF  .setRO().withReset(0.U)
266}
267
268class HidelegBundle extends InterruptBundle {
269  this.getALL.foreach(_.setRW().withReset(0.U))
270  // default RW
271  this.SSI .setRO().withReset(0.U)
272  this.MSI .setRO().withReset(0.U)
273  this.STI .setRO().withReset(0.U)
274  this.MTI .setRO().withReset(0.U)
275  this.SEI .setRO().withReset(0.U)
276  this.MEI .setRO().withReset(0.U)
277  this.SGEI.setRO().withReset(0.U)
278}
279
280class HipToHvip extends Bundle {
281  val VSSIP = ValidIO(RW(0))
282}
283
284class SipToHvip extends ToAliasIpLocalPart {
285
286}
287
288class HieToMie extends IeValidBundle {
289  this.getVS.foreach(_.bits.setRW())
290  this.SGEIE.bits.setRW()
291}
292
293class HvictlBundle extends CSRBundle {
294  // Virtual Trap Interrupt control
295  val VTI = RW(30)
296  // WARL in AIA spec.
297  // RW, since we support max width of IID
298  val IID = RW(15 + HIIDWidth, 16)
299  // determines the interrupt’s presumed default priority order relative to a (virtual) supervisor external interrupt (SEI), major identity 9
300  // 0 = interrupt has higher default priority than an SEI
301  // 1 = interrupt has lower default priority than an SEI
302  // When hvictl.IID = 9, DPR is ignored.
303  // Todo: sort the interrupt specified by hvictl with DPR
304  val DPR = RW(9)
305  val IPRIOM = RW(8)
306  val IPRIO = RW(7, 0)
307}
308
309class Hviprio1Bundle extends CSRBundle {
310  val PrioSSI = RW(15,  8)
311  val PrioSTI = RW(31, 24)
312  val PrioCOI = RW(47, 40)
313  val Prio14  = RW(55, 48)
314  val Prio15  = RW(63, 56)
315}
316
317class Hviprio2Bundle extends CSRBundle {
318  val Prio16 = RW(7, 0)
319  val Prio17 = RW(15, 8)
320  val Prio18 = RW(23, 16)
321  val Prio19 = RW(31, 24)
322  val Prio20 = RW(39, 32)
323  val Prio21 = RW(47, 40)
324  val Prio22 = RW(55, 48)
325  val Prio23 = RW(63, 56)
326}
327
328class HgatpBundle extends CSRBundle {
329  val MODE = HgatpMode(63, 60, wNoFilter).withReset(HgatpMode.Bare)
330  // WARL in privileged spec.
331  // RW, since we support max width of VMID
332  val VMID = RW(44 - 1 + VMIDLEN, 44)
333  val PPN = RW(43, 0)
334}
335
336class HEnvCfg extends EnvCfg {
337  if (CSRConfig.EXT_SSTC) {
338    this.STCE.setRW().withReset(1.U)
339  }
340}
341
342trait HypervisorBundle { self: CSRModule[_] =>
343  val hstatus = IO(Input(new HstatusBundle))
344}
345
346trait HasHypervisorEnvBundle { self: CSRModule[_] =>
347  val menvcfg = IO(Input(new MEnvCfg))
348  val privState = IO(Input(new PrivState))
349  val accessStimecmp = IO(Input(Bool()))
350}