Validate mstatus.mpp/dcsr.prv values on MRET/DRET
The registers can still hold invalid values, but an attempt to switch to the mode stored therein will instead go to an implemented mode.
This commit is contained in:
parent
35fbbfc70d
commit
5164f947c0
@ -144,6 +144,9 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
||||
reset_mstatus.prv := PRV.M
|
||||
val reg_mstatus = Reg(init=reset_mstatus)
|
||||
|
||||
val new_prv = Wire(init = reg_mstatus.prv)
|
||||
reg_mstatus.prv := legalizePrivilege(new_prv)
|
||||
|
||||
val reset_dcsr = Wire(init=new DCSR().fromBits(0))
|
||||
reset_dcsr.xdebugver := 1
|
||||
reset_dcsr.prv := PRV.M
|
||||
@ -400,7 +403,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
||||
reg_debug := true
|
||||
reg_dpc := epc
|
||||
reg_dcsr.cause := Mux(reg_singleStepped, UInt(4), Mux(causeIsDebugInt, UInt(3), UInt(1)))
|
||||
reg_dcsr.prv := reg_mstatus.prv
|
||||
reg_dcsr.prv := trimPrivilege(reg_mstatus.prv)
|
||||
}.elsewhen (delegate) {
|
||||
reg_sepc := epc
|
||||
reg_scause := cause
|
||||
@ -408,15 +411,15 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
||||
reg_mstatus.spie := pie
|
||||
reg_mstatus.spp := reg_mstatus.prv
|
||||
reg_mstatus.sie := false
|
||||
reg_mstatus.prv := PRV.S
|
||||
new_prv := PRV.S
|
||||
}.otherwise {
|
||||
reg_mepc := epc
|
||||
reg_mcause := cause
|
||||
when (write_badaddr) { reg_mbadaddr := io.badaddr }
|
||||
reg_mstatus.mpie := pie
|
||||
reg_mstatus.mpp := reg_mstatus.prv
|
||||
reg_mstatus.mpp := trimPrivilege(reg_mstatus.prv)
|
||||
reg_mstatus.mie := false
|
||||
reg_mstatus.prv := PRV.M
|
||||
new_prv := PRV.M
|
||||
}
|
||||
}
|
||||
|
||||
@ -425,16 +428,16 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
||||
when (reg_mstatus.spp.toBool) { reg_mstatus.sie := reg_mstatus.spie }
|
||||
reg_mstatus.spie := false
|
||||
reg_mstatus.spp := PRV.U
|
||||
reg_mstatus.prv := reg_mstatus.spp
|
||||
new_prv := reg_mstatus.spp
|
||||
}.elsewhen (csr_debug) {
|
||||
reg_mstatus.prv := reg_dcsr.prv
|
||||
new_prv := reg_dcsr.prv
|
||||
reg_debug := false
|
||||
}.otherwise {
|
||||
when (reg_mstatus.mpp(1)) { reg_mstatus.mie := reg_mstatus.mpie }
|
||||
.elsewhen (Bool(usingVM) && reg_mstatus.mpp(0)) { reg_mstatus.sie := reg_mstatus.mpie }
|
||||
reg_mstatus.mpie := false
|
||||
reg_mstatus.mpp := PRV.U
|
||||
reg_mstatus.prv := reg_mstatus.mpp
|
||||
reg_mstatus.mpp := legalizePrivilege(PRV.U)
|
||||
new_prv := reg_mstatus.mpp
|
||||
}
|
||||
}
|
||||
|
||||
@ -450,18 +453,16 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
||||
reg_fflags := reg_fflags | io.fcsr_flags.bits
|
||||
}
|
||||
|
||||
val supportedModes = Vec((PRV.M +: (if (usingUser) Some(PRV.U) else None) ++: (if (usingVM) Seq(PRV.S) else Nil)).map(UInt(_)))
|
||||
|
||||
when (wen) {
|
||||
when (decoded_addr(CSRs.mstatus)) {
|
||||
val new_mstatus = new MStatus().fromBits(wdata)
|
||||
reg_mstatus.mie := new_mstatus.mie
|
||||
reg_mstatus.mpie := new_mstatus.mpie
|
||||
|
||||
if (supportedModes.size > 1) {
|
||||
if (usingUser) {
|
||||
reg_mstatus.mprv := new_mstatus.mprv
|
||||
when (supportedModes contains new_mstatus.mpp) { reg_mstatus.mpp := new_mstatus.mpp }
|
||||
if (supportedModes.size > 2) {
|
||||
reg_mstatus.mpp := trimPrivilege(new_mstatus.mpp)
|
||||
if (usingVM) {
|
||||
reg_mstatus.mxr := new_mstatus.mxr
|
||||
reg_mstatus.pum := new_mstatus.pum
|
||||
reg_mstatus.spp := new_mstatus.spp
|
||||
@ -506,7 +507,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
||||
reg_dcsr.ebreakm := new_dcsr.ebreakm
|
||||
if (usingVM) reg_dcsr.ebreaks := new_dcsr.ebreaks
|
||||
if (usingUser) reg_dcsr.ebreaku := new_dcsr.ebreaku
|
||||
if (supportedModes.size > 1) reg_dcsr.prv := new_dcsr.prv
|
||||
if (usingUser) reg_dcsr.prv := trimPrivilege(new_dcsr.prv)
|
||||
}
|
||||
when (decoded_addr(CSRs.dpc)) { reg_dpc := ~(~wdata | (coreInstBytes-1)) }
|
||||
when (decoded_addr(CSRs.dscratch)) { reg_dscratch := wdata }
|
||||
@ -554,12 +555,6 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
||||
reg_dcsr.debugint := io.prci.interrupts.debug
|
||||
reg_dcsr.hwbpcount := UInt(p(NBreakpoints))
|
||||
|
||||
if (!usingUser) {
|
||||
reg_mstatus.mpp := PRV.M
|
||||
reg_mstatus.prv := PRV.M
|
||||
reg_mstatus.mprv := false
|
||||
}
|
||||
|
||||
reg_sptbr.asid := 0
|
||||
reg_tdrselect.reserved := 0
|
||||
reg_tdrselect.tdrmode := true // TODO support D-mode breakpoint theft
|
||||
@ -581,4 +576,13 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
|
||||
}
|
||||
for (bp <- reg_bp drop p(NBreakpoints))
|
||||
bp := new BP().fromBits(0)
|
||||
|
||||
def legalizePrivilege(priv: UInt): UInt =
|
||||
if (usingVM) Mux(priv === PRV.H, PRV.U, priv)
|
||||
else if (usingUser) Fill(2, priv(0))
|
||||
else PRV.M
|
||||
|
||||
def trimPrivilege(priv: UInt): UInt =
|
||||
if (usingVM) priv
|
||||
else legalizePrivilege(priv)
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ trait HasCoreParameters extends HasAddrMapParameters {
|
||||
val xLen = p(XLen)
|
||||
|
||||
val usingVM = p(UseVM)
|
||||
val usingUser = p(UseUser)
|
||||
val usingUser = p(UseUser) || usingVM
|
||||
val usingDebug = p(UseDebug)
|
||||
val usingFPU = p(UseFPU)
|
||||
val usingAtomics = p(UseAtomics)
|
||||
|
Loading…
Reference in New Issue
Block a user