1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.util.BitPat.bitPatToUInt 5import chisel3.util._ 6import freechips.rocketchip.rocket.CSRs 7import utility.{SignExt, ZeroExt} 8import xiangshan.backend.fu.NewCSR.CSRBundles._ 9import xiangshan.backend.fu.NewCSR.CSRDefines.{VirtMode, CSRROField => RO, CSRRWField => RW, CSRWARLField => WARL, CSRWLRLField => WLRL, _} 10import xiangshan.backend.fu.NewCSR.CSREvents._ 11import xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._ 12import xiangshan.backend.fu.NewCSR.CSRBundleImplicitCast._ 13import xiangshan.backend.fu.NewCSR.CSRConfig.PPNLength 14import xiangshan.backend.fu.NewCSR.ChiselRecordForField._ 15 16import scala.collection.immutable.SeqMap 17 18trait VirtualSupervisorLevel { self: NewCSR with SupervisorLevel with HypervisorLevel => 19 20 val vsstatus = Module( 21 new CSRModule("VSstatus", new SstatusBundle) 22 with SretEventSinkBundle 23 with MretEventSinkBundle 24 with MNretEventSinkBundle 25 with DretEventSinkBundle 26 with TrapEntryVSEventSinkBundle 27 with HasRobCommitBundle 28 with HasVirtualSupervisorEnvBundle 29 { 30 when ((robCommit.fsDirty || writeFCSR) && isVirtMode) { 31 assert(reg.FS =/= ContextStatus.Off, "The vsstatus.FS should not be Off when set dirty, please check decode") 32 reg.FS := ContextStatus.Dirty 33 } 34 35 when ((robCommit.vsDirty || writeVCSR) && isVirtMode) { 36 assert(reg.VS =/= ContextStatus.Off, "The vsstatus.VS should not be Off when set dirty, please check decode") 37 reg.VS := ContextStatus.Dirty 38 } 39 // when menvcfg or henvcfg.DTE close, vsstatus.SDT is read-only 40 val writeSDT = Wire(Bool()) 41 writeSDT := Mux(this.menvcfg.DTE && this.henvcfg.DTE, w.wdataFields.SDT.asBool, 0.U) 42 when (!(this.menvcfg.DTE && this.henvcfg.DTE)) { 43 regOut.SDT := false.B 44 } 45 // SDT and SIE is the same as mstatus 46 when (writeSDT && w.wen ) { 47 reg.SIE := false.B 48 } 49 50 } 51 ) 52 .setAddr(CSRs.vsstatus) 53 54 val vsie = Module(new CSRModule("VSie", new VSieBundle) 55 with HypervisorBundle 56 with HasIpIeBundle 57 { 58 val toMie = IO(new VSieToMie) 59 val toSie = IO(new VSieToSie) 60 61 val mieIsAlias = hideleg & mideleg 62 val sieIsAlias = hideleg & ~mideleg & mvien 63 val usingReg = ~hideleg & hvien 64 65 val originAliasIE = (mieIsAlias & mie) | (sieIsAlias & sie) 66 val shiftedIE = Cat(originAliasIE(63, InterruptNO.COI), 0.U(1.W), originAliasIE(InterruptNO.SGEI, InterruptNO.SSI)) 67 val shiftedUsingReg = Cat(usingReg(63, InterruptNO.COI), 0.U(1.W), usingReg(InterruptNO.SGEI, InterruptNO.SSI)) 68 69 regOut := 70 shiftedIE | 71 (shiftedUsingReg & reg) 72 73 bundle.getVS.map(_.lsb).foreach { vsNum => 74 // vsie.SSIE(1) map mie.VSSIE(1) 75 val sNum = vsNum - 1 76 val wtMie = toMie.getByNum(vsNum) 77 val wtSie = toSie.getByNum(vsNum) 78 val r = reg(sNum) 79 80 wtMie.specifyField( 81 _.valid := mieIsAlias(vsNum) && wtMie.bits.isRW.B && wen, 82 _.bits := mieIsAlias(vsNum) && wtMie.bits.isRW.B && wen &< wdata(sNum), 83 ) 84 85 wtSie.specifyField( 86 _.valid := sieIsAlias(vsNum) && wtSie.bits.isRW.B && wen, 87 _.bits := sieIsAlias(vsNum) && wtSie.bits.isRW.B && wen &< wdata(sNum), 88 ) 89 90 when (wen && usingReg(vsNum) && r.isRW.B) { 91 r := wdata(sNum) 92 }.otherwise { 93 r := r 94 } 95 } 96 97 bundle.getNonVS.map(_.lsb).foreach { num => 98 val wtMie = toMie.getByNum(num) 99 val wtSie = toSie.getByNum(num) 100 101 val r = reg(num) 102 103 wtMie.specifyField( 104 _.valid := mieIsAlias(num) && wtMie.bits.isRW.B && wen, 105 _.bits := mieIsAlias(num) && wtMie.bits.isRW.B && wen &< wdata(num), 106 ) 107 108 wtSie.specifyField( 109 _.valid := sieIsAlias(num) && wtSie.bits.isRW.B && wen, 110 _.bits := sieIsAlias(num) && wtSie.bits.isRW.B && wen &< wdata(num), 111 ) 112 113 when(wen && usingReg(num) && r.isRW.B) { 114 r := wdata(num) 115 }.otherwise { 116 r := r 117 } 118 } 119 120 regOut.getFields.foreach { field => 121 if (field.isHardWired) { 122 field := field.getHardWireValue 123 } 124 } 125 }).setAddr(CSRs.vsie) 126 127 val vstvec = Module(new CSRModule("VStvec", new XtvecBundle)) 128 .setAddr(CSRs.vstvec) 129 130 val vsscratch = Module(new CSRModule("VSscratch")) 131 .setAddr(CSRs.vsscratch) 132 133 val vsepc = Module( 134 new CSRModule("VSepc", new Epc) 135 with TrapEntryVSEventSinkBundle 136 ) 137 .setAddr(CSRs.vsepc) 138 139 val vscause = Module( 140 new CSRModule("VScause", new CauseBundle) 141 with TrapEntryVSEventSinkBundle 142 ) 143 .setAddr(CSRs.vscause) 144 145 // Todo: shrink the width of vstval to the maximum width Virtual Address 146 val vstval = Module( 147 new CSRModule("VStval", new XtvalBundle) 148 with TrapEntryVSEventSinkBundle 149 ) 150 .setAddr(CSRs.vstval) 151 152 val vsip = Module(new CSRModule("VSip", new VSipBundle) 153 with HypervisorBundle 154 with HasIpIeBundle 155 { 156 val toMip = IO(new VSipToMip).connectZeroNonRW 157 val toMvip = IO(new VSipToMvip).connectZeroNonRW 158 val toHvip = IO(new VSipToHvip).connectZeroNonRW 159 160 val originIP = mideleg & hideleg & mip | (~mideleg & hideleg & mvien & mvip) | (~hideleg & hvien & hvip) 161 val shiftedIP = Cat(originIP(63, InterruptNO.COI), 0.U(1.W), originIP(InterruptNO.SGEI, InterruptNO.SSI)) 162 163 regOut := shiftedIP 164 regOut.getM.foreach(_ := 0.U) 165 regOut.getVS.foreach(_ := 0.U) 166 regOut.SGEIP := 0.U 167 168 toHvip.VSSIP.valid := wen && hideleg.VSSI 169 toHvip.VSSIP.bits := wdata.SSIP 170 171 wdata.getLocal lazyZip 172 (toMip.getLocal lazyZip toMvip.getLocal lazyZip toHvip.getLocal) lazyZip 173 (mideleg.getLocal lazyZip hideleg.getLocal lazyZip mvien.getLocal lazyZip hvien.getLocal) foreach { 174 case (wLCIP, (toMipLCIP, toMvipLCIP, toHvipLCIP), (midelegBit, hidelegBit, mvienBit, hvienBit)) => 175 toMipLCIP .valid := wen && hidelegBit && midelegBit 176 toMvipLCIP.valid := wen && hidelegBit && !midelegBit && mvienBit 177 toHvipLCIP.valid := wen && !hidelegBit && hvienBit 178 toMipLCIP .bits := wLCIP 179 toMvipLCIP.bits := wLCIP 180 toHvipLCIP.bits := wLCIP 181 } 182 183 regOut.getFields.foreach { field => 184 if (field.isHardWired) { 185 field := field.getHardWireValue 186 } 187 } 188 }).setAddr(CSRs.vsip) 189 190 val vstimecmp = Module(new CSRModule("VStimecmp", new CSRBundle { 191 val vstimecmp = RW(63, 0).withReset(bitPatToUInt(BitPat.Y(64))) 192 })) 193 .setAddr(CSRs.vstimecmp) 194 195 val vsatp = Module(new CSRModule("VSatp", new SatpBundle) with VirtualSupervisorBundle { 196 val ppnMask = Fill(PPNLength, 1.U(1.W)) 197 val ppnMaskHgatpIsBare = ZeroExt(ppnMask.take(PAddrBits - PageOffsetWidth), PPNLength) 198 val ppnMaskHgatpIsSv39x4 = ZeroExt(ppnMask.take(39 + 2 - PageOffsetWidth), PPNLength) 199 val ppnMaskHgatpIsSv48x4 = ZeroExt(ppnMask.take(48 + 2 - PageOffsetWidth), PPNLength) 200 201 val effectivePPNMask = Mux1H(Seq( 202 (hgatp.MODE === HgatpMode.Bare) -> ppnMaskHgatpIsBare, 203 (hgatp.MODE === HgatpMode.Sv39x4) -> ppnMaskHgatpIsSv39x4, 204 (hgatp.MODE === HgatpMode.Sv48x4) -> ppnMaskHgatpIsSv48x4, 205 )) 206 // Ref: 13.2.18. Virtual Supervisor Address Translation and Protection Register (vsatp) 207 // When V=0, a write to vsatp with an unsupported MODE value is either ignored as it is for satp, or the 208 // fields of vsatp are treated as WARL in the normal way. 209 // However, when V=1, a write to satp with an unsupported MODE value is ignored and no write to vsatp is effected. 210 // if satp is written with an unsupported MODE, the entire write has no effect; no fields in satp are modified. 211 // 212 // We treat all circumstances as if V=1. That is if vsatp is written with an unsupported MODE, 213 // the entire write has no effect; no fields in satp are modified. 214 when(wen && wdata.MODE.isLegal) { 215 reg := wdata 216 reg.PPN := wdata.PPN & effectivePPNMask 217 }.elsewhen(wen && !v && !wdata.MODE.isLegal) { 218 reg.PPN := wdata.PPN & effectivePPNMask 219 reg.ASID := wdata.ASID 220 }.otherwise { 221 reg := reg 222 } 223 }).setAddr(CSRs.vsatp) 224 225 val virtualSupervisorCSRMods = Seq( 226 vsstatus, 227 vsie, 228 vstvec, 229 vsscratch, 230 vsepc, 231 vscause, 232 vstval, 233 vsip, 234 vstimecmp, 235 vsatp, 236 ) 237 238 virtualSupervisorCSRMods.foreach(mod => 239 require(mod.addr > 0, s"The address of ${mod.modName} has not been set, you can use setAddr(CSRAddr) to set it.")) 240 241 val virtualSupervisorCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from( 242 virtualSupervisorCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))) 243 ) 244 245 val virtualSupervisorCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 246 virtualSupervisorCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)) 247 ) 248 249 import freechips.rocketchip.rocket.CSRs 250 251 val sMapVS = SeqMap( 252 CSRs.sstatus -> CSRs.vsstatus, 253 CSRs.sie -> CSRs.vsie, 254 CSRs.stvec -> CSRs.vstvec, 255 CSRs.sscratch -> CSRs.vsscratch, 256 CSRs.sepc -> CSRs.vsepc, 257 CSRs.scause -> CSRs.vscause, 258 CSRs.stval -> CSRs.vstval, 259 CSRs.sip -> CSRs.vsip, 260 CSRs.stimecmp -> CSRs.vstimecmp, 261 CSRs.siselect -> CSRs.vsiselect, 262 CSRs.sireg -> CSRs.vsireg, 263 CSRs.stopei -> CSRs.vstopei, 264 CSRs.satp -> CSRs.vsatp, 265 CSRs.stopi -> CSRs.vstopi, 266 ) 267 268 val vsMapS: SeqMap[Int, Int] = SeqMap.from(sMapVS.map(x => (x._2 -> x._1))) 269} 270 271class VSipBundle extends InterruptPendingBundle { 272 // All pending bits in vsip are aliases of mip/mvip/hvip or read-only 0 273 this.getM.foreach(_.setHardWired(0.U)) 274 this.getVS.foreach(_.setHardWired(0.U)) 275 this.SGEIP.setHardWired(0.U) 276} 277 278class VSieBundle extends InterruptEnableBundle { 279 this.getLocal.foreach(_.setRW().withReset(0.U)) 280 this.getM .foreach(_.setHardWired(0.U)) 281 this.getVS.foreach(_.setHardWired(0.U)) 282 this.SGEIE.setHardWired(0.U) 283} 284 285class VSipToMvip extends IpValidBundle { 286 this.getLocal.foreach(_.bits.setRW()) 287} 288 289class VSipToHvip extends IpValidBundle { 290 this.VSSIP.bits.setRW() 291 this.getLocal.foreach(_.bits.setRW()) 292} 293 294class VSieToMie extends IeValidBundle { 295 this.getVS.foreach(_.bits.setRW()) 296 this.getLocal.foreach(_.bits.setRW()) 297} 298 299class VSieToSie extends IeValidBundle { 300 this.getVS.foreach(_.bits.setRW()) 301 this.getLocal.foreach(_.bits.setRW()) 302} 303 304class VSipToHip extends Bundle { 305 val SSIP = ValidIO(RW(0)) 306 val STIP = ValidIO(RW(0)) 307 val SEIP = ValidIO(RW(0)) 308} 309 310trait VirtualSupervisorBundle { self: CSRModule[_] => 311 val v = IO(Input(Bool())) 312 val hgatp = IO(Input(new HgatpBundle)) 313} 314 315trait HasVirtualSupervisorEnvBundle { self: CSRModule[_] => 316 val menvcfg = IO(Input(new MEnvCfg)) 317 val henvcfg = IO(Input(new HEnvCfg)) 318} 319