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