xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/VirtualSupervisorLevel.scala (revision 946f00901b63f0c0ae0b2d9431bb61f4be4ddecd)
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.CSREvents.{SretEventSinkBundle, TrapEntryVSEventSinkBundle}
17import xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._
18import xiangshan.backend.fu.NewCSR.CSRBundleImplicitCast._
19import xiangshan.backend.fu.NewCSR.ChiselRecordForField._
20
21import scala.collection.immutable.SeqMap
22
23trait VirtualSupervisorLevel { self: NewCSR with SupervisorLevel with HypervisorLevel =>
24
25  val vsstatus = Module(
26    new CSRModule("VSstatus", new SstatusBundle)
27      with SretEventSinkBundle
28      with TrapEntryVSEventSinkBundle
29  )
30    .setAddr(0x200)
31
32  val vsie = Module(new CSRModule("VSie", new VSieBundle)
33    with HypervisorBundle
34    with HasIpIeBundle
35  {
36    val toMie = IO(new VSieToMie)
37    val toSie = IO(new VSieToSie)
38
39    val mieIsAlias =  hideleg &  mideleg
40    val sieIsAlias =  hideleg & ~mideleg & mvien
41    val usingReg   = ~hideleg &            hvien
42
43    val originAliasIE = (mieIsAlias & mie) | (sieIsAlias & sie)
44    val shiftedIE = Cat(originAliasIE(63, InterruptNO.COI), 0.U(1.W), originAliasIE(InterruptNO.SGEI, InterruptNO.SSI))
45    val shiftedUsingReg = Cat(usingReg(63, InterruptNO.COI), 0.U(1.W), usingReg(InterruptNO.SGEI, InterruptNO.SSI))
46
47    regOut :=
48      shiftedIE |
49      (shiftedUsingReg & reg)
50
51    bundle.getVS.map(_.lsb).foreach { vsNum =>
52      // vsie.SSIE(1) map mie.VSSIE(1)
53      val sNum = vsNum - 1
54      val wtMie = toMie.getByNum(vsNum)
55      val wtSie = toSie.getByNum(vsNum)
56      val r = reg(sNum)
57
58      wtMie.specifyField(
59        _.valid := mieIsAlias(vsNum) && wtMie.bits.isRW.B && wen,
60        _.bits  := mieIsAlias(vsNum) && wtMie.bits.isRW.B && wen &< wdata(sNum),
61      )
62
63      wtSie.specifyField(
64        _.valid := sieIsAlias(vsNum) && wtSie.bits.isRW.B && wen,
65        _.bits  := sieIsAlias(vsNum) && wtSie.bits.isRW.B && wen &< wdata(sNum),
66      )
67
68      when (wen && usingReg(vsNum) && r.isRW.B) {
69        r := wdata(sNum)
70      }.otherwise {
71        r := r
72      }
73    }
74
75    bundle.getNonVS.map(_.lsb).foreach { num =>
76      val wtMie = toMie.getByNum(num)
77      val wtSie = toSie.getByNum(num)
78
79      val r = reg(num)
80
81      wtMie.specifyField(
82        _.valid := mieIsAlias(num) && wtMie.bits.isRW.B && wen,
83        _.bits  := mieIsAlias(num) && wtMie.bits.isRW.B && wen &< wdata(num),
84      )
85
86      wtSie.specifyField(
87        _.valid := sieIsAlias(num) && wtSie.bits.isRW.B && wen,
88        _.bits  := sieIsAlias(num) && wtSie.bits.isRW.B && wen &< wdata(num),
89      )
90
91      when(wen && usingReg(num) && r.isRW.B) {
92        r := wdata(num)
93      }.otherwise {
94        r := r
95      }
96    }
97
98    regOut.getFields.foreach { field =>
99      if (field.isHardWired) {
100        field := field.getHardWireValue
101      }
102    }
103  }).setAddr(0x204)
104
105  val vstvec = Module(new CSRModule("VStvec", new XtvecBundle))
106    .setAddr(0x205)
107
108  val vsscratch = Module(new CSRModule("VSscratch"))
109    .setAddr(0x240)
110
111  val vsepc = Module(
112    new CSRModule("VSepc", new Epc)
113      with TrapEntryVSEventSinkBundle
114    {
115      rdata := SignExt(Cat(reg.epc.asUInt, 0.U(1.W)), XLEN)
116    }
117  )
118    .setAddr(0x241)
119
120  val vscause = Module(
121    new CSRModule("VScause", new CauseBundle)
122      with TrapEntryVSEventSinkBundle
123  )
124    .setAddr(0x242)
125
126  // Todo: shrink the width of vstval to the maximum width Virtual Address
127  val vstval = Module(
128    new CSRModule("VStval")
129      with TrapEntryVSEventSinkBundle
130  )
131    .setAddr(0x243)
132
133  val vsip = Module(new CSRModule("VSip", new VSipBundle)
134    with HypervisorBundle
135    with HasIpIeBundle
136  {
137    val toMip  = IO(new VSipToMip).connectZeroNonRW
138    val toMvip = IO(new VSipToMvip).connectZeroNonRW
139    val toHvip = IO(new VSipToHvip).connectZeroNonRW
140
141    val originIP = mideleg & hideleg & mip | (~mideleg & hideleg & mvien & mvip) | (~hideleg & hvien & hvip)
142    val shiftedIP = Cat(originIP(63, InterruptNO.COI), 0.U(1.W), originIP(InterruptNO.SGEI, InterruptNO.SSI))
143
144    regOut := shiftedIP
145    regOut.getM.foreach(_ := 0.U)
146    regOut.getVS.foreach(_ := 0.U)
147    regOut.SGEIP := 0.U
148
149    toHvip.VSSIP.valid := wen && hideleg.VSSI
150    toHvip.VSSIP.bits  := wdata.SSIP
151
152    wdata.getLocal lazyZip
153      (toMip.getLocal lazyZip toMvip.getLocal lazyZip toHvip.getLocal) lazyZip
154      (mideleg.getLocal lazyZip hideleg.getLocal lazyZip mvien.getLocal) foreach {
155        case (wLCIP, (toMipLCIP, toMvipLCIP, toHvipLCIP), (midelegBit, hidelegBit, mvienBit)) =>
156          toMipLCIP .valid := wen &&  midelegBit &&  hidelegBit
157          toMvipLCIP.valid := wen && !midelegBit &&  hidelegBit &&  mvienBit
158          toHvipLCIP.valid := wen &&                !hidelegBit &&  mvienBit
159          toMipLCIP .bits := wLCIP
160          toMvipLCIP.bits := wLCIP
161          toHvipLCIP.bits := wLCIP
162    }
163
164    regOut.getFields.foreach { field =>
165      if (field.isHardWired) {
166        field := field.getHardWireValue
167      }
168    }
169  }).setAddr(0x244)
170
171  val vstimecmp = Module(new CSRModule("VStimecmp", new CSRBundle {
172    val vstimecmp = RW(63, 0).withReset(bitPatToUInt(BitPat.Y(64)))
173  }))
174    .setAddr(0x24D)
175
176  val vsatp = Module(new CSRModule("VSatp", new SatpBundle) with VirtualSupervisorBundle {
177    // Ref: 13.2.18. Virtual Supervisor Address Translation and Protection Register (vsatp)
178    // When V=0, a write to vsatp with an unsupported MODE value is either ignored as it is for satp, or the
179    // fields of vsatp are treated as WARL in the normal way.
180    // However, when V=1, a write to satp with an unsupported MODE value is ignored and no write to vsatp is effected.
181    // if satp is written with an unsupported MODE, the entire write has no effect; no fields in satp are modified.
182    //
183    // We treat all circumstances as if V=1. That is if vsatp is written with an unsupported MODE,
184    // the entire write has no effect; no fields in satp are modified.
185    when(wen && wdata.MODE.isLegal) {
186      reg := wdata
187    }.elsewhen(wen && !v && !wdata.MODE.isLegal) {
188      reg.PPN := wdata.PPN
189      reg.ASID := wdata.ASID
190    }.otherwise {
191      reg := reg
192    }
193  }).setAddr(0x280)
194
195  val virtualSupervisorCSRMods = Seq(
196    vsstatus,
197    vsie,
198    vstvec,
199    vsscratch,
200    vsepc,
201    vscause,
202    vstval,
203    vsip,
204    vstimecmp,
205    vsatp,
206  )
207
208  virtualSupervisorCSRMods.foreach(mod =>
209    require(mod.addr > 0, s"The address of ${mod.modName} has not been set, you can use setAddr(CSRAddr) to set it."))
210
211  val virtualSupervisorCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from(
212    virtualSupervisorCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata)))
213  )
214
215  val virtualSupervisorCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
216    virtualSupervisorCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt))
217  )
218
219  import freechips.rocketchip.rocket.CSRs
220
221  val sMapVS = SeqMap(
222    CSRs.sstatus  -> CSRs.vsstatus,
223    CSRs.sie      -> CSRs.vsie,
224    CSRs.stvec    -> CSRs.vstvec,
225    CSRs.sscratch -> CSRs.vsscratch,
226    CSRs.sepc     -> CSRs.vsepc,
227    CSRs.scause   -> CSRs.vscause,
228    CSRs.stval    -> CSRs.vstval,
229    CSRs.sip      -> CSRs.vsip,
230    CSRs.stimecmp -> CSRs.vstimecmp,
231    CSRs.siselect -> CSRs.vsiselect,
232    CSRs.sireg    -> CSRs.vsireg,
233    CSRs.stopei   -> CSRs.vstopei,
234    CSRs.satp     -> CSRs.vsatp,
235    CSRs.stopi    -> CSRs.vstopi,
236  )
237
238  val vsMapS: SeqMap[Int, Int] = SeqMap.from(sMapVS.map(x => (x._2 -> x._1)))
239}
240
241class VSipBundle extends InterruptPendingBundle {
242  // All pending bits in vsip are aliases of mip/mvip/hvip or read-only 0
243  this.getM.foreach(_.setHardWired(0.U))
244  this.getVS.foreach(_.setHardWired(0.U))
245  this.SGEIP.setHardWired(0.U)
246}
247
248class VSieBundle extends InterruptEnableBundle {
249  this.getLocal.foreach(_.setRW())
250  this.getM .foreach(_.setHardWired(0.U))
251  this.getVS.foreach(_.setHardWired(0.U))
252  this.SGEIE.setHardWired(0.U)
253}
254
255class VSipToMvip extends IpValidBundle {
256  this.getLocal.foreach(_.bits.setRW())
257}
258
259class VSipToHvip extends IpValidBundle {
260  this.VSSIP.bits.setRW()
261  this.getLocal.foreach(_.bits.setRW())
262}
263
264class VSieToMie extends IeValidBundle {
265  this.getVS.foreach(_.bits.setRW())
266  this.getLocal.foreach(_.bits.setRW())
267}
268
269class VSieToSie extends IeValidBundle {
270  this.getVS.foreach(_.bits.setRW())
271  this.getLocal.foreach(_.bits.setRW())
272}
273
274class VSipToHip extends Bundle {
275  val SSIP = ValidIO(RW(0))
276  val STIP = ValidIO(RW(0))
277  val SEIP = ValidIO(RW(0))
278}
279
280trait VirtualSupervisorBundle { self: CSRModule[_] =>
281  val v = IO(Input(Bool()))
282}
283