system.cc revision 2665
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 &section)
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