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