Fix the system clock at 1THz making 1 simulation tick = 1 ps
[gem5.git] / cpu / exec_context.cc
index 52d5c8d1ecf22e3a90e08479c86300d1af4d9c0a..9bed3ba471be7662f650fb5421323e1eed6eab91 100644 (file)
 #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
@@ -43,7 +48,7 @@
 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)
@@ -51,10 +56,24 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
       cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys),
       memctrl(_sys->memctrl), physmem(_sys->physmem),
       kernelBinning(system->kernelBinning), bin(kernelBinning->bin),
-      fnbin(kernelBinning->fnbin), func_exe_inst(0), storeCondFailures(0)
+      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,
@@ -78,18 +97,26 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
 
 ExecContext::~ExecContext()
 {
-#ifdef FULL_SYSTEM
+#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);
@@ -106,15 +133,6 @@ ExecContext::takeOverFrom(ExecContext *oldContext)
     oldContext->_status = ExecContext::Unallocated;
 }
 
-#ifdef FULL_SYSTEM
-void
-ExecContext::execute(const StaticInstBase *inst)
-{
-    assert(kernelStats);
-    system->kernelBinning->execute(this, inst);
-}
-#endif
-
 void
 ExecContext::serialize(ostream &os)
 {
@@ -124,7 +142,7 @@ ExecContext::serialize(ostream &os)
     SERIALIZE_SCALAR(func_exe_inst);
     SERIALIZE_SCALAR(inst);
 
-#ifdef FULL_SYSTEM
+#if FULL_SYSTEM
     kernelStats->serialize(os);
 #endif
 }
@@ -139,7 +157,7 @@ ExecContext::unserialize(Checkpoint *cp, const std::string &section)
     UNSERIALIZE_SCALAR(func_exe_inst);
     UNSERIALIZE_SCALAR(inst);
 
-#ifdef FULL_SYSTEM
+#if FULL_SYSTEM
     kernelStats->unserialize(cp, section);
 #endif
 }
@@ -161,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);
@@ -197,7 +215,7 @@ ExecContext::halt()
 void
 ExecContext::regStats(const string &name)
 {
-#ifdef FULL_SYSTEM
+#if FULL_SYSTEM
     kernelStats->regStats(name + ".kern");
 #endif
 }
@@ -208,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());