xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRPermitModule.scala (revision 30f35717e23156cb95b30a36db530384545b48a4)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import chisel3.util.experimental.decode.TruthTable
6import freechips.rocketchip.rocket.CSRs
7import xiangshan.backend.fu.NewCSR.CSRBundles.{Counteren, PrivState}
8import xiangshan.backend.fu.NewCSR.CSRDefines._
9import org.chipsalliance.cde.config.Parameters
10import system.HasSoCParameter
11
12class CSRPermitModule(implicit p: Parameters) extends Module {
13  val io = IO(new CSRPermitIO)
14
15  val xRetPermitMod = Module(new XRetPermitModule)
16  val mLevelPermitMod = Module(new MLevelPermitModule)
17  val sLevelPermitMod = Module(new SLevelPermitModule)
18  val privilegePermitMod = Module(new PrivilegePermitModule)
19  val virtualLevelPermitMod = Module(new VirtualLevelPermitModule)
20  val indirectCSRPermitMod = Module(new IndirectCSRPermitModule)
21
22  xRetPermitMod.io.in.privState := io.in.privState
23  xRetPermitMod.io.in.debugMode := io.in.debugMode
24  xRetPermitMod.io.in.xRet      := io.in.xRet
25  xRetPermitMod.io.in.status    := io.in.status
26
27  mLevelPermitMod.io.in.csrAccess  := io.in.csrAccess
28  mLevelPermitMod.io.in.privState  := io.in.privState
29  mLevelPermitMod.io.in.status     := io.in.status
30  mLevelPermitMod.io.in.xcounteren := io.in.xcounteren
31  mLevelPermitMod.io.in.xenvcfg    := io.in.xenvcfg
32  mLevelPermitMod.io.in.xstateen   := io.in.xstateen
33  mLevelPermitMod.io.in.aia        := io.in.aia
34
35  sLevelPermitMod.io.in.csrAccess  := io.in.csrAccess
36  sLevelPermitMod.io.in.privState  := io.in.privState
37  sLevelPermitMod.io.in.xcounteren := io.in.xcounteren
38  sLevelPermitMod.io.in.xstateen   := io.in.xstateen
39
40  privilegePermitMod.io.in.csrAccess := io.in.csrAccess
41  privilegePermitMod.io.in.privState := io.in.privState
42  privilegePermitMod.io.in.debugMode := io.in.debugMode
43
44  virtualLevelPermitMod.io.in.csrAccess   := io.in.csrAccess
45  virtualLevelPermitMod.io.in.privState   := io.in.privState
46  virtualLevelPermitMod.io.in.status      := io.in.status
47  virtualLevelPermitMod.io.in.xcounteren  := io.in.xcounteren
48  virtualLevelPermitMod.io.in.xenvcfg     := io.in.xenvcfg
49  virtualLevelPermitMod.io.in.xstateen    := io.in.xstateen
50  virtualLevelPermitMod.io.in.aia         := io.in.aia
51
52  indirectCSRPermitMod.io.in.csrAccess := io.in.csrAccess
53  indirectCSRPermitMod.io.in.privState := io.in.privState
54  indirectCSRPermitMod.io.in.aia       := io.in.aia
55
56  private val (ren, wen) = (
57    io.in.csrAccess.ren,
58    io.in.csrAccess.wen,
59  )
60
61  private val csrAccess = WireInit(ren || wen)
62
63  val mPermit_EX_II = mLevelPermitMod.io.out.mLevelPermit_EX_II
64
65  val sPermit_EX_II = sLevelPermitMod.io.out.sLevelPermit_EX_II
66
67  val pPermit_EX_II = privilegePermitMod.io.out.privilege_EX_II
68  val pPermit_EX_VI = privilegePermitMod.io.out.privilege_EX_VI
69
70  val vPermit_EX_II = virtualLevelPermitMod.io.out.virtualLevelPermit_EX_II
71  val vPermit_EX_VI = virtualLevelPermitMod.io.out.virtualLevelPermit_EX_VI
72
73  val indirectPermit_EX_II = indirectCSRPermitMod.io.out.indirectCSR_EX_II
74  val indirectPermit_EX_VI = indirectCSRPermitMod.io.out.indirectCSR_EX_VI
75
76  val directPermit_illegal = mPermit_EX_II || sPermit_EX_II || pPermit_EX_II || pPermit_EX_VI || vPermit_EX_II || vPermit_EX_VI
77
78  val csrAccess_EX_II = csrAccess && (
79    (mPermit_EX_II || sPermit_EX_II || pPermit_EX_II || vPermit_EX_II) ||
80    (!directPermit_illegal && indirectPermit_EX_II)
81  )
82  val csrAccess_EX_VI = csrAccess && (
83    (pPermit_EX_VI || vPermit_EX_VI) ||
84    (!directPermit_illegal && indirectPermit_EX_VI)
85  )
86
87  val Xret_EX_II = xRetPermitMod.io.out.Xret_EX_II
88  val Xret_EX_VI = xRetPermitMod.io.out.Xret_EX_VI
89
90  io.out.EX_II := csrAccess_EX_II || Xret_EX_II
91  io.out.EX_VI := !io.out.EX_II && (csrAccess_EX_VI || Xret_EX_VI)
92
93  io.out.hasLegalWen   := wen   && !(io.out.EX_II || io.out.EX_VI)
94  io.out.hasLegalMNret := xRetPermitMod.io.out.hasLegalMNret
95  io.out.hasLegalMret  := xRetPermitMod.io.out.hasLegalMret
96  io.out.hasLegalSret  := xRetPermitMod.io.out.hasLegalSret
97  io.out.hasLegalDret  := xRetPermitMod.io.out.hasLegalDret
98
99  io.out.hasLegalWriteFcsr := mLevelPermitMod.io.out.hasLegalWriteFcsr
100  io.out.hasLegalWriteVcsr := mLevelPermitMod.io.out.hasLegalWriteVcsr
101}
102
103class XRetPermitModule extends Module {
104  val io = IO(new Bundle() {
105    val in = Input(new Bundle {
106      val privState = new PrivState
107      val debugMode = Bool()
108      val xRet = new xRetIO
109      val status = new statusIO
110    })
111    val out = Output(new Bundle {
112      val Xret_EX_II = Bool()
113      val Xret_EX_VI = Bool()
114      val hasLegalMNret = Bool()
115      val hasLegalMret  = Bool()
116      val hasLegalSret  = Bool()
117      val hasLegalDret  = Bool()
118    })
119  })
120
121  private val (privState, debugMode) = (
122    io.in.privState,
123    io.in.debugMode,
124  )
125
126  private val (mnret, mret, sret, dret) = (
127    io.in.xRet.mnret,
128    io.in.xRet.mret,
129    io.in.xRet.sret,
130    io.in.xRet.dret,
131  )
132
133  private val (tsr, vtsr) = (
134    io.in.status.tsr,
135    io.in.status.vtsr,
136  )
137
138  private val mnret_EX_II = mnret && !privState.isModeM
139  private val mnretIllegal =  mnret_EX_II
140
141  private val mret_EX_II = mret && !privState.isModeM
142  private val mretIllegal = mret_EX_II
143
144  private val sret_EX_II = sret && (privState.isModeHU || privState.isModeHS && tsr)
145  private val sret_EX_VI = sret && (privState.isModeVU || privState.isModeVS && vtsr)
146  private val sretIllegal = sret_EX_II || sret_EX_VI
147
148  private val dret_EX_II = dret && !debugMode
149  private val dretIllegal = dret_EX_II
150
151  io.out.Xret_EX_II := mnret_EX_II || mret_EX_II || sret_EX_II || dret_EX_II
152  io.out.Xret_EX_VI := sret_EX_VI
153  io.out.hasLegalMNret := mnret && !mnretIllegal
154  io.out.hasLegalMret  := mret  && !mretIllegal
155  io.out.hasLegalSret  := sret  && !sretIllegal
156  io.out.hasLegalDret  := dret  && !dretIllegal
157}
158
159class MLevelPermitModule extends Module {
160  val io = IO(new Bundle() {
161    val in = Input(new Bundle {
162      val csrAccess = new csrAccessIO
163      val privState = new PrivState
164      val status = new statusIO
165      val xcounteren = new xcounterenIO
166      val xenvcfg = new xenvcfgIO
167      val xstateen = new xstateenIO
168      val aia = new aiaIO
169    })
170    val out = Output(new Bundle {
171      val mLevelPermit_EX_II = Bool()
172      val hasLegalWriteFcsr = Bool()
173      val hasLegalWriteVcsr = Bool()
174    })
175  })
176
177  private val (wen, addr, privState) = (
178    io.in.csrAccess.wen,
179    io.in.csrAccess.addr,
180    io.in.privState,
181  )
182
183  private val tvm = io.in.status.tvm
184
185  private val mcounteren = io.in.xcounteren.mcounteren
186
187  private val mstateen0 = io.in.xstateen.mstateen0
188
189  private val mcounterenTM = mcounteren(1)
190
191  private val menvcfg = io.in.xenvcfg.menvcfg
192
193  private val menvcfgSTCE = menvcfg(63)
194
195  private val (sFSIsOff, sVSIsOff, sOrVsFSIsOff, sOrVsVSIsOff) = (
196    io.in.status.mstatusFSOff,
197    io.in.status.mstatusVSOff,
198    io.in.status.mstatusFSOff || io.in.status.vsstatusFSOff,
199    io.in.status.mstatusVSOff || io.in.status.vsstatusVSOff,
200  )
201
202  private val mvienSEIE = io.in.aia.mvienSEIE
203
204  private val csrIsRO = addr(11, 10) === "b11".U
205  private val csrIsHPM = addr >= CSRs.cycle.U && addr <= CSRs.hpmcounter31.U
206  private val csrIsFp = Seq(CSRs.fflags, CSRs.frm, CSRs.fcsr).map(_.U === addr).reduce(_ || _)
207  private val csrIsVec = Seq(CSRs.vstart, CSRs.vxsat, CSRs.vxrm, CSRs.vcsr, CSRs.vtype).map(_.U === addr).reduce(_ || _)
208  private val csrIsWritableVec = Seq(CSRs.vstart, CSRs.vxsat, CSRs.vxrm, CSRs.vcsr).map(_.U === addr).reduce(_ || _)
209  private val counterAddr = addr(4, 0) // 32 counters
210
211  private val rwIllegal = csrIsRO && wen
212
213  private val fsEffectiveOff = sFSIsOff && !privState.isVirtual || sOrVsFSIsOff && privState.isVirtual
214  private val vsEffectiveOff = sVSIsOff && !privState.isVirtual || sOrVsVSIsOff && privState.isVirtual
215
216  private val fpOff_EX_II  = csrIsFp  && fsEffectiveOff
217  private val vecOff_EX_II = csrIsVec && vsEffectiveOff
218
219  private val fpVec_EX_II = fpOff_EX_II || vecOff_EX_II
220
221  private val rwStimecmp_EX_II = !privState.isModeM && (!mcounterenTM || !menvcfgSTCE) && (addr === CSRs.vstimecmp.U || addr === CSRs.stimecmp.U)
222
223  private val accessHPM_EX_II = csrIsHPM && !privState.isModeM && !mcounteren(counterAddr)
224
225  private val rwSatp_EX_II = privState.isModeHS && tvm && (addr === CSRs.satp.U || addr === CSRs.hgatp.U)
226
227  private val rwStopei_EX_II = privState.isModeHS && mvienSEIE && (addr === CSRs.stopei.U)
228
229  /**
230   * Sm/Ssstateen0 begin
231   */
232  // SE0 bit 63
233  private val csrIsHstateen0 = addr === CSRs.hstateen0.U
234  private val csrIsSstateen0 = addr === CSRs.sstateen0.U
235  private val csrIsStateen0 = csrIsHstateen0 || csrIsSstateen0
236  private val accessStateen0_EX_II = csrIsStateen0 && !privState.isModeM && !mstateen0.SE0.asBool
237
238  // ENVCFG bit 62
239  private val csrIsHenvcfg = addr === CSRs.henvcfg.U
240  private val csrIsSenvcfg = addr === CSRs.senvcfg.U
241  private val csrIsEnvcfg = csrIsHenvcfg || csrIsSenvcfg
242  private val accessEnvcfg_EX_II = csrIsEnvcfg && !privState.isModeM && !mstateen0.ENVCFG.asBool
243
244  // CSRIND bit 60 indirect reg (Sscsrind extensions), this is not implemented
245  // csr addr S: [0x150, 0x157]     VS: [0x250, 0x257]
246  private val csrIsSi = addr.head(9) === CSRs.siselect.U.head(9)
247  private val csrIsVSi = addr.head(9) === CSRs.vsiselect.U.head(9)
248  private val csrIsIND = csrIsSi || csrIsVSi
249  private val accessIND_EX_II = csrIsIND && !privState.isModeM && !mstateen0.CSRIND.asBool
250
251  // AIA bit 59
252  private val ssAiaHaddr = Seq(CSRs.hvien.U, CSRs.hvictl.U, CSRs.hviprio1.U, CSRs.hviprio2.U)
253  private val ssAiaVSaddr = addr === CSRs.vstopi.U
254  private val ssAiaSaddr = addr === CSRs.stopi.U
255  private val csrIsAIA = ssAiaHaddr.map(_ === addr).reduce(_ || _) || ssAiaVSaddr || ssAiaSaddr
256  private val accessAIA_EX_II = csrIsAIA && !privState.isModeM && !mstateen0.AIA.asBool
257
258  // IMSIC bit 58 (Ssaia extension)
259  private val csrIsStopei = addr === CSRs.stopei.U
260  private val csrIsVStopei = addr === CSRs.vstopei.U
261  private val csrIsTpoie = csrIsStopei || csrIsVStopei
262  private val accessTopie_EX_II = csrIsTpoie && !privState.isModeM && !mstateen0.IMSIC.asBool
263
264  // CONTEXT bit 57 context reg (Sdtrig extensions), this is not implemented
265  private val csrIsHcontext = addr === CSRs.hcontext.U
266  private val csrIsScontext = addr === CSRs.scontext.U
267  private val csrIsContext = csrIsHcontext || csrIsScontext
268  private val accessContext_EX_II = csrIsContext && !privState.isModeM && !mstateen0.CONTEXT.asBool
269
270  // P1P13 bit 56, Read-only 0
271
272  // Custom bit 0
273  // csr addr HVS: [0x6c0, 0x6ff], [0xac0, 0xaff], [0xec0, 0xeff]
274  private val csrIsHVSCustom = (addr(11, 10) =/= "b00".U) && (addr(9, 8) === "b10".U) && (addr(7, 6) === "b11".U)
275  // [0x5c0, 0x5ff], [0x9c0, 0x9ff], [0xdc0, 0xdff]
276  private val csrIsSCustom   = (addr(11, 10) =/= "b00".U) && (addr(9, 8) === "b01".U) && (addr(7, 6) === "b11".U)
277  // [0x800, 0x8ff], [0xcc0, 0xcff]
278  private val csrIsUCustom   = (addr(11, 8) === "b1000".U) || (addr(11, 6) === "b110011".U)
279  private val allCustom      = csrIsHVSCustom || csrIsSCustom || csrIsUCustom
280  private val accessCustom_EX_II = allCustom && !privState.isModeM && !mstateen0.C.asBool
281
282  val xstateControlAccess_EX_II = accessStateen0_EX_II || accessEnvcfg_EX_II || accessIND_EX_II || accessAIA_EX_II ||
283    accessTopie_EX_II || accessContext_EX_II || accessCustom_EX_II
284  /**
285   * Sm/Ssstateen end
286   */
287
288  io.out.mLevelPermit_EX_II := rwIllegal || fpVec_EX_II || rwStimecmp_EX_II ||
289    accessHPM_EX_II || rwSatp_EX_II || rwStopei_EX_II || xstateControlAccess_EX_II
290  io.out.hasLegalWriteFcsr := wen && csrIsFp && !fsEffectiveOff
291  io.out.hasLegalWriteVcsr := wen && csrIsWritableVec && !vsEffectiveOff
292}
293
294class SLevelPermitModule extends Module {
295  val io = IO(new Bundle() {
296    val in = Input(new Bundle {
297      val csrAccess = new csrAccessIO
298      val privState = new PrivState
299      val xcounteren = new xcounterenIO
300      val xstateen = new xstateenIO
301    })
302    val out = Output(new Bundle {
303      val sLevelPermit_EX_II = Bool()
304    })
305  })
306
307  private val (addr, privState) = (
308    io.in.csrAccess.addr,
309    io.in.privState,
310  )
311
312  private val scounteren = io.in.xcounteren.scounteren
313
314  private val sstateen0 = io.in.xstateen.sstateen0
315
316  private val csrIsHPM = addr >= CSRs.cycle.U && addr <= CSRs.hpmcounter31.U
317  private val counterAddr = addr(4, 0) // 32 counters
318
319  private val accessHPM_EX_II = csrIsHPM && privState.isModeHU && !scounteren(counterAddr)
320
321  private val csrIsUCustom   = (addr(11, 8) === "b1000".U) || (addr(11, 6) === "b110011".U)
322  private val accessCustom_EX_II = csrIsUCustom && privState.isModeHU && !sstateen0.C.asBool
323
324  io.out.sLevelPermit_EX_II := accessHPM_EX_II || accessCustom_EX_II
325}
326
327class PrivilegePermitModule extends Module {
328  val io = IO(new Bundle() {
329    val in = Input(new Bundle {
330      val csrAccess = new csrAccessIO
331      val privState = new PrivState
332      val debugMode = Bool()
333    })
334    val out = Output(new Bundle {
335      val privilege_EX_II = Bool()
336      val privilege_EX_VI = Bool()
337    })
338  })
339
340  private val (addr, privState, debugMode) = (
341    io.in.csrAccess.addr,
342    io.in.privState,
343    io.in.debugMode
344  )
345
346  private val accessTable = TruthTable(Seq(
347    //       V PRVM ADDR
348    BitPat("b0__00___00") -> BitPat.Y(), // HU access U
349    BitPat("b1__00___00") -> BitPat.Y(), // VU access U
350    BitPat("b0__01___00") -> BitPat.Y(), // HS access U
351    BitPat("b0__01___01") -> BitPat.Y(), // HS access S
352    BitPat("b0__01___10") -> BitPat.Y(), // HS access H
353    BitPat("b1__01___00") -> BitPat.Y(), // VS access U
354    BitPat("b1__01___01") -> BitPat.Y(), // VS access S
355    BitPat("b0__11___00") -> BitPat.Y(), // M  access HU
356    BitPat("b0__11___01") -> BitPat.Y(), // M  access HS
357    BitPat("b0__11___10") -> BitPat.Y(), // M  access H
358    BitPat("b0__11___11") -> BitPat.Y(), // M  access M
359  ), BitPat.N())
360
361  private val regularPrivilegeLegal = chisel3.util.experimental.decode.decoder(
362    privState.V.asUInt ## privState.PRVM.asUInt ## addr(9, 8),
363    accessTable
364  ).asBool
365
366  private val csrIsM = addr(9, 8) === "b11".U
367  private val isDebugReg   = addr(11, 4) === "h7b".U
368  private val privilegeLegal = Mux(isDebugReg, debugMode, regularPrivilegeLegal || debugMode)
369
370  io.out.privilege_EX_II := !privilegeLegal && (!privState.isVirtual || csrIsM)
371  io.out.privilege_EX_VI := !privilegeLegal && privState.isVirtual && !csrIsM
372}
373
374class VirtualLevelPermitModule(implicit val p: Parameters) extends Module with HasSoCParameter {
375  val io = IO(new Bundle() {
376    val in = Input(new Bundle {
377      val csrAccess = new csrAccessIO
378      val privState = new PrivState
379      val status = new statusIO
380      val xcounteren = new xcounterenIO
381      val xenvcfg = new xenvcfgIO
382      val xstateen = new xstateenIO
383      val aia = new aiaIO
384    })
385    val out = Output(new Bundle {
386      val virtualLevelPermit_EX_II = Bool()
387      val virtualLevelPermit_EX_VI = Bool()
388    })
389  })
390
391  private val (wen, addr, privState) = (
392    io.in.csrAccess.wen,
393    io.in.csrAccess.addr,
394    io.in.privState,
395  )
396
397  private val (vtvm, vgein) = (
398    io.in.status.vtvm,
399    io.in.status.vgein,
400  )
401
402  private val (hcounteren, scounteren) = (
403    io.in.xcounteren.hcounteren,
404    io.in.xcounteren.scounteren,
405  )
406
407  private val hcounterenTM = hcounteren(1)
408
409  private val henvcfg = io.in.xenvcfg.henvcfg
410
411  private val henvcfgSTCE = henvcfg(63)
412
413  private val (hstateen0, sstateen0) = (
414    io.in.xstateen.hstateen0,
415    io.in.xstateen.sstateen0,
416  )
417
418  private val hvictlVTI = io.in.aia.hvictlVTI
419
420  private val csrIsHPM = addr >= CSRs.cycle.U && addr <= CSRs.hpmcounter31.U
421  private val counterAddr = addr(4, 0) // 32 counters
422
423  private val rwSatp_EX_VI = privState.isModeVS && vtvm && (addr === CSRs.satp.U)
424
425  private val rwVStopei_EX_II = (privState.isModeM || privState.isModeHS) && (addr === CSRs.vstopei.U) && (vgein === 0.U || vgein > soc.IMSICParams.geilen.U)
426  private val rwStopei_EX_VI = privState.isModeVS && (addr === CSRs.stopei.U) && (vgein === 0.U || vgein > soc.IMSICParams.geilen.U)
427
428  private val rwSip_Sie_EX_VI = privState.isModeVS && hvictlVTI && (addr === CSRs.sip.U || addr === CSRs.sie.U)
429
430  private val rwStimecmp_EX_VI = privState.isModeVS && (addr === CSRs.stimecmp.U) &&
431    (!hcounterenTM || !henvcfgSTCE || wen && hvictlVTI)
432
433  private val accessHPM_EX_VI = csrIsHPM && (
434      privState.isModeVS && !hcounteren(counterAddr) ||
435      privState.isModeVU && (!hcounteren(counterAddr) || !scounteren(counterAddr))
436    )
437
438  /**
439   * Sm/Ssstateen0 begin
440   */
441  // SE0 bit 63
442  private val csrIsSstateen0 = addr === CSRs.sstateen0.U
443  private val accessStateen0_EX_VI = csrIsSstateen0 && privState.isVirtual && !hstateen0.SE0.asBool
444
445  // ENVCFG bit 62
446  private val csrIsSenvcfg = addr === CSRs.senvcfg.U
447  private val accessEnvcfg_EX_VI = csrIsSenvcfg && privState.isVirtual && !hstateen0.ENVCFG.asBool
448
449  // CSRIND bit 60 indirect reg (Sscsrind extensions), this is not implemented
450  // csr addr S: [0x150, 0x157]
451  private val csrIsSi = addr.head(9) === CSRs.siselect.U.head(9)
452  private val accessIND_EX_VI = csrIsSi && privState.isVirtual && !hstateen0.CSRIND.asBool
453
454  // AIA bit 59
455  private val ssAiaSaddr = addr === CSRs.stopi.U
456  private val accessAIA_EX_VI = ssAiaSaddr && privState.isVirtual && !hstateen0.AIA.asBool
457
458  // IMSIC bit 58 (Ssaia extension)
459  private val csrIsStopei = addr === CSRs.stopei.U
460  private val accessTopie_EX_VI = csrIsStopei && privState.isVirtual && !hstateen0.IMSIC.asBool
461
462  // CONTEXT bit 57 context reg (Sdtrig extensions), this is not implemented
463  private val csrIsScontext = addr === CSRs.scontext.U
464  private val accessContext_EX_VI = csrIsScontext && privState.isVirtual && !hstateen0.CONTEXT.asBool
465
466  // P1P13 bit 56, Read-only 0
467
468  // Custom bit 0
469  // [0x5c0, 0x5ff], [0x9c0, 0x9ff], [0xdc0, 0xdff]
470  private val csrIsSCustom   = (addr(11, 10) =/= "b00".U) && (addr(9, 8) === "b01".U) && (addr(7, 6) === "b11".U)
471  // [0x800, 0x8ff], [0xcc0, 0xcff]
472  private val csrIsUCustom   = (addr(11, 8) === "b1000".U) || (addr(11, 6) === "b110011".U)
473  private val accessCustom_EX_VI = (csrIsSCustom || csrIsUCustom) && privState.isVirtual && !hstateen0.C.asBool ||
474    csrIsUCustom && privState.isModeVU && hstateen0.C.asBool && !sstateen0.C.asBool
475
476  private val xstateControlAccess_EX_VI = accessStateen0_EX_VI || accessEnvcfg_EX_VI || accessIND_EX_VI || accessAIA_EX_VI ||
477    accessTopie_EX_VI || accessContext_EX_VI || accessCustom_EX_VI
478
479  io.out.virtualLevelPermit_EX_II := rwVStopei_EX_II
480  io.out.virtualLevelPermit_EX_VI := rwSatp_EX_VI || rwStopei_EX_VI || rwSip_Sie_EX_VI || rwStimecmp_EX_VI || accessHPM_EX_VI || xstateControlAccess_EX_VI
481}
482
483class IndirectCSRPermitModule extends Module {
484  val io = IO(new Bundle() {
485    val in = Input(new Bundle {
486      val csrAccess = new csrAccessIO
487      val privState = new PrivState
488      val aia = new aiaIO
489    })
490    val out = Output(new Bundle {
491      val indirectCSR_EX_II = Bool()
492      val indirectCSR_EX_VI = Bool()
493    })
494  })
495
496  private val (addr, privState) = (
497    io.in.csrAccess.addr,
498    io.in.privState,
499  )
500
501  private val (miselectIsIllegal, siselectIsIllegal, vsiselectIsIllegal) = (
502    io.in.aia.miselectIsIllegal,
503    io.in.aia.siselectIsIllegal,
504    io.in.aia.vsiselectIsIllegal,
505  )
506
507  private val (siselect, vsiselect) = (
508    io.in.aia.siselect,
509    io.in.aia.vsiselect,
510  )
511
512  private val mvienSEIE = io.in.aia.mvienSEIE
513
514  private val rwMireg_EX_II = miselectIsIllegal && addr === CSRs.mireg.U
515
516  private val rwSireg_EX_II = (
517      (privState.isModeHS && mvienSEIE && siselect >= 0x70.U && siselect <= 0xFF.U) ||
518      ((privState.isModeM || privState.isModeHS) && siselectIsIllegal) ||
519      (privState.isModeVS && (vsiselect < 0x30.U || (vsiselect >= 0x40.U && vsiselect < 0x70.U) || vsiselect > 0xFF.U))
520    ) && addr === CSRs.sireg.U
521
522  private val rwSireg_EX_VI = privState.isModeVS && (vsiselect >= 0x30.U && vsiselect <= 0x3F.U) && addr === CSRs.sireg.U
523
524  private val rwVSireg_EX_II = vsiselectIsIllegal && addr === CSRs.vsireg.U
525
526  io.out.indirectCSR_EX_II := rwMireg_EX_II || rwSireg_EX_II || rwVSireg_EX_II
527  io.out.indirectCSR_EX_VI := rwSireg_EX_VI
528}
529
530class csrAccessIO extends Bundle {
531  val ren   = Bool()
532  val wen   = Bool()
533  val addr  = UInt(12.W)
534}
535
536class xRetIO extends Bundle {
537  val mnret = Bool()
538  val mret = Bool()
539  val sret = Bool()
540  val dret = Bool()
541}
542
543class statusIO extends Bundle {
544  // Trap SRET
545  val tsr = Bool()
546  // Virtual Trap SRET
547  val vtsr = Bool()
548  // Trap Virtual Memory
549  val tvm = Bool()
550  // Virtual Trap Virtual Memory
551  val vtvm = Bool()
552  val vgein = UInt(6.W)
553  val mstatusFSOff = Bool()
554  val vsstatusFSOff = Bool()
555  val mstatusVSOff = Bool()
556  val vsstatusVSOff = Bool()
557}
558
559class xcounterenIO extends Bundle {
560  // Machine level counter enable, access PMC from the level less than M will trap EX_II
561  val mcounteren = UInt(32.W)
562  // Hypervisor level counter enable.
563  // Accessing PMC from VS/VU level will trap EX_VI, if m[x]=1 && h[x]=0
564  val hcounteren = UInt(32.W)
565  // Supervisor level counter enable.
566  // Accessing PMC from **HU level** will trap EX_II, if s[x]=0
567  // Accessing PMC from **VU level** will trap EX_VI, if m[x]=1 && h[x]=1 && s[x]=0
568  val scounteren = UInt(32.W)
569}
570
571class xenvcfgIO extends Bundle {
572  // Machine environment configuration register.
573  // Accessing stimecmp or vstimecmp from **Non-M level** will trap EX_II, if menvcfg.STCE=0
574  val menvcfg = UInt(64.W)
575  // Hypervisor environment configuration register.
576  // Accessing vstimecmp from ** V level** will trap EX_VI, if menvcfg.STCE=1 && henvcfg.STCE=0
577  val henvcfg = UInt(64.W)
578}
579
580class xstateenIO extends Bundle {
581  // Sm/Ssstateen: to control state access
582  val mstateen0 = new MstateenBundle0
583  val hstateen0 = new HstateenBundle0
584  val sstateen0 = new SstateenBundle0
585}
586
587class aiaIO extends Bundle {
588  val miselectIsIllegal = Bool()
589  val siselectIsIllegal = Bool()
590  val vsiselectIsIllegal = Bool()
591  val siselect = UInt(64.W)
592  val vsiselect = UInt(64.W)
593  val mvienSEIE = Bool()
594  val hvictlVTI = Bool()
595}
596
597class CSRPermitIO extends Bundle {
598  val in = Input(new Bundle {
599    val csrAccess = new csrAccessIO
600    val privState = new PrivState
601    val debugMode = Bool()
602    val xRet = new xRetIO
603    val status = new statusIO
604    val xcounteren = new xcounterenIO
605    val xenvcfg = new xenvcfgIO
606    val xstateen = new xstateenIO
607    val aia = new aiaIO
608  })
609
610  val out = Output(new Bundle {
611    val hasLegalWen   = Bool()
612    val hasLegalMNret = Bool()
613    val hasLegalMret  = Bool()
614    val hasLegalSret  = Bool()
615    val hasLegalDret  = Bool()
616    val hasLegalWriteFcsr = Bool()
617    val hasLegalWriteVcsr = Bool()
618    val EX_II = Bool()
619    val EX_VI = Bool()
620  })
621}
622