system.cc revision 869
1451SN/A/* 21762SN/A * Copyright (c) 2003 The Regents of The University of Michigan 3451SN/A * All rights reserved. 4451SN/A * 5451SN/A * Redistribution and use in source and binary forms, with or without 6451SN/A * modification, are permitted provided that the following conditions are 7451SN/A * met: redistributions of source code must retain the above copyright 8451SN/A * notice, this list of conditions and the following disclaimer; 9451SN/A * redistributions in binary form must reproduce the above copyright 10451SN/A * notice, this list of conditions and the following disclaimer in the 11451SN/A * documentation and/or other materials provided with the distribution; 12451SN/A * neither the name of the copyright holders nor the names of its 13451SN/A * contributors may be used to endorse or promote products derived from 14451SN/A * this software without specific prior written permission. 15451SN/A * 16451SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17451SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18451SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19451SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20451SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21451SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22451SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23451SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24451SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25451SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26451SN/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" 302665Ssaidi@eecs.umich.edu#include "base/loader/elf_object.hh" 312665Ssaidi@eecs.umich.edu#include "base/loader/object_file.hh" 32451SN/A#include "base/loader/symtab.hh" 33451SN/A#include "base/remote_gdb.hh" 34885SN/A#include "base/trace.hh" 35885SN/A#include "cpu/exec_context.hh" 361040SN/A#include "cpu/base_cpu.hh" 371040SN/A#include "kern/linux/linux_events.hh" 381040SN/A#include "kern/linux/linux_system.hh" 391040SN/A#include "mem/functional_mem/memory_control.hh" 401040SN/A#include "mem/functional_mem/physical_memory.hh" 41885SN/A#include "sim/builder.hh" 42885SN/A#include "dev/platform.hh" 432212SN/A#include "targetarch/isa_traits.hh" 442212SN/A#include "targetarch/vtophys.hh" 453565Sgblack@eecs.umich.edu 462212SN/Aextern SymbolTable *debugSymbolTable; 472212SN/A 482158SN/Ausing namespace std; 491180SN/A 502680Sktlim@umich.eduLinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param, 511717SN/A MemoryController *_memCtrl, PhysicalMemory *_physmem, 522212SN/A const string &kernel_path, const string &console_path, 531885SN/A const string &palcode, const string &boot_osflags, 542212SN/A const string &bootloader_path, const bool _bin, 552521SN/A const vector<string> &_binned_fns) 562521SN/A : System(_name, _init_param, _memCtrl, _physmem, _bin, _binned_fns), 572036SN/A bin(_bin), binned_fns(_binned_fns) 58451SN/A{ 59451SN/A kernelSymtab = new SymbolTable; 602212SN/A consoleSymtab = new SymbolTable; 612212SN/A bootloaderSymtab = new SymbolTable; 62451SN/A 632212SN/A ObjectFile *kernel = createObjectFile(kernel_path); 642158SN/A if (kernel == NULL) 65451SN/A fatal("Could not load kernel file %s", kernel_path); 66451SN/A 671855SN/A ObjectFile *console = createObjectFile(console_path); 681855SN/A if (console == NULL) 691855SN/A fatal("Could not load console file %s", console_path); 701855SN/A 711855SN/A ObjectFile *bootloader = createObjectFile(bootloader_path); 721855SN/A if (bootloader == NULL) 731855SN/A fatal("Could not load bootloader file %s", bootloader_path); 741855SN/A 751855SN/A if (!kernel->loadGlobalSymbols(kernelSymtab)) 761855SN/A panic("could not load kernel symbols\n"); 771855SN/A debugSymbolTable = kernelSymtab; 781855SN/A 791855SN/A if (!kernel->loadLocalSymbols(kernelSymtab)) 802521SN/A panic("could not load kernel local symbols\n"); 812548SN/A 82836SN/A if (!console->loadGlobalSymbols(consoleSymtab)) 83885SN/A panic("could not load console symbols\n"); 841070SN/A 851070SN/A if (!bootloader->loadGlobalSymbols(bootloaderSymtab)) 861070SN/A panic("could not load bootloader symbols\n"); 87885SN/A 882521SN/A // Load pal file 892521SN/A ObjectFile *pal = createObjectFile(palcode); 902521SN/A if (pal == NULL) 91451SN/A fatal("Could not load PALcode file %s", palcode); 92836SN/A pal->loadSections(physmem, true); 93885SN/A 94943SN/A // Load console file 95943SN/A console->loadSections(physmem, true); 96943SN/A 97943SN/A // Load kernel file 98943SN/A kernel->loadSections(physmem, true); 992521SN/A kernelStart = kernel->textBase(); 1002521SN/A kernelEnd = kernel->bssBase() + kernel->bssSize(); 1012521SN/A /* FIXME: entrypoint not in kernel, but in bootloader, 1021070SN/A variable should be re-named appropriately */ 103943SN/A kernelEntry = kernel->entryPoint(); 1041492SN/A 1051885SN/A 1061885SN/A DPRINTF(Loader, "Kernel start = %#x\n" 107451SN/A "Kernel end = %#x\n" 1081885SN/A "Kernel entry = %#x\n", 1091646SN/A kernelStart, kernelEnd, kernelEntry); 1101885SN/A 1111885SN/A DPRINTF(Loader, "Kernel loaded...\n"); 1121492SN/A 1131646SN/A // Load bootloader file 1141492SN/A bootloader->loadSections(physmem, true); 115860SN/A kernelEntry = bootloader->entryPoint(); 116451SN/A kernelStart = bootloader->textBase(); 117885SN/A DPRINTF(Loader, "Bootloader entry at %#x\n", kernelEntry); 1181895SN/A 1191070SN/A#ifdef DEBUG 1201070SN/A kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic"); 1211070SN/A consolePanicEvent = new BreakPCEvent(&pcEventQueue, "console panic"); 1221070SN/A#endif 123885SN/A 124848SN/A skipIdeDelay50msEvent = new LinuxSkipIdeDelay50msEvent(&pcEventQueue, 1251885SN/A "ide_delay_50ms"); 1261885SN/A 1271885SN/A skipDelayLoopEvent = new LinuxSkipDelayLoopEvent(&pcEventQueue, 1281885SN/A "calibrate_delay"); 1291885SN/A 1301885SN/A skipCacheProbeEvent = new LinuxSkipFuncEvent(&pcEventQueue, "determine_cpu_caches"); 1311885SN/A 1321885SN/A Addr addr = 0; 1331885SN/A 1344741Sstever@eecs.umich.edu if (kernelSymtab->findAddress("est_cycle_freq", addr)) { 1354741Sstever@eecs.umich.edu Addr paddr = vtophys(physmem, addr); 1364741Sstever@eecs.umich.edu uint8_t *est_cycle_frequency = 1374741Sstever@eecs.umich.edu physmem->dma_addr(paddr, sizeof(uint64_t)); 1384741Sstever@eecs.umich.edu 1394741Sstever@eecs.umich.edu if (est_cycle_frequency) 1401885SN/A *(uint64_t *)est_cycle_frequency = ticksPerSecond; 1411885SN/A } 1421885SN/A 1431885SN/A if (kernelSymtab->findAddress("aic7xxx_no_reset", addr)) { 1441657SN/A Addr paddr = vtophys(physmem, addr); 145451SN/A uint8_t *aic7xxx_no_reset = 146451SN/A physmem->dma_addr(paddr, sizeof(uint32_t)); 1472212SN/A 148451SN/A if (aic7xxx_no_reset) { 1491492SN/A *(uint32_t *)aic7xxx_no_reset = 1; 150451SN/A } 1511070SN/A } 152869SN/A 153869SN/A if (consoleSymtab->findAddress("env_booted_osflags", addr)) { 154869SN/A Addr paddr = vtophys(physmem, addr); 1551070SN/A char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t)); 1561070SN/A 1571082SN/A if (osflags) 158451SN/A strcpy(osflags, boot_osflags.c_str()); 159451SN/A } 160882SN/A 161803SN/A if (consoleSymtab->findAddress("xxm_rpb", addr)) { 1622680Sktlim@umich.edu Addr paddr = vtophys(physmem, addr); 163803SN/A char *hwprb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t)); 164803SN/A 165803SN/A if (hwprb) { 1662680Sktlim@umich.edu *(uint64_t*)(hwprb+0x50) = 34; // Tsunami 1671634SN/A *(uint64_t*)(hwprb+0x58) = (1<<10); 1682684Ssaidi@eecs.umich.edu } 1692684Ssaidi@eecs.umich.edu else 1702684Ssaidi@eecs.umich.edu panic("could not translate hwprb addr to set system type/variation\n"); 1712684Ssaidi@eecs.umich.edu 1722684Ssaidi@eecs.umich.edu } else 173803SN/A panic("could not find hwprb to set system type/variation\n"); 174803SN/A 175803SN/A#ifdef DEBUG 1762212SN/A if (kernelSymtab->findAddress("panic", addr)) 1771885SN/A kernelPanicEvent->schedule(addr); 1782680Sktlim@umich.edu else 1791885SN/A panic("could not find kernel symbol \'panic\'"); 1802680Sktlim@umich.edu 1811885SN/A if (consoleSymtab->findAddress("panic", addr)) 1822680Sktlim@umich.edu consolePanicEvent->schedule(addr); 1831885SN/A#endif 1841885SN/A 1851885SN/A if (kernelSymtab->findAddress("ide_delay_50ms", addr)) 1862680Sktlim@umich.edu skipIdeDelay50msEvent->schedule(addr+8); 1871885SN/A 1882680Sktlim@umich.edu if (kernelSymtab->findAddress("calibrate_delay", addr)) 1891885SN/A skipDelayLoopEvent->schedule(addr+8); 1901885SN/A 1911885SN/A if (kernelSymtab->findAddress("determine_cpu_caches", addr)) 1921885SN/A skipCacheProbeEvent->schedule(addr+8); 1931885SN/A} 1944762Snate@binkert.org 1954762Snate@binkert.orgLinuxSystem::~LinuxSystem() 196451SN/A{ 1974762Snate@binkert.org delete kernel; 198451SN/A delete console; 199 200 delete kernelSymtab; 201 delete consoleSymtab; 202 delete bootloaderSymtab; 203 204 delete kernelPanicEvent; 205 delete consolePanicEvent; 206 delete skipIdeDelay50msEvent; 207 delete skipDelayLoopEvent; 208 delete skipCacheProbeEvent; 209} 210 211void 212LinuxSystem::setDelayLoop(ExecContext *xc) 213{ 214 Addr addr = 0; 215 if (kernelSymtab->findAddress("loops_per_jiffy", addr)) { 216 Addr paddr = vtophys(physmem, addr); 217 218 uint8_t *loops_per_jiffy = 219 physmem->dma_addr(paddr, sizeof(uint32_t)); 220 221 Tick cpuFreq = xc->cpu->getFreq(); 222 Tick intrFreq = platform->interrupt_frequency; 223 *(uint32_t *)loops_per_jiffy = 224 (uint32_t)((cpuFreq / intrFreq) * 0.9988); 225 } 226} 227 228int 229LinuxSystem::registerExecContext(ExecContext *xc) 230{ 231 int xcIndex = System::registerExecContext(xc); 232 233 if (xcIndex == 0) { 234 // activate with zero delay so that we start ticking right 235 // away on cycle 0 236 xc->activate(0); 237 } 238 239 RemoteGDB *rgdb = new RemoteGDB(this, xc); 240 GDBListener *gdbl = new GDBListener(rgdb, 7000 + xcIndex); 241 gdbl->listen(); 242// gdbl->accept(); 243 244 if (remoteGDB.size() <= xcIndex) { 245 remoteGDB.resize(xcIndex+1); 246 } 247 248 remoteGDB[xcIndex] = rgdb; 249 250 return xcIndex; 251} 252 253 254void 255LinuxSystem::replaceExecContext(ExecContext *xc, int xcIndex) 256{ 257 System::replaceExecContext(xcIndex, xc); 258 remoteGDB[xcIndex]->replaceExecContext(xc); 259} 260 261bool 262LinuxSystem::breakpoint() 263{ 264 return remoteGDB[0]->trap(ALPHA_KENTRY_IF); 265} 266 267BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem) 268 269 Param<bool> bin; 270 SimObjectParam<MemoryController *> mem_ctl; 271 SimObjectParam<PhysicalMemory *> physmem; 272 Param<uint64_t> init_param; 273 274 Param<string> kernel_code; 275 Param<string> console_code; 276 Param<string> pal_code; 277 Param<string> boot_osflags; 278 Param<string> bootloader_code; 279 VectorParam<string> binned_fns; 280 281END_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem) 282 283BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxSystem) 284 285 286 INIT_PARAM_DFLT(bin, "is this system to be binned", false), 287 INIT_PARAM(mem_ctl, "memory controller"), 288 INIT_PARAM(physmem, "phsyical memory"), 289 INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), 290 INIT_PARAM(kernel_code, "file that contains the code"), 291 INIT_PARAM(console_code, "file that contains the console code"), 292 INIT_PARAM(pal_code, "file that contains palcode"), 293 INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", 294 "a"), 295 INIT_PARAM(bootloader_code, "file that contains the bootloader"), 296 INIT_PARAM(binned_fns, "functions to be broken down and binned") 297 298 299END_INIT_SIM_OBJECT_PARAMS(LinuxSystem) 300 301CREATE_SIM_OBJECT(LinuxSystem) 302{ 303 LinuxSystem *sys = new LinuxSystem(getInstanceName(), init_param, mem_ctl, 304 physmem, kernel_code, console_code, 305 pal_code, boot_osflags, bootloader_code, 306 bin, binned_fns); 307 308 return sys; 309} 310 311REGISTER_SIM_OBJECT("LinuxSystem", LinuxSystem) 312