xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/HypervisorLevel.scala (revision 8b7dc6f554c87e939d588726affdf7b89b1aad5b)
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      when (wdata.MODE === HgatpMode.Bare) {
131        reg := 0.U
132      }.otherwise {
133        reg := wdata
134      }
135    }.elsewhen (wen && !wdata.MODE.isLegal) {
136      reg.PPN := wdata.PPN
137      reg.VMID := wdata.VMID
138    }.otherwise {
139      reg := reg
140    }
141  })
142    .setAddr(0x680)
143
144  val hgeip = Module(new CSRModule("Hgeip", new HgeipBundle))
145    .setAddr(0xE12)
146
147  val hypervisorCSRMods: Seq[CSRModule[_]] = Seq(
148    hstatus,
149    hedeleg,
150    hideleg,
151    hie,
152    htimedelta,
153    hcounteren,
154    hgeie,
155    hvien,
156    hvictl,
157    henvcfg,
158    htval,
159    hip,
160    hvip,
161    hviprio1,
162    hviprio2,
163    htinst,
164    hgatp,
165    hgeip,
166  )
167
168  val hypervisorCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], Data)] = SeqMap.from(
169    hypervisorCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator
170  )
171
172  val hypervisorCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
173    hypervisorCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator
174  )
175}
176
177class HstatusBundle extends CSRBundle {
178
179  val VSBE  = RO(5).withReset(0.U)
180  val GVA   = RW(6)
181  val SPV   = VirtMode(7)
182  val SPVP  = RW(8)
183  val HU    = RW(9)
184  val VGEIN = HstatusVgeinField(17, 12, wNoFilter, rNoFilter)
185  val VTVM  = RW(20)
186  val VTW   = RW(21)
187  val VTSR  = RW(22)
188  val VSXL  = XLENField(33, 32).withReset(XLENField.XLEN64)
189
190}
191
192object HstatusVgeinField extends CSREnum with WLRLApply {
193  override def isLegal(enum: CSREnumType): Bool = enum.asUInt <= GEILEN.U
194}
195
196class HstatusModule(implicit p: Parameters) extends CSRModule("Hstatus", new HstatusBundle)
197  with SretEventSinkBundle
198  with TrapEntryHSEventSinkBundle
199
200class HvipBundle extends CSRBundle {
201  val VSSIP = RW(2)
202  val VSTIP = RW(6)
203  val VSEIP = RW(10)
204}
205
206class HieBundle extends CSRBundle {
207  val VSSIE = RW( 2).withReset(0.U)
208  val VSTIE = RW( 6).withReset(0.U)
209  val VSEIE = RW(10).withReset(0.U)
210  val SGEIE = RW(12).withReset(0.U)
211}
212
213class HipBundle extends CSRBundle {
214  val VSSIP = RW( 2).withReset(0.U) // alias of hvip.VSSIP
215  val VSTIP = RO( 6).withReset(0.U) // hvip.VSTIP | PLIC.VSTIP
216  val VSEIP = RO(10).withReset(0.U) // hvip.VSEIP | hgeip(hstatus.VGEIN) | PLIC.VSEIP
217  val SGEIP = RO(12).withReset(0.U) // |(hgeip & hegie)
218}
219
220class HgeieBundle extends CSRBundle {
221  val ie = RW(GEILEN, 1)
222  // bit 0 is read only 0
223}
224
225class HgeipBundle extends CSRBundle {
226  val ip = RW(GEILEN, 1)
227  // bit 0 is read only 0
228}
229
230class HedelegBundle extends ExceptionBundle {
231  this.getALL.foreach(_.setRW().withReset(0.U))
232  // The default configs are RW
233  this.EX_HSCALL.setRO().withReset(0.U)
234  this.EX_VSCALL.setRO().withReset(0.U)
235  this.EX_MCALL .setRO().withReset(0.U)
236  this.EX_IGPF  .setRO().withReset(0.U)
237  this.EX_LGPF  .setRO().withReset(0.U)
238  this.EX_VI    .setRO().withReset(0.U)
239  this.EX_SGPF  .setRO().withReset(0.U)
240}
241
242class HidelegBundle extends InterruptBundle {
243  this.getALL.foreach(_.setRW().withReset(0.U))
244  // default RW
245  this.SSI .setRO().withReset(0.U)
246  this.MSI .setRO().withReset(0.U)
247  this.STI .setRO().withReset(0.U)
248  this.MTI .setRO().withReset(0.U)
249  this.SEI .setRO().withReset(0.U)
250  this.MEI .setRO().withReset(0.U)
251  this.SGEI.setRO().withReset(0.U)
252}
253
254class HipToHvip extends Bundle {
255  val VSSIP = ValidIO(RW(0))
256}
257
258class HvictlBundle extends CSRBundle {
259  // Virtual Trap Interrupt control
260  val VTI = RW(30)
261  // WARL in AIA spec.
262  // RW, since we support max width of IID
263  val IID = RW(15 + HIIDWidth, 16)
264  // determines the interrupt’s presumed default priority order relative to a (virtual) supervisor external interrupt (SEI), major identity 9
265  // 0 = interrupt has higher default priority than an SEI
266  // 1 = interrupt has lower default priority than an SEI
267  // When hvictl.IID = 9, DPR is ignored.
268  // Todo: sort the interrupt specified by hvictl with DPR
269  val DPR = RW(9)
270  val IPRIOM = RW(8)
271  val IPRIO = RW(7, 0)
272}
273
274class Hviprio1Bundle extends CSRBundle {
275  val PrioSSI = RW(15, 8)
276  val PrioSTI = RW(31, 24)
277  val PrioCOI = RW(47, 40)
278  val Prio14  = RW(55, 48)
279  val Prio15  = RW(63, 56)
280}
281
282class Hviprio2Bundle extends CSRBundle {
283  val Prio16 = RW(7, 0)
284  val Prio17 = RW(15, 8)
285  val Prio18 = RW(23, 16)
286  val Prio19 = RW(31, 24)
287  val Prio20 = RW(39, 32)
288  val Prio21 = RW(47, 40)
289  val Prio22 = RW(55, 48)
290  val Prio23 = RW(63, 56)
291}
292
293class HgatpBundle extends CSRBundle {
294  final val PPN_msb = PAddrWidth - AddrWidthInPage - 1
295  val MODE = HgatpMode(63, 60, wNoFilter).withReset(HgatpMode.Bare)
296  // WARL in privileged spec.
297  // RW, since we support max width of VMID
298  val VMID = RW(44 - 1 + VMIDLEN, 44)
299  val PPN = RW(PAddrWidth, 0)
300}
301
302trait HypervisorBundle { self: CSRModule[_] =>
303  val hstatus = IO(Input(new HstatusBundle))
304  val hvip    = IO(Input(new HvipBundle))
305  val hideleg = IO(Input(new HidelegBundle))
306  val hedeleg = IO(Input(new HedelegBundle))
307  val hgeip   = IO(Input(new HgeipBundle))
308  val hgeie   = IO(Input(new HgeieBundle))
309  val hip     = IO(Input(new HipBundle))
310  val hie     = IO(Input(new HieBundle))
311}
312