ARM: Don't reset CPUs that are going to be switched in.
[gem5.git] / src / arch / arm / isa.cc
index b8a047f6501756de7c215d8465f5650d887ca61f..b8a0fe2823572e7d674e515c2de110c47cdb3237 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 ARM Limited
+ * Copyright (c) 2010-2012 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
  */
 
 #include "arch/arm/isa.hh"
+#include "config/use_checker.hh"
 #include "debug/Arm.hh"
 #include "debug/MiscRegs.hh"
 #include "sim/faults.hh"
 #include "sim/stat_control.hh"
 #include "sim/system.hh"
 
+#if USE_CHECKER
+#include "cpu/checker/cpu.hh"
+#endif
+
 namespace ArmISA
 {
 
@@ -140,7 +145,7 @@ ISA::clear()
 
     // See section B4.1.84 of ARM ARM
     // All values are latest for ARMv7-A profile
-    miscRegs[MISCREG_ID_ISAR0] = 0x01101111;
+    miscRegs[MISCREG_ID_ISAR0] = 0x02101111;
     miscRegs[MISCREG_ID_ISAR1] = 0x02112111;
     miscRegs[MISCREG_ID_ISAR2] = 0x21232141;
     miscRegs[MISCREG_ID_ISAR3] = 0x01112131;
@@ -184,7 +189,9 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
 
     switch (misc_reg) {
       case MISCREG_MPIDR:
-        return tc->cpuId();
+
+        return 0x80000000 | // multiprocessor extensions available
+               tc->cpuId();
         break;
       case MISCREG_ID_MMFR0:
         return 0x03; // VMSAv7 support
@@ -208,8 +215,7 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
              "config registers and jumping to ThumbEE vectors\n");
         return 0x0031; // !ThumbEE | !Jazelle | Thumb | ARM
       case MISCREG_ID_PFR1:
-        warn("reading unimplmented register ID_PFR1");
-        return 0;
+        return 0x00001; // !Timer | !Virti | !M Profile | !TrustZone | ARMv4
       case MISCREG_CTR:
         return 0x86468006; // V7, 64 byte cache line, load/exclusive is exact
       case MISCREG_ACTLR:
@@ -227,6 +233,21 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
         return readMiscRegNoEffect(MISCREG_FPSCR) & ~FpscrQcMask;
       case MISCREG_FPSCR_EXC:
         return readMiscRegNoEffect(MISCREG_FPSCR) & ~FpscrExcMask;
+      case MISCREG_L2CTLR:
+        {
+            // mostly unimplemented, just set NumCPUs field from sim and return
+            L2CTLR l2ctlr = 0;
+            // b00:1CPU to b11:4CPUs
+            l2ctlr.numCPUs = tc->getSystemPtr()->numContexts() - 1;
+            return l2ctlr;
+        }
+      case MISCREG_DBGDIDR:
+        /* For now just implement the version number.
+         * Return 0 as we don't support debug architecture yet.
+         */
+         return 0;
+      case MISCREG_DBGDSCR_INT:
+        return 0;
     }
     return readMiscRegNoEffect(misc_reg);
 }
@@ -273,7 +294,11 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
         PCState pc = tc->pcState();
         pc.nextThumb(cpsr.t);
         pc.nextJazelle(cpsr.j);
+#if USE_CHECKER
+        tc->pcStateNoRecord(pc);
+#else
         tc->pcState(pc);
+#endif //USE_CHECKER
     } else if (misc_reg >= MISCREG_CP15_UNIMP_START &&
         misc_reg < MISCREG_CP15_END) {
         panic("Unimplemented CP15 register %s wrote with %#x.\n",
@@ -360,6 +385,31 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
                 miscRegs[MISCREG_SCTLR] = (MiscReg)new_sctlr;
                 tc->getITBPtr()->invalidateMiscReg();
                 tc->getDTBPtr()->invalidateMiscReg();
+
+                // Check if all CPUs are booted with caches enabled
+                // so we can stop enforcing coherency of some kernel
+                // structures manually.
+                sys = tc->getSystemPtr();
+                for (x = 0; x < sys->numContexts(); x++) {
+                    oc = sys->getThreadContext(x);
+                    SCTLR other_sctlr = oc->readMiscRegNoEffect(MISCREG_SCTLR);
+                    if (!other_sctlr.c && oc->status() != ThreadContext::Halted)
+                        return;
+                }
+
+                for (x = 0; x < sys->numContexts(); x++) {
+                    oc = sys->getThreadContext(x);
+                    oc->getDTBPtr()->allCpusCaching();
+                    oc->getITBPtr()->allCpusCaching();
+#if USE_CHECKER
+                    CheckerCPU *checker =
+                        dynamic_cast<CheckerCPU*>(oc->getCheckerCpuPtr());
+                    if (checker) {
+                        checker->getDTBPtr()->allCpusCaching();
+                        checker->getITBPtr()->allCpusCaching();
+                    }
+#endif
+                }
                 return;
             }
           case MISCREG_TLBTR:
@@ -376,6 +426,14 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
                 assert(oc->getITBPtr() && oc->getDTBPtr());
                 oc->getITBPtr()->flushAll();
                 oc->getDTBPtr()->flushAll();
+#if USE_CHECKER
+                CheckerCPU *checker =
+                    dynamic_cast<CheckerCPU*>(oc->getCheckerCpuPtr());
+                if (checker) {
+                    checker->getITBPtr()->flushAll();
+                    checker->getDTBPtr()->flushAll();
+                }
+#endif
             }
             return;
           case MISCREG_ITLBIALL:
@@ -394,6 +452,16 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
                         bits(newVal, 7,0));
                 oc->getDTBPtr()->flushMvaAsid(mbits(newVal, 31, 12),
                         bits(newVal, 7,0));
+#if USE_CHECKER
+                CheckerCPU *checker =
+                    dynamic_cast<CheckerCPU*>(oc->getCheckerCpuPtr());
+                if (checker) {
+                    checker->getITBPtr()->flushMvaAsid(mbits(newVal, 31, 12),
+                            bits(newVal, 7,0));
+                    checker->getDTBPtr()->flushMvaAsid(mbits(newVal, 31, 12),
+                            bits(newVal, 7,0));
+                }
+#endif
             }
             return;
           case MISCREG_TLBIASIDIS:
@@ -404,6 +472,14 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
                 assert(oc->getITBPtr() && oc->getDTBPtr());
                 oc->getITBPtr()->flushAsid(bits(newVal, 7,0));
                 oc->getDTBPtr()->flushAsid(bits(newVal, 7,0));
+#if USE_CHECKER
+                CheckerCPU *checker =
+                    dynamic_cast<CheckerCPU*>(oc->getCheckerCpuPtr());
+                if (checker) {
+                    checker->getITBPtr()->flushAsid(bits(newVal, 7,0));
+                    checker->getDTBPtr()->flushAsid(bits(newVal, 7,0));
+                }
+#endif
             }
             return;
           case MISCREG_TLBIMVAAIS:
@@ -414,6 +490,14 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
                 assert(oc->getITBPtr() && oc->getDTBPtr());
                 oc->getITBPtr()->flushMva(mbits(newVal, 31,12));
                 oc->getDTBPtr()->flushMva(mbits(newVal, 31,12));
+#if USE_CHECKER
+                CheckerCPU *checker =
+                    dynamic_cast<CheckerCPU*>(oc->getCheckerCpuPtr());
+                if (checker) {
+                    checker->getITBPtr()->flushMva(mbits(newVal, 31,12));
+                    checker->getDTBPtr()->flushMva(mbits(newVal, 31,12));
+                }
+#endif
             }
             return;
           case MISCREG_ITLBIMVA:
@@ -485,7 +569,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
                       panic("Security Extensions not implemented!");
               }
               warn("Translating via MISCREG in atomic mode! Fix Me!\n");
-              req->setVirt(0, val, 1, flags, tc->pcState().pc());
+              req->setVirt(0, val, 1, flags, tc->pcState().pc(),
+                      Request::funcMasterId);
               fault = tc->getDTBPtr()->translateAtomic(req, tc, mode);
               if (fault == NoFault) {
                   miscRegs[MISCREG_PAR] =
@@ -520,6 +605,9 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
             // see all of the registers for the copy.
             updateRegMap(val);
             return;
+          case MISCREG_L2CTLR:
+            warn("miscreg L2CTLR (%s) written with %#x. ignored...\n",
+                 miscRegName[misc_reg], uint32_t(val));
         }
     }
     setMiscRegNoEffect(misc_reg, newVal);