system.cc revision 75
113481Sgiacomo.travaglini@arm.com/*
213481Sgiacomo.travaglini@arm.com * Copyright (c) 2003 The Regents of The University of Michigan
313481Sgiacomo.travaglini@arm.com * All rights reserved.
413481Sgiacomo.travaglini@arm.com *
513481Sgiacomo.travaglini@arm.com * Redistribution and use in source and binary forms, with or without
613481Sgiacomo.travaglini@arm.com * modification, are permitted provided that the following conditions are
713481Sgiacomo.travaglini@arm.com * met: redistributions of source code must retain the above copyright
813481Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer;
913481Sgiacomo.travaglini@arm.com * redistributions in binary form must reproduce the above copyright
1013481Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer in the
1113481Sgiacomo.travaglini@arm.com * documentation and/or other materials provided with the distribution;
1213481Sgiacomo.travaglini@arm.com * neither the name of the copyright holders nor the names of its
1313481Sgiacomo.travaglini@arm.com * contributors may be used to endorse or promote products derived from
1413481Sgiacomo.travaglini@arm.com * this software without specific prior written permission.
1513481Sgiacomo.travaglini@arm.com *
1613481Sgiacomo.travaglini@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1713481Sgiacomo.travaglini@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1813481Sgiacomo.travaglini@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1913481Sgiacomo.travaglini@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2013481Sgiacomo.travaglini@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2113481Sgiacomo.travaglini@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2213481Sgiacomo.travaglini@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2313481Sgiacomo.travaglini@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2413481Sgiacomo.travaglini@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2513481Sgiacomo.travaglini@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2613481Sgiacomo.travaglini@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2713481Sgiacomo.travaglini@arm.com */
2813481Sgiacomo.travaglini@arm.com
2913481Sgiacomo.travaglini@arm.com#include "cpu/exec_context.hh"
3013481Sgiacomo.travaglini@arm.com#include "base/loader/object_file.hh"
3113481Sgiacomo.travaglini@arm.com#include "mem/functional_mem/memory_control.hh"
3213481Sgiacomo.travaglini@arm.com#include "mem/functional_mem/physical_memory.hh"
3313481Sgiacomo.travaglini@arm.com#include "base/loader/symtab.hh"
3413481Sgiacomo.travaglini@arm.com#include "base/remote_gdb.hh"
3513481Sgiacomo.travaglini@arm.com#include "targetarch/vtophys.hh"
3613481Sgiacomo.travaglini@arm.com#include "sim/system.hh"
3713481Sgiacomo.travaglini@arm.com#include "base/trace.hh"
3813481Sgiacomo.travaglini@arm.com
3913481Sgiacomo.travaglini@arm.comusing namespace std;
4013481Sgiacomo.travaglini@arm.com
4113481Sgiacomo.travaglini@arm.comvector<System *> System::systemList;
4213481Sgiacomo.travaglini@arm.com
4313481Sgiacomo.travaglini@arm.comint System::numSystemsRunning = 0;
4413481Sgiacomo.travaglini@arm.com
4513481Sgiacomo.travaglini@arm.comSystem::System(const std::string _name,
4613481Sgiacomo.travaglini@arm.com               MemoryController *_memCtrl,
4713481Sgiacomo.travaglini@arm.com               PhysicalMemory *_physmem,
4813481Sgiacomo.travaglini@arm.com               const std::string &kernel_path,
4913481Sgiacomo.travaglini@arm.com               const std::string &console_path,
5013481Sgiacomo.travaglini@arm.com               const std::string &palcode,
5113481Sgiacomo.travaglini@arm.com               const std::string &boot_osflags)
5213481Sgiacomo.travaglini@arm.com    : SimObject(_name),
5313481Sgiacomo.travaglini@arm.com      kernel_panic_event(&pcEventQueue, "kernel panic"),
5413481Sgiacomo.travaglini@arm.com      console_panic_event(&pcEventQueue, "console panic"),
5513481Sgiacomo.travaglini@arm.com      badaddr_event(&pcEventQueue, "badaddr"),
5613481Sgiacomo.travaglini@arm.com      skip_power_state(&pcEventQueue, "tl_v48_capture_power_state"),
5713481Sgiacomo.travaglini@arm.com      skip_scavenge_boot(&pcEventQueue, "pmap_scavenge_boot"),
5813481Sgiacomo.travaglini@arm.com      printf_event(&pcEventQueue, "printf"),
5913481Sgiacomo.travaglini@arm.com      debug_printf_event(&pcEventQueue, "debug_printf", false),
6013481Sgiacomo.travaglini@arm.com      debug_printfr_event(&pcEventQueue, "debug_printfr", true),
6113481Sgiacomo.travaglini@arm.com      dump_mbuf_event(&pcEventQueue, "dump_mbuf"),
6213481Sgiacomo.travaglini@arm.com      memCtrl(_memCtrl),
6313481Sgiacomo.travaglini@arm.com      physmem(_physmem),
6413481Sgiacomo.travaglini@arm.com      remoteGDB(NULL),
6513481Sgiacomo.travaglini@arm.com      gdbListen(NULL)
6613481Sgiacomo.travaglini@arm.com{
6713481Sgiacomo.travaglini@arm.com    kernelSymtab = new SymbolTable;
6813481Sgiacomo.travaglini@arm.com    consoleSymtab = new SymbolTable;
6913481Sgiacomo.travaglini@arm.com
7013481Sgiacomo.travaglini@arm.com    ObjectFile *kernel = createObjectFile(kernel_path);
7113481Sgiacomo.travaglini@arm.com    if (kernel == NULL)
7213481Sgiacomo.travaglini@arm.com        fatal("Could not load kernel file %s", kernel_path);
7313481Sgiacomo.travaglini@arm.com
7413481Sgiacomo.travaglini@arm.com    ObjectFile *console = createObjectFile(console_path);
7513481Sgiacomo.travaglini@arm.com    if (console == NULL)
7613481Sgiacomo.travaglini@arm.com        fatal("Could not load console file %s", console_path);
7713481Sgiacomo.travaglini@arm.com
7813481Sgiacomo.travaglini@arm.com    if (!kernel->loadGlobalSymbols(kernelSymtab))
7913481Sgiacomo.travaglini@arm.com        panic("could not load kernel symbols\n");
8013481Sgiacomo.travaglini@arm.com
8113481Sgiacomo.travaglini@arm.com    if (!console->loadGlobalSymbols(consoleSymtab))
8213481Sgiacomo.travaglini@arm.com        panic("could not load console symbols\n");
8313481Sgiacomo.travaglini@arm.com
8413481Sgiacomo.travaglini@arm.com    // Load pal file
8513481Sgiacomo.travaglini@arm.com    ObjectFile *pal = createObjectFile(palcode);
8613481Sgiacomo.travaglini@arm.com    if (pal == NULL)
8713481Sgiacomo.travaglini@arm.com        fatal("Could not load PALcode file %s", palcode);
8813481Sgiacomo.travaglini@arm.com    pal->loadSections(physmem, true);
8913481Sgiacomo.travaglini@arm.com
9013481Sgiacomo.travaglini@arm.com    // copy of initial reg file contents
9113481Sgiacomo.travaglini@arm.com    initRegs = new RegFile;
9213481Sgiacomo.travaglini@arm.com    memset(initRegs, 0, sizeof(RegFile));
9313481Sgiacomo.travaglini@arm.com
9413481Sgiacomo.travaglini@arm.com    // Load console file
9513481Sgiacomo.travaglini@arm.com    console->loadSections(physmem, true);
9613481Sgiacomo.travaglini@arm.com
9713481Sgiacomo.travaglini@arm.com    // Load kernel file
9813481Sgiacomo.travaglini@arm.com    kernel->loadSections(physmem, true);
9913481Sgiacomo.travaglini@arm.com    kernelStart = kernel->textBase();
10013481Sgiacomo.travaglini@arm.com    kernelEnd = kernel->bssBase() + kernel->bssSize();
10113481Sgiacomo.travaglini@arm.com    kernelEntry = kernel->entryPoint();
10213481Sgiacomo.travaglini@arm.com
10313481Sgiacomo.travaglini@arm.com    DPRINTF(Loader, "Kernel start = %#x\n"
10413481Sgiacomo.travaglini@arm.com            "Kernel end   = %#x\n"
10513481Sgiacomo.travaglini@arm.com            "Kernel entry = %#x\n",
10613481Sgiacomo.travaglini@arm.com            kernelStart, kernelEnd, kernelEntry);
10713481Sgiacomo.travaglini@arm.com
10813481Sgiacomo.travaglini@arm.com    // Setup kernel boot parameters
10913481Sgiacomo.travaglini@arm.com    initRegs->pc = 0x4001;
11013481Sgiacomo.travaglini@arm.com    initRegs->npc = initRegs->pc + sizeof(MachInst);
11113481Sgiacomo.travaglini@arm.com
11213481Sgiacomo.travaglini@arm.com    DPRINTF(Loader, "Kernel loaded...\n");
11313481Sgiacomo.travaglini@arm.com
11413481Sgiacomo.travaglini@arm.com#ifdef FULL_SYSTEM
11513481Sgiacomo.travaglini@arm.com    Addr addr = 0;
11613481Sgiacomo.travaglini@arm.com
11713481Sgiacomo.travaglini@arm.com    if (kernelSymtab->findAddress("enable_async_printf", addr)) {
11813481Sgiacomo.travaglini@arm.com        Addr paddr = vtophys(physmem, addr);
11913481Sgiacomo.travaglini@arm.com        uint8_t *enable_async_printf =
12013481Sgiacomo.travaglini@arm.com            physmem->dma_addr(paddr, sizeof(uint32_t));
12113481Sgiacomo.travaglini@arm.com
12213481Sgiacomo.travaglini@arm.com        if (enable_async_printf)
12313481Sgiacomo.travaglini@arm.com            *(uint32_t *)enable_async_printf = 0;
12413481Sgiacomo.travaglini@arm.com    }
12513481Sgiacomo.travaglini@arm.com
12613481Sgiacomo.travaglini@arm.com    if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
12713481Sgiacomo.travaglini@arm.com        Addr paddr = vtophys(physmem, addr);
12813481Sgiacomo.travaglini@arm.com        char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t));
12913481Sgiacomo.travaglini@arm.com
13013481Sgiacomo.travaglini@arm.com        if (osflags)
13113481Sgiacomo.travaglini@arm.com            strcpy(osflags, boot_osflags.c_str());
13213481Sgiacomo.travaglini@arm.com    }
13313481Sgiacomo.travaglini@arm.com
13413481Sgiacomo.travaglini@arm.com    if (kernelSymtab->findAddress("panic", addr))
13513481Sgiacomo.travaglini@arm.com        kernel_panic_event.schedule(addr);
13613481Sgiacomo.travaglini@arm.com    else
13713481Sgiacomo.travaglini@arm.com        panic("could not find kernel symbol \'panic\'");
13813481Sgiacomo.travaglini@arm.com
13913481Sgiacomo.travaglini@arm.com    if (consoleSymtab->findAddress("panic", addr))
14013481Sgiacomo.travaglini@arm.com        console_panic_event.schedule(addr);
14113481Sgiacomo.travaglini@arm.com
14213481Sgiacomo.travaglini@arm.com    if (kernelSymtab->findAddress("badaddr", addr))
14313481Sgiacomo.travaglini@arm.com        badaddr_event.schedule(addr);
14413481Sgiacomo.travaglini@arm.com    else
14513481Sgiacomo.travaglini@arm.com        panic("could not find kernel symbol \'badaddr\'");
14613481Sgiacomo.travaglini@arm.com
14713481Sgiacomo.travaglini@arm.com    if (kernelSymtab->findAddress("tl_v48_capture_power_state", addr))
14813481Sgiacomo.travaglini@arm.com        skip_power_state.schedule(addr);
14913481Sgiacomo.travaglini@arm.com
15013481Sgiacomo.travaglini@arm.com    if (kernelSymtab->findAddress("pmap_scavenge_boot", addr))
15113481Sgiacomo.travaglini@arm.com        skip_scavenge_boot.schedule(addr);
15213481Sgiacomo.travaglini@arm.com
15313481Sgiacomo.travaglini@arm.com#if TRACING_ON
15413481Sgiacomo.travaglini@arm.com    if (kernelSymtab->findAddress("printf", addr))
15513481Sgiacomo.travaglini@arm.com        printf_event.schedule(addr);
15613481Sgiacomo.travaglini@arm.com
15713481Sgiacomo.travaglini@arm.com    if (kernelSymtab->findAddress("m5printf", addr))
15813481Sgiacomo.travaglini@arm.com        debug_printf_event.schedule(addr);
15913481Sgiacomo.travaglini@arm.com
16013481Sgiacomo.travaglini@arm.com    if (kernelSymtab->findAddress("m5printfr", addr))
16113481Sgiacomo.travaglini@arm.com        debug_printfr_event.schedule(addr);
16213481Sgiacomo.travaglini@arm.com
16313481Sgiacomo.travaglini@arm.com    if (kernelSymtab->findAddress("m5_dump_mbuf", addr))
16413481Sgiacomo.travaglini@arm.com        dump_mbuf_event.schedule(addr);
16513481Sgiacomo.travaglini@arm.com#endif
16613481Sgiacomo.travaglini@arm.com
16713481Sgiacomo.travaglini@arm.com#endif
16813481Sgiacomo.travaglini@arm.com
16913481Sgiacomo.travaglini@arm.com    // add self to global system list
17013481Sgiacomo.travaglini@arm.com    systemList.push_back(this);
17113481Sgiacomo.travaglini@arm.com
17213481Sgiacomo.travaglini@arm.com    numSystemsRunning++;
17313481Sgiacomo.travaglini@arm.com}
17413481Sgiacomo.travaglini@arm.com
17513481Sgiacomo.travaglini@arm.com
17613481Sgiacomo.travaglini@arm.comSystem::~System()
17713481Sgiacomo.travaglini@arm.com{
17813481Sgiacomo.travaglini@arm.com    delete kernelSymtab;
17913481Sgiacomo.travaglini@arm.com    delete consoleSymtab;
18013481Sgiacomo.travaglini@arm.com    delete initRegs;
18113481Sgiacomo.travaglini@arm.com}
18213481Sgiacomo.travaglini@arm.com
18313481Sgiacomo.travaglini@arm.com
18413481Sgiacomo.travaglini@arm.comvoid
18513481Sgiacomo.travaglini@arm.comSystem::initBootContext(ExecContext *xc)
18613481Sgiacomo.travaglini@arm.com{
18713481Sgiacomo.travaglini@arm.com    xc->regs = *initRegs;
18813481Sgiacomo.travaglini@arm.com
18913481Sgiacomo.travaglini@arm.com    remoteGDB = new RemoteGDB(this, xc);
19013481Sgiacomo.travaglini@arm.com    gdbListen = new GDBListener(remoteGDB, 7000);
19113481Sgiacomo.travaglini@arm.com    gdbListen->listen();
19213481Sgiacomo.travaglini@arm.com
19313481Sgiacomo.travaglini@arm.com    // Reset the system
19413481Sgiacomo.travaglini@arm.com    //
19513481Sgiacomo.travaglini@arm.com    TheISA::init(physmem, &xc->regs);
19613481Sgiacomo.travaglini@arm.com}
19713481Sgiacomo.travaglini@arm.com
19813481Sgiacomo.travaglini@arm.com
19913481Sgiacomo.travaglini@arm.comvoid
20013481Sgiacomo.travaglini@arm.comSystem::registerExecContext(ExecContext *xc)
20113481Sgiacomo.travaglini@arm.com{
20213481Sgiacomo.travaglini@arm.com    if (xc->cpu_id >= 12/*MAX_CPUS*/)
20313481Sgiacomo.travaglini@arm.com        panic("Too many CPU's\n");
20413481Sgiacomo.travaglini@arm.com
20513481Sgiacomo.travaglini@arm.com    if (xc->cpu_id >= xcvec.size())
20613481Sgiacomo.travaglini@arm.com        xcvec.resize(xc->cpu_id + 1);
20713481Sgiacomo.travaglini@arm.com
20813481Sgiacomo.travaglini@arm.com    xcvec[xc->cpu_id] = xc;
20913481Sgiacomo.travaglini@arm.com}
21013481Sgiacomo.travaglini@arm.com
21113481Sgiacomo.travaglini@arm.com
21213481Sgiacomo.travaglini@arm.comvoid
21313481Sgiacomo.travaglini@arm.comSystem::printSystems()
21413481Sgiacomo.travaglini@arm.com{
21513481Sgiacomo.travaglini@arm.com    vector<System *>::iterator i = systemList.begin();
21613481Sgiacomo.travaglini@arm.com    vector<System *>::iterator end = systemList.end();
21713481Sgiacomo.travaglini@arm.com    for (; i != end; ++i) {
21813481Sgiacomo.travaglini@arm.com        System *sys = *i;
21913481Sgiacomo.travaglini@arm.com        cerr << "System " << sys->name() << ": " << hex << sys << endl;
22013481Sgiacomo.travaglini@arm.com    }
22113481Sgiacomo.travaglini@arm.com}
22213481Sgiacomo.travaglini@arm.com
22313481Sgiacomo.travaglini@arm.com
22413481Sgiacomo.travaglini@arm.comextern "C"
22513481Sgiacomo.travaglini@arm.comvoid
22613481Sgiacomo.travaglini@arm.comprintSystems()
22713481Sgiacomo.travaglini@arm.com{
22813481Sgiacomo.travaglini@arm.com    System::printSystems();
22913481Sgiacomo.travaglini@arm.com}
23013481Sgiacomo.travaglini@arm.com
23113481Sgiacomo.travaglini@arm.com
23213481Sgiacomo.travaglini@arm.comBEGIN_DECLARE_SIM_OBJECT_PARAMS(System)
23313481Sgiacomo.travaglini@arm.com
23413481Sgiacomo.travaglini@arm.com    SimObjectParam<MemoryController *> mem_ctl;
23513481Sgiacomo.travaglini@arm.com    SimObjectParam<PhysicalMemory *> physmem;
23613481Sgiacomo.travaglini@arm.com
23713481Sgiacomo.travaglini@arm.com    Param<string> kernel_code;
23813481Sgiacomo.travaglini@arm.com    Param<string> console_code;
23913481Sgiacomo.travaglini@arm.com    Param<string> pal_code;
24013481Sgiacomo.travaglini@arm.com    Param<string> boot_osflags;
24113481Sgiacomo.travaglini@arm.com
24213481Sgiacomo.travaglini@arm.comEND_DECLARE_SIM_OBJECT_PARAMS(System)
24313481Sgiacomo.travaglini@arm.com
24413481Sgiacomo.travaglini@arm.comBEGIN_INIT_SIM_OBJECT_PARAMS(System)
24513481Sgiacomo.travaglini@arm.com
24613481Sgiacomo.travaglini@arm.com    INIT_PARAM(mem_ctl, "memory controller"),
24713481Sgiacomo.travaglini@arm.com    INIT_PARAM(physmem, "phsyical memory"),
24813481Sgiacomo.travaglini@arm.com    INIT_PARAM(kernel_code, "file that contains the kernel code"),
24913481Sgiacomo.travaglini@arm.com    INIT_PARAM(console_code, "file that contains the console code"),
25013481Sgiacomo.travaglini@arm.com    INIT_PARAM(pal_code, "file that contains palcode"),
25113481Sgiacomo.travaglini@arm.com    INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
25213481Sgiacomo.travaglini@arm.com                    "a")
25313481Sgiacomo.travaglini@arm.com
25413481Sgiacomo.travaglini@arm.comEND_INIT_SIM_OBJECT_PARAMS(System)
25513481Sgiacomo.travaglini@arm.com
25613481Sgiacomo.travaglini@arm.com
25713481Sgiacomo.travaglini@arm.comCREATE_SIM_OBJECT(System)
25813481Sgiacomo.travaglini@arm.com{
25913481Sgiacomo.travaglini@arm.com    System *sys = new System(getInstanceName(), mem_ctl, physmem,
26013481Sgiacomo.travaglini@arm.com                             kernel_code, console_code, pal_code,
26113481Sgiacomo.travaglini@arm.com                             boot_osflags);
26213481Sgiacomo.travaglini@arm.com
26313481Sgiacomo.travaglini@arm.com    return sys;
26413481Sgiacomo.travaglini@arm.com}
26513481Sgiacomo.travaglini@arm.com
26613481Sgiacomo.travaglini@arm.comREGISTER_SIM_OBJECT("System", System)
26713481Sgiacomo.travaglini@arm.com