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