ARM: Fix MPIDR and MIDR register implementation.
authorChander Sudanthi <chander.sudanthi@arm.com>
Tue, 5 Jun 2012 05:23:10 +0000 (01:23 -0400)
committerChander Sudanthi <chander.sudanthi@arm.com>
Tue, 5 Jun 2012 05:23:10 +0000 (01:23 -0400)
This change allows designating a system as MP capable or not as some
bootloaders/kernels care that it's set right. You can have a single
processor MP capable system, but you can't have a multi-processor
UP only system. This change also fixes the initialization of the MIDR
register.

src/arch/arm/ArmSystem.py
src/arch/arm/isa.cc
src/arch/arm/system.cc
src/arch/arm/system.hh

index a86fc88221f64d9e1d4738c3886f7b2014701a8f..54bf99e9037742656633eaa41e3ab56efbdf3fe4 100644 (file)
@@ -55,6 +55,7 @@ class ArmSystem(System):
     # 0xc00 Primary part number ("c" or higher implies ARM v7)
     # 0x0 Revision
     midr_regval = Param.UInt32(0x350fc000, "MIDR value")
+    multi_proc = Param.Bool(True, "Multiprocessor system?")
     boot_loader = Param.String("", "File that contains the boot loader code if any")
     gic_cpu_addr = Param.Addr(0, "Addres of the GIC CPU interface")
     flags_addr = Param.Addr(0, "Address of the flags register for MP booting")
index a452991aab085c8eaa639a5934291785ae920cc0..2a5fbd2f00a032e994cd565e68b954044db58ded 100644 (file)
@@ -39,6 +39,7 @@
  */
 
 #include "arch/arm/isa.hh"
+#include "arch/arm/system.hh"
 #include "cpu/checker/cpu.hh"
 #include "debug/Arm.hh"
 #include "debug/MiscRegs.hh"
@@ -72,7 +73,7 @@ ISA::clear()
     miscRegs[MISCREG_SCTLR] = sctlr;
     miscRegs[MISCREG_SCTLR_RST] = sctlr_rst;
 
-    // Preserve MIDR accross reset
+    // Preserve MIDR across reset
     miscRegs[MISCREG_MIDR] = midr;
 
     /* Start with an event in the mailbox */
@@ -102,8 +103,6 @@ ISA::clear()
     mvfr1.vfpHalfPrecision = 1;
     miscRegs[MISCREG_MVFR1] = mvfr1;
 
-    miscRegs[MISCREG_MPIDR] = 0;
-
     // Reset values of PRRR and NMRR are implementation dependent
 
     miscRegs[MISCREG_PRRR] =
@@ -172,6 +171,8 @@ ISA::readMiscRegNoEffect(int misc_reg)
 MiscReg
 ISA::readMiscReg(int misc_reg, ThreadContext *tc)
 {
+    ArmSystem *arm_sys;
+
     if (misc_reg == MISCREG_CPSR) {
         CPSR cpsr = miscRegs[misc_reg];
         PCState pc = tc->pcState();
@@ -185,9 +186,17 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
 
     switch (misc_reg) {
       case MISCREG_MPIDR:
+        arm_sys = dynamic_cast<ArmSystem*>(tc->getSystemPtr());
+        assert(arm_sys);
 
-        return 0x80000000 | // multiprocessor extensions available
-               tc->cpuId();
+        if (arm_sys->multiProc) {
+            return 0x80000000 | // multiprocessor extensions available
+                   tc->cpuId();
+        } else {
+            return 0x80000000 |  // multiprocessor extensions available
+                   0x40000000 |  // in up system
+                   tc->cpuId();
+        }
         break;
       case MISCREG_ID_MMFR0:
         return 0x03; // VMSAv7 support
index f6c4ad783447414beca104e6f27032fddecdec5e..380676bbb62adc1ba874433b5ec22c2b41132ae1 100644 (file)
@@ -53,7 +53,7 @@ using namespace std;
 using namespace Linux;
 
 ArmSystem::ArmSystem(Params *p)
-    : System(p), bootldr(NULL)
+    : System(p), bootldr(NULL), multiProc(p->multi_proc)
 {
     if (p->boot_loader != "") {
         bootldr = createObjectFile(p->boot_loader);
@@ -107,10 +107,8 @@ ArmSystem::initState()
     }
 
     for (int i = 0; i < threadContexts.size(); i++) {
-        if (p->midr_regval) {
-            threadContexts[i]->setMiscReg(ArmISA::MISCREG_MIDR,
-                                          p->midr_regval);
-        }
+        threadContexts[i]->setMiscReg(ArmISA::MISCREG_MIDR,
+                                      p->midr_regval);
     }
 }
 
index 7cf36fd6ce0931140f01e9b04370ee138d5d444b..3135c5da1c1af12b1d17c3005b23e7aeb0b61fb1 100644 (file)
@@ -98,6 +98,9 @@ class ArmSystem : public System
             return addr & ~1;
         return addr;
     }
+
+    /** true if this a multiprocessor system */
+    bool multiProc;
 };
 
 #endif