arch-arm: Add System register trap check for EL1
authorJordi Vaquero <jordi.vaquero@metempsy.com>
Wed, 22 Jul 2020 11:20:46 +0000 (13:20 +0200)
committerJordi Vaquero <jordi.vaquero@metempsy.com>
Thu, 23 Jul 2020 13:11:13 +0000 (13:11 +0000)
This change adds and refactors the register trap checks
for EL1 in the same function, unifying the registry trapping

Change-Id: Ief3e0a9f70cc8cd44c1c8215515f36168927362d
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/31694
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/arm/insts/misc64.cc
src/arch/arm/isa/insts/data64.isa
src/arch/arm/miscregs.cc
src/arch/arm/miscregs_types.hh

index 51e602863ab8621b83bde1e734df2edb8294500e..49cc6b0f87f04bc123428aa50f1383c6c01d32da 100644 (file)
@@ -114,9 +114,26 @@ MiscRegOp64::checkEL1Trap(ThreadContext *tc, const MiscRegIndex misc_reg,
                           uint32_t &immediate) const
 {
     const CPACR cpacr = tc->readMiscReg(MISCREG_CPACR_EL1);
+    const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
+    const SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR_EL1);
+    const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
 
     bool trap_to_sup = false;
     switch (misc_reg) {
+      case MISCREG_DAIF:
+        trap_to_sup = !scr.ns && !scr.eel2 && !sctlr.uma && el == EL0;
+        trap_to_sup = trap_to_sup ||
+            (el == EL0 && (scr.ns || scr.eel2) && !hcr.tge && !sctlr.uma);
+        break;
+      case MISCREG_DC_ZVA_Xt:
+        // In syscall-emulation mode, this test is skipped and DCZVA is always
+        // allowed at EL0
+        trap_to_sup =  el == EL0 && !sctlr.dze && FullSystem;
+        break;
+      case MISCREG_DC_CIVAC_Xt:
+      case MISCREG_DC_CVAC_Xt:
+        trap_to_sup = el == EL0 && !sctlr.uci;
+        break;
       case MISCREG_FPCR:
       case MISCREG_FPSR:
       case MISCREG_FPEXC32_EL2:
@@ -127,6 +144,24 @@ MiscRegOp64::checkEL1Trap(ThreadContext *tc, const MiscRegIndex misc_reg,
             immediate = 0x1E00000;
         }
         break;
+      case MISCREG_DC_CVAU_Xt:
+        trap_to_sup = !sctlr.uci && (!hcr.tge || (!scr.ns && !scr.eel2)) &&
+            el == EL1;
+        break;
+      case MISCREG_CTR_EL0:
+        trap_to_sup = el == EL0 && !sctlr.uct &&
+            (!hcr.tge || (!scr.ns && !scr.eel2));
+        break;
+       case MISCREG_MDCCSR_EL0:
+         {
+             DBGDS32 mdscr = tc->readMiscReg(MISCREG_MDSCR_EL1);
+             trap_to_sup = el == EL0 && mdscr.tdcc &&
+                     (hcr.tge == 0x0 || ( scr.ns == 0x0));
+         }
+         break;
+     case MISCREG_ZCR_EL1:
+        trap_to_sup = el == EL1 && ((cpacr.zen & 0x1) == 0x0);
+        break;
       // Generic Timer
       case MISCREG_CNTFRQ_EL0 ... MISCREG_CNTVOFF_EL2:
         trap_to_sup = el == EL0 &&
index 3c1e941537522351fa86070e068846685c10fe6b..1b099bf91a510ddb5c257377a10b34f555f2bc78 100644 (file)
@@ -312,14 +312,6 @@ let {{
     msrMrs64EnabledCheckCode = '''
         // Check for read/write access right
         if (!can%sAArch64SysReg(flat_idx, Hcr64, Scr64, cpsr, xc->tcBase())) {
-            if (flat_idx == MISCREG_DAIF ||
-                flat_idx == MISCREG_DC_ZVA_Xt ||
-                flat_idx == MISCREG_DC_CVAC_Xt ||
-                flat_idx == MISCREG_DC_CIVAC_Xt
-                )
-                return std::make_shared<UndefinedInstruction>(
-                                    machInst, 0, EC_TRAPPED_MSR_MRS_64,
-                                    mnemonic);
             return std::make_shared<UndefinedInstruction>(machInst, false,
                                                           mnemonic);
         }
index cc451c6c185653aa7107b9b5d9e63c791912a230..525fbcdde995e13c56538e39085e84b3da70fa00 100644 (file)
@@ -1415,23 +1415,6 @@ canWriteAArch64SysReg(MiscRegIndex reg, HCR hcr, SCR scr, CPSR cpsr,
     if ((reg == MISCREG_SP_EL0) && (tc->readMiscReg(MISCREG_SPSEL) == 0))
         return false;
     ExceptionLevel el = currEL(cpsr);
-    if (reg == MISCREG_DAIF) {
-        SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR_EL1);
-        if (el == EL0 && !sctlr.uma)
-            return false;
-    }
-    if (FullSystem && reg == MISCREG_DC_ZVA_Xt) {
-        // In syscall-emulation mode, this test is skipped and DCZVA is always
-        // allowed at EL0
-        SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR_EL1);
-        if (el == EL0 && !sctlr.dze)
-            return false;
-    }
-    if (reg == MISCREG_DC_CVAC_Xt || reg == MISCREG_DC_CIVAC_Xt) {
-        SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR_EL1);
-        if (el == EL0 && !sctlr.uci)
-            return false;
-    }
 
     bool secure = ArmSystem::haveSecurity(tc) && !scr.ns;
     bool el2_host = EL2Enabled(tc) && hcr.e2h;
index d3787ffae5768719524cbd297c67c0ca3213a861..3578f58c5673c2c6fa80715af8730f97c688c51a 100644 (file)
@@ -730,6 +730,7 @@ namespace ArmISA
         Bitfield<14> hde;
         Bitfield<13> res0_;
         Bitfield<12> udccdis;
+        Bitfield<12> tdcc;
         Bitfield<11, 7> res0_2;
         Bitfield<6> err;
         Bitfield<5, 2> moe;