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