system.cc revision 882
12207SN/A/* 22207SN/A * Copyright (c) 2003 The Regents of The University of Michigan 32207SN/A * All rights reserved. 42207SN/A * 52207SN/A * Redistribution and use in source and binary forms, with or without 62207SN/A * modification, are permitted provided that the following conditions are 72207SN/A * met: redistributions of source code must retain the above copyright 82207SN/A * notice, this list of conditions and the following disclaimer; 92207SN/A * redistributions in binary form must reproduce the above copyright 102207SN/A * notice, this list of conditions and the following disclaimer in the 112207SN/A * documentation and/or other materials provided with the distribution; 122207SN/A * neither the name of the copyright holders nor the names of its 132207SN/A * contributors may be used to endorse or promote products derived from 142207SN/A * this software without specific prior written permission. 152207SN/A * 162207SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172207SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182207SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192207SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202207SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212207SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222207SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232207SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242207SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252207SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262207SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 292665Ssaidi@eecs.umich.edu#include "base/loader/aout_object.hh" 302207SN/A#include "base/loader/elf_object.hh" 312207SN/A#include "base/loader/object_file.hh" 323589Sgblack@eecs.umich.edu#include "base/loader/symtab.hh" 334111Sgblack@eecs.umich.edu#include "base/remote_gdb.hh" 342474SN/A#include "base/trace.hh" 352207SN/A#include "cpu/exec_context.hh" 363760Sgblack@eecs.umich.edu#include "cpu/base_cpu.hh" 372454SN/A#include "kern/linux/linux_events.hh" 382976Sgblack@eecs.umich.edu#include "kern/linux/linux_system.hh" 392454SN/A#include "mem/functional_mem/memory_control.hh" 402680Sktlim@umich.edu#include "mem/functional_mem/physical_memory.hh" 412561SN/A#include "sim/builder.hh" 424434Ssaidi@eecs.umich.edu#include "dev/platform.hh" 432561SN/A#include "targetarch/isa_traits.hh" 442474SN/A#include "targetarch/vtophys.hh" 452207SN/A 462458SN/Aextern SymbolTable *debugSymbolTable; 472474SN/A 482458SN/Ausing namespace std; 492207SN/A 505154Sgblack@eecs.umich.eduLinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param, 515154Sgblack@eecs.umich.edu MemoryController *_memCtrl, PhysicalMemory *_physmem, 525154Sgblack@eecs.umich.edu const string &kernel_path, const string &console_path, 532474SN/A const string &palcode, const string &boot_osflags, 542474SN/A const bool _bin, const vector<string> &_binned_fns) 552474SN/A : System(_name, _init_param, _memCtrl, _physmem, _bin, _binned_fns), 562474SN/A bin(_bin), binned_fns(_binned_fns) 572474SN/A{ 582474SN/A kernelSymtab = new SymbolTable; 592474SN/A consoleSymtab = new SymbolTable; 602474SN/A 613415Sgblack@eecs.umich.edu // Load kernel code 623415Sgblack@eecs.umich.edu ObjectFile *kernel = createObjectFile(kernel_path); 633415Sgblack@eecs.umich.edu if (kernel == NULL) 643415Sgblack@eecs.umich.edu fatal("Could not load kernel file %s", kernel_path); 652474SN/A 662474SN/A // Load Console Code 674111Sgblack@eecs.umich.edu ObjectFile *console = createObjectFile(console_path); 684111Sgblack@eecs.umich.edu if (console == NULL) 694111Sgblack@eecs.umich.edu fatal("Could not load console file %s", console_path); 704111Sgblack@eecs.umich.edu 715128Sgblack@eecs.umich.edu // Load pal file 725128Sgblack@eecs.umich.edu ObjectFile *pal = createObjectFile(palcode); 735128Sgblack@eecs.umich.edu if (pal == NULL) 745128Sgblack@eecs.umich.edu fatal("Could not load PALcode file %s", palcode); 755128Sgblack@eecs.umich.edu pal->loadSections(physmem, true); 765128Sgblack@eecs.umich.edu 775128Sgblack@eecs.umich.edu // Load console file 784111Sgblack@eecs.umich.edu console->loadSections(physmem, true); 795128Sgblack@eecs.umich.edu 805128Sgblack@eecs.umich.edu // Load kernel file 815128Sgblack@eecs.umich.edu kernel->loadSections(physmem, true); 825128Sgblack@eecs.umich.edu kernelStart = kernel->textBase(); 835128Sgblack@eecs.umich.edu kernelEnd = kernel->bssBase() + kernel->bssSize(); 845128Sgblack@eecs.umich.edu kernelEntry = kernel->entryPoint(); 855128Sgblack@eecs.umich.edu 865128Sgblack@eecs.umich.edu // load symbols 875128Sgblack@eecs.umich.edu if (!kernel->loadGlobalSymbols(kernelSymtab)) 885128Sgblack@eecs.umich.edu panic("could not load kernel symbols\n"); 895128Sgblack@eecs.umich.edu debugSymbolTable = kernelSymtab; 905128Sgblack@eecs.umich.edu 915128Sgblack@eecs.umich.edu if (!kernel->loadLocalSymbols(kernelSymtab)) 925128Sgblack@eecs.umich.edu panic("could not load kernel local symbols\n"); 935128Sgblack@eecs.umich.edu 945128Sgblack@eecs.umich.edu if (!console->loadGlobalSymbols(consoleSymtab)) 955128Sgblack@eecs.umich.edu panic("could not load console symbols\n"); 965128Sgblack@eecs.umich.edu 975128Sgblack@eecs.umich.edu DPRINTF(Loader, "Kernel start = %#x\n" 985128Sgblack@eecs.umich.edu "Kernel end = %#x\n" 995128Sgblack@eecs.umich.edu "Kernel entry = %#x\n", 1005128Sgblack@eecs.umich.edu kernelStart, kernelEnd, kernelEntry); 1015128Sgblack@eecs.umich.edu 1025128Sgblack@eecs.umich.edu DPRINTF(Loader, "Kernel loaded...\n"); 1035128Sgblack@eecs.umich.edu 1044111Sgblack@eecs.umich.edu 1054111Sgblack@eecs.umich.edu#ifdef DEBUG 1064111Sgblack@eecs.umich.edu kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic"); 1074111Sgblack@eecs.umich.edu consolePanicEvent = new BreakPCEvent(&pcEventQueue, "console panic"); 1084111Sgblack@eecs.umich.edu#endif 1094111Sgblack@eecs.umich.edu 1102474SN/A skipIdeDelay50msEvent = new LinuxSkipIdeDelay50msEvent(&pcEventQueue, 1114111Sgblack@eecs.umich.edu "ide_delay_50ms"); 1124111Sgblack@eecs.umich.edu 1134111Sgblack@eecs.umich.edu skipDelayLoopEvent = new LinuxSkipDelayLoopEvent(&pcEventQueue, 1144111Sgblack@eecs.umich.edu "calibrate_delay"); 1154111Sgblack@eecs.umich.edu 1164111Sgblack@eecs.umich.edu skipCacheProbeEvent = new LinuxSkipFuncEvent(&pcEventQueue, "determine_cpu_caches"); 1174648Sgblack@eecs.umich.edu 1184648Sgblack@eecs.umich.edu Addr addr = 0; 1194111Sgblack@eecs.umich.edu 1204111Sgblack@eecs.umich.edu if (kernelSymtab->findAddress("est_cycle_freq", addr)) { 1214172Ssaidi@eecs.umich.edu Addr paddr = vtophys(physmem, addr); 1224111Sgblack@eecs.umich.edu uint8_t *est_cycle_frequency = 1234172Ssaidi@eecs.umich.edu physmem->dma_addr(paddr, sizeof(uint64_t)); 1244111Sgblack@eecs.umich.edu 1254111Sgblack@eecs.umich.edu if (est_cycle_frequency) 1264111Sgblack@eecs.umich.edu *(uint64_t *)est_cycle_frequency = ticksPerSecond; 1274111Sgblack@eecs.umich.edu } 1284111Sgblack@eecs.umich.edu 1294111Sgblack@eecs.umich.edu 1304172Ssaidi@eecs.umich.edu if (consoleSymtab->findAddress("env_booted_osflags", addr)) { 1314111Sgblack@eecs.umich.edu Addr paddr = vtophys(physmem, addr); 1324111Sgblack@eecs.umich.edu char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t)); 1334172Ssaidi@eecs.umich.edu 1344111Sgblack@eecs.umich.edu if (osflags) 1354111Sgblack@eecs.umich.edu strcpy(osflags, boot_osflags.c_str()); 1364172Ssaidi@eecs.umich.edu } 1374111Sgblack@eecs.umich.edu 1384111Sgblack@eecs.umich.edu { 1394172Ssaidi@eecs.umich.edu Addr paddr = vtophys(physmem, PARAM_ADDR); 1404111Sgblack@eecs.umich.edu char *commandline = (char*)physmem->dma_addr(paddr, sizeof(uint64_t)); 1414111Sgblack@eecs.umich.edu if (commandline) 1424172Ssaidi@eecs.umich.edu strcpy(commandline, boot_osflags.c_str()); 1434111Sgblack@eecs.umich.edu } 1444172Ssaidi@eecs.umich.edu 1454111Sgblack@eecs.umich.edu 1464111Sgblack@eecs.umich.edu if (consoleSymtab->findAddress("xxm_rpb", addr)) { 1474172Ssaidi@eecs.umich.edu Addr paddr = vtophys(physmem, addr); 1484111Sgblack@eecs.umich.edu char *hwprb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t)); 1494172Ssaidi@eecs.umich.edu 1504997Sgblack@eecs.umich.edu if (hwprb) { 1514997Sgblack@eecs.umich.edu *(uint64_t*)(hwprb+0x50) = 34; // Tsunami 1524997Sgblack@eecs.umich.edu *(uint64_t*)(hwprb+0x58) = (1<<10); 1534997Sgblack@eecs.umich.edu } 1544997Sgblack@eecs.umich.edu else 1554997Sgblack@eecs.umich.edu panic("could not translate hwprb addr to set system type/variation\n"); 1564111Sgblack@eecs.umich.edu 1574111Sgblack@eecs.umich.edu } else 1584111Sgblack@eecs.umich.edu panic("could not find hwprb to set system type/variation\n"); 1594111Sgblack@eecs.umich.edu 1602474SN/A#ifdef DEBUG 1613760Sgblack@eecs.umich.edu if (kernelSymtab->findAddress("panic", addr)) 1622561SN/A kernelPanicEvent->schedule(addr); 1632561SN/A else 1642561SN/A panic("could not find kernel symbol \'panic\'"); 1652561SN/A 1664172Ssaidi@eecs.umich.edu if (consoleSymtab->findAddress("panic", addr)) 1672561SN/A consolePanicEvent->schedule(addr); 1682646Ssaidi@eecs.umich.edu#endif 1694172Ssaidi@eecs.umich.edu 1702646Ssaidi@eecs.umich.edu if (kernelSymtab->findAddress("ide_delay_50ms", addr)) 1714172Ssaidi@eecs.umich.edu skipIdeDelay50msEvent->schedule(addr+8); 1724997Sgblack@eecs.umich.edu 1732561SN/A if (kernelSymtab->findAddress("calibrate_delay", addr)) 1742561SN/A skipDelayLoopEvent->schedule(addr+8); 1752561SN/A 1762561SN/A if (kernelSymtab->findAddress("determine_cpu_caches", addr)) 1772561SN/A skipCacheProbeEvent->schedule(addr+8); 1784172Ssaidi@eecs.umich.edu} 1793761Sgblack@eecs.umich.edu 1802561SN/ALinuxSystem::~LinuxSystem() 1814172Ssaidi@eecs.umich.edu{ 1823761Sgblack@eecs.umich.edu delete kernel; 1832561SN/A delete console; 1844172Ssaidi@eecs.umich.edu 1853761Sgblack@eecs.umich.edu delete kernelSymtab; 1862561SN/A delete consoleSymtab; 1874172Ssaidi@eecs.umich.edu 1883761Sgblack@eecs.umich.edu delete kernelPanicEvent; 1892561SN/A delete consolePanicEvent; 1904172Ssaidi@eecs.umich.edu delete skipIdeDelay50msEvent; 1913415Sgblack@eecs.umich.edu delete skipDelayLoopEvent; 1924172Ssaidi@eecs.umich.edu delete skipCacheProbeEvent; 1933761Sgblack@eecs.umich.edu} 1943415Sgblack@eecs.umich.edu 1954172Ssaidi@eecs.umich.edu 1963589Sgblack@eecs.umich.eduvoid 1974172Ssaidi@eecs.umich.eduLinuxSystem::setDelayLoop(ExecContext *xc) 1984997Sgblack@eecs.umich.edu{ 1994997Sgblack@eecs.umich.edu Addr addr = 0; 2004997Sgblack@eecs.umich.edu if (kernelSymtab->findAddress("loops_per_jiffy", addr)) { 2014997Sgblack@eecs.umich.edu Addr paddr = vtophys(physmem, addr); 2024997Sgblack@eecs.umich.edu 2034997Sgblack@eecs.umich.edu uint8_t *loops_per_jiffy = 2042474SN/A physmem->dma_addr(paddr, sizeof(uint32_t)); 2052474SN/A 2064111Sgblack@eecs.umich.edu Tick cpuFreq = xc->cpu->getFreq(); 2072585SN/A Tick intrFreq = platform->interrupt_frequency; 2084111Sgblack@eecs.umich.edu *(uint32_t *)loops_per_jiffy = 2094111Sgblack@eecs.umich.edu (uint32_t)((cpuFreq / intrFreq) * 0.9988); 2102585SN/A } 2112585SN/A} 2124111Sgblack@eecs.umich.edu 2133415Sgblack@eecs.umich.eduint 2144111Sgblack@eecs.umich.eduLinuxSystem::registerExecContext(ExecContext *xc) 2154111Sgblack@eecs.umich.edu{ 2164111Sgblack@eecs.umich.edu int xcIndex = System::registerExecContext(xc); 2173415Sgblack@eecs.umich.edu 2182561SN/A if (xcIndex == 0) { 2194111Sgblack@eecs.umich.edu // activate with zero delay so that we start ticking right 2202561SN/A // away on cycle 0 2214111Sgblack@eecs.umich.edu xc->activate(0); 2222561SN/A } 2232474SN/A 2243044Sgblack@eecs.umich.edu RemoteGDB *rgdb = new RemoteGDB(this, xc); 2253044Sgblack@eecs.umich.edu GDBListener *gdbl = new GDBListener(rgdb, 7000 + xcIndex); 2263044Sgblack@eecs.umich.edu gdbl->listen(); 2273044Sgblack@eecs.umich.edu// gdbl->accept(); 2283044Sgblack@eecs.umich.edu 2293044Sgblack@eecs.umich.edu if (remoteGDB.size() <= xcIndex) { 2302561SN/A remoteGDB.resize(xcIndex+1); 2312561SN/A } 2322561SN/A 2332561SN/A remoteGDB[xcIndex] = rgdb; 2342561SN/A 2352585SN/A return xcIndex; 2362585SN/A} 2372585SN/A 2382585SN/A 2392585SN/Avoid 2402585SN/ALinuxSystem::replaceExecContext(ExecContext *xc, int xcIndex) 2412585SN/A{ 2422585SN/A System::replaceExecContext(xcIndex, xc); 2432585SN/A remoteGDB[xcIndex]->replaceExecContext(xc); 2442585SN/A} 2452585SN/A 2462585SN/Abool 2472585SN/ALinuxSystem::breakpoint() 2482585SN/A{ 2492585SN/A return remoteGDB[0]->trap(ALPHA_KENTRY_IF); 2502585SN/A} 2512585SN/A 2522585SN/ABEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem) 2532585SN/A 2542585SN/A Param<bool> bin; 2552585SN/A SimObjectParam<MemoryController *> mem_ctl; 2562976Sgblack@eecs.umich.edu SimObjectParam<PhysicalMemory *> physmem; 2572976Sgblack@eecs.umich.edu Param<uint64_t> init_param; 2582976Sgblack@eecs.umich.edu 2592976Sgblack@eecs.umich.edu Param<string> kernel_code; 2602976Sgblack@eecs.umich.edu Param<string> console_code; 2612976Sgblack@eecs.umich.edu Param<string> pal_code; 2622976Sgblack@eecs.umich.edu Param<string> boot_osflags; 2634793Sgblack@eecs.umich.edu VectorParam<string> binned_fns; 2642976Sgblack@eecs.umich.edu 2654793Sgblack@eecs.umich.eduEND_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem) 2662976Sgblack@eecs.umich.edu 2672976Sgblack@eecs.umich.eduBEGIN_INIT_SIM_OBJECT_PARAMS(LinuxSystem) 2684793Sgblack@eecs.umich.edu 2692976Sgblack@eecs.umich.edu 2702976Sgblack@eecs.umich.edu INIT_PARAM_DFLT(bin, "is this system to be binned", false), 2714793Sgblack@eecs.umich.edu INIT_PARAM(mem_ctl, "memory controller"), 2722976Sgblack@eecs.umich.edu INIT_PARAM(physmem, "phsyical memory"), 2734793Sgblack@eecs.umich.edu INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), 2742976Sgblack@eecs.umich.edu INIT_PARAM(kernel_code, "file that contains the code"), 2754793Sgblack@eecs.umich.edu INIT_PARAM(console_code, "file that contains the console code"), 2762976Sgblack@eecs.umich.edu INIT_PARAM(pal_code, "file that contains palcode"), 2772976Sgblack@eecs.umich.edu INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", 2782976Sgblack@eecs.umich.edu "a"), 2794793Sgblack@eecs.umich.edu INIT_PARAM(binned_fns, "functions to be broken down and binned") 2802976Sgblack@eecs.umich.edu 2814793Sgblack@eecs.umich.edu 2822976Sgblack@eecs.umich.eduEND_INIT_SIM_OBJECT_PARAMS(LinuxSystem) 2834793Sgblack@eecs.umich.edu 2842976Sgblack@eecs.umich.eduCREATE_SIM_OBJECT(LinuxSystem) 2854793Sgblack@eecs.umich.edu{ 2864793Sgblack@eecs.umich.edu LinuxSystem *sys = new LinuxSystem(getInstanceName(), init_param, mem_ctl, 2874793Sgblack@eecs.umich.edu physmem, kernel_code, console_code, 2884793Sgblack@eecs.umich.edu pal_code, boot_osflags, bin, binned_fns); 2892976Sgblack@eecs.umich.edu 2904793Sgblack@eecs.umich.edu return sys; 2912976Sgblack@eecs.umich.edu} 2922585SN/A 2932561SN/AREGISTER_SIM_OBJECT("LinuxSystem", LinuxSystem) 2942561SN/A