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