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.
This commit is contained in:
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user