- Clean up and factor out all of the binning code into a
authorNathan Binkert <binkertn@umich.edu>
Fri, 20 Aug 2004 15:35:31 +0000 (11:35 -0400)
committerNathan Binkert <binkertn@umich.edu>
Fri, 20 Aug 2004 15:35:31 +0000 (11:35 -0400)
single place so it's easier to work with.
-  Add support for binning kernel/user/idle time separately from
lisa's binning stuff, but make the two compatible.
-  KernelStats used to directly implement the pImpl idiom, but
it makes more sense to just remove the level of indirection and
make the exec context have a pointer to the stats.
-  Factor common code out of LinuxSystem and Tru64System and put
it into the System base class.  While doing that, make all
constructors take a pointer to a parameter struct instead of
naming the parameters individually to make it much easier to add
parameters to these classes.

SConscript:
    Move the function tracking and binning stuff around.
arch/alpha/ev5.cc:
    kernelStats is now a pointer
arch/alpha/pseudo_inst.cc:
    kernelStats is now a pointer
    the parameters to the system have been moved into their own
    struct
base/trace.hh:
    provide a little functor class for wrapping a string that
    can allow you to define name() in any scope very simply
    for use with DPRINTF
cpu/base_cpu.cc:
    New order of arguments for consistency.
cpu/exec_context.cc:
    kernelStats no longer has the level of indirection in it,
    execContext has the indirection now.  so, kernelStats is a pointer.
    We also need a pointer to the kernelBinning stuff from the system
    and we need to figure out if we want to do binning or not.
    Move a whole bunch of code into kern_binning.cc so it's all
    in the same place.
cpu/exec_context.hh:
    We want pointers to the kernel binning/stats stuff and we'll
    have the exec_context and system have the level of indirection
    instead of having the extra layer in the kernel stats class.
cpu/simple_cpu/simple_cpu.cc:
    call through the exec context to do the special binning
    stuff.
kern/kernel_stats.cc:
kern/kernel_stats.hh:
    Re-organize the stats stuff and remove the level of indirection
    (that was there to simplify building) and move the binning stuff
    into its own class/file.
kern/linux/linux_system.cc:
kern/linux/linux_system.hh:
kern/tru64/tru64_system.cc:
kern/tru64/tru64_system.hh:
sim/system.cc:
sim/system.hh:
    move lots of common system code into the base system class so
    that it can be shared between linux, tru64, and whatever else
    we decide to support in the future.

    Make the constructor take a pointer to a parameter struct so that
    it is easier to pass parameters to the parent.
kern/system_events.cc:
    move the majority of the binning code into the Kernel::Binning class
    in the kern_binning file
kern/system_events.hh:
    FnEvents only need to know the bin
    create the Idle start event to find the PCBB of the idle
    process when it starts.
kern/tru64/tru64_events.cc:
    memCtrl -> memctrl
sim/process.cc:
sim/process.hh:
    re-order args for consistency

--HG--
extra : convert_revision : 86cb39738c41fcd680f2aad125c9dde000227b2b

21 files changed:
SConscript
arch/alpha/ev5.cc
arch/alpha/pseudo_inst.cc
base/trace.hh
cpu/base_cpu.cc
cpu/exec_context.cc
cpu/exec_context.hh
cpu/simple_cpu/simple_cpu.cc
kern/kernel_stats.cc
kern/kernel_stats.hh
kern/linux/linux_system.cc
kern/linux/linux_system.hh
kern/system_events.cc
kern/system_events.hh
kern/tru64/tru64_events.cc
kern/tru64/tru64_system.cc
kern/tru64/tru64_system.hh
sim/process.cc
sim/process.hh
sim/system.cc
sim/system.hh

index 0f2d90c2d888e6705e28947c03f4ceccd4a2d771..f22c85059f66692330f70768370231eed97fa6c2 100644 (file)
@@ -190,7 +190,6 @@ base_sources = Split('''
        sim/sim_object.cc
        sim/stat_context.cc
        sim/stat_control.cc
-       sim/sw_context.cc
        sim/trace_context.cc
        sim/universe.cc
         sim/pyconfig/pyconfig.cc
@@ -288,6 +287,7 @@ full_system_sources = Split('''
        dev/tsunami_pchip.cc
        dev/uart.cc
 
+       kern/kernel_binning.cc
        kern/kernel_stats.cc
        kern/system_events.cc
        kern/linux/linux_events.cc
index b043ed0eef00adbae7adfa8c69b1478bfacb7379..b0f2251dcfe6da25248b01c2c82b26e5769979c0 100644 (file)
@@ -9,6 +9,7 @@
 #include "cpu/base_cpu.hh"
 #include "cpu/exec_context.hh"
 #include "cpu/fast_cpu/fast_cpu.hh"
+#include "kern/kernel_stats.hh"
 #include "sim/debug.hh"
 #include "sim/sim_events.hh"
 
@@ -167,7 +168,7 @@ ExecContext::ev5_trap(Fault fault)
     cpu->recordEvent(csprintf("Fault %s", FaultName(fault)));
 
     assert(!misspeculating());
-    kernelStats.fault(fault);
+    kernelStats->fault(fault);
 
     if (fault == Arithmetic_Fault)
         panic("Arithmetic traps are unimplemented!");
@@ -232,7 +233,7 @@ ExecContext::hwrei()
     setNextPC(ipr[AlphaISA::IPR_EXC_ADDR]);
 
     if (!misspeculating()) {
-        kernelStats.hwrei();
+        kernelStats->hwrei();
 
         if ((ipr[AlphaISA::IPR_EXC_ADDR] & 1) == 0)
             AlphaISA::swap_palshadow(&regs, false);
@@ -415,7 +416,7 @@ ExecContext::setIpr(int idx, uint64_t val)
         // write entire quad w/ no side-effect
         old = ipr[idx];
         ipr[idx] = val;
-        kernelStats.context(old, val);
+        kernelStats->context(old, val);
         break;
 
       case AlphaISA::IPR_DTB_PTE:
@@ -442,11 +443,11 @@ ExecContext::setIpr(int idx, uint64_t val)
 
         // only write least significant five bits - interrupt level
         ipr[idx] = val & 0x1f;
-        kernelStats.swpipl(ipr[idx]);
+        kernelStats->swpipl(ipr[idx]);
         break;
 
       case AlphaISA::IPR_DTB_CM:
-        kernelStats.mode((val & 0x18) != 0);
+        kernelStats->mode((val & 0x18) != 0);
 
       case AlphaISA::IPR_ICM:
         // only write two mode bits - processor mode
@@ -622,7 +623,7 @@ ExecContext::setIpr(int idx, uint64_t val)
 bool
 ExecContext::simPalCheck(int palFunc)
 {
-    kernelStats.callpal(palFunc);
+    kernelStats->callpal(palFunc);
 
     switch (palFunc) {
       case PAL::halt:
index fd674280159a151adb2db91943979839840319f0..95c85b45a9ff50c3e732b6ba77b5efc0fdb0c898 100644 (file)
@@ -37,6 +37,7 @@
 #include "cpu/base_cpu.hh"
 #include "cpu/sampling_cpu/sampling_cpu.hh"
 #include "cpu/exec_context.hh"
+#include "kern/kernel_stats.hh"
 #include "sim/param.hh"
 #include "sim/serialize.hh"
 #include "sim/sim_exit.hh"
@@ -60,7 +61,7 @@ namespace AlphaPseudo
     void
     arm(ExecContext *xc)
     {
-        xc->kernelStats.arm();
+        xc->kernelStats->arm();
     }
 
     void
@@ -70,13 +71,13 @@ namespace AlphaPseudo
             return;
 
         xc->suspend();
-        xc->kernelStats.quiesce();
+        xc->kernelStats->quiesce();
     }
 
     void
     ivlb(ExecContext *xc)
     {
-        xc->kernelStats.ivlb();
+        xc->kernelStats->ivlb();
     }
 
     void
@@ -164,7 +165,7 @@ namespace AlphaPseudo
     void
     readfile(ExecContext *xc)
     {
-        const string &file = xc->cpu->system->readfile;
+        const string &file = xc->cpu->system->params->readfile;
         if (file.empty()) {
             xc->regs.intRegFile[0] = ULL(0);
             return;
index 1aadb36cf98bad7f753811f1493854c682532541..5e05d6e5e6ec23c5564e4875972dc2623de6b5a5 100644 (file)
@@ -157,8 +157,16 @@ namespace Trace {
     extern const std::string DefaultName;
 };
 
-inline const std::string &name() { return Trace::DefaultName; }
+// This silly little class allows us to wrap a string in a functor
+// object so that we can give a name() that DPRINTF will like
+struct StringWrap
+{
+    std::string str;
+    StringWrap(const std::string &s) : str(s) {}
+    const std::string &operator()() const { return str; }
+};
 
+inline const std::string &name() { return Trace::DefaultName; }
 std::ostream &DebugOut();
 
 //
index 3ee7a3892321e64e9824372c44a144302c829ee0..8a9c9a102a659f9ab8e1a337aadd6f65478ed232 100644 (file)
@@ -185,10 +185,10 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
         newXC->takeOverFrom(oldXC);
         assert(newXC->cpu_id == oldXC->cpu_id);
 #ifdef FULL_SYSTEM
-        system->replaceExecContext(newXC->cpu_id, newXC);
+        system->replaceExecContext(newXC, newXC->cpu_id);
 #else
         assert(newXC->process == oldXC->process);
-        newXC->process->replaceExecContext(newXC->cpu_id, newXC);
+        newXC->process->replaceExecContext(newXC, newXC->cpu_id);
 #endif
     }
 
index 9c21b3a56df8a658fa235c71f3f161db36ea8fbb..1cb33f13e5d5cddb0a14e073f5d812849f5af357 100644 (file)
@@ -32,6 +32,9 @@
 #include "cpu/exec_context.hh"
 
 #ifdef FULL_SYSTEM
+#include "base/cprintf.hh"
+#include "kern/kernel_stats.hh"
+#include "sim/serialize.hh"
 #include "sim/system.hh"
 #else
 #include "sim/process.hh"
@@ -44,12 +47,13 @@ using namespace std;
 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), func_exe_inst(0), storeCondFailures(0)
 {
+    kernelStats = new Kernel::Statistics(this);
     memset(&regs, 0, sizeof(RegFile));
 }
 #else
@@ -72,6 +76,13 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
 }
 #endif
 
+ExecContext::~ExecContext()
+{
+#ifdef FULL_SYSTEM
+    delete kernelStats;
+#endif
+}
+
 
 void
 ExecContext::takeOverFrom(ExecContext *oldContext)
@@ -86,9 +97,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,6 +106,14 @@ 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)
@@ -109,31 +125,8 @@ ExecContext::serialize(ostream &os)
     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
+    kernelStats->serialize(os);
+#endif
 }
 
 
@@ -147,35 +140,8 @@ ExecContext::unserialize(Checkpoint *cp, const std::string &section)
     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
+    kernelStats->unserialize(cp, section);
+#endif
 }
 
 
@@ -232,7 +198,7 @@ void
 ExecContext::regStats(const string &name)
 {
 #ifdef FULL_SYSTEM
-    kernelStats.regStats(name + ".kern");
+    kernelStats->regStats(name + ".kern");
 #endif
 }
 
index b47f5cd081b3ae827c841022be6ad6f76e478753..2ba2d7524ffc12011e7cf1acda670358c3f6c2df 100644 (file)
@@ -42,12 +42,12 @@ class BaseCPU;
 
 #ifdef FULL_SYSTEM
 
+#include "sim/system.hh"
 #include "targetarch/alpha_memory.hh"
-class MemoryController;
 
-#include "kern/kernel_stats.hh"
-#include "sim/system.hh"
-#include "sim/sw_context.hh"
+class MemoryController;
+class StaticInstBase;
+namespace Kernel { class Binning; class Statistics; }
 
 #else // !FULL_SYSTEM
 
@@ -105,11 +105,6 @@ class ExecContext
     /// Set the status to Halted.
     void halt();
 
-#ifdef FULL_SYSTEM
-  public:
-    KernelStats kernelStats;
-#endif
-
   public:
     RegFile regs;      // correct-path register context
 
@@ -127,7 +122,6 @@ class ExecContext
     int cpu_id;
 
 #ifdef FULL_SYSTEM
-
     FunctionalMemory *mem;
     AlphaITB *itb;
     AlphaDTB *dtb;
@@ -136,10 +130,15 @@ class ExecContext
     // the following two fields are redundant, since we can always
     // look them up through the system pointer, but we'll leave them
     // here for now for convenience
-    MemoryController *memCtrl;
+    MemoryController *memctrl;
     PhysicalMemory *physmem;
 
-    SWContext *swCtx;
+    Kernel::Binning *kernelBinning;
+    Kernel::Statistics *kernelStats;
+    bool bin;
+    bool fnbin;
+    void execute(const StaticInstBase *inst);
+
 #else
     Process *process;
 
@@ -185,7 +184,7 @@ class ExecContext
     ExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem,
                 int _asid);
 #endif
-    virtual ~ExecContext() {}
+    virtual ~ExecContext();
 
     virtual void takeOverFrom(ExecContext *oldContext);
 
index 6c22d7c81ba5cd08c4c4a7f7dec0ba72ad1f1490..449b20feecccac2e1c8f5e60c7b8d31f67df73f8 100644 (file)
@@ -733,9 +733,8 @@ SimpleCPU::tick()
         fault = si->execute(this, traceData);
 
 #ifdef FULL_SYSTEM
-        SWContext *ctx = xc->swCtx;
-        if (ctx)
-            ctx->process(xc, si.get());
+        if (xc->fnbin)
+            xc->execute(si.get());
 #endif
 
         if (si->isMemRef()) {
index e6bcb4d29c1ead647760a5f6d44ec2fa0d4f5f6a..c8c04e6d14bdda327633fc5b1913440a00bc3194 100644 (file)
 #include <stack>
 #include <string>
 
-#include "base/statistics.hh"
+#include "arch/alpha/osfpal.hh"
 #include "base/trace.hh"
+#include "base/statistics.hh"
+#include "base/stats/bin.hh"
 #include "cpu/exec_context.hh"
+#include "cpu/pc_event.hh"
+#include "cpu/static_inst.hh"
 #include "kern/kernel_stats.hh"
-#include "sim/stats.hh"
-#include "sim/sw_context.hh"
-#include "targetarch/isa_traits.hh"
-#include "targetarch/osfpal.hh"
-#include "targetarch/syscalls.hh"
+#include "kern/linux/linux_syscalls.hh"
 
 using namespace std;
 using namespace Stats;
 
-class KSData
-{
-  private:
-    string _name;
-    ExecContext *xc;
-    BaseCPU *cpu;
-
-  public:
-    KSData(ExecContext *_xc, BaseCPU *_cpu)
-        : xc(_xc), cpu(_cpu), iplLast(0), iplLastTick(0), lastUser(false),
-          lastModeTick(0)
-    {}
-
-    const string &name() { return _name; }
-    void regStats(const string &name);
-
-  public:
-    Scalar<> _arm;
-    Scalar<> _quiesce;
-    Scalar<> _ivlb;
-    Scalar<> _ivle;
-    Scalar<> _hwrei;
-
-    Vector<> _iplCount;
-    Vector<> _iplGood;
-    Vector<> _iplTicks;
-    Formula _iplUsed;
-
-    Vector<> _callpal;
-    Vector<> _syscall;
-    Vector<> _faults;
-
-    Vector<> _mode;
-    Vector<> _modeGood;
-    Formula _modeFraction;
-    Vector<> _modeTicks;
-
-    Scalar<> _swap_context;
-
-  private:
-    int iplLast;
-    Tick iplLastTick;
-
-    bool lastUser;
-    Tick lastModeTick;
-
-  public:
-    void swpipl(int ipl);
-    void mode(bool user);
-    void callpal(int code);
-};
-
-KernelStats::KernelStats(ExecContext *xc, BaseCPU *cpu)
-{ data = new KSData(xc, cpu); }
-
-KernelStats::~KernelStats()
-{ delete data; }
+namespace Kernel {
 
-void
-KernelStats::regStats(const string &name)
-{ data->regStats(name); }
+const char *modestr[] = { "kernel", "user", "idle" };
+
+Statistics::Statistics(ExecContext *context)
+    : xc(context), idleProcess((Addr)-1), themode(kernel), lastModeTick(0),
+      iplLast(0), iplLastTick(0)
+{
+}
 
 void
-KSData::regStats(const string &name)
+Statistics::regStats(const string &_name)
 {
-    _name = name;
+    myname = _name;
 
     _arm
-        .name(name + ".inst.arm")
+        .name(name() + ".inst.arm")
         .desc("number of arm instructions executed")
         ;
 
     _quiesce
-        .name(name + ".inst.quiesce")
+        .name(name() + ".inst.quiesce")
         .desc("number of quiesce instructions executed")
         ;
 
     _ivlb
-        .name(name + ".inst.ivlb")
+        .name(name() + ".inst.ivlb")
         .desc("number of ivlb instructions executed")
         ;
 
     _ivle
-        .name(name + ".inst.ivle")
+        .name(name() + ".inst.ivle")
         .desc("number of ivle instructions executed")
         ;
 
     _hwrei
-        .name(name + ".inst.hwrei")
+        .name(name() + ".inst.hwrei")
         .desc("number of hwrei instructions executed")
         ;
 
     _iplCount
         .init(32)
-        .name(name + ".ipl_count")
+        .name(name() + ".ipl_count")
         .desc("number of times we switched to this ipl")
         .flags(total | pdf | nozero | nonan)
         ;
 
     _iplGood
         .init(32)
-        .name(name + ".ipl_good")
+        .name(name() + ".ipl_good")
         .desc("number of times we switched to this ipl from a different ipl")
         .flags(total | pdf | nozero | nonan)
         ;
 
     _iplTicks
         .init(32)
-        .name(name + ".ipl_ticks")
+        .name(name() + ".ipl_ticks")
         .desc("number of cycles we spent at this ipl")
         .flags(total | pdf | nozero | nonan)
         ;
 
     _iplUsed
-        .name(name + ".ipl_used")
+        .name(name() + ".ipl_used")
         .desc("fraction of swpipl calls that actually changed the ipl")
         .flags(total | nozero | nonan)
         ;
@@ -166,7 +114,7 @@ KSData::regStats(const string &name)
 
     _callpal
         .init(256)
-        .name(name + ".callpal")
+        .name(name() + ".callpal")
         .desc("number of callpals executed")
         .flags(total | pdf | nozero | nonan)
         ;
@@ -179,7 +127,7 @@ KSData::regStats(const string &name)
 
     _syscall
         .init(SystemCalls<Tru64>::Number)
-        .name(name + ".syscall")
+        .name(name() + ".syscall")
         .desc("number of syscalls executed")
         .flags(total | pdf | nozero | nonan)
         ;
@@ -193,7 +141,7 @@ KSData::regStats(const string &name)
 
     _faults
         .init(Num_Faults)
-        .name(name + ".faults")
+        .name(name() + ".faults")
         .desc("number of faults")
         .flags(total | pdf | nozero | nonan)
         ;
@@ -205,85 +153,79 @@ KSData::regStats(const string &name)
     }
 
     _mode
-        .init(2)
-        .name(name + ".mode_switch")
-        .subname(0, "kernel")
-        .subname(1, "user")
+        .init(3)
+        .name(name() + ".mode_switch")
         .desc("number of protection mode switches")
         ;
 
+    for (int i = 0; i < 3; ++i)
+        _mode.subname(i, modestr[i]);
+
     _modeGood
-        .init(2)
-        .name(name + ".mode_good")
+        .init(3)
+        .name(name() + ".mode_good")
         ;
 
+    for (int i = 0; i < 3; ++i)
+        _modeGood.subname(i, modestr[i]);
+
     _modeFraction
-        .name(name + ".mode_switch_good")
-        .subname(0, "kernel")
-        .subname(1, "user")
+        .name(name() + ".mode_switch_good")
         .desc("fraction of useful protection mode switches")
         .flags(total)
         ;
+
+    for (int i = 0; i < 3; ++i)
+        _modeFraction.subname(i, modestr[i]);
+
     _modeFraction = _modeGood / _mode;
 
     _modeTicks
-        .init(2)
-        .name(name + ".mode_ticks")
-        .subname(0, "kernel")
-        .subname(1, "user")
+        .init(3)
+        .name(name() + ".mode_ticks")
         .desc("number of ticks spent at the given mode")
         .flags(pdf)
         ;
+    for (int i = 0; i < 3; ++i)
+        _modeTicks.subname(i, modestr[i]);
 
     _swap_context
-        .name(name + ".swap_context")
+        .name(name() + ".swap_context")
         .desc("number of times the context was actually changed")
         ;
 }
 
 void
-KernelStats::arm()
-{ data->_arm++; }
-
-void
-KernelStats::quiesce()
-{ data->_quiesce++; }
-
-void
-KernelStats::ivlb()
-{ data->_ivlb++; }
-
-void
-KernelStats::ivle()
-{ data->_ivle++; }
+Statistics::setIdleProcess(Addr idlepcbb)
+{
+    assert(themode == kernel);
+    idleProcess = idlepcbb;
+    themode = idle;
+    changeMode(themode);
+}
 
 void
-KernelStats::hwrei()
-{ data->_hwrei++; }
+Statistics::changeMode(cpu_mode newmode)
+{
+    _mode[newmode]++;
 
-void
-KernelStats::fault(Fault fault)
-{ data->_faults[fault]++; }
+    if (newmode == themode)
+        return;
 
-void
-KernelStats::swpipl(int ipl)
-{ data->swpipl(ipl); }
+    DPRINTF(Context, "old mode=%-8s new mode=%-8s\n",
+            modestr[themode], modestr[newmode]);
 
-void
-KernelStats::mode(bool user)
-{ data->mode(user); }
+    _modeGood[newmode]++;
+    _modeTicks[themode] += curTick - lastModeTick;
 
-void
-KernelStats::context(Addr old_pcbb, Addr new_pcbb)
-{ data->_swap_context++; }
-
-void
-KernelStats::callpal(int code)
-{ data->callpal(code); }
+    xc->system->kernelBinning->changeMode(newmode);
 
+    lastModeTick = curTick;
+    themode = newmode;
+}
 
 void
-KSData::swpipl(int ipl)
+Statistics::swpipl(int ipl)
 {
     assert(ipl >= 0 && ipl <= 0x1f && "invalid IPL\n");
 
@@ -299,30 +241,28 @@ KSData::swpipl(int ipl)
 }
 
 void
-KSData::mode(bool user)
+Statistics::mode(bool usermode)
 {
-    _mode[user]++;
-    if (user == lastUser)
-        return;
+    Addr pcbb = xc->regs.ipr[AlphaISA::IPR_PALtemp23];
 
-    _modeGood[user]++;
-    _modeTicks[lastUser] += curTick - lastModeTick;
+    cpu_mode newmode = usermode ? user : kernel;
+    if (newmode == kernel && pcbb == idleProcess)
+        newmode = idle;
 
-    lastModeTick = curTick;
-    lastUser = user;
-
-    if (xc->system->bin) {
-        if (!xc->swCtx || xc->swCtx->callStack.empty()) {
-            if (user)
-                xc->system->User->activate();
-            else
-                xc->system->Kernel->activate();
-        }
-    }
+    changeMode(newmode);
+}
+
+void
+Statistics::context(Addr oldpcbb, Addr newpcbb)
+{
+    assert(themode != user);
+
+    _swap_context++;
+    changeMode(newpcbb == idleProcess ? idle : kernel);
 }
 
 void
-KSData::callpal(int code)
+Statistics::callpal(int code)
 {
     if (!PAL::name(code))
         return;
@@ -330,63 +270,34 @@ KSData::callpal(int code)
     _callpal[code]++;
 
     switch (code) {
-      case PAL::callsys:
-        {
-            int number = xc->regs.intRegFile[0];
-            if (SystemCalls<Tru64>::validSyscallNumber(number)) {
-                int cvtnum = SystemCalls<Tru64>::convert(number);
-                _syscall[cvtnum]++;
-            }
-        }
+      case PAL::callsys: {
+          int number = xc->regs.intRegFile[0];
+          if (SystemCalls<Tru64>::validSyscallNumber(number)) {
+              int cvtnum = SystemCalls<Tru64>::convert(number);
+              _syscall[cvtnum]++;
+          }
+      } break;
+
+      case PAL::swpctx:
+        if (xc->system->kernelBinning)
+            xc->system->kernelBinning->palSwapContext(xc);
         break;
     }
+}
 
-    if (code == PAL::swpctx) {
-        SWContext *out = xc->swCtx;
-        System *sys = xc->system;
-        if (!sys->bin)
-            return;
-        DPRINTF(TCPIP, "swpctx event\n");
-        if (out) {
-            DPRINTF(TCPIP, "swapping context out with this stack!\n");
-            xc->system->dumpState(xc);
-            Addr oldPCB = xc->regs.ipr[TheISA::IPR_PALtemp23];
-
-            if (out->callStack.empty()) {
-                DPRINTF(TCPIP, "but removing it, cuz empty!\n");
-                SWContext *find = sys->findContext(oldPCB);
-                if (find) {
-                    assert(sys->findContext(oldPCB) == out);
-                    sys->remContext(oldPCB);
-                }
-                delete out;
-            } else {
-                DPRINTF(TCPIP, "switching out context with pcb %#x, top fn %s\n",
-                        oldPCB, out->callStack.top()->name);
-                if (!sys->findContext(oldPCB)) {
-                    if (!sys->addContext(oldPCB, out))
-                        panic("could not add context");
-                }
-            }
-        }
+void
+Statistics::serialize(ostream &os)
+{
+    int exemode = themode;
+    SERIALIZE_SCALAR(exemode);
+}
 
-        Addr newPCB = xc->regs.intRegFile[16];
-        SWContext *in = sys->findContext(newPCB);
-        xc->swCtx = in;
-
-        if (in) {
-            assert(!in->callStack.empty() &&
-                   "should not be switching in empty context");
-            DPRINTF(TCPIP, "swapping context in with this callstack!\n");
-            xc->system->dumpState(xc);
-            sys->remContext(newPCB);
-            fnCall *top = in->callStack.top();
-            DPRINTF(TCPIP, "switching in to pcb %#x, %s\n", newPCB, top->name);
-            assert(top->myBin && "should not switch to context with no Bin");
-            top->myBin->activate();
-        } else {
-            sys->Kernel->activate();
-        }
-        DPRINTF(TCPIP, "end swpctx\n");
-    }
+void
+Statistics::unserialize(Checkpoint *cp, const string &section)
+{
+    int exemode;
+    UNSERIALIZE_SCALAR(exemode);
+    themode = (cpu_mode)exemode;
 }
+
+/* end namespace Kernel */ }
index 49740376231c5758b1668e96a6566dd371ca25d4..8339c578c4430325fc4e75d83adc497f3e56be3b 100644 (file)
 #ifndef __KERNEL_STATS_HH__
 #define __KERNEL_STATS_HH__
 
+#include <map>
+#include <stack>
 #include <string>
+#include <vector>
+
+#include "base/statistics.hh"
+#include "sim/serialize.hh"
+#include "targetarch/isa_traits.hh"
 
-class KSData;
-class ExecContext;
 class BaseCPU;
+class ExecContext;
+class FnEvent;
 enum Fault;
 
-class KernelStats
+namespace Kernel {
+
+enum cpu_mode { kernel, user, idle, cpu_mode_num };
+extern const char *modestr[];
+
+class Binning
 {
   private:
-    KSData *data;
+    std::string myname;
+    System *system;
+
+  private:
+    // lisa's binning stuff
+    struct fnCall
+    {
+        Stats::MainBin *myBin;
+        std::string name;
+    };
+
+    struct SWContext
+    {
+        Counter calls;
+        std::stack<fnCall *> callStack;
+    };
+
+    std::map<const std::string, Stats::MainBin *> fnBins;
+    std::map<const Addr, SWContext *> swCtxMap;
+
+    std::multimap<const std::string, std::string> callerMap;
+    void populateMap(std::string caller, std::string callee);
+
+    std::vector<FnEvent *> fnEvents;
+
+    Stats::Scalar<> fnCalls;
+
+    Stats::MainBin *getBin(const std::string &name);
+    bool findCaller(std::string, std::string) const;
+
+    SWContext *findContext(Addr pcb);
+    bool addContext(Addr pcb, SWContext *ctx)
+    {
+        return (swCtxMap.insert(std::make_pair(pcb, ctx))).second;
+    }
+
+    void remContext(Addr pcb)
+    {
+        swCtxMap.erase(pcb);
+    }
+
+    void dumpState() const;
+
+    SWContext *swctx;
+    std::vector<std::string> binned_fns;
+
+  private:
+    Stats::MainBin *modeBin[3];
+
+  public:
+    const bool bin;
+    const bool fnbin;
+
+    cpu_mode themode;
+    void palSwapContext(ExecContext *xc);
+    void execute(ExecContext *xc, const StaticInstBase *inst);
+    void call(ExecContext *xc, Stats::MainBin *myBin);
+    void changeMode(cpu_mode mode);
 
   public:
-    KernelStats(ExecContext *_xc, BaseCPU *_cpu);
-    ~KernelStats();
+    Binning(System *sys);
+    virtual ~Binning();
 
+    const std::string name() const { return myname; }
     void regStats(const std::string &name);
 
-    void arm();
-    void quiesce();
-    void ivlb();
-    void ivle();
-    void hwrei();
+  public:
+    virtual void serialize(std::ostream &os);
+    virtual void unserialize(Checkpoint *cp, const std::string &section);
+};
 
-    void fault(Fault fault);
+class Statistics : public Serializable
+{
+    friend class Binning;
+
+  private:
+    std::string myname;
+    ExecContext *xc;
+
+    Addr idleProcess;
+    cpu_mode themode;
+    Tick lastModeTick;
+
+    void changeMode(cpu_mode newmode);
+
+  private:
+    Stats::Scalar<> _arm;
+    Stats::Scalar<> _quiesce;
+    Stats::Scalar<> _ivlb;
+    Stats::Scalar<> _ivle;
+    Stats::Scalar<> _hwrei;
+
+    Stats::Vector<> _iplCount;
+    Stats::Vector<> _iplGood;
+    Stats::Vector<> _iplTicks;
+    Stats::Formula _iplUsed;
+
+    Stats::Vector<> _callpal;
+    Stats::Vector<> _syscall;
+    Stats::Vector<> _faults;
+
+    Stats::Vector<> _mode;
+    Stats::Vector<> _modeGood;
+    Stats::Formula _modeFraction;
+    Stats::Vector<> _modeTicks;
+
+    Stats::Scalar<> _swap_context;
+
+  private:
+    int iplLast;
+    Tick iplLastTick;
+
+  public:
+    Statistics(ExecContext *context);
+
+    const std::string name() const { return myname; }
+    void regStats(const std::string &name);
+
+  public:
+    void arm() { _arm++; }
+    void quiesce() { _quiesce++; }
+    void ivlb() { _ivlb++; }
+    void ivle() { _ivle++; }
+    void hwrei() { _hwrei++; }
+    void fault(Fault fault) { _faults[fault]++; }
     void swpipl(int ipl);
-    void mode(bool user);
-    void context(Addr old_pcbb, Addr new_pcbb);
+    void mode(bool usermode);
+    void context(Addr oldpcbb, Addr newpcbb);
     void callpal(int code);
+
+    void setIdleProcess(Addr idle);
+
+  public:
+    virtual void serialize(std::ostream &os);
+    virtual void unserialize(Checkpoint *cp, const std::string &section);
 };
 
+/* end namespace Kernel */ }
+
 #endif // __KERNEL_STATS_HH__
index dd188ffe07cdd78aa06ee80d64ce782ef6c7a24a..10641de874644f742b365e0c1146761af8aab748 100644 (file)
  * up boot time.
  */
 
-#include "base/loader/aout_object.hh"
-#include "base/loader/elf_object.hh"
-#include "base/loader/object_file.hh"
-#include "base/loader/symtab.hh"
-#include "base/remote_gdb.hh"
 #include "base/trace.hh"
 #include "cpu/exec_context.hh"
 #include "cpu/base_cpu.hh"
@@ -58,88 +53,15 @@ extern SymbolTable *debugSymbolTable;
 
 using namespace std;
 
-LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
-                         MemoryController *_memCtrl, PhysicalMemory *_physmem,
-                         const string &kernel_path, const string &console_path,
-                         const string &palcode, const string &boot_osflags,
-                         const bool _bin, const vector<string> &_binned_fns)
-     : System(_name, _init_param, _memCtrl, _physmem, _bin, _binned_fns),
-       bin(_bin), binned_fns(_binned_fns)
+LinuxSystem::LinuxSystem(Params *p)
+    : System(p)
 {
-    kernelSymtab = new SymbolTable;
-    consoleSymtab = new SymbolTable;
-
-    /**
-     * Load the kernel, pal, and console code into memory
-     */
-    // Load kernel code
-    ObjectFile *kernel = createObjectFile(kernel_path);
-    if (kernel == NULL)
-        fatal("Could not load kernel file %s", kernel_path);
-
-    // Load Console Code
-    ObjectFile *console = createObjectFile(console_path);
-    if (console == NULL)
-        fatal("Could not load console file %s", console_path);
-
-    // Load pal file
-    ObjectFile *pal = createObjectFile(palcode);
-    if (pal == NULL)
-        fatal("Could not load PALcode file %s", palcode);
-    pal->loadSections(physmem, true);
-
-    // Load console file
-    console->loadSections(physmem, true);
-
-    // Load kernel file
-    kernel->loadSections(physmem, true);
-    kernelStart = kernel->textBase();
-    kernelEnd = kernel->bssBase() + kernel->bssSize();
-    kernelEntry = kernel->entryPoint();
-
-    // load symbols
-    if (!kernel->loadGlobalSymbols(kernelSymtab))
-        panic("could not load kernel symbols\n");
-        debugSymbolTable = kernelSymtab;
-
-    if (!kernel->loadLocalSymbols(kernelSymtab))
-        panic("could not load kernel local symbols\n");
-
-    if (!console->loadGlobalSymbols(consoleSymtab))
-        panic("could not load console symbols\n");
-
-    DPRINTF(Loader, "Kernel start = %#x\n"
-            "Kernel end   = %#x\n"
-            "Kernel entry = %#x\n",
-            kernelStart, kernelEnd, kernelEntry);
-
-    DPRINTF(Loader, "Kernel loaded...\n");
-
-
-#ifdef DEBUG
-    kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic");
-    consolePanicEvent = new BreakPCEvent(&pcEventQueue, "console panic");
-#endif
-
-    skipIdeDelay50msEvent = new SkipFuncEvent(&pcEventQueue,
-                                              "ide_delay_50ms");
-
-    skipDelayLoopEvent = new LinuxSkipDelayLoopEvent(&pcEventQueue,
-                                                     "calibrate_delay");
-
-    skipCacheProbeEvent = new SkipFuncEvent(&pcEventQueue,
-                                            "determine_cpu_caches");
-
-    debugPrintkEvent = new DebugPrintkEvent(&pcEventQueue, "dprintk");
-
-    printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo");
-
     Addr addr = 0;
 
     /**
-     * find the address of the est_cycle_freq variable and insert it so we don't
-     * through the lengthly process of trying to calculated it by using the PIT,
-     * RTC, etc.
+     * find the address of the est_cycle_freq variable and insert it
+     * so we don't through the lengthly process of trying to
+     * calculated it by using the PIT, RTC, etc.
      */
     if (kernelSymtab->findAddress("est_cycle_freq", addr)) {
         Addr paddr = vtophys(physmem, addr);
@@ -151,19 +73,6 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
     }
 
 
-    /**
-     * Copy the osflags (kernel arguments) into the consoles memory. Presently
-     * Linux does use the console service routine to get these command line
-     * arguments, but we might as well make them available just in case.
-     */
-    if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
-        Addr paddr = vtophys(physmem, addr);
-        char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t));
-
-        if (osflags)
-              strcpy(osflags, boot_osflags.c_str());
-    }
-
     /**
      * Since we aren't using a bootloader, we have to copy the kernel arguments
      * directly into the kernels memory.
@@ -172,31 +81,10 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
         Addr paddr = vtophys(physmem, PARAM_ADDR);
         char *commandline = (char*)physmem->dma_addr(paddr, sizeof(uint64_t));
         if (commandline)
-            strcpy(commandline, boot_osflags.c_str());
+            strcpy(commandline, params->boot_osflags.c_str());
     }
 
 
-    /**
-     * Set the hardware reset parameter block system type and revision
-     * information to Tsunami.
-     */
-    if (consoleSymtab->findAddress("xxm_rpb", addr)) {
-        Addr paddr = vtophys(physmem, addr);
-        char *hwprb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t));
-
-        if (hwprb) {
-            // Tsunami
-            *(uint64_t*)(hwprb + 0x50) = htoa(ULL(34));
-
-            // Plain DP264
-            *(uint64_t*)(hwprb + 0x58) = htoa(ULL(1) << 10);
-        }
-        else
-            panic("could not translate hwprb addr to set system type/variation\n");
-
-    } else
-        panic("could not find hwprb to set system type/variation\n");
-
     /**
      * EV5 only supports 127 ASNs so we are going to tell the kernel that the
      * paritiuclar EV6 we have only supports 127 asns.
@@ -210,59 +98,63 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
         if (dp264_mv) {
             *(uint32_t*)(dp264_mv+0x18) = htoa((uint32_t)127);
         } else
-            panic("could not translate dp264_mv addr to set the MAX_ASN to 127\n");
+            panic("could not translate dp264_mv addr\n");
 
     } else
-        panic("could not find dp264_mv to set the MAX_ASN to 127\n");
-
-
+        panic("could not find dp264_mv\n");
 
 #ifdef DEBUG
+    kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic");
     if (kernelSymtab->findAddress("panic", addr))
         kernelPanicEvent->schedule(addr);
     else
         panic("could not find kernel symbol \'panic\'");
-
-    if (consoleSymtab->findAddress("panic", addr))
-        consolePanicEvent->schedule(addr);
 #endif
 
     /**
-     * Any time ide_delay_50ms, calibarte_delay or determine_cpu_caches is called
-     * just skip the function. Currently determine_cpu_caches only is used put
-     * information in proc, however if that changes in the future we will have to
-     * fill in the cache size variables appropriately.
+     * Any time ide_delay_50ms, calibarte_delay or
+     * determine_cpu_caches is called just skip the
+     * function. Currently determine_cpu_caches only is used put
+     * information in proc, however if that changes in the future we
+     * will have to fill in the cache size variables appropriately.
      */
+    skipIdeDelay50msEvent = new SkipFuncEvent(&pcEventQueue, "ide_delay_50ms");
     if (kernelSymtab->findAddress("ide_delay_50ms", addr))
         skipIdeDelay50msEvent->schedule(addr+sizeof(MachInst));
 
+    skipDelayLoopEvent = new LinuxSkipDelayLoopEvent(&pcEventQueue,
+                                                     "calibrate_delay");
     if (kernelSymtab->findAddress("calibrate_delay", addr))
         skipDelayLoopEvent->schedule(addr+sizeof(MachInst));
 
+    skipCacheProbeEvent = new SkipFuncEvent(&pcEventQueue,
+                                            "determine_cpu_caches");
     if (kernelSymtab->findAddress("determine_cpu_caches", addr))
         skipCacheProbeEvent->schedule(addr+sizeof(MachInst));
 
+    debugPrintkEvent = new DebugPrintkEvent(&pcEventQueue, "dprintk");
     if (kernelSymtab->findAddress("dprintk", addr))
-        debugPrintkEvent->schedule(addr+sizeof(MachInst)*2);
+        debugPrintkEvent->schedule(addr+8);
+
+    idleStartEvent = new IdleStartEvent(&pcEventQueue, "cpu_idle", this);
+    if (kernelSymtab->findAddress("cpu_idle", addr))
+        idleStartEvent->schedule(addr);
 
-    if (kernelSymtab->findAddress("alpha_switch_to", addr) &&
-            DTRACE(Thread))
-        printThreadEvent->schedule(addr+sizeof(MachInst)*6);
+    printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo");
+    if (kernelSymtab->findAddress("alpha_switch_to", addr) && DTRACE(Thread))
+        printThreadEvent->schedule(addr + sizeof(MachInst) * 6);
 }
 
 LinuxSystem::~LinuxSystem()
 {
-    delete kernel;
-    delete console;
-
-    delete kernelSymtab;
-    delete consoleSymtab;
-
+#ifdef DEBUG
     delete kernelPanicEvent;
-    delete consolePanicEvent;
+#endif
     delete skipIdeDelay50msEvent;
     delete skipDelayLoopEvent;
     delete skipCacheProbeEvent;
+    delete debugPrintkEvent;
+    delete idleStartEvent;
 }
 
 
@@ -283,92 +175,64 @@ LinuxSystem::setDelayLoop(ExecContext *xc)
     }
 }
 
-int
-LinuxSystem::registerExecContext(ExecContext *xc)
-{
-    int xcIndex = System::registerExecContext(xc);
-
-    if (xcIndex == 0) {
-        // activate with zero delay so that we start ticking right
-        // away on cycle 0
-        xc->activate(0);
-    }
-
-    RemoteGDB *rgdb = new RemoteGDB(this, xc);
-    GDBListener *gdbl = new GDBListener(rgdb, 7000 + xcIndex);
-    gdbl->listen();
-    /**
-     * Uncommenting this line waits for a remote debugger to connect
-     * to the simulator before continuing.
-     */
-    //gdbl->accept();
-
-    if (remoteGDB.size() <= xcIndex) {
-        remoteGDB.resize(xcIndex+1);
-    }
-
-    remoteGDB[xcIndex] = rgdb;
-
-    return xcIndex;
-}
-
-
-void
-LinuxSystem::replaceExecContext(ExecContext *xc, int xcIndex)
-{
-    System::replaceExecContext(xcIndex, xc);
-    remoteGDB[xcIndex]->replaceExecContext(xc);
-}
-
-bool
-LinuxSystem::breakpoint()
-{
-    return remoteGDB[0]->trap(ALPHA_KENTRY_IF);
-}
-
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
 
-    Param<bool> bin;
     SimObjectParam<MemoryController *> mem_ctl;
     SimObjectParam<PhysicalMemory *> physmem;
-    Param<uint64_t> init_param;
 
     Param<string> kernel_code;
     Param<string> console_code;
     Param<string> pal_code;
-    Param<string> boot_osflags;
-    VectorParam<string> binned_fns;
 
+    Param<string> boot_osflags;
     Param<string> readfile;
+    Param<unsigned int> init_param;
+
+    Param<uint64_t> system_type;
+    Param<uint64_t> system_rev;
+
+    Param<bool> bin;
+    VectorParam<string> binned_fns;
 
 END_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
 
 BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxSystem)
 
-
-    INIT_PARAM_DFLT(bin, "is this system to be binned", false),
     INIT_PARAM(mem_ctl, "memory controller"),
     INIT_PARAM(physmem, "phsyical memory"),
-    INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
-    INIT_PARAM(kernel_code, "file that contains the code"),
+    INIT_PARAM(kernel_code, "file that contains the kernel code"),
     INIT_PARAM(console_code, "file that contains the console code"),
     INIT_PARAM(pal_code, "file that contains palcode"),
     INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
-                                   "a"),
-    INIT_PARAM(binned_fns, "functions to be broken down and binned"),
-    INIT_PARAM_DFLT(readfile, "file to read startup script from", "")
-
+                    "a"),
+    INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
+    INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
+    INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
+    INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10),
+    INIT_PARAM_DFLT(bin, "is this system to be binned", false),
+    INIT_PARAM(binned_fns, "functions to be broken down and binned")
 
 END_INIT_SIM_OBJECT_PARAMS(LinuxSystem)
 
 CREATE_SIM_OBJECT(LinuxSystem)
 {
-    LinuxSystem *sys = new LinuxSystem(getInstanceName(), init_param, mem_ctl,
-                                       physmem, kernel_code, console_code,
-                                       pal_code, boot_osflags, bin, binned_fns);
-
-    sys->readfile = readfile;
-    return sys;
+    System::Params *p = new System::Params;
+    p->name = getInstanceName();
+    p->memctrl = mem_ctl;
+    p->physmem = physmem;
+    p->kernel_path = kernel_code;
+    p->console_path = console_code;
+    p->palcode = pal_code;
+    p->boot_osflags = boot_osflags;
+    p->init_param = init_param;
+    p->readfile = readfile;
+    p->system_type = system_type;
+    p->system_rev = system_rev;
+    p->bin = bin;
+    p->binned_fns = binned_fns;
+
+    return new LinuxSystem(p);
 }
 
 REGISTER_SIM_OBJECT("LinuxSystem", LinuxSystem)
+
index fbfcb788f671859319790277a738286feb18c6e4..7072046077cc992e4253d063e38e1f99fe8eceaf 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef __LINUX_SYSTEM_HH__
-#define __LINUX_SYSTEM_HH__
+#ifndef __KERN_LINUX_LINUX_SYSTEM_HH__
+#define __KERN_LINUX_LINUX_SYSTEM_HH__
 
-#include <vector>
-
-#include "sim/system.hh"
 #include "sim/host.hh"
+#include "sim/system.hh"
 #include "targetarch/isa_traits.hh"
 
-#include <map>
-
 /**
  * MAGIC address where the kernel arguments should go. Defined as
  * PARAM in linux kernel alpha-asm.
  */
-const Addr PARAM_ADDR =  ULL(0xfffffc000030a000);
+const Addr PARAM_ADDR = ULL(0xfffffc000030a000);
 
 class ExecContext;
-class ElfObject;
-class SymbolTable;
+
+class BreakPCEvent;
 class DebugPrintkEvent;
 class BreakPCEvent;
 class LinuxSkipDelayLoopEvent;
 class SkipFuncEvent;
-class FnEvent;
-class AlphaArguments;
+class IdleStartEvent;
 class PrintThreadInfo;
 
 /**
@@ -62,96 +57,42 @@ class PrintThreadInfo;
 class LinuxSystem : public System
 {
   private:
-    /** Object pointer for the kernel code */
-    ElfObject *kernel;
-
-    /** Object pointer for the console code */
-    ElfObject *console;
-
-    /** kernel Symbol table */
-    SymbolTable *kernelSymtab;
-
-    /** console symbol table */
-    SymbolTable *consoleSymtab;
-
+#ifdef DEBUG
     /** Event to halt the simulator if the kernel calls panic()  */
     BreakPCEvent *kernelPanicEvent;
+#endif
 
-    /** Event to halt the simulator if the console calls panic() */
-    BreakPCEvent *consolePanicEvent;
-
-    /** Event to skip determine_cpu_caches() because we don't support the
-     * IPRs that the code can access to figure out cache sizes
+    /**
+     * Event to skip determine_cpu_caches() because we don't support
+     * the IPRs that the code can access to figure out cache sizes
      */
     SkipFuncEvent *skipCacheProbeEvent;
 
     /** PC based event to skip the ide_delay_50ms() call */
     SkipFuncEvent *skipIdeDelay50msEvent;
 
-    /** PC based event to skip the dprink() call and emulate its functionality */
+    /**
+     * PC based event to skip the dprink() call and emulate its
+     * functionality
+     */
     DebugPrintkEvent *debugPrintkEvent;
 
-    /** Skip calculate_delay_loop() rather than waiting for this to be
+    /**
+     * Skip calculate_delay_loop() rather than waiting for this to be
      * calculated
      */
     LinuxSkipDelayLoopEvent *skipDelayLoopEvent;
 
     PrintThreadInfo *printThreadEvent;
 
-    /** Begining of kernel code */
-    Addr kernelStart;
-
-    /** End of kernel code */
-    Addr kernelEnd;
-
-    /** Entry point in the kernel to start at */
-    Addr kernelEntry;
-
-    bool bin;
-    std::vector<string> binned_fns;
+    /** Grab the PCBB of the idle process when it starts */
+    IdleStartEvent *idleStartEvent;
 
   public:
-    std::vector<RemoteGDB *>   remoteGDB;
-    std::vector<GDBListener *> gdbListen;
-
-    LinuxSystem(const std::string _name,
-                const uint64_t _init_param,
-                MemoryController *_memCtrl,
-                PhysicalMemory *_physmem,
-                const std::string &kernel_path,
-                const std::string &console_path,
-                const std::string &palcode,
-                const std::string &boot_osflags,
-                const bool _bin,
-                const std::vector<std::string> &_binned_fns);
-
+    LinuxSystem(Params *p);
     ~LinuxSystem();
 
     void setDelayLoop(ExecContext *xc);
-
-    int registerExecContext(ExecContext *xc);
-    void replaceExecContext(ExecContext *xc, int xcIndex);
-
-    /**
-     * Returns the addess the kernel starts at.
-     * @return address the kernel starts at
-     */
-    Addr getKernelStart() const { return kernelStart; }
-
-    /**
-     * Returns the addess the kernel ends at.
-     * @return address the kernel ends at
-     */
-    Addr getKernelEnd() const { return kernelEnd; }
-
-    /**
-     * Returns the addess the entry point to the kernel code.
-     * @return entry point of the kernel code
-     */
-    Addr getKernelEntry() const { return kernelEntry; }
-
-
-    bool breakpoint();
 };
 
-#endif // __LINUX_SYSTEM_HH__
+#endif // __KERN_LINUX_LINUX_SYSTEM_HH__
index 351c3ddb2c0fd0e3ab59069f91bb1b4b7ffaff91..91daf53ca4e80339cfabf9ade0174d0f609e3a80 100644 (file)
@@ -30,9 +30,9 @@
 #include "cpu/base_cpu.hh"
 #include "cpu/full_cpu/bpred.hh"
 #include "cpu/full_cpu/full_cpu.hh"
+#include "kern/kernel_stats.hh"
 #include "kern/system_events.hh"
 #include "sim/system.hh"
-#include "sim/sw_context.hh"
 
 void
 SkipFuncEvent::process(ExecContext *xc)
@@ -52,11 +52,9 @@ SkipFuncEvent::process(ExecContext *xc)
 }
 
 
-FnEvent::FnEvent(PCEventQueue *q, const std::string & desc, System *system)
-    : PCEvent(q, desc), _name(desc)
+FnEvent::FnEvent(PCEventQueue *q, const std::string &desc, Stats::MainBin *bin)
+    : PCEvent(q, desc), _name(desc), mybin(bin)
 {
-    myBin = system->getBin(desc);
-    assert(myBin);
 }
 
 void
@@ -64,46 +62,12 @@ FnEvent::process(ExecContext *xc)
 {
     if (xc->misspeculating())
         return;
-    assert(xc->system->bin && "FnEvent must be in a binned system");
-    SWContext *ctx = xc->swCtx;
-    DPRINTF(TCPIP, "%s: %s Event!!!\n", xc->system->name(), description);
 
-    if (ctx && !ctx->callStack.empty()) {
-        DPRINTF(TCPIP, "already a callstack!\n");
-        fnCall *last = ctx->callStack.top();
-
-        if (last->name == "idle_thread")
-            ctx->calls++;
-
-        if (!xc->system->findCaller(myname(), "" ) &&
-            !xc->system->findCaller(myname(), last->name)) {
-
-            DPRINTF(TCPIP, "but can't find parent %s\n", last->name);
-            return;
-        }
-        ctx->calls--;
+    xc->system->kernelBinning->call(xc, mybin);
+}
 
-        //assert(!ctx->calls && "on a binned fn, calls should == 0 (but can happen in boot)");
-    } else {
-        DPRINTF(TCPIP, "no callstack yet\n");
-        if (!xc->system->findCaller(myname(), "")) {
-            DPRINTF(TCPIP, "not the right function, returning\n");
-            return;
-        }
-        if (!ctx)  {
-            DPRINTF(TCPIP, "creating new context for %s\n", myname());
-            ctx = new SWContext;
-            xc->swCtx = ctx;
-        }
-    }
-    DPRINTF(TCPIP, "adding fn %s to context\n", myname());
-    fnCall *call = new fnCall;
-    call->myBin = myBin;
-    call->name = myname();
-    ctx->callStack.push(call);
-    myBin->activate();
-    xc->system->fnCalls++;
-    DPRINTF(TCPIP, "fnCalls for %s is %d\n", description,
-            xc->system->fnCalls.value());
-    xc->system->dumpState(xc);
+void
+IdleStartEvent::process(ExecContext *xc)
+{
+    xc->kernelStats->setIdleProcess(xc->regs.ipr[AlphaISA::IPR_PALtemp23]);
 }
index 7f658bde9320ee5b2bbd7df5093de69be964ccc9..95027572f67c112783ab1c312011fa2f00d5171c 100644 (file)
@@ -44,13 +44,24 @@ class SkipFuncEvent : public PCEvent
 class FnEvent : public PCEvent
 {
   public:
-    FnEvent(PCEventQueue *q, const std::string &desc, System *system);
+    FnEvent(PCEventQueue *q, const std::string &desc, Stats::MainBin *bin);
     virtual void process(ExecContext *xc);
     std::string myname() const { return _name; }
 
   private:
     std::string _name;
-    Stats::MainBin *myBin;
+    Stats::MainBin *mybin;
 };
 
+class IdleStartEvent : public PCEvent
+{
+  private:
+    System *system;
+
+  public:
+    IdleStartEvent(PCEventQueue *q, const std::string &desc, System *sys)
+        : PCEvent(q, desc), system(sys)
+    {}
+    virtual void process(ExecContext *xc);
+};
 #endif // __SYSTEM_EVENTS_HH__
index e96cc9c5d40f20d93535acc6364612cde8e884df..fb9d43a0e52d709398253ffa26e7a1af9a95e379 100644 (file)
@@ -47,7 +47,7 @@ BadAddrEvent::process(ExecContext *xc)
     uint64_t a0 = xc->regs.intRegFile[ArgumentReg0];
 
     if (a0 < ALPHA_K0SEG_BASE || a0 >= ALPHA_K1SEG_BASE ||
-        xc->memCtrl->badaddr(ALPHA_K0SEG_TO_PHYS(a0) & PA_IMPL_MASK)) {
+        xc->memctrl->badaddr(ALPHA_K0SEG_TO_PHYS(a0) & PA_IMPL_MASK)) {
 
         DPRINTF(BADADDR, "badaddr arg=%#x bad\n", a0);
         xc->regs.intRegFile[ReturnValueReg] = 0x1;
index 4395162e4414ae25ad4e5bdd5d307d333fa844ad..5493139ee04e8a7792031b16b1a1e6c43e90f52c 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "base/loader/aout_object.hh"
-#include "base/loader/ecoff_object.hh"
-#include "base/loader/object_file.hh"
-#include "base/loader/symtab.hh"
-#include "base/remote_gdb.hh"
 #include "base/trace.hh"
 #include "cpu/exec_context.hh"
 #include "kern/tru64/tru64_events.hh"
 #include "targetarch/isa_traits.hh"
 #include "targetarch/vtophys.hh"
 
-extern SymbolTable *debugSymbolTable;
-
 using namespace std;
 
-Tru64System::Tru64System(const string _name, const uint64_t _init_param,
-                         MemoryController *_memCtrl, PhysicalMemory *_physmem,
-                         const string &kernel_path, const string &console_path,
-                         const string &palcode, const string &boot_osflags,
-                         const bool _bin, const vector<string> &_binned_fns,
-                         const uint64_t system_type, const uint64_t system_rev)
-    : System(_name, _init_param, _memCtrl, _physmem, _bin,_binned_fns),
-      bin(_bin), binned_fns(_binned_fns)
+Tru64System::Tru64System(Tru64System::Params *p)
+    : System(p)
 {
-    kernelSymtab = new SymbolTable;
-    consoleSymtab = new SymbolTable;
-    debugSymbolTable = kernelSymtab;
-
-    ObjectFile *kernel = createObjectFile(kernel_path);
-    if (kernel == NULL)
-        fatal("Could not load kernel file %s", kernel_path);
-
-    ObjectFile *console = createObjectFile(console_path);
-    if (console == NULL)
-        fatal("Could not load console file %s", console_path);
-
-    if (!kernel->loadGlobalSymbols(kernelSymtab))
-        panic("could not load kernel symbols\n");
-
-    if (!console->loadGlobalSymbols(consoleSymtab))
-        panic("could not load console symbols\n");
-
-    // Load pal file
-    ObjectFile *pal = createObjectFile(palcode);
-    if (pal == NULL)
-        fatal("Could not load PALcode file %s", palcode);
-    pal->loadSections(physmem, true);
-
-    // Load console file
-    console->loadSections(physmem, true);
-
-    // Load kernel file
-    kernel->loadSections(physmem, true);
-    kernelStart = kernel->textBase();
-    kernelEnd = kernel->bssBase() + kernel->bssSize();
-    kernelEntry = kernel->entryPoint();
-
-    DPRINTF(Loader, "Kernel start = %#x\n"
-            "Kernel end   = %#x\n"
-            "Kernel entry = %#x\n",
-            kernelStart, kernelEnd, kernelEntry);
-
-    DPRINTF(Loader, "Kernel loaded...\n");
-
-#ifdef DEBUG
-    kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic");
-    consolePanicEvent = new BreakPCEvent(&pcEventQueue, "console panic");
-#endif
-    badaddrEvent = new BadAddrEvent(&pcEventQueue, "badaddr");
-    skipPowerStateEvent = new SkipFuncEvent(&pcEventQueue,
-                                            "tl_v48_capture_power_state");
-    skipScavengeBootEvent = new SkipFuncEvent(&pcEventQueue,
-                                              "pmap_scavenge_boot");
-    printfEvent = new PrintfEvent(&pcEventQueue, "printf");
-    debugPrintfEvent = new DebugPrintfEvent(&pcEventQueue,
-                                            "debug_printf", false);
-    debugPrintfrEvent = new DebugPrintfEvent(&pcEventQueue,
-                                             "debug_printfr", true);
-    dumpMbufEvent = new DumpMbufEvent(&pcEventQueue, "dump_mbuf");
-
     Addr addr = 0;
     if (kernelSymtab->findAddress("enable_async_printf", addr)) {
         Addr paddr = vtophys(physmem, addr);
@@ -121,180 +52,124 @@ Tru64System::Tru64System(const string _name, const uint64_t _init_param,
             *(uint32_t *)enable_async_printf = 0;
     }
 
-    if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
-        Addr paddr = vtophys(physmem, addr);
-        char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t));
-
-        if (osflags)
-            strcpy(osflags, boot_osflags.c_str());
-    }
-
-    if (consoleSymtab->findAddress("xxm_rpb", addr)) {
-        Addr paddr = vtophys(physmem, addr);
-        char *hwprb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t));
-
-        if (hwprb) {
-            *(uint64_t*)(hwprb+0x50) = system_type;
-            *(uint64_t*)(hwprb+0x58) = system_rev;
-        }
-        else
-            panic("could not translate hwprb addr to set system type/variation\n");
-    } else
-        panic("could not find hwprb to set system type/variation\n");
-
-
 #ifdef DEBUG
+    kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic");
     if (kernelSymtab->findAddress("panic", addr))
         kernelPanicEvent->schedule(addr);
     else
         panic("could not find kernel symbol \'panic\'");
-
-    if (consoleSymtab->findAddress("panic", addr))
-        consolePanicEvent->schedule(addr);
 #endif
 
+    badaddrEvent = new BadAddrEvent(&pcEventQueue, "badaddr");
     if (kernelSymtab->findAddress("badaddr", addr))
         badaddrEvent->schedule(addr);
     else
         panic("could not find kernel symbol \'badaddr\'");
 
+    skipPowerStateEvent = new SkipFuncEvent(&pcEventQueue,
+                                            "tl_v48_capture_power_state");
     if (kernelSymtab->findAddress("tl_v48_capture_power_state", addr))
         skipPowerStateEvent->schedule(addr);
 
+    skipScavengeBootEvent = new SkipFuncEvent(&pcEventQueue,
+                                              "pmap_scavenge_boot");
     if (kernelSymtab->findAddress("pmap_scavenge_boot", addr))
         skipScavengeBootEvent->schedule(addr);
 
 #if TRACING_ON
+    printfEvent = new PrintfEvent(&pcEventQueue, "printf");
     if (kernelSymtab->findAddress("printf", addr))
         printfEvent->schedule(addr);
 
+    debugPrintfEvent = new DebugPrintfEvent(&pcEventQueue, "debug_printf",
+                                            false);
     if (kernelSymtab->findAddress("m5printf", addr))
         debugPrintfEvent->schedule(addr);
 
+    debugPrintfrEvent = new DebugPrintfEvent(&pcEventQueue, "debug_printfr",
+                                             true);
     if (kernelSymtab->findAddress("m5printfr", addr))
         debugPrintfrEvent->schedule(addr);
 
+    dumpMbufEvent = new DumpMbufEvent(&pcEventQueue, "dump_mbuf");
     if (kernelSymtab->findAddress("m5_dump_mbuf", addr))
         dumpMbufEvent->schedule(addr);
 #endif
-
-    // BINNING STUFF
-    if (bin == true) {
-        int end = binned_fns.size();
-        Addr address = 0;
-
-        for (int i = 0; i < end; i +=2) {
-            if (kernelSymtab->findAddress(binned_fns[i], address))
-                fnEvents[(i>>1)]->schedule(address);
-            else
-                panic("could not find kernel symbol %s\n", binned_fns[i]);
-        }
-    }
-    //
 }
 
 Tru64System::~Tru64System()
 {
-    delete kernel;
-    delete console;
-
-    delete kernelSymtab;
-    delete consoleSymtab;
-
 #ifdef DEBUG
     delete kernelPanicEvent;
-    delete consolePanicEvent;
 #endif
     delete badaddrEvent;
     delete skipPowerStateEvent;
     delete skipScavengeBootEvent;
+#if TRACING_ON
     delete printfEvent;
     delete debugPrintfEvent;
     delete debugPrintfrEvent;
     delete dumpMbufEvent;
-}
-
-int
-Tru64System::registerExecContext(ExecContext *xc)
-{
-    int xcIndex = System::registerExecContext(xc);
-
-    if (xcIndex == 0) {
-        // activate with zero delay so that we start ticking right
-        // away on cycle 0
-        xc->activate(0);
-    }
-
-    RemoteGDB *rgdb = new RemoteGDB(this, xc);
-    GDBListener *gdbl = new GDBListener(rgdb, 7000 + xcIndex);
-    gdbl->listen();
-
-    if (remoteGDB.size() <= xcIndex) {
-        remoteGDB.resize(xcIndex+1);
-    }
-
-    remoteGDB[xcIndex] = rgdb;
-
-    return xcIndex;
-}
-
-
-void
-Tru64System::replaceExecContext(ExecContext *xc, int xcIndex)
-{
-    System::replaceExecContext(xcIndex, xc);
-    remoteGDB[xcIndex]->replaceExecContext(xc);
-}
-
-bool
-Tru64System::breakpoint()
-{
-    return remoteGDB[0]->trap(ALPHA_KENTRY_INT);
+#endif
 }
 
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64System)
 
-    Param<bool> bin;
     SimObjectParam<MemoryController *> mem_ctl;
     SimObjectParam<PhysicalMemory *> physmem;
-    Param<unsigned int> init_param;
 
     Param<string> kernel_code;
     Param<string> console_code;
     Param<string> pal_code;
+
     Param<string> boot_osflags;
-    VectorParam<string> binned_fns;
+    Param<string> readfile;
+    Param<unsigned int> init_param;
+
     Param<uint64_t> system_type;
     Param<uint64_t> system_rev;
 
+    Param<bool> bin;
+    VectorParam<string> binned_fns;
+
 END_DECLARE_SIM_OBJECT_PARAMS(Tru64System)
 
 BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64System)
 
-    INIT_PARAM_DFLT(bin, "is this system to be binned", false),
     INIT_PARAM(mem_ctl, "memory controller"),
     INIT_PARAM(physmem, "phsyical memory"),
-    INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
     INIT_PARAM(kernel_code, "file that contains the kernel code"),
     INIT_PARAM(console_code, "file that contains the console code"),
     INIT_PARAM(pal_code, "file that contains palcode"),
     INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
                     "a"),
-    INIT_PARAM(binned_fns, "functions to be broken down and binned"),
+    INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
+    INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
     INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 12),
-    INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 2<<1)
-
+    INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 2<<1),
+    INIT_PARAM_DFLT(bin, "is this system to be binned", false),
+    INIT_PARAM(binned_fns, "functions to be broken down and binned")
 
 END_INIT_SIM_OBJECT_PARAMS(Tru64System)
 
 CREATE_SIM_OBJECT(Tru64System)
 {
-    Tru64System *sys = new Tru64System(getInstanceName(), init_param, mem_ctl,
-                                       physmem, kernel_code, console_code,
-                                       pal_code, boot_osflags, bin,
-                                       binned_fns, system_type, system_rev);
-
-    return sys;
+    System::Params *p = new System::Params;
+    p->name = getInstanceName();
+    p->memctrl = mem_ctl;
+    p->physmem = physmem;
+    p->kernel_path = kernel_code;
+    p->console_path = console_code;
+    p->palcode = pal_code;
+    p->boot_osflags = boot_osflags;
+    p->init_param = init_param;
+    p->readfile = readfile;
+    p->system_type = system_type;
+    p->system_rev = system_rev;
+    p->bin = bin;
+    p->binned_fns = binned_fns;
+
+    return new Tru64System(p);
 }
 
 REGISTER_SIM_OBJECT("Tru64System", Tru64System)
index 8dd696b797fc7c7e722f782c405d1b8a95f39031..13d283fb3562dd7e2c9646618fef616953b5b12e 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef __TRU64_SYSTEM_HH__
-#define __TRU64_SYSTEM_HH__
-
-#include <map>
-#include <vector>
+#ifndef __KERN_TRU64_TRU64_SYSTEM_HH__
+#define __KERN_TRU64_TRU64_SYSTEM_HH__
 
 #include "sim/system.hh"
 #include "targetarch/isa_traits.hh"
 
 class ExecContext;
-class EcoffObject;
-class SymbolTable;
 
 class BreakPCEvent;
 class BadAddrEvent;
@@ -45,20 +40,16 @@ class SkipFuncEvent;
 class PrintfEvent;
 class DebugPrintfEvent;
 class DumpMbufEvent;
-class FnEvent;
 class AlphaArguments;
 
 class Tru64System : public System
 {
   private:
-    EcoffObject *kernel;
-    EcoffObject *console;
-
-    SymbolTable *kernelSymtab;
-    SymbolTable *consoleSymtab;
-
+#ifdef DEBUG
+    /** Event to halt the simulator if the kernel calls panic()  */
     BreakPCEvent *kernelPanicEvent;
-    BreakPCEvent *consolePanicEvent;
+#endif
+
     BadAddrEvent *badaddrEvent;
     SkipFuncEvent *skipPowerStateEvent;
     SkipFuncEvent *skipScavengeBootEvent;
@@ -67,43 +58,12 @@ class Tru64System : public System
     DebugPrintfEvent *debugPrintfrEvent;
     DumpMbufEvent *dumpMbufEvent;
 
-  private:
-
-    Addr kernelStart;
-    Addr kernelEnd;
-    Addr kernelEntry;
-    bool bin;
-    std::vector<string> binned_fns;
-
-  public:
-    std::vector<RemoteGDB *>   remoteGDB;
-    std::vector<GDBListener *> gdbListen;
-
   public:
-    Tru64System(const std::string _name,
-                const uint64_t _init_param,
-                MemoryController *_memCtrl,
-                PhysicalMemory *_physmem,
-                const std::string &kernel_path,
-                const std::string &console_path,
-                const std::string &palcode,
-                const std::string &boot_osflags,
-                const bool _bin,
-                const std::vector<string> &binned_fns,
-        const uint64_t system_type,
-        const uint64_t system_rev);
+    Tru64System(Params *p);
     ~Tru64System();
 
-    int registerExecContext(ExecContext *xc);
-    void replaceExecContext(ExecContext *xc, int xcIndex);
-
-    Addr getKernelStart() const { return kernelStart; }
-    Addr getKernelEnd() const { return kernelEnd; }
-    Addr getKernelEntry() const { return kernelEntry; }
-    bool breakpoint();
-
     static void Printf(AlphaArguments args);
     static void DumpMbuf(AlphaArguments args);
 };
 
-#endif // __TRU64_SYSTEM_HH__
+#endif // __KERN_TRU64_TRU64_SYSTEM_HH__
index 7f93c1d9e2d08faaf0f5c36874db6044ebbef079..b4febc75b64766ae76066a0dac327a5d96b96fdd 100644 (file)
@@ -161,7 +161,7 @@ Process::registerExecContext(ExecContext *xc)
 
 
 void
-Process::replaceExecContext(int xcIndex, ExecContext *xc)
+Process::replaceExecContext(ExecContext *xc, int xcIndex)
 {
     if (xcIndex >= execContexts.size()) {
         panic("replaceExecContext: bad xcIndex, %d >= %d\n",
index bd6adc55cc3f5eb6b2c6964c0e17e98e858b5006..bb48298759a89bcf2342f6bc49fb3c91fb2dc583 100644 (file)
@@ -130,7 +130,7 @@ class Process : public SimObject
     int registerExecContext(ExecContext *xc);
 
 
-    void replaceExecContext(int xcIndex, ExecContext *xc);
+    void replaceExecContext(ExecContext *xc, int xcIndex);
 
     // map simulator fd sim_fd to target fd tgt_fd
     void dup_fd(int sim_fd, int tgt_fd);
index b5a0e7a564847a77b097e80ead4f0d6175515640..2d91e187b8b82930a6991308c49a892386e6e62b 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "base/loader/object_file.hh"
+#include "base/loader/symtab.hh"
+#include "base/remote_gdb.hh"
 #include "cpu/exec_context.hh"
+#include "kern/kernel_stats.hh"
+#include "mem/functional_mem/memory_control.hh"
+#include "mem/functional_mem/physical_memory.hh"
 #include "targetarch/vtophys.hh"
 #include "sim/param.hh"
 #include "sim/system.hh"
@@ -38,82 +44,160 @@ vector<System *> System::systemList;
 
 int System::numSystemsRunning = 0;
 
-System::System(const std::string _name,
-               const uint64_t _init_param,
-               MemoryController *_memCtrl,
-               PhysicalMemory *_physmem,
-               const bool _bin,
-               const std::vector<string> &binned_fns)
-
-    : SimObject(_name),
-      init_param(_init_param),
-      memCtrl(_memCtrl),
-      physmem(_physmem),
-      bin(_bin),
-      binned_fns(binned_fns)
-{
-    // increment the number of running systems
-    numSystemsRunning++;
+extern SymbolTable *debugSymbolTable;
 
+System::System(Params *p)
+    : SimObject(p->name), memctrl(p->memctrl), physmem(p->physmem),
+      init_param(p->init_param), params(p)
+{
     // add self to global system list
     systemList.push_back(this);
-    if (bin == true) {
-        Kernel = new Stats::MainBin("non TCPIP Kernel stats");
-        Kernel->activate();
-        User = new Stats::MainBin("User stats");
-
-        int end = binned_fns.size();
-        assert(!(end & 1));
 
-        Stats::MainBin *Bin;
-
-        fnEvents.resize(end>>1);
+    kernelSymtab = new SymbolTable;
+    consoleSymtab = new SymbolTable;
+    debugSymbolTable = kernelSymtab;
+
+    /**
+     * Load the kernel, pal, and console code into memory
+     */
+    // Load kernel code
+    kernel = createObjectFile(params->kernel_path);
+    if (kernel == NULL)
+        fatal("Could not load kernel file %s", params->kernel_path);
+
+    // Load Console Code
+    console = createObjectFile(params->console_path);
+    if (console == NULL)
+        fatal("Could not load console file %s", params->console_path);
+
+    // Load pal file
+    pal = createObjectFile(params->palcode);
+    if (pal == NULL)
+        fatal("Could not load PALcode file %s", params->palcode);
+
+
+    // Load program sections into memory
+    pal->loadSections(physmem, true);
+    console->loadSections(physmem, true);
+    kernel->loadSections(physmem, true);
+
+    // setup entry points
+    kernelStart = kernel->textBase();
+    kernelEnd = kernel->bssBase() + kernel->bssSize();
+    kernelEntry = kernel->entryPoint();
+
+    // load symbols
+    if (!kernel->loadGlobalSymbols(kernelSymtab))
+        panic("could not load kernel symbols\n");
+        debugSymbolTable = kernelSymtab;
+
+    if (!kernel->loadLocalSymbols(kernelSymtab))
+        panic("could not load kernel local symbols\n");
+
+    if (!console->loadGlobalSymbols(consoleSymtab))
+        panic("could not load console symbols\n");
+
+    DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
+    DPRINTF(Loader, "Kernel end   = %#x\n", kernelEnd);
+    DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry);
+    DPRINTF(Loader, "Kernel loaded...\n");
+
+    Addr addr = 0;
+#ifdef DEBUG
+    consolePanicEvent = new BreakPCEvent(&pcEventQueue, "console panic");
+    if (consoleSymtab->findAddress("panic", addr))
+        consolePanicEvent->schedule(addr);
+#endif
+
+    /**
+     * Copy the osflags (kernel arguments) into the consoles
+     * memory. (Presently Linux does not use the console service
+     * routine to get these command line arguments, but Tru64 and
+     * others do.)
+     */
+    if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
+        Addr paddr = vtophys(physmem, addr);
+        char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t));
+
+        if (osflags)
+              strcpy(osflags, params->boot_osflags.c_str());
+    }
 
-        for (int i = 0; i < end; i +=2) {
-            Bin = new Stats::MainBin(binned_fns[i]);
-            fnBins.insert(make_pair(binned_fns[i], Bin));
+    /**
+     * Set the hardware reset parameter block system type and revision
+     * information to Tsunami.
+     */
+    if (consoleSymtab->findAddress("xxm_rpb", addr)) {
+        Addr paddr = vtophys(physmem, addr);
+        char *hwrpb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t));
 
-            fnEvents[(i>>1)] = new FnEvent(&pcEventQueue, binned_fns[i], this);
+        if (!hwrpb)
+            panic("could not translate hwrpb addr\n");
 
-            if (binned_fns[i+1] == "null")
-                populateMap(binned_fns[i], "");
-            else
-                populateMap(binned_fns[i], binned_fns[i+1]);
-        }
+        *(uint64_t*)(hwrpb+0x50) = params->system_type;
+        *(uint64_t*)(hwrpb+0x58) = params->system_rev;
+    } else
+        panic("could not find hwrpb\n");
 
-        fnCalls
-            .name(name() + ":fnCalls")
-            .desc("all fn calls being tracked")
-            ;
+    // increment the number of running systms
+    numSystemsRunning++;
 
-    } else
-        Kernel = NULL;
+    kernelBinning = new Kernel::Binning(this);
 }
 
-
 System::~System()
 {
-    if (bin == true) {
-        int end = fnEvents.size();
-        for (int i = 0; i < end; ++i) {
-            delete fnEvents[i];
-        }
-        fnEvents.clear();
-    }
+    delete kernelSymtab;
+    delete consoleSymtab;
+    delete kernel;
+    delete console;
+    delete pal;
+
+    delete kernelBinning;
+
+#ifdef DEBUG
+    delete consolePanicEvent;
+#endif
 }
 
+bool
+System::breakpoint()
+{
+    return remoteGDB[0]->trap(ALPHA_KENTRY_INT);
+}
 
 int
 System::registerExecContext(ExecContext *xc)
 {
-    int myIndex = execContexts.size();
+    int xcIndex = execContexts.size();
     execContexts.push_back(xc);
-    return myIndex;
-}
 
+    if (xcIndex == 0) {
+        // activate with zero delay so that we start ticking right
+        // away on cycle 0
+        xc->activate(0);
+    }
+
+    RemoteGDB *rgdb = new RemoteGDB(this, xc);
+    GDBListener *gdbl = new GDBListener(rgdb, 7000 + xcIndex);
+    gdbl->listen();
+    /**
+     * Uncommenting this line waits for a remote debugger to connect
+     * to the simulator before continuing.
+     */
+    //gdbl->accept();
+
+    if (remoteGDB.size() <= xcIndex) {
+        remoteGDB.resize(xcIndex+1);
+    }
+
+    remoteGDB[xcIndex] = rgdb;
+
+    return xcIndex;
+}
 
 void
-System::replaceExecContext(int xcIndex, ExecContext *xc)
+System::replaceExecContext(ExecContext *xc, int xcIndex)
 {
     if (xcIndex >= execContexts.size()) {
         panic("replaceExecContext: bad xcIndex, %d >= %d\n",
@@ -121,154 +205,44 @@ System::replaceExecContext(int xcIndex, ExecContext *xc)
     }
 
     execContexts[xcIndex] = xc;
+    remoteGDB[xcIndex]->replaceExecContext(xc);
 }
 
-
-void
-System::printSystems()
-{
-    vector<System *>::iterator i = systemList.begin();
-    vector<System *>::iterator end = systemList.end();
-    for (; i != end; ++i) {
-        System *sys = *i;
-        cerr << "System " << sys->name() << ": " << hex << sys << endl;
-    }
-}
-
-extern "C"
 void
-printSystems()
+System::regStats()
 {
-    System::printSystems();
+    kernelBinning->regStats(name() + ".kern");
 }
 
 void
-System::populateMap(std::string callee, std::string caller)
+System::serialize(ostream &os)
 {
-    multimap<const string, string>::const_iterator i;
-    i = callerMap.insert(make_pair(callee, caller));
-    assert(i != callerMap.end() && "should not fail populating callerMap");
+    kernelBinning->serialize(os);
 }
 
-bool
-System::findCaller(std::string callee, std::string caller) const
-{
-    typedef multimap<const std::string, std::string>::const_iterator iter;
-    pair<iter, iter> range;
-
-    range = callerMap.equal_range(callee);
-    for (iter i = range.first; i != range.second; ++i) {
-        if ((*i).second == caller)
-            return true;
-    }
-    return false;
-}
 
 void
-System::dumpState(ExecContext *xc) const
-{
-    if (xc->swCtx) {
-        stack<fnCall *> copy(xc->swCtx->callStack);
-        if (copy.empty())
-            return;
-        DPRINTF(TCPIP, "xc->swCtx, size: %d:\n", copy.size());
-        fnCall *top;
-        DPRINTF(TCPIP, "||     call : %d\n",xc->swCtx->calls);
-        for (top = copy.top(); !copy.empty(); copy.pop() ) {
-            top = copy.top();
-            DPRINTF(TCPIP, "||  %13s : %s \n", top->name, top->myBin->name());
-        }
-    }
-}
-
-Stats::MainBin *
-System::getBin(const std::string &name)
-{
-    std::map<const std::string, Stats::MainBin *>::const_iterator i;
-    i = fnBins.find(name);
-    if (i == fnBins.end())
-        panic("trying to getBin %s that is not on system map!", name);
-    return (*i).second;
-}
-
-SWContext *
-System::findContext(Addr pcb)
+System::unserialize(Checkpoint *cp, const string &section)
 {
-  std::map<Addr, SWContext *>::const_iterator iter;
-  iter = swCtxMap.find(pcb);
-  if (iter != swCtxMap.end()) {
-      SWContext *ctx = (*iter).second;
-      assert(ctx != NULL && "should never have a null ctx in ctxMap");
-      return ctx;
-  } else
-      return NULL;
+    kernelBinning->unserialize(cp, section);
 }
 
 void
-System::serialize(std::ostream &os)
+System::printSystems()
 {
-    if (bin == true) {
-        map<const Addr, SWContext *>::const_iterator iter, end;
-        iter = swCtxMap.begin();
-        end = swCtxMap.end();
-
-        int numCtxs = swCtxMap.size();
-        SERIALIZE_SCALAR(numCtxs);
-        SWContext *ctx;
-        for (int i = 0; iter != end; ++i, ++iter) {
-            paramOut(os, csprintf("Addr[%d]",i), (*iter).first);
-            ctx = (*iter).second;
-            paramOut(os, csprintf("calls[%d]",i), ctx->calls);
-
-            stack<fnCall *> *stack = &(ctx->callStack);
-            fnCall *top;
-            int size = stack->size();
-            paramOut(os, csprintf("stacksize[%d]",i), size);
-            for (int j=0; j<size; ++j) {
-                top = stack->top();
-                paramOut(os, csprintf("ctx[%d].stackpos[%d]",i,j),
-                         top->name);
-                delete top;
-                stack->pop();
-            }
-        }
+    vector<System *>::iterator i = systemList.begin();
+    vector<System *>::iterator end = systemList.end();
+    for (; i != end; ++i) {
+        System *sys = *i;
+        cerr << "System " << sys->name() << ": " << hex << sys << endl;
     }
 }
 
+extern "C"
 void
-System::unserialize(Checkpoint *cp, const std::string &section)
+printSystems()
 {
-    if (bin == true) {
-        int numCtxs;
-        UNSERIALIZE_SCALAR(numCtxs);
-
-        SWContext *ctx;
-        Addr addr;
-        int size;
-        for(int i = 0; i < numCtxs; ++i) {
-            ctx = new SWContext;
-            paramIn(cp, section, csprintf("Addr[%d]",i), addr);
-            paramIn(cp, section, csprintf("calls[%d]",i), ctx->calls);
-
-            paramIn(cp, section, csprintf("stacksize[%d]",i), size);
-
-            vector<fnCall *> calls;
-            fnCall *call;
-            for (int j = 0; j < size; ++j) {
-                call = new fnCall;
-                paramIn(cp, section, csprintf("ctx[%d].stackpos[%d]",i,j),
-                        call->name);
-                call->myBin = getBin(call->name);
-                calls.push_back(call);
-            }
-
-            for (int j=size-1; j>=0; --j) {
-                ctx->callStack.push(calls[j]);
-            }
-
-            addContext(addr, ctx);
-        }
-    }
+    System::printSystems();
 }
 
 DEFINE_SIM_OBJECT_CLASS_NAME("System", System)
index da974cfdd7ab13a5d673adec367eaf07cc3335df..05b97ad62987226b46707115a1231c9449f14e0c 100644 (file)
 #include "cpu/pc_event.hh"
 #include "kern/system_events.hh"
 #include "sim/sim_object.hh"
-#include "sim/sw_context.hh"
 
 class MemoryController;
 class PhysicalMemory;
 class Platform;
 class RemoteGDB;
 class GDBListener;
-
+class ObjectFile;
 class ExecContext;
+namespace Kernel { class Binning; }
 
 class System : public SimObject
 {
-    // lisa's binning stuff
-  private:
-    std::map<const std::string, Stats::MainBin *> fnBins;
-    std::map<const Addr, SWContext *> swCtxMap;
+  public:
+    MemoryController *memctrl;
+    PhysicalMemory *physmem;
+    Platform *platform;
+    PCEventQueue pcEventQueue;
+    uint64_t init_param;
 
-  protected:
-    std::vector<FnEvent *> fnEvents;
+    std::vector<ExecContext *> execContexts;
 
-  public:
-    Stats::Scalar<> fnCalls;
-    Stats::MainBin *Kernel;
-    Stats::MainBin *User;
+    /** kernel Symbol table */
+    SymbolTable *kernelSymtab;
 
-    Stats::MainBin * getBin(const std::string &name);
-    bool findCaller(std::string, std::string) const;
+    /** console symbol table */
+    SymbolTable *consoleSymtab;
 
-    SWContext *findContext(Addr pcb);
-    bool addContext(Addr pcb, SWContext *ctx) {
-        return (swCtxMap.insert(make_pair(pcb, ctx))).second;
-    }
-    void remContext(Addr pcb) {
-        swCtxMap.erase(pcb);
-        return;
-    }
-    void dumpState(ExecContext *xc) const;
+    /** Object pointer for the kernel code */
+    ObjectFile *kernel;
 
-    virtual void serialize(std::ostream &os);
-    virtual void unserialize(Checkpoint *cp, const std::string &section);
+    /** Object pointer for the console code */
+    ObjectFile *console;
 
+    /** Object pointer for the PAL code */
+    ObjectFile *pal;
 
-  private:
-    std::multimap<const std::string, std::string> callerMap;
-    void populateMap(std::string caller, std::string callee);
-//
+    /** Begining of kernel code */
+    Addr kernelStart;
 
-  public:
-    const uint64_t init_param;
-    MemoryController *memCtrl;
-    PhysicalMemory *physmem;
-    Platform *platform;
-    bool bin;
-    std::vector<string> binned_fns;
+    /** End of kernel code */
+    Addr kernelEnd;
 
-    PCEventQueue pcEventQueue;
+    /** Entry point in the kernel to start at */
+    Addr kernelEntry;
 
-    std::vector<ExecContext *> execContexts;
+    Kernel::Binning *kernelBinning;
 
-    std::string readfile;
+#ifdef DEBUG
+    /** Event to halt the simulator if the console calls panic() */
+    BreakPCEvent *consolePanicEvent;
+#endif
 
-    virtual int registerExecContext(ExecContext *xc);
-    virtual void replaceExecContext(int xcIndex, ExecContext *xc);
+  public:
+    std::vector<RemoteGDB *> remoteGDB;
+    std::vector<GDBListener *> gdbListen;
+    bool breakpoint();
 
   public:
-    System(const std::string _name, const uint64_t _init_param,
-           MemoryController *, PhysicalMemory *, const bool,
-           const std::vector<string> &binned_fns);
+    struct Params
+    {
+        std::string name;
+        MemoryController *memctrl;
+        PhysicalMemory *physmem;
+        uint64_t init_param;
+        bool bin;
+        std::vector<std::string> binned_fns;
+
+        std::string kernel_path;
+        std::string console_path;
+        std::string palcode;
+        std::string boot_osflags;
+
+        std::string readfile;
+        uint64_t system_type;
+        uint64_t system_rev;
+    };
+    Params *params;
+
+    System(Params *p);
     ~System();
 
-    virtual Addr getKernelStart() const = 0;
-    virtual Addr getKernelEnd() const = 0;
-    virtual Addr getKernelEntry() const = 0;
-    virtual bool breakpoint() = 0;
+  public:
+    /**
+     * Returns the addess the kernel starts at.
+     * @return address the kernel starts at
+     */
+    Addr getKernelStart() const { return kernelStart; }
+
+    /**
+     * Returns the addess the kernel ends at.
+     * @return address the kernel ends at
+     */
+    Addr getKernelEnd() const { return kernelEnd; }
+
+    /**
+     * Returns the addess the entry point to the kernel code.
+     * @return entry point of the kernel code
+     */
+    Addr getKernelEntry() const { return kernelEntry; }
+
+    int registerExecContext(ExecContext *xc);
+    void replaceExecContext(ExecContext *xc, int xcIndex);
+
+    void regStats();
+    void serialize(std::ostream &os);
+    void unserialize(Checkpoint *cp, const std::string &section);
 
   public:
     ////////////////////////////////////////////