Code update for CPU models.

arch/alpha/isa_traits.hh:
    Add in clear functions.
cpu/base.cc:
cpu/base.hh:
    Add in CPU progress event.
cpu/base_dyn_inst.hh:
    Mimic normal registers in terms of writing/reading floats.
cpu/checker/cpu.cc:
cpu/checker/cpu.hh:
cpu/checker/cpu_builder.cc:
cpu/checker/o3_cpu_builder.cc:
    Fix up stuff.
cpu/cpu_exec_context.cc:
cpu/cpu_exec_context.hh:
cpu/o3/cpu.cc:
cpu/o3/cpu.hh:
    Bring up to speed with newmem.
cpu/o3/alpha_cpu_builder.cc:
    Allow for progress intervals.
cpu/o3/tournament_pred.cc:
    Fix up predictor.
cpu/o3/tournament_pred.hh:
cpu/ozone/cpu.hh:
cpu/ozone/cpu_impl.hh:
cpu/simple/cpu.cc:
    Fixes.
cpu/ozone/cpu_builder.cc:
    Allow progress interval.
cpu/ozone/front_end_impl.hh:
    Comment out this message.
cpu/ozone/lw_back_end_impl.hh:
    Remove this.
python/m5/objects/BaseCPU.py:
    Add progress interval.
python/m5/objects/Root.py:
    Allow for stat reset.
sim/serialize.cc:
sim/stat_control.cc:
    Add in stats reset.

--HG--
extra : convert_revision : fdb5ac5542099173cc30c40ea93372a065534b5e
This commit is contained in:
Kevin Lim 2006-08-11 17:42:59 -04:00
parent 5ec58c4bdc
commit 716ceb6c10
25 changed files with 241 additions and 35 deletions

View file

@ -168,6 +168,9 @@ namespace AlphaISA
typedef union { typedef union {
uint64_t q[NumFloatRegs]; // integer qword view uint64_t q[NumFloatRegs]; // integer qword view
double d[NumFloatRegs]; // double-precision floating point view double d[NumFloatRegs]; // double-precision floating point view
void clear()
{ bzero(d, sizeof(d)); }
} FloatRegFile; } FloatRegFile;
extern const Addr PageShift; extern const Addr PageShift;
@ -266,6 +269,13 @@ extern const int reg_redir[NumIntRegs];
void serialize(std::ostream &os); void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section); 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); static inline ExtMachInst makeExtMI(MachInst inst, const uint64_t &pc);

View file

@ -54,6 +54,26 @@ vector<BaseCPU *> BaseCPU::cpuList;
// been initialized // been initialized
int maxThreadsPerCPU = 1; 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 #if FULL_SYSTEM
BaseCPU::BaseCPU(Params *p) BaseCPU::BaseCPU(Params *p)
: SimObject(p->name), clock(p->clock), checkInterrupts(true), : SimObject(p->name), clock(p->clock), checkInterrupts(true),
@ -150,7 +170,6 @@ BaseCPU::BaseCPU(Params *p)
if (params->profile) if (params->profile)
profileEvent = new ProfileEvent(this, params->profile); profileEvent = new ProfileEvent(this, params->profile);
#endif #endif
} }
BaseCPU::Params::Params() BaseCPU::Params::Params()
@ -185,6 +204,11 @@ BaseCPU::startup()
if (!params->deferRegistration && profileEvent) if (!params->deferRegistration && profileEvent)
profileEvent->schedule(curTick); profileEvent->schedule(curTick);
#endif #endif
if (params->progress_interval) {
new CPUProgressEvent(&mainEventQueue, params->progress_interval,
this);
}
} }

View file

@ -43,6 +43,23 @@ class CheckerCPU;
class ExecContext; class ExecContext;
class System; 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 class BaseCPU : public SimObject
{ {
protected: protected:
@ -125,6 +142,7 @@ class BaseCPU : public SimObject
int cpu_id; int cpu_id;
Tick profile; Tick profile;
#endif #endif
Tick progress_interval;
BaseCPU *checker; BaseCPU *checker;
Params(); Params();

View file

@ -200,7 +200,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
union Result { union Result {
uint64_t integer; uint64_t integer;
float fp; // float fp;
double dbl; double dbl;
}; };
@ -394,7 +394,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
uint64_t readIntResult() { return instResult.integer; } uint64_t readIntResult() { return instResult.integer; }
/** Returns the result of a floating point instruction. */ /** 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. */ /** Returns the result of a floating point (double) instruction. */
double readDoubleResult() { return instResult.dbl; } double readDoubleResult() { return instResult.dbl; }
@ -406,7 +406,8 @@ class BaseDynInst : public FastAlloc, public RefCounted
void setFloatRegSingle(const StaticInst *si, int idx, float val) 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) void setFloatRegDouble(const StaticInst *si, int idx, double val)

View file

@ -735,9 +735,20 @@ Checker<DynInstPtr>::validateState()
{ {
if (updateThisCycle) { if (updateThisCycle) {
warn("%lli: Instruction PC %#x results didn't match up, copying all " 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 // Heavy-weight copying of all registers
cpuXC->copyArchRegs(unverifiedInst->xcBase()); 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; updateThisCycle = false;
} }
} }

View file

@ -151,7 +151,7 @@ class CheckerCPU : public BaseCPU
virtual Counter totalInstructions() const virtual Counter totalInstructions() const
{ {
return numInst - startNumInst; return 0;
} }
// number of simulated loads // number of simulated loads

View file

@ -58,6 +58,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(OzoneChecker)
Param<Counter> max_insts_all_threads; Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread; Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads; Param<Counter> max_loads_all_threads;
Param<Tick> progress_interval;
#if FULL_SYSTEM #if FULL_SYSTEM
SimObjectParam<AlphaITB *> itb; SimObjectParam<AlphaITB *> itb;
@ -91,6 +92,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(OzoneChecker)
"terminate when any thread reaches this load count"), "terminate when any thread reaches this load count"),
INIT_PARAM(max_loads_all_threads, INIT_PARAM(max_loads_all_threads,
"terminate when all threads have reached this load count"), "terminate when all threads have reached this load count"),
INIT_PARAM_DFLT(progress_interval, "CPU Progress Interval", 0),
#if FULL_SYSTEM #if FULL_SYSTEM
INIT_PARAM(itb, "Instruction TLB"), INIT_PARAM(itb, "Instruction TLB"),
@ -138,6 +140,8 @@ CREATE_SIM_OBJECT(OzoneChecker)
temp = max_insts_all_threads; temp = max_insts_all_threads;
temp = max_loads_any_thread; temp = max_loads_any_thread;
temp = max_loads_all_threads; temp = max_loads_all_threads;
Tick temp2 = progress_interval;
temp2++;
BaseMem *cache = icache; BaseMem *cache = icache;
cache = dcache; cache = dcache;

View file

@ -58,6 +58,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(O3Checker)
Param<Counter> max_insts_all_threads; Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread; Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads; Param<Counter> max_loads_all_threads;
Param<Tick> progress_interval;
#if FULL_SYSTEM #if FULL_SYSTEM
SimObjectParam<AlphaITB *> itb; SimObjectParam<AlphaITB *> itb;
@ -75,6 +76,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(O3Checker)
Param<bool> defer_registration; Param<bool> defer_registration;
Param<bool> exitOnError; Param<bool> exitOnError;
Param<bool> updateOnError;
Param<bool> function_trace; Param<bool> function_trace;
Param<Tick> function_trace_start; Param<Tick> function_trace_start;
@ -90,6 +92,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(O3Checker)
"terminate when any thread reaches this load count"), "terminate when any thread reaches this load count"),
INIT_PARAM(max_loads_all_threads, INIT_PARAM(max_loads_all_threads,
"terminate when all threads have reached this load count"), "terminate when all threads have reached this load count"),
INIT_PARAM_DFLT(progress_interval, "CPU Progress Interval", 0),
#if FULL_SYSTEM #if FULL_SYSTEM
INIT_PARAM(itb, "Instruction TLB"), 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(defer_registration, "defer system registration (for sampling)"),
INIT_PARAM(exitOnError, "exit on error"), 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, "Enable function trace"),
INIT_PARAM(function_trace_start, "Cycle to start 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_any_thread = 0;
params->max_loads_all_threads = 0; params->max_loads_all_threads = 0;
params->exitOnError = exitOnError; params->exitOnError = exitOnError;
params->updateOnError = updateOnError;
params->deferRegistration = defer_registration; params->deferRegistration = defer_registration;
params->functionTrace = function_trace; params->functionTrace = function_trace;
params->functionTraceStart = function_trace_start; params->functionTraceStart = function_trace_start;
@ -135,6 +140,8 @@ CREATE_SIM_OBJECT(O3Checker)
temp = max_insts_all_threads; temp = max_insts_all_threads;
temp = max_loads_any_thread; temp = max_loads_any_thread;
temp = max_loads_all_threads; temp = max_loads_all_threads;
Tick temp2 = progress_interval;
temp2++;
BaseMem *cache = icache; BaseMem *cache = icache;
cache = dcache; cache = dcache;

View file

@ -118,6 +118,20 @@ CPUExecContext::CPUExecContext(RegFile *regFile)
#endif #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() CPUExecContext::~CPUExecContext()
{ {
delete proxy; delete proxy;
@ -158,13 +172,8 @@ CPUExecContext::takeOverFrom(ExecContext *oldContext)
assert(process == oldContext->getProcessPtr()); assert(process == oldContext->getProcessPtr());
#endif #endif
// copy over functional state copyState(oldContext);
_status = oldContext->status(); #if FULL_SYSTEM
copyArchRegs(oldContext);
cpu_id = oldContext->readCpuId();
#if !FULL_SYSTEM
func_exe_inst = oldContext->readFuncExeInst();
#else
EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent(); EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent();
if (quiesce) { if (quiesce) {
// Point the quiesce event's XC at this XC so that it wakes up // Point the quiesce event's XC at this XC so that it wakes up
@ -181,6 +190,36 @@ CPUExecContext::takeOverFrom(ExecContext *oldContext)
oldContext->setStatus(ExecContext::Unallocated); oldContext->setStatus(ExecContext::Unallocated);
} }
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 void
CPUExecContext::serialize(ostream &os) CPUExecContext::serialize(ostream &os)
{ {
@ -294,6 +333,8 @@ CPUExecContext::regStats(const string &name)
void void
CPUExecContext::copyArchRegs(ExecContext *xc) CPUExecContext::copyArchRegs(ExecContext *xc)
{ {
TheISA::copyRegs(xc, proxy);
/*
// First loop through the integer registers. // First loop through the integer registers.
for (int i = 0; i < AlphaISA::NumIntRegs; ++i) { for (int i = 0; i < AlphaISA::NumIntRegs; ++i) {
setIntReg(i, xc->readIntReg(i)); setIntReg(i, xc->readIntReg(i));
@ -311,5 +352,6 @@ CPUExecContext::copyArchRegs(ExecContext *xc)
// Lastly copy PC/NPC // Lastly copy PC/NPC
setPC(xc->readPC()); setPC(xc->readPC());
setNextPC(xc->readNextPC()); setNextPC(xc->readNextPC());
*/
} }

View file

@ -203,12 +203,19 @@ class CPUExecContext
// else. // else.
CPUExecContext(RegFile *regFile); CPUExecContext(RegFile *regFile);
#endif #endif
CPUExecContext();
virtual ~CPUExecContext(); virtual ~CPUExecContext();
virtual void takeOverFrom(ExecContext *oldContext); virtual void takeOverFrom(ExecContext *oldContext);
void regStats(const std::string &name); void regStats(const std::string &name);
void copyXC(ExecContext *context);
void copyState(ExecContext *oldContext);
void serialize(std::ostream &os); void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section); void unserialize(Checkpoint *cp, const std::string &section);

View file

@ -68,6 +68,7 @@ Param<Counter> max_insts_any_thread;
Param<Counter> max_insts_all_threads; Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread; Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads; Param<Counter> max_loads_all_threads;
Param<Tick> progress_interval;
SimObjectParam<BaseCache *> icache; SimObjectParam<BaseCache *> icache;
SimObjectParam<BaseCache *> dcache; SimObjectParam<BaseCache *> dcache;
@ -189,6 +190,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivAlphaFullCPU)
"Terminate when all threads have reached this load" "Terminate when all threads have reached this load"
"count", "count",
0), 0),
INIT_PARAM_DFLT(progress_interval, "Progress interval", 0),
INIT_PARAM_DFLT(icache, "L1 instruction cache", NULL), INIT_PARAM_DFLT(icache, "L1 instruction cache", NULL),
INIT_PARAM_DFLT(dcache, "L1 data 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_insts_all_threads = max_insts_all_threads;
params->max_loads_any_thread = max_loads_any_thread; params->max_loads_any_thread = max_loads_any_thread;
params->max_loads_all_threads = max_loads_all_threads; params->max_loads_all_threads = max_loads_all_threads;
params->progress_interval = progress_interval;
// //
// Caches // Caches

View file

@ -29,6 +29,7 @@
#include "config/full_system.hh" #include "config/full_system.hh"
#if FULL_SYSTEM #if FULL_SYSTEM
#include "cpu/quiesce_event.hh"
#include "sim/system.hh" #include "sim/system.hh"
#else #else
#include "sim/process.hh" #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 // Be sure to signal that there's some activity so the CPU doesn't
// deschedule itself. // deschedule itself.
activityRec.activity(); activityRec.activity();
if (thread[tid]->quiesceEvent && thread[tid]->quiesceEvent->scheduled())
thread[tid]->quiesceEvent->deschedule();
fetch.wakeFromQuiesce(); fetch.wakeFromQuiesce();
_status = Running; _status = Running;
@ -759,7 +763,6 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
tickEvent.schedule(curTick); tickEvent.schedule(curTick);
} }
/*
template <class Impl> template <class Impl>
void void
FullO3CPU<Impl>::serialize(std::ostream &os) 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 // Use SimpleThread's ability to checkpoint to make it easier to
// write out the registers. Also make this static so it doesn't // write out the registers. Also make this static so it doesn't
// get instantiated multiple times (causes a panic in statistics). // get instantiated multiple times (causes a panic in statistics).
static SimpleThread temp; static CPUExecContext temp;
for (int i = 0; i < thread.size(); i++) { for (int i = 0; i < thread.size(); i++) {
nameOut(os, csprintf("%s.xc.%i", name(), i)); nameOut(os, csprintf("%s.xc.%i", name(), i));
temp.copyXC(thread[i]->getXC()); temp.copyXC(thread[i]->getXCProxy());
temp.serialize(os); 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 // Use SimpleThread's ability to checkpoint to make it easier to
// read in the registers. Also make this static so it doesn't // read in the registers. Also make this static so it doesn't
// get instantiated multiple times (causes a panic in statistics). // get instantiated multiple times (causes a panic in statistics).
static SimpleThread temp; static CPUExecContext temp;
for (int i = 0; i < thread.size(); i++) { 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)); temp.unserialize(cp, csprintf("%s.xc.%i", section, i));
thread[i]->getXC()->copyArchRegs(temp.getXC()); thread[i]->getXCProxy()->copyArchRegs(temp.getProxy());
} }
} }
*/
template <class Impl> template <class Impl>
uint64_t uint64_t
FullO3CPU<Impl>::readIntReg(int reg_idx) FullO3CPU<Impl>::readIntReg(int reg_idx)

View file

@ -198,6 +198,13 @@ class FullO3CPU : public BaseFullCPU
/** Update The Order In Which We Process Threads. */ /** Update The Order In Which We Process Threads. */
void updateThreadPriority(); 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. /** Executes a syscall on this cycle.
* --------------------------------------- * ---------------------------------------
* Note: this is a virtual function. CPU-Specific * Note: this is a virtual function. CPU-Specific

View file

@ -60,6 +60,8 @@ TournamentBP::TournamentBP(unsigned _localPredictorSize,
for (int i = 0; i < localPredictorSize; ++i) for (int i = 0; i < localPredictorSize; ++i)
localCtrs[i].setBits(localCtrBits); localCtrs[i].setBits(localCtrBits);
localPredictorMask = floorPow2(localPredictorSize) - 1;
if (!isPowerOf2(localHistoryTableSize)) { if (!isPowerOf2(localHistoryTableSize)) {
fatal("Invalid local history table size!\n"); 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 //Lookup in the local predictor to get its branch prediction
local_history_idx = calcLocHistIdx(branch_addr); local_history_idx = calcLocHistIdx(branch_addr);
local_predictor_idx = localHistoryTable[local_history_idx] local_predictor_idx = localHistoryTable[local_history_idx]
& localHistoryMask; & localPredictorMask;
local_prediction = localCtrs[local_predictor_idx].read() > threshold; local_prediction = localCtrs[local_predictor_idx].read() > threshold;
//Lookup in the global predictor to get its branch prediction //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; bp_history = (void *)history;
assert(globalHistory < globalPredictorSize && 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 // Commented code is for doing speculative update of counters and
// all histories. // all histories.
@ -232,7 +235,7 @@ TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history)
// Get the local predictor's current prediction // Get the local predictor's current prediction
local_history_idx = calcLocHistIdx(branch_addr); local_history_idx = calcLocHistIdx(branch_addr);
local_predictor_hist = localHistoryTable[local_history_idx]; 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 // Update the choice predictor to tell it which one was correct if
// there was a prediction. // there was a prediction.
@ -254,6 +257,7 @@ TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history)
} }
assert(globalHistory < globalPredictorSize && assert(globalHistory < globalPredictorSize &&
local_history_idx < localHistoryTableSize &&
local_predictor_idx < localPredictorSize); local_predictor_idx < localPredictorSize);
// Update the counters and local history with the proper // Update the counters and local history with the proper

View file

@ -158,6 +158,9 @@ class TournamentBP
/** Size of the local predictor. */ /** Size of the local predictor. */
unsigned localPredictorSize; unsigned localPredictorSize;
/** Mask to get the proper index bits into the predictor. */
unsigned localPredictorMask;
/** Number of bits of the local predictor's counters. */ /** Number of bits of the local predictor's counters. */
unsigned localCtrBits; unsigned localCtrBits;

View file

@ -300,8 +300,6 @@ class OzoneCPU : public BaseCPU
Status _status; Status _status;
public: public:
bool checkInterrupts;
void post_interrupt(int int_num, int index); void post_interrupt(int int_num, int index);
void zero_fill_64(Addr addr) { void zero_fill_64(Addr addr) {

View file

@ -84,6 +84,7 @@ Param<Counter> max_insts_any_thread;
Param<Counter> max_insts_all_threads; Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread; Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads; Param<Counter> max_loads_all_threads;
Param<Tick> progress_interval;
SimObjectParam<BaseCache *> icache; SimObjectParam<BaseCache *> icache;
SimObjectParam<BaseCache *> dcache; SimObjectParam<BaseCache *> dcache;
@ -212,6 +213,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivOzoneCPU)
"Terminate when all threads have reached this load" "Terminate when all threads have reached this load"
"count", "count",
0), 0),
INIT_PARAM_DFLT(progress_interval, "Progress interval", 0),
INIT_PARAM_DFLT(icache, "L1 instruction cache", NULL), INIT_PARAM_DFLT(icache, "L1 instruction cache", NULL),
INIT_PARAM_DFLT(dcache, "L1 data 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_insts_all_threads = max_insts_all_threads;
params->max_loads_any_thread = max_loads_any_thread; params->max_loads_any_thread = max_loads_any_thread;
params->max_loads_all_threads = max_loads_all_threads; params->max_loads_all_threads = max_loads_all_threads;
params->progress_interval = progress_interval;
// //
// Caches // Caches

View file

@ -249,6 +249,9 @@ OzoneCPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
{ {
BaseCPU::takeOverFrom(oldCPU); BaseCPU::takeOverFrom(oldCPU);
thread.trapPending = false;
thread.inSyscall = false;
backEnd->takeOverFrom(); backEnd->takeOverFrom();
frontEnd->takeOverFrom(); frontEnd->takeOverFrom();
assert(!tickEvent.scheduled()); assert(!tickEvent.scheduled());
@ -288,6 +291,8 @@ OzoneCPU<Impl>::activateContext(int thread_num, int delay)
scheduleTickEvent(delay); scheduleTickEvent(delay);
_status = Running; _status = Running;
thread._status = ExecContext::Active; thread._status = ExecContext::Active;
if (thread.quiesceEvent && thread.quiesceEvent->scheduled())
thread.quiesceEvent->deschedule();
frontEnd->wakeFromQuiesce(); frontEnd->wakeFromQuiesce();
} }
@ -395,11 +400,17 @@ void
OzoneCPU<Impl>::serialize(std::ostream &os) OzoneCPU<Impl>::serialize(std::ostream &os)
{ {
BaseCPU::serialize(os); BaseCPU::serialize(os);
SERIALIZE_ENUM(_status);
nameOut(os, csprintf("%s.xc", name()));
ozoneXC.serialize(os);
nameOut(os, csprintf("%s.tickEvent", name())); nameOut(os, csprintf("%s.tickEvent", name()));
tickEvent.serialize(os); 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> template <class Impl>
@ -407,9 +418,16 @@ void
OzoneCPU<Impl>::unserialize(Checkpoint *cp, const std::string &section) OzoneCPU<Impl>::unserialize(Checkpoint *cp, const std::string &section)
{ {
BaseCPU::unserialize(cp, section); BaseCPU::unserialize(cp, section);
UNSERIALIZE_ENUM(_status);
ozoneXC.unserialize(cp, csprintf("%s.xc", section));
tickEvent.unserialize(cp, csprintf("%s.tickEvent", 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> template <class Impl>

View file

@ -353,7 +353,7 @@ FrontEnd<Impl>::tick()
#if FULL_SYSTEM #if FULL_SYSTEM
if (inst->isQuiesce()) { if (inst->isQuiesce()) {
warn("%lli: Quiesce instruction encountered, halting fetch!", curTick); // warn("%lli: Quiesce instruction encountered, halting fetch!", curTick);
status = QuiescePending; status = QuiescePending;
break; break;
} }

View file

@ -1499,7 +1499,6 @@ template <class Impl>
void void
LWBackEnd<Impl>::takeOverFrom(ExecContext *old_xc) LWBackEnd<Impl>::takeOverFrom(ExecContext *old_xc)
{ {
switchedOut = false;
xcSquash = false; xcSquash = false;
trapSquash = false; trapSquash = false;

View file

@ -304,7 +304,7 @@ SimpleCPU::serialize(ostream &os)
BaseCPU::serialize(os); BaseCPU::serialize(os);
SERIALIZE_ENUM(_status); SERIALIZE_ENUM(_status);
SERIALIZE_SCALAR(inst); SERIALIZE_SCALAR(inst);
nameOut(os, csprintf("%s.xc", name())); nameOut(os, csprintf("%s.xc.0", name()));
cpuXC->serialize(os); cpuXC->serialize(os);
nameOut(os, csprintf("%s.tickEvent", name())); nameOut(os, csprintf("%s.tickEvent", name()));
tickEvent.serialize(os); tickEvent.serialize(os);
@ -318,7 +318,7 @@ SimpleCPU::unserialize(Checkpoint *cp, const string &section)
BaseCPU::unserialize(cp, section); BaseCPU::unserialize(cp, section);
UNSERIALIZE_ENUM(_status); UNSERIALIZE_ENUM(_status);
UNSERIALIZE_SCALAR(inst); 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)); tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
cacheCompletionEvent cacheCompletionEvent
.unserialize(cp, csprintf("%s.cacheCompletionEvent", section)); .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_insts_all_threads;
Param<Counter> max_loads_any_thread; Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads; Param<Counter> max_loads_all_threads;
Param<Tick> progress_interval;
#if FULL_SYSTEM #if FULL_SYSTEM
SimObjectParam<AlphaITB *> itb; SimObjectParam<AlphaITB *> itb;
@ -896,6 +897,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
"terminate when any thread reaches this load count"), "terminate when any thread reaches this load count"),
INIT_PARAM(max_loads_all_threads, INIT_PARAM(max_loads_all_threads,
"terminate when all threads have reached this load count"), "terminate when all threads have reached this load count"),
INIT_PARAM_DFLT(progress_interval, "CPU Progress interval", 0),
#if FULL_SYSTEM #if FULL_SYSTEM
INIT_PARAM(itb, "Instruction TLB"), INIT_PARAM(itb, "Instruction TLB"),
@ -936,6 +938,7 @@ CREATE_SIM_OBJECT(SimpleCPU)
params->dcache_interface = (dcache) ? dcache->getInterface() : NULL; params->dcache_interface = (dcache) ? dcache->getInterface() : NULL;
params->width = width; params->width = width;
params->progress_interval = progress_interval;
#if FULL_SYSTEM #if FULL_SYSTEM
params->itb = itb; params->itb = itb;
params->dtb = dtb; params->dtb = dtb;

View file

@ -22,6 +22,7 @@ class BaseCPU(SimObject):
"terminate when all threads have reached this load count") "terminate when all threads have reached this load count")
max_loads_any_thread = Param.Counter(0, max_loads_any_thread = Param.Counter(0,
"terminate when any thread reaches this load count") "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 = Param.Bool(False,
"defer registration with system (for sampling)") "defer registration with system (for sampling)")

View file

@ -1,6 +1,7 @@
from m5 import * from m5 import *
from HierParams import HierParams from HierParams import HierParams
from Serialize import Serialize from Serialize import Serialize
from Serialize import Statreset
from Statistics import Statistics from Statistics import Statistics
from Trace import Trace from Trace import Trace
from ExeTrace import ExecutionTrace from ExeTrace import ExecutionTrace
@ -23,3 +24,4 @@ class Root(SimObject):
trace = Trace() trace = Trace()
exetrace = ExecutionTrace() exetrace = ExecutionTrace()
serialize = Serialize() serialize = Serialize()
statsreset = Statreset()

View file

@ -49,6 +49,9 @@
#include "sim/sim_exit.hh" #include "sim/sim_exit.hh"
#include "sim/sim_object.hh" #include "sim/sim_object.hh"
// For stat reset hack
#include "sim/stat_control.hh"
using namespace std; using namespace std;
int Serializable::ckptMaxCount = 0; int Serializable::ckptMaxCount = 0;
@ -482,3 +485,36 @@ Checkpoint::sectionExists(const std::string &section)
{ {
return db->sectionExists(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);
}
}

View file

@ -183,8 +183,10 @@ StatEvent::process()
if (flags & Stats::Dump) if (flags & Stats::Dump)
DumpNow(); DumpNow();
if (flags & Stats::Reset) if (flags & Stats::Reset) {
cprintf("Resetting stats!\n");
reset(); reset();
}
if (repeat) if (repeat)
schedule(curTick + repeat); schedule(curTick + repeat);