From a14013af3a9e04d68985aea7bcff6c1e70bdbb82 Mon Sep 17 00:00:00 2001 From: Andreas Hansson Date: Fri, 30 Mar 2012 09:38:35 -0400 Subject: [PATCH] CPU: Unify initMemProxies across CPUs and simulation modes 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 | 15 +++++++-------- src/cpu/o3/cpu.cc | 11 ++++++----- src/cpu/simple/atomic.cc | 7 ++++--- src/cpu/simple/timing.cc | 7 ++++--- src/cpu/thread_state.cc | 34 ++++++++++++++++------------------ src/cpu/thread_state.hh | 4 ++-- 6 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index ac7a1b209..8dab82d71 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -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()); } } diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index f68b500ea..bfc9438d3 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -639,10 +639,13 @@ FullO3CPU::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::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()); } } diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index cc2c3576f..e5b3bd67d 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -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(); diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 3d1fe081d..f661756da 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -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 diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc index 3d58b4da4..eda62dad1 100644 --- a/src/cpu/thread_state.cc +++ b/src/cpu/thread_state.cc @@ -101,17 +101,25 @@ ThreadState::unserialize(Checkpoint *cp, const std::string §ion) 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; -} diff --git a/src/cpu/thread_state.hh b/src/cpu/thread_state.hh index 3f58e4f14..995a870f5 100644 --- a/src/cpu/thread_state.hh +++ b/src/cpu/thread_state.hh @@ -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. -- 2.30.2