xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/VirtualSupervisorLevel.scala (revision eca6983f19d9c20aa907987dff616649c3d204a2)
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