diff -r fd01ef3f4a58 -r 1a12feac8b2a src/cpu/base.hh --- a/src/cpu/base.hh Mon Jan 07 14:29:09 2013 -0500 +++ b/src/cpu/base.hh Mon Jan 07 14:29:24 2013 -0500 @@ -342,6 +342,17 @@ bool switchedOut() const { return _switchedOut; } /** + * Verify that the system is in a memory mode supported by the + * CPU. + * + * Implementations are expected to query the system for the + * current memory mode and ensure that it is what the CPU model + * expects. If the check fails, the implementation should + * terminate the simulation using fatal(). + */ + virtual void verifyMemoryMode() const { }; + + /** * Number of threads we're actually simulating (<= SMT_MAX_THREADS). * This is a constant for the duration of the simulation. */ diff -r fd01ef3f4a58 -r 1a12feac8b2a src/cpu/base.cc --- a/src/cpu/base.cc Mon Jan 07 14:29:09 2013 -0500 +++ b/src/cpu/base.cc Mon Jan 07 14:29:24 2013 -0500 @@ -254,8 +254,11 @@ void BaseCPU::init() { - if (!params()->switched_out) + if (!params()->switched_out) { registerThreadContexts(); + + verifyMemoryMode(); + } } void diff -r fd01ef3f4a58 -r 1a12feac8b2a src/cpu/inorder/cpu.hh --- a/src/cpu/inorder/cpu.hh Mon Jan 07 14:29:09 2013 -0500 +++ b/src/cpu/inorder/cpu.hh Mon Jan 07 14:29:24 2013 -0500 @@ -109,6 +109,8 @@ /* Destructor */ ~InOrderCPU(); + void verifyMemoryMode() const; + /** Return a reference to the data port. */ virtual CpuPort &getDataPort() { return dataPort; } diff -r fd01ef3f4a58 -r 1a12feac8b2a src/cpu/inorder/cpu.cc --- a/src/cpu/inorder/cpu.cc Mon Jan 07 14:29:09 2013 -0500 +++ b/src/cpu/inorder/cpu.cc Mon Jan 07 14:29:24 2013 -0500 @@ -786,12 +786,6 @@ { BaseCPU::init(); - if (!params()->switched_out && - system->getMemoryMode() != Enums::timing) { - fatal("The in-order CPU requires the memory system to be in " - "'timing' mode.\n"); - } - for (ThreadID tid = 0; tid < numThreads; ++tid) { // Set noSquashFromTC so that the CPU doesn't squash when initially // setting up registers. @@ -815,6 +809,15 @@ resPool->init(); } +void +InOrderCPU::verifyMemoryMode() const +{ + if (system->getMemoryMode() != Enums::timing) { + fatal("The in-order CPU requires the memory system to be in " + "'timing' mode.\n"); + } +} + Fault InOrderCPU::hwrei(ThreadID tid) { diff -r fd01ef3f4a58 -r 1a12feac8b2a src/cpu/o3/cpu.hh --- a/src/cpu/o3/cpu.hh Mon Jan 07 14:29:09 2013 -0500 +++ b/src/cpu/o3/cpu.hh Mon Jan 07 14:29:24 2013 -0500 @@ -479,6 +479,8 @@ /** Takes over from another CPU. */ virtual void takeOverFrom(BaseCPU *oldCPU); + void verifyMemoryMode() const; + /** Get the current instruction sequence number, and increment it. */ InstSeqNum getAndIncrementInstSeq() { return globalSeqNum++; } diff -r fd01ef3f4a58 -r 1a12feac8b2a src/cpu/o3/cpu.cc --- a/src/cpu/o3/cpu.cc Mon Jan 07 14:29:09 2013 -0500 +++ b/src/cpu/o3/cpu.cc Mon Jan 07 14:29:24 2013 -0500 @@ -646,12 +646,6 @@ { BaseCPU::init(); - if (!params()->switched_out && - system->getMemoryMode() != Enums::timing) { - fatal("The O3 CPU requires the memory system to be in " - "'timing' mode.\n"); - } - for (ThreadID tid = 0; tid < numThreads; ++tid) { // Set noSquashFromTC so that the CPU doesn't squash when initially // setting up registers. @@ -1259,11 +1253,7 @@ return; DPRINTF(Drain, "Resuming...\n"); - - if (system->getMemoryMode() != Enums::timing) { - fatal("The O3 CPU requires the memory system to be in " - "'timing' mode.\n"); - } + verifyMemoryMode(); fetch.drainResume(); commit.drainResume(); @@ -1320,6 +1310,16 @@ } template +void +FullO3CPU::verifyMemoryMode() const +{ + if (system->getMemoryMode() != Enums::timing) { + fatal("The O3 CPU requires the memory system to be in " + "'timing' mode.\n"); + } +} + +template TheISA::MiscReg FullO3CPU::readMiscRegNoEffect(int misc_reg, ThreadID tid) { diff -r fd01ef3f4a58 -r 1a12feac8b2a src/cpu/simple/atomic.hh --- a/src/cpu/simple/atomic.hh Mon Jan 07 14:29:09 2013 -0500 +++ b/src/cpu/simple/atomic.hh Mon Jan 07 14:29:24 2013 -0500 @@ -164,6 +164,8 @@ void switchOut(); void takeOverFrom(BaseCPU *oldCPU); + void verifyMemoryMode() const; + virtual void activateContext(ThreadID thread_num, Cycles delay); virtual void suspendContext(ThreadID thread_num); diff -r fd01ef3f4a58 -r 1a12feac8b2a src/cpu/simple/atomic.cc --- a/src/cpu/simple/atomic.cc Mon Jan 07 14:29:09 2013 -0500 +++ b/src/cpu/simple/atomic.cc Mon Jan 07 14:29:24 2013 -0500 @@ -84,12 +84,6 @@ { BaseCPU::init(); - if (!params()->switched_out && - system->getMemoryMode() != Enums::atomic) { - fatal("The atomic CPU requires the memory system to be in " - "'atomic' mode.\n"); - } - // Initialise the ThreadContext's memory proxies tcBase()->initMemProxies(tcBase()); @@ -157,10 +151,7 @@ return; DPRINTF(SimpleCPU, "Resume\n"); - if (system->getMemoryMode() != Enums::atomic) { - fatal("The atomic CPU requires the memory system to be in " - "'atomic' mode.\n"); - } + verifyMemoryMode(); assert(!threadContexts.empty()); if (threadContexts.size() > 1) @@ -218,6 +209,14 @@ data_write_req.setThreadContext(_cpuId, 0); // Add thread ID here too } +void +AtomicSimpleCPU::verifyMemoryMode() const +{ + if (system->getMemoryMode() != Enums::atomic) { + fatal("The atomic CPU requires the memory system to be in " + "'atomic' mode.\n"); + } +} void AtomicSimpleCPU::activateContext(ThreadID thread_num, Cycles delay) diff -r fd01ef3f4a58 -r 1a12feac8b2a src/cpu/simple/timing.hh --- a/src/cpu/simple/timing.hh Mon Jan 07 14:29:09 2013 -0500 +++ b/src/cpu/simple/timing.hh Mon Jan 07 14:29:24 2013 -0500 @@ -261,6 +261,8 @@ void switchOut(); void takeOverFrom(BaseCPU *oldCPU); + void verifyMemoryMode() const; + virtual void activateContext(ThreadID thread_num, Cycles delay); virtual void suspendContext(ThreadID thread_num); diff -r fd01ef3f4a58 -r 1a12feac8b2a src/cpu/simple/timing.cc --- a/src/cpu/simple/timing.cc Mon Jan 07 14:29:09 2013 -0500 +++ b/src/cpu/simple/timing.cc Mon Jan 07 14:29:24 2013 -0500 @@ -66,12 +66,6 @@ { BaseCPU::init(); - if (!params()->switched_out && - system->getMemoryMode() != Enums::timing) { - fatal("The timing CPU requires the memory system to be in " - "'timing' mode.\n"); - } - // Initialise the ThreadContext's memory proxies tcBase()->initMemProxies(tcBase()); @@ -141,10 +135,7 @@ return; DPRINTF(SimpleCPU, "Resume\n"); - if (system->getMemoryMode() != Enums::timing) { - fatal("The timing CPU requires the memory system to be in " - "'timing' mode.\n"); - } + verifyMemoryMode(); assert(!threadContexts.empty()); if (threadContexts.size() > 1) @@ -197,6 +188,14 @@ previousCycle = curCycle(); } +void +TimingSimpleCPU::verifyMemoryMode() const +{ + if (system->getMemoryMode() != Enums::timing) { + fatal("The timing CPU requires the memory system to be in " + "'timing' mode.\n"); + } +} void TimingSimpleCPU::activateContext(ThreadID thread_num, Cycles delay)