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