xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/VirtualSupervisorLevel.scala (revision 25dc4a827ee27e3ccbaf02e8e5134872cba28fcd)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import xiangshan.backend.fu.NewCSR.CSRBundles._
6import xiangshan.backend.fu.NewCSR.CSRDefines.{
7  CSRRWField => RW,
8  CSRROField => RO,
9  CSRWLRLField => WLRL,
10  CSRWARLField => WARL,
11  _
12}
13import xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast.CSREnumTypeToUInt
14import xiangshan.backend.fu.NewCSR.CSREvents.{SretEventSinkBundle, TrapEntryVSEventSinkBundle}
15
16import scala.collection.immutable.SeqMap
17
18trait VirtualSupervisorLevel { self: NewCSR with HypervisorLevel =>
19
20  val vsstatus = Module(
21    new CSRModule("VSstatus", new SstatusBundle)
22      with SretEventSinkBundle
23      with TrapEntryVSEventSinkBundle
24  )
25    .setAddr(0x200)
26
27  val vsie = Module(new CSRModule("VSie", new VSie) with HypervisorBundle {
28    val toHie = IO(new VSieToHie)
29    // read alias of hie is here, write alias will be in hie
30    rdata.SEIE := Mux(hideleg.VSEI.asUInt === 0.U, 0.U, hie.VSEIE.asUInt)
31    rdata.STIE := Mux(hideleg.VSTI.asUInt === 0.U, 0.U, hie.VSTIE.asUInt)
32    rdata.SSIE := Mux(hideleg.VSSI.asUInt === 0.U, 0.U, hie.VSSIE.asUInt)
33
34    toHie.SEIE.valid := wen && hideleg.VSEI.asUInt.asBool
35    toHie.STIE.valid := wen && hideleg.VSTI.asUInt.asBool
36    toHie.SSIE.valid := wen && hideleg.VSSI.asUInt.asBool
37    toHie.SEIE.bits := wdata.SEIE
38    toHie.STIE.bits := wdata.STIE
39    toHie.SSIE.bits := wdata.SSIE
40  }).setAddr(0x204)
41
42  hie.fromVSie := vsie.toHie
43
44  val vstvec = Module(new CSRModule("VStvec", new XtvecBundle))
45    .setAddr(0x205)
46
47  val vsscratch = Module(new CSRModule("VSscratch"))
48    .setAddr(0x240)
49
50  val vsepc = Module(
51    new CSRModule("VSepc", new Epc)
52      with TrapEntryVSEventSinkBundle
53  )
54    .setAddr(0x241)
55
56  val vscause = Module(
57    new CSRModule("VScause", new CauseBundle)
58      with TrapEntryVSEventSinkBundle
59  )
60    .setAddr(0x242)
61
62  // Todo: shrink the width of vstval to the maximum width Virtual Address
63  val vstval = Module(
64    new CSRModule("VStval")
65      with TrapEntryVSEventSinkBundle
66  )
67    .setAddr(0x243)
68
69  val vsip = Module(new CSRModule("VSip", new VSip) with HypervisorBundle {
70    val toHip = IO(new VSipToHip)
71    // read alias of hip is here, write alias will be in hvip
72    // hip.VSEIP is read-only zero when hideleg.VSEI=0, alias if hip.VSEIP when hideleg.VSEI=1
73    rdata.SEIP := Mux(hideleg.VSEI.asUInt === 0.U, 0.U, hip.VSEIP.asUInt)
74    // hip.VSTIP is read-only zero when hideleg.VSTI=0, alias if hip.VSTIP when hideleg.VSTI=1
75    rdata.STIP := Mux(hideleg.VSTI.asUInt === 0.U, 0.U, hip.VSTIP.asUInt)
76    // hip.VSSIP is read-only zero when hideleg.VSSI=0, alias (writable) of the same bit in hvip, when hideleg.VSSI=1
77    rdata.SSIP := Mux(hideleg.VSSI.asUInt === 0.U, 0.U, hip.VSSIP.asUInt)
78
79    toHip.SEIP.valid := wen && hideleg.VSEI.asUInt.asBool
80    toHip.STIP.valid := wen && hideleg.VSTI.asUInt.asBool
81    toHip.SSIP.valid := wen && hideleg.VSSI.asUInt.asBool
82    toHip.SEIP.bits := wdata.SEIP
83    toHip.STIP.bits := wdata.STIP
84    toHip.SSIP.bits := wdata.SSIP
85  }).setAddr(0x244)
86
87  hip.fromVSip := vsip.toHip
88
89  val vsatp = Module(new CSRModule("VSatp", new SatpBundle) {
90    // Ref: 13.2.18. Virtual Supervisor Address Translation and Protection Register (vsatp)
91    // When V=0, a write to vsatp with an unsupported MODE value is either ignored as it is for satp, or the
92    // fields of vsatp are treated as WARL in the normal way.
93    // However, when V=1, a write to satp with an unsupported MODE value is ignored and no write to vsatp is effected.
94    // if satp is written with an unsupported MODE, the entire write has no effect; no fields in satp are modified.
95    //
96    // We treat all circumstances as if V=1. That is if satp is written with an unsupported MODE,
97    // the entire write has no effect; no fields in satp are modified.
98    when(wen && !wdata.MODE.isLegal) {
99      reg.ASID := reg.ASID
100      reg.PPN := reg.PPN
101    }
102  }).setAddr(0x280)
103
104  val virtualSupervisorCSRMods = Seq(
105    vsstatus,
106    vsie,
107    vstvec,
108    vsscratch,
109    vsepc,
110    vscause,
111    vstval,
112    vsip,
113    vsatp,
114  )
115
116  virtualSupervisorCSRMods.foreach(mod =>
117    require(mod.addr > 0, s"The address of ${mod.modName} has not been set, you can use setAddr(CSRAddr) to set it."))
118
119  val virtualSupervisorCSRMap = SeqMap.from(
120    virtualSupervisorCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata.asInstanceOf[CSRBundle].asUInt)))
121  )
122
123  val virtualSupervisorCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
124    virtualSupervisorCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt))
125  )
126}
127
128class VSip extends InterruptPendingBundle {
129  this.getM.foreach(_.setRO())
130  this.getVS.foreach(_.setRO())
131  this.getSOC.foreach(_.setRO())
132  // 13.2.12. Virtual Supervisor Interrupt Registers (vsip and vsie)
133  // When bit 10 of hideleg is zero, vsip.SEIP is read-only zeros.
134  // Else, vsip.SEIP is alias of hip.VSEIP
135  this.SEIP
136  // When bit 6 of hideleg is zero, vsip.STIP is read-only zeros.
137  // Else, vsip.STIP is alias of hip.VSTIP
138  this.STIP
139  // When bit 2 of hideleg is zero, vsip.SSIP is read-only zeros.
140  // Else, vsip.SSIP is alias of hip.VSSIP
141  this.SEIP
142}
143
144class VSie extends InterruptEnableBundle {
145  this.getM.foreach(_.setRO())
146  this.getVS.foreach(_.setRO())
147  // 13.2.12. Virtual Supervisor Interrupt Registers (vsip and vsie)
148  // When bit 10 of hideleg is zero, vsip.SEIE is read-only zeros.
149  // Else, vsip.SEIE is alias of hip.VSEIE
150  this.SSIE
151  // When bit 6 of hideleg is zero, vsip.STIE is read-only zeros.
152  // Else, vsip.STIE is alias of hip.VSTIE
153  this.STIE
154  // When bit 2 of hideleg is zero, vsip.SSIE is read-only zeros.
155  // Else, vsip.SSIE is alias of hip.VSSIE
156  this.SEIE
157}
158
159class VSieToHie extends Bundle {
160  val SSIE: ValidIO[CSREnumType] = ValidIO(RW(0))
161  val STIE: ValidIO[CSREnumType] = ValidIO(RW(0))
162  val SEIE: ValidIO[CSREnumType] = ValidIO(RW(0))
163}
164
165class VSipToHip extends Bundle {
166  val SSIP = ValidIO(RW(0))
167  val STIP = ValidIO(RW(0))
168  val SEIP = ValidIO(RW(0))
169}
170