arm: miscreg refactoring
authorCurtis Dunham <Curtis.Dunham@arm.com>
Mon, 19 Dec 2016 17:03:27 +0000 (11:03 -0600)
committerCurtis Dunham <Curtis.Dunham@arm.com>
Mon, 19 Dec 2016 17:03:27 +0000 (11:03 -0600)
Change-Id: I4e9e8f264a4a4239dd135a6c7a1c8da213b6d345
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
src/arch/arm/isa.cc
src/arch/arm/isa.hh
src/arch/arm/miscregs.cc

index 034340049bf048222f080efe90088695a7c44b32..c093ceda9abd11bf1de226154a3bafbccc08ae95 100644 (file)
@@ -226,12 +226,14 @@ ISA::ISA(Params *p)
 
     // Cache system-level properties
     if (FullSystem && system) {
+        highestELIs64 = system->highestELIs64();
         haveSecurity = system->haveSecurity();
         haveLPAE = system->haveLPAE();
         haveVirtualization = system->haveVirtualization();
         haveLargeAsid64 = system->haveLargeAsid64();
         physAddrRange64 = system->physAddrRange64();
     } else {
+        highestELIs64 = true; // ArmSystem::highestELIs64 does the same
         haveSecurity = haveLPAE = haveVirtualization = false;
         haveLargeAsid64 = false;
         physAddrRange64 = 32;  // dummy value
@@ -487,22 +489,10 @@ ISA::readMiscRegNoEffect(int misc_reg) const
 {
     assert(misc_reg < NumMiscRegs);
 
-    int flat_idx = flattenMiscIndex(misc_reg);  // Note: indexes of AArch64
-                                                // registers are left unchanged
-    MiscReg val;
-
-    if (lookUpMiscReg[flat_idx].lower == 0 || flat_idx == MISCREG_SPSR) {
-        if (flat_idx == MISCREG_SPSR)
-            flat_idx = flattenMiscIndex(MISCREG_SPSR);
-        val = miscRegs[flat_idx];
-    } else
-        if (lookUpMiscReg[flat_idx].upper > 0)
-            val = ((miscRegs[lookUpMiscReg[flat_idx].lower] & mask(32))
-                    | (miscRegs[lookUpMiscReg[flat_idx].upper] << 32));
-        else
-            val = miscRegs[lookUpMiscReg[flat_idx].lower];
-
-    return val;
+    auto regs = getMiscIndices(misc_reg);
+    int lower = regs.first, upper = regs.second;
+    return !upper ? miscRegs[lower] : ((miscRegs[lower] & mask(32))
+                                      |(miscRegs[upper] << 32));
 }
 
 
@@ -801,25 +791,17 @@ ISA::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
 {
     assert(misc_reg < NumMiscRegs);
 
-    int flat_idx = flattenMiscIndex(misc_reg);  // Note: indexes of AArch64
-                                                // registers are left unchanged
-
-    int flat_idx2 = lookUpMiscReg[flat_idx].upper;
-
-    if (flat_idx2 > 0) {
-        miscRegs[lookUpMiscReg[flat_idx].lower] = bits(val, 31, 0);
-        miscRegs[flat_idx2] = bits(val, 63, 32);
+    auto regs = getMiscIndices(misc_reg);
+    int lower = regs.first, upper = regs.second;
+    if (upper > 0) {
+        miscRegs[lower] = bits(val, 31, 0);
+        miscRegs[upper] = bits(val, 63, 32);
         DPRINTF(MiscRegs, "Writing to misc reg %d (%d:%d) : %#x\n",
-                misc_reg, flat_idx, flat_idx2, val);
+                misc_reg, lower, upper, val);
     } else {
-        if (flat_idx == MISCREG_SPSR)
-            flat_idx = flattenMiscIndex(MISCREG_SPSR);
-        else
-            flat_idx = (lookUpMiscReg[flat_idx].lower > 0) ?
-                       lookUpMiscReg[flat_idx].lower : flat_idx;
-        miscRegs[flat_idx] = val;
+        miscRegs[lower] = val;
         DPRINTF(MiscRegs, "Writing to misc reg %d (%d) : %#x\n",
-                misc_reg, flat_idx, val);
+                misc_reg, lower, val);
     }
 }
 
index 79db09e1dcc39d6f2f6947f1b69e10159c46a626..e05f0e18ad3f8f9b4cf3c5aa1929b7fb7e51c29e 100644 (file)
@@ -79,6 +79,7 @@ namespace ArmISA
         std::unique_ptr<BaseISADevice> timer;
 
         // Cached copies of system-level properties
+        bool highestELIs64;
         bool haveSecurity;
         bool haveLPAE;
         bool haveVirtualization;
@@ -328,7 +329,7 @@ namespace ArmISA
                 }
             } else {
                 if (miscRegInfo[reg][MISCREG_BANKED]) {
-                    bool secureReg = haveSecurity &&
+                    bool secureReg = haveSecurity && !highestELIs64 &&
                                      inSecureState(miscRegs[MISCREG_SCR],
                                                    miscRegs[MISCREG_CPSR]);
                     flat_idx += secureReg ? 2 : 1;
@@ -337,11 +338,33 @@ namespace ArmISA
             return flat_idx;
         }
 
+        std::pair<int,int> getMiscIndices(int misc_reg) const
+        {
+            // Note: indexes of AArch64 registers are left unchanged
+            int flat_idx = flattenMiscIndex(misc_reg);
+
+            if (lookUpMiscReg[flat_idx].lower == 0) {
+                return std::make_pair(flat_idx, 0);
+            }
+
+            // do additional S/NS flattenings if mapped to NS while in S
+            bool S = haveSecurity && !highestELIs64 &&
+                     inSecureState(miscRegs[MISCREG_SCR],
+                                   miscRegs[MISCREG_CPSR]);
+            int lower = lookUpMiscReg[flat_idx].lower;
+            int upper = lookUpMiscReg[flat_idx].upper;
+            // upper == 0, which is CPSR, is not MISCREG_BANKED_CHILD (no-op)
+            lower += S && miscRegInfo[lower][MISCREG_BANKED_CHILD];
+            upper += S && miscRegInfo[upper][MISCREG_BANKED_CHILD];
+            return std::make_pair(lower, upper);
+        }
+
         void serialize(CheckpointOut &cp) const
         {
             DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
             SERIALIZE_ARRAY(miscRegs, NumMiscRegs);
 
+            SERIALIZE_SCALAR(highestELIs64);
             SERIALIZE_SCALAR(haveSecurity);
             SERIALIZE_SCALAR(haveLPAE);
             SERIALIZE_SCALAR(haveVirtualization);
@@ -355,6 +378,7 @@ namespace ArmISA
             CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
             updateRegMap(tmp_cpsr);
 
+            UNSERIALIZE_SCALAR(highestELIs64);
             UNSERIALIZE_SCALAR(haveSecurity);
             UNSERIALIZE_SCALAR(haveLPAE);
             UNSERIALIZE_SCALAR(haveVirtualization);
index c4915cb54f381c026921affcf10afee16efc72b8..525d448107316086ec430f3b09195e54229ced96 100644 (file)
@@ -2039,12 +2039,8 @@ canWriteCoprocReg(MiscRegIndex reg, SCR scr, CPSR cpsr, ThreadContext *tc)
 int
 flattenMiscRegNsBanked(MiscRegIndex reg, ThreadContext *tc)
 {
-    int reg_as_int = static_cast<int>(reg);
-    if (miscRegInfo[reg][MISCREG_BANKED]) {
-        SCR scr = tc->readMiscReg(MISCREG_SCR);
-        reg_as_int += (ArmSystem::haveSecurity(tc) && !scr.ns) ? 2 : 1;
-    }
-    return reg_as_int;
+    SCR scr = tc->readMiscReg(MISCREG_SCR);
+    return flattenMiscRegNsBanked(reg, tc, scr.ns);
 }
 
 int
@@ -2052,7 +2048,8 @@ flattenMiscRegNsBanked(MiscRegIndex reg, ThreadContext *tc, bool ns)
 {
     int reg_as_int = static_cast<int>(reg);
     if (miscRegInfo[reg][MISCREG_BANKED]) {
-        reg_as_int += (ArmSystem::haveSecurity(tc) && !ns) ? 2 : 1;
+        reg_as_int += (ArmSystem::haveSecurity(tc) &&
+                      !ArmSystem::highestELIs64(tc) && !ns) ? 2 : 1;
     }
     return reg_as_int;
 }