diff options
Diffstat (limited to 'sim')
-rw-r--r-- | sim/process.cc | 2 | ||||
-rw-r--r-- | sim/process.hh | 2 | ||||
-rw-r--r-- | sim/system.cc | 332 | ||||
-rw-r--r-- | sim/system.hh | 128 |
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 §ion) { - 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 §ion) +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 §ion); + /** 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 §ion); public: //////////////////////////////////////////// |