xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSREvents/MNretEvent.scala (revision 3088616cbf0793407bb68460b2db89b7de80c12a)
1package xiangshan.backend.fu.NewCSR.CSREvents
2
3import chisel3._
4import chisel3.util._
5import org.chipsalliance.cde.config.Parameters
6import utility.{SignExt, ZeroExt}
7import xiangshan.ExceptionNO
8import xiangshan.ExceptionNO._
9import xiangshan.backend.fu.NewCSR.CSRBundles.{CauseBundle, OneFieldBundle, PrivState}
10import xiangshan.backend.fu.NewCSR.CSRConfig.{VaddrMaxWidth, XLEN}
11import xiangshan.backend.fu.NewCSR.CSRDefines.{HgatpMode, PrivMode, SatpMode, VirtMode}
12import xiangshan.backend.fu.NewCSR._
13import xiangshan.AddrTransType
14
15
16class MNretEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase {
17  val mnstatus  = ValidIO((new MnstatusBundle).addInEvent(_.MNPP, _.MNPV, _.NMIE))
18  val mstatus   = ValidIO((new MstatusBundle).addInEvent(_.MPRV))
19  val targetPc  = ValidIO(new TargetPCBundle)
20
21  override def getBundleByName(name: String): ValidIO[CSRBundle] = {
22    name match {
23      case "mnstatus"  => this.mnstatus
24      case "mstatus"   => this.mstatus
25    }
26  }
27}
28
29class MNretEventInput extends Bundle {
30  val mnstatus = Input(new MnstatusBundle)
31  val mstatus  = Input(new MstatusBundle)
32  val mnepc    = Input(new Epc())
33  val satp     = Input(new SatpBundle)
34  val vsatp    = Input(new SatpBundle)
35  val hgatp    = Input(new HgatpBundle)
36}
37
38class MNretEventModule(implicit p: Parameters) extends Module with CSREventBase {
39  val in = IO(new MNretEventInput)
40  val out = IO(new MNretEventOutput)
41
42  private val satp = in.satp
43  private val vsatp = in.vsatp
44  private val hgatp = in.hgatp
45  private val nextPrivState = out.privState.bits
46
47  private val instrAddrTransType = AddrTransType(
48    bare = nextPrivState.isModeM ||
49           (!nextPrivState.isVirtual && satp.MODE === SatpMode.Bare) ||
50           (nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Bare),
51    sv39 = !nextPrivState.isModeM && !nextPrivState.isVirtual && satp.MODE === SatpMode.Sv39 ||
52           nextPrivState.isVirtual && vsatp.MODE === SatpMode.Sv39,
53    sv48 = !nextPrivState.isModeM && !nextPrivState.isVirtual && satp.MODE === SatpMode.Sv48 ||
54           nextPrivState.isVirtual && vsatp.MODE === SatpMode.Sv48,
55    sv39x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv39x4,
56    sv48x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv48x4
57  )
58
59  out := DontCare
60
61  out.privState.valid := valid
62  out.mnstatus .valid := valid
63  out.targetPc .valid := valid
64
65  out.privState.bits.PRVM     := in.mnstatus.MNPP
66  out.privState.bits.V        := Mux(in.mnstatus.MNPP === PrivMode.M, VirtMode.Off.asUInt, in.mnstatus.MNPV.asUInt)
67  out.mnstatus.bits.MNPP      := PrivMode.U
68  out.mnstatus.bits.MNPV      := VirtMode.Off.asUInt
69  out.mnstatus.bits.NMIE      := 1.U
70  out.mstatus.bits.MPRV       := Mux(in.mnstatus.MNPP =/= PrivMode.M, 0.U, in.mstatus.MPRV.asUInt)
71  out.targetPc.bits.pc        := in.mnepc.asUInt
72  out.targetPc.bits.raiseIPF  := instrAddrTransType.checkPageFault(in.mnepc.asUInt)
73  out.targetPc.bits.raiseIAF  := instrAddrTransType.checkAccessFault(in.mnepc.asUInt)
74  out.targetPc.bits.raiseIGPF := instrAddrTransType.checkGuestPageFault(in.mnepc.asUInt)
75}
76
77trait MNretEventSinkBundle { self: CSRModule[_] =>
78  val retFromMN = IO(Flipped(new MNretEventOutput))
79
80  private val updateBundle: ValidIO[CSRBundle] = retFromMN.getBundleByName(self.modName.toLowerCase())
81
82  (reg.asInstanceOf[CSRBundle].getFields zip updateBundle.bits.getFields).foreach { case (sink, source) =>
83    if (updateBundle.bits.eventFields.contains(source)) {
84      when(updateBundle.valid) {
85        sink := source
86      }
87    }
88  }
89
90}