system.cc revision 5222
1/* 2 * Copyright .AN) 2007 MIPS Technologies, Inc. All Rights Reserved 3 * 4 * This software is part of the M5 simulator. 5 * 6 * THIS IS A LEGAL AGREEMENT. BY DOWNLOADING, USING, COPYING, CREATING 7 * DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING 8 * TO THESE TERMS AND CONDITIONS. 9 * 10 * Permission is granted to use, copy, create derivative works and 11 * distribute this software and such derivative works for any purpose, 12 * so long as (1) the copyright notice above, this grant of permission, 13 * and the disclaimer below appear in all copies and derivative works 14 * made, (2) the copyright notice above is augmented as appropriate to 15 * reflect the addition of any new copyrightable work in a derivative 16 * work (e.g., Copyright .AN) <Publication Year> Copyright Owner), and (3) 17 * the name of MIPS Technologies, Inc. ($B!H(BMIPS$B!I(B) is not used in any 18 * advertising or publicity pertaining to the use or distribution of 19 * this software without specific, written prior authorization. 20 * 21 * THIS SOFTWARE IS PROVIDED $B!H(BAS IS.$B!I(B MIPS MAKES NO WARRANTIES AND 22 * DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR 23 * OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND 25 * NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE. 26 * IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, 27 * INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF 28 * ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT, 29 * THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY 30 * IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR 31 * STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE 32 * POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE. 33 * 34 * 35 * Authors: Ali G. Saidi 36 * Lisa R. Hsu 37 * Nathan L. Binkert 38 * Steven K. Reinhardt 39 */ 40 41/** 42 * @file 43 * This code loads the linux kernel, console, pal and patches certain 44 * functions. The symbol tables are loaded so that traces can show 45 * the executing function and we can skip functions. Various delay 46 * loops are skipped and their final values manually computed to speed 47 * up boot time. 48 */ 49 50#include "arch/vtophys.hh" 51#include "arch/mips/idle_event.hh" 52#include "arch/mips/linux/system.hh" 53#include "arch/mips/linux/threadinfo.hh" 54#include "arch/mips/system.hh" 55#include "base/loader/symtab.hh" 56#include "cpu/thread_context.hh" 57#include "cpu/base.hh" 58#include "dev/platform.hh" 59#include "kern/linux/printk.hh" 60#include "kern/linux/events.hh" 61#include "mem/physical.hh" 62#include "mem/port.hh" 63#include "sim/arguments.hh" 64#include "sim/byteswap.hh" 65 66using namespace std; 67using namespace MipsISA; 68using namespace Linux; 69 70LinuxMipsSystem::LinuxMipsSystem(Params *p) 71 : MipsSystem(p) 72{ 73 Addr addr = 0; 74 75 /** 76 * The symbol swapper_pg_dir marks the beginning of the kernel and 77 * the location of bootloader passed arguments 78 */ 79 if (!kernelSymtab->findAddress("swapper_pg_dir", KernelStart)) { 80 panic("Could not determine start location of kernel"); 81 } 82 83 /** 84 * Since we aren't using a bootloader, we have to copy the 85 * kernel arguments directly into the kernel's memory. 86 */ 87 virtPort.writeBlob(CommandLine(), (uint8_t*)params()->boot_osflags.c_str(), 88 params()->boot_osflags.length()+1); 89 90 /** 91 * find the address of the est_cycle_freq variable and insert it 92 * so we don't through the lengthly process of trying to 93 * calculated it by using the PIT, RTC, etc. 94 */ 95 if (kernelSymtab->findAddress("est_cycle_freq", addr)) 96 virtPort.write(addr, (uint64_t)(Clock::Frequency / 97 p->boot_cpu_frequency)); 98 99 100 /** 101 * EV5 only supports 127 ASNs so we are going to tell the kernel that the 102 * paritiuclar EV6 we have only supports 127 asns. 103 * @todo At some point we should change ev5.hh and the palcode to support 104 * 255 ASNs. 105 */ 106 if (kernelSymtab->findAddress("dp264_mv", addr)) 107 virtPort.write(addr + 0x18, LittleEndianGuest::htog((uint32_t)127)); 108 else 109 panic("could not find dp264_mv\n"); 110 111#ifndef NDEBUG 112 kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic"); 113 if (!kernelPanicEvent) 114 panic("could not find kernel symbol \'panic\'"); 115 116#if 0 117 kernelDieEvent = addKernelFuncEvent<BreakPCEvent>("die_if_kernel"); 118 if (!kernelDieEvent) 119 panic("could not find kernel symbol \'die_if_kernel\'"); 120#endif 121 122#endif 123 124 /** 125 * Any time ide_delay_50ms, calibarte_delay or 126 * determine_cpu_caches is called just skip the 127 * function. Currently determine_cpu_caches only is used put 128 * information in proc, however if that changes in the future we 129 * will have to fill in the cache size variables appropriately. 130 */ 131 132 skipIdeDelay50msEvent = 133 addKernelFuncEvent<SkipFuncEvent>("ide_delay_50ms"); 134 skipDelayLoopEvent = 135 addKernelFuncEvent<SkipDelayLoopEvent>("calibrate_delay"); 136 skipCacheProbeEvent = 137 addKernelFuncEvent<SkipFuncEvent>("determine_cpu_caches"); 138 debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk"); 139 idleStartEvent = addKernelFuncEvent<IdleStartEvent>("cpu_idle"); 140 141 // Disable for now as it runs into panic() calls in VPTr methods 142 // (see sim/vptr.hh). Once those bugs are fixed, we can 143 // re-enable, but we should find a better way to turn it on than 144 // using DTRACE(Thread), since looking at a trace flag at tick 0 145 // leads to non-intuitive behavior with --trace-start. 146 if (false && kernelSymtab->findAddress("mips_switch_to", addr)) { 147 printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo", 148 addr + sizeof(MachInst) * 6); 149 } else { 150 printThreadEvent = NULL; 151 } 152} 153 154LinuxMipsSystem::~LinuxMipsSystem() 155{ 156#ifndef NDEBUG 157 delete kernelPanicEvent; 158#endif 159 delete skipIdeDelay50msEvent; 160 delete skipDelayLoopEvent; 161 delete skipCacheProbeEvent; 162 delete debugPrintkEvent; 163 delete idleStartEvent; 164 delete printThreadEvent; 165} 166 167 168void 169LinuxMipsSystem::setDelayLoop(ThreadContext *tc) 170{ 171 Addr addr = 0; 172 if (kernelSymtab->findAddress("loops_per_jiffy", addr)) { 173 Tick cpuFreq = tc->getCpuPtr()->frequency(); 174 Tick intrFreq = platform->intrFrequency(); 175 VirtualPort *vp; 176 177 vp = tc->getVirtPort(); 178 vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988)); 179 tc->delVirtPort(vp); 180 } 181} 182 183 184void 185LinuxMipsSystem::SkipDelayLoopEvent::process(ThreadContext *tc) 186{ 187 SkipFuncEvent::process(tc); 188 // calculate and set loops_per_jiffy 189 ((LinuxMipsSystem *)tc->getSystemPtr())->setDelayLoop(tc); 190} 191 192void 193LinuxMipsSystem::PrintThreadInfo::process(ThreadContext *tc) 194{ 195 Linux::ThreadInfo ti(tc); 196 197 DPRINTF(Thread, "Currently Executing Thread %s, pid %d, started at: %d\n", 198 ti.curTaskName(), ti.curTaskPID(), ti.curTaskStart()); 199} 200 201LinuxMipsSystem * 202LinuxMipsSystemParams::create() 203{ 204 return new LinuxMipsSystem(this); 205} 206