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