Code update for CPU models.
authorKevin Lim <ktlim@umich.edu>
Fri, 11 Aug 2006 21:42:59 +0000 (17:42 -0400)
committerKevin Lim <ktlim@umich.edu>
Fri, 11 Aug 2006 21:42:59 +0000 (17:42 -0400)
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

25 files changed:
arch/alpha/isa_traits.hh
cpu/base.cc
cpu/base.hh
cpu/base_dyn_inst.hh
cpu/checker/cpu.cc
cpu/checker/cpu.hh
cpu/checker/cpu_builder.cc
cpu/checker/o3_cpu_builder.cc
cpu/cpu_exec_context.cc
cpu/cpu_exec_context.hh
cpu/o3/alpha_cpu_builder.cc
cpu/o3/cpu.cc
cpu/o3/cpu.hh
cpu/o3/tournament_pred.cc
cpu/o3/tournament_pred.hh
cpu/ozone/cpu.hh
cpu/ozone/cpu_builder.cc
cpu/ozone/cpu_impl.hh
cpu/ozone/front_end_impl.hh
cpu/ozone/lw_back_end_impl.hh
cpu/simple/cpu.cc
python/m5/objects/BaseCPU.py
python/m5/objects/Root.py
sim/serialize.cc
sim/stat_control.cc

index 515ec933b12bf6c79e3cd1b9c432b51a378ecf21..6f5cae9ef69827af1a399e67ddc1f18435bbb15d 100644 (file)
@@ -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);
index de03b9eab5cb282c8f7f14faf2cdf3bbd33adee6..36950a68386b4da43132a1d51e3569568c718e6a 100644 (file)
@@ -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);
+    }
 }
 
 
index dd776859d435dfab4cfbac0dc8e0de8e1d36ee32..4f1578f6779f48cbeae0dd1d5282488ed507d0fd 100644 (file)
@@ -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();
index 01f6be18507ed63e7bd856458270590795c0b17b..6333a1fb123a29b8f040c643a410afb6a0a32738 100644 (file)
@@ -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)
index f195c8842467eac3bfb2988275b475840a1f9e33..071559b7ca72390c0016bcaa9f600ea611ee899d 100644 (file)
@@ -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;
     }
 }
index f48d1135a29f099bc380925e6c12b00bbf2031be..3000cee92d2c7b1e91ad7b14d4072239c0a095e2 100644 (file)
@@ -151,7 +151,7 @@ class CheckerCPU : public BaseCPU
 
     virtual Counter totalInstructions() const
     {
-        return numInst - startNumInst;
+        return 0;
     }
 
     // number of simulated loads
index 802944e47bf7617514a14efe24173d68a5ad8116..d1b5434c30cb992296d262563d6e90ee63a70f2d 100644 (file)
@@ -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;
 
index 410f91352551e0d3777e04618cb7c559f5413ebd..496cca779821a6725cc13b1365099c2b575c92c5 100644 (file)
@@ -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;
 
index e28c34f88fa735adb88b6feb2bad8cf134738345..0dcf149fd7ccda3ca8757a1412ccad1020d91d16 100644 (file)
@@ -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());
+*/
 }
 
index 061fe450aade58bed506d614b3cb8b56d034c950..619d07d3a2095e7f14d30ca8a3de2a23708c6e98 100644 (file)
@@ -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);
 
index c563fbef3787aa22da883f954d1c404c121ee978..fa0e892aa0899f45358ad8b7df92c99a1ec9193c 100644 (file)
@@ -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
index f1571e61b4a8c22e351e405759e9113e303e80ed..0025d4144552346c298d39de1e98e7683f71a5fa 100644 (file)
@@ -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)
index ef5c9ae53f220dc459ce2331081bb0e852feea8d..4d4adca5aee6cefa3e900a90c9b7b04802df08e0 100644 (file)
@@ -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
index f8c95abd8a775849a289626cd82634cc7ff8f1bf..8b1af6c7c8d606db3a55e883580ddef25d129e43 100644 (file)
@@ -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
index 6d77999cc1fec0dffc99bd2fa481c5a648e56617..dc0cc55dce9f373181c821c2e8743345957764fb 100644 (file)
@@ -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;
 
index c272528b1b4240328bb01d1c41f2caf6fd3ebb48..345e526ef84f007f5145c5a7c2a7833d26582f0a 100644 (file)
@@ -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) {
index 1ab7a4c299389a59bbf5af4516031891aae73b9f..9df5962c8476046d3f3434b7d2a3cf42d3a9a1f1 100644 (file)
@@ -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
index 4f41f220a35f5bfb5f5a1a0e31730f220f44c43f..050bdb9a385a1d1d048ba5cc322f0ecd7bebe0b0 100644 (file)
@@ -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>
index ffbcf33400b660faa05072d3dce91ddd1988442c..ca9948b7dc598e39e167862bd526416666e26c72 100644 (file)
@@ -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;
         }
index 18b2e8f47572955012a831960d76425a224a67c8..9e1cd28cf13d2e4c4295342368d85484d2e810de 100644 (file)
@@ -1499,7 +1499,6 @@ template <class Impl>
 void
 LWBackEnd<Impl>::takeOverFrom(ExecContext *old_xc)
 {
-    switchedOut = false;
     xcSquash = false;
     trapSquash = false;
 
index c03945ffa7cbeec755a3d0416f1737e1e5268089..0a4b3c3e4cbaa9b01571ee133e9338980419bc28 100644 (file)
@@ -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;
index a902037297a1b1a11a103c44e30e5ece448beb2f..29fb6ebcec9fc345329e91ad61b1f1d312b1e11e 100644 (file)
@@ -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)")
index 23b13fc675ba40fce4e4e083e1ae628d6939aaf6..0973d6ae5d2408efa01666b5529ce8a46e5e2cc4 100644 (file)
@@ -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()
index c4ef124bb5723490a644a56bcacfe4cc71fa78e2..1827a617e7a23d897a21ab53b94bd62d67202ea6 100644 (file)
@@ -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);
+    }
+}
index 85c405b7f2ca0c008bf556e6e62fdcc4df2fc7b4..e4394cfa3857a645c6d93439523ef2b31a2c0832 100644 (file)
@@ -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);