1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.util._ 5import freechips.rocketchip.rocket.CSRs 6import org.chipsalliance.cde.config.Parameters 7import utility.ZeroExt 8import xiangshan.backend.fu.NewCSR.CSRBundles._ 9import xiangshan.backend.fu.NewCSR.CSRConfig._ 10import xiangshan.backend.fu.NewCSR.CSRDefines.{CSRROField => RO, CSRRWField => RW, _} 11import xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._ 12import xiangshan.backend.fu.NewCSR.CSREvents.{SretEventSinkBundle, TrapEntryHSEventSinkBundle} 13import xiangshan.backend.fu.NewCSR.CSRFunc._ 14import xiangshan.backend.fu.NewCSR.ChiselRecordForField._ 15 16import scala.collection.immutable.SeqMap 17 18trait HypervisorLevel { self: NewCSR => 19 20 val hstatus = Module(new HstatusModule) 21 .setAddr(CSRs.hstatus) 22 23 val hedeleg = Module(new CSRModule("Hedeleg", new HedelegBundle)) 24 .setAddr(CSRs.hedeleg) 25 26 val hideleg = Module(new CSRModule("Hideleg", new HidelegBundle)) 27 .setAddr(CSRs.hideleg) 28 29 val hie = Module(new CSRModule("Hie", new HieBundle) 30 with HasIpIeBundle 31 with HypervisorBundle 32 { 33 val toMie = IO(new HieToMie) 34 35 val mieIsAlias = mideleg 36 37 bundle.getFields.map(_.lsb).foreach { num => 38 val wtMie = toMie.getByNum(num) 39 wtMie.specifyField( 40 _.valid := wen && mieIsAlias(num) && wtMie.bits.isRW.B, 41 _.bits := wen && mieIsAlias(num) && wtMie.bits.isRW.B &< wdata(num), 42 ) 43 44 regOut(num) := mieIsAlias(num) && wtMie.bits.isRW.B &< mie(num) 45 } 46 }) 47 .setAddr(CSRs.hie) 48 49 val htimedelta = Module(new CSRModule("Htimedelta")) 50 .setAddr(CSRs.htimedelta) 51 52 val hcounteren = Module(new CSRModule("Hcounteren", new Counteren)) 53 .setAddr(CSRs.hcounteren) 54 55 val hgeie = Module(new CSRModule("Hgeie", new HgeieBundle)) 56 .setAddr(CSRs.hgeie) 57 58 val hvien = Module(new CSRModule("Hvien", new HvienBundle)) 59 .setAddr(CSRs.hvien) 60 61 val hvictl = Module(new CSRModule("Hvictl", new HvictlBundle)) 62 .setAddr(CSRs.hvictl) 63 64 val henvcfg = Module(new CSRModule("Henvcfg", new HEnvCfg) with HasHypervisorEnvBundle { 65 when (!menvcfg.STCE.asBool) { 66 regOut.STCE := 0.U 67 } 68 when (!menvcfg.PBMTE) { 69 regOut.PBMTE := 0.U 70 } 71 }) 72 .setAddr(CSRs.henvcfg) 73 74 val htval = Module(new CSRModule("Htval", new XtvalBundle) with TrapEntryHSEventSinkBundle) 75 .setAddr(CSRs.htval) 76 77 val hip = Module(new CSRModule("Hip", new HipBundle) 78 with HypervisorBundle 79 with HasExternalInterruptBundle 80 with HasIpIeBundle 81 { 82 val toHvip = IO(new HipToHvip) 83 84 // hip.VSEIP is read-only alias of mip.VSEIP, mip.VSEIP := hvip.VSEIP|hgeip(VGEIN)|platIR.VSEIP 85 // hip.VSTIP is read-only alias of mip.VSTIP, mip.VSTIP := hvip.VSTIP|time+htimedelta>=vstimecmp 86 // hip.SGEIP is read-only alias of mip.SGEIP, mip.SGEIP := |(hgeip&hgeie) 87 regOut.VSTIP := mip.VSTIP 88 regOut.VSEIP := mip.VSEIP 89 regOut.SGEIP := mip.SGEIP 90 91 // hip.VSSIP is alias of hvip.VSSIP, writable 92 toHvip.VSSIP.valid := wen 93 toHvip.VSSIP.bits := wdata.VSSIP 94 regOut.VSSIP := this.hvip.VSSIP 95 // vsip.SSIP is alias of hip.VSSIP, so vsip.SSIP is alias of hvip.VSSIP. 96 // vsip.SSIP write throuth to hvip.VSSIP 97 }) 98 .setAddr(CSRs.hip) 99 100 val hvip = Module(new CSRModule("Hvip", new HvipBundle) { 101 val fromMip = IO(Flipped(new MipToHvip)) 102 val fromHip = IO(Flipped(new HipToHvip)) 103 val fromVSip = IO(Flipped(new VSipToHvip)) 104 105 when (fromMip.VSSIP.valid || fromHip.VSSIP.valid || fromVSip.VSSIP.valid) { 106 reg.VSSIP := Mux1H(Seq( 107 fromMip.VSSIP.valid -> fromMip.VSSIP.bits, 108 fromHip.VSSIP.valid -> fromHip.VSSIP.bits, 109 fromVSip.VSSIP.valid -> fromVSip.VSSIP.bits, 110 )) 111 } 112 113 reg.getLocal zip fromVSip.getLocal foreach { case (rLCIP, vsipLCIP) => 114 // sip should assert valid when hideleg=0 && hvien=1 115 when(vsipLCIP.valid) { 116 rLCIP := vsipLCIP.bits 117 } 118 } 119 }) 120 .setAddr(CSRs.hvip) 121 122 val hviprio1 = Module(new CSRModule("Hviprio1", new Hviprio1Bundle)) 123 .setAddr(CSRs.hviprio1) 124 125 val hviprio2 = Module(new CSRModule("Hviprio2", new Hviprio2Bundle)) 126 .setAddr(CSRs.hviprio2) 127 128 val htinst = Module(new CSRModule("Htinst", new XtinstBundle) with TrapEntryHSEventSinkBundle) 129 .setAddr(CSRs.htinst) 130 131 val hgatp = Module(new CSRModule("Hgatp", new HgatpBundle) { 132 // Ref: 13.2.10. Hypervisor Guest Address Translation and Protection Register (hgatp) 133 // A write to hgatp with an unsupported MODE value is not ignored as it is for satp. Instead, the fields of 134 // hgatp are WARL in the normal way, when so indicated. 135 136 // The length of ppn is 44 bits. 137 // make PPN[1:0] read-only zero. 138 val ppnMask = ZeroExt((Fill(PPNLength - 2, 1.U(1.W)) ## 0.U(2.W)).take(PAddrBits - PageOffsetWidth), PPNLength) 139 140 when (wen) { 141 reg.VMID := wdata.VMID 142 reg.PPN := wdata.PPN & ppnMask 143 when (wdata.MODE.isLegal) { 144 reg.MODE := wdata.MODE 145 }.otherwise { 146 reg.MODE := reg.MODE 147 } 148 }.otherwise { 149 reg := reg 150 } 151 }) 152 .setAddr(CSRs.hgatp) 153 154 val hgeip = Module(new CSRModule("Hgeip", new HgeipBundle) with HasAIABundle { 155 regOut.ip := aiaToCSR.vseip 156 }) 157 .setAddr(CSRs.hgeip) 158 159 val hstateen0 = Module(new CSRModule("Hstateen", new HstateenBundle0) with HasStateen0Bundle { 160 // For every bit in an mstateen CSR that is zero (whether read-only zero or set to zero), the same bit 161 // appears as read-only zero in the matching hstateen and sstateen CSRs. 162 regOut := reg.asUInt & fromMstateen0.asUInt 163 }).setAddr(CSRs.hstateen0) 164 165 val hypervisorCSRMods: Seq[CSRModule[_]] = Seq( 166 hstatus, 167 hedeleg, 168 hideleg, 169 hie, 170 htimedelta, 171 hcounteren, 172 hgeie, 173 hvien, 174 hvictl, 175 henvcfg, 176 htval, 177 hip, 178 hvip, 179 hviprio1, 180 hviprio2, 181 htinst, 182 hgatp, 183 hgeip, 184 hstateen0, 185 ) 186 187 val hypervisorCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from( 188 hypervisorCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator 189 ) 190 191 val hypervisorCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 192 hypervisorCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator 193 ) 194} 195 196class HstatusBundle extends CSRBundle { 197 198 val VSBE = RO(5).withReset(0.U) 199 val GVA = RW(6) 200 val SPV = VirtMode(7) 201 val SPVP = RW(8) 202 val HU = RW(9) 203 val VGEIN = HstatusVgeinField(17, 12, wNoFilter, rNoFilter).withReset(0.U) 204 val VTVM = RW(20).withReset(0.U) 205 val VTW = RW(21).withReset(0.U) 206 val VTSR = RW(22).withReset(0.U) 207 val VSXL = XLENField(33, 32).withReset(XLENField.XLEN64) 208 209} 210 211object HstatusVgeinField extends CSREnum with WLRLApply { 212 override def isLegal(enumeration: CSREnumType): Bool = enumeration.asUInt <= GEILEN.U 213} 214 215class HstatusModule(implicit p: Parameters) extends CSRModule("Hstatus", new HstatusBundle) 216 with SretEventSinkBundle 217 with TrapEntryHSEventSinkBundle 218 219class HvipBundle extends InterruptPendingBundle { 220 // VSSIP, VSTIP, VSEIP, localIP is writable 221 this.getVS.foreach(_.setRW().withReset(0.U)) 222 this.getLocal.foreach(_.setRW().withReset(0.U)) 223} 224 225class HieBundle extends InterruptEnableBundle { 226 // All bits in hie are RO, since all registers implemented in mie. 227} 228 229class HipBundle extends InterruptPendingBundle { 230 this.VSSIP.setRW().withReset(0.U) // aliasRW of mip.VSSIP when mideleg=1. 231 this.VSTIP.setRO().withReset(0.U) // aliasRO of mip.VSTIP when mideleg=1. (hvip.VSTIP | PLIC.VSTIP) 232 this.VSEIP.setRO().withReset(0.U) // aliasRO of mip.VSEIP when mideleg=1. (hvip.VSEIP | hgeip(hstatus.VGEIN) | PLIC.VSEIP) 233 this.SGEIP.setRO().withReset(0.U) // aliasRO of mip.SGEIP (|(hgeip & hegie)) 234} 235 236class HvienBundle extends InterruptEnableBundle { 237 // Ref: riscv interrupt spec - 6.3.2 Virtual interrupts for VS level 238 // Bits 12:0 of hvien are reserved and must be read-only zeros. 239 // For interrupt numbers 13–63, implementations may freely choose which bits of hvien are writable 240 // and which bits are read-only zero or one. 241 this.getLocal.foreach(_.setRW().withReset(0.U)) 242 243} 244 245class HgeieBundle extends CSRBundle { 246 val ie = RW(GEILEN, 1).withReset(0.U) 247 // bit 0 is read only 0 248} 249 250class HgeipBundle extends CSRBundle { 251 val ip = RO(GEILEN, 1) 252 // bit 0 is read only 0 253} 254 255class HedelegBundle extends ExceptionBundle { 256 this.getALL.foreach(_.setRW().withReset(0.U)) 257 // The default configs are RW 258 this.EX_HSCALL.setRO().withReset(0.U) 259 this.EX_VSCALL.setRO().withReset(0.U) 260 this.EX_MCALL .setRO().withReset(0.U) 261 this.EX_IGPF .setRO().withReset(0.U) 262 this.EX_LGPF .setRO().withReset(0.U) 263 this.EX_VI .setRO().withReset(0.U) 264 this.EX_SGPF .setRO().withReset(0.U) 265} 266 267class HidelegBundle extends InterruptBundle { 268 this.getALL.foreach(_.setRW().withReset(0.U)) 269 // default RW 270 this.SSI .setRO().withReset(0.U) 271 this.MSI .setRO().withReset(0.U) 272 this.STI .setRO().withReset(0.U) 273 this.MTI .setRO().withReset(0.U) 274 this.SEI .setRO().withReset(0.U) 275 this.MEI .setRO().withReset(0.U) 276 this.SGEI.setRO().withReset(0.U) 277 this.getLocal.foreach(_.setRO().withReset(0.U)) 278 this.LCOFI.setRW().withReset(0.U) 279} 280 281class HipToHvip extends Bundle { 282 val VSSIP = ValidIO(RW(0)) 283} 284 285class SipToHvip extends ToAliasIpLocalPart { 286 287} 288 289class HieToMie extends IeValidBundle { 290 this.getVS.foreach(_.bits.setRW()) 291 this.SGEIE.bits.setRW() 292} 293 294class HvictlBundle extends CSRBundle { 295 // Virtual Trap Interrupt control 296 val VTI = RW(30).withReset(0.U) 297 // WARL in AIA spec. 298 // RW, since we support max width of IID 299 val IID = RW(15 + HIIDWidth, 16).withReset(0.U) 300 // determines the interrupt’s presumed default priority order relative to a (virtual) supervisor external interrupt (SEI), major identity 9 301 // 0 = interrupt has higher default priority than an SEI 302 // 1 = interrupt has lower default priority than an SEI 303 // When hvictl.IID = 9, DPR is ignored. 304 // Todo: sort the interrupt specified by hvictl with DPR 305 val DPR = RW(9).withReset(0.U) 306 val IPRIOM = RW(8).withReset(0.U) 307 val IPRIO = RW(7, 0).withReset(0.U) 308} 309 310class Hviprio1Bundle extends CSRBundle { 311 val PrioSSI = RW(15, 8).withReset(0.U) 312 val PrioSTI = RW(31, 24).withReset(0.U) 313 val PrioCOI = RW(47, 40).withReset(0.U) 314 val Prio14 = RO(55, 48).withReset(0.U) 315 val Prio15 = RO(63, 56).withReset(0.U) 316} 317 318class Hviprio2Bundle extends CSRBundle { 319 val Prio16 = RO(7, 0).withReset(0.U) 320 val Prio17 = RO(15, 8).withReset(0.U) 321 val Prio18 = RO(23, 16).withReset(0.U) 322 val Prio19 = RO(31, 24).withReset(0.U) 323 val Prio20 = RO(39, 32).withReset(0.U) 324 val Prio21 = RO(47, 40).withReset(0.U) 325 val Prio22 = RO(55, 48).withReset(0.U) 326 val Prio23 = RO(63, 56).withReset(0.U) 327} 328 329class HgatpBundle extends CSRBundle { 330 val MODE = HgatpMode(63, 60, wNoFilter).withReset(HgatpMode.Bare) 331 // WARL in privileged spec. 332 // RW, since we support max width of VMID 333 val VMID = RW(44 - 1 + VMIDLEN, 44).withReset(0.U) 334 val PPN = RW(43, 0).withReset(0.U) 335} 336 337class HEnvCfg extends EnvCfg { 338 if (CSRConfig.EXT_SSTC) { 339 this.STCE.setRW().withReset(1.U) 340 } 341 // Always enable PBMT 342 this.PBMTE.setRO().withReset(1.U) 343} 344 345trait HypervisorBundle { self: CSRModule[_] => 346 val hstatus = IO(Input(new HstatusBundle)) 347} 348 349trait HasHypervisorEnvBundle { self: CSRModule[_] => 350 val menvcfg = IO(Input(new MEnvCfg)) 351 val privState = IO(Input(new PrivState)) 352 val accessStimecmp = IO(Input(Bool())) 353}