system.cc revision 2521
15647Sgblack@eecs.umich.edu/* 25647Sgblack@eecs.umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan 35647Sgblack@eecs.umich.edu * All rights reserved. 45647Sgblack@eecs.umich.edu * 57087Snate@binkert.org * Redistribution and use in source and binary forms, with or without 67087Snate@binkert.org * modification, are permitted provided that the following conditions are 77087Snate@binkert.org * met: redistributions of source code must retain the above copyright 87087Snate@binkert.org * notice, this list of conditions and the following disclaimer; 97087Snate@binkert.org * redistributions in binary form must reproduce the above copyright 107087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 117087Snate@binkert.org * documentation and/or other materials provided with the distribution; 127087Snate@binkert.org * neither the name of the copyright holders nor the names of its 135647Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 147087Snate@binkert.org * this software without specific prior written permission. 157087Snate@binkert.org * 167087Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177087Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187087Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197087Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207087Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 217087Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225647Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237087Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245647Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255647Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265647Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275647Sgblack@eecs.umich.edu */ 285647Sgblack@eecs.umich.edu 295647Sgblack@eecs.umich.edu#include "arch/alpha/ev5.hh" 305647Sgblack@eecs.umich.edu#include "arch/alpha/system.hh" 315647Sgblack@eecs.umich.edu#include "arch/vtophys.hh" 325647Sgblack@eecs.umich.edu#include "base/remote_gdb.hh" 335647Sgblack@eecs.umich.edu#include "base/loader/object_file.hh" 345647Sgblack@eecs.umich.edu#include "base/loader/symtab.hh" 355647Sgblack@eecs.umich.edu#include "base/trace.hh" 365647Sgblack@eecs.umich.edu#include "mem/physical.hh" 375647Sgblack@eecs.umich.edu#include "sim/byteswap.hh" 385647Sgblack@eecs.umich.edu#include "sim/builder.hh" 395647Sgblack@eecs.umich.edu 405647Sgblack@eecs.umich.edu 415654Sgblack@eecs.umich.eduusing namespace LittleEndianGuest; 427629Sgblack@eecs.umich.edu 435647Sgblack@eecs.umich.eduAlphaSystem::AlphaSystem(Params *p) 446137Sgblack@eecs.umich.edu : System(p) 456137Sgblack@eecs.umich.edu{ 466137Sgblack@eecs.umich.edu consoleSymtab = new SymbolTable; 475654Sgblack@eecs.umich.edu palSymtab = new SymbolTable; 486046Sgblack@eecs.umich.edu 495647Sgblack@eecs.umich.edu 505648Sgblack@eecs.umich.edu /** 515648Sgblack@eecs.umich.edu * Load the pal, and console code into memory 525647Sgblack@eecs.umich.edu */ 535647Sgblack@eecs.umich.edu // Load Console Code 545647Sgblack@eecs.umich.edu console = createObjectFile(params()->console_path); 555647Sgblack@eecs.umich.edu if (console == NULL) 565647Sgblack@eecs.umich.edu fatal("Could not load console file %s", params()->console_path); 575647Sgblack@eecs.umich.edu 585647Sgblack@eecs.umich.edu // Load pal file 595647Sgblack@eecs.umich.edu pal = createObjectFile(params()->palcode); 605647Sgblack@eecs.umich.edu if (pal == NULL) 615648Sgblack@eecs.umich.edu fatal("Could not load PALcode file %s", params()->palcode); 625647Sgblack@eecs.umich.edu 635648Sgblack@eecs.umich.edu 645648Sgblack@eecs.umich.edu // Load program sections into memory 655648Sgblack@eecs.umich.edu pal->loadSections(&functionalPort, AlphaISA::LoadAddrMask); 665648Sgblack@eecs.umich.edu console->loadSections(&functionalPort, AlphaISA::LoadAddrMask); 675648Sgblack@eecs.umich.edu 685648Sgblack@eecs.umich.edu // load symbols 695648Sgblack@eecs.umich.edu if (!console->loadGlobalSymbols(consoleSymtab)) 705648Sgblack@eecs.umich.edu panic("could not load console symbols\n"); 715648Sgblack@eecs.umich.edu 725648Sgblack@eecs.umich.edu if (!pal->loadGlobalSymbols(palSymtab)) 735648Sgblack@eecs.umich.edu panic("could not load pal symbols\n"); 745648Sgblack@eecs.umich.edu 755648Sgblack@eecs.umich.edu if (!pal->loadLocalSymbols(palSymtab)) 765648Sgblack@eecs.umich.edu panic("could not load pal symbols\n"); 775648Sgblack@eecs.umich.edu 785648Sgblack@eecs.umich.edu if (!console->loadGlobalSymbols(debugSymbolTable)) 795648Sgblack@eecs.umich.edu panic("could not load console symbols\n"); 805648Sgblack@eecs.umich.edu 815648Sgblack@eecs.umich.edu if (!pal->loadGlobalSymbols(debugSymbolTable)) 825648Sgblack@eecs.umich.edu panic("could not load pal symbols\n"); 835648Sgblack@eecs.umich.edu 845648Sgblack@eecs.umich.edu if (!pal->loadLocalSymbols(debugSymbolTable)) 855648Sgblack@eecs.umich.edu panic("could not load pal symbols\n"); 865648Sgblack@eecs.umich.edu 875648Sgblack@eecs.umich.edu Addr addr = 0; 885648Sgblack@eecs.umich.edu#ifndef NDEBUG 895648Sgblack@eecs.umich.edu consolePanicEvent = addConsoleFuncEvent<BreakPCEvent>("panic"); 905648Sgblack@eecs.umich.edu#endif 915648Sgblack@eecs.umich.edu 925648Sgblack@eecs.umich.edu /** 935648Sgblack@eecs.umich.edu * Copy the osflags (kernel arguments) into the consoles 945648Sgblack@eecs.umich.edu * memory. (Presently Linux does not use the console service 955648Sgblack@eecs.umich.edu * routine to get these command line arguments, but Tru64 and 965648Sgblack@eecs.umich.edu * others do.) 975648Sgblack@eecs.umich.edu */ 985648Sgblack@eecs.umich.edu if (consoleSymtab->findAddress("env_booted_osflags", addr)) { 995648Sgblack@eecs.umich.edu virtPort.writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(), 1005648Sgblack@eecs.umich.edu strlen(params()->boot_osflags.c_str())); 1015648Sgblack@eecs.umich.edu } 1025648Sgblack@eecs.umich.edu 1035648Sgblack@eecs.umich.edu /** 1045648Sgblack@eecs.umich.edu * Set the hardware reset parameter block system type and revision 1055648Sgblack@eecs.umich.edu * information to Tsunami. 1065648Sgblack@eecs.umich.edu */ 1075648Sgblack@eecs.umich.edu if (consoleSymtab->findAddress("m5_rpb", addr)) { 1085648Sgblack@eecs.umich.edu uint64_t data; 1095648Sgblack@eecs.umich.edu data = htog(params()->system_type); 1105648Sgblack@eecs.umich.edu virtPort.write(addr, data); 1115648Sgblack@eecs.umich.edu data = htog(params()->system_rev); 1125648Sgblack@eecs.umich.edu virtPort.write(addr, data); 1135648Sgblack@eecs.umich.edu } else 1145648Sgblack@eecs.umich.edu panic("could not find hwrpb\n"); 1155648Sgblack@eecs.umich.edu 1165648Sgblack@eecs.umich.edu} 1175648Sgblack@eecs.umich.edu 1185648Sgblack@eecs.umich.eduAlphaSystem::~AlphaSystem() 1195648Sgblack@eecs.umich.edu{ 1205648Sgblack@eecs.umich.edu delete consoleSymtab; 1215648Sgblack@eecs.umich.edu delete console; 1225648Sgblack@eecs.umich.edu delete pal; 1235648Sgblack@eecs.umich.edu#ifdef DEBUG 1245648Sgblack@eecs.umich.edu delete consolePanicEvent; 1255648Sgblack@eecs.umich.edu#endif 1265648Sgblack@eecs.umich.edu} 1275648Sgblack@eecs.umich.edu 1285648Sgblack@eecs.umich.edu/** 1295648Sgblack@eecs.umich.edu * This function fixes up addresses that are used to match PCs for 1305648Sgblack@eecs.umich.edu * hooking simulator events on to target function executions. 1315648Sgblack@eecs.umich.edu * 1325648Sgblack@eecs.umich.edu * Alpha binaries may have multiple global offset table (GOT) 1335648Sgblack@eecs.umich.edu * sections. A function that uses the GOT starts with a 1345648Sgblack@eecs.umich.edu * two-instruction prolog which sets the global pointer (gp == r29) to 1355648Sgblack@eecs.umich.edu * the appropriate GOT section. The proper gp value is calculated 1365648Sgblack@eecs.umich.edu * based on the function address, which must be passed by the caller 1375648Sgblack@eecs.umich.edu * in the procedure value register (pv aka t12 == r27). This sequence 1385648Sgblack@eecs.umich.edu * looks like the following: 1395648Sgblack@eecs.umich.edu * 1405648Sgblack@eecs.umich.edu * opcode Ra Rb offset 1415648Sgblack@eecs.umich.edu * ldah gp,X(pv) 09 29 27 X 1425648Sgblack@eecs.umich.edu * lda gp,Y(gp) 08 29 29 Y 1435648Sgblack@eecs.umich.edu * 1445648Sgblack@eecs.umich.edu * for some constant offsets X and Y. The catch is that the linker 1455648Sgblack@eecs.umich.edu * (or maybe even the compiler, I'm not sure) may recognize that the 1465648Sgblack@eecs.umich.edu * caller and callee are using the same GOT section, making this 1475648Sgblack@eecs.umich.edu * prolog redundant, and modify the call target to skip these 1485648Sgblack@eecs.umich.edu * instructions. If we check for execution of the first instruction 1495648Sgblack@eecs.umich.edu * of a function (the one the symbol points to) to detect when to skip 1505648Sgblack@eecs.umich.edu * it, we'll miss all these modified calls. It might work to 1515648Sgblack@eecs.umich.edu * unconditionally check for the third instruction, but not all 1525648Sgblack@eecs.umich.edu * functions have this prolog, and there's some chance that those 1535648Sgblack@eecs.umich.edu * first two instructions could have undesired consequences. So we do 1545648Sgblack@eecs.umich.edu * the Right Thing and pattern-match the first two instructions of the 1555648Sgblack@eecs.umich.edu * function to decide where to patch. 1565648Sgblack@eecs.umich.edu * 1575648Sgblack@eecs.umich.edu * Eventually this code should be moved into an ISA-specific file. 1585648Sgblack@eecs.umich.edu */ 1595648Sgblack@eecs.umich.eduAddr 1605648Sgblack@eecs.umich.eduAlphaSystem::fixFuncEventAddr(Addr addr) 1615648Sgblack@eecs.umich.edu{ 1625648Sgblack@eecs.umich.edu // mask for just the opcode, Ra, and Rb fields (not the offset) 1635648Sgblack@eecs.umich.edu const uint32_t inst_mask = 0xffff0000; 1645648Sgblack@eecs.umich.edu // ldah gp,X(pv): opcode 9, Ra = 29, Rb = 27 1655648Sgblack@eecs.umich.edu const uint32_t gp_ldah_pattern = (9 << 26) | (29 << 21) | (27 << 16); 1665648Sgblack@eecs.umich.edu // lda gp,Y(gp): opcode 8, Ra = 29, rb = 29 1675648Sgblack@eecs.umich.edu const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16); 1685648Sgblack@eecs.umich.edu 1695648Sgblack@eecs.umich.edu uint32_t i1 = virtPort.read<uint32_t>(addr); 1705648Sgblack@eecs.umich.edu uint32_t i2 = virtPort.read<uint32_t>(addr + sizeof(AlphaISA::MachInst)); 1715648Sgblack@eecs.umich.edu 1725648Sgblack@eecs.umich.edu if ((i1 & inst_mask) == gp_ldah_pattern && 1735648Sgblack@eecs.umich.edu (i2 & inst_mask) == gp_lda_pattern) { 1745648Sgblack@eecs.umich.edu Addr new_addr = addr + 2* sizeof(AlphaISA::MachInst); 1755648Sgblack@eecs.umich.edu DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr); 1765648Sgblack@eecs.umich.edu return new_addr; 1775648Sgblack@eecs.umich.edu } else { 1785648Sgblack@eecs.umich.edu return addr; 1795648Sgblack@eecs.umich.edu } 1805648Sgblack@eecs.umich.edu} 1815648Sgblack@eecs.umich.edu 1825648Sgblack@eecs.umich.edu 1835648Sgblack@eecs.umich.eduvoid 1845648Sgblack@eecs.umich.eduAlphaSystem::setAlphaAccess(Addr access) 1855648Sgblack@eecs.umich.edu{ 1865648Sgblack@eecs.umich.edu Addr addr = 0; 1875648Sgblack@eecs.umich.edu if (consoleSymtab->findAddress("m5AlphaAccess", addr)) { 1885648Sgblack@eecs.umich.edu virtPort.write(addr, htog(EV5::Phys2K0Seg(access))); 1895648Sgblack@eecs.umich.edu } else 1905648Sgblack@eecs.umich.edu panic("could not find m5AlphaAccess\n"); 1915648Sgblack@eecs.umich.edu} 1925648Sgblack@eecs.umich.edu 1935648Sgblack@eecs.umich.edubool 1945648Sgblack@eecs.umich.eduAlphaSystem::breakpoint() 1955648Sgblack@eecs.umich.edu{ 1965648Sgblack@eecs.umich.edu return remoteGDB[0]->trap(ALPHA_KENTRY_INT); 1975648Sgblack@eecs.umich.edu} 1985648Sgblack@eecs.umich.edu 1995648Sgblack@eecs.umich.eduvoid 2005648Sgblack@eecs.umich.eduAlphaSystem::serialize(std::ostream &os) 2015648Sgblack@eecs.umich.edu{ 2025648Sgblack@eecs.umich.edu System::serialize(os); 2035648Sgblack@eecs.umich.edu consoleSymtab->serialize("console_symtab", os); 2045648Sgblack@eecs.umich.edu palSymtab->serialize("pal_symtab", os); 2055648Sgblack@eecs.umich.edu} 2065649Sgblack@eecs.umich.edu 2075649Sgblack@eecs.umich.edu 2085649Sgblack@eecs.umich.eduvoid 2095648Sgblack@eecs.umich.eduAlphaSystem::unserialize(Checkpoint *cp, const std::string §ion) 2105898Sgblack@eecs.umich.edu{ 2115648Sgblack@eecs.umich.edu System::unserialize(cp,section); 2125648Sgblack@eecs.umich.edu consoleSymtab->unserialize("console_symtab", cp, section); 2135648Sgblack@eecs.umich.edu palSymtab->unserialize("pal_symtab", cp, section); 2145648Sgblack@eecs.umich.edu} 2155648Sgblack@eecs.umich.edu 2165648Sgblack@eecs.umich.edu 2175648Sgblack@eecs.umich.eduBEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem) 2185648Sgblack@eecs.umich.edu 2195648Sgblack@eecs.umich.edu Param<Tick> boot_cpu_frequency; 2205648Sgblack@eecs.umich.edu SimObjectParam<PhysicalMemory *> physmem; 2215648Sgblack@eecs.umich.edu 2225648Sgblack@eecs.umich.edu Param<std::string> kernel; 2235648Sgblack@eecs.umich.edu Param<std::string> console; 2245649Sgblack@eecs.umich.edu Param<std::string> pal; 2255649Sgblack@eecs.umich.edu 2265649Sgblack@eecs.umich.edu Param<std::string> boot_osflags; 2275648Sgblack@eecs.umich.edu Param<std::string> readfile; 2285898Sgblack@eecs.umich.edu Param<unsigned int> init_param; 2295648Sgblack@eecs.umich.edu 2305647Sgblack@eecs.umich.edu Param<uint64_t> system_type; 2315691Sgblack@eecs.umich.edu Param<uint64_t> system_rev; 2325691Sgblack@eecs.umich.edu 2335691Sgblack@eecs.umich.edu Param<bool> bin; 2345691Sgblack@eecs.umich.edu VectorParam<std::string> binned_fns; 2355691Sgblack@eecs.umich.edu Param<bool> bin_int; 2365691Sgblack@eecs.umich.edu 2375691Sgblack@eecs.umich.eduEND_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem) 2385691Sgblack@eecs.umich.edu 2395691Sgblack@eecs.umich.eduBEGIN_INIT_SIM_OBJECT_PARAMS(AlphaSystem) 2405691Sgblack@eecs.umich.edu 2415691Sgblack@eecs.umich.edu INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"), 2425691Sgblack@eecs.umich.edu INIT_PARAM(physmem, "phsyical memory"), 2435691Sgblack@eecs.umich.edu INIT_PARAM(kernel, "file that contains the kernel code"), 2445691Sgblack@eecs.umich.edu INIT_PARAM(console, "file that contains the console code"), 2455691Sgblack@eecs.umich.edu INIT_PARAM(pal, "file that contains palcode"), 2465691Sgblack@eecs.umich.edu INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", 2475691Sgblack@eecs.umich.edu "a"), 2485691Sgblack@eecs.umich.edu INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), 2495691Sgblack@eecs.umich.edu INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), 2505691Sgblack@eecs.umich.edu INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34), 2515691Sgblack@eecs.umich.edu INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10), 2525691Sgblack@eecs.umich.edu INIT_PARAM_DFLT(bin, "is this system to be binned", false), 2535691Sgblack@eecs.umich.edu INIT_PARAM(binned_fns, "functions to be broken down and binned"), 2545691Sgblack@eecs.umich.edu INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true) 2555691Sgblack@eecs.umich.edu 2565691Sgblack@eecs.umich.eduEND_INIT_SIM_OBJECT_PARAMS(AlphaSystem) 2575691Sgblack@eecs.umich.edu 2585691Sgblack@eecs.umich.eduCREATE_SIM_OBJECT(AlphaSystem) 2595691Sgblack@eecs.umich.edu{ 2605691Sgblack@eecs.umich.edu AlphaSystem::Params *p = new AlphaSystem::Params; 2615691Sgblack@eecs.umich.edu p->name = getInstanceName(); 2625691Sgblack@eecs.umich.edu p->boot_cpu_frequency = boot_cpu_frequency; 2635691Sgblack@eecs.umich.edu p->physmem = physmem; 2645691Sgblack@eecs.umich.edu p->kernel_path = kernel; 2655691Sgblack@eecs.umich.edu p->console_path = console; 2665691Sgblack@eecs.umich.edu p->palcode = pal; 2675691Sgblack@eecs.umich.edu p->boot_osflags = boot_osflags; 2685691Sgblack@eecs.umich.edu p->init_param = init_param; 2695691Sgblack@eecs.umich.edu p->readfile = readfile; 2706066Sgblack@eecs.umich.edu p->system_type = system_type; 2716066Sgblack@eecs.umich.edu p->system_rev = system_rev; 2726050Sgblack@eecs.umich.edu p->bin = bin; 2736050Sgblack@eecs.umich.edu p->binned_fns = binned_fns; 2745691Sgblack@eecs.umich.edu p->bin_int = bin_int; 2755691Sgblack@eecs.umich.edu return new AlphaSystem(p); 2765811Sgblack@eecs.umich.edu} 2775691Sgblack@eecs.umich.edu 2785647Sgblack@eecs.umich.eduREGISTER_SIM_OBJECT("AlphaSystem", AlphaSystem) 2796041Sgblack@eecs.umich.edu 2806041Sgblack@eecs.umich.edu 2816041Sgblack@eecs.umich.edu