system.cc revision 2422
1#include "base/loader/object_file.hh" 2#include "base/loader/symtab.hh" 3#include "cpu/exec_context.hh" 4#include "arch/vtophys.hh" 5#include "mem/memory.hh" 6#include "sim/builder.hh" 7#include "arch/isa_traits.hh" 8#include "sim/byteswap.hh" 9#include "sim/system.hh" 10#include "base/trace.hh" 11#if FULL_SYSTEM 12#include "base/remote_gdb.hh" 13#include "kern/kernel_stats.hh" 14#include "mem/functional/memory_control.hh" 15#include "targetarch/vtophys.hh" 16#endif 17 18using namespace std; 19using namespace TheISA; 20 21vector<System *> System::systemList; 22 23int System::numSystemsRunning = 0; 24 25System::System(Params *p) 26 : SimObject(p->name), physmem(p->physmem), numcpus(0), 27#if FULL_SYSTEM 28 memctrl(p->memctrl), init_param(p->init_param), 29#else 30 page_ptr(0), 31#endif 32 _params(p) 33{ 34 // add self to global system list 35 systemList.push_back(this); 36 37#if FULL_SYSTEM 38 kernelSymtab = new SymbolTable; 39 debugSymbolTable = new SymbolTable; 40 41 /** 42 * Load the kernel code into memory 43 */ 44 // Load kernel code 45 kernel = createObjectFile(params()->kernel_path); 46 if (kernel == NULL) 47 fatal("Could not load kernel file %s", params()->kernel_path); 48 49 // Load program sections into memory 50 kernel->loadSections(physmem, true); 51 52 // setup entry points 53 kernelStart = kernel->textBase(); 54 kernelEnd = kernel->bssBase() + kernel->bssSize(); 55 kernelEntry = kernel->entryPoint(); 56 57 // load symbols 58 if (!kernel->loadGlobalSymbols(kernelSymtab)) 59 panic("could not load kernel symbols\n"); 60 61 if (!kernel->loadLocalSymbols(kernelSymtab)) 62 panic("could not load kernel local symbols\n"); 63 64 if (!kernel->loadGlobalSymbols(debugSymbolTable)) 65 panic("could not load kernel symbols\n"); 66 67 if (!kernel->loadLocalSymbols(debugSymbolTable)) 68 panic("could not load kernel local symbols\n"); 69 70 DPRINTF(Loader, "Kernel start = %#x\n", kernelStart); 71 DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd); 72 DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry); 73 DPRINTF(Loader, "Kernel loaded...\n"); 74 75#if FULL_SYSTEM 76 kernelBinning = new Kernel::Binning(this); 77#endif // FULL_SYSTEM 78 79 // increment the number of running systms 80 numSystemsRunning++; 81} 82 83System::~System() 84{ 85#if FULL_SYSTEM 86 delete kernelSymtab; 87 delete kernel; 88 89 delete kernelBinning; 90#else 91 panic("System::fixFuncEventAddr needs to be rewritten " 92 "to work with syscall emulation"); 93#endif // FULL_SYSTEM} 94} 95 96#if FULL_SYSTEM 97 98 99int rgdb_wait = -1; 100 101#endif // FULL_SYSTEM 102 103int 104System::registerExecContext(ExecContext *xc, int id) 105{ 106 if (id == -1) { 107 for (id = 0; id < execContexts.size(); id++) { 108 if (!execContexts[id]) 109 break; 110 } 111 } 112 113 if (execContexts.size() <= id) 114 execContexts.resize(id + 1); 115 116 if (execContexts[id]) 117 panic("Cannot have two CPUs with the same id (%d)\n", id); 118 119 execContexts[id] = xc; 120 numcpus++; 121 122#if FULL_SYSTEM 123 RemoteGDB *rgdb = new RemoteGDB(this, xc); 124 GDBListener *gdbl = new GDBListener(rgdb, 7000 + id); 125 gdbl->listen(); 126 /** 127 * Uncommenting this line waits for a remote debugger to connect 128 * to the simulator before continuing. 129 */ 130 if (rgdb_wait != -1 && rgdb_wait == id) 131 gdbl->accept(); 132 133 if (remoteGDB.size() <= id) { 134 remoteGDB.resize(id + 1); 135 } 136 137 remoteGDB[id] = rgdb; 138#endif // FULL_SYSTEM 139 140 return id; 141} 142 143void 144System::startup() 145{ 146 int i; 147 for (i = 0; i < execContexts.size(); i++) 148 execContexts[i]->activate(0); 149} 150 151void 152System::replaceExecContext(ExecContext *xc, int id) 153{ 154 if (id >= execContexts.size()) { 155 panic("replaceExecContext: bad id, %d >= %d\n", 156 id, execContexts.size()); 157 } 158 159 execContexts[id] = xc; 160#if FULL_SYSTEM 161 remoteGDB[id]->replaceExecContext(xc); 162#endif // FULL_SYSTEM 163} 164 165#if !FULL_SYSTEM 166Addr 167System::new_page() 168{ 169 Addr return_addr = page_ptr << LogVMPageSize; 170 ++page_ptr; 171 return return_addr; 172} 173#endif 174 175void 176System::regStats() 177{ 178#if FULL_SYSTEM 179 kernelBinning->regStats(name() + ".kern"); 180#endif // FULL_SYSTEM 181} 182 183void 184System::serialize(ostream &os) 185{ 186#if FULL_SYSTEM 187 kernelBinning->serialize(os); 188 189 kernelSymtab->serialize("kernel_symtab", os); 190#endif // FULL_SYSTEM 191} 192 193 194void 195System::unserialize(Checkpoint *cp, const string §ion) 196{ 197#if FULL_SYSTEM 198 kernelBinning->unserialize(cp, section); 199 200 kernelSymtab->unserialize("kernel_symtab", cp, section); 201#endif // FULL_SYSTEM 202} 203 204void 205System::printSystems() 206{ 207 vector<System *>::iterator i = systemList.begin(); 208 vector<System *>::iterator end = systemList.end(); 209 for (; i != end; ++i) { 210 System *sys = *i; 211 cerr << "System " << sys->name() << ": " << hex << sys << endl; 212 } 213} 214 215extern "C" 216void 217printSystems() 218{ 219 System::printSystems(); 220} 221 222DEFINE_SIM_OBJECT_CLASS_NAME("System", System) 223 224