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) with HasAIABundle { 158 regOut.ip := aiaToCSR.vseip 159 }) 160 .setAddr(CSRs.hgeip) 161 162 val hstateen0 = Module(new CSRModule("Hstateen", new HstateenBundle0) with HasStateen0Bundle { 163 // For every bit in an mstateen CSR that is zero (whether read-only zero or set to zero), the same bit 164 // appears as read-only zero in the matching hstateen and sstateen CSRs. 165 regOut := reg.asUInt & fromMstateen0.asUInt 166 }).setAddr(CSRs.hstateen0) 167 168 val hypervisorCSRMods: Seq[CSRModule[_]] = Seq( 169 hstatus, 170 hedeleg, 171 hideleg, 172 hie, 173 htimedelta, 174 hcounteren, 175 hgeie, 176 hvien, 177 hvictl, 178 henvcfg, 179 htval, 180 hip, 181 hvip, 182 hviprio1, 183 hviprio2, 184 htinst, 185 hgatp, 186 hgeip, 187 hstateen0, 188 ) 189 190 val hypervisorCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from( 191 hypervisorCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator 192 ) 193 194 val hypervisorCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 195 hypervisorCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator 196 ) 197} 198 199class HstatusBundle extends CSRBundle { 200 201 val VSBE = RO(5).withReset(0.U) 202 val GVA = RW(6) 203 val SPV = VirtMode(7) 204 val SPVP = RW(8) 205 val HU = RW(9) 206 val VGEIN = HstatusVgeinField(17, 12, wNoFilter, rNoFilter) 207 val VTVM = RW(20) 208 val VTW = RW(21) 209 val VTSR = RW(22) 210 val VSXL = XLENField(33, 32).withReset(XLENField.XLEN64) 211 212} 213 214object HstatusVgeinField extends CSREnum with WLRLApply { 215 override def isLegal(enum: CSREnumType): Bool = enum.asUInt <= GEILEN.U 216} 217 218class HstatusModule(implicit p: Parameters) extends CSRModule("Hstatus", new HstatusBundle) 219 with SretEventSinkBundle 220 with TrapEntryHSEventSinkBundle 221 222class HvipBundle extends InterruptPendingBundle { 223 // VSSIP, VSTIP, VSEIP, localIP is writable 224 this.getVS.foreach(_.setRW().withReset(0.U)) 225 this.getLocal.foreach(_.setRW().withReset(0.U)) 226} 227 228class HieBundle extends InterruptEnableBundle { 229 // All bits in hie are RO, since all registers implemented in mie. 230} 231 232class HipBundle extends InterruptPendingBundle { 233 this.VSSIP.setRW().withReset(0.U) // aliasRW of mip.VSSIP when mideleg=1. 234 this.VSTIP.setRO().withReset(0.U) // aliasRO of mip.VSTIP when mideleg=1. (hvip.VSTIP | PLIC.VSTIP) 235 this.VSEIP.setRO().withReset(0.U) // aliasRO of mip.VSEIP when mideleg=1. (hvip.VSEIP | hgeip(hstatus.VGEIN) | PLIC.VSEIP) 236 this.SGEIP.setRO().withReset(0.U) // aliasRO of mip.SGEIP (|(hgeip & hegie)) 237} 238 239class HvienBundle extends InterruptEnableBundle { 240 // Ref: riscv interrupt spec - 6.3.2 Virtual interrupts for VS level 241 // Bits 12:0 of hvien are reserved and must be read-only zeros. 242 // For interrupt numbers 13–63, implementations may freely choose which bits of hvien are writable 243 // and which bits are read-only zero or one. 244 this.getLocal.foreach(_.setRW().withReset(0.U)) 245 246} 247 248class HgeieBundle extends CSRBundle { 249 val ie = RW(GEILEN, 1) 250 // bit 0 is read only 0 251} 252 253class HgeipBundle extends CSRBundle { 254 val ip = RO(GEILEN, 1) 255 // bit 0 is read only 0 256} 257 258class HedelegBundle extends ExceptionBundle { 259 this.getALL.foreach(_.setRW().withReset(0.U)) 260 // The default configs are RW 261 this.EX_HSCALL.setRO().withReset(0.U) 262 this.EX_VSCALL.setRO().withReset(0.U) 263 this.EX_MCALL .setRO().withReset(0.U) 264 this.EX_IGPF .setRO().withReset(0.U) 265 this.EX_LGPF .setRO().withReset(0.U) 266 this.EX_VI .setRO().withReset(0.U) 267 this.EX_SGPF .setRO().withReset(0.U) 268} 269 270class HidelegBundle extends InterruptBundle { 271 this.getALL.foreach(_.setRW().withReset(0.U)) 272 // default RW 273 this.SSI .setRO().withReset(0.U) 274 this.MSI .setRO().withReset(0.U) 275 this.STI .setRO().withReset(0.U) 276 this.MTI .setRO().withReset(0.U) 277 this.SEI .setRO().withReset(0.U) 278 this.MEI .setRO().withReset(0.U) 279 this.SGEI.setRO().withReset(0.U) 280} 281 282class HipToHvip extends Bundle { 283 val VSSIP = ValidIO(RW(0)) 284} 285 286class SipToHvip extends ToAliasIpLocalPart { 287 288} 289 290class HieToMie extends IeValidBundle { 291 this.getVS.foreach(_.bits.setRW()) 292 this.SGEIE.bits.setRW() 293} 294 295class HvictlBundle extends CSRBundle { 296 // Virtual Trap Interrupt control 297 val VTI = RW(30).withReset(0.U) 298 // WARL in AIA spec. 299 // RW, since we support max width of IID 300 val IID = RW(15 + HIIDWidth, 16).withReset(0.U) 301 // determines the interrupt’s presumed default priority order relative to a (virtual) supervisor external interrupt (SEI), major identity 9 302 // 0 = interrupt has higher default priority than an SEI 303 // 1 = interrupt has lower default priority than an SEI 304 // When hvictl.IID = 9, DPR is ignored. 305 // Todo: sort the interrupt specified by hvictl with DPR 306 val DPR = RW(9).withReset(0.U) 307 val IPRIOM = RW(8).withReset(0.U) 308 val IPRIO = RW(7, 0).withReset(0.U) 309} 310 311class Hviprio1Bundle extends CSRBundle { 312 val PrioSSI = RW(15, 8).withReset(0.U) 313 val PrioSTI = RW(31, 24).withReset(0.U) 314 val PrioCOI = RW(47, 40).withReset(0.U) 315 val Prio14 = RO(55, 48).withReset(0.U) 316 val Prio15 = RO(63, 56).withReset(0.U) 317} 318 319class Hviprio2Bundle extends CSRBundle { 320 val Prio16 = RO(7, 0).withReset(0.U) 321 val Prio17 = RO(15, 8).withReset(0.U) 322 val Prio18 = RO(23, 16).withReset(0.U) 323 val Prio19 = RO(31, 24).withReset(0.U) 324 val Prio20 = RO(39, 32).withReset(0.U) 325 val Prio21 = RO(47, 40).withReset(0.U) 326 val Prio22 = RO(55, 48).withReset(0.U) 327 val Prio23 = RO(63, 56).withReset(0.U) 328} 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) 335 val PPN = RW(43, 0) 336} 337 338class HEnvCfg extends EnvCfg { 339 if (CSRConfig.EXT_SSTC) { 340 this.STCE.setRW().withReset(1.U) 341 } 342} 343 344trait HypervisorBundle { self: CSRModule[_] => 345 val hstatus = IO(Input(new HstatusBundle)) 346} 347 348trait HasHypervisorEnvBundle { self: CSRModule[_] => 349 val menvcfg = IO(Input(new MEnvCfg)) 350 val privState = IO(Input(new PrivState)) 351 val accessStimecmp = IO(Input(Bool())) 352}