xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/VirtualSupervisorLevel.scala (revision 760398d77ceaf708c6dbc8a489765e90cd0e0aae)
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 satp is written with an unsupported MODE,
100    // the entire write has no effect; no fields in satp are modified.
101    when(wen && !wdata.MODE.isLegal) {
102      reg.ASID := reg.ASID
103      reg.PPN := reg.PPN
104    }
105  }).setAddr(0x280)
106
107  val virtualSupervisorCSRMods = Seq(
108    vsstatus,
109    vsie,
110    vstvec,
111    vsscratch,
112    vsepc,
113    vscause,
114    vstval,
115    vsip,
116    vstimecmp,
117    vsatp,
118  )
119
120  virtualSupervisorCSRMods.foreach(mod =>
121    require(mod.addr > 0, s"The address of ${mod.modName} has not been set, you can use setAddr(CSRAddr) to set it."))
122
123  val virtualSupervisorCSRMap = SeqMap.from(
124    virtualSupervisorCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata.asInstanceOf[CSRBundle].asUInt)))
125  )
126
127  val virtualSupervisorCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
128    virtualSupervisorCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt))
129  )
130
131  import freechips.rocketchip.rocket.CSRs
132
133  val sMapVS = SeqMap(
134    CSRs.sstatus  -> CSRs.vsstatus,
135    CSRs.sie      -> CSRs.vsie,
136    CSRs.stvec    -> CSRs.vstvec,
137    CSRs.sscratch -> CSRs.vsscratch,
138    CSRs.sepc     -> CSRs.vsepc,
139    CSRs.scause   -> CSRs.vscause,
140    CSRs.stval    -> CSRs.vstval,
141    CSRs.sip      -> CSRs.vsip,
142    CSRs.stimecmp -> CSRs.vstimecmp,
143    CSRs.siselect -> CSRs.vsiselect,
144    CSRs.sireg    -> CSRs.vsireg,
145    CSRs.stopei   -> CSRs.vstopei,
146    CSRs.satp     -> CSRs.vsatp,
147    CSRs.stopi    -> CSRs.vstopi,
148  )
149
150  val vsMapS: SeqMap[Int, Int] = SeqMap.from(sMapVS.map(x => (x._2 -> x._1)))
151}
152
153class VSip extends InterruptPendingBundle {
154  this.getM.foreach(_.setRO())
155  this.getVS.foreach(_.setRO())
156  this.getSOC.foreach(_.setRO())
157  // 13.2.12. Virtual Supervisor Interrupt Registers (vsip and vsie)
158  // When bit 10 of hideleg is zero, vsip.SEIP is read-only zeros.
159  // Else, vsip.SEIP is alias of hip.VSEIP
160  this.SEIP
161  // When bit 6 of hideleg is zero, vsip.STIP is read-only zeros.
162  // Else, vsip.STIP is alias of hip.VSTIP
163  this.STIP
164  // When bit 2 of hideleg is zero, vsip.SSIP is read-only zeros.
165  // Else, vsip.SSIP is alias of hip.VSSIP
166  this.SEIP
167}
168
169class VSie extends InterruptEnableBundle {
170  this.getM.foreach(_.setRO())
171  this.getVS.foreach(_.setRO())
172  // 13.2.12. Virtual Supervisor Interrupt Registers (vsip and vsie)
173  // When bit 10 of hideleg is zero, vsip.SEIE is read-only zeros.
174  // Else, vsip.SEIE is alias of hip.VSEIE
175  this.SSIE
176  // When bit 6 of hideleg is zero, vsip.STIE is read-only zeros.
177  // Else, vsip.STIE is alias of hip.VSTIE
178  this.STIE
179  // When bit 2 of hideleg is zero, vsip.SSIE is read-only zeros.
180  // Else, vsip.SSIE is alias of hip.VSSIE
181  this.SEIE
182}
183
184class VSieToHie extends Bundle {
185  val SSIE: ValidIO[CSREnumType] = ValidIO(RW(0))
186  val STIE: ValidIO[CSREnumType] = ValidIO(RW(0))
187  val SEIE: ValidIO[CSREnumType] = ValidIO(RW(0))
188}
189
190class VSipToHip extends Bundle {
191  val SSIP = ValidIO(RW(0))
192  val STIP = ValidIO(RW(0))
193  val SEIP = ValidIO(RW(0))
194}
195