1
0

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:
Andrew Waterman 2016-08-17 15:02:27 -07:00
parent 35fbbfc70d
commit 5164f947c0
2 changed files with 26 additions and 22 deletions

View File

@ -144,6 +144,9 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
reset_mstatus.prv := PRV.M reset_mstatus.prv := PRV.M
val reg_mstatus = Reg(init=reset_mstatus) 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)) val reset_dcsr = Wire(init=new DCSR().fromBits(0))
reset_dcsr.xdebugver := 1 reset_dcsr.xdebugver := 1
reset_dcsr.prv := PRV.M reset_dcsr.prv := PRV.M
@ -400,7 +403,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
reg_debug := true reg_debug := true
reg_dpc := epc reg_dpc := epc
reg_dcsr.cause := Mux(reg_singleStepped, UInt(4), Mux(causeIsDebugInt, UInt(3), UInt(1))) 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) { }.elsewhen (delegate) {
reg_sepc := epc reg_sepc := epc
reg_scause := cause reg_scause := cause
@ -408,33 +411,33 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
reg_mstatus.spie := pie reg_mstatus.spie := pie
reg_mstatus.spp := reg_mstatus.prv reg_mstatus.spp := reg_mstatus.prv
reg_mstatus.sie := false reg_mstatus.sie := false
reg_mstatus.prv := PRV.S new_prv := PRV.S
}.otherwise { }.otherwise {
reg_mepc := epc reg_mepc := epc
reg_mcause := cause reg_mcause := cause
when (write_badaddr) { reg_mbadaddr := io.badaddr } when (write_badaddr) { reg_mbadaddr := io.badaddr }
reg_mstatus.mpie := pie reg_mstatus.mpie := pie
reg_mstatus.mpp := reg_mstatus.prv reg_mstatus.mpp := trimPrivilege(reg_mstatus.prv)
reg_mstatus.mie := false reg_mstatus.mie := false
reg_mstatus.prv := PRV.M new_prv := PRV.M
} }
} }
when (insn_ret) { when (insn_ret) {
when (Bool(p(UseVM)) && !csr_addr_priv(1)) { when (Bool(p(UseVM)) && !csr_addr_priv(1)) {
when (reg_mstatus.spp.toBool) { reg_mstatus.sie := reg_mstatus.spie } when (reg_mstatus.spp.toBool) { reg_mstatus.sie := reg_mstatus.spie }
reg_mstatus.spie := false reg_mstatus.spie := false
reg_mstatus.spp := PRV.U reg_mstatus.spp := PRV.U
reg_mstatus.prv := reg_mstatus.spp new_prv := reg_mstatus.spp
}.elsewhen (csr_debug) { }.elsewhen (csr_debug) {
reg_mstatus.prv := reg_dcsr.prv new_prv := reg_dcsr.prv
reg_debug := false reg_debug := false
}.otherwise { }.otherwise {
when (reg_mstatus.mpp(1)) { reg_mstatus.mie := reg_mstatus.mpie } when (reg_mstatus.mpp(1)) { reg_mstatus.mie := reg_mstatus.mpie }
.elsewhen (Bool(usingVM) && reg_mstatus.mpp(0)) { reg_mstatus.sie := reg_mstatus.mpie } .elsewhen (Bool(usingVM) && reg_mstatus.mpp(0)) { reg_mstatus.sie := reg_mstatus.mpie }
reg_mstatus.mpie := false reg_mstatus.mpie := false
reg_mstatus.mpp := PRV.U reg_mstatus.mpp := legalizePrivilege(PRV.U)
reg_mstatus.prv := reg_mstatus.mpp 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 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 (wen) {
when (decoded_addr(CSRs.mstatus)) { when (decoded_addr(CSRs.mstatus)) {
val new_mstatus = new MStatus().fromBits(wdata) val new_mstatus = new MStatus().fromBits(wdata)
reg_mstatus.mie := new_mstatus.mie reg_mstatus.mie := new_mstatus.mie
reg_mstatus.mpie := new_mstatus.mpie reg_mstatus.mpie := new_mstatus.mpie
if (supportedModes.size > 1) { if (usingUser) {
reg_mstatus.mprv := new_mstatus.mprv reg_mstatus.mprv := new_mstatus.mprv
when (supportedModes contains new_mstatus.mpp) { reg_mstatus.mpp := new_mstatus.mpp } reg_mstatus.mpp := trimPrivilege(new_mstatus.mpp)
if (supportedModes.size > 2) { if (usingVM) {
reg_mstatus.mxr := new_mstatus.mxr reg_mstatus.mxr := new_mstatus.mxr
reg_mstatus.pum := new_mstatus.pum reg_mstatus.pum := new_mstatus.pum
reg_mstatus.spp := new_mstatus.spp reg_mstatus.spp := new_mstatus.spp
@ -506,7 +507,7 @@ class CSRFile(implicit p: Parameters) extends CoreModule()(p)
reg_dcsr.ebreakm := new_dcsr.ebreakm reg_dcsr.ebreakm := new_dcsr.ebreakm
if (usingVM) reg_dcsr.ebreaks := new_dcsr.ebreaks if (usingVM) reg_dcsr.ebreaks := new_dcsr.ebreaks
if (usingUser) reg_dcsr.ebreaku := new_dcsr.ebreaku 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.dpc)) { reg_dpc := ~(~wdata | (coreInstBytes-1)) }
when (decoded_addr(CSRs.dscratch)) { reg_dscratch := wdata } 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.debugint := io.prci.interrupts.debug
reg_dcsr.hwbpcount := UInt(p(NBreakpoints)) 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_sptbr.asid := 0
reg_tdrselect.reserved := 0 reg_tdrselect.reserved := 0
reg_tdrselect.tdrmode := true // TODO support D-mode breakpoint theft 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)) for (bp <- reg_bp drop p(NBreakpoints))
bp := new BP().fromBits(0) 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)
} }

View File

@ -38,7 +38,7 @@ trait HasCoreParameters extends HasAddrMapParameters {
val xLen = p(XLen) val xLen = p(XLen)
val usingVM = p(UseVM) val usingVM = p(UseVM)
val usingUser = p(UseUser) val usingUser = p(UseUser) || usingVM
val usingDebug = p(UseDebug) val usingDebug = p(UseDebug)
val usingFPU = p(UseFPU) val usingFPU = p(UseFPU)
val usingAtomics = p(UseAtomics) val usingAtomics = p(UseAtomics)