X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fsim%2Fsystem.cc;h=45e06616da83929bfd217a348e6658dfbe2179af;hb=29676286c8b52014c44f5001ff2d039881189030;hp=f6febe4b199bf7c126fd9ca41ab9d31184b6e8e9;hpb=8840ebcb00f3988c781063e572b6df5742968f95;p=gem5.git diff --git a/src/sim/system.cc b/src/sim/system.cc index f6febe4b1..45e06616d 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -33,18 +33,24 @@ #include "arch/isa_traits.hh" #include "arch/remote_gdb.hh" +#include "arch/utility.hh" #include "base/loader/object_file.hh" #include "base/loader/symtab.hh" #include "base/trace.hh" #include "cpu/thread_context.hh" +#include "config/full_system.hh" +#include "config/the_isa.hh" #include "mem/mem_object.hh" #include "mem/physical.hh" -#include "sim/builder.hh" #include "sim/byteswap.hh" #include "sim/system.hh" +#include "sim/debug.hh" + #if FULL_SYSTEM #include "arch/vtophys.hh" #include "kern/kernel_stats.hh" +#else +#include "params/System.hh" #endif using namespace std; @@ -55,13 +61,15 @@ vector System::systemList; int System::numSystemsRunning = 0; System::System(Params *p) - : SimObject(p->name), physmem(p->physmem), numcpus(0), + : SimObject(p), physmem(p->physmem), _numContexts(0), #if FULL_SYSTEM init_param(p->init_param), functionalPort(p->name + "-fport"), virtPort(p->name + "-vport"), + loadAddrMask(p->load_addr_mask), #else page_ptr(0), + next_PID(0), #endif memoryMode(p->mem_mode), _params(p) { @@ -70,7 +78,8 @@ System::System(Params *p) #if FULL_SYSTEM kernelSymtab = new SymbolTable; - debugSymbolTable = new SymbolTable; + if (!debugSymbolTable) + debugSymbolTable = new SymbolTable; /** @@ -89,17 +98,19 @@ System::System(Params *p) /** * Load the kernel code into memory */ - if (params()->kernel_path == "") { - warn("No kernel set for full system simulation. Assuming you know what" + if (params()->kernel == "") { + inform("No kernel set for full system simulation. Assuming you know what" " you're doing...\n"); } else { // Load kernel code - kernel = createObjectFile(params()->kernel_path); + kernel = createObjectFile(params()->kernel); + inform("kernel located at: %s", params()->kernel); + if (kernel == NULL) - fatal("Could not load kernel file %s", params()->kernel_path); + fatal("Could not load kernel file %s", params()->kernel); // Load program sections into memory - kernel->loadSections(&functionalPort, LoadAddrMask); + kernel->loadSections(&functionalPort, loadAddrMask); // setup entry points kernelStart = kernel->textBase(); @@ -108,16 +119,16 @@ System::System(Params *p) // load symbols if (!kernel->loadGlobalSymbols(kernelSymtab)) - panic("could not load kernel symbols\n"); + fatal("could not load kernel symbols\n"); if (!kernel->loadLocalSymbols(kernelSymtab)) - panic("could not load kernel local symbols\n"); + fatal("could not load kernel local symbols\n"); if (!kernel->loadGlobalSymbols(debugSymbolTable)) - panic("could not load kernel symbols\n"); + fatal("could not load kernel symbols\n"); if (!kernel->loadLocalSymbols(debugSymbolTable)) - panic("could not load kernel local symbols\n"); + fatal("could not load kernel local symbols\n"); DPRINTF(Loader, "Kernel start = %#x\n", kernelStart); DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd); @@ -141,10 +152,8 @@ System::~System() #endif // FULL_SYSTEM} } -int rgdb_wait = -1; - void -System::setMemoryMode(MemoryMode mode) +System::setMemoryMode(Enums::MemoryMode mode) { assert(getState() == Drained); memoryMode = mode; @@ -152,65 +161,93 @@ System::setMemoryMode(MemoryMode mode) bool System::breakpoint() { - return remoteGDB[0]->breakpoint(); + if (remoteGDB.size()) + return remoteGDB[0]->breakpoint(); + return false; } +/** + * Setting rgdb_wait to a positive integer waits for a remote debugger to + * connect to that context ID before continuing. This should really + be a parameter on the CPU object or something... + */ +int rgdb_wait = -1; + int -System::registerThreadContext(ThreadContext *tc, int id) +System::registerThreadContext(ThreadContext *tc, int assigned) { - if (id == -1) { + int id; + if (assigned == -1) { for (id = 0; id < threadContexts.size(); id++) { if (!threadContexts[id]) break; } - } - if (threadContexts.size() <= id) - threadContexts.resize(id + 1); + if (threadContexts.size() <= id) + threadContexts.resize(id + 1); + } else { + if (threadContexts.size() <= assigned) + threadContexts.resize(assigned + 1); + id = assigned; + } if (threadContexts[id]) - panic("Cannot have two CPUs with the same id (%d)\n", id); + fatal("Cannot have two CPUs with the same id (%d)\n", id); threadContexts[id] = tc; - numcpus++; + _numContexts++; - RemoteGDB *rgdb = new RemoteGDB(this, tc); - GDBListener *gdbl = new GDBListener(rgdb, 7000 + id); - gdbl->listen(); - /** - * Uncommenting this line waits for a remote debugger to connect - * to the simulator before continuing. - */ - if (rgdb_wait != -1 && rgdb_wait == id) - gdbl->accept(); + int port = getRemoteGDBPort(); + if (port) { + RemoteGDB *rgdb = new RemoteGDB(this, tc); + GDBListener *gdbl = new GDBListener(rgdb, port + id); + gdbl->listen(); - if (remoteGDB.size() <= id) { - remoteGDB.resize(id + 1); - } + if (rgdb_wait != -1 && rgdb_wait == id) + gdbl->accept(); + + if (remoteGDB.size() <= id) { + remoteGDB.resize(id + 1); + } - remoteGDB[id] = rgdb; + remoteGDB[id] = rgdb; + } return id; } +int +System::numRunningContexts() +{ + int running = 0; + for (int i = 0; i < _numContexts; ++i) { + if (threadContexts[i]->status() != ThreadContext::Halted) + ++running; + } + return running; +} + void System::startup() { +#if FULL_SYSTEM int i; for (i = 0; i < threadContexts.size(); i++) - threadContexts[i]->activate(0); + TheISA::startupCPU(threadContexts[i], i); +#endif } void -System::replaceThreadContext(ThreadContext *tc, int id) +System::replaceThreadContext(ThreadContext *tc, int context_id) { - if (id >= threadContexts.size()) { + if (context_id >= threadContexts.size()) { panic("replaceThreadContext: bad id, %d >= %d\n", - id, threadContexts.size()); + context_id, threadContexts.size()); } - threadContexts[id] = tc; - remoteGDB[id]->replaceThreadContext(tc); + threadContexts[context_id] = tc; + if (context_id < remoteGDB.size()) + remoteGDB[context_id]->replaceThreadContext(tc); } #if !FULL_SYSTEM @@ -223,6 +260,19 @@ System::new_page() fatal("Out of memory, please increase size of physical memory."); return return_addr; } + +Addr +System::memSize() +{ + return physmem->size(); +} + +Addr +System::freeMemSize() +{ + return physmem->size() - (page_ptr << LogVMPageSize); +} + #endif void @@ -230,7 +280,9 @@ System::serialize(ostream &os) { #if FULL_SYSTEM kernelSymtab->serialize("kernel_symtab", os); -#endif // FULL_SYSTEM +#else // !FULL_SYSTEM + SERIALIZE_SCALAR(page_ptr); +#endif } @@ -239,7 +291,9 @@ System::unserialize(Checkpoint *cp, const string §ion) { #if FULL_SYSTEM kernelSymtab->unserialize("kernel_symtab", cp, section); -#endif // FULL_SYSTEM +#else // !FULL_SYSTEM + UNSERIALIZE_SCALAR(page_ptr); +#endif } void @@ -262,39 +316,12 @@ printSystems() const char *System::MemoryModeStrings[3] = {"invalid", "atomic", "timing"}; -#if FULL_SYSTEM - -// In full system mode, only derived classes (e.g. AlphaLinuxSystem) -// can be created directly. - -DEFINE_SIM_OBJECT_CLASS_NAME("System", System) - -#else - -BEGIN_DECLARE_SIM_OBJECT_PARAMS(System) - - SimObjectParam physmem; - SimpleEnumParam mem_mode; - -END_DECLARE_SIM_OBJECT_PARAMS(System) - -BEGIN_INIT_SIM_OBJECT_PARAMS(System) - - INIT_PARAM(physmem, "physical memory"), - INIT_ENUM_PARAM(mem_mode, "Memory Mode, (1=atomic, 2=timing)", - System::MemoryModeStrings) - -END_INIT_SIM_OBJECT_PARAMS(System) +#if !FULL_SYSTEM -CREATE_SIM_OBJECT(System) +System * +SystemParams::create() { - System::Params *p = new System::Params; - p->name = getInstanceName(); - p->physmem = physmem; - p->mem_mode = mem_mode; - return new System(p); + return new System(this); } -REGISTER_SIM_OBJECT("System", System) - #endif