summaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
Diffstat (limited to 'sim')
-rw-r--r--sim/process.cc2
-rw-r--r--sim/process.hh2
-rw-r--r--sim/system.cc332
-rw-r--r--sim/system.hh128
4 files changed, 235 insertions, 229 deletions
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:
////////////////////////////////////////////