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