Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ object CSRBundles {
val STCE = RO( 63) .withReset(0.U) // Sstc Enable
val PBMTE = RO( 62) .withReset(0.U) // Svpbmt Enable
val ADUE = RO( 61) .withReset(0.U) // Svadu extension Enable
val DTE = RO( 59) .withReset(0.U) // Ssdbltrp extension Enable
val PMM = RO(33, 32) .withReset(0.U) // Smnpm extension
val CBZE = RW( 7) .withReset(1.U) // Zicboz extension
val CBCFE = RW( 6) .withReset(1.U) // Zicbom extension
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ class TrapEntryEventInput(implicit val p: Parameters) extends Bundle with HasXSP
val isFetchMalAddr = Input(Bool())
val isFetchBkpt = Input(Bool())
val trapIsForVSnonLeafPTE = Input(Bool())
val hasDTExcp = Input(Bool())

// always current privilege
val iMode = Input(new PrivState())
Expand All @@ -136,6 +137,9 @@ class TrapEntryEventInput(implicit val p: Parameters) extends Bundle with HasXSP
val hstatus = Input(new HstatusBundle)
val sstatus = Input(new SstatusBundle)
val vsstatus = Input(new SstatusBundle)
// envcfg
val menvcfg = Input(new MEnvCfg)
val henvcfg = Input(new HEnvCfg)

val pcFromXtvec = Input(UInt(XLEN.W))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import xiangshan.AddrTransType

class MNretEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase {
val mnstatus = ValidIO((new MnstatusBundle).addInEvent(_.MNPP, _.MNPV, _.NMIE))
val mstatus = ValidIO((new MstatusBundle).addInEvent(_.MPRV))
val mstatus = ValidIO((new MstatusBundle).addInEvent(_.MPRV, _.MDT, _.SDT))
val vsstatus = ValidIO((new SstatusBundle).addInEvent(_.SDT))
val targetPc = ValidIO(new TargetPCBundle)
}

Expand All @@ -26,6 +27,7 @@ class MNretEventInput extends Bundle {
val satp = Input(new SatpBundle)
val vsatp = Input(new SatpBundle)
val hgatp = Input(new HgatpBundle)
val vsstatus = Input(new SstatusBundle)
}

class MNretEventModule(implicit p: Parameters) extends Module with CSREventBase {
Expand All @@ -49,18 +51,29 @@ class MNretEventModule(implicit p: Parameters) extends Module with CSREventBase
sv48x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv48x4
)

val outPrivState = Wire(new PrivState)
outPrivState.PRVM := in.mnstatus.MNPP
outPrivState.V := Mux(in.mnstatus.MNPP === PrivMode.M, VirtMode.Off.asUInt, in.mnstatus.MNPV.asUInt)

val mnretToM = outPrivState.isModeM
val mnretToS = outPrivState.isModeHS
val mnretToVU = outPrivState.isModeVU

out := DontCare

out.privState.valid := valid
out.mnstatus .valid := valid
out.targetPc .valid := valid

out.privState.bits.PRVM := in.mnstatus.MNPP
out.privState.bits.V := Mux(in.mnstatus.MNPP === PrivMode.M, VirtMode.Off.asUInt, in.mnstatus.MNPV.asUInt)
out.privState.bits := outPrivState
out.mnstatus.bits.MNPP := PrivMode.U
out.mnstatus.bits.MNPV := VirtMode.Off.asUInt
out.mnstatus.bits.NMIE := 1.U
out.mstatus.bits.MPRV := Mux(in.mnstatus.MNPP =/= PrivMode.M, 0.U, in.mstatus.MPRV.asUInt)
// clear MDT when mnret to below M
out.mstatus.bits.MDT := Mux(mnretToM, in.mstatus.MDT.asBool, 0.U)
out.mstatus.bits.SDT := Mux(mnretToM || mnretToS, in.mstatus.SDT.asBool, 0.U)
out.vsstatus.bits.SDT := Mux(mnretToVU, 0.U, in.vsstatus.SDT.asBool)
out.targetPc.bits.pc := in.mnepc.asUInt
out.targetPc.bits.raiseIPF := instrAddrTransType.checkPageFault(in.mnepc.asUInt)
out.targetPc.bits.raiseIAF := instrAddrTransType.checkAccessFault(in.mnepc.asUInt)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ import xiangshan.AddrTransType


class MretEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase {
val mstatus = ValidIO((new MstatusBundle).addInEvent(_.MPP, _.MPV, _.MIE, _.MPIE, _.MPRV))
val mstatus = ValidIO((new MstatusBundle).addInEvent(_.MPP, _.MPV, _.MIE, _.MPIE, _.MPRV, _.MDT, _.SDT))
val vsstatus = ValidIO((new SstatusBundle).addInEvent(_.SDT))
val targetPc = ValidIO(new TargetPCBundle)
}

class MretEventInput extends Bundle {
val mstatus = Input(new MstatusBundle)
val vsstatus = Input(new SstatusBundle)
val mepc = Input(new Epc())
val satp = Input(new SatpBundle)
val vsatp = Input(new SatpBundle)
Expand All @@ -46,20 +48,33 @@ class MretEventModule(implicit p: Parameters) extends Module with CSREventBase {
sv39x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv39x4,
sv48x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv48x4
)
val outPrivState = Wire(new PrivState)
outPrivState.PRVM := in.mstatus.MPP
outPrivState.V := Mux(in.mstatus.MPP === PrivMode.M, VirtMode.Off.asUInt, in.mstatus.MPV.asUInt)

val mretToM = outPrivState.isModeM
val mretToS = outPrivState.isModeHS
val mretToVu = outPrivState.isModeVU

out := DontCare

out.privState.valid := valid
out.mstatus .valid := valid
out.targetPc .valid := valid

out.privState.bits.PRVM := in.mstatus.MPP
out.privState.bits.V := Mux(in.mstatus.MPP === PrivMode.M, VirtMode.Off.asUInt, in.mstatus.MPV.asUInt)
out.privState.bits := outPrivState
out.mstatus.bits.MPP := PrivMode.U
out.mstatus.bits.MPV := VirtMode.Off.asUInt
out.mstatus.bits.MIE := in.mstatus.MPIE
out.mstatus.bits.MPIE := 1.U
out.mstatus.bits.MPRV := Mux(in.mstatus.MPP =/= PrivMode.M, 0.U, in.mstatus.MPRV.asUInt)
// clear MDT when return mret always execute in M mode
out.mstatus.bits.MDT := 0.U
// clear sstatus.SDT when return mode below M and HS
out.mstatus.bits.SDT := Mux(mretToM || mretToS, in.mstatus.SDT.asBool, 0.U)
// clear vsstatus.SDT when return to VU
out.vsstatus.bits.SDT := Mux(mretToVu, 0.U, in.vsstatus.SDT.asBool)

out.targetPc.bits.pc := in.mepc.asUInt
out.targetPc.bits.raiseIPF := instrAddrTransType.checkPageFault(in.mepc.asUInt)
out.targetPc.bits.raiseIAF := instrAddrTransType.checkAccessFault(in.mepc.asUInt)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ import xiangshan.AddrTransType

class SretEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase {
// Todo: write sstatus instead of mstatus
val mstatus = ValidIO((new MstatusBundle).addInEvent(_.SIE, _.SPIE, _.SPP, _.MPRV))
val mstatus = ValidIO((new MstatusBundle).addInEvent(_.SIE, _.SPIE, _.SPP, _.MPRV, _.MDT, _.SDT))
val hstatus = ValidIO((new HstatusBundle).addInEvent(_.SPV))
val vsstatus = ValidIO((new SstatusBundle).addInEvent(_.SIE, _.SPIE, _.SPP))
val vsstatus = ValidIO((new SstatusBundle).addInEvent(_.SIE, _.SPIE, _.SPP, _.SDT))
val targetPc = ValidIO(new TargetPCBundle)
}

class SretEventInput extends Bundle {
val privState = Input(new PrivState)
val sstatus = Input(new SstatusBundle)
val mstatus = Input(new MstatusBundle)
val hstatus = Input(new HstatusBundle)
val vsstatus = Input(new SstatusBundle)
val sepc = Input(new Epc())
Expand Down Expand Up @@ -53,45 +53,62 @@ class SretEventModule(implicit p: Parameters) extends Module with CSREventBase {
sv48x4 = nextPrivState.isVirtual && vsatp.MODE === SatpMode.Bare && hgatp.MODE === HgatpMode.Sv48x4
)

private val sretInHSorM = in.privState.isModeM || in.privState.isModeHS
private val sretInM = in.privState.isModeM
private val sretInHS = in.privState.isModeHS
private val sretInHSorM = sretInM || sretInHS
private val sretInVS = in.privState.isModeVS

private val xepc = Mux1H(Seq(
sretInHSorM -> in.sepc,
sretInVS -> in.vsepc,
)).asUInt

out := DontCare

out.privState.valid := valid
out.targetPc .valid := valid

out.privState.bits.PRVM := Mux1H(Seq(
private val outPrivState = Wire(new PrivState)
outPrivState.PRVM := Mux1H(Seq(
// SPP is not PrivMode enum type, so asUInt
sretInHSorM -> in.sstatus.SPP.asUInt,
sretInHSorM -> in.mstatus.SPP.asUInt,
sretInVS -> in.vsstatus.SPP.asUInt,
))
out.privState.bits.V := Mux1H(Seq(
outPrivState.V := Mux1H(Seq(
sretInHSorM -> in.hstatus.SPV,
sretInVS -> in.privState.V, // keep
))

private val sretToVU = outPrivState.isModeVU
private val sretToVS = outPrivState.isModeVS
private val sretToU = outPrivState.isModeHU

out := DontCare

out.privState.valid := valid
out.targetPc .valid := valid

out.privState.bits := outPrivState

// hstatus
out.hstatus.valid := valid && sretInHSorM
out.hstatus.bits.SPV := VirtMode.Off

// sstatus
out.mstatus.valid := valid && sretInHSorM
out.mstatus.bits.SPP := PrivMode.U.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width
out.mstatus.bits.SIE := in.sstatus.SPIE
out.mstatus.bits.SIE := in.mstatus.SPIE
out.mstatus.bits.SPIE := 1.U
out.mstatus.bits.MPRV := 0.U // sret will always leave M mode
out.mstatus.bits.MDT := Mux(sretInM, 0.U, in.mstatus.MDT.asBool) // when execute return in M mode, set MDT 0
out.mstatus.bits.SDT := MuxCase(in.mstatus.SDT.asBool, Seq(
sretInHS -> 0.U, // sret will alway leave M mode
(sretInM && (sretToU || sretToVS || sretToVU)) -> 0.U
))


// vsstatus
out.vsstatus.valid := valid && sretInVS
out.vsstatus.bits.SPP := PrivMode.U.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width
out.vsstatus.bits.SIE := in.vsstatus.SPIE
out.vsstatus.bits.SPIE := 1.U
out.vsstatus.bits.SDT := Mux(sretToVU || sretInVS, 0.U, in.vsstatus.SDT.asBool) // clear SDT when return to VU or sret in vs

out.targetPc.bits.pc := xepc
out.targetPc.bits.raiseIPF := instrAddrTransType.checkPageFault(xepc)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import xiangshan.AddrTransType
class TrapEntryHSEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase {

// Todo: use sstatus instead of mstatus
val mstatus = ValidIO((new MstatusBundle ).addInEvent(_.SPP, _.SPIE, _.SIE))
val mstatus = ValidIO((new MstatusBundle ).addInEvent(_.SPP, _.SPIE, _.SIE, _.SDT))
val hstatus = ValidIO((new HstatusBundle ).addInEvent(_.SPV, _.SPVP, _.GVA))
val sepc = ValidIO((new Epc ).addInEvent(_.epc))
val scause = ValidIO((new CauseBundle ).addInEvent(_.Interrupt, _.ExceptionCode))
Expand Down Expand Up @@ -124,6 +124,7 @@ class TrapEntryHSEventModule(implicit val p: Parameters) extends Module with CSR
out.mstatus.bits.SPP := current.privState.PRVM.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width
out.mstatus.bits.SPIE := current.sstatus.SIE
out.mstatus.bits.SIE := 0.U
out.mstatus.bits.SDT := in.menvcfg.DTE.asBool // when DTE open set SDT to 1, else SDT is readonly 0
// hstatus
out.hstatus.bits.SPV := current.privState.V
// SPVP is not PrivMode enum type, so asUInt and shrink the width
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import xiangshan.AddrTransType

class TrapEntryMEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase {

val mstatus = ValidIO((new MstatusBundle ).addInEvent(_.MPV, _.MPP, _.GVA, _.MPIE, _.MIE))
val mstatus = ValidIO((new MstatusBundle ).addInEvent(_.MPV, _.MPP, _.GVA, _.MPIE, _.MIE, _.MDT))
val mepc = ValidIO((new Epc ).addInEvent(_.epc))
val mcause = ValidIO((new CauseBundle ).addInEvent(_.Interrupt, _.ExceptionCode))
val mtval = ValidIO((new OneFieldBundle).addInEvent(_.ALL))
Expand All @@ -32,6 +32,7 @@ class TrapEntryMEventModule(implicit val p: Parameters) extends Module with CSRE
private val satp = current.satp
private val vsatp = current.vsatp
private val hgatp = current.hgatp
private val isDTExcp = current.hasDTExcp

private val highPrioTrapNO = in.causeNO.ExceptionCode.asUInt
private val isException = !in.causeNO.Interrupt.asBool
Expand Down Expand Up @@ -96,6 +97,8 @@ class TrapEntryMEventModule(implicit val p: Parameters) extends Module with CSRE
(isLSGuestExcp ) -> trapMemGPA,
))

private val precause = Cat(isInterrupt, highPrioTrapNO)

out := DontCare

out.privState.valid := valid
Expand All @@ -113,11 +116,12 @@ class TrapEntryMEventModule(implicit val p: Parameters) extends Module with CSRE
out.mstatus.bits.GVA := tvalFillGVA
out.mstatus.bits.MPIE := current.mstatus.MIE
out.mstatus.bits.MIE := 0.U
out.mstatus.bits.MDT := 1.U
out.mepc.bits.epc := Mux(isFetchMalAddr, in.fetchMalTval(63, 1), trapPC(63, 1))
out.mcause.bits.Interrupt := isInterrupt
out.mcause.bits.ExceptionCode := highPrioTrapNO
out.mcause.bits.ExceptionCode := Mux(isDTExcp, ExceptionNO.EX_DT.U, highPrioTrapNO)
out.mtval.bits.ALL := Mux(isFetchMalAddr, in.fetchMalTval, tval)
out.mtval2.bits.ALL := tval2 >> 2
out.mtval2.bits.ALL := Mux(isDTExcp, precause, tval2 >> 2)
out.mtinst.bits.ALL := Mux(isFetchGuestExcp && in.trapIsForVSnonLeafPTE || isLSGuestExcp && in.memExceptionIsForVSnonLeafPTE, 0x3000.U, 0.U)
out.targetPc.bits.pc := in.pcFromXtvec
out.targetPc.bits.raiseIPF := false.B
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import xiangshan.AddrTransType

class TrapEntryVSEventOutput extends Bundle with EventUpdatePrivStateOutput with EventOutputBase {

val vsstatus = ValidIO((new SstatusBundle ).addInEvent(_.SPP, _.SPIE, _.SIE))
val vsstatus = ValidIO((new SstatusBundle ).addInEvent(_.SPP, _.SPIE, _.SIE, _.SDT))
val vsepc = ValidIO((new Epc ).addInEvent(_.epc))
val vscause = ValidIO((new CauseBundle ).addInEvent(_.Interrupt, _.ExceptionCode))
val vstval = ValidIO((new OneFieldBundle).addInEvent(_.ALL))
Expand Down Expand Up @@ -122,6 +122,7 @@ class TrapEntryVSEventModule(implicit val p: Parameters) extends Module with CSR
out.vsstatus.bits.SPP := current.privState.PRVM.asUInt(0, 0) // SPP is not PrivMode enum type, so asUInt and shrink the width
out.vsstatus.bits.SPIE := current.vsstatus.SIE
out.vsstatus.bits.SIE := 0.U
out.vsstatus.bits.SDT := in.henvcfg.DTE.asBool // when DTE open set SDT to 1, else SDT is readonly 0
// SPVP is not PrivMode enum type, so asUInt and shrink the width
out.vsepc.bits.epc := Mux(isFetchMalAddr, in.fetchMalTval(63, 1), trapPC(63, 1))
out.vscause.bits.Interrupt := isInterrupt
Expand Down
15 changes: 11 additions & 4 deletions src/main/scala/xiangshan/backend/fu/NewCSR/HypervisorLevel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,16 @@ trait HypervisorLevel { self: NewCSR =>
.setAddr(CSRs.hvictl)

val henvcfg = Module(new CSRModule("Henvcfg", new HEnvCfg) with HasHypervisorEnvBundle {
when (!menvcfg.STCE.asBool) {
when(!menvcfg.STCE) {
regOut.STCE := 0.U
}
when (!menvcfg.PBMTE) {
when(!menvcfg.PBMTE) {
regOut.PBMTE := 0.U
}
})
.setAddr(CSRs.henvcfg)
when(!menvcfg.DTE) {
regOut.DTE := 0.U
}
}).setAddr(CSRs.henvcfg)

val htval = Module(new CSRModule("Htval", new XtvalBundle) with TrapEntryHSEventSinkBundle)
.setAddr(CSRs.htval)
Expand Down Expand Up @@ -340,6 +342,11 @@ class HEnvCfg extends EnvCfg {
this.STCE.setRW().withReset(1.U)
}
this.PBMTE.setRW().withReset(0.U)
if (CSRConfig.EXT_DBLTRP) {
// software write envcfg to open ssdbltrp if need
// set 0 to pass ci
this.DTE.setRW().withReset(0.U)
}
}

trait HypervisorBundle { self: CSRModule[_] =>
Expand Down
26 changes: 24 additions & 2 deletions src/main/scala/xiangshan/backend/fu/NewCSR/MachineLevel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -452,12 +452,14 @@ class MstatusBundle extends CSRBundle {
val TVM = CSRRWField (20).withReset(0.U)
val TW = CSRRWField (21).withReset(0.U)
val TSR = CSRRWField (22).withReset(0.U)
val SDT = CSRRWField (24).withReset(0.U)
val UXL = XLENField (33, 32).withReset(XLENField.XLEN64)
val SXL = XLENField (35, 34).withReset(XLENField.XLEN64)
val SBE = CSRROField (36).withReset(0.U)
val MBE = CSRROField (37).withReset(0.U)
val GVA = CSRRWField (38).withReset(0.U)
val MPV = VirtMode (39).withReset(0.U)
val MDT = CSRRWField (42).withReset(mdtInit.U)
val SD = CSRROField (63,
(_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty
)
Expand All @@ -471,6 +473,7 @@ class MstatusModule(implicit override val p: Parameters) extends CSRModule("MSta
with MNretEventSinkBundle
with SretEventSinkBundle
with HasRobCommitBundle
with HasMachineEnvBundle
{
val mstatus = IO(Output(bundle))
val sstatus = IO(Output(new SstatusBundle))
Expand All @@ -496,9 +499,23 @@ class MstatusModule(implicit override val p: Parameters) extends CSRModule("MSta
assert(reg.VS =/= ContextStatus.Off, "The [m|s]status.VS should not be Off when set dirty, please check decode")
reg.VS := ContextStatus.Dirty
}

// when MDT is explicitly written by 1, clear MIE
// only when reg.MDT is zero or wdata.MDT is zero , MIE can be explicitly written by 1
when (w.wdataFields.MDT && w.wen) {
reg.MIE := false.B
}
// when DTE is zero, SDT field is read-only zero(write any, read zero, side effect of write 1 is block)
val writeSDT = Wire(Bool())
writeSDT := Mux(this.menvcfg.DTE.asBool, (w.wdataFields.SDT && w.wen) || (wAliasSstatus.wdataFields.SDT && wAliasSstatus.wen), 0.U)
when (!this.menvcfg.DTE) {
regOut.SDT := false.B
}
// SDT and SIE is the same as MDT and MIE
when (writeSDT) {
reg.SIE := false.B
}
// read connection
mstatus :|= reg
mstatus :|= regOut
sstatus := mstatus
rdata := mstatus.asUInt
sstatusRdata := sstatus.asUInt
Expand Down Expand Up @@ -628,6 +645,11 @@ class MEnvCfg extends EnvCfg {
this.STCE.setRW().withReset(1.U)
}
this.PBMTE.setRW().withReset(0.U)
if (CSRConfig.EXT_DBLTRP) {
// software write envcfg to open ssdbltrp if need
// set 0 to pass ci
this.DTE.setRW().withReset(0.U)
}
}

object MarchidField extends CSREnum with ROApply {
Expand Down
Loading