system.cc revision 8229:78bf55f23338
112853Sgabeblack@google.com/* 212853Sgabeblack@google.com * Copyright (c) 2004-2005 The Regents of The University of Michigan 312853Sgabeblack@google.com * All rights reserved. 412853Sgabeblack@google.com * 512853Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 612853Sgabeblack@google.com * modification, are permitted provided that the following conditions are 712853Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 812853Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 912853Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1012853Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1112853Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1212853Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1312853Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1412853Sgabeblack@google.com * this software without specific prior written permission. 1512853Sgabeblack@google.com * 1612853Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712853Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812853Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912853Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012853Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112853Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212853Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312853Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412853Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512853Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612853Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712853Sgabeblack@google.com * 2812853Sgabeblack@google.com * Authors: Ali Saidi 2912853Sgabeblack@google.com * Lisa Hsu 3012853Sgabeblack@google.com * Nathan Binkert 3112853Sgabeblack@google.com * Steve Reinhardt 3212853Sgabeblack@google.com */ 3312853Sgabeblack@google.com 3412853Sgabeblack@google.com/** 3512853Sgabeblack@google.com * @file 3612853Sgabeblack@google.com * This code loads the linux kernel, console, pal and patches certain 3712853Sgabeblack@google.com * functions. The symbol tables are loaded so that traces can show 3812853Sgabeblack@google.com * the executing function and we can skip functions. Various delay 3912853Sgabeblack@google.com * loops are skipped and their final values manually computed to speed 4012853Sgabeblack@google.com * up boot time. 4112853Sgabeblack@google.com */ 4212853Sgabeblack@google.com 4312853Sgabeblack@google.com#include "arch/alpha/linux/system.hh" 4412853Sgabeblack@google.com#include "arch/alpha/linux/threadinfo.hh" 4512853Sgabeblack@google.com#include "arch/alpha/idle_event.hh" 4612853Sgabeblack@google.com#include "arch/alpha/system.hh" 4712853Sgabeblack@google.com#include "arch/vtophys.hh" 4812853Sgabeblack@google.com#include "base/loader/symtab.hh" 4912853Sgabeblack@google.com#include "cpu/base.hh" 5012853Sgabeblack@google.com#include "cpu/thread_context.hh" 5112853Sgabeblack@google.com#include "dev/platform.hh" 5212853Sgabeblack@google.com#include "kern/linux/events.hh" 5312853Sgabeblack@google.com#include "kern/linux/printk.hh" 5412853Sgabeblack@google.com#include "mem/physical.hh" 5512853Sgabeblack@google.com#include "mem/port.hh" 5612853Sgabeblack@google.com#include "sim/arguments.hh" 5712853Sgabeblack@google.com#include "sim/byteswap.hh" 5812853Sgabeblack@google.com 5912853Sgabeblack@google.comusing namespace std; 6012853Sgabeblack@google.comusing namespace AlphaISA; 6112853Sgabeblack@google.comusing namespace Linux; 6212853Sgabeblack@google.com 6312853Sgabeblack@google.comLinuxAlphaSystem::LinuxAlphaSystem(Params *p) 6412853Sgabeblack@google.com : AlphaSystem(p) 6512853Sgabeblack@google.com{ 6612853Sgabeblack@google.com Addr addr = 0; 6712853Sgabeblack@google.com 6812853Sgabeblack@google.com /** 6912853Sgabeblack@google.com * The symbol swapper_pg_dir marks the beginning of the kernel and 7012853Sgabeblack@google.com * the location of bootloader passed arguments 7112853Sgabeblack@google.com */ 7212853Sgabeblack@google.com if (!kernelSymtab->findAddress("swapper_pg_dir", KernelStart)) { 7312853Sgabeblack@google.com panic("Could not determine start location of kernel"); 7412853Sgabeblack@google.com } 7512853Sgabeblack@google.com 7612853Sgabeblack@google.com /** 7712853Sgabeblack@google.com * Since we aren't using a bootloader, we have to copy the 7812853Sgabeblack@google.com * kernel arguments directly into the kernel's memory. 7912853Sgabeblack@google.com */ 8012853Sgabeblack@google.com virtPort->writeBlob(CommandLine(), (uint8_t*)params()->boot_osflags.c_str(), 8112853Sgabeblack@google.com params()->boot_osflags.length()+1); 8212853Sgabeblack@google.com 8312853Sgabeblack@google.com /** 8412853Sgabeblack@google.com * find the address of the est_cycle_freq variable and insert it 8512853Sgabeblack@google.com * so we don't through the lengthly process of trying to 8612853Sgabeblack@google.com * calculated it by using the PIT, RTC, etc. 8712853Sgabeblack@google.com */ 8812853Sgabeblack@google.com if (kernelSymtab->findAddress("est_cycle_freq", addr)) 8912853Sgabeblack@google.com virtPort->write(addr, (uint64_t)(SimClock::Frequency / 9012853Sgabeblack@google.com p->boot_cpu_frequency)); 9112853Sgabeblack@google.com 9212853Sgabeblack@google.com 9312853Sgabeblack@google.com /** 9412853Sgabeblack@google.com * EV5 only supports 127 ASNs so we are going to tell the kernel that the 9512853Sgabeblack@google.com * paritiuclar EV6 we have only supports 127 asns. 9612853Sgabeblack@google.com * @todo At some point we should change ev5.hh and the palcode to support 9712853Sgabeblack@google.com * 255 ASNs. 9812853Sgabeblack@google.com */ 9912853Sgabeblack@google.com if (kernelSymtab->findAddress("dp264_mv", addr)) 10012853Sgabeblack@google.com virtPort->write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127)); 10112853Sgabeblack@google.com else 10212853Sgabeblack@google.com panic("could not find dp264_mv\n"); 10312853Sgabeblack@google.com 10412853Sgabeblack@google.com#ifndef NDEBUG 10512853Sgabeblack@google.com kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic"); 10612853Sgabeblack@google.com if (!kernelPanicEvent) 10712853Sgabeblack@google.com panic("could not find kernel symbol \'panic\'"); 10812853Sgabeblack@google.com 10912853Sgabeblack@google.com#if 0 11012853Sgabeblack@google.com kernelDieEvent = addKernelFuncEvent<BreakPCEvent>("die_if_kernel"); 11112853Sgabeblack@google.com if (!kernelDieEvent) 11212853Sgabeblack@google.com panic("could not find kernel symbol \'die_if_kernel\'"); 11312853Sgabeblack@google.com#endif 11412853Sgabeblack@google.com 11512853Sgabeblack@google.com#endif 11612853Sgabeblack@google.com 11712853Sgabeblack@google.com /** 11812853Sgabeblack@google.com * Any time ide_delay_50ms, calibarte_delay or 11912853Sgabeblack@google.com * determine_cpu_caches is called just skip the 12012853Sgabeblack@google.com * function. Currently determine_cpu_caches only is used put 12112853Sgabeblack@google.com * information in proc, however if that changes in the future we 12212853Sgabeblack@google.com * will have to fill in the cache size variables appropriately. 12312853Sgabeblack@google.com */ 12412853Sgabeblack@google.com 12512853Sgabeblack@google.com skipIdeDelay50msEvent = 12612853Sgabeblack@google.com addKernelFuncEvent<SkipFuncEvent>("ide_delay_50ms"); 12712853Sgabeblack@google.com skipDelayLoopEvent = 12812853Sgabeblack@google.com addKernelFuncEvent<SkipDelayLoopEvent>("calibrate_delay"); 12912853Sgabeblack@google.com skipCacheProbeEvent = 13012853Sgabeblack@google.com addKernelFuncEvent<SkipFuncEvent>("determine_cpu_caches"); 13112853Sgabeblack@google.com debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk"); 13212853Sgabeblack@google.com idleStartEvent = addKernelFuncEvent<IdleStartEvent>("cpu_idle"); 13312853Sgabeblack@google.com 13412853Sgabeblack@google.com // Disable for now as it runs into panic() calls in VPTr methods 13512853Sgabeblack@google.com // (see sim/vptr.hh). Once those bugs are fixed, we can 13612853Sgabeblack@google.com // re-enable, but we should find a better way to turn it on than 13712853Sgabeblack@google.com // using DTRACE(Thread), since looking at a trace flag at tick 0 13812853Sgabeblack@google.com // leads to non-intuitive behavior with --trace-start. 13912853Sgabeblack@google.com if (false && kernelSymtab->findAddress("alpha_switch_to", addr)) { 14012853Sgabeblack@google.com printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo", 14112853Sgabeblack@google.com addr + sizeof(MachInst) * 6); 14212853Sgabeblack@google.com } else { 14312853Sgabeblack@google.com printThreadEvent = NULL; 14412853Sgabeblack@google.com } 14512853Sgabeblack@google.com} 14612853Sgabeblack@google.com 14712853Sgabeblack@google.comLinuxAlphaSystem::~LinuxAlphaSystem() 14812853Sgabeblack@google.com{ 14912853Sgabeblack@google.com#ifndef NDEBUG 15012853Sgabeblack@google.com delete kernelPanicEvent; 15112853Sgabeblack@google.com#endif 15212853Sgabeblack@google.com delete skipIdeDelay50msEvent; 15312853Sgabeblack@google.com delete skipDelayLoopEvent; 15412853Sgabeblack@google.com delete skipCacheProbeEvent; 15512853Sgabeblack@google.com delete debugPrintkEvent; 15612853Sgabeblack@google.com delete idleStartEvent; 15712853Sgabeblack@google.com delete printThreadEvent; 15812853Sgabeblack@google.com} 15912853Sgabeblack@google.com 16012853Sgabeblack@google.comvoid 16112853Sgabeblack@google.comLinuxAlphaSystem::setDelayLoop(ThreadContext *tc) 16212853Sgabeblack@google.com{ 16312853Sgabeblack@google.com Addr addr = 0; 16412853Sgabeblack@google.com if (kernelSymtab->findAddress("loops_per_jiffy", addr)) { 16512853Sgabeblack@google.com Tick cpuFreq = tc->getCpuPtr()->frequency(); 16612853Sgabeblack@google.com Tick intrFreq = platform->intrFrequency(); 16712853Sgabeblack@google.com VirtualPort *vp; 16812853Sgabeblack@google.com 16912853Sgabeblack@google.com vp = tc->getVirtPort(); 17012853Sgabeblack@google.com vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988)); 17112853Sgabeblack@google.com } 17212853Sgabeblack@google.com} 17312853Sgabeblack@google.com 17412853Sgabeblack@google.comvoid 17512853Sgabeblack@google.comLinuxAlphaSystem::SkipDelayLoopEvent::process(ThreadContext *tc) 17612853Sgabeblack@google.com{ 17712853Sgabeblack@google.com SkipFuncEvent::process(tc); 17812853Sgabeblack@google.com // calculate and set loops_per_jiffy 17912853Sgabeblack@google.com ((LinuxAlphaSystem *)tc->getSystemPtr())->setDelayLoop(tc); 18012853Sgabeblack@google.com} 18112853Sgabeblack@google.com 18212853Sgabeblack@google.comvoid 18312853Sgabeblack@google.comLinuxAlphaSystem::PrintThreadInfo::process(ThreadContext *tc) 18412853Sgabeblack@google.com{ 18512853Sgabeblack@google.com Linux::ThreadInfo ti(tc); 18612853Sgabeblack@google.com 18712853Sgabeblack@google.com DPRINTF(Thread, "Currently Executing Thread %s, pid %d, started at: %d\n", 18812853Sgabeblack@google.com ti.curTaskName(), ti.curTaskPID(), ti.curTaskStart()); 18912853Sgabeblack@google.com} 19012853Sgabeblack@google.com 19112853Sgabeblack@google.comLinuxAlphaSystem * 19212853Sgabeblack@google.comLinuxAlphaSystemParams::create() 19312853Sgabeblack@google.com{ 19412853Sgabeblack@google.com return new LinuxAlphaSystem(this); 19512853Sgabeblack@google.com} 19612853Sgabeblack@google.com