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