system.cc revision 2422
111293Sandreas.hansson@arm.com#include "base/loader/object_file.hh"
211293Sandreas.hansson@arm.com#include "base/loader/symtab.hh"
311293Sandreas.hansson@arm.com#include "cpu/exec_context.hh"
411293Sandreas.hansson@arm.com#include "arch/vtophys.hh"
511293Sandreas.hansson@arm.com#include "mem/memory.hh"
611293Sandreas.hansson@arm.com#include "sim/builder.hh"
711293Sandreas.hansson@arm.com#include "arch/isa_traits.hh"
811293Sandreas.hansson@arm.com#include "sim/byteswap.hh"
911293Sandreas.hansson@arm.com#include "sim/system.hh"
1011293Sandreas.hansson@arm.com#include "base/trace.hh"
1111293Sandreas.hansson@arm.com#if FULL_SYSTEM
1211293Sandreas.hansson@arm.com#include "base/remote_gdb.hh"
1311293Sandreas.hansson@arm.com#include "kern/kernel_stats.hh"
1411293Sandreas.hansson@arm.com#include "mem/functional/memory_control.hh"
1511293Sandreas.hansson@arm.com#include "targetarch/vtophys.hh"
1611293Sandreas.hansson@arm.com#endif
1711293Sandreas.hansson@arm.com
1811293Sandreas.hansson@arm.comusing namespace std;
1911293Sandreas.hansson@arm.comusing namespace TheISA;
2011293Sandreas.hansson@arm.com
2111293Sandreas.hansson@arm.comvector<System *> System::systemList;
2211293Sandreas.hansson@arm.com
2311293Sandreas.hansson@arm.comint System::numSystemsRunning = 0;
2411293Sandreas.hansson@arm.com
2511293Sandreas.hansson@arm.comSystem::System(Params *p)
2611293Sandreas.hansson@arm.com    : SimObject(p->name), physmem(p->physmem), numcpus(0),
2711293Sandreas.hansson@arm.com#if FULL_SYSTEM
2811293Sandreas.hansson@arm.com      memctrl(p->memctrl), init_param(p->init_param),
2911293Sandreas.hansson@arm.com#else
3011293Sandreas.hansson@arm.com      page_ptr(0),
3111293Sandreas.hansson@arm.com#endif
3211293Sandreas.hansson@arm.com      _params(p)
3311293Sandreas.hansson@arm.com{
3411293Sandreas.hansson@arm.com    // add self to global system list
3511293Sandreas.hansson@arm.com    systemList.push_back(this);
3611293Sandreas.hansson@arm.com
3711293Sandreas.hansson@arm.com#if FULL_SYSTEM
3811293Sandreas.hansson@arm.com    kernelSymtab = new SymbolTable;
3911293Sandreas.hansson@arm.com    debugSymbolTable = new SymbolTable;
4011293Sandreas.hansson@arm.com
4111293Sandreas.hansson@arm.com    /**
4211293Sandreas.hansson@arm.com     * Load the kernel code into memory
4311293Sandreas.hansson@arm.com     */
4411293Sandreas.hansson@arm.com    // Load kernel code
4511293Sandreas.hansson@arm.com    kernel = createObjectFile(params()->kernel_path);
4611293Sandreas.hansson@arm.com    if (kernel == NULL)
4711293Sandreas.hansson@arm.com        fatal("Could not load kernel file %s", params()->kernel_path);
4811293Sandreas.hansson@arm.com
4911293Sandreas.hansson@arm.com    // Load program sections into memory
5011293Sandreas.hansson@arm.com    kernel->loadSections(physmem, true);
5111293Sandreas.hansson@arm.com
5211293Sandreas.hansson@arm.com    // setup entry points
5311293Sandreas.hansson@arm.com    kernelStart = kernel->textBase();
5411293Sandreas.hansson@arm.com    kernelEnd = kernel->bssBase() + kernel->bssSize();
5511293Sandreas.hansson@arm.com    kernelEntry = kernel->entryPoint();
5611293Sandreas.hansson@arm.com
5711293Sandreas.hansson@arm.com    // load symbols
5811293Sandreas.hansson@arm.com    if (!kernel->loadGlobalSymbols(kernelSymtab))
5911293Sandreas.hansson@arm.com        panic("could not load kernel symbols\n");
6011293Sandreas.hansson@arm.com
6111293Sandreas.hansson@arm.com    if (!kernel->loadLocalSymbols(kernelSymtab))
6211293Sandreas.hansson@arm.com        panic("could not load kernel local symbols\n");
6311293Sandreas.hansson@arm.com
6411293Sandreas.hansson@arm.com    if (!kernel->loadGlobalSymbols(debugSymbolTable))
6511293Sandreas.hansson@arm.com        panic("could not load kernel symbols\n");
6611293Sandreas.hansson@arm.com
6711293Sandreas.hansson@arm.com    if (!kernel->loadLocalSymbols(debugSymbolTable))
6811293Sandreas.hansson@arm.com        panic("could not load kernel local symbols\n");
6911293Sandreas.hansson@arm.com
7011293Sandreas.hansson@arm.com    DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
7111293Sandreas.hansson@arm.com    DPRINTF(Loader, "Kernel end   = %#x\n", kernelEnd);
7211293Sandreas.hansson@arm.com    DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry);
7311293Sandreas.hansson@arm.com    DPRINTF(Loader, "Kernel loaded...\n");
7411293Sandreas.hansson@arm.com
7511293Sandreas.hansson@arm.com#if FULL_SYSTEM
7611293Sandreas.hansson@arm.com    kernelBinning = new Kernel::Binning(this);
7711293Sandreas.hansson@arm.com#endif // FULL_SYSTEM
7811293Sandreas.hansson@arm.com
7911293Sandreas.hansson@arm.com    // increment the number of running systms
8011293Sandreas.hansson@arm.com    numSystemsRunning++;
8111293Sandreas.hansson@arm.com}
8211293Sandreas.hansson@arm.com
8311293Sandreas.hansson@arm.comSystem::~System()
8411293Sandreas.hansson@arm.com{
8511293Sandreas.hansson@arm.com#if FULL_SYSTEM
8611293Sandreas.hansson@arm.com    delete kernelSymtab;
8711293Sandreas.hansson@arm.com    delete kernel;
8811293Sandreas.hansson@arm.com
8911293Sandreas.hansson@arm.com    delete kernelBinning;
9011293Sandreas.hansson@arm.com#else
9111293Sandreas.hansson@arm.com    panic("System::fixFuncEventAddr needs to be rewritten "
9211293Sandreas.hansson@arm.com          "to work with syscall emulation");
9311293Sandreas.hansson@arm.com#endif // FULL_SYSTEM}
9411293Sandreas.hansson@arm.com}
9511293Sandreas.hansson@arm.com
9611293Sandreas.hansson@arm.com#if FULL_SYSTEM
9711293Sandreas.hansson@arm.com
9811293Sandreas.hansson@arm.com
9911293Sandreas.hansson@arm.comint rgdb_wait = -1;
10011293Sandreas.hansson@arm.com
10111293Sandreas.hansson@arm.com#endif // FULL_SYSTEM
10211293Sandreas.hansson@arm.com
10311293Sandreas.hansson@arm.comint
10411293Sandreas.hansson@arm.comSystem::registerExecContext(ExecContext *xc, int id)
10511293Sandreas.hansson@arm.com{
10611293Sandreas.hansson@arm.com    if (id == -1) {
10711293Sandreas.hansson@arm.com        for (id = 0; id < execContexts.size(); id++) {
10811293Sandreas.hansson@arm.com            if (!execContexts[id])
10911293Sandreas.hansson@arm.com                break;
11011293Sandreas.hansson@arm.com        }
11111293Sandreas.hansson@arm.com    }
11211293Sandreas.hansson@arm.com
11311293Sandreas.hansson@arm.com    if (execContexts.size() <= id)
11411293Sandreas.hansson@arm.com        execContexts.resize(id + 1);
11511293Sandreas.hansson@arm.com
11611293Sandreas.hansson@arm.com    if (execContexts[id])
11711293Sandreas.hansson@arm.com        panic("Cannot have two CPUs with the same id (%d)\n", id);
11811293Sandreas.hansson@arm.com
11911293Sandreas.hansson@arm.com    execContexts[id] = xc;
12011293Sandreas.hansson@arm.com    numcpus++;
12111293Sandreas.hansson@arm.com
12211293Sandreas.hansson@arm.com#if FULL_SYSTEM
12311293Sandreas.hansson@arm.com    RemoteGDB *rgdb = new RemoteGDB(this, xc);
12411293Sandreas.hansson@arm.com    GDBListener *gdbl = new GDBListener(rgdb, 7000 + id);
12511293Sandreas.hansson@arm.com    gdbl->listen();
12611293Sandreas.hansson@arm.com    /**
12711293Sandreas.hansson@arm.com     * Uncommenting this line waits for a remote debugger to connect
12811293Sandreas.hansson@arm.com     * to the simulator before continuing.
12911293Sandreas.hansson@arm.com     */
13011293Sandreas.hansson@arm.com    if (rgdb_wait != -1 && rgdb_wait == id)
13111293Sandreas.hansson@arm.com        gdbl->accept();
13211293Sandreas.hansson@arm.com
13311293Sandreas.hansson@arm.com    if (remoteGDB.size() <= id) {
13411293Sandreas.hansson@arm.com        remoteGDB.resize(id + 1);
13511293Sandreas.hansson@arm.com    }
13611293Sandreas.hansson@arm.com
13711293Sandreas.hansson@arm.com    remoteGDB[id] = rgdb;
13811293Sandreas.hansson@arm.com#endif // FULL_SYSTEM
13911293Sandreas.hansson@arm.com
14011293Sandreas.hansson@arm.com    return id;
14111293Sandreas.hansson@arm.com}
14211293Sandreas.hansson@arm.com
14311293Sandreas.hansson@arm.comvoid
14411293Sandreas.hansson@arm.comSystem::startup()
14511293Sandreas.hansson@arm.com{
14611293Sandreas.hansson@arm.com    int i;
14711293Sandreas.hansson@arm.com    for (i = 0; i < execContexts.size(); i++)
14811293Sandreas.hansson@arm.com        execContexts[i]->activate(0);
14911293Sandreas.hansson@arm.com}
15011293Sandreas.hansson@arm.com
15111293Sandreas.hansson@arm.comvoid
15211293Sandreas.hansson@arm.comSystem::replaceExecContext(ExecContext *xc, int id)
15311293Sandreas.hansson@arm.com{
15411293Sandreas.hansson@arm.com    if (id >= execContexts.size()) {
15511293Sandreas.hansson@arm.com        panic("replaceExecContext: bad id, %d >= %d\n",
15611293Sandreas.hansson@arm.com              id, execContexts.size());
15711293Sandreas.hansson@arm.com    }
15811293Sandreas.hansson@arm.com
15911293Sandreas.hansson@arm.com    execContexts[id] = xc;
16011293Sandreas.hansson@arm.com#if FULL_SYSTEM
16111293Sandreas.hansson@arm.com    remoteGDB[id]->replaceExecContext(xc);
16211293Sandreas.hansson@arm.com#endif // FULL_SYSTEM
16311293Sandreas.hansson@arm.com}
16411293Sandreas.hansson@arm.com
16511293Sandreas.hansson@arm.com#if !FULL_SYSTEM
16611293Sandreas.hansson@arm.comAddr
16711293Sandreas.hansson@arm.comSystem::new_page()
16811293Sandreas.hansson@arm.com{
16911293Sandreas.hansson@arm.com    Addr return_addr = page_ptr << LogVMPageSize;
17011293Sandreas.hansson@arm.com    ++page_ptr;
17111293Sandreas.hansson@arm.com    return return_addr;
17211293Sandreas.hansson@arm.com}
17311293Sandreas.hansson@arm.com#endif
17411293Sandreas.hansson@arm.com
17511293Sandreas.hansson@arm.comvoid
17611293Sandreas.hansson@arm.comSystem::regStats()
17711293Sandreas.hansson@arm.com{
17811293Sandreas.hansson@arm.com#if FULL_SYSTEM
17911293Sandreas.hansson@arm.com    kernelBinning->regStats(name() + ".kern");
18011293Sandreas.hansson@arm.com#endif // FULL_SYSTEM
18111293Sandreas.hansson@arm.com}
18211293Sandreas.hansson@arm.com
18311293Sandreas.hansson@arm.comvoid
18411293Sandreas.hansson@arm.comSystem::serialize(ostream &os)
18511293Sandreas.hansson@arm.com{
18611293Sandreas.hansson@arm.com#if FULL_SYSTEM
18711293Sandreas.hansson@arm.com    kernelBinning->serialize(os);
18811293Sandreas.hansson@arm.com
18911293Sandreas.hansson@arm.com    kernelSymtab->serialize("kernel_symtab", os);
19011293Sandreas.hansson@arm.com#endif // FULL_SYSTEM
19111293Sandreas.hansson@arm.com}
19211293Sandreas.hansson@arm.com
19311293Sandreas.hansson@arm.com
19411293Sandreas.hansson@arm.comvoid
19511293Sandreas.hansson@arm.comSystem::unserialize(Checkpoint *cp, const string &section)
19611293Sandreas.hansson@arm.com{
19711293Sandreas.hansson@arm.com#if FULL_SYSTEM
19811293Sandreas.hansson@arm.com    kernelBinning->unserialize(cp, section);
19911293Sandreas.hansson@arm.com
20011293Sandreas.hansson@arm.com    kernelSymtab->unserialize("kernel_symtab", cp, section);
20111293Sandreas.hansson@arm.com#endif // FULL_SYSTEM
20211293Sandreas.hansson@arm.com}
20311293Sandreas.hansson@arm.com
20411293Sandreas.hansson@arm.comvoid
20511293Sandreas.hansson@arm.comSystem::printSystems()
20611293Sandreas.hansson@arm.com{
20711293Sandreas.hansson@arm.com    vector<System *>::iterator i = systemList.begin();
20811293Sandreas.hansson@arm.com    vector<System *>::iterator end = systemList.end();
20911293Sandreas.hansson@arm.com    for (; i != end; ++i) {
21011293Sandreas.hansson@arm.com        System *sys = *i;
21111293Sandreas.hansson@arm.com        cerr << "System " << sys->name() << ": " << hex << sys << endl;
21211293Sandreas.hansson@arm.com    }
21311293Sandreas.hansson@arm.com}
21411293Sandreas.hansson@arm.com
21511293Sandreas.hansson@arm.comextern "C"
21611293Sandreas.hansson@arm.comvoid
21711293Sandreas.hansson@arm.comprintSystems()
21811293Sandreas.hansson@arm.com{
21911293Sandreas.hansson@arm.com    System::printSystems();
22011293Sandreas.hansson@arm.com}
22111293Sandreas.hansson@arm.com
22211293Sandreas.hansson@arm.comDEFINE_SIM_OBJECT_CLASS_NAME("System", System)
22311293Sandreas.hansson@arm.com
22411293Sandreas.hansson@arm.com