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