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