system.cc revision 2640
12521SN/A#include "arch/isa_traits.hh" 21070SN/A#include "base/loader/object_file.hh" 31070SN/A#include "base/loader/symtab.hh" 42521SN/A#include "base/trace.hh" 556SN/A#include "cpu/exec_context.hh" 62521SN/A#include "mem/mem_object.hh" 72522SN/A#include "mem/physical.hh" 81711SN/A#include "sim/builder.hh" 92037SN/A#include "sim/byteswap.hh" 1056SN/A#include "sim/system.hh" 112378SN/A#if FULL_SYSTEM 122521SN/A#include "arch/vtophys.hh" 132378SN/A#include "base/remote_gdb.hh" 142378SN/A#include "kern/kernel_stats.hh" 152378SN/A#endif 162SN/A 172SN/Ausing namespace std; 182107SN/Ausing namespace TheISA; 192SN/A 202SN/Avector<System *> System::systemList; 212SN/A 222SN/Aint System::numSystemsRunning = 0; 232SN/A 241070SN/ASystem::System(Params *p) 252378SN/A : SimObject(p->name), physmem(p->physmem), numcpus(0), 262378SN/A#if FULL_SYSTEM 272521SN/A init_param(p->init_param), 282640Sstever@eecs.umich.edu functionalPort(p->name + "-fport"), 292640Sstever@eecs.umich.edu virtPort(p->name + "-vport"), 302378SN/A#else 312378SN/A page_ptr(0), 322378SN/A#endif 332422SN/A _params(p) 342SN/A{ 351070SN/A // add self to global system list 361070SN/A systemList.push_back(this); 371070SN/A 382378SN/A#if FULL_SYSTEM 391070SN/A kernelSymtab = new SymbolTable; 401074SN/A debugSymbolTable = new SymbolTable; 411070SN/A 422520SN/A 432520SN/A /** 442520SN/A * Get a functional port to memory 452520SN/A */ 462520SN/A Port *mem_port; 472520SN/A mem_port = physmem->getPort("functional"); 482520SN/A functionalPort.setPeer(mem_port); 492520SN/A mem_port->setPeer(&functionalPort); 502520SN/A 512521SN/A mem_port = physmem->getPort("functional"); 522521SN/A virtPort.setPeer(mem_port); 532521SN/A mem_port->setPeer(&virtPort); 542521SN/A 552520SN/A 561070SN/A /** 572158SN/A * Load the kernel code into memory 581070SN/A */ 591070SN/A // Load kernel code 602158SN/A kernel = createObjectFile(params()->kernel_path); 611070SN/A if (kernel == NULL) 622158SN/A fatal("Could not load kernel file %s", params()->kernel_path); 631070SN/A 641070SN/A // Load program sections into memory 652520SN/A kernel->loadSections(&functionalPort, LoadAddrMask); 661070SN/A 671070SN/A // setup entry points 681070SN/A kernelStart = kernel->textBase(); 691070SN/A kernelEnd = kernel->bssBase() + kernel->bssSize(); 701070SN/A kernelEntry = kernel->entryPoint(); 711070SN/A 721070SN/A // load symbols 731070SN/A if (!kernel->loadGlobalSymbols(kernelSymtab)) 741070SN/A panic("could not load kernel symbols\n"); 751070SN/A 761070SN/A if (!kernel->loadLocalSymbols(kernelSymtab)) 771070SN/A panic("could not load kernel local symbols\n"); 781070SN/A 791082SN/A if (!kernel->loadGlobalSymbols(debugSymbolTable)) 801074SN/A panic("could not load kernel symbols\n"); 811074SN/A 821074SN/A if (!kernel->loadLocalSymbols(debugSymbolTable)) 831074SN/A panic("could not load kernel local symbols\n"); 841074SN/A 851070SN/A DPRINTF(Loader, "Kernel start = %#x\n", kernelStart); 861070SN/A DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd); 871070SN/A DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry); 881070SN/A DPRINTF(Loader, "Kernel loaded...\n"); 891070SN/A 902378SN/A kernelBinning = new Kernel::Binning(this); 912378SN/A#endif // FULL_SYSTEM 922378SN/A 931070SN/A // increment the number of running systms 94878SN/A numSystemsRunning++; 952SN/A} 962SN/A 972SN/ASystem::~System() 982SN/A{ 992378SN/A#if FULL_SYSTEM 1001070SN/A delete kernelSymtab; 1011070SN/A delete kernel; 1021070SN/A 1031070SN/A delete kernelBinning; 1042378SN/A#else 1052378SN/A panic("System::fixFuncEventAddr needs to be rewritten " 1062378SN/A "to work with syscall emulation"); 1072378SN/A#endif // FULL_SYSTEM} 1082SN/A} 1092SN/A 1102378SN/A#if FULL_SYSTEM 1111885SN/A 1122SN/A 1131808SN/Aint rgdb_wait = -1; 1141808SN/A 1152378SN/A#endif // FULL_SYSTEM 1162378SN/A 117180SN/Aint 1181806SN/ASystem::registerExecContext(ExecContext *xc, int id) 1192SN/A{ 1201806SN/A if (id == -1) { 1211806SN/A for (id = 0; id < execContexts.size(); id++) { 1221806SN/A if (!execContexts[id]) 1231806SN/A break; 1241806SN/A } 1251806SN/A } 1261806SN/A 1271806SN/A if (execContexts.size() <= id) 1281806SN/A execContexts.resize(id + 1); 1291806SN/A 1301806SN/A if (execContexts[id]) 1311806SN/A panic("Cannot have two CPUs with the same id (%d)\n", id); 1321806SN/A 1331806SN/A execContexts[id] = xc; 1341806SN/A numcpus++; 1351070SN/A 1362378SN/A#if FULL_SYSTEM 1371070SN/A RemoteGDB *rgdb = new RemoteGDB(this, xc); 1381806SN/A GDBListener *gdbl = new GDBListener(rgdb, 7000 + id); 1391070SN/A gdbl->listen(); 1401070SN/A /** 1411070SN/A * Uncommenting this line waits for a remote debugger to connect 1421070SN/A * to the simulator before continuing. 1431070SN/A */ 1441808SN/A if (rgdb_wait != -1 && rgdb_wait == id) 1451808SN/A gdbl->accept(); 1461070SN/A 1471806SN/A if (remoteGDB.size() <= id) { 1481806SN/A remoteGDB.resize(id + 1); 1491070SN/A } 1501070SN/A 1511806SN/A remoteGDB[id] = rgdb; 1522378SN/A#endif // FULL_SYSTEM 1531070SN/A 1541806SN/A return id; 155180SN/A} 15675SN/A 157180SN/Avoid 1581129SN/ASystem::startup() 1591129SN/A{ 1602114SN/A int i; 1612114SN/A for (i = 0; i < execContexts.size(); i++) 1622114SN/A execContexts[i]->activate(0); 1631129SN/A} 1641129SN/A 1651129SN/Avoid 1661806SN/ASystem::replaceExecContext(ExecContext *xc, int id) 167180SN/A{ 1681806SN/A if (id >= execContexts.size()) { 1691806SN/A panic("replaceExecContext: bad id, %d >= %d\n", 1701806SN/A id, execContexts.size()); 171180SN/A } 172180SN/A 1731806SN/A execContexts[id] = xc; 1742378SN/A#if FULL_SYSTEM 1751806SN/A remoteGDB[id]->replaceExecContext(xc); 1762378SN/A#endif // FULL_SYSTEM 1772SN/A} 1782SN/A 1792378SN/A#if !FULL_SYSTEM 1802378SN/AAddr 1812378SN/ASystem::new_page() 1822378SN/A{ 1832378SN/A Addr return_addr = page_ptr << LogVMPageSize; 1842378SN/A ++page_ptr; 1852378SN/A return return_addr; 1862378SN/A} 1872378SN/A#endif 1882378SN/A 1891070SN/Avoid 1901070SN/ASystem::regStats() 1911070SN/A{ 1922378SN/A#if FULL_SYSTEM 1931070SN/A kernelBinning->regStats(name() + ".kern"); 1942378SN/A#endif // FULL_SYSTEM 1951070SN/A} 1961070SN/A 1971070SN/Avoid 1981070SN/ASystem::serialize(ostream &os) 1991070SN/A{ 2002378SN/A#if FULL_SYSTEM 2011070SN/A kernelBinning->serialize(os); 2021984SN/A 2031984SN/A kernelSymtab->serialize("kernel_symtab", os); 2042378SN/A#endif // FULL_SYSTEM 2051070SN/A} 2061070SN/A 2071070SN/A 2081070SN/Avoid 2091070SN/ASystem::unserialize(Checkpoint *cp, const string §ion) 2101070SN/A{ 2112378SN/A#if FULL_SYSTEM 2121070SN/A kernelBinning->unserialize(cp, section); 2131984SN/A 2141984SN/A kernelSymtab->unserialize("kernel_symtab", cp, section); 2152378SN/A#endif // FULL_SYSTEM 2161070SN/A} 2172SN/A 2182SN/Avoid 2192SN/ASystem::printSystems() 2202SN/A{ 2212SN/A vector<System *>::iterator i = systemList.begin(); 2222SN/A vector<System *>::iterator end = systemList.end(); 2232SN/A for (; i != end; ++i) { 2242SN/A System *sys = *i; 2252SN/A cerr << "System " << sys->name() << ": " << hex << sys << endl; 2262SN/A } 2272SN/A} 2282SN/A 2292SN/Aextern "C" 2302SN/Avoid 2312SN/AprintSystems() 2322SN/A{ 2332SN/A System::printSystems(); 2342SN/A} 2352SN/A 2362424SN/A#if FULL_SYSTEM 2372424SN/A 2382424SN/A// In full system mode, only derived classes (e.g. AlphaLinuxSystem) 2392424SN/A// can be created directly. 2402424SN/A 2412158SN/ADEFINE_SIM_OBJECT_CLASS_NAME("System", System) 2422SN/A 2432424SN/A#else 2442424SN/A 2452424SN/ABEGIN_DECLARE_SIM_OBJECT_PARAMS(System) 2462424SN/A 2472522SN/A SimObjectParam<PhysicalMemory *> physmem; 2482424SN/A 2492424SN/AEND_DECLARE_SIM_OBJECT_PARAMS(System) 2502424SN/A 2512424SN/ABEGIN_INIT_SIM_OBJECT_PARAMS(System) 2522424SN/A 2532424SN/A INIT_PARAM(physmem, "physical memory") 2542424SN/A 2552424SN/AEND_INIT_SIM_OBJECT_PARAMS(System) 2562424SN/A 2572424SN/ACREATE_SIM_OBJECT(System) 2582424SN/A{ 2592424SN/A System::Params *p = new System::Params; 2602424SN/A p->name = getInstanceName(); 2612424SN/A p->physmem = physmem; 2622424SN/A return new System(p); 2632424SN/A} 2642424SN/A 2652424SN/AREGISTER_SIM_OBJECT("System", System) 2662424SN/A 2672424SN/A#endif 268