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