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