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