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