system.cc revision 8852:c744483edfcf
1955SN/A/*
2955SN/A * Copyright (c) 2011-2012 ARM Limited
37816Ssteve.reinhardt@amd.com * All rights reserved
45871Snate@binkert.org *
51762SN/A * The license below extends only to copyright in the software and shall
6955SN/A * not be construed as granting a license to any other intellectual
7955SN/A * property including but not limited to intellectual property relating
8955SN/A * to a hardware implementation of the functionality of the software
9955SN/A * licensed hereunder.  You may use the software subject to the license
10955SN/A * terms below provided that you ensure that this notice is replicated
11955SN/A * unmodified and in its entirety in all distributions of the software,
12955SN/A * modified or unmodified, in source code or in binary form.
13955SN/A *
14955SN/A * Copyright (c) 2003-2006 The Regents of The University of Michigan
15955SN/A * Copyright (c) 2011 Regents of the University of California
16955SN/A * All rights reserved.
17955SN/A *
18955SN/A * Redistribution and use in source and binary forms, with or without
19955SN/A * modification, are permitted provided that the following conditions are
20955SN/A * met: redistributions of source code must retain the above copyright
21955SN/A * notice, this list of conditions and the following disclaimer;
22955SN/A * redistributions in binary form must reproduce the above copyright
23955SN/A * notice, this list of conditions and the following disclaimer in the
24955SN/A * documentation and/or other materials provided with the distribution;
25955SN/A * neither the name of the copyright holders nor the names of its
26955SN/A * contributors may be used to endorse or promote products derived from
27955SN/A * this software without specific prior written permission.
28955SN/A *
29955SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
302665Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
312665Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
325863Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
382632Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
392632Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
402632Sstever@eecs.umich.edu *
412632Sstever@eecs.umich.edu * Authors: Steve Reinhardt
42955SN/A *          Lisa Hsu
432632Sstever@eecs.umich.edu *          Nathan Binkert
442632Sstever@eecs.umich.edu *          Ali Saidi
452761Sstever@eecs.umich.edu *          Rick Strong
462632Sstever@eecs.umich.edu */
472632Sstever@eecs.umich.edu
482632Sstever@eecs.umich.edu#include "arch/isa_traits.hh"
492761Sstever@eecs.umich.edu#include "arch/remote_gdb.hh"
502761Sstever@eecs.umich.edu#include "arch/utility.hh"
512761Sstever@eecs.umich.edu#include "arch/vtophys.hh"
522632Sstever@eecs.umich.edu#include "base/loader/object_file.hh"
532632Sstever@eecs.umich.edu#include "base/loader/symtab.hh"
542761Sstever@eecs.umich.edu#include "base/trace.hh"
552761Sstever@eecs.umich.edu#include "config/the_isa.hh"
562761Sstever@eecs.umich.edu#include "cpu/thread_context.hh"
572761Sstever@eecs.umich.edu#include "debug/Loader.hh"
582761Sstever@eecs.umich.edu#include "debug/WorkItems.hh"
592632Sstever@eecs.umich.edu#include "kern/kernel_stats.hh"
602632Sstever@eecs.umich.edu#include "mem/physical.hh"
612632Sstever@eecs.umich.edu#include "params/System.hh"
622632Sstever@eecs.umich.edu#include "sim/byteswap.hh"
632632Sstever@eecs.umich.edu#include "sim/debug.hh"
642632Sstever@eecs.umich.edu#include "sim/full_system.hh"
652632Sstever@eecs.umich.edu#include "sim/system.hh"
66955SN/A
67955SN/Ausing namespace std;
68955SN/Ausing namespace TheISA;
695863Snate@binkert.org
705863Snate@binkert.orgvector<System *> System::systemList;
715863Snate@binkert.org
725863Snate@binkert.orgint System::numSystemsRunning = 0;
735863Snate@binkert.org
745863Snate@binkert.orgSystem::System(Params *p)
755863Snate@binkert.org    : MemObject(p), _systemPort("system_port", this),
765863Snate@binkert.org      physmem(p->physmem),
775863Snate@binkert.org      _numContexts(0),
785863Snate@binkert.org      pagePtr(0),
795863Snate@binkert.org      init_param(p->init_param),
805863Snate@binkert.org      physProxy(_systemPort),
815863Snate@binkert.org      virtProxy(_systemPort),
825863Snate@binkert.org      loadAddrMask(p->load_addr_mask),
835863Snate@binkert.org      nextPID(0),
845863Snate@binkert.org      memoryMode(p->mem_mode),
855863Snate@binkert.org      workItemsBegin(0),
865863Snate@binkert.org      workItemsEnd(0),
875863Snate@binkert.org      numWorkIds(p->num_work_ids),
885863Snate@binkert.org      _params(p),
895863Snate@binkert.org      totalNumInsts(0),
905863Snate@binkert.org      instEventQueue("system instruction-based event queue")
915863Snate@binkert.org{
925863Snate@binkert.org    // add self to global system list
935863Snate@binkert.org    systemList.push_back(this);
945863Snate@binkert.org
955863Snate@binkert.org    /** Keep track of all memories we can execute code out of
965863Snate@binkert.org     * in our system
975863Snate@binkert.org     */
985863Snate@binkert.org    for (int x = 0; x < p->memories.size(); x++) {
995863Snate@binkert.org        if (!p->memories[x])
1006654Snate@binkert.org            continue;
101955SN/A        memRanges.push_back(RangeSize(p->memories[x]->start(),
1025396Ssaidi@eecs.umich.edu                                      p->memories[x]->size()));
1035863Snate@binkert.org    }
1045863Snate@binkert.org
1054202Sbinkertn@umich.edu    if (FullSystem) {
1065863Snate@binkert.org        kernelSymtab = new SymbolTable;
1075863Snate@binkert.org        if (!debugSymbolTable)
1085863Snate@binkert.org            debugSymbolTable = new SymbolTable;
1095863Snate@binkert.org    }
110955SN/A
1116654Snate@binkert.org    // Get the generic system master IDs
1125273Sstever@gmail.com    MasterID tmp_id M5_VAR_USED;
1135871Snate@binkert.org    tmp_id = getMasterId("writebacks");
1145273Sstever@gmail.com    assert(tmp_id == Request::wbMasterId);
1156655Snate@binkert.org    tmp_id = getMasterId("functional");
1166655Snate@binkert.org    assert(tmp_id == Request::funcMasterId);
1176655Snate@binkert.org    tmp_id = getMasterId("interrupt");
1186655Snate@binkert.org    assert(tmp_id == Request::intMasterId);
1196655Snate@binkert.org
1206655Snate@binkert.org}
1215871Snate@binkert.org
1226654Snate@binkert.orgSystem::~System()
1235396Ssaidi@eecs.umich.edu{
1248120Sgblack@eecs.umich.edu    delete kernelSymtab;
1258120Sgblack@eecs.umich.edu    delete kernel;
1268120Sgblack@eecs.umich.edu
1278120Sgblack@eecs.umich.edu    for (uint32_t j = 0; j < numWorkIds; j++)
1288120Sgblack@eecs.umich.edu        delete workItemStats[j];
1298120Sgblack@eecs.umich.edu}
1308120Sgblack@eecs.umich.edu
1318120Sgblack@eecs.umich.eduvoid
1328120Sgblack@eecs.umich.eduSystem::init()
1338120Sgblack@eecs.umich.edu{
1348120Sgblack@eecs.umich.edu    // check that the system port is connected
1358120Sgblack@eecs.umich.edu    if (!_systemPort.isConnected())
1368120Sgblack@eecs.umich.edu        panic("System port on %s is not connected.\n", name());
1378120Sgblack@eecs.umich.edu}
1388120Sgblack@eecs.umich.edu
1398120Sgblack@eecs.umich.eduPort*
1408120Sgblack@eecs.umich.eduSystem::getPort(const std::string &if_name, int idx)
1418120Sgblack@eecs.umich.edu{
1428120Sgblack@eecs.umich.edu    // no need to distinguish at the moment (besides checking)
1438120Sgblack@eecs.umich.edu    return &_systemPort;
1448120Sgblack@eecs.umich.edu}
1458120Sgblack@eecs.umich.edu
1468120Sgblack@eecs.umich.eduvoid
1478120Sgblack@eecs.umich.eduSystem::setMemoryMode(Enums::MemoryMode mode)
1488120Sgblack@eecs.umich.edu{
1498120Sgblack@eecs.umich.edu    assert(getState() == Drained);
1508120Sgblack@eecs.umich.edu    memoryMode = mode;
1518120Sgblack@eecs.umich.edu}
1528120Sgblack@eecs.umich.edu
1538120Sgblack@eecs.umich.edubool System::breakpoint()
1548120Sgblack@eecs.umich.edu{
1558120Sgblack@eecs.umich.edu    if (remoteGDB.size())
1568120Sgblack@eecs.umich.edu        return remoteGDB[0]->breakpoint();
1578120Sgblack@eecs.umich.edu    return false;
1588120Sgblack@eecs.umich.edu}
1598120Sgblack@eecs.umich.edu
1607816Ssteve.reinhardt@amd.com/**
1617816Ssteve.reinhardt@amd.com * Setting rgdb_wait to a positive integer waits for a remote debugger to
1627816Ssteve.reinhardt@amd.com * connect to that context ID before continuing.  This should really
1637816Ssteve.reinhardt@amd.com   be a parameter on the CPU object or something...
1647816Ssteve.reinhardt@amd.com */
1657816Ssteve.reinhardt@amd.comint rgdb_wait = -1;
1667816Ssteve.reinhardt@amd.com
1677816Ssteve.reinhardt@amd.comint
1687816Ssteve.reinhardt@amd.comSystem::registerThreadContext(ThreadContext *tc, int assigned)
1695871Snate@binkert.org{
1705871Snate@binkert.org    int id;
1716121Snate@binkert.org    if (assigned == -1) {
1725871Snate@binkert.org        for (id = 0; id < threadContexts.size(); id++) {
1735871Snate@binkert.org            if (!threadContexts[id])
1746003Snate@binkert.org                break;
1756655Snate@binkert.org        }
176955SN/A
1775871Snate@binkert.org        if (threadContexts.size() <= id)
1785871Snate@binkert.org            threadContexts.resize(id + 1);
1795871Snate@binkert.org    } else {
1805871Snate@binkert.org        if (threadContexts.size() <= assigned)
181955SN/A            threadContexts.resize(assigned + 1);
1826121Snate@binkert.org        id = assigned;
1836121Snate@binkert.org    }
1846121Snate@binkert.org
1851533SN/A    if (threadContexts[id])
1866655Snate@binkert.org        fatal("Cannot have two CPUs with the same id (%d)\n", id);
1876655Snate@binkert.org
1886655Snate@binkert.org    threadContexts[id] = tc;
1896655Snate@binkert.org    _numContexts++;
1905871Snate@binkert.org
1915871Snate@binkert.org    int port = getRemoteGDBPort();
1925863Snate@binkert.org    if (port) {
1935871Snate@binkert.org        RemoteGDB *rgdb = new RemoteGDB(this, tc);
1945871Snate@binkert.org        GDBListener *gdbl = new GDBListener(rgdb, port + id);
1955871Snate@binkert.org        gdbl->listen();
1965871Snate@binkert.org
1975871Snate@binkert.org        if (rgdb_wait != -1 && rgdb_wait == id)
1985863Snate@binkert.org            gdbl->accept();
1996121Snate@binkert.org
2005863Snate@binkert.org        if (remoteGDB.size() <= id) {
2015871Snate@binkert.org            remoteGDB.resize(id + 1);
2024678Snate@binkert.org        }
2034678Snate@binkert.org
2044678Snate@binkert.org        remoteGDB[id] = rgdb;
2054678Snate@binkert.org    }
2064678Snate@binkert.org
2074678Snate@binkert.org    activeCpus.push_back(false);
2084678Snate@binkert.org
2094678Snate@binkert.org    return id;
2104678Snate@binkert.org}
2114678Snate@binkert.org
2124678Snate@binkert.orgint
2137827Snate@binkert.orgSystem::numRunningContexts()
2147827Snate@binkert.org{
2156121Snate@binkert.org    int running = 0;
2164678Snate@binkert.org    for (int i = 0; i < _numContexts; ++i) {
2175871Snate@binkert.org        if (threadContexts[i]->status() != ThreadContext::Halted)
2185871Snate@binkert.org            ++running;
2195871Snate@binkert.org    }
2205871Snate@binkert.org    return running;
2215871Snate@binkert.org}
2225871Snate@binkert.org
2235871Snate@binkert.orgvoid
2245871Snate@binkert.orgSystem::initState()
2255871Snate@binkert.org{
2265871Snate@binkert.org    int i;
2275871Snate@binkert.org    if (FullSystem) {
2285871Snate@binkert.org        for (i = 0; i < threadContexts.size(); i++)
2295871Snate@binkert.org            TheISA::startupCPU(threadContexts[i], i);
2305871Snate@binkert.org        // Moved from the constructor to here since it relies on the
2318126Sgblack@eecs.umich.edu        // address map being resolved in the interconnect
2325871Snate@binkert.org        /**
2335871Snate@binkert.org         * Load the kernel code into memory
2348122Sgblack@eecs.umich.edu         */
2355871Snate@binkert.org        if (params()->kernel == "") {
2365871Snate@binkert.org            inform("No kernel set for full system simulation. "
2374678Snate@binkert.org                    "Assuming you know what you're doing...\n");
2385871Snate@binkert.org        } else {
2394678Snate@binkert.org            // Load kernel code
2405871Snate@binkert.org            kernel = createObjectFile(params()->kernel);
2415871Snate@binkert.org            inform("kernel located at: %s", params()->kernel);
2425871Snate@binkert.org
2435871Snate@binkert.org            if (kernel == NULL)
2445871Snate@binkert.org                fatal("Could not load kernel file %s", params()->kernel);
2455871Snate@binkert.org
2465871Snate@binkert.org            // Load program sections into memory
2475871Snate@binkert.org            kernel->loadSections(physProxy, loadAddrMask);
2485871Snate@binkert.org
2496121Snate@binkert.org            // setup entry points
250955SN/A            kernelStart = kernel->textBase();
251955SN/A            kernelEnd = kernel->bssBase() + kernel->bssSize();
2522632Sstever@eecs.umich.edu            kernelEntry = kernel->entryPoint();
2532632Sstever@eecs.umich.edu
254955SN/A            // load symbols
255955SN/A            if (!kernel->loadGlobalSymbols(kernelSymtab))
256955SN/A                fatal("could not load kernel symbols\n");
257955SN/A
2585863Snate@binkert.org            if (!kernel->loadLocalSymbols(kernelSymtab))
259955SN/A                fatal("could not load kernel local symbols\n");
2602632Sstever@eecs.umich.edu
2612632Sstever@eecs.umich.edu            if (!kernel->loadGlobalSymbols(debugSymbolTable))
2622632Sstever@eecs.umich.edu                fatal("could not load kernel symbols\n");
2632632Sstever@eecs.umich.edu
2642632Sstever@eecs.umich.edu            if (!kernel->loadLocalSymbols(debugSymbolTable))
2652632Sstever@eecs.umich.edu                fatal("could not load kernel local symbols\n");
2662632Sstever@eecs.umich.edu
2678268Ssteve.reinhardt@amd.com            DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
2688268Ssteve.reinhardt@amd.com            DPRINTF(Loader, "Kernel end   = %#x\n", kernelEnd);
2698268Ssteve.reinhardt@amd.com            DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry);
2708268Ssteve.reinhardt@amd.com            DPRINTF(Loader, "Kernel loaded...\n");
2718268Ssteve.reinhardt@amd.com        }
2728268Ssteve.reinhardt@amd.com    }
2738268Ssteve.reinhardt@amd.com
2742632Sstever@eecs.umich.edu    // increment the number of running systms
2752632Sstever@eecs.umich.edu    numSystemsRunning++;
2762632Sstever@eecs.umich.edu
2772632Sstever@eecs.umich.edu    activeCpus.clear();
2788268Ssteve.reinhardt@amd.com
2792632Sstever@eecs.umich.edu    if (!FullSystem)
2808268Ssteve.reinhardt@amd.com        return;
2818268Ssteve.reinhardt@amd.com
2828268Ssteve.reinhardt@amd.com    for (i = 0; i < threadContexts.size(); i++)
2838268Ssteve.reinhardt@amd.com        TheISA::startupCPU(threadContexts[i], i);
2843718Sstever@eecs.umich.edu}
2852634Sstever@eecs.umich.edu
2862634Sstever@eecs.umich.eduvoid
2875863Snate@binkert.orgSystem::replaceThreadContext(ThreadContext *tc, int context_id)
2882638Sstever@eecs.umich.edu{
2898268Ssteve.reinhardt@amd.com    if (context_id >= threadContexts.size()) {
2902632Sstever@eecs.umich.edu        panic("replaceThreadContext: bad id, %d >= %d\n",
2912632Sstever@eecs.umich.edu              context_id, threadContexts.size());
2922632Sstever@eecs.umich.edu    }
2932632Sstever@eecs.umich.edu
2942632Sstever@eecs.umich.edu    threadContexts[context_id] = tc;
2951858SN/A    if (context_id < remoteGDB.size())
2963716Sstever@eecs.umich.edu        remoteGDB[context_id]->replaceThreadContext(tc);
2972638Sstever@eecs.umich.edu}
2982638Sstever@eecs.umich.edu
2992638Sstever@eecs.umich.eduAddr
3002638Sstever@eecs.umich.eduSystem::allocPhysPages(int npages)
3012638Sstever@eecs.umich.edu{
3022638Sstever@eecs.umich.edu    Addr return_addr = pagePtr << LogVMPageSize;
3032638Sstever@eecs.umich.edu    pagePtr += npages;
3045863Snate@binkert.org    if (pagePtr > physmem->size())
3055863Snate@binkert.org        fatal("Out of memory, please increase size of physical memory.");
3065863Snate@binkert.org    return return_addr;
307955SN/A}
3085341Sstever@gmail.com
3095341Sstever@gmail.comAddr
3105863Snate@binkert.orgSystem::memSize()
3117756SAli.Saidi@ARM.com{
3125341Sstever@gmail.com    return physmem->size();
3136121Snate@binkert.org}
3144494Ssaidi@eecs.umich.edu
3156121Snate@binkert.orgAddr
3161105SN/ASystem::freeMemSize()
3172667Sstever@eecs.umich.edu{
3182667Sstever@eecs.umich.edu   return physmem->size() - (pagePtr << LogVMPageSize);
3192667Sstever@eecs.umich.edu}
3202667Sstever@eecs.umich.edu
3216121Snate@binkert.orgbool
3222667Sstever@eecs.umich.eduSystem::isMemory(const Addr addr) const
3235341Sstever@gmail.com{
3245863Snate@binkert.org    std::list<Range<Addr> >::const_iterator i;
3255341Sstever@gmail.com    for (i = memRanges.begin(); i != memRanges.end(); i++) {
3265341Sstever@gmail.com        if (*i == addr)
3275341Sstever@gmail.com            return true;
3288120Sgblack@eecs.umich.edu    }
3295341Sstever@gmail.com    return false;
3308120Sgblack@eecs.umich.edu}
3315341Sstever@gmail.com
3328120Sgblack@eecs.umich.eduvoid
3336121Snate@binkert.orgSystem::resume()
3346121Snate@binkert.org{
3355397Ssaidi@eecs.umich.edu    SimObject::resume();
3365397Ssaidi@eecs.umich.edu    totalNumInsts = 0;
3377727SAli.Saidi@ARM.com}
3388268Ssteve.reinhardt@amd.com
3396168Snate@binkert.orgvoid
3405341Sstever@gmail.comSystem::serialize(ostream &os)
3418120Sgblack@eecs.umich.edu{
3428120Sgblack@eecs.umich.edu    if (FullSystem)
3438120Sgblack@eecs.umich.edu        kernelSymtab->serialize("kernel_symtab", os);
3446814Sgblack@eecs.umich.edu    SERIALIZE_SCALAR(pagePtr);
3455863Snate@binkert.org    SERIALIZE_SCALAR(nextPID);
3468120Sgblack@eecs.umich.edu}
3475341Sstever@gmail.com
3485863Snate@binkert.org
3498268Ssteve.reinhardt@amd.comvoid
3506121Snate@binkert.orgSystem::unserialize(Checkpoint *cp, const string &section)
3516121Snate@binkert.org{
3528268Ssteve.reinhardt@amd.com    if (FullSystem)
3535742Snate@binkert.org        kernelSymtab->unserialize("kernel_symtab", cp, section);
3545742Snate@binkert.org    UNSERIALIZE_SCALAR(pagePtr);
3555341Sstever@gmail.com    UNSERIALIZE_SCALAR(nextPID);
3565742Snate@binkert.org}
3575742Snate@binkert.org
3585341Sstever@gmail.comvoid
3596017Snate@binkert.orgSystem::regStats()
3606121Snate@binkert.org{
3616017Snate@binkert.org    for (uint32_t j = 0; j < numWorkIds ; j++) {
3627816Ssteve.reinhardt@amd.com        workItemStats[j] = new Stats::Histogram();
3637756SAli.Saidi@ARM.com        stringstream namestr;
3647756SAli.Saidi@ARM.com        ccprintf(namestr, "work_item_type%d", j);
3657756SAli.Saidi@ARM.com        workItemStats[j]->init(20)
3667756SAli.Saidi@ARM.com                         .name(name() + "." + namestr.str())
3677756SAli.Saidi@ARM.com                         .desc("Run time stat for" + namestr.str())
3687756SAli.Saidi@ARM.com                         .prereq(*workItemStats[j]);
3697756SAli.Saidi@ARM.com    }
3707756SAli.Saidi@ARM.com}
3717816Ssteve.reinhardt@amd.com
3727816Ssteve.reinhardt@amd.comvoid
3737816Ssteve.reinhardt@amd.comSystem::workItemEnd(uint32_t tid, uint32_t workid)
3747816Ssteve.reinhardt@amd.com{
3757816Ssteve.reinhardt@amd.com    std::pair<uint32_t,uint32_t> p(tid, workid);
3767816Ssteve.reinhardt@amd.com    if (!lastWorkItemStarted.count(p))
3777816Ssteve.reinhardt@amd.com        return;
3787816Ssteve.reinhardt@amd.com
3797816Ssteve.reinhardt@amd.com    Tick samp = curTick() - lastWorkItemStarted[p];
3807816Ssteve.reinhardt@amd.com    DPRINTF(WorkItems, "Work item end: %d\t%d\t%lld\n", tid, workid, samp);
3817756SAli.Saidi@ARM.com
3827816Ssteve.reinhardt@amd.com    if (workid >= numWorkIds)
3837816Ssteve.reinhardt@amd.com        fatal("Got workid greater than specified in system configuration\n");
3847816Ssteve.reinhardt@amd.com
3857816Ssteve.reinhardt@amd.com    workItemStats[workid]->sample(samp);
3867816Ssteve.reinhardt@amd.com    lastWorkItemStarted.erase(p);
3877816Ssteve.reinhardt@amd.com}
3887816Ssteve.reinhardt@amd.com
3897816Ssteve.reinhardt@amd.comvoid
3907816Ssteve.reinhardt@amd.comSystem::printSystems()
3917816Ssteve.reinhardt@amd.com{
3927816Ssteve.reinhardt@amd.com    vector<System *>::iterator i = systemList.begin();
3937816Ssteve.reinhardt@amd.com    vector<System *>::iterator end = systemList.end();
3947816Ssteve.reinhardt@amd.com    for (; i != end; ++i) {
3957816Ssteve.reinhardt@amd.com        System *sys = *i;
3967816Ssteve.reinhardt@amd.com        cerr << "System " << sys->name() << ": " << hex << sys << endl;
3977816Ssteve.reinhardt@amd.com    }
3987816Ssteve.reinhardt@amd.com}
3997816Ssteve.reinhardt@amd.com
4007816Ssteve.reinhardt@amd.comvoid
4017816Ssteve.reinhardt@amd.comprintSystems()
4027816Ssteve.reinhardt@amd.com{
4037816Ssteve.reinhardt@amd.com    System::printSystems();
4047816Ssteve.reinhardt@amd.com}
4057816Ssteve.reinhardt@amd.com
4067816Ssteve.reinhardt@amd.comMasterID
4077816Ssteve.reinhardt@amd.comSystem::getMasterId(std::string master_name)
4087816Ssteve.reinhardt@amd.com{
4097816Ssteve.reinhardt@amd.com    // strip off system name if the string starts with it
4107816Ssteve.reinhardt@amd.com    if (master_name.size() > name().size() &&
4117816Ssteve.reinhardt@amd.com                          master_name.compare(0, name().size(), name()) == 0)
4127816Ssteve.reinhardt@amd.com        master_name = master_name.erase(0, name().size() + 1);
4137816Ssteve.reinhardt@amd.com
4147816Ssteve.reinhardt@amd.com    // CPUs in switch_cpus ask for ids again after switching
4157816Ssteve.reinhardt@amd.com    for (int i = 0; i < masterIds.size(); i++) {
4167816Ssteve.reinhardt@amd.com        if (masterIds[i] == master_name) {
4177816Ssteve.reinhardt@amd.com            return i;
4187816Ssteve.reinhardt@amd.com        }
4197816Ssteve.reinhardt@amd.com    }
4207816Ssteve.reinhardt@amd.com
4217816Ssteve.reinhardt@amd.com    // todo: Check if stats are enabled yet
4227816Ssteve.reinhardt@amd.com    // I just don't know a good way to do it
4237816Ssteve.reinhardt@amd.com
4247816Ssteve.reinhardt@amd.com    if (false)
4257816Ssteve.reinhardt@amd.com        fatal("Can't request a masterId after regStats(). \
4267816Ssteve.reinhardt@amd.com                You must do so in init().\n");
4277816Ssteve.reinhardt@amd.com
4287816Ssteve.reinhardt@amd.com    masterIds.push_back(master_name);
4297816Ssteve.reinhardt@amd.com
4307816Ssteve.reinhardt@amd.com    return masterIds.size() - 1;
4317816Ssteve.reinhardt@amd.com}
4327816Ssteve.reinhardt@amd.com
4337816Ssteve.reinhardt@amd.comstd::string
4347816Ssteve.reinhardt@amd.comSystem::getMasterName(MasterID master_id)
4357816Ssteve.reinhardt@amd.com{
4367816Ssteve.reinhardt@amd.com    if (master_id >= masterIds.size())
4377816Ssteve.reinhardt@amd.com        fatal("Invalid master_id passed to getMasterName()\n");
4387816Ssteve.reinhardt@amd.com
4397816Ssteve.reinhardt@amd.com    return masterIds[master_id];
4407816Ssteve.reinhardt@amd.com}
4417816Ssteve.reinhardt@amd.com
4427816Ssteve.reinhardt@amd.comconst char *System::MemoryModeStrings[3] = {"invalid", "atomic",
4437756SAli.Saidi@ARM.com    "timing"};
4448120Sgblack@eecs.umich.edu
4457756SAli.Saidi@ARM.comSystem *
4467756SAli.Saidi@ARM.comSystemParams::create()
4477756SAli.Saidi@ARM.com{
4487756SAli.Saidi@ARM.com    return new System(this);
4497816Ssteve.reinhardt@amd.com}
4507816Ssteve.reinhardt@amd.com