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