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