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