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