cpu, arm: Allow the specification of a socket field
authorAkash Bagdia <akash.bagdia@arm.com>
Fri, 9 May 2014 22:58:46 +0000 (18:58 -0400)
committerAkash Bagdia <akash.bagdia@arm.com>
Fri, 9 May 2014 22:58:46 +0000 (18:58 -0400)
Allow the specification of a socket ID for every core that is reflected in the
MPIDR field in ARM systems.  This allows studying multi-socket / cluster
systems with ARM CPUs.

src/arch/arm/utility.cc
src/cpu/BaseCPU.py
src/cpu/base.cc
src/cpu/base.hh
src/cpu/base_dyn_inst.hh
src/cpu/checker/thread_context.hh
src/cpu/inorder/thread_context.hh
src/cpu/o3/thread_context.hh
src/cpu/thread_context.hh
src/cpu/thread_state.hh

index d5b062621144104de182006f2a224a578c1ced58..ae84391e99df480532a202d73646d892ff6d3ba3 100644 (file)
@@ -195,13 +195,26 @@ longDescFormatInUse(ThreadContext *tc)
 uint32_t
 getMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
 {
+    // Multiprocessor Affinity Register MPIDR from Cortex(tm)-A15 Technical
+    // Reference Manual
+    //
+    // bit   31 - Multi-processor extensions available
+    // bit   30 - Uni-processor system
+    // bit   24 - Multi-threaded cores
+    // bit 11-8 - Cluster ID
+    // bit  1-0 - CPU ID
+    //
+    // We deliberately extend both the Cluster ID and CPU ID fields to allow
+    // for simulation of larger systems
+    assert((0 <= tc->cpuId()) && (tc->cpuId() < 256));
+    assert((0 <= tc->socketId()) && (tc->socketId() < 65536));
     if (arm_sys->multiProc) {
        return 0x80000000 | // multiprocessor extensions available
-              tc->cpuId();
+              tc->cpuId() | tc->socketId() << 8;
     } else {
        return 0x80000000 |  // multiprocessor extensions available
               0x40000000 |  // in up system
-              tc->cpuId();
+              tc->cpuId() | tc->socketId() << 8;
     }
 }
 
index 652af0b80c3e1e6a5d77c7a120e5277f41beba27..b7f0b208909b22f690dede7bdaa5b734ae071fb8 100644 (file)
@@ -128,6 +128,7 @@ class BaseCPU(MemObject):
 
     system = Param.System(Parent.any, "system object")
     cpu_id = Param.Int(-1, "CPU identifier")
+    socket_id = Param.Unsigned(0, "Physical Socket identifier")
     numThreads = Param.Unsigned(1, "number of HW thread contexts")
 
     function_trace = Param.Bool(False, "Enable function trace")
index 3078472fd1fca9b4a7d95c2223d73ad89a512842..9057856316860cd62ac0a900b9570255585e8f35 100644 (file)
@@ -117,7 +117,7 @@ CPUProgressEvent::description() const
 }
 
 BaseCPU::BaseCPU(Params *p, bool is_checker)
-    : MemObject(p), instCnt(0), _cpuId(p->cpu_id),
+    : MemObject(p), instCnt(0), _cpuId(p->cpu_id), _socketId(p->socket_id),
       _instMasterId(p->system->getMasterId(name() + ".inst")),
       _dataMasterId(p->system->getMasterId(name() + ".data")),
       _taskId(ContextSwitchTaskId::Unknown), _pid(Request::invldPid),
@@ -133,7 +133,8 @@ BaseCPU::BaseCPU(Params *p, bool is_checker)
     // add self to global list of CPUs
     cpuList.push_back(this);
 
-    DPRINTF(SyscallVerbose, "Constructing CPU with id %d\n", _cpuId);
+    DPRINTF(SyscallVerbose, "Constructing CPU with id %d, socket id %d\n",
+                _cpuId, _socketId);
 
     if (numThreads > maxThreadsPerCPU)
         maxThreadsPerCPU = numThreads;
index 321b785a241fe20e9d4cae1e4bb15370f0e99ebd..cc3f861cca93583fd66f19d7f82597204bff1b52 100644 (file)
@@ -101,6 +101,13 @@ class BaseCPU : public MemObject
     // therefore no setCpuId() method is provided
     int _cpuId;
 
+    /** Each cpu will have a socket ID that corresponds to its physical location
+     * in the system. This is usually used to bucket cpu cores under single DVFS
+     * domain. This information may also be required by the OS to identify the
+     * cpu core grouping (as in the case of ARM via MPIDR register)
+     */
+    const uint32_t _socketId;
+
     /** instruction side request id that must be placed in all requests */
     MasterID _instMasterId;
 
@@ -145,6 +152,9 @@ class BaseCPU : public MemObject
     /** Reads this CPU's ID. */
     int cpuId() const { return _cpuId; }
 
+    /** Reads this CPU's Socket ID. */
+    uint32_t socketId() const { return _socketId; }
+
     /** Reads this CPU's unique data requestor ID */
     MasterID dataMasterId() { return _dataMasterId; }
     /** Reads this CPU's unique instruction requestor ID */
index cafe51fd700e88351c564d77a6365b851f96c898..08e16d330495a67540752079d4857d6ed49017d8 100644 (file)
@@ -456,6 +456,9 @@ class BaseDynInst : public RefCounted
     /** Read this CPU's ID. */
     int cpuId() const { return cpu->cpuId(); }
 
+    /** Read this CPU's Socket ID. */
+    uint32_t socketId() const { return cpu->socketId(); }
+
     /** Read this CPU's data requestor ID */
     MasterID masterId() const { return cpu->dataMasterId(); }
 
index ddd07ea584b94d9641a544389ffcc84273531488..f868f4cbb5c6fa108259f05ba3c9f578fae73096 100644 (file)
@@ -92,6 +92,8 @@ class CheckerThreadContext : public ThreadContext
 
     BaseCPU *getCpuPtr() { return actualTC->getCpuPtr(); }
 
+    uint32_t socketId() const { return actualTC->socketId(); }
+
     int cpuId() const { return actualTC->cpuId(); }
 
     int contextId() const { return actualTC->contextId(); }
index 96ec063c8b58dbc5ddcf693333b6b3012d1bbc3d..2e525eb2acc58216a08b1ddec6ce6aa281e75cc7 100644 (file)
@@ -113,6 +113,9 @@ class InOrderThreadContext : public ThreadContext
     /** Reads this CPU's ID. */
     int cpuId() const { return cpu->cpuId(); }
 
+    /** Reads this CPU's Socket ID. */
+    uint32_t socketId() const { return cpu->socketId(); }
+
     int contextId() const { return thread->contextId(); }
 
     void setContextId(int id) { thread->setContextId(id); }
index ef72fdb0365cddb15b8b577eb1a5a5379340884b..a00d2ffa311ebe2d7bc35262931a3b863d7c7a80 100755 (executable)
@@ -98,6 +98,9 @@ class O3ThreadContext : public ThreadContext
     /** Reads this CPU's ID. */
     virtual int cpuId() const { return cpu->cpuId(); }
 
+    /** Reads this CPU's Socket ID. */
+    virtual uint32_t socketId() const { return cpu->socketId(); }
+
     virtual int contextId() const { return thread->contextId(); }
 
     virtual void setContextId(int id) { thread->setContextId(id); }
index 4b88b4a0bfbf3eeaf75ab6d5f57f5593862f3eb7..40150ac05526e5ab092ac12ccb1144883b7bbcdc 100644 (file)
@@ -123,6 +123,8 @@ class ThreadContext
 
     virtual int cpuId() const = 0;
 
+    virtual uint32_t socketId() const = 0;
+
     virtual int threadId() const = 0;
 
     virtual void setThreadId(int id) = 0;
@@ -323,6 +325,8 @@ class ProxyThreadContext : public ThreadContext
 
     int cpuId() const { return actualTC->cpuId(); }
 
+    uint32_t socketId() const { return actualTC->socketId(); }
+
     int threadId() const { return actualTC->threadId(); }
 
     void setThreadId(int id) { actualTC->setThreadId(id); }
index 775f6fbd4d3780e02a7ae34864fbd30f1632e872..f937964ffa3b052d9fa9e81d0823b9e30b066185 100644 (file)
@@ -69,6 +69,8 @@ struct ThreadState {
 
     int cpuId() const { return baseCpu->cpuId(); }
 
+    uint32_t socketId() const { return baseCpu->socketId(); }
+
     int contextId() const { return _contextId; }
 
     void setContextId(int id) { _contextId = id; }