xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/SupervisorLevel.scala (revision dadf9cfc4ad5fd01f86dbade10d12f1a3c69f2d2)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util.BitPat.bitPatToUInt
5import chisel3.util.{BitPat, Cat, Fill, Mux1H, MuxCase, ValidIO}
6import utility.{SignExt, ZeroExt}
7import freechips.rocketchip.rocket.CSRs
8import xiangshan.backend.fu.NewCSR.CSRBundles._
9import xiangshan.backend.fu.NewCSR.CSRDefines._
10import xiangshan.backend.fu.NewCSR.CSRFunc._
11import xiangshan.backend.fu.NewCSR.CSRDefines.{CSRROField => RO, CSRRWField => RW, CSRWARLField => WARL, CSRWLRLField => WLRL, _}
12import xiangshan.backend.fu.NewCSR.CSRConfig._
13import xiangshan.backend.fu.NewCSR.CSREvents.TrapEntryHSEventSinkBundle
14import xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._
15import xiangshan.backend.fu.NewCSR.CSRBundleImplicitCast._
16import xiangshan.backend.fu.NewCSR.ChiselRecordForField._
17
18import scala.collection.immutable.SeqMap
19
20trait SupervisorLevel { self: NewCSR with MachineLevel =>
21  val sie = Module(new CSRModule("Sie", new SieBundle)
22    with HasIpIeBundle
23  {
24    val toMie    = IO(new SieToMie)
25    val fromVSie = IO(Flipped(new VSieToSie))
26
27    // Sie is alias of mie when mideleg=1.
28    // Otherwise, sie has seperate writable registers
29    // There are no regs in CSR sie.
30    val mieIsAlias = mideleg
31    val usingReg   = ~mideleg & mvien
32    regOut := (mieIsAlias & mie) | (usingReg & reg)
33
34    bundle.getFields.map(_.lsb).foreach { num =>
35      val wtMie  = toMie.getByNum(num)
36      val vsieWt = fromVSie.getByNum(num)
37
38      wtMie.specifyField(
39        _.valid := wen && mieIsAlias(num) && wtMie.bits.isRW.B,
40        _.bits  := wen && mieIsAlias(num) && wtMie.bits.isRW.B &< wdata(num),
41      )
42
43      when (
44        wen && usingReg(num) && reg(num).isRW.B ||
45        vsieWt.valid && usingReg(num) && vsieWt.bits.isRW.B
46      ) {
47        reg(num) := Mux1H(Seq(
48          wen          -> wdata(num),
49          vsieWt.valid -> vsieWt.bits,
50        ))
51      }.otherwise {
52        reg(num) := reg(num)
53      }
54    }
55
56    regOut.getFields.foreach { field =>
57      if (field.isHardWired) {
58        field := field.getHardWireValue
59      }
60    }
61  })
62    .setAddr(CSRs.sie)
63
64  val stvec = Module(new CSRModule("Stvec", new XtvecBundle))
65    .setAddr(CSRs.stvec)
66
67  val scounteren = Module(new CSRModule("Scounteren", new Counteren))
68    .setAddr(CSRs.scounteren)
69
70  val senvcfg = Module(new CSRModule("Senvcfg", new SEnvCfg))
71    .setAddr(CSRs.senvcfg)
72
73  val sscratch = Module(new CSRModule("Sscratch"))
74    .setAddr(CSRs.sscratch)
75
76  val sepc = Module(new CSRModule("Sepc", new Epc) with TrapEntryHSEventSinkBundle)
77    .setAddr(CSRs.sepc)
78
79  val scause = Module(new CSRModule("Scause", new CauseBundle) with TrapEntryHSEventSinkBundle)
80    .setAddr(CSRs.scause)
81
82  val stval = Module(new CSRModule("Stval", new XtvalBundle) with TrapEntryHSEventSinkBundle)
83    .setAddr(CSRs.stval)
84
85  val sip = Module(new CSRModule("Sip", new SipBundle)
86    with HasIpIeBundle
87  {
88    val toMip  = IO(new SipToMip)
89    val toMvip = IO(new SipToMvip)
90
91    // Ref: 7.1.3. Supervisor Interrupt Registers (sip and sie)
92    // The sip and sie registers are subsets of the mip and mie registers. Reading any
93    // implemented field, or writing any writable field, of sip/sie effects a read or write of the
94    // homonymous field of mip/mie.
95
96    // Ref: 3.1.9. Machine Interrupt Registers (mip and mie)
97    // Restricted views of the mip and mie registers appear as the sip and sie registers for supervisor level. If
98    // an interrupt is delegated to S-mode by setting a bit in the mideleg register, it becomes visible in the
99    // sip register and is maskable using the sie register. Otherwise, the corresponding bits in sip and sie
100    // are **read-only zero**.
101    val mipIsAlias  = mideleg
102    val mvipIsAlias = ~mideleg & mvien
103
104    dontTouch(mvipIsAlias)
105
106    regOut := mipIsAlias & mip | (mvipIsAlias & mvip)
107
108    bundle.getFields.map(_.lsb).foreach { num =>
109      val wtMip  = toMip.getByNum(num)
110      val wtMvip = toMvip.getByNum(num)
111
112      wtMip.specifyField(
113        _.valid := wen && mipIsAlias(num) && wtMip.bits.isRW.B,
114        _.bits  := wen && mipIsAlias(num) && wtMip.bits.isRW.B &< wdata(num),
115      )
116
117      wtMvip.specifyField(
118        _.valid := wen && mvipIsAlias(num) && wtMvip.bits.isRW.B,
119        _.bits  := wen && mvipIsAlias(num) && wtMvip.bits.isRW.B &< wdata(num),
120      )
121    }
122
123    regOut.getFields.foreach { field =>
124      if (field.isHardWired) {
125        field := field.getHardWireValue
126      }
127    }
128  })
129    .setAddr(CSRs.sip)
130
131  val stimecmp = Module(new CSRModule("Stimecmp", new CSRBundle {
132    val stimecmp = RW(63, 0).withReset(bitPatToUInt(BitPat.Y(64)))
133  }))
134    .setAddr(CSRs.stimecmp)
135
136  val satp = Module(new CSRModule("Satp", new SatpBundle) {
137    val ppnMask = ZeroExt(Fill(PPNLength, 1.U(1.W)).take(PAddrBits - PageOffsetWidth), PPNLength)
138    // If satp is written with an unsupported MODE,
139    // the entire write has no effect; no fields in satp are modified.
140    when (wen && wdata.MODE.isLegal) {
141      reg.MODE := wdata.MODE
142      reg.ASID := wdata.ASID
143      reg.PPN := wdata.PPN & ppnMask
144    }.otherwise {
145      reg := reg
146    }
147  })
148    .setAddr(CSRs.satp)
149
150  // scountovf: This register enables supervisor-level overflow interrupt handler software to quickly and easily
151  // determine which counter(s) have overflowed (without needing to make an execution environment call
152  // or series of calls ultimately up to M-mode).
153  val scountovf = Module(new CSRModule("Scountovf", new CSRBundle {
154    override val len: Int = 32
155    val OFVEC = RO(31, 3).withReset(0.U)
156  }) with HasMhpmeventOfBundle {
157    regOut.OFVEC := Mux1H(Seq(
158      privState.isModeM  -> ofVec,
159      privState.isModeHS -> (mcounteren.HPM.asUInt & ofVec),
160      privState.isModeVS -> (mcounteren.HPM.asUInt & hcounteren.HPM.asUInt & ofVec),
161    ))
162  }).setAddr(CSRs.scountovf)
163
164  val sstateen0 = Module(new CSRModule("Sstateen", new SstateenBundle0) with HasStateen0Bundle {
165    // For every bit in an mstateen CSR that is zero (whether read-only zero or set to zero), the same bit
166    // appears as read-only zero in the matching hstateen and sstateen CSRs. For every bit in an hstateen
167    // CSR that is zero (whether read-only zero or set to zero), the same bit appears as read-only zero in
168    // sstateen when accessed in VS-mode.
169    regOut := Mux(privState.isVirtual, fromHstateen0.asUInt, fromMstateen0.asUInt) & reg.asUInt
170  }).setAddr(CSRs.sstateen0)
171
172  val supervisorLevelCSRMods: Seq[CSRModule[_]] = Seq(
173    sie,
174    stvec,
175    scounteren,
176    senvcfg,
177    sscratch,
178    sepc,
179    scause,
180    stval,
181    sip,
182    stimecmp,
183    satp,
184    scountovf,
185    sstateen0,
186  )
187
188  val supervisorLevelCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap(
189    CSRs.sstatus -> (mstatus.wAliasSstatus, mstatus.sstatusRdata),
190  ) ++ SeqMap.from(
191    supervisorLevelCSRMods.map(csr => (csr.addr -> (csr.w, csr.rdata))).iterator
192  )
193
194  val supervisorLevelCSROutMap: SeqMap[Int, UInt] = SeqMap(
195    CSRs.sstatus -> mstatus.sstatus.asUInt,
196  ) ++ SeqMap.from(
197    supervisorLevelCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator
198  )
199}
200
201class SstatusBundle extends CSRBundle {
202  val SIE  = CSRWARLField   (1, wNoFilter)
203  val SPIE = CSRWARLField   (5, wNoFilter)
204  val UBE  = CSRROField     (6).withReset(0.U)
205  val SPP  = CSRWARLField   (8, wNoFilter).withReset(0.U)
206  val VS   = ContextStatus  (10, 9).withReset(ContextStatus.Off)
207  val FS   = ContextStatus  (14, 13).withReset(ContextStatus.Off)
208  val XS   = ContextStatusRO(16, 15).withReset(0.U)
209  val SUM  = CSRWARLField   (18, wNoFilter).withReset(0.U)
210  val MXR  = CSRWARLField   (19, wNoFilter).withReset(0.U)
211  val SDT  = CSRWARLField   (24, wNoFilter).withReset(0.U)
212  val UXL  = XLENField      (33, 32).withReset(XLENField.XLEN64)
213  val SD   = CSRROField     (63, (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty)
214}
215
216class SieBundle extends InterruptEnableBundle {
217  this.getHS.foreach(_.setRW().withReset(0.U))
218  this.STIE.setRO().withReset(0.U)
219  this.getLocal.foreach(_.setRW().withReset(0.U))
220  this.getM .foreach(_.setHardWired(0.U))
221  this.getVS.foreach(_.setHardWired(0.U))
222  this.SGEIE.setHardWired(0.U)
223}
224
225class SipBundle extends InterruptPendingBundle {
226  // All pending bits in sip are aliases of mip or read-only 0
227  this.getM .foreach(_.setHardWired(0.U))
228  this.getVS.foreach(_.setHardWired(0.U))
229  this.SGEIP.setHardWired(0.U)
230}
231
232class SatpBundle extends CSRBundle {
233  val MODE = SatpMode(63, 60, null).withReset(SatpMode.Bare)
234  // WARL in privileged spec.
235  // RW, since we support max width of ASID
236  val ASID = RW(44 - 1 + ASIDLEN, 44).withReset(0.U)
237  // Do WARL in SatpModule/VSatpModule
238  val PPN  = RW(43, 0).withReset(0.U)
239}
240
241class SEnvCfg extends EnvCfg
242
243class SipToMip extends IpValidBundle {
244  this.SSIP.bits.setRW()
245  this.LCOFIP.bits.setRW()
246}
247
248class SipToMvip extends IpValidBundle {
249  this.SSIP.bits.setRW()
250  this.getLocal.foreach(_.bits.setRW())
251}
252
253class SieToMie extends IeValidBundle {
254  this.getHS.foreach(_.bits.setRW())
255  this.getLocal.foreach(_.bits.setRW())
256}
257
258trait HasMhpmeventOfBundle { self: CSRModule[_] =>
259  val ofVec = IO(Input(UInt(perfCntNum.W)))
260  val privState = IO(Input(new PrivState))
261  val mcounteren = IO(Input(new Counteren))
262  val hcounteren = IO(Input(new Counteren))
263}