system.cc revision 882
110923SN/A/*
210923SN/A * Copyright (c) 2003 The Regents of The University of Michigan
310923SN/A * All rights reserved.
410923SN/A *
510923SN/A * Redistribution and use in source and binary forms, with or without
610923SN/A * modification, are permitted provided that the following conditions are
710923SN/A * met: redistributions of source code must retain the above copyright
810923SN/A * notice, this list of conditions and the following disclaimer;
910923SN/A * redistributions in binary form must reproduce the above copyright
1010923SN/A * notice, this list of conditions and the following disclaimer in the
1110923SN/A * documentation and/or other materials provided with the distribution;
1210923SN/A * neither the name of the copyright holders nor the names of its
134486SN/A * contributors may be used to endorse or promote products derived from
144486SN/A * this software without specific prior written permission.
154486SN/A *
164486SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
174486SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
184486SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
194486SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
204486SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
214486SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
224486SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
234486SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
244486SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
254486SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
264486SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
274486SN/A */
284486SN/A
294486SN/A#include "base/loader/aout_object.hh"
304486SN/A#include "base/loader/elf_object.hh"
314486SN/A#include "base/loader/object_file.hh"
324486SN/A#include "base/loader/symtab.hh"
334486SN/A#include "base/remote_gdb.hh"
344486SN/A#include "base/trace.hh"
354486SN/A#include "cpu/exec_context.hh"
364486SN/A#include "cpu/base_cpu.hh"
374486SN/A#include "kern/linux/linux_events.hh"
384486SN/A#include "kern/linux/linux_system.hh"
394486SN/A#include "mem/functional_mem/memory_control.hh"
404486SN/A#include "mem/functional_mem/physical_memory.hh"
413102SN/A#include "sim/builder.hh"
423102SN/A#include "dev/platform.hh"
433102SN/A#include "targetarch/isa_traits.hh"
4411260SN/A#include "targetarch/vtophys.hh"
451310SN/A
464981SN/Aextern SymbolTable *debugSymbolTable;
474981SN/A
481310SN/Ausing namespace std;
4911263Sandreas.sandberg@arm.com
501310SN/ALinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
514981SN/A                         MemoryController *_memCtrl, PhysicalMemory *_physmem,
521366SN/A                         const string &kernel_path, const string &console_path,
5311263Sandreas.sandberg@arm.com                         const string &palcode, const string &boot_osflags,
548839SN/A                         const bool _bin, const vector<string> &_binned_fns)
558839SN/A     : System(_name, _init_param, _memCtrl, _physmem, _bin, _binned_fns),
561634SN/A       bin(_bin), binned_fns(_binned_fns)
571952SN/A{
581702SN/A    kernelSymtab = new SymbolTable;
591310SN/A    consoleSymtab = new SymbolTable;
601310SN/A
6111290Sgabor.dozsa@arm.com    // Load kernel code
6211290Sgabor.dozsa@arm.com    ObjectFile *kernel = createObjectFile(kernel_path);
6311290Sgabor.dozsa@arm.com    if (kernel == NULL)
6410923SN/A        fatal("Could not load kernel file %s", kernel_path);
6510923SN/A
6610923SN/A    // Load Console Code
6710923SN/A    ObjectFile *console = createObjectFile(console_path);
6810923SN/A    if (console == NULL)
6911290Sgabor.dozsa@arm.com        fatal("Could not load console file %s", console_path);
7011290Sgabor.dozsa@arm.com
7111290Sgabor.dozsa@arm.com    // Load pal file
7211290Sgabor.dozsa@arm.com    ObjectFile *pal = createObjectFile(palcode);
7310923SN/A    if (pal == NULL)
7410923SN/A        fatal("Could not load PALcode file %s", palcode);
7511290Sgabor.dozsa@arm.com    pal->loadSections(physmem, true);
7611703Smichael.lebeane@amd.com
7711290Sgabor.dozsa@arm.com    // Load console file
7810923SN/A    console->loadSections(physmem, true);
794981SN/A
801366SN/A    // Load kernel file
8111263Sandreas.sandberg@arm.com    kernel->loadSections(physmem, true);
821634SN/A    kernelStart = kernel->textBase();
831310SN/A    kernelEnd = kernel->bssBase() + kernel->bssSize();
841634SN/A    kernelEntry = kernel->entryPoint();
851310SN/A
8611317Sm.alian1369@gmail.com    // load symbols
8711317Sm.alian1369@gmail.com    if (!kernel->loadGlobalSymbols(kernelSymtab))
8811317Sm.alian1369@gmail.com        panic("could not load kernel symbols\n");
8911317Sm.alian1369@gmail.com        debugSymbolTable = kernelSymtab;
9011317Sm.alian1369@gmail.com
9111317Sm.alian1369@gmail.com    if (!kernel->loadLocalSymbols(kernelSymtab))
9211317Sm.alian1369@gmail.com        panic("could not load kernel local symbols\n");
9311317Sm.alian1369@gmail.com
9411317Sm.alian1369@gmail.com    if (!console->loadGlobalSymbols(consoleSymtab))
9511317Sm.alian1369@gmail.com        panic("could not load console symbols\n");
9611317Sm.alian1369@gmail.com
9711317Sm.alian1369@gmail.com    DPRINTF(Loader, "Kernel start = %#x\n"
9812055Sgabeblack@google.com            "Kernel end   = %#x\n"
9912055Sgabeblack@google.com            "Kernel entry = %#x\n",
10012055Sgabeblack@google.com            kernelStart, kernelEnd, kernelEntry);
10111263Sandreas.sandberg@arm.com
1021310SN/A    DPRINTF(Loader, "Kernel loaded...\n");
1031310SN/A
10412055Sgabeblack@google.com
10512055Sgabeblack@google.com#ifdef DEBUG
10612055Sgabeblack@google.com    kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic");
10712055Sgabeblack@google.com    consolePanicEvent = new BreakPCEvent(&pcEventQueue, "console panic");
10812055Sgabeblack@google.com#endif
10912054Sgabeblack@google.com
1101310SN/A    skipIdeDelay50msEvent = new LinuxSkipIdeDelay50msEvent(&pcEventQueue,
1111692SN/A                                                     "ide_delay_50ms");
1121366SN/A
11311263Sandreas.sandberg@arm.com    skipDelayLoopEvent = new LinuxSkipDelayLoopEvent(&pcEventQueue,
1141310SN/A                                                     "calibrate_delay");
1151880SN/A
1161310SN/A    skipCacheProbeEvent = new LinuxSkipFuncEvent(&pcEventQueue, "determine_cpu_caches");
1174981SN/A
1184981SN/A    Addr addr = 0;
1194981SN/A
12011263Sandreas.sandberg@arm.com    if (kernelSymtab->findAddress("est_cycle_freq", addr)) {
1218839SN/A        Addr paddr = vtophys(physmem, addr);
1224981SN/A        uint8_t *est_cycle_frequency =
1234981SN/A            physmem->dma_addr(paddr, sizeof(uint64_t));
1245763SN/A
1253116SN/A        if (est_cycle_frequency)
12611263Sandreas.sandberg@arm.com            *(uint64_t *)est_cycle_frequency = ticksPerSecond;
1274597SN/A    }
1284597SN/A
1294283SN/A
1304283SN/A    if (consoleSymtab->findAddress("env_booted_osflags", addr)) {
1314486SN/A        Addr paddr = vtophys(physmem, addr);
1324486SN/A        char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t));
1334486SN/A
1344486SN/A        if (osflags)
1353116SN/A              strcpy(osflags, boot_osflags.c_str());
1363116SN/A    }
1373116SN/A
1383116SN/A    {
1393116SN/A        Addr paddr = vtophys(physmem, PARAM_ADDR);
1403116SN/A        char *commandline = (char*)physmem->dma_addr(paddr, sizeof(uint64_t));
1413116SN/A        if (commandline)
1423116SN/A            strcpy(commandline, boot_osflags.c_str());
1433116SN/A    }
1443116SN/A
1453116SN/A
1463116SN/A    if (consoleSymtab->findAddress("xxm_rpb", addr)) {
1473116SN/A        Addr paddr = vtophys(physmem, addr);
1483116SN/A        char *hwprb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t));
1493116SN/A
1503116SN/A        if (hwprb) {
1513116SN/A            *(uint64_t*)(hwprb+0x50) = 34;      // Tsunami
1523116SN/A            *(uint64_t*)(hwprb+0x58) = (1<<10);
1535535SN/A        }
1545535SN/A        else
1555535SN/A            panic("could not translate hwprb addr to set system type/variation\n");
1565535SN/A
1575535SN/A    } else
1585535SN/A        panic("could not find hwprb to set system type/variation\n");
1595781SN/A
1605781SN/A#ifdef DEBUG
1613116SN/A    if (kernelSymtab->findAddress("panic", addr))
1625763SN/A        kernelPanicEvent->schedule(addr);
1635763SN/A    else
1645763SN/A        panic("could not find kernel symbol \'panic\'");
1655763SN/A
1665781SN/A    if (consoleSymtab->findAddress("panic", addr))
1675781SN/A        consolePanicEvent->schedule(addr);
1685763SN/A#endif
1695763SN/A
1705763SN/A    if (kernelSymtab->findAddress("ide_delay_50ms", addr))
1715763SN/A        skipIdeDelay50msEvent->schedule(addr+8);
1725763SN/A
1735781SN/A    if (kernelSymtab->findAddress("calibrate_delay", addr))
1745781SN/A        skipDelayLoopEvent->schedule(addr+8);
1755763SN/A
1764981SN/A    if (kernelSymtab->findAddress("determine_cpu_caches", addr))
1774597SN/A        skipCacheProbeEvent->schedule(addr+8);
1784597SN/A}
17911263Sandreas.sandberg@arm.com
1809339SN/ALinuxSystem::~LinuxSystem()
1811310SN/A{
1821310SN/A    delete kernel;
1831310SN/A    delete console;
1841634SN/A
1851634SN/A    delete kernelSymtab;
1861634SN/A    delete consoleSymtab;
1871634SN/A
1881647SN/A    delete kernelPanicEvent;
1891925SN/A    delete consolePanicEvent;
1901925SN/A    delete skipIdeDelay50msEvent;
1911925SN/A    delete skipDelayLoopEvent;
1921925SN/A    delete skipCacheProbeEvent;
1931310SN/A}
1941369SN/A
1952008SN/A
1962008SN/Avoid
1972008SN/ALinuxSystem::setDelayLoop(ExecContext *xc)
1982210SN/A{
1991310SN/A    Addr addr = 0;
2004982SN/A    if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
2014982SN/A        Addr paddr = vtophys(physmem, addr);
20211263Sandreas.sandberg@arm.com
2034982SN/A        uint8_t *loops_per_jiffy =
2044982SN/A            physmem->dma_addr(paddr, sizeof(uint32_t));
2054982SN/A
2064982SN/A        Tick cpuFreq = xc->cpu->getFreq();
2074982SN/A        Tick intrFreq = platform->interrupt_frequency;
2082916SN/A        *(uint32_t *)loops_per_jiffy =
2092916SN/A            (uint32_t)((cpuFreq / intrFreq) * 0.9988);
2102916SN/A    }
2112916SN/A}
2122916SN/A
2132916SN/Aint
2142916SN/ALinuxSystem::registerExecContext(ExecContext *xc)
2152916SN/A{
2162916SN/A    int xcIndex = System::registerExecContext(xc);
2172916SN/A
2182916SN/A    if (xcIndex == 0) {
2192916SN/A        // activate with zero delay so that we start ticking right
2202916SN/A        // away on cycle 0
2212916SN/A        xc->activate(0);
2222916SN/A    }
2232916SN/A
2242916SN/A    RemoteGDB *rgdb = new RemoteGDB(this, xc);
2252916SN/A    GDBListener *gdbl = new GDBListener(rgdb, 7000 + xcIndex);
2262916SN/A    gdbl->listen();
2271310SN/A//    gdbl->accept();
2281644SN/A
2294982SN/A    if (remoteGDB.size() <= xcIndex) {
2304982SN/A        remoteGDB.resize(xcIndex+1);
2315610SN/A    }
23211263Sandreas.sandberg@arm.com
2332916SN/A    remoteGDB[xcIndex] = rgdb;
2344982SN/A
2354982SN/A    return xcIndex;
2364982SN/A}
2374982SN/A
2384982SN/A
2394982SN/Avoid
2404982SN/ALinuxSystem::replaceExecContext(ExecContext *xc, int xcIndex)
2414982SN/A{
2425603SN/A    System::replaceExecContext(xcIndex, xc);
2435603SN/A    remoteGDB[xcIndex]->replaceExecContext(xc);
2445603SN/A}
2454982SN/A
2464982SN/Abool
2474982SN/ALinuxSystem::breakpoint()
2481310SN/A{
2492916SN/A    return remoteGDB[0]->trap(ALPHA_KENTRY_IF);
2502916SN/A}
2512916SN/A
2522916SN/ABEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
2532916SN/A
2542916SN/A    Param<bool> bin;
2552916SN/A    SimObjectParam<MemoryController *> mem_ctl;
2562916SN/A    SimObjectParam<PhysicalMemory *> physmem;
2572916SN/A    Param<uint64_t> init_param;
2582916SN/A
2592916SN/A    Param<string> kernel_code;
2602916SN/A    Param<string> console_code;
2612916SN/A    Param<string> pal_code;
2622916SN/A    Param<string> boot_osflags;
2632916SN/A    VectorParam<string> binned_fns;
2642916SN/A
2652916SN/AEND_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
2662916SN/A
2671310SN/ABEGIN_INIT_SIM_OBJECT_PARAMS(LinuxSystem)
268
269
270    INIT_PARAM_DFLT(bin, "is this system to be binned", false),
271    INIT_PARAM(mem_ctl, "memory controller"),
272    INIT_PARAM(physmem, "phsyical memory"),
273    INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
274    INIT_PARAM(kernel_code, "file that contains the code"),
275    INIT_PARAM(console_code, "file that contains the console code"),
276    INIT_PARAM(pal_code, "file that contains palcode"),
277    INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
278                                   "a"),
279    INIT_PARAM(binned_fns, "functions to be broken down and binned")
280
281
282END_INIT_SIM_OBJECT_PARAMS(LinuxSystem)
283
284CREATE_SIM_OBJECT(LinuxSystem)
285{
286    LinuxSystem *sys = new LinuxSystem(getInstanceName(), init_param, mem_ctl,
287                                       physmem, kernel_code, console_code,
288                                       pal_code, boot_osflags, bin, binned_fns);
289
290    return sys;
291}
292
293REGISTER_SIM_OBJECT("LinuxSystem", LinuxSystem)
294