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.
This commit is contained in:
parent
1c7aa665bf
commit
1eec115c31
10 changed files with 61 additions and 38 deletions
|
@ -254,8 +254,11 @@ BaseCPU::~BaseCPU()
|
||||||
void
|
void
|
||||||
BaseCPU::init()
|
BaseCPU::init()
|
||||||
{
|
{
|
||||||
if (!params()->switched_out)
|
if (!params()->switched_out) {
|
||||||
registerThreadContexts();
|
registerThreadContexts();
|
||||||
|
|
||||||
|
verifyMemoryMode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -341,6 +341,17 @@ class BaseCPU : public MemObject
|
||||||
*/
|
*/
|
||||||
bool switchedOut() const { return _switchedOut; }
|
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).
|
* Number of threads we're actually simulating (<= SMT_MAX_THREADS).
|
||||||
* This is a constant for the duration of the simulation.
|
* This is a constant for the duration of the simulation.
|
||||||
|
|
|
@ -786,12 +786,6 @@ InOrderCPU::init()
|
||||||
{
|
{
|
||||||
BaseCPU::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) {
|
for (ThreadID tid = 0; tid < numThreads; ++tid) {
|
||||||
// Set noSquashFromTC so that the CPU doesn't squash when initially
|
// Set noSquashFromTC so that the CPU doesn't squash when initially
|
||||||
// setting up registers.
|
// setting up registers.
|
||||||
|
@ -815,6 +809,15 @@ InOrderCPU::init()
|
||||||
resPool->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
|
Fault
|
||||||
InOrderCPU::hwrei(ThreadID tid)
|
InOrderCPU::hwrei(ThreadID tid)
|
||||||
{
|
{
|
||||||
|
|
|
@ -109,6 +109,8 @@ class InOrderCPU : public BaseCPU
|
||||||
/* Destructor */
|
/* Destructor */
|
||||||
~InOrderCPU();
|
~InOrderCPU();
|
||||||
|
|
||||||
|
void verifyMemoryMode() const;
|
||||||
|
|
||||||
/** Return a reference to the data port. */
|
/** Return a reference to the data port. */
|
||||||
virtual CpuPort &getDataPort() { return dataPort; }
|
virtual CpuPort &getDataPort() { return dataPort; }
|
||||||
|
|
||||||
|
|
|
@ -646,12 +646,6 @@ FullO3CPU<Impl>::init()
|
||||||
{
|
{
|
||||||
BaseCPU::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) {
|
for (ThreadID tid = 0; tid < numThreads; ++tid) {
|
||||||
// Set noSquashFromTC so that the CPU doesn't squash when initially
|
// Set noSquashFromTC so that the CPU doesn't squash when initially
|
||||||
// setting up registers.
|
// setting up registers.
|
||||||
|
@ -1262,11 +1256,7 @@ FullO3CPU<Impl>::drainResume()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DPRINTF(Drain, "Resuming...\n");
|
DPRINTF(Drain, "Resuming...\n");
|
||||||
|
verifyMemoryMode();
|
||||||
if (system->getMemoryMode() != Enums::timing) {
|
|
||||||
fatal("The O3 CPU requires the memory system to be in "
|
|
||||||
"'timing' mode.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
fetch.drainResume();
|
fetch.drainResume();
|
||||||
commit.drainResume();
|
commit.drainResume();
|
||||||
|
@ -1322,6 +1312,16 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
|
||||||
_status = Idle;
|
_status = Idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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>
|
template <class Impl>
|
||||||
TheISA::MiscReg
|
TheISA::MiscReg
|
||||||
FullO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, ThreadID tid)
|
FullO3CPU<Impl>::readMiscRegNoEffect(int misc_reg, ThreadID tid)
|
||||||
|
|
|
@ -479,6 +479,8 @@ class FullO3CPU : public BaseO3CPU
|
||||||
/** Takes over from another CPU. */
|
/** Takes over from another CPU. */
|
||||||
virtual void takeOverFrom(BaseCPU *oldCPU);
|
virtual void takeOverFrom(BaseCPU *oldCPU);
|
||||||
|
|
||||||
|
void verifyMemoryMode() const;
|
||||||
|
|
||||||
/** Get the current instruction sequence number, and increment it. */
|
/** Get the current instruction sequence number, and increment it. */
|
||||||
InstSeqNum getAndIncrementInstSeq()
|
InstSeqNum getAndIncrementInstSeq()
|
||||||
{ return globalSeqNum++; }
|
{ return globalSeqNum++; }
|
||||||
|
|
|
@ -84,12 +84,6 @@ AtomicSimpleCPU::init()
|
||||||
{
|
{
|
||||||
BaseCPU::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
|
// Initialise the ThreadContext's memory proxies
|
||||||
tcBase()->initMemProxies(tcBase());
|
tcBase()->initMemProxies(tcBase());
|
||||||
|
|
||||||
|
@ -157,10 +151,7 @@ AtomicSimpleCPU::drainResume()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DPRINTF(SimpleCPU, "Resume\n");
|
DPRINTF(SimpleCPU, "Resume\n");
|
||||||
if (system->getMemoryMode() != Enums::atomic) {
|
verifyMemoryMode();
|
||||||
fatal("The atomic CPU requires the memory system to be in "
|
|
||||||
"'atomic' mode.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(!threadContexts.empty());
|
assert(!threadContexts.empty());
|
||||||
if (threadContexts.size() > 1)
|
if (threadContexts.size() > 1)
|
||||||
|
@ -218,6 +209,14 @@ AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
|
||||||
data_write_req.setThreadContext(_cpuId, 0); // Add thread ID here too
|
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
|
void
|
||||||
AtomicSimpleCPU::activateContext(ThreadID thread_num, Cycles delay)
|
AtomicSimpleCPU::activateContext(ThreadID thread_num, Cycles delay)
|
||||||
|
|
|
@ -164,6 +164,8 @@ class AtomicSimpleCPU : public BaseSimpleCPU
|
||||||
void switchOut();
|
void switchOut();
|
||||||
void takeOverFrom(BaseCPU *oldCPU);
|
void takeOverFrom(BaseCPU *oldCPU);
|
||||||
|
|
||||||
|
void verifyMemoryMode() const;
|
||||||
|
|
||||||
virtual void activateContext(ThreadID thread_num, Cycles delay);
|
virtual void activateContext(ThreadID thread_num, Cycles delay);
|
||||||
virtual void suspendContext(ThreadID thread_num);
|
virtual void suspendContext(ThreadID thread_num);
|
||||||
|
|
||||||
|
|
|
@ -66,12 +66,6 @@ TimingSimpleCPU::init()
|
||||||
{
|
{
|
||||||
BaseCPU::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
|
// Initialise the ThreadContext's memory proxies
|
||||||
tcBase()->initMemProxies(tcBase());
|
tcBase()->initMemProxies(tcBase());
|
||||||
|
|
||||||
|
@ -141,10 +135,7 @@ TimingSimpleCPU::drainResume()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DPRINTF(SimpleCPU, "Resume\n");
|
DPRINTF(SimpleCPU, "Resume\n");
|
||||||
if (system->getMemoryMode() != Enums::timing) {
|
verifyMemoryMode();
|
||||||
fatal("The timing CPU requires the memory system to be in "
|
|
||||||
"'timing' mode.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(!threadContexts.empty());
|
assert(!threadContexts.empty());
|
||||||
if (threadContexts.size() > 1)
|
if (threadContexts.size() > 1)
|
||||||
|
@ -197,6 +188,14 @@ TimingSimpleCPU::takeOverFrom(BaseCPU *oldCPU)
|
||||||
previousCycle = curCycle();
|
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
|
void
|
||||||
TimingSimpleCPU::activateContext(ThreadID thread_num, Cycles delay)
|
TimingSimpleCPU::activateContext(ThreadID thread_num, Cycles delay)
|
||||||
|
|
|
@ -261,6 +261,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
|
||||||
void switchOut();
|
void switchOut();
|
||||||
void takeOverFrom(BaseCPU *oldCPU);
|
void takeOverFrom(BaseCPU *oldCPU);
|
||||||
|
|
||||||
|
void verifyMemoryMode() const;
|
||||||
|
|
||||||
virtual void activateContext(ThreadID thread_num, Cycles delay);
|
virtual void activateContext(ThreadID thread_num, Cycles delay);
|
||||||
virtual void suspendContext(ThreadID thread_num);
|
virtual void suspendContext(ThreadID thread_num);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue