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