system.cc revision 2358
11689SN/A/* 27944SGiacomo.Gabrielli@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 37944SGiacomo.Gabrielli@arm.com * All rights reserved. 47944SGiacomo.Gabrielli@arm.com * 57944SGiacomo.Gabrielli@arm.com * Redistribution and use in source and binary forms, with or without 67944SGiacomo.Gabrielli@arm.com * modification, are permitted provided that the following conditions are 77944SGiacomo.Gabrielli@arm.com * met: redistributions of source code must retain the above copyright 87944SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer; 97944SGiacomo.Gabrielli@arm.com * redistributions in binary form must reproduce the above copyright 107944SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer in the 117944SGiacomo.Gabrielli@arm.com * documentation and/or other materials provided with the distribution; 127944SGiacomo.Gabrielli@arm.com * neither the name of the copyright holders nor the names of its 137944SGiacomo.Gabrielli@arm.com * contributors may be used to endorse or promote products derived from 142326SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271689SN/A */ 281689SN/A 291689SN/A#include "arch/alpha/system.hh" 301689SN/A#include "arch/vtophys.hh" 311689SN/A#include "base/remote_gdb.hh" 321689SN/A#include "base/loader/object_file.hh" 331689SN/A#include "base/loader/symtab.hh" 341689SN/A#include "base/trace.hh" 351689SN/A#include "mem/functional/memory_control.hh" 361689SN/A#include "mem/functional/physical.hh" 371689SN/A#include "sim/byteswap.hh" 381689SN/A#include "sim/builder.hh" 392665Ssaidi@eecs.umich.edu 402665Ssaidi@eecs.umich.edu 412831Sksewell@umich.eduusing namespace LittleEndianGuest; 421689SN/A 431689SN/AAlphaSystem::AlphaSystem(Params *p) 442064SN/A : System(p) 451060SN/A{ 461060SN/A consoleSymtab = new SymbolTable; 472292SN/A palSymtab = new SymbolTable; 481717SN/A 498232Snate@binkert.org 504762Snate@binkert.org /** 516221Snate@binkert.org * Load the pal, and console code into memory 524762Snate@binkert.org */ 531060SN/A // Load Console Code 546221Snate@binkert.org console = createObjectFile(params()->console_path); 555529Snate@binkert.org if (console == NULL) 561061SN/A fatal("Could not load console file %s", params()->console_path); 572292SN/A 585606Snate@binkert.org // Load pal file 598581Ssteve.reinhardt@amd.com pal = createObjectFile(params()->palcode); 608581Ssteve.reinhardt@amd.com if (pal == NULL) 611060SN/A fatal("Could not load PALcode file %s", params()->palcode); 622292SN/A 632292SN/A 642292SN/A // Load program sections into memory 652292SN/A pal->loadSections(physmem, true); 662292SN/A console->loadSections(physmem, true); 672292SN/A 682326SN/A // load symbols 692292SN/A if (!console->loadGlobalSymbols(consoleSymtab)) 702292SN/A panic("could not load console symbols\n"); 712292SN/A 722292SN/A if (!pal->loadGlobalSymbols(palSymtab)) 732292SN/A panic("could not load pal symbols\n"); 742292SN/A 755336Shines@cs.fsu.edu if (!pal->loadLocalSymbols(palSymtab)) 762292SN/A panic("could not load pal symbols\n"); 774873Sstever@eecs.umich.edu 782292SN/A if (!console->loadGlobalSymbols(debugSymbolTable)) 792292SN/A panic("could not load console symbols\n"); 802292SN/A 814329Sktlim@umich.edu if (!pal->loadGlobalSymbols(debugSymbolTable)) 825529Snate@binkert.org panic("could not load pal symbols\n"); 834329Sktlim@umich.edu 844329Sktlim@umich.edu if (!pal->loadLocalSymbols(debugSymbolTable)) 854329Sktlim@umich.edu panic("could not load pal symbols\n"); 862292SN/A 872292SN/A Addr addr = 0; 882292SN/A#ifndef NDEBUG 892292SN/A consolePanicEvent = addConsoleFuncEvent<BreakPCEvent>("panic"); 902292SN/A#endif 912292SN/A 922292SN/A /** 932292SN/A * Copy the osflags (kernel arguments) into the consoles 942307SN/A * memory. (Presently Linux does not use the console service 952307SN/A * routine to get these command line arguments, but Tru64 and 965529Snate@binkert.org * others do.) 971060SN/A */ 981060SN/A if (consoleSymtab->findAddress("env_booted_osflags", addr)) { 991060SN/A Addr paddr = vtophys(physmem, addr); 1001060SN/A char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t)); 1011060SN/A 1021060SN/A if (osflags) 1032326SN/A strcpy(osflags, params()->boot_osflags.c_str()); 1041060SN/A } 1051060SN/A 1061060SN/A /** 1071060SN/A * Set the hardware reset parameter block system type and revision 1082292SN/A * information to Tsunami. 1096221Snate@binkert.org */ 1106221Snate@binkert.org if (consoleSymtab->findAddress("m5_rpb", addr)) { 1116221Snate@binkert.org Addr paddr = vtophys(physmem, addr); 1121060SN/A char *hwrpb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t)); 1131060SN/A 1142307SN/A if (!hwrpb) 1152292SN/A panic("could not translate hwrpb addr\n"); 1162980Sgblack@eecs.umich.edu 1172292SN/A *(uint64_t*)(hwrpb+0x50) = htog(params()->system_type); 1182292SN/A *(uint64_t*)(hwrpb+0x58) = htog(params()->system_rev); 1192292SN/A } else 1202292SN/A panic("could not find hwrpb\n"); 1212292SN/A 1222292SN/A} 1232292SN/A 1242292SN/AAlphaSystem::~AlphaSystem() 1252292SN/A{ 1262292SN/A delete consoleSymtab; 1276221Snate@binkert.org delete console; 1286221Snate@binkert.org delete pal; 1292292SN/A#ifdef DEBUG 1302292SN/A delete consolePanicEvent; 1312292SN/A#endif 1322292SN/A} 1332292SN/A 1342292SN/A/** 1352292SN/A * This function fixes up addresses that are used to match PCs for 1362292SN/A * hooking simulator events on to target function executions. 1372292SN/A * 1386221Snate@binkert.org * Alpha binaries may have multiple global offset table (GOT) 1396221Snate@binkert.org * sections. A function that uses the GOT starts with a 1402292SN/A * two-instruction prolog which sets the global pointer (gp == r29) to 1412292SN/A * the appropriate GOT section. The proper gp value is calculated 1422831Sksewell@umich.edu * based on the function address, which must be passed by the caller 1432292SN/A * in the procedure value register (pv aka t12 == r27). This sequence 1442292SN/A * looks like the following: 1452292SN/A * 1462292SN/A * opcode Ra Rb offset 1472292SN/A * ldah gp,X(pv) 09 29 27 X 1482292SN/A * lda gp,Y(gp) 08 29 29 Y 1492292SN/A * 1502292SN/A * for some constant offsets X and Y. The catch is that the linker 1512292SN/A * (or maybe even the compiler, I'm not sure) may recognize that the 1526221Snate@binkert.org * caller and callee are using the same GOT section, making this 1536221Snate@binkert.org * prolog redundant, and modify the call target to skip these 1542292SN/A * instructions. If we check for execution of the first instruction 1552292SN/A * of a function (the one the symbol points to) to detect when to skip 1562831Sksewell@umich.edu * it, we'll miss all these modified calls. It might work to 1572292SN/A * unconditionally check for the third instruction, but not all 1582292SN/A * functions have this prolog, and there's some chance that those 1592292SN/A * first two instructions could have undesired consequences. So we do 1602292SN/A * the Right Thing and pattern-match the first two instructions of the 1612292SN/A * function to decide where to patch. 1622292SN/A * 1632292SN/A * Eventually this code should be moved into an ISA-specific file. 1642292SN/A */ 1652292SN/AAddr 1662292SN/AAlphaSystem::fixFuncEventAddr(Addr addr) 1672326SN/A{ 1682348SN/A // mask for just the opcode, Ra, and Rb fields (not the offset) 1692326SN/A const uint32_t inst_mask = 0xffff0000; 1702326SN/A // ldah gp,X(pv): opcode 9, Ra = 29, Rb = 27 1712348SN/A const uint32_t gp_ldah_pattern = (9 << 26) | (29 << 21) | (27 << 16); 1722292SN/A // lda gp,Y(gp): opcode 8, Ra = 29, rb = 29 1732292SN/A const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16); 1742292SN/A // instruction size 1752292SN/A const int sz = sizeof(uint32_t); 1762292SN/A 1772292SN/A Addr paddr = vtophys(physmem, addr); 1782292SN/A uint32_t i1 = *(uint32_t *)physmem->dma_addr(paddr, sz); 1791060SN/A uint32_t i2 = *(uint32_t *)physmem->dma_addr(paddr+sz, sz); 1801060SN/A 1811061SN/A if ((i1 & inst_mask) == gp_ldah_pattern && 1821060SN/A (i2 & inst_mask) == gp_lda_pattern) { 1831062SN/A Addr new_addr = addr + 2*sz; 1841062SN/A DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr); 1852301SN/A return new_addr; 1861062SN/A } else { 1871062SN/A return addr; 1881062SN/A } 1891062SN/A} 1901062SN/A 1911062SN/A 1921062SN/Avoid 1931062SN/AAlphaSystem::setAlphaAccess(Addr access) 1941062SN/A{ 1951062SN/A Addr addr = 0; 1962301SN/A if (consoleSymtab->findAddress("m5AlphaAccess", addr)) { 1972301SN/A Addr paddr = vtophys(physmem, addr); 1982301SN/A uint64_t *m5AlphaAccess = 1992301SN/A (uint64_t *)physmem->dma_addr(paddr, sizeof(uint64_t)); 2001062SN/A 2011062SN/A if (!m5AlphaAccess) 2021062SN/A panic("could not translate m5AlphaAccess addr\n"); 2031062SN/A 2041062SN/A *m5AlphaAccess = htog(EV5::Phys2K0Seg(access)); 2051062SN/A } else 2061062SN/A panic("could not find m5AlphaAccess\n"); 2071062SN/A} 2081062SN/A 2091062SN/Abool 2101062SN/AAlphaSystem::breakpoint() 2111062SN/A{ 2121062SN/A return remoteGDB[0]->trap(ALPHA_KENTRY_INT); 2131062SN/A} 2141062SN/A 2151062SN/Avoid 2161062SN/AAlphaSystem::serialize(std::ostream &os) 2171062SN/A{ 2181062SN/A System::serialize(os); 2191062SN/A consoleSymtab->serialize("console_symtab", os); 2201062SN/A palSymtab->serialize("pal_symtab", os); 2211062SN/A} 2221062SN/A 2231062SN/A 2241062SN/Avoid 2251062SN/AAlphaSystem::unserialize(Checkpoint *cp, const std::string §ion) 2261062SN/A{ 2271062SN/A System::unserialize(cp,section); 2281062SN/A consoleSymtab->unserialize("console_symtab", cp, section); 2291062SN/A palSymtab->unserialize("pal_symtab", cp, section); 2301062SN/A} 2311062SN/A 2321062SN/A 2331062SN/ABEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem) 2341062SN/A 2351062SN/A Param<Tick> boot_cpu_frequency; 2361062SN/A SimObjectParam<MemoryController *> memctrl; 2371062SN/A SimObjectParam<PhysicalMemory *> physmem; 2381062SN/A 2391062SN/A Param<std::string> kernel; 2401062SN/A Param<std::string> console; 2411062SN/A Param<std::string> pal; 2421062SN/A 2431062SN/A Param<std::string> boot_osflags; 2441062SN/A Param<std::string> readfile; 2451062SN/A Param<std::string> symbolfile; 2461062SN/A Param<unsigned int> init_param; 2472361SN/A 2482326SN/A Param<uint64_t> system_type; 2492301SN/A Param<uint64_t> system_rev; 2502301SN/A 2512301SN/A Param<bool> bin; 2522301SN/A VectorParam<std::string> binned_fns; 2532301SN/A Param<bool> bin_int; 2542301SN/A 2552326SN/AEND_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem) 2562301SN/A 2572361SN/ABEGIN_INIT_SIM_OBJECT_PARAMS(AlphaSystem) 2582326SN/A 2592307SN/A INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"), 2608240Snate@binkert.org INIT_PARAM(memctrl, "memory controller"), 2612301SN/A INIT_PARAM(physmem, "phsyical memory"), 2622307SN/A INIT_PARAM(kernel, "file that contains the kernel code"), 2632301SN/A INIT_PARAM(console, "file that contains the console code"), 2642301SN/A INIT_PARAM(pal, "file that contains palcode"), 2652301SN/A INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", 2662301SN/A "a"), 2678240Snate@binkert.org INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), 2682301SN/A INIT_PARAM_DFLT(symbolfile, "file to read symbols from", ""), 2692301SN/A INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), 2702301SN/A INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34), 2712301SN/A INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10), 2722301SN/A INIT_PARAM_DFLT(bin, "is this system to be binned", false), 2732301SN/A INIT_PARAM(binned_fns, "functions to be broken down and binned"), 2742301SN/A INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true) 2752326SN/A 2764762Snate@binkert.orgEND_INIT_SIM_OBJECT_PARAMS(AlphaSystem) 2778240Snate@binkert.org 2782301SN/ACREATE_SIM_OBJECT(AlphaSystem) 2792301SN/A{ 2802301SN/A AlphaSystem::Params *p = new AlphaSystem::Params; 2814762Snate@binkert.org p->name = getInstanceName(); 2822301SN/A p->boot_cpu_frequency = boot_cpu_frequency; 2832301SN/A p->memctrl = memctrl; 2842301SN/A p->physmem = physmem; 2852301SN/A p->kernel_path = kernel; 2862361SN/A p->console_path = console; 2872326SN/A p->palcode = pal; 2882301SN/A p->boot_osflags = boot_osflags; 2898240Snate@binkert.org p->init_param = init_param; 2902301SN/A p->readfile = readfile; 2912301SN/A p->symbolfile = symbolfile; 2922301SN/A p->system_type = system_type; 2932301SN/A p->system_rev = system_rev; 2942301SN/A p->bin = bin; 2952980Sgblack@eecs.umich.edu p->binned_fns = binned_fns; 2962301SN/A p->bin_int = bin_int; 2972326SN/A return new AlphaSystem(p); 2982301SN/A} 2992361SN/A 3002326SN/AREGISTER_SIM_OBJECT("AlphaSystem", AlphaSystem) 3018240Snate@binkert.org 3022301SN/A 3032301SN/A