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