system.cc revision 882
19401SAndreas.Sandberg@ARM.com/* 29401SAndreas.Sandberg@ARM.com * Copyright (c) 2003 The Regents of The University of Michigan 39401SAndreas.Sandberg@ARM.com * All rights reserved. 49401SAndreas.Sandberg@ARM.com * 59401SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without 69401SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are 79401SAndreas.Sandberg@ARM.com * met: redistributions of source code must retain the above copyright 89401SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer; 99401SAndreas.Sandberg@ARM.com * redistributions in binary form must reproduce the above copyright 109401SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer in the 119401SAndreas.Sandberg@ARM.com * documentation and/or other materials provided with the distribution; 129401SAndreas.Sandberg@ARM.com * neither the name of the copyright holders nor the names of its 134977Ssaidi@eecs.umich.edu * contributors may be used to endorse or promote products derived from 142997Sstever@eecs.umich.edu * this software without specific prior written permission. 152997Sstever@eecs.umich.edu * 162997Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172997Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182997Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192997Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202997Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212997Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222997Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232997Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242997Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252997Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262997Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272997Sstever@eecs.umich.edu */ 282997Sstever@eecs.umich.edu 292997Sstever@eecs.umich.edu#include "base/loader/aout_object.hh" 302997Sstever@eecs.umich.edu#include "base/loader/elf_object.hh" 312997Sstever@eecs.umich.edu#include "base/loader/object_file.hh" 322997Sstever@eecs.umich.edu#include "base/loader/symtab.hh" 332997Sstever@eecs.umich.edu#include "base/remote_gdb.hh" 342997Sstever@eecs.umich.edu#include "base/trace.hh" 352997Sstever@eecs.umich.edu#include "cpu/exec_context.hh" 362997Sstever@eecs.umich.edu#include "cpu/base_cpu.hh" 372997Sstever@eecs.umich.edu#include "kern/linux/linux_events.hh" 382997Sstever@eecs.umich.edu#include "kern/linux/linux_system.hh" 392997Sstever@eecs.umich.edu#include "mem/functional_mem/memory_control.hh" 402997Sstever@eecs.umich.edu#include "mem/functional_mem/physical_memory.hh" 415523Snate@binkert.org#include "sim/builder.hh" 425523Snate@binkert.org#include "dev/platform.hh" 436928SBrad.Beckmann@amd.com#include "targetarch/isa_traits.hh" 446928SBrad.Beckmann@amd.com#include "targetarch/vtophys.hh" 456289Snate@binkert.org 466289Snate@binkert.orgextern SymbolTable *debugSymbolTable; 479654SAndreas.Sandberg@ARM.com 489654SAndreas.Sandberg@ARM.comusing namespace std; 496289Snate@binkert.org 505523Snate@binkert.orgLinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param, 515523Snate@binkert.org MemoryController *_memCtrl, PhysicalMemory *_physmem, 529401SAndreas.Sandberg@ARM.com const string &kernel_path, const string &console_path, 539401SAndreas.Sandberg@ARM.com const string &palcode, const string &boot_osflags, 549401SAndreas.Sandberg@ARM.com const bool _bin, const vector<string> &_binned_fns) 559401SAndreas.Sandberg@ARM.com : System(_name, _init_param, _memCtrl, _physmem, _bin, _binned_fns), 569401SAndreas.Sandberg@ARM.com bin(_bin), binned_fns(_binned_fns) 579401SAndreas.Sandberg@ARM.com{ 589401SAndreas.Sandberg@ARM.com kernelSymtab = new SymbolTable; 599401SAndreas.Sandberg@ARM.com consoleSymtab = new SymbolTable; 609401SAndreas.Sandberg@ARM.com 619401SAndreas.Sandberg@ARM.com // Load kernel code 629401SAndreas.Sandberg@ARM.com ObjectFile *kernel = createObjectFile(kernel_path); 639401SAndreas.Sandberg@ARM.com if (kernel == NULL) 649401SAndreas.Sandberg@ARM.com fatal("Could not load kernel file %s", kernel_path); 659401SAndreas.Sandberg@ARM.com 669401SAndreas.Sandberg@ARM.com // Load Console Code 679401SAndreas.Sandberg@ARM.com ObjectFile *console = createObjectFile(console_path); 689401SAndreas.Sandberg@ARM.com if (console == NULL) 699401SAndreas.Sandberg@ARM.com fatal("Could not load console file %s", console_path); 709401SAndreas.Sandberg@ARM.com 719401SAndreas.Sandberg@ARM.com // Load pal file 729401SAndreas.Sandberg@ARM.com ObjectFile *pal = createObjectFile(palcode); 739401SAndreas.Sandberg@ARM.com if (pal == NULL) 749401SAndreas.Sandberg@ARM.com fatal("Could not load PALcode file %s", palcode); 759401SAndreas.Sandberg@ARM.com pal->loadSections(physmem, true); 769401SAndreas.Sandberg@ARM.com 779401SAndreas.Sandberg@ARM.com // Load console file 789401SAndreas.Sandberg@ARM.com console->loadSections(physmem, true); 799401SAndreas.Sandberg@ARM.com 809401SAndreas.Sandberg@ARM.com // Load kernel file 819401SAndreas.Sandberg@ARM.com kernel->loadSections(physmem, true); 829401SAndreas.Sandberg@ARM.com kernelStart = kernel->textBase(); 839401SAndreas.Sandberg@ARM.com kernelEnd = kernel->bssBase() + kernel->bssSize(); 849401SAndreas.Sandberg@ARM.com kernelEntry = kernel->entryPoint(); 859401SAndreas.Sandberg@ARM.com 869401SAndreas.Sandberg@ARM.com // load symbols 879401SAndreas.Sandberg@ARM.com if (!kernel->loadGlobalSymbols(kernelSymtab)) 889401SAndreas.Sandberg@ARM.com panic("could not load kernel symbols\n"); 899401SAndreas.Sandberg@ARM.com debugSymbolTable = kernelSymtab; 909401SAndreas.Sandberg@ARM.com 919401SAndreas.Sandberg@ARM.com if (!kernel->loadLocalSymbols(kernelSymtab)) 929401SAndreas.Sandberg@ARM.com panic("could not load kernel local symbols\n"); 939401SAndreas.Sandberg@ARM.com 949401SAndreas.Sandberg@ARM.com if (!console->loadGlobalSymbols(consoleSymtab)) 959401SAndreas.Sandberg@ARM.com panic("could not load console symbols\n"); 969401SAndreas.Sandberg@ARM.com 979401SAndreas.Sandberg@ARM.com DPRINTF(Loader, "Kernel start = %#x\n" 989654SAndreas.Sandberg@ARM.com "Kernel end = %#x\n" 999654SAndreas.Sandberg@ARM.com "Kernel entry = %#x\n", 1009654SAndreas.Sandberg@ARM.com kernelStart, kernelEnd, kernelEntry); 1019654SAndreas.Sandberg@ARM.com 1029654SAndreas.Sandberg@ARM.com DPRINTF(Loader, "Kernel loaded...\n"); 1039654SAndreas.Sandberg@ARM.com 1049654SAndreas.Sandberg@ARM.com 1059654SAndreas.Sandberg@ARM.com#ifdef DEBUG 1069654SAndreas.Sandberg@ARM.com kernelPanicEvent = new BreakPCEvent(&pcEventQueue, "kernel panic"); 1079654SAndreas.Sandberg@ARM.com consolePanicEvent = new BreakPCEvent(&pcEventQueue, "console panic"); 1089654SAndreas.Sandberg@ARM.com#endif 1099654SAndreas.Sandberg@ARM.com 1109654SAndreas.Sandberg@ARM.com skipIdeDelay50msEvent = new LinuxSkipIdeDelay50msEvent(&pcEventQueue, 1119654SAndreas.Sandberg@ARM.com "ide_delay_50ms"); 1129654SAndreas.Sandberg@ARM.com 1139654SAndreas.Sandberg@ARM.com skipDelayLoopEvent = new LinuxSkipDelayLoopEvent(&pcEventQueue, 1149654SAndreas.Sandberg@ARM.com "calibrate_delay"); 1159654SAndreas.Sandberg@ARM.com 1169654SAndreas.Sandberg@ARM.com skipCacheProbeEvent = new LinuxSkipFuncEvent(&pcEventQueue, "determine_cpu_caches"); 1179654SAndreas.Sandberg@ARM.com 1189654SAndreas.Sandberg@ARM.com Addr addr = 0; 1199654SAndreas.Sandberg@ARM.com 1209654SAndreas.Sandberg@ARM.com if (kernelSymtab->findAddress("est_cycle_freq", addr)) { 1219654SAndreas.Sandberg@ARM.com Addr paddr = vtophys(physmem, addr); 1229654SAndreas.Sandberg@ARM.com uint8_t *est_cycle_frequency = 1239654SAndreas.Sandberg@ARM.com physmem->dma_addr(paddr, sizeof(uint64_t)); 1249654SAndreas.Sandberg@ARM.com 1259654SAndreas.Sandberg@ARM.com if (est_cycle_frequency) 1269654SAndreas.Sandberg@ARM.com *(uint64_t *)est_cycle_frequency = ticksPerSecond; 1279654SAndreas.Sandberg@ARM.com } 1289654SAndreas.Sandberg@ARM.com 1299654SAndreas.Sandberg@ARM.com 1309654SAndreas.Sandberg@ARM.com if (consoleSymtab->findAddress("env_booted_osflags", addr)) { 1319654SAndreas.Sandberg@ARM.com Addr paddr = vtophys(physmem, addr); 1329654SAndreas.Sandberg@ARM.com char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t)); 1339654SAndreas.Sandberg@ARM.com 1349654SAndreas.Sandberg@ARM.com if (osflags) 1359654SAndreas.Sandberg@ARM.com strcpy(osflags, boot_osflags.c_str()); 1369654SAndreas.Sandberg@ARM.com } 1379654SAndreas.Sandberg@ARM.com 1389447SAndreas.Sandberg@ARM.com { 1399447SAndreas.Sandberg@ARM.com Addr paddr = vtophys(physmem, PARAM_ADDR); 1409447SAndreas.Sandberg@ARM.com char *commandline = (char*)physmem->dma_addr(paddr, sizeof(uint64_t)); 1419447SAndreas.Sandberg@ARM.com if (commandline) 1429447SAndreas.Sandberg@ARM.com strcpy(commandline, boot_osflags.c_str()); 1439447SAndreas.Sandberg@ARM.com } 1449447SAndreas.Sandberg@ARM.com 1459447SAndreas.Sandberg@ARM.com 1469447SAndreas.Sandberg@ARM.com if (consoleSymtab->findAddress("xxm_rpb", addr)) { 1479447SAndreas.Sandberg@ARM.com Addr paddr = vtophys(physmem, addr); 1485523Snate@binkert.org char *hwprb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t)); 1495523Snate@binkert.org 1502997Sstever@eecs.umich.edu if (hwprb) { 1512997Sstever@eecs.umich.edu *(uint64_t*)(hwprb+0x50) = 34; // Tsunami 1528802Sgblack@eecs.umich.edu *(uint64_t*)(hwprb+0x58) = (1<<10); 1532997Sstever@eecs.umich.edu } 1542997Sstever@eecs.umich.edu else 1552997Sstever@eecs.umich.edu panic("could not translate hwprb addr to set system type/variation\n"); 1566874SSteve.Reinhardt@amd.com 1576874SSteve.Reinhardt@amd.com } else 1586289Snate@binkert.org panic("could not find hwprb to set system type/variation\n"); 1592998Sstever@eecs.umich.edu 1602998Sstever@eecs.umich.edu#ifdef DEBUG 1612998Sstever@eecs.umich.edu if (kernelSymtab->findAddress("panic", addr)) 1622998Sstever@eecs.umich.edu kernelPanicEvent->schedule(addr); 1632998Sstever@eecs.umich.edu else 1642998Sstever@eecs.umich.edu panic("could not find kernel symbol \'panic\'"); 1656289Snate@binkert.org 1662997Sstever@eecs.umich.edu if (consoleSymtab->findAddress("panic", addr)) 1673475Sktlim@umich.edu consolePanicEvent->schedule(addr); 1683475Sktlim@umich.edu#endif 1693475Sktlim@umich.edu 1703475Sktlim@umich.edu if (kernelSymtab->findAddress("ide_delay_50ms", addr)) 1713475Sktlim@umich.edu skipIdeDelay50msEvent->schedule(addr+8); 1726289Snate@binkert.org 1733475Sktlim@umich.edu if (kernelSymtab->findAddress("calibrate_delay", addr)) 1742997Sstever@eecs.umich.edu skipDelayLoopEvent->schedule(addr+8); 1756289Snate@binkert.org 1766928SBrad.Beckmann@amd.com if (kernelSymtab->findAddress("determine_cpu_caches", addr)) 1776928SBrad.Beckmann@amd.com skipCacheProbeEvent->schedule(addr+8); 1786928SBrad.Beckmann@amd.com} 1796928SBrad.Beckmann@amd.com 1806928SBrad.Beckmann@amd.comLinuxSystem::~LinuxSystem() 1812997Sstever@eecs.umich.edu{ 1822997Sstever@eecs.umich.edu delete kernel; 1832998Sstever@eecs.umich.edu delete console; 1845523Snate@binkert.org 1852997Sstever@eecs.umich.edu delete kernelSymtab; 1862997Sstever@eecs.umich.edu delete consoleSymtab; 1878802Sgblack@eecs.umich.edu 1888802Sgblack@eecs.umich.edu delete kernelPanicEvent; 1892997Sstever@eecs.umich.edu delete consolePanicEvent; 1909384SAndreas.Sandberg@arm.com delete skipIdeDelay50msEvent; 1919384SAndreas.Sandberg@arm.com delete skipDelayLoopEvent; 1929384SAndreas.Sandberg@arm.com delete skipCacheProbeEvent; 1939384SAndreas.Sandberg@arm.com} 1949384SAndreas.Sandberg@arm.com 1959851Sandreas.hansson@arm.com 1969384SAndreas.Sandberg@arm.comvoid 1979851Sandreas.hansson@arm.comLinuxSystem::setDelayLoop(ExecContext *xc) 1989851Sandreas.hansson@arm.com{ 1999384SAndreas.Sandberg@arm.com Addr addr = 0; 2009384SAndreas.Sandberg@arm.com if (kernelSymtab->findAddress("loops_per_jiffy", addr)) { 2019384SAndreas.Sandberg@arm.com Addr paddr = vtophys(physmem, addr); 2029384SAndreas.Sandberg@arm.com 2039384SAndreas.Sandberg@arm.com uint8_t *loops_per_jiffy = 2049384SAndreas.Sandberg@arm.com physmem->dma_addr(paddr, sizeof(uint32_t)); 2059384SAndreas.Sandberg@arm.com 2069384SAndreas.Sandberg@arm.com Tick cpuFreq = xc->cpu->getFreq(); 2079384SAndreas.Sandberg@arm.com Tick intrFreq = platform->interrupt_frequency; 2089384SAndreas.Sandberg@arm.com *(uint32_t *)loops_per_jiffy = 2099384SAndreas.Sandberg@arm.com (uint32_t)((cpuFreq / intrFreq) * 0.9988); 2109384SAndreas.Sandberg@arm.com } 2119384SAndreas.Sandberg@arm.com} 2129384SAndreas.Sandberg@arm.com 2139384SAndreas.Sandberg@arm.comint 2149384SAndreas.Sandberg@arm.comLinuxSystem::registerExecContext(ExecContext *xc) 2159384SAndreas.Sandberg@arm.com{ 2169384SAndreas.Sandberg@arm.com int xcIndex = System::registerExecContext(xc); 2179447SAndreas.Sandberg@ARM.com 218 if (xcIndex == 0) { 219 // activate with zero delay so that we start ticking right 220 // away on cycle 0 221 xc->activate(0); 222 } 223 224 RemoteGDB *rgdb = new RemoteGDB(this, xc); 225 GDBListener *gdbl = new GDBListener(rgdb, 7000 + xcIndex); 226 gdbl->listen(); 227// gdbl->accept(); 228 229 if (remoteGDB.size() <= xcIndex) { 230 remoteGDB.resize(xcIndex+1); 231 } 232 233 remoteGDB[xcIndex] = rgdb; 234 235 return xcIndex; 236} 237 238 239void 240LinuxSystem::replaceExecContext(ExecContext *xc, int xcIndex) 241{ 242 System::replaceExecContext(xcIndex, xc); 243 remoteGDB[xcIndex]->replaceExecContext(xc); 244} 245 246bool 247LinuxSystem::breakpoint() 248{ 249 return remoteGDB[0]->trap(ALPHA_KENTRY_IF); 250} 251 252BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem) 253 254 Param<bool> bin; 255 SimObjectParam<MemoryController *> mem_ctl; 256 SimObjectParam<PhysicalMemory *> physmem; 257 Param<uint64_t> init_param; 258 259 Param<string> kernel_code; 260 Param<string> console_code; 261 Param<string> pal_code; 262 Param<string> boot_osflags; 263 VectorParam<string> binned_fns; 264 265END_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem) 266 267BEGIN_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