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