system.cc revision 4762
12SN/A/* 21762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665SN/A * 282665SN/A * Authors: Ali Saidi 292665SN/A * Nathan Binkert 302SN/A */ 312SN/A 322SN/A#include <sys/signal.h> 332SN/A 341298SN/A#include "arch/alpha/ev5.hh" 351298SN/A#include "arch/alpha/system.hh" 361259SN/A#include "arch/alpha/remote_gdb.hh" 372SN/A#include "arch/vtophys.hh" 382SN/A#include "base/loader/object_file.hh" 39146SN/A#include "base/loader/symtab.hh" 40146SN/A#include "base/trace.hh" 417632SBrad.Beckmann@amd.com#include "mem/physical.hh" 428232Snate@binkert.org#include "params/AlphaSystem.hh" 433348SN/A#include "sim/byteswap.hh" 448229Snate@binkert.org 453348SN/A 463348SN/Ausing namespace LittleEndianGuest; 4756SN/A 48695SN/AAlphaSystem::AlphaSystem(Params *p) 498832SAli.Saidi@ARM.com : System(p) 502SN/A{ 512SN/A consoleSymtab = new SymbolTable; 522SN/A palSymtab = new SymbolTable; 531298SN/A 541298SN/A 553187SN/A /** 568975Sandreas.hansson@arm.com * Load the pal, and console code into memory 573187SN/A */ 588948Sandreas.hansson@arm.com // Load Console Code 593187SN/A console = createObjectFile(params()->console); 603187SN/A if (console == NULL) 613187SN/A fatal("Could not load console file %s", params()->console); 623187SN/A 633187SN/A // Load pal file 643187SN/A pal = createObjectFile(params()->pal); 653187SN/A if (pal == NULL) 663187SN/A fatal("Could not load PALcode file %s", params()->pal); 673187SN/A 683262SN/A 693349SN/A // Load program sections into memory 703262SN/A pal->loadSections(&functionalPort, AlphaISA::LoadAddrMask); 713262SN/A console->loadSections(&functionalPort, AlphaISA::LoadAddrMask); 723262SN/A 733262SN/A // load symbols 748975Sandreas.hansson@arm.com if (!console->loadGlobalSymbols(consoleSymtab)) 757544SN/A panic("could not load console symbols\n"); 767544SN/A 777544SN/A if (!pal->loadGlobalSymbols(palSymtab)) 787544SN/A panic("could not load pal symbols\n"); 797544SN/A 807544SN/A if (!pal->loadLocalSymbols(palSymtab)) 817544SN/A panic("could not load pal symbols\n"); 827544SN/A 833262SN/A if (!console->loadGlobalSymbols(debugSymbolTable)) 843262SN/A panic("could not load console symbols\n"); 857544SN/A 867544SN/A if (!pal->loadGlobalSymbols(debugSymbolTable)) 877544SN/A panic("could not load pal symbols\n"); 887544SN/A 893262SN/A if (!pal->loadLocalSymbols(debugSymbolTable)) 903262SN/A panic("could not load pal symbols\n"); 913262SN/A 923262SN/A Addr addr = 0; 935034SN/A#ifndef NDEBUG 945034SN/A consolePanicEvent = addConsoleFuncEvent<BreakPCEvent>("panic"); 952SN/A#endif 963187SN/A 973187SN/A /** 988853Sandreas.hansson@arm.com * Copy the osflags (kernel arguments) into the consoles 993187SN/A * memory. (Presently Linux does not use the console service 1003187SN/A * routine to get these command line arguments, but Tru64 and 1013187SN/A * others do.) 1025034SN/A */ 1035034SN/A if (consoleSymtab->findAddress("env_booted_osflags", addr)) { 1045034SN/A virtPort.writeBlob(addr, (uint8_t*)params()->boot_osflags.c_str(), 1055034SN/A strlen(params()->boot_osflags.c_str())); 1067544SN/A } 1078832SAli.Saidi@ARM.com 1085034SN/A /** 1095034SN/A * Set the hardware reset parameter block system type and revision 1105034SN/A * information to Tsunami. 1115034SN/A */ 1125034SN/A if (consoleSymtab->findAddress("m5_rpb", addr)) { 1138436SBrad.Beckmann@amd.com uint64_t data; 1148436SBrad.Beckmann@amd.com data = htog(params()->system_type); 1152SN/A virtPort.write(addr+0x50, data); 1167544SN/A data = htog(params()->system_rev); 1177544SN/A virtPort.write(addr+0x58, data); 1183187SN/A } else 1195034SN/A panic("could not find hwrpb\n"); 1202SN/A 1212SN/A} 1222SN/A 1232SN/AAlphaSystem::~AlphaSystem() 1242SN/A{ 1252SN/A delete consoleSymtab; 1262SN/A delete console; 1278436SBrad.Beckmann@amd.com delete pal; 1285606SN/A#ifdef DEBUG 1291298SN/A delete consolePanicEvent; 1303187SN/A#endif 1317544SN/A} 1323187SN/A 1333187SN/A/** 1349294Sandreas.hansson@arm.com * This function fixes up addresses that are used to match PCs for 1359294Sandreas.hansson@arm.com * hooking simulator events on to target function executions. 1363187SN/A * 1373187SN/A * Alpha binaries may have multiple global offset table (GOT) 1388922Swilliam.wang@arm.com * sections. A function that uses the GOT starts with a 1393187SN/A * two-instruction prolog which sets the global pointer (gp == r29) to 1408922Swilliam.wang@arm.com * the appropriate GOT section. The proper gp value is calculated 1413187SN/A * based on the function address, which must be passed by the caller 1428922Swilliam.wang@arm.com * in the procedure value register (pv aka t12 == r27). This sequence 1433187SN/A * looks like the following: 1443187SN/A * 1453187SN/A * opcode Ra Rb offset 1463187SN/A * ldah gp,X(pv) 09 29 27 X 1473187SN/A * lda gp,Y(gp) 08 29 29 Y 1483187SN/A * 1493187SN/A * for some constant offsets X and Y. The catch is that the linker 1503187SN/A * (or maybe even the compiler, I'm not sure) may recognize that the 1513187SN/A * caller and callee are using the same GOT section, making this 1523187SN/A * prolog redundant, and modify the call target to skip these 1534579SN/A * instructions. If we check for execution of the first instruction 1544579SN/A * of a function (the one the symbol points to) to detect when to skip 1552SN/A * it, we'll miss all these modified calls. It might work to 1562SN/A * unconditionally check for the third instruction, but not all 1572SN/A * functions have this prolog, and there's some chance that those 1582SN/A * first two instructions could have undesired consequences. So we do 1593349SN/A * the Right Thing and pattern-match the first two instructions of the 1602SN/A * function to decide where to patch. 1614628SN/A * 1624628SN/A * Eventually this code should be moved into an ISA-specific file. 1637544SN/A */ 1647544SN/AAddr 1657544SN/AAlphaSystem::fixFuncEventAddr(Addr addr) 1667544SN/A{ 1678436SBrad.Beckmann@amd.com // mask for just the opcode, Ra, and Rb fields (not the offset) 1684628SN/A const uint32_t inst_mask = 0xffff0000; 1698436SBrad.Beckmann@amd.com // ldah gp,X(pv): opcode 9, Ra = 29, Rb = 27 1708436SBrad.Beckmann@amd.com const uint32_t gp_ldah_pattern = (9 << 26) | (29 << 21) | (27 << 16); 1714628SN/A // lda gp,Y(gp): opcode 8, Ra = 29, rb = 29 1723187SN/A const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16); 1733187SN/A 1743187SN/A uint32_t i1 = virtPort.read<uint32_t>(addr); 1753187SN/A uint32_t i2 = virtPort.read<uint32_t>(addr + sizeof(AlphaISA::MachInst)); 1763187SN/A 1773187SN/A if ((i1 & inst_mask) == gp_ldah_pattern && 1781298SN/A (i2 & inst_mask) == gp_lda_pattern) { 1794628SN/A Addr new_addr = addr + 2* sizeof(AlphaISA::MachInst); 1804628SN/A DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr); 1811298SN/A return new_addr; 1821298SN/A } else { 1831298SN/A return addr; 1848436SBrad.Beckmann@amd.com } 1858436SBrad.Beckmann@amd.com} 1868436SBrad.Beckmann@amd.com 1878436SBrad.Beckmann@amd.com 1882SN/Avoid 1898436SBrad.Beckmann@amd.comAlphaSystem::setAlphaAccess(Addr access) 1908436SBrad.Beckmann@amd.com{ 1918436SBrad.Beckmann@amd.com Addr addr = 0; 1928436SBrad.Beckmann@amd.com if (consoleSymtab->findAddress("m5AlphaAccess", addr)) { 1938436SBrad.Beckmann@amd.com virtPort.write(addr, htog(EV5::Phys2K0Seg(access))); 1948436SBrad.Beckmann@amd.com } else 1958436SBrad.Beckmann@amd.com panic("could not find m5AlphaAccess\n"); 1968436SBrad.Beckmann@amd.com} 1972SN/A 1988436SBrad.Beckmann@amd.comvoid 1998436SBrad.Beckmann@amd.comAlphaSystem::serialize(std::ostream &os) 2002SN/A{ 2018436SBrad.Beckmann@amd.com System::serialize(os); 2028436SBrad.Beckmann@amd.com consoleSymtab->serialize("console_symtab", os); 2038436SBrad.Beckmann@amd.com palSymtab->serialize("pal_symtab", os); 2048436SBrad.Beckmann@amd.com} 2058436SBrad.Beckmann@amd.com 2068436SBrad.Beckmann@amd.com 2078436SBrad.Beckmann@amd.comvoid 2088436SBrad.Beckmann@amd.comAlphaSystem::unserialize(Checkpoint *cp, const std::string §ion) 2098436SBrad.Beckmann@amd.com{ 2108436SBrad.Beckmann@amd.com System::unserialize(cp,section); 2118853Sandreas.hansson@arm.com consoleSymtab->unserialize("console_symtab", cp, section); 2128436SBrad.Beckmann@amd.com palSymtab->unserialize("pal_symtab", cp, section); 2138436SBrad.Beckmann@amd.com} 2142SN/A 2152SN/AAlphaSystem * 2162SN/AAlphaSystemParams::create() 2172SN/A{ 2183187SN/A return new AlphaSystem(this); 2192SN/A} 2203187SN/A