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 §ion) 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