system.cc revision 1074
16145Snate@binkert.org/*
26145Snate@binkert.org * Copyright (c) 2002-2004 The Regents of The University of Michigan
36145Snate@binkert.org * All rights reserved.
46145Snate@binkert.org *
56145Snate@binkert.org * Redistribution and use in source and binary forms, with or without
66145Snate@binkert.org * modification, are permitted provided that the following conditions are
76145Snate@binkert.org * met: redistributions of source code must retain the above copyright
86145Snate@binkert.org * notice, this list of conditions and the following disclaimer;
96145Snate@binkert.org * redistributions in binary form must reproduce the above copyright
106145Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
116145Snate@binkert.org * documentation and/or other materials provided with the distribution;
126145Snate@binkert.org * neither the name of the copyright holders nor the names of its
136145Snate@binkert.org * contributors may be used to endorse or promote products derived from
146145Snate@binkert.org * this software without specific prior written permission.
156145Snate@binkert.org *
166145Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176145Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186145Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196145Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206145Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216145Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226145Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236145Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246145Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256145Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266145Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276145Snate@binkert.org */
286145Snate@binkert.org
296145Snate@binkert.org#include "base/loader/object_file.hh"
306145Snate@binkert.org#include "base/loader/symtab.hh"
316145Snate@binkert.org#include "base/remote_gdb.hh"
326145Snate@binkert.org#include "cpu/exec_context.hh"
336145Snate@binkert.org#include "kern/kernel_stats.hh"
346145Snate@binkert.org#include "mem/functional_mem/memory_control.hh"
356145Snate@binkert.org#include "mem/functional_mem/physical_memory.hh"
366145Snate@binkert.org#include "targetarch/vtophys.hh"
376145Snate@binkert.org#include "sim/param.hh"
386145Snate@binkert.org#include "sim/system.hh"
396145Snate@binkert.org#include "base/trace.hh"
406145Snate@binkert.org
416145Snate@binkert.orgusing namespace std;
426145Snate@binkert.org
436145Snate@binkert.orgvector<System *> System::systemList;
446145Snate@binkert.org
457002Snate@binkert.orgint System::numSystemsRunning = 0;
467002Snate@binkert.org
477002Snate@binkert.orgextern SymbolTable *debugSymbolTable;
488946Sandreas.hansson@arm.com
498946Sandreas.hansson@arm.comSystem::System(Params *p)
507002Snate@binkert.org    : SimObject(p->name), memctrl(p->memctrl), physmem(p->physmem),
517454Snate@binkert.org      init_param(p->init_param), params(p)
527832Snate@binkert.org{
537454Snate@binkert.org    // add self to global system list
547454Snate@binkert.org    systemList.push_back(this);
557056Snate@binkert.org
567048Snate@binkert.org    kernelSymtab = new SymbolTable;
578229Snate@binkert.org    consoleSymtab = new SymbolTable;
587048Snate@binkert.org    debugSymbolTable = new SymbolTable;
597048Snate@binkert.org
606154Snate@binkert.org    /**
616154Snate@binkert.org     * Load the kernel, pal, and console code into memory
626876Ssteve.reinhardt@amd.com     */
637055Snate@binkert.org    // Load kernel code
647454Snate@binkert.org    kernel = createObjectFile(params->kernel_path);
657055Snate@binkert.org    if (kernel == NULL)
666145Snate@binkert.org        fatal("Could not load kernel file %s", params->kernel_path);
676145Snate@binkert.org
686145Snate@binkert.org    // Load Console Code
696876Ssteve.reinhardt@amd.com    console = createObjectFile(params->console_path);
709171Snilay@cs.wisc.edu    if (console == NULL)
716145Snate@binkert.org        fatal("Could not load console file %s", params->console_path);
727048Snate@binkert.org
737048Snate@binkert.org    // Load pal file
746285Snate@binkert.org    pal = createObjectFile(params->palcode);
757048Snate@binkert.org    if (pal == NULL)
767048Snate@binkert.org        fatal("Could not load PALcode file %s", params->palcode);
777048Snate@binkert.org
786145Snate@binkert.org
797048Snate@binkert.org    // Load program sections into memory
807048Snate@binkert.org    pal->loadSections(physmem, true);
816876Ssteve.reinhardt@amd.com    console->loadSections(physmem, true);
827048Snate@binkert.org    kernel->loadSections(physmem, true);
836896SBrad.Beckmann@amd.com
847048Snate@binkert.org    // setup entry points
857048Snate@binkert.org    kernelStart = kernel->textBase();
866285Snate@binkert.org    kernelEnd = kernel->bssBase() + kernel->bssSize();
877048Snate@binkert.org    kernelEntry = kernel->entryPoint();
887048Snate@binkert.org
897048Snate@binkert.org    // load symbols
906285Snate@binkert.org    if (!kernel->loadGlobalSymbols(kernelSymtab))
917048Snate@binkert.org        panic("could not load kernel symbols\n");
927048Snate@binkert.org
937048Snate@binkert.org    if (!kernel->loadLocalSymbols(kernelSymtab))
947048Snate@binkert.org        panic("could not load kernel local symbols\n");
957048Snate@binkert.org
968436SBrad.Beckmann@amd.com    if (!console->loadGlobalSymbols(consoleSymtab))
978436SBrad.Beckmann@amd.com        panic("could not load console symbols\n");
986285Snate@binkert.org
996285Snate@binkert.org     if (!kernel->loadGlobalSymbols(debugSymbolTable))
1006889SBrad.Beckmann@amd.com        panic("could not load kernel symbols\n");
1016889SBrad.Beckmann@amd.com
1027048Snate@binkert.org    if (!kernel->loadLocalSymbols(debugSymbolTable))
1037048Snate@binkert.org        panic("could not load kernel local symbols\n");
1047048Snate@binkert.org
1056889SBrad.Beckmann@amd.com    if (!console->loadGlobalSymbols(debugSymbolTable))
1066889SBrad.Beckmann@amd.com        panic("could not load console symbols\n");
1077048Snate@binkert.org
1087048Snate@binkert.org    if (!pal->loadGlobalSymbols(debugSymbolTable))
1096145Snate@binkert.org        panic("could not load pal symbols\n");
1107048Snate@binkert.org
1116145Snate@binkert.org    if (!pal->loadLocalSymbols(debugSymbolTable))
1129231Snilay@cs.wisc.edu        panic("could not load pal symbols\n");
1136145Snate@binkert.org
1147048Snate@binkert.org
1157048Snate@binkert.org    DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
1169171Snilay@cs.wisc.edu    DPRINTF(Loader, "Kernel end   = %#x\n", kernelEnd);
1177048Snate@binkert.org    DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry);
1187048Snate@binkert.org    DPRINTF(Loader, "Kernel loaded...\n");
1196145Snate@binkert.org
1207048Snate@binkert.org    Addr addr = 0;
1216889SBrad.Beckmann@amd.com#ifdef DEBUG
1229171Snilay@cs.wisc.edu    consolePanicEvent = new BreakPCEvent(&pcEventQueue, "console panic");
1237048Snate@binkert.org    if (consoleSymtab->findAddress("panic", addr))
1247048Snate@binkert.org        consolePanicEvent->schedule(addr);
1256889SBrad.Beckmann@amd.com#endif
1267048Snate@binkert.org
1277054Snate@binkert.org    /**
1287048Snate@binkert.org     * Copy the osflags (kernel arguments) into the consoles
1297048Snate@binkert.org     * memory. (Presently Linux does not use the console service
1306889SBrad.Beckmann@amd.com     * routine to get these command line arguments, but Tru64 and
1316145Snate@binkert.org     * others do.)
1326145Snate@binkert.org     */
1336145Snate@binkert.org    if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
1346145Snate@binkert.org        Addr paddr = vtophys(physmem, addr);
1357048Snate@binkert.org        char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t));
1367048Snate@binkert.org
1376145Snate@binkert.org        if (osflags)
1386145Snate@binkert.org              strcpy(osflags, params->boot_osflags.c_str());
1397048Snate@binkert.org    }
1409465Snilay@cs.wisc.edu
1417048Snate@binkert.org    /**
1427048Snate@binkert.org     * Set the hardware reset parameter block system type and revision
1437048Snate@binkert.org     * information to Tsunami.
1447048Snate@binkert.org     */
1457048Snate@binkert.org    if (consoleSymtab->findAddress("xxm_rpb", addr)) {
1467048Snate@binkert.org        Addr paddr = vtophys(physmem, addr);
1477048Snate@binkert.org        char *hwrpb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t));
1487048Snate@binkert.org
1497048Snate@binkert.org        if (!hwrpb)
1507048Snate@binkert.org            panic("could not translate hwrpb addr\n");
1516145Snate@binkert.org
1526145Snate@binkert.org        *(uint64_t*)(hwrpb+0x50) = params->system_type;
1537048Snate@binkert.org        *(uint64_t*)(hwrpb+0x58) = params->system_rev;
1549206Snilay@cs.wisc.edu    } else
1557048Snate@binkert.org        panic("could not find hwrpb\n");
1567048Snate@binkert.org
1577048Snate@binkert.org    // increment the number of running systms
1589231Snilay@cs.wisc.edu    numSystemsRunning++;
1597048Snate@binkert.org
1607054Snate@binkert.org    kernelBinning = new Kernel::Binning(this);
1617048Snate@binkert.org}
1627048Snate@binkert.org
1637048Snate@binkert.orgSystem::~System()
1649206Snilay@cs.wisc.edu{
1657048Snate@binkert.org    delete kernelSymtab;
1667048Snate@binkert.org    delete consoleSymtab;
1677048Snate@binkert.org    delete kernel;
1687048Snate@binkert.org    delete console;
1697048Snate@binkert.org    delete pal;
1707048Snate@binkert.org
1717048Snate@binkert.org    delete kernelBinning;
1727048Snate@binkert.org
1737048Snate@binkert.org#ifdef DEBUG
1747048Snate@binkert.org    delete consolePanicEvent;
1757048Snate@binkert.org#endif
1767048Snate@binkert.org}
1777048Snate@binkert.org
1787048Snate@binkert.orgbool
1797048Snate@binkert.orgSystem::breakpoint()
1807048Snate@binkert.org{
1817048Snate@binkert.org    return remoteGDB[0]->trap(ALPHA_KENTRY_INT);
1827048Snate@binkert.org}
1837048Snate@binkert.org
1847048Snate@binkert.orgint
1857048Snate@binkert.orgSystem::registerExecContext(ExecContext *xc)
1867048Snate@binkert.org{
1877048Snate@binkert.org    int xcIndex = execContexts.size();
1889171Snilay@cs.wisc.edu    execContexts.push_back(xc);
1897048Snate@binkert.org
1907048Snate@binkert.org    if (xcIndex == 0) {
1917048Snate@binkert.org        // activate with zero delay so that we start ticking right
1927048Snate@binkert.org        // away on cycle 0
1937048Snate@binkert.org        xc->activate(0);
1947048Snate@binkert.org    }
1957048Snate@binkert.org
1967048Snate@binkert.org    RemoteGDB *rgdb = new RemoteGDB(this, xc);
1977048Snate@binkert.org    GDBListener *gdbl = new GDBListener(rgdb, 7000 + xcIndex);
1987048Snate@binkert.org    gdbl->listen();
1997048Snate@binkert.org    /**
2007048Snate@binkert.org     * Uncommenting this line waits for a remote debugger to connect
2017048Snate@binkert.org     * to the simulator before continuing.
2027048Snate@binkert.org     */
2037048Snate@binkert.org    //gdbl->accept();
2047048Snate@binkert.org
2057048Snate@binkert.org    if (remoteGDB.size() <= xcIndex) {
2067048Snate@binkert.org        remoteGDB.resize(xcIndex+1);
2077048Snate@binkert.org    }
2087048Snate@binkert.org
2096145Snate@binkert.org    remoteGDB[xcIndex] = rgdb;
2106145Snate@binkert.org
2119171Snilay@cs.wisc.edu    return xcIndex;
2127048Snate@binkert.org}
2137048Snate@binkert.org
2146145Snate@binkert.orgvoid
2156145Snate@binkert.orgSystem::replaceExecContext(ExecContext *xc, int xcIndex)
2167048Snate@binkert.org{
2177048Snate@binkert.org    if (xcIndex >= execContexts.size()) {
2187048Snate@binkert.org        panic("replaceExecContext: bad xcIndex, %d >= %d\n",
2197048Snate@binkert.org              xcIndex, execContexts.size());
2207054Snate@binkert.org    }
2217048Snate@binkert.org
2227048Snate@binkert.org    execContexts[xcIndex] = xc;
2237048Snate@binkert.org    remoteGDB[xcIndex]->replaceExecContext(xc);
2246145Snate@binkert.org}
2256145Snate@binkert.org
2269231Snilay@cs.wisc.eduvoid
2277048Snate@binkert.orgSystem::regStats()
2287048Snate@binkert.org{
2297048Snate@binkert.org    kernelBinning->regStats(name() + ".kern");
2309171Snilay@cs.wisc.edu}
2317048Snate@binkert.org
2326145Snate@binkert.orgvoid
2336145Snate@binkert.orgSystem::serialize(ostream &os)
2347048Snate@binkert.org{
2357048Snate@binkert.org    kernelBinning->serialize(os);
2366145Snate@binkert.org}
2377048Snate@binkert.org
2387048Snate@binkert.org
2397048Snate@binkert.orgvoid
2407048Snate@binkert.orgSystem::unserialize(Checkpoint *cp, const string &section)
2417048Snate@binkert.org{
2427048Snate@binkert.org    kernelBinning->unserialize(cp, section);
2437048Snate@binkert.org}
2447048Snate@binkert.org
2457048Snate@binkert.orgvoid
2467048Snate@binkert.orgSystem::printSystems()
2477048Snate@binkert.org{
2487048Snate@binkert.org    vector<System *>::iterator i = systemList.begin();
2497048Snate@binkert.org    vector<System *>::iterator end = systemList.end();
2507048Snate@binkert.org    for (; i != end; ++i) {
2517048Snate@binkert.org        System *sys = *i;
2527048Snate@binkert.org        cerr << "System " << sys->name() << ": " << hex << sys << endl;
2537048Snate@binkert.org    }
2547048Snate@binkert.org}
2557048Snate@binkert.org
2567048Snate@binkert.orgextern "C"
2577048Snate@binkert.orgvoid
2587048Snate@binkert.orgprintSystems()
2597048Snate@binkert.org{
2607048Snate@binkert.org    System::printSystems();
2616145Snate@binkert.org}
2626145Snate@binkert.org
2637048Snate@binkert.orgDEFINE_SIM_OBJECT_CLASS_NAME("System", System)
2647048Snate@binkert.org
2657048Snate@binkert.org