Formatting & doxygen docs for new syscall emulation code.
[gem5.git] / cpu / simple_cpu / simple_cpu.cc
index 891e6cdb3d48127f51e979896fe51f158e7eef95..476f28ea003aea0d207c1ce9f43a959bb7c0e3a5 100644 (file)
 #else // !FULL_SYSTEM
 #include "eio/eio.hh"
 #include "mem/functional_mem/functional_memory.hh"
-#include "sim/prog.hh"
 #endif // FULL_SYSTEM
 
 using namespace std;
 
+SimpleCPU::TickEvent::TickEvent(SimpleCPU *c)
+    : Event(&mainEventQueue, 100), cpu(c)
+{
+}
+
+void
+SimpleCPU::TickEvent::process()
+{
+    cpu->tick();
+}
+
+const char *
+SimpleCPU::TickEvent::description()
+{
+    return "SimpleCPU tick event";
+}
+
+
 SimpleCPU::CacheCompletionEvent::CacheCompletionEvent(SimpleCPU *_cpu)
     : Event(&mainEventQueue),
       cpu(_cpu)
@@ -89,7 +106,7 @@ void SimpleCPU::CacheCompletionEvent::process()
 const char *
 SimpleCPU::CacheCompletionEvent::description()
 {
-    return "cache completion event";
+    return "SimpleCPU cache completion event";
 }
 
 #ifdef FULL_SYSTEM
@@ -126,19 +143,10 @@ SimpleCPU::SimpleCPU(const string &_name, Process *_process,
 #ifdef FULL_SYSTEM
     xc = new ExecContext(this, 0, system, itb, dtb, mem);
 
+    // initialize CPU, including PC
     TheISA::initCPU(&xc->regs);
-
-    IntReg *ipr = xc->regs.ipr;
-    ipr[TheISA::IPR_MCSR] = 0x6;
-
-    AlphaISA::swap_palshadow(&xc->regs, true);
-
-    fault = Reset_Fault;
-    xc->regs.pc = ipr[TheISA::IPR_PAL_BASE] + AlphaISA::fault_addr[fault];
-    xc->regs.npc = xc->regs.pc + sizeof(MachInst);
 #else
     xc = new ExecContext(this, /* thread_num */ 0, _process, /* asid */ 0);
-    fault = No_Fault;
 #endif // !FULL_SYSTEM
 
     icacheInterface = icache_interface;
@@ -150,8 +158,9 @@ SimpleCPU::SimpleCPU(const string &_name, Process *_process,
     memReq->data = new uint8_t[64];
 
     numInst = 0;
+    startNumInst = 0;
     numLoad = 0;
-    last_idle = 0;
+    startNumLoad = 0;
     lastIcacheStall = 0;
     lastDcacheStall = 0;
 
@@ -162,7 +171,6 @@ SimpleCPU::~SimpleCPU()
 {
 }
 
-
 void
 SimpleCPU::switchOut()
 {
@@ -208,6 +216,8 @@ SimpleCPU::execCtxStatusChg(int thread_num) {
 void
 SimpleCPU::regStats()
 {
+    using namespace Statistics;
+
     BaseCPU::regStats();
 
     numInsts
@@ -220,11 +230,6 @@ SimpleCPU::regStats()
         .desc("Number of memory references")
         ;
 
-    idleCycles
-        .name(name() + ".idle_cycles")
-        .desc("Number of idle cycles")
-        ;
-
     idleFraction
         .name(name() + ".idle_fraction")
         .desc("Percentage of idle cycles")
@@ -242,60 +247,38 @@ SimpleCPU::regStats()
         .prereq(dcacheStallCycles)
         ;
 
-    idleFraction = idleCycles / simTicks;
-
-    numInsts = Statistics::scalar(numInst);
+    numInsts = Statistics::scalar(numInst) - Statistics::scalar(startNumInst);
     simInsts += numInsts;
 }
 
 void
-SimpleCPU::serialize()
+SimpleCPU::resetStats()
 {
-    nameOut();
-
-#ifdef FULL_SYSTEM
-#if 0
-    // do we need this anymore?? egh
-    childOut("itb", xc->itb);
-    childOut("dtb", xc->dtb);
-    childOut("physmem", physmem);
-#endif
-#endif
-
-    for (int i = 0; i < NumIntRegs; i++) {
-        stringstream buf;
-        ccprintf(buf, "R%02d", i);
-        paramOut(buf.str(), xc->regs.intRegFile[i]);
-    }
-    for (int i = 0; i < NumFloatRegs; i++) {
-        stringstream buf;
-        ccprintf(buf, "F%02d", i);
-        paramOut(buf.str(), xc->regs.floatRegFile.d[i]);
-    }
-    // CPUTraitsType::serializeSpecialRegs(getProxy(), xc->regs);
+    startNumInst = numInst;
 }
 
 void
-SimpleCPU::unserialize(IniFile &db, const string &category, ConfigNode *node)
+SimpleCPU::serialize(ostream &os)
 {
-    string data;
-
-    for (int i = 0; i < NumIntRegs; i++) {
-        stringstream buf;
-        ccprintf(buf, "R%02d", i);
-        db.findDefault(category, buf.str(), data);
-        to_number(data,xc->regs.intRegFile[i]);
-    }
-    for (int i = 0; i < NumFloatRegs; i++) {
-        stringstream buf;
-        ccprintf(buf, "F%02d", i);
-        db.findDefault(category, buf.str(), data);
-        xc->regs.floatRegFile.d[i] = strtod(data.c_str(),NULL);
-    }
-
-    // Read in Special registers
+    SERIALIZE_ENUM(_status);
+    SERIALIZE_SCALAR(inst);
+    nameOut(os, csprintf("%s.xc", name()));
+    xc->serialize(os);
+    nameOut(os, csprintf("%s.tickEvent", name()));
+    tickEvent.serialize(os);
+    nameOut(os, csprintf("%s.cacheCompletionEvent", name()));
+    cacheCompletionEvent.serialize(os);
+}
 
-    // CPUTraitsType::unserializeSpecialRegs(db,category,node,xc->regs);
+void
+SimpleCPU::unserialize(Checkpoint *cp, const string &section)
+{
+    UNSERIALIZE_ENUM(_status);
+    UNSERIALIZE_SCALAR(inst);
+    xc->unserialize(cp, csprintf("%s.xc", section));
+    tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
+    cacheCompletionEvent
+        .unserialize(cp, csprintf("%s.cacheCompletionEvent", section));
 }
 
 void
@@ -524,8 +507,10 @@ SimpleCPU::tick()
 {
     traceData = NULL;
 
+    Fault fault = No_Fault;
+
 #ifdef FULL_SYSTEM
-    if (fault == No_Fault && AlphaISA::check_interrupts &&
+    if (AlphaISA::check_interrupts &&
         xc->cpu->check_interrupts() &&
         !PC_PAL(xc->regs.pc) &&
         status() != IcacheMissComplete) {
@@ -642,7 +627,32 @@ SimpleCPU::tick()
         xc->func_exe_insn++;
 
         fault = si->execute(this, xc, traceData);
-
+#ifdef FS_MEASURE
+        if (!(xc->misspeculating()) && (xc->system->bin)) {
+            SWContext *ctx = xc->swCtx;
+            if (ctx && !ctx->callStack.empty()) {
+                if (si->isCall()) {
+                    ctx->calls++;
+                }
+                if (si->isReturn()) {
+                     if (ctx->calls == 0) {
+                        fnCall *top = ctx->callStack.top();
+                        DPRINTF(TCPIP, "Removing %s from callstack.\n", top->name);
+                        delete top;
+                        ctx->callStack.pop();
+                        if (ctx->callStack.empty())
+                            xc->system->nonPath->activate();
+                        else
+                            ctx->callStack.top()->myBin->activate();
+
+                        xc->system->dumpState(xc);
+                    } else {
+                        ctx->calls--;
+                    }
+                }
+            }
+        }
+#endif
         if (si->isMemRef()) {
             numMemRefs++;
         }