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:
parent
5ec58c4bdc
commit
716ceb6c10
25 changed files with 241 additions and 35 deletions
|
@ -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 §ion);
|
||||
|
||||
void clear()
|
||||
{
|
||||
bzero(intRegFile, sizeof(intRegFile));
|
||||
floatRegFile.clear();
|
||||
miscRegs.clear();
|
||||
}
|
||||
};
|
||||
|
||||
static inline ExtMachInst makeExtMI(MachInst inst, const uint64_t &pc);
|
||||
|
|
26
cpu/base.cc
26
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
18
cpu/base.hh
18
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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,7 +151,7 @@ class CheckerCPU : public BaseCPU
|
|||
|
||||
virtual Counter totalInstructions() const
|
||||
{
|
||||
return numInst - startNumInst;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// number of simulated loads
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -181,6 +190,36 @@ CPUExecContext::takeOverFrom(ExecContext *oldContext)
|
|||
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
|
||||
CPUExecContext::serialize(ostream &os)
|
||||
{
|
||||
|
@ -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());
|
||||
*/
|
||||
}
|
||||
|
||||
|
|
|
@ -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 §ion);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 §ion)
|
|||
// 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)
|
||||
|
|
|
@ -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 §ion);
|
||||
|
||||
public:
|
||||
/** Executes a syscall on this cycle.
|
||||
* ---------------------------------------
|
||||
* Note: this is a virtual function. CPU-Specific
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 §ion)
|
||||
{
|
||||
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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1499,7 +1499,6 @@ template <class Impl>
|
|||
void
|
||||
LWBackEnd<Impl>::takeOverFrom(ExecContext *old_xc)
|
||||
{
|
||||
switchedOut = false;
|
||||
xcSquash = false;
|
||||
trapSquash = false;
|
||||
|
||||
|
|
|
@ -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 §ion)
|
|||
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;
|
||||
|
|
|
@ -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)")
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 §ion)
|
|||
{
|
||||
return db->sectionExists(section);
|
||||
}
|
||||
|
||||
/** Hacked stat reset event */
|
||||
|
||||
class StatresetParamContext : public ParamContext
|
||||
{
|
||||
public:
|
||||
StatresetParamContext(const string §ion);
|
||||
~StatresetParamContext();
|
||||
void startup();
|
||||
};
|
||||
|
||||
StatresetParamContext statParams("statsreset");
|
||||
|
||||
Param<Tick> reset_cycle(&statParams, "reset_cycle",
|
||||
"Cycle to reset stats on", 0);
|
||||
|
||||
StatresetParamContext::StatresetParamContext(const string §ion)
|
||||
: 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue