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 §ion); + + 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::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::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 max_insts_all_threads; Param max_loads_any_thread; Param max_loads_all_threads; + Param progress_interval; #if FULL_SYSTEM SimObjectParam 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 max_insts_all_threads; Param max_loads_any_thread; Param max_loads_all_threads; + Param progress_interval; #if FULL_SYSTEM SimObjectParam itb; @@ -75,6 +76,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(O3Checker) Param defer_registration; Param exitOnError; + Param updateOnError; Param function_trace; Param 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(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()); +*/ } 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 §ion); 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 max_insts_any_thread; Param max_insts_all_threads; Param max_loads_any_thread; Param max_loads_all_threads; +Param progress_interval; SimObjectParam icache; SimObjectParam 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::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::takeOverFrom(BaseCPU *oldCPU) tickEvent.schedule(curTick); } -/* template void FullO3CPU::serialize(std::ostream &os) @@ -771,11 +774,11 @@ FullO3CPU::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::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 uint64_t FullO3CPU::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 §ion); + + 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 max_insts_any_thread; Param max_insts_all_threads; Param max_loads_any_thread; Param max_loads_all_threads; +Param progress_interval; SimObjectParam icache; SimObjectParam 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::takeOverFrom(BaseCPU *oldCPU) { BaseCPU::takeOverFrom(oldCPU); + thread.trapPending = false; + thread.inSyscall = false; + backEnd->takeOverFrom(); frontEnd->takeOverFrom(); assert(!tickEvent.scheduled()); @@ -288,6 +291,8 @@ OzoneCPU::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::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 @@ -407,9 +418,16 @@ void OzoneCPU::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 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::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 void LWBackEnd::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 §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 max_insts_all_threads; Param max_loads_any_thread; Param max_loads_all_threads; + Param progress_interval; #if FULL_SYSTEM SimObjectParam 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 §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 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); + } +} 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);