summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConscript2
-rw-r--r--arch/alpha/ev5.cc13
-rw-r--r--arch/alpha/pseudo_inst.cc9
-rw-r--r--base/trace.hh10
-rw-r--r--cpu/base_cpu.cc4
-rw-r--r--cpu/exec_context.cc90
-rw-r--r--cpu/exec_context.hh25
-rw-r--r--cpu/simple_cpu/simple_cpu.cc5
-rw-r--r--kern/kernel_stats.cc311
-rw-r--r--kern/kernel_stats.hh158
-rw-r--r--kern/linux/linux_system.cc266
-rw-r--r--kern/linux/linux_system.hh103
-rw-r--r--kern/system_events.cc54
-rw-r--r--kern/system_events.hh15
-rw-r--r--kern/tru64/tru64_events.cc2
-rw-r--r--kern/tru64/tru64_system.cc213
-rw-r--r--kern/tru64/tru64_system.hh56
-rw-r--r--sim/process.cc2
-rw-r--r--sim/process.hh2
-rw-r--r--sim/system.cc332
-rw-r--r--sim/system.hh128
21 files changed, 718 insertions, 1082 deletions
diff --git a/SConscript b/SConscript
index 0f2d90c2d..f22c85059 100644
--- a/SConscript
+++ b/SConscript
@@ -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
diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc
index b043ed0ee..b0f2251dc 100644
--- a/arch/alpha/ev5.cc
+++ b/arch/alpha/ev5.cc
@@ -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:
diff --git a/arch/alpha/pseudo_inst.cc b/arch/alpha/pseudo_inst.cc
index fd6742801..95c85b45a 100644
--- a/arch/alpha/pseudo_inst.cc
+++ b/arch/alpha/pseudo_inst.cc
@@ -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;
diff --git a/base/trace.hh b/base/trace.hh
index 1aadb36cf..5e05d6e5e 100644
--- a/base/trace.hh
+++ b/base/trace.hh
@@ -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();
//
diff --git a/cpu/base_cpu.cc b/cpu/base_cpu.cc
index 3ee7a3892..8a9c9a102 100644
--- a/cpu/base_cpu.cc
+++ b/cpu/base_cpu.cc
@@ -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
}
diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc
index 9c21b3a56..1cb33f13e 100644
--- a/cpu/exec_context.cc
+++ b/cpu/exec_context.cc
@@ -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
}
diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh
index b47f5cd08..2ba2d7524 100644
--- a/cpu/exec_context.hh
+++ b/cpu/exec_context.hh
@@ -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);
diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc
index 6c22d7c81..449b20fee 100644
--- a/cpu/simple_cpu/simple_cpu.cc
+++ b/cpu/simple_cpu/simple_cpu.cc
@@ -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()) {
diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc
index e6bcb4d29..c8c04e6d1 100644
--- a/kern/kernel_stats.cc
+++ b/kern/kernel_stats.cc
@@ -30,134 +30,82 @@
#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 */ }
diff --git a/kern/kernel_stats.hh b/kern/kernel_stats.hh
index 497403762..8339c578c 100644
--- a/kern/kernel_stats.hh
+++ b/kern/kernel_stats.hh
@@ -29,35 +29,165 @@
#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__
diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc
index dd188ffe0..10641de87 100644
--- a/kern/linux/linux_system.cc
+++ b/kern/linux/linux_system.cc
@@ -35,11 +35,6 @@
* 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);
@@ -152,19 +74,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,32 +81,11 @@ 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.
* @todo At some point we should change ev5.hh and the palcode to support
@@ -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)
+
diff --git a/kern/linux/linux_system.hh b/kern/linux/linux_system.hh
index fbfcb788f..707204607 100644
--- a/kern/linux/linux_system.hh
+++ b/kern/linux/linux_system.hh
@@ -26,32 +26,27 @@
* 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__
diff --git a/kern/system_events.cc b/kern/system_events.cc
index 351c3ddb2..91daf53ca 100644
--- a/kern/system_events.cc
+++ b/kern/system_events.cc
@@ -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]);
}
diff --git a/kern/system_events.hh b/kern/system_events.hh
index 7f658bde9..95027572f 100644
--- a/kern/system_events.hh
+++ b/kern/system_events.hh
@@ -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__
diff --git a/kern/tru64/tru64_events.cc b/kern/tru64/tru64_events.cc
index e96cc9c5d..fb9d43a0e 100644
--- a/kern/tru64/tru64_events.cc
+++ b/kern/tru64/tru64_events.cc
@@ -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;
diff --git a/kern/tru64/tru64_system.cc b/kern/tru64/tru64_system.cc
index 4395162e4..5493139ee 100644
--- a/kern/tru64/tru64_system.cc
+++ b/kern/tru64/tru64_system.cc
@@ -26,11 +26,6 @@
* 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"
@@ -42,75 +37,11 @@
#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)
diff --git a/kern/tru64/tru64_system.hh b/kern/tru64/tru64_system.hh
index 8dd696b79..13d283fb3 100644
--- a/kern/tru64/tru64_system.hh
+++ b/kern/tru64/tru64_system.hh
@@ -26,18 +26,13 @@
* 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__
diff --git a/sim/process.cc b/sim/process.cc
index 7f93c1d9e..b4febc75b 100644
--- a/sim/process.cc
+++ b/sim/process.cc
@@ -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",
diff --git a/sim/process.hh b/sim/process.hh
index bd6adc55c..bb4829875 100644
--- a/sim/process.hh
+++ b/sim/process.hh
@@ -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);
diff --git a/sim/system.cc b/sim/system.cc
index b5a0e7a56..2d91e187b 100644
--- a/sim/system.cc
+++ b/sim/system.cc
@@ -26,7 +26,13 @@
* 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)
diff --git a/sim/system.hh b/sim/system.hh
index da974cfdd..05b97ad62 100644
--- a/sim/system.hh
+++ b/sim/system.hh
@@ -37,80 +37,112 @@
#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:
////////////////////////////////////////////