arch-riscv: fault according to status.{TVM,TSK,TW}.
authorNils Asmussen <nils.asmussen@barkhauseninstitut.org>
Fri, 14 Feb 2020 14:39:44 +0000 (15:39 +0100)
committerNils Asmussen <nils.asmussen@barkhauseninstitut.org>
Wed, 29 Apr 2020 11:41:55 +0000 (11:41 +0000)
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>

src/arch/riscv/isa/decoder.isa
src/arch/riscv/isa/formats/standard.isa

index 870615582417fc7802414b81c66aec96bbb949d8..8dad14caa425fdbecfd9f206739c63eaf3f5ed18 100644 (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);
index d80c671f26a467691c571c726d0ee40860756bdd..11c06aa7ebcad11b76ffca7478ccdd961eef5323 100644 (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) {