summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/isa_traits.hh10
-rw-r--r--cpu/base.cc26
-rw-r--r--cpu/base.hh18
-rw-r--r--cpu/base_dyn_inst.hh7
-rw-r--r--cpu/checker/cpu.cc13
-rw-r--r--cpu/checker/cpu.hh2
-rw-r--r--cpu/checker/cpu_builder.cc4
-rw-r--r--cpu/checker/o3_cpu_builder.cc7
-rw-r--r--cpu/cpu_exec_context.cc56
-rw-r--r--cpu/cpu_exec_context.hh7
-rw-r--r--cpu/o3/alpha_cpu_builder.cc3
-rw-r--r--cpu/o3/cpu.cc17
-rw-r--r--cpu/o3/cpu.hh7
-rw-r--r--cpu/o3/tournament_pred.cc10
-rw-r--r--cpu/o3/tournament_pred.hh3
-rw-r--r--cpu/ozone/cpu.hh2
-rw-r--r--cpu/ozone/cpu_builder.cc3
-rw-r--r--cpu/ozone/cpu_impl.hh28
-rw-r--r--cpu/ozone/front_end_impl.hh2
-rw-r--r--cpu/ozone/lw_back_end_impl.hh1
-rw-r--r--cpu/simple/cpu.cc7
-rw-r--r--python/m5/objects/BaseCPU.py1
-rw-r--r--python/m5/objects/Root.py2
-rw-r--r--sim/serialize.cc36
-rw-r--r--sim/stat_control.cc4
25 files changed, 241 insertions, 35 deletions
diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh
index 515ec933b..6f5cae9ef 100644
--- a/arch/alpha/isa_traits.hh
+++ b/arch/alpha/isa_traits.hh
@@ -168,6 +168,9 @@ namespace AlphaISA
typedef union {
uint64_t q[NumFloatRegs]; // integer qword view
double d[NumFloatRegs]; // double-precision floating point view
+
+ void clear()
+ { bzero(d, sizeof(d)); }
} FloatRegFile;
extern const Addr PageShift;
@@ -266,6 +269,13 @@ extern const int reg_redir[NumIntRegs];
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
+
+ void clear()
+ {
+ bzero(intRegFile, sizeof(intRegFile));
+ floatRegFile.clear();
+ miscRegs.clear();
+ }
};
static inline ExtMachInst makeExtMI(MachInst inst, const uint64_t &pc);
diff --git a/cpu/base.cc b/cpu/base.cc
index de03b9eab..36950a683 100644
--- a/cpu/base.cc
+++ b/cpu/base.cc
@@ -54,6 +54,26 @@ vector<BaseCPU *> BaseCPU::cpuList;
// been initialized
int maxThreadsPerCPU = 1;
+void
+CPUProgressEvent::process()
+{
+#ifndef NDEBUG
+ Counter temp = cpu->totalInstructions();
+ double ipc = double(temp - lastNumInst) / (interval / cpu->cycles(1));
+ DPRINTFN("%s progress event, instructions committed: %lli, IPC: %0.8d\n",
+ cpu->name(), temp - lastNumInst, ipc);
+ ipc = 0.0;
+ lastNumInst = temp;
+ schedule(curTick + interval);
+#endif
+}
+
+const char *
+CPUProgressEvent::description()
+{
+ return "CPU Progress event";
+}
+
#if FULL_SYSTEM
BaseCPU::BaseCPU(Params *p)
: SimObject(p->name), clock(p->clock), checkInterrupts(true),
@@ -150,7 +170,6 @@ BaseCPU::BaseCPU(Params *p)
if (params->profile)
profileEvent = new ProfileEvent(this, params->profile);
#endif
-
}
BaseCPU::Params::Params()
@@ -185,6 +204,11 @@ BaseCPU::startup()
if (!params->deferRegistration && profileEvent)
profileEvent->schedule(curTick);
#endif
+
+ if (params->progress_interval) {
+ new CPUProgressEvent(&mainEventQueue, params->progress_interval,
+ this);
+ }
}
diff --git a/cpu/base.hh b/cpu/base.hh
index dd776859d..4f1578f67 100644
--- a/cpu/base.hh
+++ b/cpu/base.hh
@@ -43,6 +43,23 @@ class CheckerCPU;
class ExecContext;
class System;
+class CPUProgressEvent : public Event
+{
+ protected:
+ Tick interval;
+ Counter lastNumInst;
+ BaseCPU *cpu;
+
+ public:
+ CPUProgressEvent(EventQueue *q, Tick ival, BaseCPU *_cpu)
+ : Event(q, Event::Stat_Event_Pri), interval(ival), lastNumInst(0), cpu(_cpu)
+ { schedule(curTick + interval); }
+
+ void process();
+
+ virtual const char *description();
+};
+
class BaseCPU : public SimObject
{
protected:
@@ -125,6 +142,7 @@ class BaseCPU : public SimObject
int cpu_id;
Tick profile;
#endif
+ Tick progress_interval;
BaseCPU *checker;
Params();
diff --git a/cpu/base_dyn_inst.hh b/cpu/base_dyn_inst.hh
index 01f6be185..6333a1fb1 100644
--- a/cpu/base_dyn_inst.hh
+++ b/cpu/base_dyn_inst.hh
@@ -200,7 +200,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
union Result {
uint64_t integer;
- float fp;
+// float fp;
double dbl;
};
@@ -394,7 +394,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
uint64_t readIntResult() { return instResult.integer; }
/** Returns the result of a floating point instruction. */
- float readFloatResult() { return instResult.fp; }
+ float readFloatResult() { return (float)instResult.dbl; }
/** Returns the result of a floating point (double) instruction. */
double readDoubleResult() { return instResult.dbl; }
@@ -406,7 +406,8 @@ class BaseDynInst : public FastAlloc, public RefCounted
void setFloatRegSingle(const StaticInst *si, int idx, float val)
{
- instResult.fp = val;
+// instResult.fp = val;
+ instResult.dbl = (double)val;
}
void setFloatRegDouble(const StaticInst *si, int idx, double val)
diff --git a/cpu/checker/cpu.cc b/cpu/checker/cpu.cc
index f195c8842..071559b7c 100644
--- a/cpu/checker/cpu.cc
+++ b/cpu/checker/cpu.cc
@@ -735,9 +735,20 @@ Checker<DynInstPtr>::validateState()
{
if (updateThisCycle) {
warn("%lli: Instruction PC %#x results didn't match up, copying all "
- "registers from main CPU", unverifiedInst->readPC());
+ "registers from main CPU", curTick, unverifiedInst->readPC());
// Heavy-weight copying of all registers
cpuXC->copyArchRegs(unverifiedInst->xcBase());
+ // Also advance the PC. Hopefully no PC-based events happened.
+#if THE_ISA != MIPS_ISA
+ // go to the next instruction
+ cpuXC->setPC(cpuXC->readNextPC());
+ cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst));
+#else
+ // go to the next instruction
+ cpuXC->setPC(cpuXC->readNextPC());
+ cpuXC->setNextPC(cpuXC->readNextNPC());
+ cpuXC->setNextNPC(cpuXC->readNextNPC() + sizeof(MachInst));
+#endif
updateThisCycle = false;
}
}
diff --git a/cpu/checker/cpu.hh b/cpu/checker/cpu.hh
index f48d1135a..3000cee92 100644
--- a/cpu/checker/cpu.hh
+++ b/cpu/checker/cpu.hh
@@ -151,7 +151,7 @@ class CheckerCPU : public BaseCPU
virtual Counter totalInstructions() const
{
- return numInst - startNumInst;
+ return 0;
}
// number of simulated loads
diff --git a/cpu/checker/cpu_builder.cc b/cpu/checker/cpu_builder.cc
index 802944e47..d1b5434c3 100644
--- a/cpu/checker/cpu_builder.cc
+++ b/cpu/checker/cpu_builder.cc
@@ -58,6 +58,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(OzoneChecker)
Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads;
+ Param<Tick> progress_interval;
#if FULL_SYSTEM
SimObjectParam<AlphaITB *> itb;
@@ -91,6 +92,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(OzoneChecker)
"terminate when any thread reaches this load count"),
INIT_PARAM(max_loads_all_threads,
"terminate when all threads have reached this load count"),
+ INIT_PARAM_DFLT(progress_interval, "CPU Progress Interval", 0),
#if FULL_SYSTEM
INIT_PARAM(itb, "Instruction TLB"),
@@ -138,6 +140,8 @@ CREATE_SIM_OBJECT(OzoneChecker)
temp = max_insts_all_threads;
temp = max_loads_any_thread;
temp = max_loads_all_threads;
+ Tick temp2 = progress_interval;
+ temp2++;
BaseMem *cache = icache;
cache = dcache;
diff --git a/cpu/checker/o3_cpu_builder.cc b/cpu/checker/o3_cpu_builder.cc
index 410f91352..496cca779 100644
--- a/cpu/checker/o3_cpu_builder.cc
+++ b/cpu/checker/o3_cpu_builder.cc
@@ -58,6 +58,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(O3Checker)
Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads;
+ Param<Tick> progress_interval;
#if FULL_SYSTEM
SimObjectParam<AlphaITB *> itb;
@@ -75,6 +76,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(O3Checker)
Param<bool> defer_registration;
Param<bool> exitOnError;
+ Param<bool> updateOnError;
Param<bool> function_trace;
Param<Tick> function_trace_start;
@@ -90,6 +92,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(O3Checker)
"terminate when any thread reaches this load count"),
INIT_PARAM(max_loads_all_threads,
"terminate when all threads have reached this load count"),
+ INIT_PARAM_DFLT(progress_interval, "CPU Progress Interval", 0),
#if FULL_SYSTEM
INIT_PARAM(itb, "Instruction TLB"),
@@ -108,6 +111,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(O3Checker)
INIT_PARAM(defer_registration, "defer system registration (for sampling)"),
INIT_PARAM(exitOnError, "exit on error"),
+ INIT_PARAM(updateOnError, "Update the checker with the main CPU's state on error"),
INIT_PARAM(function_trace, "Enable function trace"),
INIT_PARAM(function_trace_start, "Cycle to start function trace")
@@ -124,6 +128,7 @@ CREATE_SIM_OBJECT(O3Checker)
params->max_loads_any_thread = 0;
params->max_loads_all_threads = 0;
params->exitOnError = exitOnError;
+ params->updateOnError = updateOnError;
params->deferRegistration = defer_registration;
params->functionTrace = function_trace;
params->functionTraceStart = function_trace_start;
@@ -135,6 +140,8 @@ CREATE_SIM_OBJECT(O3Checker)
temp = max_insts_all_threads;
temp = max_loads_any_thread;
temp = max_loads_all_threads;
+ Tick temp2 = progress_interval;
+ temp2++;
BaseMem *cache = icache;
cache = dcache;
diff --git a/cpu/cpu_exec_context.cc b/cpu/cpu_exec_context.cc
index e28c34f88..0dcf149fd 100644
--- a/cpu/cpu_exec_context.cc
+++ b/cpu/cpu_exec_context.cc
@@ -118,6 +118,20 @@ CPUExecContext::CPUExecContext(RegFile *regFile)
#endif
+CPUExecContext::CPUExecContext()
+#if !FULL_SYSTEM
+ : cpu(NULL), thread_num(-1), process(NULL), mem(NULL), asid(-1),
+ func_exe_inst(0), storeCondFailures(0)
+#else
+ : cpu(NULL), thread_num(-1), cpu_id(-1), lastActivate(0), lastSuspend(0),
+ mem(NULL), itb(NULL), dtb(NULL), system(NULL), memctrl(NULL),
+ physmem(NULL), profile(NULL), func_exe_inst(0), storeCondFailures(0)
+#endif
+{
+ regs.clear();
+ proxy = new ProxyExecContext<CPUExecContext>(this);
+}
+
CPUExecContext::~CPUExecContext()
{
delete proxy;
@@ -158,13 +172,8 @@ CPUExecContext::takeOverFrom(ExecContext *oldContext)
assert(process == oldContext->getProcessPtr());
#endif
- // copy over functional state
- _status = oldContext->status();
- copyArchRegs(oldContext);
- cpu_id = oldContext->readCpuId();
-#if !FULL_SYSTEM
- func_exe_inst = oldContext->readFuncExeInst();
-#else
+ copyState(oldContext);
+#if FULL_SYSTEM
EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent();
if (quiesce) {
// Point the quiesce event's XC at this XC so that it wakes up
@@ -182,6 +191,36 @@ CPUExecContext::takeOverFrom(ExecContext *oldContext)
}
void
+CPUExecContext::copyXC(ExecContext *context)
+{
+ copyState(context);
+
+#if FULL_SYSTEM
+ EndQuiesceEvent *quiesce = context->getQuiesceEvent();
+ if (quiesce) {
+ quiesceEvent = quiesce;
+ }
+ Kernel::Statistics *stats = context->getKernelStats();
+ if (stats) {
+ kernelStats = stats;
+ }
+#endif
+}
+
+void
+CPUExecContext::copyState(ExecContext *oldContext)
+{
+ // copy over functional state
+ _status = oldContext->status();
+ copyArchRegs(oldContext);
+ cpu_id = oldContext->readCpuId();
+#if !FULL_SYSTEM
+ func_exe_inst = oldContext->readFuncExeInst();
+#endif
+ inst = oldContext->getInst();
+}
+
+void
CPUExecContext::serialize(ostream &os)
{
SERIALIZE_ENUM(_status);
@@ -294,6 +333,8 @@ CPUExecContext::regStats(const string &name)
void
CPUExecContext::copyArchRegs(ExecContext *xc)
{
+ TheISA::copyRegs(xc, proxy);
+/*
// First loop through the integer registers.
for (int i = 0; i < AlphaISA::NumIntRegs; ++i) {
setIntReg(i, xc->readIntReg(i));
@@ -311,5 +352,6 @@ CPUExecContext::copyArchRegs(ExecContext *xc)
// Lastly copy PC/NPC
setPC(xc->readPC());
setNextPC(xc->readNextPC());
+*/
}
diff --git a/cpu/cpu_exec_context.hh b/cpu/cpu_exec_context.hh
index 061fe450a..619d07d3a 100644
--- a/cpu/cpu_exec_context.hh
+++ b/cpu/cpu_exec_context.hh
@@ -203,12 +203,19 @@ class CPUExecContext
// else.
CPUExecContext(RegFile *regFile);
#endif
+
+ CPUExecContext();
+
virtual ~CPUExecContext();
virtual void takeOverFrom(ExecContext *oldContext);
void regStats(const std::string &name);
+ void copyXC(ExecContext *context);
+
+ void copyState(ExecContext *oldContext);
+
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
diff --git a/cpu/o3/alpha_cpu_builder.cc b/cpu/o3/alpha_cpu_builder.cc
index c563fbef3..fa0e892aa 100644
--- a/cpu/o3/alpha_cpu_builder.cc
+++ b/cpu/o3/alpha_cpu_builder.cc
@@ -68,6 +68,7 @@ Param<Counter> max_insts_any_thread;
Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads;
+Param<Tick> progress_interval;
SimObjectParam<BaseCache *> icache;
SimObjectParam<BaseCache *> dcache;
@@ -189,6 +190,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivAlphaFullCPU)
"Terminate when all threads have reached this load"
"count",
0),
+ INIT_PARAM_DFLT(progress_interval, "Progress interval", 0),
INIT_PARAM_DFLT(icache, "L1 instruction cache", NULL),
INIT_PARAM_DFLT(dcache, "L1 data cache", NULL),
@@ -327,6 +329,7 @@ CREATE_SIM_OBJECT(DerivAlphaFullCPU)
params->max_insts_all_threads = max_insts_all_threads;
params->max_loads_any_thread = max_loads_any_thread;
params->max_loads_all_threads = max_loads_all_threads;
+ params->progress_interval = progress_interval;
//
// Caches
diff --git a/cpu/o3/cpu.cc b/cpu/o3/cpu.cc
index f1571e61b..0025d4144 100644
--- a/cpu/o3/cpu.cc
+++ b/cpu/o3/cpu.cc
@@ -29,6 +29,7 @@
#include "config/full_system.hh"
#if FULL_SYSTEM
+#include "cpu/quiesce_event.hh"
#include "sim/system.hh"
#else
#include "sim/process.hh"
@@ -598,6 +599,9 @@ FullO3CPU<Impl>::activateContext(int tid, int delay)
// Be sure to signal that there's some activity so the CPU doesn't
// deschedule itself.
activityRec.activity();
+ if (thread[tid]->quiesceEvent && thread[tid]->quiesceEvent->scheduled())
+ thread[tid]->quiesceEvent->deschedule();
+
fetch.wakeFromQuiesce();
_status = Running;
@@ -759,7 +763,6 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
tickEvent.schedule(curTick);
}
-/*
template <class Impl>
void
FullO3CPU<Impl>::serialize(std::ostream &os)
@@ -771,11 +774,11 @@ FullO3CPU<Impl>::serialize(std::ostream &os)
// Use SimpleThread's ability to checkpoint to make it easier to
// write out the registers. Also make this static so it doesn't
// get instantiated multiple times (causes a panic in statistics).
- static SimpleThread temp;
+ static CPUExecContext temp;
for (int i = 0; i < thread.size(); i++) {
nameOut(os, csprintf("%s.xc.%i", name(), i));
- temp.copyXC(thread[i]->getXC());
+ temp.copyXC(thread[i]->getXCProxy());
temp.serialize(os);
}
}
@@ -790,15 +793,15 @@ FullO3CPU<Impl>::unserialize(Checkpoint *cp, const std::string &section)
// Use SimpleThread's ability to checkpoint to make it easier to
// read in the registers. Also make this static so it doesn't
// get instantiated multiple times (causes a panic in statistics).
- static SimpleThread temp;
+ static CPUExecContext temp;
for (int i = 0; i < thread.size(); i++) {
- temp.copyXC(thread[i]->getXC());
+ temp.copyXC(thread[i]->getXCProxy());
temp.unserialize(cp, csprintf("%s.xc.%i", section, i));
- thread[i]->getXC()->copyArchRegs(temp.getXC());
+ thread[i]->getXCProxy()->copyArchRegs(temp.getProxy());
}
}
-*/
+
template <class Impl>
uint64_t
FullO3CPU<Impl>::readIntReg(int reg_idx)
diff --git a/cpu/o3/cpu.hh b/cpu/o3/cpu.hh
index ef5c9ae53..4d4adca5a 100644
--- a/cpu/o3/cpu.hh
+++ b/cpu/o3/cpu.hh
@@ -198,6 +198,13 @@ class FullO3CPU : public BaseFullCPU
/** Update The Order In Which We Process Threads. */
void updateThreadPriority();
+ /** Serialize state. */
+ virtual void serialize(std::ostream &os);
+
+ /** Unserialize from a checkpoint. */
+ virtual void unserialize(Checkpoint *cp, const std::string &section);
+
+ public:
/** Executes a syscall on this cycle.
* ---------------------------------------
* Note: this is a virtual function. CPU-Specific
diff --git a/cpu/o3/tournament_pred.cc b/cpu/o3/tournament_pred.cc
index f8c95abd8..8b1af6c7c 100644
--- a/cpu/o3/tournament_pred.cc
+++ b/cpu/o3/tournament_pred.cc
@@ -60,6 +60,8 @@ TournamentBP::TournamentBP(unsigned _localPredictorSize,
for (int i = 0; i < localPredictorSize; ++i)
localCtrs[i].setBits(localCtrBits);
+ localPredictorMask = floorPow2(localPredictorSize) - 1;
+
if (!isPowerOf2(localHistoryTableSize)) {
fatal("Invalid local history table size!\n");
}
@@ -156,7 +158,7 @@ TournamentBP::lookup(Addr &branch_addr, void * &bp_history)
//Lookup in the local predictor to get its branch prediction
local_history_idx = calcLocHistIdx(branch_addr);
local_predictor_idx = localHistoryTable[local_history_idx]
- & localHistoryMask;
+ & localPredictorMask;
local_prediction = localCtrs[local_predictor_idx].read() > threshold;
//Lookup in the global predictor to get its branch prediction
@@ -174,7 +176,8 @@ TournamentBP::lookup(Addr &branch_addr, void * &bp_history)
bp_history = (void *)history;
assert(globalHistory < globalPredictorSize &&
- local_history_idx < localPredictorSize);
+ local_history_idx < localHistoryTableSize &&
+ local_predictor_idx < localPredictorSize);
// Commented code is for doing speculative update of counters and
// all histories.
@@ -232,7 +235,7 @@ TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history)
// Get the local predictor's current prediction
local_history_idx = calcLocHistIdx(branch_addr);
local_predictor_hist = localHistoryTable[local_history_idx];
- local_predictor_idx = local_predictor_hist & localHistoryMask;
+ local_predictor_idx = local_predictor_hist & localPredictorMask;
// Update the choice predictor to tell it which one was correct if
// there was a prediction.
@@ -254,6 +257,7 @@ TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history)
}
assert(globalHistory < globalPredictorSize &&
+ local_history_idx < localHistoryTableSize &&
local_predictor_idx < localPredictorSize);
// Update the counters and local history with the proper
diff --git a/cpu/o3/tournament_pred.hh b/cpu/o3/tournament_pred.hh
index 6d77999cc..dc0cc55dc 100644
--- a/cpu/o3/tournament_pred.hh
+++ b/cpu/o3/tournament_pred.hh
@@ -158,6 +158,9 @@ class TournamentBP
/** Size of the local predictor. */
unsigned localPredictorSize;
+ /** Mask to get the proper index bits into the predictor. */
+ unsigned localPredictorMask;
+
/** Number of bits of the local predictor's counters. */
unsigned localCtrBits;
diff --git a/cpu/ozone/cpu.hh b/cpu/ozone/cpu.hh
index c272528b1..345e526ef 100644
--- a/cpu/ozone/cpu.hh
+++ b/cpu/ozone/cpu.hh
@@ -300,8 +300,6 @@ class OzoneCPU : public BaseCPU
Status _status;
public:
- bool checkInterrupts;
-
void post_interrupt(int int_num, int index);
void zero_fill_64(Addr addr) {
diff --git a/cpu/ozone/cpu_builder.cc b/cpu/ozone/cpu_builder.cc
index 1ab7a4c29..9df5962c8 100644
--- a/cpu/ozone/cpu_builder.cc
+++ b/cpu/ozone/cpu_builder.cc
@@ -84,6 +84,7 @@ Param<Counter> max_insts_any_thread;
Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads;
+Param<Tick> progress_interval;
SimObjectParam<BaseCache *> icache;
SimObjectParam<BaseCache *> dcache;
@@ -212,6 +213,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivOzoneCPU)
"Terminate when all threads have reached this load"
"count",
0),
+ INIT_PARAM_DFLT(progress_interval, "Progress interval", 0),
INIT_PARAM_DFLT(icache, "L1 instruction cache", NULL),
INIT_PARAM_DFLT(dcache, "L1 data cache", NULL),
@@ -355,6 +357,7 @@ CREATE_SIM_OBJECT(DerivOzoneCPU)
params->max_insts_all_threads = max_insts_all_threads;
params->max_loads_any_thread = max_loads_any_thread;
params->max_loads_all_threads = max_loads_all_threads;
+ params->progress_interval = progress_interval;
//
// Caches
diff --git a/cpu/ozone/cpu_impl.hh b/cpu/ozone/cpu_impl.hh
index 4f41f220a..050bdb9a3 100644
--- a/cpu/ozone/cpu_impl.hh
+++ b/cpu/ozone/cpu_impl.hh
@@ -249,6 +249,9 @@ OzoneCPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
{
BaseCPU::takeOverFrom(oldCPU);
+ thread.trapPending = false;
+ thread.inSyscall = false;
+
backEnd->takeOverFrom();
frontEnd->takeOverFrom();
assert(!tickEvent.scheduled());
@@ -288,6 +291,8 @@ OzoneCPU<Impl>::activateContext(int thread_num, int delay)
scheduleTickEvent(delay);
_status = Running;
thread._status = ExecContext::Active;
+ if (thread.quiesceEvent && thread.quiesceEvent->scheduled())
+ thread.quiesceEvent->deschedule();
frontEnd->wakeFromQuiesce();
}
@@ -395,11 +400,17 @@ void
OzoneCPU<Impl>::serialize(std::ostream &os)
{
BaseCPU::serialize(os);
- SERIALIZE_ENUM(_status);
- nameOut(os, csprintf("%s.xc", name()));
- ozoneXC.serialize(os);
nameOut(os, csprintf("%s.tickEvent", name()));
tickEvent.serialize(os);
+
+ // Use SimpleThread's ability to checkpoint to make it easier to
+ // write out the registers. Also make this static so it doesn't
+ // get instantiated multiple times (causes a panic in statistics).
+ static CPUExecContext temp;
+
+ nameOut(os, csprintf("%s.xc.0", name()));
+ temp.copyXC(thread.getXCProxy());
+ temp.serialize(os);
}
template <class Impl>
@@ -407,9 +418,16 @@ void
OzoneCPU<Impl>::unserialize(Checkpoint *cp, const std::string &section)
{
BaseCPU::unserialize(cp, section);
- UNSERIALIZE_ENUM(_status);
- ozoneXC.unserialize(cp, csprintf("%s.xc", section));
tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
+
+ // Use SimpleThread's ability to checkpoint to make it easier to
+ // read in the registers. Also make this static so it doesn't
+ // get instantiated multiple times (causes a panic in statistics).
+ static CPUExecContext temp;
+
+ temp.copyXC(thread.getXCProxy());
+ temp.unserialize(cp, csprintf("%s.xc.0", section));
+ thread.getXCProxy()->copyArchRegs(temp.getProxy());
}
template <class Impl>
diff --git a/cpu/ozone/front_end_impl.hh b/cpu/ozone/front_end_impl.hh
index ffbcf3340..ca9948b7d 100644
--- a/cpu/ozone/front_end_impl.hh
+++ b/cpu/ozone/front_end_impl.hh
@@ -353,7 +353,7 @@ FrontEnd<Impl>::tick()
#if FULL_SYSTEM
if (inst->isQuiesce()) {
- warn("%lli: Quiesce instruction encountered, halting fetch!", curTick);
+// warn("%lli: Quiesce instruction encountered, halting fetch!", curTick);
status = QuiescePending;
break;
}
diff --git a/cpu/ozone/lw_back_end_impl.hh b/cpu/ozone/lw_back_end_impl.hh
index 18b2e8f47..9e1cd28cf 100644
--- a/cpu/ozone/lw_back_end_impl.hh
+++ b/cpu/ozone/lw_back_end_impl.hh
@@ -1499,7 +1499,6 @@ template <class Impl>
void
LWBackEnd<Impl>::takeOverFrom(ExecContext *old_xc)
{
- switchedOut = false;
xcSquash = false;
trapSquash = false;
diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc
index c03945ffa..0a4b3c3e4 100644
--- a/cpu/simple/cpu.cc
+++ b/cpu/simple/cpu.cc
@@ -304,7 +304,7 @@ SimpleCPU::serialize(ostream &os)
BaseCPU::serialize(os);
SERIALIZE_ENUM(_status);
SERIALIZE_SCALAR(inst);
- nameOut(os, csprintf("%s.xc", name()));
+ nameOut(os, csprintf("%s.xc.0", name()));
cpuXC->serialize(os);
nameOut(os, csprintf("%s.tickEvent", name()));
tickEvent.serialize(os);
@@ -318,7 +318,7 @@ SimpleCPU::unserialize(Checkpoint *cp, const string &section)
BaseCPU::unserialize(cp, section);
UNSERIALIZE_ENUM(_status);
UNSERIALIZE_SCALAR(inst);
- cpuXC->unserialize(cp, csprintf("%s.xc", section));
+ cpuXC->unserialize(cp, csprintf("%s.xc.0", section));
tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
cacheCompletionEvent
.unserialize(cp, csprintf("%s.cacheCompletionEvent", section));
@@ -863,6 +863,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads;
+ Param<Tick> progress_interval;
#if FULL_SYSTEM
SimObjectParam<AlphaITB *> itb;
@@ -896,6 +897,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
"terminate when any thread reaches this load count"),
INIT_PARAM(max_loads_all_threads,
"terminate when all threads have reached this load count"),
+ INIT_PARAM_DFLT(progress_interval, "CPU Progress interval", 0),
#if FULL_SYSTEM
INIT_PARAM(itb, "Instruction TLB"),
@@ -936,6 +938,7 @@ CREATE_SIM_OBJECT(SimpleCPU)
params->dcache_interface = (dcache) ? dcache->getInterface() : NULL;
params->width = width;
+ params->progress_interval = progress_interval;
#if FULL_SYSTEM
params->itb = itb;
params->dtb = dtb;
diff --git a/python/m5/objects/BaseCPU.py b/python/m5/objects/BaseCPU.py
index a90203729..29fb6ebce 100644
--- a/python/m5/objects/BaseCPU.py
+++ b/python/m5/objects/BaseCPU.py
@@ -22,6 +22,7 @@ class BaseCPU(SimObject):
"terminate when all threads have reached this load count")
max_loads_any_thread = Param.Counter(0,
"terminate when any thread reaches this load count")
+ progress_interval = Param.Tick(0, "interval to print out the progress message")
defer_registration = Param.Bool(False,
"defer registration with system (for sampling)")
diff --git a/python/m5/objects/Root.py b/python/m5/objects/Root.py
index 23b13fc67..0973d6ae5 100644
--- a/python/m5/objects/Root.py
+++ b/python/m5/objects/Root.py
@@ -1,6 +1,7 @@
from m5 import *
from HierParams import HierParams
from Serialize import Serialize
+from Serialize import Statreset
from Statistics import Statistics
from Trace import Trace
from ExeTrace import ExecutionTrace
@@ -23,3 +24,4 @@ class Root(SimObject):
trace = Trace()
exetrace = ExecutionTrace()
serialize = Serialize()
+ statsreset = Statreset()
diff --git a/sim/serialize.cc b/sim/serialize.cc
index c4ef124bb..1827a617e 100644
--- a/sim/serialize.cc
+++ b/sim/serialize.cc
@@ -49,6 +49,9 @@
#include "sim/sim_exit.hh"
#include "sim/sim_object.hh"
+// For stat reset hack
+#include "sim/stat_control.hh"
+
using namespace std;
int Serializable::ckptMaxCount = 0;
@@ -482,3 +485,36 @@ Checkpoint::sectionExists(const std::string &section)
{
return db->sectionExists(section);
}
+
+/** Hacked stat reset event */
+
+class StatresetParamContext : public ParamContext
+{
+ public:
+ StatresetParamContext(const string &section);
+ ~StatresetParamContext();
+ void startup();
+};
+
+StatresetParamContext statParams("statsreset");
+
+Param<Tick> reset_cycle(&statParams, "reset_cycle",
+ "Cycle to reset stats on", 0);
+
+StatresetParamContext::StatresetParamContext(const string &section)
+ : ParamContext(section)
+{ }
+
+StatresetParamContext::~StatresetParamContext()
+{
+}
+
+void
+StatresetParamContext::startup()
+{
+ if (reset_cycle > 0) {
+ Stats::SetupEvent(Stats::Reset, curTick + reset_cycle, 0);
+ cprintf("Stats reset event scheduled for %lli\n",
+ curTick + reset_cycle);
+ }
+}
diff --git a/sim/stat_control.cc b/sim/stat_control.cc
index 85c405b7f..e4394cfa3 100644
--- a/sim/stat_control.cc
+++ b/sim/stat_control.cc
@@ -183,8 +183,10 @@ StatEvent::process()
if (flags & Stats::Dump)
DumpNow();
- if (flags & Stats::Reset)
+ if (flags & Stats::Reset) {
+ cprintf("Resetting stats!\n");
reset();
+ }
if (repeat)
schedule(curTick + repeat);