xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/SupervisorLevel.scala (revision b50a88ec4b3215ee22819c5f5cb3ba82f401d37f)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util.BitPat.bitPatToUInt
5import chisel3.util.{BitPat, Cat, Mux1H, MuxCase, ValidIO}
6import utility.SignExt
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    .setAddr(CSRs.sie)
57
58  val stvec = Module(new CSRModule("Stvec", new XtvecBundle))
59    .setAddr(CSRs.stvec)
60
61  val scounteren = Module(new CSRModule("Scounteren", new Counteren))
62    .setAddr(CSRs.scounteren)
63
64  val senvcfg = Module(new CSRModule("Senvcfg", new SEnvCfg))
65    .setAddr(CSRs.senvcfg)
66
67  val sscratch = Module(new CSRModule("Sscratch"))
68    .setAddr(CSRs.sscratch)
69
70  val sepc = Module(new CSRModule("Sepc", new Epc) with TrapEntryHSEventSinkBundle {
71    rdata := SignExt(Cat(reg.epc.asUInt, 0.U(1.W)), XLEN)
72  })
73    .setAddr(CSRs.sepc)
74
75  val scause = Module(new CSRModule("Scause", new CauseBundle) with TrapEntryHSEventSinkBundle)
76    .setAddr(CSRs.scause)
77
78  val stval = Module(new CSRModule("Stval") with TrapEntryHSEventSinkBundle)
79    .setAddr(CSRs.stval)
80
81  val sip = Module(new CSRModule("Sip", new SipBundle)
82    with HasIpIeBundle
83  {
84    val toMip  = IO(new SipToMip)
85    val toMvip = IO(new SipToMvip)
86
87    // Ref: 7.1.3. Supervisor Interrupt Registers (sip and sie)
88    // The sip and sie registers are subsets of the mip and mie registers. Reading any
89    // implemented field, or writing any writable field, of sip/sie effects a read or write of the
90    // homonymous field of mip/mie.
91
92    // Ref: 3.1.9. Machine Interrupt Registers (mip and mie)
93    // Restricted views of the mip and mie registers appear as the sip and sie registers for supervisor level. If
94    // an interrupt is delegated to S-mode by setting a bit in the mideleg register, it becomes visible in the
95    // sip register and is maskable using the sie register. Otherwise, the corresponding bits in sip and sie
96    // are **read-only zero**.
97    val mipIsAlias  = mideleg
98    val mvipIsAlias = ~mideleg & mvien
99
100    dontTouch(mvipIsAlias)
101
102    regOut := mipIsAlias & mip | (mvipIsAlias & mvip)
103
104    bundle.getFields.map(_.lsb).foreach { num =>
105      val wtMip  = toMip.getByNum(num)
106      val wtMvip = toMvip.getByNum(num)
107
108      wtMip.specifyField(
109        _.valid := wen && mipIsAlias(num) && wtMip.bits.isRW.B,
110        _.bits  := wen && mipIsAlias(num) && wtMip.bits.isRW.B &< wdata(num),
111      )
112
113      wtMvip.specifyField(
114        _.valid := wen && mvipIsAlias(num) && wtMvip.bits.isRW.B,
115        _.bits  := wen && mvipIsAlias(num) && wtMvip.bits.isRW.B &< wdata(num),
116      )
117    }
118  })
119    .setAddr(CSRs.sip)
120
121  val stimecmp = Module(new CSRModule("Stimecmp", new CSRBundle {
122    val stimecmp = RW(63, 0).withReset(bitPatToUInt(BitPat.Y(64)))
123  }))
124    .setAddr(CSRs.stimecmp)
125
126  val satp = Module(new CSRModule("Satp", new SatpBundle) {
127    // If satp is written with an unsupported MODE,
128    // the entire write has no effect; no fields in satp are modified.
129    when (wen && wdata.MODE.isLegal) {
130      reg := wdata
131    }.otherwise {
132      reg := reg
133    }
134  })
135    .setAddr(CSRs.satp)
136
137  val supervisorLevelCSRMods: Seq[CSRModule[_]] = Seq(
138    sie,
139    stvec,
140    scounteren,
141    senvcfg,
142    sscratch,
143    sepc,
144    scause,
145    stval,
146    sip,
147    stimecmp,
148    satp,
149  )
150
151  val supervisorLevelCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], Data)] = SeqMap(
152    CSRs.sstatus -> (mstatus.wAliasSstatus, mstatus.sstatus),
153  ) ++ SeqMap.from(
154    supervisorLevelCSRMods.map(csr => (csr.addr -> (csr.w, csr.rdata))).iterator
155  )
156
157  val supervisorLevelCSROutMap: SeqMap[Int, UInt] = SeqMap(
158    CSRs.sstatus -> mstatus.sstatus.asUInt,
159  ) ++ SeqMap.from(
160    supervisorLevelCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator
161  )
162}
163
164class SstatusBundle extends CSRBundle {
165  val SIE  = CSRWARLField   (1, wNoFilter)
166  val SPIE = CSRWARLField   (5, wNoFilter)
167  val UBE  = CSRROField     (6)
168  val SPP  = CSRWARLField   (8, wNoFilter)
169  val VS   = ContextStatus  (10, 9)
170  val FS   = ContextStatus  (14, 13)
171  val XS   = ContextStatusRO(16, 15).withReset(0.U)
172  val SUM  = CSRWARLField   (18, wNoFilter)
173  val MXR  = CSRWARLField   (19, wNoFilter)
174  val UXL  = XLENField      (33, 32).withReset(XLENField.XLEN64)
175  val SD   = CSRROField     (63, (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty)
176}
177
178class SieBundle extends InterruptEnableBundle {
179  this.getHS.foreach(_.setRW().withReset(0.U))
180  this.STIE.setRO()
181  this.getLocal.foreach(_.setRW().withReset(0.U))
182}
183
184class SipBundle extends InterruptPendingBundle {
185  // All pending bits in sip are aliases of mip or read-only 0
186}
187
188class SatpBundle extends CSRBundle {
189  final val PPN_msb = PAddrWidth - AddrWidthInPage - 1
190  val MODE = SatpMode(63, 60, null).withReset(SatpMode.Bare)
191  // WARL in privileged spec.
192  // RW, since we support max width of ASID
193  val ASID = RW(44 - 1 + ASIDLEN, 44)
194  val PPN  = RW(PPN_msb, 0)
195}
196
197class SEnvCfg extends EnvCfg
198
199class SipToMip extends IpValidBundle {
200  this.SSIP.bits.setRW()
201  this.LCOFIP.bits.setRW()
202}
203
204class SipToMvip extends IpValidBundle {
205  this.SSIP.bits.setRW()
206  this.getLocal.foreach(_.bits.setRW())
207}
208
209class SieToMie extends IeValidBundle {
210  this.getHS.foreach(_.bits.setRW())
211  this.getLocal.foreach(_.bits.setRW())
212}
213