CPU: Unify initMemProxies across CPUs and simulation modes
authorAndreas Hansson <andreas.hansson@arm.com>
Fri, 30 Mar 2012 13:38:35 +0000 (09:38 -0400)
committerAndreas Hansson <andreas.hansson@arm.com>
Fri, 30 Mar 2012 13:38:35 +0000 (09:38 -0400)
This patch unifies where initMemProxies is called, in the init()
method of each BaseCPU subclass, before TheISA::initCPU is
called. Moreover, it also ensures that initMemProxies is called in
both full-system and syscall-emulation mode, thus unifying also across
the modes. An additional check is added in the ThreadState to ensure
that initMemProxies is only called once.

src/cpu/inorder/cpu.cc
src/cpu/o3/cpu.cc
src/cpu/simple/atomic.cc
src/cpu/simple/timing.cc
src/cpu/thread_state.cc
src/cpu/thread_state.hh

index ac7a1b209de0b974d974d465c6a70178b599feef..8dab82d7184bdf02b7847ae9c36c4937ef7deabd 100644 (file)
@@ -787,21 +787,20 @@ InOrderCPU::tick()
 void
 InOrderCPU::init()
 {
-    if (!deferRegistration) {
-        registerThreadContexts();
-    }
+    BaseCPU::init();
 
-    // Set inSyscall so that the CPU doesn't squash when initially
-    // setting up registers.
-    for (ThreadID tid = 0; tid < numThreads; ++tid)
+    for (ThreadID tid = 0; tid < numThreads; ++tid) {
+        // Set inSyscall so that the CPU doesn't squash when initially
+        // setting up registers.
         thread[tid]->inSyscall = true;
+        // Initialise the ThreadContext's memory proxies
+        thread[tid]->initMemProxies(thread[tid]->getTC());
+    }
 
     if (FullSystem) {
         for (ThreadID tid = 0; tid < numThreads; tid++) {
             ThreadContext *src_tc = threadContexts[tid];
             TheISA::initCPU(src_tc, src_tc->contextId());
-            // Initialise the ThreadContext's memory proxies
-            thread[tid]->initMemProxies(thread[tid]->getTC());
         }
     }
 
index f68b500ea68bf6ebf1c1d9801f2bd161afab0575..bfc9438d309a8ff3811867040ce0231ba0d9c1be 100644 (file)
@@ -639,10 +639,13 @@ FullO3CPU<Impl>::init()
 {
     BaseCPU::init();
 
-    // Set inSyscall so that the CPU doesn't squash when initially
-    // setting up registers.
-    for (ThreadID tid = 0; tid < numThreads; ++tid)
+    for (ThreadID tid = 0; tid < numThreads; ++tid) {
+        // Set inSyscall so that the CPU doesn't squash when initially
+        // setting up registers.
         thread[tid]->inSyscall = true;
+        // Initialise the ThreadContext's memory proxies
+        thread[tid]->initMemProxies(thread[tid]->getTC());
+    }
 
     // this CPU could still be unconnected if we are restoring from a
     // checkpoint and this CPU is to be switched in, thus we can only
@@ -655,8 +658,6 @@ FullO3CPU<Impl>::init()
         for (ThreadID tid = 0; tid < numThreads; tid++) {
             ThreadContext *src_tc = threadContexts[tid];
             TheISA::initCPU(src_tc, src_tc->contextId());
-            // Initialise the ThreadContext's memory proxies
-            thread[tid]->initMemProxies(thread[tid]->getTC());
         }
     }
 
index cc2c3576f31cca2afd95a8c645de6cbba9e77e3a..e5b3bd67da15006f032fa4eebdabb5a42539086f 100644 (file)
@@ -80,6 +80,10 @@ void
 AtomicSimpleCPU::init()
 {
     BaseCPU::init();
+
+    // Initialise the ThreadContext's memory proxies
+    tcBase()->initMemProxies(tcBase());
+
     if (FullSystem) {
         ThreadID size = threadContexts.size();
         for (ThreadID i = 0; i < size; ++i) {
@@ -89,9 +93,6 @@ AtomicSimpleCPU::init()
         }
     }
 
-    // Initialise the ThreadContext's memory proxies
-    tcBase()->initMemProxies(tcBase());
-
     if (hasPhysMemPort) {
         AddrRangeList pmAddrList = physmemPort.getPeer()->getAddrRanges();
         physMemAddr = *pmAddrList.begin();
index 3d1fe081d99029e151e81ad833c3a83a024b16da..f661756dab4616c8097da2417a4e1c3f83286854 100644 (file)
@@ -64,6 +64,10 @@ void
 TimingSimpleCPU::init()
 {
     BaseCPU::init();
+
+    // Initialise the ThreadContext's memory proxies
+    tcBase()->initMemProxies(tcBase());
+
     if (FullSystem) {
         for (int i = 0; i < threadContexts.size(); ++i) {
             ThreadContext *tc = threadContexts[i];
@@ -71,9 +75,6 @@ TimingSimpleCPU::init()
             TheISA::initCPU(tc, _cpuId);
         }
     }
-
-    // Initialise the ThreadContext's memory proxies
-    tcBase()->initMemProxies(tcBase());
 }
 
 void
index 3d58b4da4f3fa71e485315baa85db7c57ea08f4a..eda62dad17ed14cc3715e1d89acdd164b638c962 100644 (file)
@@ -101,17 +101,25 @@ ThreadState::unserialize(Checkpoint *cp, const std::string &section)
 void
 ThreadState::initMemProxies(ThreadContext *tc)
 {
-    // Note that this only refers to the port on the CPU side and can
-    // safely be done at init() time even if the CPU is not connected
-    // (i.e. due to restoring from a checkpoint and later switching
-    // in.
-    if (physProxy == NULL)
-        // this cannot be done in the constructor as the thread state
+    // The port proxies only refer to the data port on the CPU side
+    // and can safely be done at init() time even if the CPU is not
+    // connected, i.e. when restoring from a checkpoint and later
+    // switching the CPU in.
+    if (FullSystem) {
+        assert(physProxy == NULL);
+        // This cannot be done in the constructor as the thread state
         // itself is created in the base cpu constructor and the
-        // getPort is a virtual function at the moment
+        // getDataPort is a virtual function
         physProxy = new PortProxy(baseCpu->getDataPort());
-    if (virtProxy == NULL)
+
+        assert(virtProxy == NULL);
         virtProxy = new FSTranslatingPortProxy(tc);
+    } else {
+        assert(proxy == NULL);
+        proxy = new SETranslatingPortProxy(baseCpu->getDataPort(),
+                                           process,
+                                           SETranslatingPortProxy::NextPage);
+    }
 }
 
 void
@@ -127,13 +135,3 @@ ThreadState::profileSample()
     if (profile)
         profile->sample(profileNode, profilePC);
 }
-
-SETranslatingPortProxy &
-ThreadState::getMemProxy()
-{
-    if (proxy == NULL)
-        proxy = new SETranslatingPortProxy(baseCpu->getDataPort(),
-                                           process,
-                                           SETranslatingPortProxy::NextPage);
-    return *proxy;
-}
index 3f58e4f146595eb06cab65b12319e172e7c537a4..995a870f59fbf56c1af3ebea1758a1eb98fee869 100644 (file)
@@ -85,7 +85,7 @@ struct ThreadState {
      * Initialise the physical and virtual port proxies and tie them to
      * the data port of the CPU.
      *
-     * tc ThreadContext for the virtual-to-physical translation
+     * @param tc ThreadContext for the virtual-to-physical translation
      */
     void initMemProxies(ThreadContext *tc);
 
@@ -105,7 +105,7 @@ struct ThreadState {
 
     Process *getProcessPtr() { return process; }
 
-    SETranslatingPortProxy &getMemProxy();
+    SETranslatingPortProxy &getMemProxy() { return *proxy; }
 
     /** Reads the number of instructions functionally executed and
      * committed.