summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Sandberg <Andreas.Sandberg@ARM.com>2013-02-15 17:40:08 -0500
committerAndreas Sandberg <Andreas.Sandberg@ARM.com>2013-02-15 17:40:08 -0500
commit1eec115c31395e2819c073a1859d75eb5933dac2 (patch)
tree503552557b8a5504bbb9aa9a3515b0bb398a97fc
parent1c7aa665bfc678c33cc05829acc52aebb1d2612c (diff)
downloadgem5-1eec115c31395e2819c073a1859d75eb5933dac2.tar.xz
cpu: Refactor memory system checks
CPUs need to test that the memory system is in the right mode in two places, when the CPU is initialized (unless it's switched out) and on a drainResume(). This led to some code duplication in the CPU models. This changeset introduces the verifyMemoryMode() method which is called by BaseCPU::init() if the CPU isn't switched out. The individual CPU models are responsible for calling this method when resuming from a drain as this code is CPU model specific.
-rw-r--r--src/cpu/base.cc5
-rw-r--r--src/cpu/base.hh11
-rw-r--r--src/cpu/inorder/cpu.cc15
-rw-r--r--src/cpu/inorder/cpu.hh2
-rw-r--r--src/cpu/o3/cpu.cc22
-rw-r--r--src/cpu/o3/cpu.hh2
-rw-r--r--src/cpu/simple/atomic.cc19
-rw-r--r--src/cpu/simple/atomic.hh2
-rw-r--r--src/cpu/simple/timing.cc19
-rw-r--r--src/cpu/simple/timing.hh2
10 files changed, 61 insertions, 38 deletions
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index 3e7a6d4b6..36caea79a 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -254,8 +254,11 @@ BaseCPU::~BaseCPU()
void
BaseCPU::init()
{
- if (!params()->switched_out)
+ if (!params()->switched_out) {
registerThreadContexts();
+
+ verifyMemoryMode();
+ }
}
void
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index 34b23cea0..073050816 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -342,6 +342,17 @@ class BaseCPU : public MemObject
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 --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc
index 87272da7f..5490cb3f2 100644
--- a/src/cpu/inorder/cpu.cc
+++ b/src/cpu/inorder/cpu.cc
@@ -786,12 +786,6 @@ InOrderCPU::init()
{
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 @@ InOrderCPU::init()
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 --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh
index 1037ea2e6..7ca4355de 100644
--- a/src/cpu/inorder/cpu.hh
+++ b/src/cpu/inorder/cpu.hh
@@ -109,6 +109,8 @@ class InOrderCPU : public BaseCPU
/* Destructor */
~InOrderCPU();
+ void verifyMemoryMode() const;
+
/** Return a reference to the data port. */
virtual CpuPort &getDataPort() { return dataPort; }
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index 393b9a189..53250d495 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -646,12 +646,6 @@ FullO3CPU<Impl>::init()
{
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.
@@ -1262,11 +1256,7 @@ FullO3CPU<Impl>::drainResume()
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();
@@ -1323,6 +1313,16 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
}
template <class Impl>
+void
+FullO3CPU<Impl>::verifyMemoryMode() const
+{
+ if (system->getMemoryMode() != Enums::timing) {
+ fatal("The O3 CPU requires the memory system to be in "
+ "'timing' mode.\n");
+ }
+}
+
+template <class Impl>
TheISA::MiscReg
FullO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, ThreadID tid)
{
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index 5dd0e222d..719d38ef0 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -479,6 +479,8 @@ class FullO3CPU : public BaseO3CPU
/** 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 --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index 7255469a0..7a0778961 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -84,12 +84,6 @@ AtomicSimpleCPU::init()
{
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 @@ AtomicSimpleCPU::drainResume()
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 @@ AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
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 --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh
index 684125106..e3eafe8e0 100644
--- a/src/cpu/simple/atomic.hh
+++ b/src/cpu/simple/atomic.hh
@@ -164,6 +164,8 @@ class AtomicSimpleCPU : public BaseSimpleCPU
void switchOut();
void takeOverFrom(BaseCPU *oldCPU);
+ void verifyMemoryMode() const;
+
virtual void activateContext(ThreadID thread_num, Cycles delay);
virtual void suspendContext(ThreadID thread_num);
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index f6dc1fbf6..7423d082c 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -66,12 +66,6 @@ TimingSimpleCPU::init()
{
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 @@ TimingSimpleCPU::drainResume()
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 @@ TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
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)
diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh
index af780265f..348129150 100644
--- a/src/cpu/simple/timing.hh
+++ b/src/cpu/simple/timing.hh
@@ -261,6 +261,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
void switchOut();
void takeOverFrom(BaseCPU *oldCPU);
+ void verifyMemoryMode() const;
+
virtual void activateContext(ThreadID thread_num, Cycles delay);
virtual void suspendContext(ThreadID thread_num);