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