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