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