arch-riscv: fault according to status.{TVM,TSK,TW}.

Change-Id: I38dddadb3373d2156b8fc57eabff861a062021cf
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/25654
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
This commit is contained in:
Nils Asmussen
2020-02-14 15:39:44 +01:00
parent c11aed1931
commit 33d651b254
2 changed files with 36 additions and 4 deletions

View File

@@ -1779,13 +1779,16 @@ decode QUADRANT default Unknown::unknown() {
}
0x8: decode RS2 {
0x2: sret({{
if (xc->readMiscReg(MISCREG_PRV) == PRV_U) {
STATUS status = xc->readMiscReg(MISCREG_STATUS);
auto pm = (PrivilegeMode)xc->readMiscReg(
MISCREG_PRV);
if (pm == PRV_U ||
(pm == PRV_S && status.tsr == 1)) {
fault = make_shared<IllegalInstFault>(
"sret in user mode", machInst);
"sret in user mode or TSR enabled",
machInst);
NPC = NPC;
} else {
STATUS status = xc->readMiscReg(
MISCREG_STATUS);
xc->setMiscReg(MISCREG_PRV, status.spp);
status.sie = status.spie;
status.spie = 1;
@@ -1795,10 +1798,26 @@ decode QUADRANT default Unknown::unknown() {
}
}}, IsReturn);
0x5: wfi({{
STATUS status = xc->readMiscReg(MISCREG_STATUS);
auto pm = (PrivilegeMode)xc->readMiscReg(
MISCREG_PRV);
if (pm == PRV_U ||
(pm == PRV_S && status.tw == 1)) {
fault = make_shared<IllegalInstFault>(
"wfi in user mode or TW enabled",
machInst);
}
// don't do anything for now
}}, No_OpClass);
}
0x9: sfence_vma({{
STATUS status = xc->readMiscReg(MISCREG_STATUS);
auto pm = (PrivilegeMode)xc->readMiscReg(MISCREG_PRV);
if (pm == PRV_U || (pm == PRV_S && status.tvm == 1)) {
fault = make_shared<IllegalInstFault>(
"sfence in user mode or TVM enabled",
machInst);
}
xc->tcBase()->getITBPtr()->demapPage(Rs1, Rs2);
xc->tcBase()->getDTBPtr()->demapPage(Rs1, Rs2);
}}, IsNonSpeculative, IsSerializeAfter, No_OpClass);

View File

@@ -307,6 +307,19 @@ def template CSRExecute {{
olddata = xc->readMiscReg(MISCREG_FFLAGS) |
(xc->readMiscReg(MISCREG_FRM) << FRM_OFFSET);
break;
case CSR_SATP: {
auto pm = (PrivilegeMode)xc->readMiscReg(MISCREG_PRV);
STATUS status = xc->readMiscReg(MISCREG_STATUS);
if (pm == PRV_U || (pm == PRV_S && status.tvm == 1)) {
std::string error = csprintf(
"SATP access in user mode or with TVM enabled\n");
fault = make_shared<IllegalInstFault>(error, machInst);
olddata = 0;
} else {
olddata = xc->readMiscReg(CSRData.at(csr).physIndex);
}
break;
}
case CSR_MSTATUS: {
auto pm = (PrivilegeMode)xc->readMiscReg(MISCREG_PRV);
if (pm != PrivilegeMode::PRV_M) {