Mem: Reclaim some request flags used by MIPS for alignment checking.
[gem5.git] / src / arch / arm / isa.hh
index a4a328614e66d59501e6055276bb38c9783b5b16..8318417f59c3ea59add17099036f29ff41a0b4cf 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2009 The Regents of The University of Michigan
  * All rights reserved.
  *
  */
 
 #ifndef __ARCH_ARM_ISA_HH__
-#define __ARCH_MRM_ISA_HH__
+#define __ARCH_ARM_ISA_HH__
 
 #include "arch/arm/registers.hh"
+#include "arch/arm/tlb.hh"
 #include "arch/arm/types.hh"
 
 class ThreadContext;
@@ -78,46 +91,12 @@ namespace ArmISA
         }
 
       public:
-        void clear()
-        {
-            memset(miscRegs, 0, sizeof(miscRegs));
-            CPSR cpsr = 0;
-            cpsr.mode = MODE_USER;
-            miscRegs[MISCREG_CPSR] = cpsr;
-            updateRegMap(cpsr);
-            //XXX We need to initialize the rest of the state.
-        }
-
-        MiscReg
-        readMiscRegNoEffect(int misc_reg)
-        {
-            assert(misc_reg < NumMiscRegs);
-            return miscRegs[misc_reg];
-        }
-
-        MiscReg
-        readMiscReg(int misc_reg, ThreadContext *tc)
-        {
-            assert(misc_reg < NumMiscRegs);
-            return miscRegs[misc_reg];
-        }
-
-        void
-        setMiscRegNoEffect(int misc_reg, const MiscReg &val)
-        {
-            assert(misc_reg < NumMiscRegs);
-            miscRegs[misc_reg] = val;
-        }
+        void clear();
 
-        void
-        setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
-        {
-            if (misc_reg == MISCREG_CPSR) {
-                updateRegMap(val);
-            }
-            assert(misc_reg < NumMiscRegs);
-            miscRegs[misc_reg] = val;
-        }
+        MiscReg readMiscRegNoEffect(int misc_reg);
+        MiscReg readMiscReg(int misc_reg, ThreadContext *tc);
+        void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
+        void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc);
 
         int
         flattenIntIndex(int reg)
@@ -128,9 +107,27 @@ namespace ArmISA
             } else if (reg < NUM_INTREGS) {
                 return reg;
             } else {
-                reg -= NUM_INTREGS;
-                assert(reg < NUM_ARCH_INTREGS);
-                return reg;
+                int mode = reg / intRegsPerMode;
+                reg = reg % intRegsPerMode;
+                switch (mode) {
+                  case MODE_USER:
+                  case MODE_SYSTEM:
+                    return INTREG_USR(reg);
+                  case MODE_FIQ:
+                    return INTREG_FIQ(reg);
+                  case MODE_IRQ:
+                    return INTREG_IRQ(reg);
+                  case MODE_SVC:
+                    return INTREG_SVC(reg);
+                  case MODE_MON:
+                    return INTREG_MON(reg);
+                  case MODE_ABORT:
+                    return INTREG_ABT(reg);
+                  case MODE_UNDEFINED:
+                    return INTREG_UND(reg);
+                  default:
+                    panic("Flattening into an unknown mode.\n");
+                }
             }
         }
 
@@ -140,6 +137,46 @@ namespace ArmISA
             return reg;
         }
 
+        int
+        flattenMiscIndex(int reg)
+        {
+            if (reg == MISCREG_SPSR) {
+                int spsr_idx = NUM_MISCREGS;
+                CPSR cpsr = miscRegs[MISCREG_CPSR];
+                switch (cpsr.mode) {
+                  case MODE_USER:
+                    warn("User mode does not have SPSR\n");
+                    spsr_idx = MISCREG_SPSR;
+                    break;
+                  case MODE_FIQ:
+                    spsr_idx = MISCREG_SPSR_FIQ;
+                    break;
+                  case MODE_IRQ:
+                    spsr_idx = MISCREG_SPSR_IRQ;
+                    break;
+                  case MODE_SVC:
+                    spsr_idx = MISCREG_SPSR_SVC;
+                    break;
+                  case MODE_MON:
+                    spsr_idx = MISCREG_SPSR_MON;
+                    break;
+                  case MODE_ABORT:
+                    spsr_idx = MISCREG_SPSR_ABT;
+                    break;
+                  case MODE_UNDEFINED:
+                    spsr_idx = MISCREG_SPSR_UND;
+                    break;
+                  default:
+                    warn("Trying to access SPSR in an invalid mode: %d\n",
+                         cpsr.mode);
+                    spsr_idx = MISCREG_SPSR;
+                    break;
+                }
+                return spsr_idx;
+            }
+            return reg;
+        }
+
         void serialize(EventManager *em, std::ostream &os)
         {}
         void unserialize(EventManager *em, Checkpoint *cp,
@@ -148,6 +185,10 @@ namespace ArmISA
 
         ISA()
         {
+            SCTLR sctlr;
+            sctlr = 0;
+            miscRegs[MISCREG_SCTLR_RST] = sctlr;
+
             clear();
         }
     };