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 this.EX_DBLTRP.setRO().withReset(0.U) // double trap is not delegatable 266} 267 268class HidelegBundle extends InterruptBundle { 269 this.getALL.foreach(_.setRW().withReset(0.U)) 270 // default RW 271 this.SSI .setRO().withReset(0.U) 272 this.MSI .setRO().withReset(0.U) 273 this.STI .setRO().withReset(0.U) 274 this.MTI .setRO().withReset(0.U) 275 this.SEI .setRO().withReset(0.U) 276 this.MEI .setRO().withReset(0.U) 277 this.SGEI.setRO().withReset(0.U) 278 this.getLocal.foreach(_.setRO().withReset(0.U)) 279 this.LCOFI.setRW().withReset(0.U) 280} 281 282class HipToHvip extends Bundle { 283 val VSSIP = ValidIO(RW(0)) 284} 285 286class SipToHvip extends ToAliasIpLocalPart { 287 288} 289 290class HieToMie extends IeValidBundle { 291 this.getVS.foreach(_.bits.setRW()) 292 this.SGEIE.bits.setRW() 293} 294 295class HvictlBundle extends CSRBundle { 296 // Virtual Trap Interrupt control 297 val VTI = RW(30).withReset(0.U) 298 // WARL in AIA spec. 299 // RW, since we support max width of IID 300 val IID = RW(15 + HIIDWidth, 16).withReset(0.U) 301 // determines the interrupt’s presumed default priority order relative to a (virtual) supervisor external interrupt (SEI), major identity 9 302 // 0 = interrupt has higher default priority than an SEI 303 // 1 = interrupt has lower default priority than an SEI 304 // When hvictl.IID = 9, DPR is ignored. 305 // Todo: sort the interrupt specified by hvictl with DPR 306 val DPR = RW(9).withReset(0.U) 307 val IPRIOM = RW(8).withReset(0.U) 308 val IPRIO = RW(7, 0).withReset(0.U) 309} 310 311class Hviprio1Bundle extends CSRBundle { 312 val PrioSSI = RW(15, 8).withReset(0.U) 313 val PrioSTI = RW(31, 24).withReset(0.U) 314 val PrioCOI = RW(47, 40).withReset(0.U) 315 val Prio14 = RO(55, 48).withReset(0.U) 316 val Prio15 = RO(63, 56).withReset(0.U) 317} 318 319class Hviprio2Bundle extends CSRBundle { 320 val Prio16 = RO(7, 0).withReset(0.U) 321 val Prio17 = RO(15, 8).withReset(0.U) 322 val Prio18 = RO(23, 16).withReset(0.U) 323 val Prio19 = RO(31, 24).withReset(0.U) 324 val Prio20 = RO(39, 32).withReset(0.U) 325 val Prio21 = RO(47, 40).withReset(0.U) 326 val Prio22 = RO(55, 48).withReset(0.U) 327 val Prio23 = RO(63, 56).withReset(0.U) 328} 329 330class HgatpBundle extends CSRBundle { 331 val MODE = HgatpMode(63, 60, wNoFilter).withReset(HgatpMode.Bare) 332 // WARL in privileged spec. 333 // RW, since we support max width of VMID 334 val VMID = RW(44 - 1 + VMIDLEN, 44).withReset(0.U) 335 val PPN = RW(43, 0).withReset(0.U) 336} 337 338class HEnvCfg extends EnvCfg { 339 if (CSRConfig.EXT_SSTC) { 340 this.STCE.setRW().withReset(1.U) 341 } 342 this.PBMTE.setRW().withReset(0.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}