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) { 66 regOut.STCE := 0.U 67 } 68 when(!menvcfg.PBMTE) { 69 regOut.PBMTE := 0.U 70 } 71 when(!menvcfg.DTE) { 72 regOut.DTE := 0.U 73 } 74 }).setAddr(CSRs.henvcfg) 75 76 val htval = Module(new CSRModule("Htval", new XtvalBundle) with TrapEntryHSEventSinkBundle) 77 .setAddr(CSRs.htval) 78 79 val hip = Module(new CSRModule("Hip", new HipBundle) 80 with HypervisorBundle 81 with HasExternalInterruptBundle 82 with HasIpIeBundle 83 { 84 val toHvip = IO(new HipToHvip) 85 86 // hip.VSEIP is read-only alias of mip.VSEIP, mip.VSEIP := hvip.VSEIP|hgeip(VGEIN)|platIR.VSEIP 87 // hip.VSTIP is read-only alias of mip.VSTIP, mip.VSTIP := hvip.VSTIP|time+htimedelta>=vstimecmp 88 // hip.SGEIP is read-only alias of mip.SGEIP, mip.SGEIP := |(hgeip&hgeie) 89 regOut.VSTIP := mip.VSTIP 90 regOut.VSEIP := mip.VSEIP 91 regOut.SGEIP := mip.SGEIP 92 93 // hip.VSSIP is alias of hvip.VSSIP, writable 94 toHvip.VSSIP.valid := wen 95 toHvip.VSSIP.bits := wdata.VSSIP 96 regOut.VSSIP := this.hvip.VSSIP 97 // vsip.SSIP is alias of hip.VSSIP, so vsip.SSIP is alias of hvip.VSSIP. 98 // vsip.SSIP write throuth to hvip.VSSIP 99 }) 100 .setAddr(CSRs.hip) 101 102 val hvip = Module(new CSRModule("Hvip", new HvipBundle) { 103 val fromMip = IO(Flipped(new MipToHvip)) 104 val fromHip = IO(Flipped(new HipToHvip)) 105 val fromVSip = IO(Flipped(new VSipToHvip)) 106 107 when (fromMip.VSSIP.valid || fromHip.VSSIP.valid || fromVSip.VSSIP.valid) { 108 reg.VSSIP := Mux1H(Seq( 109 fromMip.VSSIP.valid -> fromMip.VSSIP.bits, 110 fromHip.VSSIP.valid -> fromHip.VSSIP.bits, 111 fromVSip.VSSIP.valid -> fromVSip.VSSIP.bits, 112 )) 113 } 114 115 reg.getLocal zip fromVSip.getLocal foreach { case (rLCIP, vsipLCIP) => 116 // sip should assert valid when hideleg=0 && hvien=1 117 when(vsipLCIP.valid) { 118 rLCIP := vsipLCIP.bits 119 } 120 } 121 }) 122 .setAddr(CSRs.hvip) 123 124 val hviprio1 = Module(new CSRModule("Hviprio1", new Hviprio1Bundle)) 125 .setAddr(CSRs.hviprio1) 126 127 val hviprio2 = Module(new CSRModule("Hviprio2", new Hviprio2Bundle)) 128 .setAddr(CSRs.hviprio2) 129 130 val htinst = Module(new CSRModule("Htinst", new XtinstBundle) with TrapEntryHSEventSinkBundle) 131 .setAddr(CSRs.htinst) 132 133 val hgatp = Module(new CSRModule("Hgatp", new HgatpBundle) { 134 // Ref: 13.2.10. Hypervisor Guest Address Translation and Protection Register (hgatp) 135 // A write to hgatp with an unsupported MODE value is not ignored as it is for satp. Instead, the fields of 136 // hgatp are WARL in the normal way, when so indicated. 137 138 // The length of ppn is 44 bits. 139 // make PPN[1:0] read-only zero. 140 val ppnMask = ZeroExt((Fill(PPNLength - 2, 1.U(1.W)) ## 0.U(2.W)).take(PAddrBits - PageOffsetWidth), PPNLength) 141 142 when (wen) { 143 reg.VMID := wdata.VMID 144 reg.PPN := wdata.PPN & ppnMask 145 when (wdata.MODE.isLegal) { 146 reg.MODE := wdata.MODE 147 }.otherwise { 148 reg.MODE := reg.MODE 149 } 150 }.otherwise { 151 reg := reg 152 } 153 }) 154 .setAddr(CSRs.hgatp) 155 156 val hgeip = Module(new CSRModule("Hgeip", new HgeipBundle) with HasAIABundle { 157 regOut.ip := aiaToCSR.vseip 158 }) 159 .setAddr(CSRs.hgeip) 160 161 val hstateen0 = Module(new CSRModule("Hstateen", new HstateenBundle0) with HasStateen0Bundle { 162 // For every bit in an mstateen CSR that is zero (whether read-only zero or set to zero), the same bit 163 // appears as read-only zero in the matching hstateen and sstateen CSRs. 164 regOut := reg.asUInt & fromMstateen0.asUInt 165 }).setAddr(CSRs.hstateen0) 166 167 val hypervisorCSRMods: Seq[CSRModule[_]] = Seq( 168 hstatus, 169 hedeleg, 170 hideleg, 171 hie, 172 htimedelta, 173 hcounteren, 174 hgeie, 175 hvien, 176 hvictl, 177 henvcfg, 178 htval, 179 hip, 180 hvip, 181 hviprio1, 182 hviprio2, 183 htinst, 184 hgatp, 185 hgeip, 186 hstateen0, 187 ) 188 189 val hypervisorCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from( 190 hypervisorCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator 191 ) 192 193 val hypervisorCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 194 hypervisorCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator 195 ) 196} 197 198class HstatusBundle extends CSRBundle { 199 200 val VSBE = RO(5).withReset(0.U) 201 val GVA = RW(6) 202 val SPV = VirtMode(7) 203 val SPVP = RW(8) 204 val HU = RW(9) 205 val VGEIN = HstatusVgeinField(17, 12, wNoFilter, rNoFilter).withReset(0.U) 206 val VTVM = RW(20).withReset(0.U) 207 val VTW = RW(21).withReset(0.U) 208 val VTSR = RW(22).withReset(0.U) 209 val VSXL = XLENField(33, 32).withReset(XLENField.XLEN64) 210 val HUPMM = EnvPMM(49, 48, wNoEffect).withReset(EnvPMM.Disable) // Ssnpm extension 211 212} 213 214object HstatusVgeinField extends CSREnum with WLRLApply { 215 override def isLegal(enumeration: CSREnumType): Bool = enumeration.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).withReset(0.U) 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 this.EX_DBLTRP.setRO().withReset(0.U) // double trap is not delegatable 269} 270 271class HidelegBundle extends InterruptBundle { 272 this.getALL.foreach(_.setRW().withReset(0.U)) 273 // default RW 274 this.SSI .setRO().withReset(0.U) 275 this.MSI .setRO().withReset(0.U) 276 this.STI .setRO().withReset(0.U) 277 this.MTI .setRO().withReset(0.U) 278 this.SEI .setRO().withReset(0.U) 279 this.MEI .setRO().withReset(0.U) 280 this.SGEI.setRO().withReset(0.U) 281 this.getLocal.foreach(_.setRO().withReset(0.U)) 282 this.LCOFI.setRW().withReset(0.U) 283} 284 285class HipToHvip extends Bundle { 286 val VSSIP = ValidIO(RW(0)) 287} 288 289class SipToHvip extends ToAliasIpLocalPart { 290 291} 292 293class HieToMie extends IeValidBundle { 294 this.getVS.foreach(_.bits.setRW()) 295 this.SGEIE.bits.setRW() 296} 297 298class HvictlBundle extends CSRBundle { 299 // Virtual Trap Interrupt control 300 val VTI = RW(30).withReset(0.U) 301 // WARL in AIA spec. 302 // RW, since we support max width of IID 303 val IID = RW(15 + HIIDWidth, 16).withReset(0.U) 304 // determines the interrupt’s presumed default priority order relative to a (virtual) supervisor external interrupt (SEI), major identity 9 305 // 0 = interrupt has higher default priority than an SEI 306 // 1 = interrupt has lower default priority than an SEI 307 // When hvictl.IID = 9, DPR is ignored. 308 // Todo: sort the interrupt specified by hvictl with DPR 309 val DPR = RW(9).withReset(0.U) 310 val IPRIOM = RW(8).withReset(0.U) 311 val IPRIO = RW(7, 0).withReset(0.U) 312} 313 314class Hviprio1Bundle extends CSRBundle { 315 val PrioSSI = RW(15, 8).withReset(0.U) 316 val PrioSTI = RW(31, 24).withReset(0.U) 317 val PrioCOI = RW(47, 40).withReset(0.U) 318 val Prio14 = RW(55, 48).withReset(0.U) 319 val Prio15 = RW(63, 56).withReset(0.U) 320} 321 322class Hviprio2Bundle extends FieldInitBundle 323 324class HgatpBundle extends CSRBundle { 325 val MODE = HgatpMode(63, 60, wNoFilter).withReset(HgatpMode.Bare) 326 // WARL in privileged spec. 327 // RW, since we support max width of VMID 328 val VMID = RW(44 - 1 + VMIDLEN, 44).withReset(0.U) 329 val PPN = RW(43, 0).withReset(0.U) 330} 331 332class HEnvCfg extends EnvCfg { 333 if (CSRConfig.EXT_SSTC) { 334 this.STCE.setRW().withReset(1.U) 335 } 336 this.PBMTE.setRW().withReset(0.U) 337 if (CSRConfig.EXT_DBLTRP) { 338 // software write envcfg to open ssdbltrp if need 339 // set 0 to pass ci 340 this.DTE.setRW().withReset(0.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}