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 &section)
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