xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/VirtualSupervisorLevel.scala (revision f9913d9bdcc10cc60704f66908eec762622854c4)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import xiangshan.backend.fu.NewCSR.CSRBundles._
6import xiangshan.backend.fu.NewCSR.CSRDefines.{
7  CSRRWField => RW,
8  CSRROField => RO,
9  CSRWLRLField => WLRL,
10  CSRWARLField => WARL,
11  _
12}
13import xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast.CSREnumTypeToUInt
14import xiangshan.backend.fu.NewCSR.CSREvents.{SretEventSinkBundle, TrapEntryVSEventSinkBundle}
15
16import scala.collection.immutable.SeqMap
17
18trait VirtualSupervisorLevel { self: NewCSR with SupervisorLevel with HypervisorLevel =>
19
20  val vsstatus = Module(
21    new CSRModule("VSstatus", new SstatusBundle)
22      with SretEventSinkBundle
23      with TrapEntryVSEventSinkBundle
24  )
25    .setAddr(0x200)
26
27  val vsie = Module(new CSRModule("VSie", new VSie) with HypervisorBundle {
28    val toHie = IO(new VSieToHie)
29    // read alias of hie is here, write alias will be in hie
30    rdata.SEIE := Mux(hideleg.VSEI.asUInt === 0.U, 0.U, hie.VSEIE.asUInt)
31    rdata.STIE := Mux(hideleg.VSTI.asUInt === 0.U, 0.U, hie.VSTIE.asUInt)
32    rdata.SSIE := Mux(hideleg.VSSI.asUInt === 0.U, 0.U, hie.VSSIE.asUInt)
33
34    toHie.SEIE.valid := wen && hideleg.VSEI.asUInt.asBool
35    toHie.STIE.valid := wen && hideleg.VSTI.asUInt.asBool
36    toHie.SSIE.valid := wen && hideleg.VSSI.asUInt.asBool
37    toHie.SEIE.bits := wdata.SEIE
38    toHie.STIE.bits := wdata.STIE
39    toHie.SSIE.bits := wdata.SSIE
40  }).setAddr(0x204)
41
42  hie.fromVSie := vsie.toHie
43
44  val vstvec = Module(new CSRModule("VStvec", new XtvecBundle))
45    .setAddr(0x205)
46
47  val vsscratch = Module(new CSRModule("VSscratch"))
48    .setAddr(0x240)
49
50  val vsepc = Module(
51    new CSRModule("VSepc", new Epc)
52      with TrapEntryVSEventSinkBundle
53  )
54    .setAddr(0x241)
55
56  val vscause = Module(
57    new CSRModule("VScause", new CauseBundle)
58      with TrapEntryVSEventSinkBundle
59  )
60    .setAddr(0x242)
61
62  // Todo: shrink the width of vstval to the maximum width Virtual Address
63  val vstval = Module(
64    new CSRModule("VStval")
65      with TrapEntryVSEventSinkBundle
66  )
67    .setAddr(0x243)
68
69  val vsip = Module(new CSRModule("VSip", new VSip) with HypervisorBundle {
70    val toHip = IO(new VSipToHip)
71    // read alias of hip is here, write alias will be in hvip
72    // hip.VSEIP is read-only zero when hideleg.VSEI=0, alias if hip.VSEIP when hideleg.VSEI=1
73    rdata.SEIP := Mux(hideleg.VSEI.asUInt === 0.U, 0.U, hip.VSEIP.asUInt)
74    // hip.VSTIP is read-only zero when hideleg.VSTI=0, alias if hip.VSTIP when hideleg.VSTI=1
75    rdata.STIP := Mux(hideleg.VSTI.asUInt === 0.U, 0.U, hip.VSTIP.asUInt)
76    // hip.VSSIP is read-only zero when hideleg.VSSI=0, alias (writable) of the same bit in hvip, when hideleg.VSSI=1
77    rdata.SSIP := Mux(hideleg.VSSI.asUInt === 0.U, 0.U, hip.VSSIP.asUInt)
78
79    toHip.SEIP.valid := wen && hideleg.VSEI.asUInt.asBool
80    toHip.STIP.valid := wen && hideleg.VSTI.asUInt.asBool
81    toHip.SSIP.valid := wen && hideleg.VSSI.asUInt.asBool
82    toHip.SEIP.bits := wdata.SEIP
83    toHip.STIP.bits := wdata.STIP
84    toHip.SSIP.bits := wdata.SSIP
85  }).setAddr(0x244)
86
87  hip.fromVSip := vsip.toHip
88
89  val vstimecmp = Module(new CSRModule("VStimecmp"))
90    .setAddr(0x24D)
91
92  val vsatp = Module(new CSRModule("VSatp", new SatpBundle) {
93    // Ref: 13.2.18. Virtual Supervisor Address Translation and Protection Register (vsatp)
94    // When V=0, a write to vsatp with an unsupported MODE value is either ignored as it is for satp, or the
95    // fields of vsatp are treated as WARL in the normal way.
96    // However, when V=1, a write to satp with an unsupported MODE value is ignored and no write to vsatp is effected.
97    // if satp is written with an unsupported MODE, the entire write has no effect; no fields in satp are modified.
98    //
99    // We treat all circumstances as if V=1. That is if vsatp is written with an unsupported MODE,
100    // the entire write has no effect; no fields in satp are modified.
101    when(wen) {
102      when (wdata.MODE.isLegal) {
103        reg := wdata
104      }
105    }.otherwise {
106      reg := reg
107    }
108  }).setAddr(0x280)
109
110  val virtualSupervisorCSRMods = Seq(
111    vsstatus,
112    vsie,
113    vstvec,
114    vsscratch,
115    vsepc,
116    vscause,
117    vstval,
118    vsip,
119    vstimecmp,
120    vsatp,
121  )
122
123  virtualSupervisorCSRMods.foreach(mod =>
124    require(mod.addr > 0, s"The address of ${mod.modName} has not been set, you can use setAddr(CSRAddr) to set it."))
125
126  val virtualSupervisorCSRMap = SeqMap.from(
127    virtualSupervisorCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata.asInstanceOf[CSRBundle].asUInt)))
128  )
129
130  val virtualSupervisorCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
131    virtualSupervisorCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt))
132  )
133
134  import freechips.rocketchip.rocket.CSRs
135
136  val sMapVS = SeqMap(
137    CSRs.sstatus  -> CSRs.vsstatus,
138    CSRs.sie      -> CSRs.vsie,
139    CSRs.stvec    -> CSRs.vstvec,
140    CSRs.sscratch -> CSRs.vsscratch,
141    CSRs.sepc     -> CSRs.vsepc,
142    CSRs.scause   -> CSRs.vscause,
143    CSRs.stval    -> CSRs.vstval,
144    CSRs.sip      -> CSRs.vsip,
145    CSRs.stimecmp -> CSRs.vstimecmp,
146    CSRs.siselect -> CSRs.vsiselect,
147    CSRs.sireg    -> CSRs.vsireg,
148    CSRs.stopei   -> CSRs.vstopei,
149    CSRs.satp     -> CSRs.vsatp,
150    CSRs.stopi    -> CSRs.vstopi,
151  )
152
153  val vsMapS: SeqMap[Int, Int] = SeqMap.from(sMapVS.map(x => (x._2 -> x._1)))
154}
155
156class VSip extends InterruptPendingBundle {
157  this.getM.foreach(_.setRO())
158  this.getVS.foreach(_.setRO())
159  this.getSOC.foreach(_.setRO())
160  // 13.2.12. Virtual Supervisor Interrupt Registers (vsip and vsie)
161  // When bit 10 of hideleg is zero, vsip.SEIP is read-only zeros.
162  // Else, vsip.SEIP is alias of hip.VSEIP
163  this.SEIP
164  // When bit 6 of hideleg is zero, vsip.STIP is read-only zeros.
165  // Else, vsip.STIP is alias of hip.VSTIP
166  this.STIP
167  // When bit 2 of hideleg is zero, vsip.SSIP is read-only zeros.
168  // Else, vsip.SSIP is alias of hip.VSSIP
169  this.SEIP
170}
171
172class VSie extends InterruptEnableBundle {
173  this.getM.foreach(_.setRO())
174  this.getVS.foreach(_.setRO())
175  this.getSOC.foreach(_.setRO())
176  // 13.2.12. Virtual Supervisor Interrupt Registers (vsip and vsie)
177  // When bit 10 of hideleg is zero, vsip.SEIE is read-only zeros.
178  // Else, vsip.SEIE is alias of hip.VSEIE
179  this.SSIE
180  // When bit 6 of hideleg is zero, vsip.STIE is read-only zeros.
181  // Else, vsip.STIE is alias of hip.VSTIE
182  this.STIE
183  // When bit 2 of hideleg is zero, vsip.SSIE is read-only zeros.
184  // Else, vsip.SSIE is alias of hip.VSSIE
185  this.SEIE
186}
187
188class VSieToHie extends Bundle {
189  val SSIE: ValidIO[CSREnumType] = ValidIO(RW(0))
190  val STIE: ValidIO[CSREnumType] = ValidIO(RW(0))
191  val SEIE: ValidIO[CSREnumType] = ValidIO(RW(0))
192}
193
194class VSipToHip extends Bundle {
195  val SSIP = ValidIO(RW(0))
196  val STIP = ValidIO(RW(0))
197  val SEIP = ValidIO(RW(0))
198}
199