Mem: Reclaim some request flags used by MIPS for alignment checking.
[gem5.git] / src / arch / arm / isa.hh
index 9b21c03cd7b28e25fde22e81168ea1fe66d5cbbe..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;
@@ -44,54 +57,123 @@ namespace ArmISA
     {
       protected:
         MiscReg miscRegs[NumMiscRegs];
+        const IntRegIndex *intRegMap;
 
-      public:
-        void clear()
-        {
-            memset(miscRegs, 0, sizeof(miscRegs));
-            CPSR cpsr = 0;
-            cpsr.mode = MODE_USER;
-            miscRegs[MISCREG_CPSR] = cpsr;
-            //XXX We need to initialize the rest of the state.
-        }
-
-        MiscReg
-        readMiscRegNoEffect(int misc_reg)
+        void
+        updateRegMap(CPSR cpsr)
         {
-            assert(misc_reg < NumMiscRegs);
-            return miscRegs[misc_reg];
+            switch (cpsr.mode) {
+              case MODE_USER:
+              case MODE_SYSTEM:
+                intRegMap = IntRegUsrMap;
+                break;
+              case MODE_FIQ:
+                intRegMap = IntRegFiqMap;
+                break;
+              case MODE_IRQ:
+                intRegMap = IntRegIrqMap;
+                break;
+              case MODE_SVC:
+                intRegMap = IntRegSvcMap;
+                break;
+              case MODE_MON:
+                intRegMap = IntRegMonMap;
+                break;
+              case MODE_ABORT:
+                intRegMap = IntRegAbtMap;
+                break;
+              case MODE_UNDEFINED:
+                intRegMap = IntRegUndMap;
+                break;
+              default:
+                panic("Unrecognized mode setting in CPSR.\n");
+            }
         }
 
-        MiscReg
-        readMiscReg(int misc_reg, ThreadContext *tc)
-        {
-            assert(misc_reg < NumMiscRegs);
-            return miscRegs[misc_reg];
-        }
+      public:
+        void clear();
 
-        void
-        setMiscRegNoEffect(int misc_reg, const MiscReg &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);
 
-        void
-        setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
+        int
+        flattenIntIndex(int reg)
         {
-            assert(misc_reg < NumMiscRegs);
-            miscRegs[misc_reg] = val;
+            assert(reg >= 0);
+            if (reg < NUM_ARCH_INTREGS) {
+                return intRegMap[reg];
+            } else if (reg < NUM_INTREGS) {
+                return reg;
+            } else {
+                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");
+                }
+            }
         }
 
         int
-        flattenIntIndex(int reg)
+        flattenFloatIndex(int reg)
         {
             return reg;
         }
 
         int
-        flattenFloatIndex(int reg)
+        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;
         }
 
@@ -103,6 +185,10 @@ namespace ArmISA
 
         ISA()
         {
+            SCTLR sctlr;
+            sctlr = 0;
+            miscRegs[MISCREG_SCTLR_RST] = sctlr;
+
             clear();
         }
     };