1039cdc35SXuan Hupackage xiangshan.backend.fu.NewCSR 2039cdc35SXuan Hu 3039cdc35SXuan Huimport chisel3._ 40b4c00ffSXuan Huimport chisel3.util.BitPat.bitPatToUInt 5039cdc35SXuan Huimport chisel3.util._ 64d2be3d2SsinceforYyimport freechips.rocketchip.rocket.CSRs 79c0fd28fSXuan Huimport utility.{SignExt, ZeroExt} 8039cdc35SXuan Huimport xiangshan.backend.fu.NewCSR.CSRBundles._ 99c0fd28fSXuan Huimport xiangshan.backend.fu.NewCSR.CSRDefines.{VirtMode, CSRROField => RO, CSRRWField => RW, CSRWARLField => WARL, CSRWLRLField => WLRL, _} 10e50a46eaSGuanghui Chengimport xiangshan.backend.fu.NewCSR.CSREvents._ 111d192ad8SXuan Huimport xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._ 121d192ad8SXuan Huimport xiangshan.backend.fu.NewCSR.CSRBundleImplicitCast._ 139c0fd28fSXuan Huimport xiangshan.backend.fu.NewCSR.CSRConfig.PPNLength 141d192ad8SXuan Huimport xiangshan.backend.fu.NewCSR.ChiselRecordForField._ 15039cdc35SXuan Hu 16039cdc35SXuan Huimport scala.collection.immutable.SeqMap 17039cdc35SXuan Hu 18760398d7SXuan Hutrait VirtualSupervisorLevel { self: NewCSR with SupervisorLevel with HypervisorLevel => 19039cdc35SXuan Hu 20237d4cfdSXuan Hu val vsstatus = Module( 21237d4cfdSXuan Hu new CSRModule("VSstatus", new SstatusBundle) 22237d4cfdSXuan Hu with SretEventSinkBundle 23*eca6983fSZehao Liu with SretEventSDTSinkBundle 246808b803SZehao Liu with MretEventSinkBundle 256808b803SZehao Liu with MNretEventSinkBundle 26e50a46eaSGuanghui Cheng with DretEventSinkBundle 27237d4cfdSXuan Hu with TrapEntryVSEventSinkBundle 284d2be3d2SsinceforYy with HasRobCommitBundle 296808b803SZehao Liu with HasVirtualSupervisorEnvBundle 304d2be3d2SsinceforYy { 31a0231889SXuan Hu when ((robCommit.fsDirty || writeFCSR) && isVirtMode) { 324d2be3d2SsinceforYy assert(reg.FS =/= ContextStatus.Off, "The vsstatus.FS should not be Off when set dirty, please check decode") 334d2be3d2SsinceforYy reg.FS := ContextStatus.Dirty 344d2be3d2SsinceforYy } 354d2be3d2SsinceforYy 3687e82eddSXiaokun-Pei when ((robCommit.vsDirty || writeVCSR) && isVirtMode) { 374d2be3d2SsinceforYy assert(reg.VS =/= ContextStatus.Off, "The vsstatus.VS should not be Off when set dirty, please check decode") 384d2be3d2SsinceforYy reg.VS := ContextStatus.Dirty 394d2be3d2SsinceforYy } 406808b803SZehao Liu // when menvcfg or henvcfg.DTE close, vsstatus.SDT is read-only 416808b803SZehao Liu val writeSDT = Wire(Bool()) 426808b803SZehao Liu writeSDT := Mux(this.menvcfg.DTE && this.henvcfg.DTE, w.wdataFields.SDT.asBool, 0.U) 436808b803SZehao Liu when (!(this.menvcfg.DTE && this.henvcfg.DTE)) { 446808b803SZehao Liu regOut.SDT := false.B 456808b803SZehao Liu } 466808b803SZehao Liu // SDT and SIE is the same as mstatus 476808b803SZehao Liu when (writeSDT && w.wen ) { 486808b803SZehao Liu reg.SIE := false.B 496808b803SZehao Liu } 506808b803SZehao Liu 514d2be3d2SsinceforYy } 52237d4cfdSXuan Hu ) 534d2be3d2SsinceforYy .setAddr(CSRs.vsstatus) 54039cdc35SXuan Hu 551d192ad8SXuan Hu val vsie = Module(new CSRModule("VSie", new VSieBundle) 561d192ad8SXuan Hu with HypervisorBundle 571d192ad8SXuan Hu with HasIpIeBundle 581d192ad8SXuan Hu { 591d192ad8SXuan Hu val toMie = IO(new VSieToMie) 601d192ad8SXuan Hu val toSie = IO(new VSieToSie) 61039cdc35SXuan Hu 621d192ad8SXuan Hu val mieIsAlias = hideleg & mideleg 631d192ad8SXuan Hu val sieIsAlias = hideleg & ~mideleg & mvien 641d192ad8SXuan Hu val usingReg = ~hideleg & hvien 651d192ad8SXuan Hu 668e6494c1SXuan Hu val originAliasIE = (mieIsAlias & mie) | (sieIsAlias & sie) 678e6494c1SXuan Hu val shiftedIE = Cat(originAliasIE(63, InterruptNO.COI), 0.U(1.W), originAliasIE(InterruptNO.SGEI, InterruptNO.SSI)) 688e6494c1SXuan Hu val shiftedUsingReg = Cat(usingReg(63, InterruptNO.COI), 0.U(1.W), usingReg(InterruptNO.SGEI, InterruptNO.SSI)) 698e6494c1SXuan Hu 701d192ad8SXuan Hu regOut := 718e6494c1SXuan Hu shiftedIE | 728e6494c1SXuan Hu (shiftedUsingReg & reg) 731d192ad8SXuan Hu 74a2eeddbfSXuan Hu bundle.getVS.map(_.lsb).foreach { vsNum => 75a2eeddbfSXuan Hu // vsie.SSIE(1) map mie.VSSIE(1) 76a2eeddbfSXuan Hu val sNum = vsNum - 1 77a2eeddbfSXuan Hu val wtMie = toMie.getByNum(vsNum) 78a2eeddbfSXuan Hu val wtSie = toSie.getByNum(vsNum) 79a2eeddbfSXuan Hu val r = reg(sNum) 80a2eeddbfSXuan Hu 81a2eeddbfSXuan Hu wtMie.specifyField( 82a2eeddbfSXuan Hu _.valid := mieIsAlias(vsNum) && wtMie.bits.isRW.B && wen, 83a2eeddbfSXuan Hu _.bits := mieIsAlias(vsNum) && wtMie.bits.isRW.B && wen &< wdata(sNum), 84a2eeddbfSXuan Hu ) 85a2eeddbfSXuan Hu 86a2eeddbfSXuan Hu wtSie.specifyField( 87a2eeddbfSXuan Hu _.valid := sieIsAlias(vsNum) && wtSie.bits.isRW.B && wen, 88a2eeddbfSXuan Hu _.bits := sieIsAlias(vsNum) && wtSie.bits.isRW.B && wen &< wdata(sNum), 89a2eeddbfSXuan Hu ) 90a2eeddbfSXuan Hu 91a2eeddbfSXuan Hu when (wen && usingReg(vsNum) && r.isRW.B) { 92a2eeddbfSXuan Hu r := wdata(sNum) 93a2eeddbfSXuan Hu }.otherwise { 94a2eeddbfSXuan Hu r := r 95a2eeddbfSXuan Hu } 96a2eeddbfSXuan Hu } 97a2eeddbfSXuan Hu 98a2eeddbfSXuan Hu bundle.getNonVS.map(_.lsb).foreach { num => 991d192ad8SXuan Hu val wtMie = toMie.getByNum(num) 1001d192ad8SXuan Hu val wtSie = toSie.getByNum(num) 101a2eeddbfSXuan Hu 1021d192ad8SXuan Hu val r = reg(num) 1031d192ad8SXuan Hu 1041d192ad8SXuan Hu wtMie.specifyField( 1051d192ad8SXuan Hu _.valid := mieIsAlias(num) && wtMie.bits.isRW.B && wen, 1061d192ad8SXuan Hu _.bits := mieIsAlias(num) && wtMie.bits.isRW.B && wen &< wdata(num), 1071d192ad8SXuan Hu ) 1081d192ad8SXuan Hu 1091d192ad8SXuan Hu wtSie.specifyField( 1101d192ad8SXuan Hu _.valid := sieIsAlias(num) && wtSie.bits.isRW.B && wen, 1111d192ad8SXuan Hu _.bits := sieIsAlias(num) && wtSie.bits.isRW.B && wen &< wdata(num), 1121d192ad8SXuan Hu ) 1131d192ad8SXuan Hu 1141d192ad8SXuan Hu when(wen && usingReg(num) && r.isRW.B) { 1151d192ad8SXuan Hu r := wdata(num) 1161d192ad8SXuan Hu }.otherwise { 1171d192ad8SXuan Hu r := r 1181d192ad8SXuan Hu } 1191d192ad8SXuan Hu } 120946f0090SXuan Hu 121946f0090SXuan Hu regOut.getFields.foreach { field => 122946f0090SXuan Hu if (field.isHardWired) { 123946f0090SXuan Hu field := field.getHardWireValue 124946f0090SXuan Hu } 125946f0090SXuan Hu } 1264d2be3d2SsinceforYy }).setAddr(CSRs.vsie) 127039cdc35SXuan Hu 128039cdc35SXuan Hu val vstvec = Module(new CSRModule("VStvec", new XtvecBundle)) 1294d2be3d2SsinceforYy .setAddr(CSRs.vstvec) 130039cdc35SXuan Hu 131039cdc35SXuan Hu val vsscratch = Module(new CSRModule("VSscratch")) 1324d2be3d2SsinceforYy .setAddr(CSRs.vsscratch) 133039cdc35SXuan Hu 134237d4cfdSXuan Hu val vsepc = Module( 135237d4cfdSXuan Hu new CSRModule("VSepc", new Epc) 136237d4cfdSXuan Hu with TrapEntryVSEventSinkBundle 137237d4cfdSXuan Hu ) 1384d2be3d2SsinceforYy .setAddr(CSRs.vsepc) 139039cdc35SXuan Hu 140237d4cfdSXuan Hu val vscause = Module( 141237d4cfdSXuan Hu new CSRModule("VScause", new CauseBundle) 142237d4cfdSXuan Hu with TrapEntryVSEventSinkBundle 143237d4cfdSXuan Hu ) 1444d2be3d2SsinceforYy .setAddr(CSRs.vscause) 145039cdc35SXuan Hu 146039cdc35SXuan Hu // Todo: shrink the width of vstval to the maximum width Virtual Address 147237d4cfdSXuan Hu val vstval = Module( 148499d09b3SsinceforYy new CSRModule("VStval", new XtvalBundle) 149237d4cfdSXuan Hu with TrapEntryVSEventSinkBundle 150237d4cfdSXuan Hu ) 1514d2be3d2SsinceforYy .setAddr(CSRs.vstval) 152039cdc35SXuan Hu 1531d192ad8SXuan Hu val vsip = Module(new CSRModule("VSip", new VSipBundle) 1541d192ad8SXuan Hu with HypervisorBundle 1551d192ad8SXuan Hu with HasIpIeBundle 1561d192ad8SXuan Hu { 1571d192ad8SXuan Hu val toMip = IO(new VSipToMip).connectZeroNonRW 1581d192ad8SXuan Hu val toMvip = IO(new VSipToMvip).connectZeroNonRW 1591d192ad8SXuan Hu val toHvip = IO(new VSipToHvip).connectZeroNonRW 160039cdc35SXuan Hu 1611d192ad8SXuan Hu val originIP = mideleg & hideleg & mip | (~mideleg & hideleg & mvien & mvip) | (~hideleg & hvien & hvip) 1621d192ad8SXuan Hu val shiftedIP = Cat(originIP(63, InterruptNO.COI), 0.U(1.W), originIP(InterruptNO.SGEI, InterruptNO.SSI)) 1631d192ad8SXuan Hu 1641d192ad8SXuan Hu regOut := shiftedIP 1651d192ad8SXuan Hu regOut.getM.foreach(_ := 0.U) 1668e6494c1SXuan Hu regOut.getVS.foreach(_ := 0.U) 1671d192ad8SXuan Hu regOut.SGEIP := 0.U 1681d192ad8SXuan Hu 1691d192ad8SXuan Hu toHvip.VSSIP.valid := wen && hideleg.VSSI 1701d192ad8SXuan Hu toHvip.VSSIP.bits := wdata.SSIP 1711d192ad8SXuan Hu 1721d192ad8SXuan Hu wdata.getLocal lazyZip 1731d192ad8SXuan Hu (toMip.getLocal lazyZip toMvip.getLocal lazyZip toHvip.getLocal) lazyZip 17460b1c081SXuan Hu (mideleg.getLocal lazyZip hideleg.getLocal lazyZip mvien.getLocal lazyZip hvien.getLocal) foreach { 17560b1c081SXuan Hu case (wLCIP, (toMipLCIP, toMvipLCIP, toHvipLCIP), (midelegBit, hidelegBit, mvienBit, hvienBit)) => 17660b1c081SXuan Hu toMipLCIP .valid := wen && hidelegBit && midelegBit 17760b1c081SXuan Hu toMvipLCIP.valid := wen && hidelegBit && !midelegBit && mvienBit 17860b1c081SXuan Hu toHvipLCIP.valid := wen && !hidelegBit && hvienBit 1791d192ad8SXuan Hu toMipLCIP .bits := wLCIP 1801d192ad8SXuan Hu toMvipLCIP.bits := wLCIP 1811d192ad8SXuan Hu toHvipLCIP.bits := wLCIP 1821d192ad8SXuan Hu } 183946f0090SXuan Hu 184946f0090SXuan Hu regOut.getFields.foreach { field => 185946f0090SXuan Hu if (field.isHardWired) { 186946f0090SXuan Hu field := field.getHardWireValue 187946f0090SXuan Hu } 188946f0090SXuan Hu } 1894d2be3d2SsinceforYy }).setAddr(CSRs.vsip) 190039cdc35SXuan Hu 1910b4c00ffSXuan Hu val vstimecmp = Module(new CSRModule("VStimecmp", new CSRBundle { 1920b4c00ffSXuan Hu val vstimecmp = RW(63, 0).withReset(bitPatToUInt(BitPat.Y(64))) 1930b4c00ffSXuan Hu })) 1944d2be3d2SsinceforYy .setAddr(CSRs.vstimecmp) 195760398d7SXuan Hu 196f56c6de4SsinceforYy val vsatp = Module(new CSRModule("VSatp", new SatpBundle) with VirtualSupervisorBundle { 1979c0fd28fSXuan Hu val ppnMask = Fill(PPNLength, 1.U(1.W)) 1989c0fd28fSXuan Hu val ppnMaskHgatpIsBare = ZeroExt(ppnMask.take(PAddrBits - PageOffsetWidth), PPNLength) 1999c0fd28fSXuan Hu val ppnMaskHgatpIsSv39x4 = ZeroExt(ppnMask.take(39 + 2 - PageOffsetWidth), PPNLength) 2009c0fd28fSXuan Hu val ppnMaskHgatpIsSv48x4 = ZeroExt(ppnMask.take(48 + 2 - PageOffsetWidth), PPNLength) 2019c0fd28fSXuan Hu 2029c0fd28fSXuan Hu val effectivePPNMask = Mux1H(Seq( 2039c0fd28fSXuan Hu (hgatp.MODE === HgatpMode.Bare) -> ppnMaskHgatpIsBare, 2049c0fd28fSXuan Hu (hgatp.MODE === HgatpMode.Sv39x4) -> ppnMaskHgatpIsSv39x4, 2059c0fd28fSXuan Hu (hgatp.MODE === HgatpMode.Sv48x4) -> ppnMaskHgatpIsSv48x4, 2069c0fd28fSXuan Hu )) 207039cdc35SXuan Hu // Ref: 13.2.18. Virtual Supervisor Address Translation and Protection Register (vsatp) 208039cdc35SXuan Hu // When V=0, a write to vsatp with an unsupported MODE value is either ignored as it is for satp, or the 209039cdc35SXuan Hu // fields of vsatp are treated as WARL in the normal way. 210039cdc35SXuan Hu // However, when V=1, a write to satp with an unsupported MODE value is ignored and no write to vsatp is effected. 211039cdc35SXuan Hu // if satp is written with an unsupported MODE, the entire write has no effect; no fields in satp are modified. 212039cdc35SXuan Hu // 213f9913d9bSXuan Hu // We treat all circumstances as if V=1. That is if vsatp is written with an unsupported MODE, 214039cdc35SXuan Hu // the entire write has no effect; no fields in satp are modified. 215f56c6de4SsinceforYy when(wen && wdata.MODE.isLegal) { 216f9913d9bSXuan Hu reg := wdata 2179c0fd28fSXuan Hu reg.PPN := wdata.PPN & effectivePPNMask 218f56c6de4SsinceforYy }.elsewhen(wen && !v && !wdata.MODE.isLegal) { 2199c0fd28fSXuan Hu reg.PPN := wdata.PPN & effectivePPNMask 220f56c6de4SsinceforYy reg.ASID := wdata.ASID 221f9913d9bSXuan Hu }.otherwise { 222f9913d9bSXuan Hu reg := reg 223039cdc35SXuan Hu } 2244d2be3d2SsinceforYy }).setAddr(CSRs.vsatp) 225039cdc35SXuan Hu 226039cdc35SXuan Hu val virtualSupervisorCSRMods = Seq( 227039cdc35SXuan Hu vsstatus, 228039cdc35SXuan Hu vsie, 229039cdc35SXuan Hu vstvec, 230039cdc35SXuan Hu vsscratch, 231039cdc35SXuan Hu vsepc, 232039cdc35SXuan Hu vscause, 233039cdc35SXuan Hu vstval, 234039cdc35SXuan Hu vsip, 235760398d7SXuan Hu vstimecmp, 236039cdc35SXuan Hu vsatp, 237039cdc35SXuan Hu ) 238039cdc35SXuan Hu 239039cdc35SXuan Hu virtualSupervisorCSRMods.foreach(mod => 240039cdc35SXuan Hu require(mod.addr > 0, s"The address of ${mod.modName} has not been set, you can use setAddr(CSRAddr) to set it.")) 241039cdc35SXuan Hu 24294895e77SXuan Hu val virtualSupervisorCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from( 2438aa89407SXuan Hu virtualSupervisorCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))) 244039cdc35SXuan Hu ) 245e877d8bfSXuan Hu 246e877d8bfSXuan Hu val virtualSupervisorCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 247e877d8bfSXuan Hu virtualSupervisorCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)) 248e877d8bfSXuan Hu ) 249760398d7SXuan Hu 250760398d7SXuan Hu import freechips.rocketchip.rocket.CSRs 251760398d7SXuan Hu 252760398d7SXuan Hu val sMapVS = SeqMap( 253760398d7SXuan Hu CSRs.sstatus -> CSRs.vsstatus, 254760398d7SXuan Hu CSRs.sie -> CSRs.vsie, 255760398d7SXuan Hu CSRs.stvec -> CSRs.vstvec, 256760398d7SXuan Hu CSRs.sscratch -> CSRs.vsscratch, 257760398d7SXuan Hu CSRs.sepc -> CSRs.vsepc, 258760398d7SXuan Hu CSRs.scause -> CSRs.vscause, 259760398d7SXuan Hu CSRs.stval -> CSRs.vstval, 260760398d7SXuan Hu CSRs.sip -> CSRs.vsip, 261760398d7SXuan Hu CSRs.stimecmp -> CSRs.vstimecmp, 262760398d7SXuan Hu CSRs.siselect -> CSRs.vsiselect, 263760398d7SXuan Hu CSRs.sireg -> CSRs.vsireg, 264760398d7SXuan Hu CSRs.stopei -> CSRs.vstopei, 265760398d7SXuan Hu CSRs.satp -> CSRs.vsatp, 266760398d7SXuan Hu CSRs.stopi -> CSRs.vstopi, 267760398d7SXuan Hu ) 268760398d7SXuan Hu 269760398d7SXuan Hu val vsMapS: SeqMap[Int, Int] = SeqMap.from(sMapVS.map(x => (x._2 -> x._1))) 270039cdc35SXuan Hu} 271039cdc35SXuan Hu 2721d192ad8SXuan Huclass VSipBundle extends InterruptPendingBundle { 2731d192ad8SXuan Hu // All pending bits in vsip are aliases of mip/mvip/hvip or read-only 0 274946f0090SXuan Hu this.getM.foreach(_.setHardWired(0.U)) 275946f0090SXuan Hu this.getVS.foreach(_.setHardWired(0.U)) 276946f0090SXuan Hu this.SGEIP.setHardWired(0.U) 277039cdc35SXuan Hu} 278039cdc35SXuan Hu 2791d192ad8SXuan Huclass VSieBundle extends InterruptEnableBundle { 280499d09b3SsinceforYy this.getLocal.foreach(_.setRW().withReset(0.U)) 281946f0090SXuan Hu this.getM .foreach(_.setHardWired(0.U)) 282946f0090SXuan Hu this.getVS.foreach(_.setHardWired(0.U)) 283946f0090SXuan Hu this.SGEIE.setHardWired(0.U) 284039cdc35SXuan Hu} 285039cdc35SXuan Hu 2861d192ad8SXuan Huclass VSipToMvip extends IpValidBundle { 2871d192ad8SXuan Hu this.getLocal.foreach(_.bits.setRW()) 2881d192ad8SXuan Hu} 2891d192ad8SXuan Hu 2901d192ad8SXuan Huclass VSipToHvip extends IpValidBundle { 2911d192ad8SXuan Hu this.VSSIP.bits.setRW() 2921d192ad8SXuan Hu this.getLocal.foreach(_.bits.setRW()) 2931d192ad8SXuan Hu} 2941d192ad8SXuan Hu 2951d192ad8SXuan Huclass VSieToMie extends IeValidBundle { 2961d192ad8SXuan Hu this.getVS.foreach(_.bits.setRW()) 2971d192ad8SXuan Hu this.getLocal.foreach(_.bits.setRW()) 2981d192ad8SXuan Hu} 2991d192ad8SXuan Hu 3001d192ad8SXuan Huclass VSieToSie extends IeValidBundle { 3011d192ad8SXuan Hu this.getVS.foreach(_.bits.setRW()) 3021d192ad8SXuan Hu this.getLocal.foreach(_.bits.setRW()) 303039cdc35SXuan Hu} 304039cdc35SXuan Hu 305039cdc35SXuan Huclass VSipToHip extends Bundle { 306039cdc35SXuan Hu val SSIP = ValidIO(RW(0)) 307039cdc35SXuan Hu val STIP = ValidIO(RW(0)) 308039cdc35SXuan Hu val SEIP = ValidIO(RW(0)) 309039cdc35SXuan Hu} 310f56c6de4SsinceforYy 311f56c6de4SsinceforYytrait VirtualSupervisorBundle { self: CSRModule[_] => 312f56c6de4SsinceforYy val v = IO(Input(Bool())) 3139c0fd28fSXuan Hu val hgatp = IO(Input(new HgatpBundle)) 314f56c6de4SsinceforYy} 3156808b803SZehao Liu 3166808b803SZehao Liutrait HasVirtualSupervisorEnvBundle { self: CSRModule[_] => 3176808b803SZehao Liu val menvcfg = IO(Input(new MEnvCfg)) 3186808b803SZehao Liu val henvcfg = IO(Input(new HEnvCfg)) 3196808b803SZehao Liu} 320