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 override def isLegal(enumeration: CSREnumType): Bool = enumeration.asUInt <= GEILEN.U 224} 225 226class HstatusModule(implicit p: Parameters) extends CSRModule("Hstatus", new HstatusBundle) 227 with SretEventSinkBundle 228 with TrapEntryHSEventSinkBundle 229 230class HvipBundle extends InterruptPendingBundle { 231 // VSSIP, VSTIP, VSEIP, localIP is writable 232 this.getVS.foreach(_.setRW().withReset(0.U)) 233 this.getLocal.foreach(_.setRW().withReset(0.U)) 234} 235 236class HieBundle extends InterruptEnableBundle { 237 // All bits in hie are RO, since all registers implemented in mie. 238} 239 240class HipBundle extends InterruptPendingBundle { 241 this.VSSIP.setRW().withReset(0.U) // aliasRW of mip.VSSIP when mideleg=1. 242 this.VSTIP.setRO().withReset(0.U) // aliasRO of mip.VSTIP when mideleg=1. (hvip.VSTIP | PLIC.VSTIP) 243 this.VSEIP.setRO().withReset(0.U) // aliasRO of mip.VSEIP when mideleg=1. (hvip.VSEIP | hgeip(hstatus.VGEIN) | PLIC.VSEIP) 244 this.SGEIP.setRO().withReset(0.U) // aliasRO of mip.SGEIP (|(hgeip & hegie)) 245} 246 247class HvienBundle extends InterruptEnableBundle { 248 // Ref: riscv interrupt spec - 6.3.2 Virtual interrupts for VS level 249 // Bits 12:0 of hvien are reserved and must be read-only zeros. 250 // For interrupt numbers 13–63, implementations may freely choose which bits of hvien are writable 251 // and which bits are read-only zero or one. 252 this.getLocal.foreach(_.setRW().withReset(0.U)) 253 254} 255 256class HgeieBundle extends CSRBundle { 257 val ie = RW(GEILEN, 1).withReset(0.U) 258 // bit 0 is read only 0 259} 260 261class HgeipBundle extends CSRBundle { 262 val ip = RO(GEILEN, 1) 263 // bit 0 is read only 0 264} 265 266class HedelegBundle extends ExceptionBundle { 267 this.getALL.foreach(_.setRW().withReset(0.U)) 268 // The default configs are RW 269 this.EX_HSCALL.setRO().withReset(0.U) 270 this.EX_VSCALL.setRO().withReset(0.U) 271 this.EX_MCALL .setRO().withReset(0.U) 272 this.EX_IGPF .setRO().withReset(0.U) 273 this.EX_LGPF .setRO().withReset(0.U) 274 this.EX_VI .setRO().withReset(0.U) 275 this.EX_SGPF .setRO().withReset(0.U) 276 this.EX_DBLTRP.setRO().withReset(0.U) // double trap is not delegatable 277} 278 279class HidelegBundle extends InterruptBundle { 280 this.getALL.foreach(_.setRW().withReset(0.U)) 281 // default RW 282 this.SSI .setRO().withReset(0.U) 283 this.MSI .setRO().withReset(0.U) 284 this.STI .setRO().withReset(0.U) 285 this.MTI .setRO().withReset(0.U) 286 this.SEI .setRO().withReset(0.U) 287 this.MEI .setRO().withReset(0.U) 288 this.SGEI.setRO().withReset(0.U) 289 this.getLocal.foreach(_.setRO().withReset(0.U)) 290 this.LCOFI.setRW().withReset(0.U) 291} 292 293class HipToHvip extends Bundle { 294 val VSSIP = ValidIO(RW(0)) 295} 296 297class SipToHvip extends ToAliasIpLocalPart { 298 299} 300 301class HieToMie extends IeValidBundle { 302 this.getVS.foreach(_.bits.setRW()) 303 this.SGEIE.bits.setRW() 304} 305 306class HvictlBundle extends CSRBundle { 307 // Virtual Trap Interrupt control 308 val VTI = RW(30).withReset(0.U) 309 // WARL in AIA spec. 310 // RW, since we support max width of IID 311 val IID = RW(15 + HIIDWidth, 16).withReset(0.U) 312 // determines the interrupt’s presumed default priority order relative to a (virtual) supervisor external interrupt (SEI), major identity 9 313 // 0 = interrupt has higher default priority than an SEI 314 // 1 = interrupt has lower default priority than an SEI 315 // When hvictl.IID = 9, DPR is ignored. 316 // Todo: sort the interrupt specified by hvictl with DPR 317 val DPR = RW(9).withReset(0.U) 318 val IPRIOM = RW(8).withReset(0.U) 319 val IPRIO = RW(7, 0).withReset(0.U) 320} 321 322class Hviprio1Bundle extends CSRBundle { 323 val PrioSSI = RW(15, 8).withReset(0.U) 324 val PrioSTI = RW(31, 24).withReset(0.U) 325 val PrioCOI = RW(47, 40).withReset(0.U) 326 val Prio14 = RW(55, 48).withReset(0.U) 327 val Prio15 = RW(63, 56).withReset(0.U) 328} 329 330class Hviprio2Bundle extends FieldInitBundle 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 352class Htimedelta extends FieldInitBundle 353 354trait HypervisorBundle { self: CSRModule[_] => 355 val hstatus = IO(Input(new HstatusBundle)) 356} 357 358trait HasHypervisorEnvBundle { self: CSRModule[_] => 359 val menvcfg = IO(Input(new MEnvCfg)) 360}