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