Fix the system clock at 1THz making 1 simulation tick = 1 ps
[gem5.git] / cpu / exec_context.cc
index 0d3a80fe73ff940bfc8742dddd1434b7a7c11ab7..9bed3ba471be7662f650fb5421323e1eed6eab91 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003 The Regents of The University of Michigan
+ * Copyright (c) 2001-2005 The Regents of The University of Michigan
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 #include <string>
 
-#include "cpu/base_cpu.hh"
+#include "cpu/base.hh"
 #include "cpu/exec_context.hh"
 
-#ifdef FULL_SYSTEM
+#if FULL_SYSTEM
+#include "base/callback.hh"
+#include "base/cprintf.hh"
+#include "base/output.hh"
+#include "cpu/profile.hh"
+#include "kern/kernel_stats.hh"
+#include "sim/serialize.hh"
+#include "sim/sim_exit.hh"
 #include "sim/system.hh"
+#include "targetarch/stacktrace.hh"
 #else
 #include "sim/process.hh"
 #endif
 using namespace std;
 
 // constructor
-#ifdef FULL_SYSTEM
+#if FULL_SYSTEM
 ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
                          AlphaITB *_itb, AlphaDTB *_dtb,
                          FunctionalMemory *_mem)
-    : _status(ExecContext::Unallocated),
-      kernelStats(this, _cpu), cpu(_cpu), thread_num(_thread_num),
+    : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num),
       cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys),
-      memCtrl(_sys->memCtrl), physmem(_sys->physmem),
-      swCtx(NULL), func_exe_inst(0), storeCondFailures(0)
+      memctrl(_sys->memctrl), physmem(_sys->physmem),
+      kernelBinning(system->kernelBinning), bin(kernelBinning->bin),
+      fnbin(kernelBinning->fnbin), profile(NULL),
+      func_exe_inst(0), storeCondFailures(0)
 {
+    kernelStats = new Kernel::Statistics(this);
     memset(&regs, 0, sizeof(RegFile));
+
+    if (cpu->params->profile) {
+        profile = new FunctionProfile(system->kernelSymtab);
+        Callback *cb =
+            new MakeCallback<ExecContext, &ExecContext::dumpFuncProfile>(this);
+        registerExitCallback(cb);
+    }
+
+    // let's fill with a dummy node for now so we don't get a segfault
+    // on the first cycle when there's no node available.
+    static ProfileNode dummyNode;
+    profileNode = &dummyNode;
+    profilePC = 3;
 }
 #else
 ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
@@ -72,13 +95,28 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
 }
 #endif
 
+ExecContext::~ExecContext()
+{
+#if FULL_SYSTEM
+    delete kernelStats;
+#endif
+}
+
+#if FULL_SYSTEM
+void
+ExecContext::dumpFuncProfile()
+{
+    std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
+    profile->dump(this, *os);
+}
+#endif
 
 void
 ExecContext::takeOverFrom(ExecContext *oldContext)
 {
     // some things should already be set up
     assert(mem == oldContext->mem);
-#ifdef FULL_SYSTEM
+#if FULL_SYSTEM
     assert(system == oldContext->system);
 #else
     assert(process == oldContext->process);
@@ -86,9 +124,6 @@ ExecContext::takeOverFrom(ExecContext *oldContext)
 
     // copy over functional state
     _status = oldContext->_status;
-#ifdef FULL_SYSTEM
-    kernelStats = oldContext->kernelStats;
-#endif
     regs = oldContext->regs;
     cpu_id = oldContext->cpu_id;
     func_exe_inst = oldContext->func_exe_inst;
@@ -98,7 +133,6 @@ ExecContext::takeOverFrom(ExecContext *oldContext)
     oldContext->_status = ExecContext::Unallocated;
 }
 
-
 void
 ExecContext::serialize(ostream &os)
 {
@@ -108,32 +142,9 @@ ExecContext::serialize(ostream &os)
     SERIALIZE_SCALAR(func_exe_inst);
     SERIALIZE_SCALAR(inst);
 
-#ifdef FULL_SYSTEM
-    bool ctx = false;
-    if (swCtx) {
-        ctx = true;
-        SERIALIZE_SCALAR(ctx);
-        SERIALIZE_SCALAR(swCtx->calls);
-        std::stack<fnCall *> *stack = &(swCtx->callStack);
-        fnCall *top;
-        int size = stack->size();
-        SERIALIZE_SCALAR(size);
-
-        for (int j=0; j<size; ++j) {
-            top = stack->top();
-            paramOut(os, csprintf("stackpos[%d]",j), top->name);
-            delete top;
-            stack->pop();
-        }
-    } else {
-        SERIALIZE_SCALAR(ctx);
-    }
-    if (system->bin) {
-        Stats::MainBin *cur = Stats::MainBin::curBin();
-        string bin_name = cur->name();
-        SERIALIZE_SCALAR(bin_name);
-    }
-#endif //FULL_SYSTEM
+#if FULL_SYSTEM
+    kernelStats->serialize(os);
+#endif
 }
 
 
@@ -146,36 +157,9 @@ ExecContext::unserialize(Checkpoint *cp, const std::string &section)
     UNSERIALIZE_SCALAR(func_exe_inst);
     UNSERIALIZE_SCALAR(inst);
 
-#ifdef FULL_SYSTEM
-    bool ctx;
-    UNSERIALIZE_SCALAR(ctx);
-    if (ctx) {
-        swCtx = new SWContext;
-        UNSERIALIZE_SCALAR(swCtx->calls);
-        int size;
-        UNSERIALIZE_SCALAR(size);
-
-        vector<fnCall *> calls;
-        fnCall *call;
-        for (int i=0; i<size; ++i) {
-            call = new fnCall;
-            paramIn(cp, section, csprintf("stackpos[%d]",i), call->name);
-            call->myBin = system->getBin(call->name);
-            calls.push_back(call);
-        }
-
-        for (int i=size-1; i>=0; --i) {
-            swCtx->callStack.push(calls[i]);
-        }
-
-    }
-
-    if (system->bin) {
-        string bin_name;
-        UNSERIALIZE_SCALAR(bin_name);
-        system->getBin(bin_name)->activate();
-    }
-#endif //FULL_SYSTEM
+#if FULL_SYSTEM
+    kernelStats->unserialize(cp, section);
+#endif
 }
 
 
@@ -195,7 +179,7 @@ ExecContext::suspend()
     if (status() == Suspended)
         return;
 
-#ifdef FULL_SYSTEM
+#if FULL_SYSTEM
     // Don't change the status from active if there are pending interrupts
     if (cpu->check_interrupts()) {
         assert(status() == Active);
@@ -231,8 +215,8 @@ ExecContext::halt()
 void
 ExecContext::regStats(const string &name)
 {
-#ifdef FULL_SYSTEM
-    kernelStats.regStats(name + ".kern");
+#if FULL_SYSTEM
+    kernelStats->regStats(name + ".kern");
 #endif
 }
 
@@ -242,7 +226,7 @@ ExecContext::trap(Fault fault)
     //TheISA::trap(fault);    //One possible way to do it...
 
     /** @todo: Going to hack it for now.  Do a true fixup later. */
-#ifdef FULL_SYSTEM
+#if FULL_SYSTEM
     ev5_trap(fault);
 #else
     fatal("fault (%d) detected @ PC 0x%08p", fault, readPC());