system.cc revision 12272:bcc67ee98e6d
113558Snikos.nikoleris@arm.com/* 28839Sandreas.hansson@arm.com * Copyright (c) 2011-2014,2017 ARM Limited 38839Sandreas.hansson@arm.com * All rights reserved 48839Sandreas.hansson@arm.com * 58839Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 68839Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 78839Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 88839Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 98839Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 108839Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 118839Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 128839Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 133101Sstever@eecs.umich.edu * 148579Ssteve.reinhardt@amd.com * Copyright (c) 2003-2006 The Regents of The University of Michigan 153101Sstever@eecs.umich.edu * Copyright (c) 2011 Regents of the University of California 163101Sstever@eecs.umich.edu * All rights reserved. 173101Sstever@eecs.umich.edu * 183101Sstever@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 193101Sstever@eecs.umich.edu * modification, are permitted provided that the following conditions are 203101Sstever@eecs.umich.edu * met: redistributions of source code must retain the above copyright 213101Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 223101Sstever@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 233101Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 243101Sstever@eecs.umich.edu * documentation and/or other materials provided with the distribution; 253101Sstever@eecs.umich.edu * neither the name of the copyright holders nor the names of its 263101Sstever@eecs.umich.edu * contributors may be used to endorse or promote products derived from 273101Sstever@eecs.umich.edu * this software without specific prior written permission. 283101Sstever@eecs.umich.edu * 293101Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 303101Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 313101Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 323101Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 333101Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 343101Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 353101Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 363101Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 373101Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 383101Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 393101Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 403101Sstever@eecs.umich.edu * 413101Sstever@eecs.umich.edu * Authors: Steve Reinhardt 427778Sgblack@eecs.umich.edu * Lisa Hsu 438839Sandreas.hansson@arm.com * Nathan Binkert 443101Sstever@eecs.umich.edu * Ali Saidi 453101Sstever@eecs.umich.edu * Rick Strong 463101Sstever@eecs.umich.edu */ 473101Sstever@eecs.umich.edu 483101Sstever@eecs.umich.edu#include "sim/system.hh" 493101Sstever@eecs.umich.edu 503101Sstever@eecs.umich.edu#include "arch/remote_gdb.hh" 513101Sstever@eecs.umich.edu#include "arch/utility.hh" 523101Sstever@eecs.umich.edu#include "base/loader/object_file.hh" 533101Sstever@eecs.umich.edu#include "base/loader/symtab.hh" 543101Sstever@eecs.umich.edu#include "base/str.hh" 553101Sstever@eecs.umich.edu#include "base/trace.hh" 563101Sstever@eecs.umich.edu#include "config/use_kvm.hh" 573101Sstever@eecs.umich.edu#if USE_KVM 583101Sstever@eecs.umich.edu#include "cpu/kvm/base.hh" 593101Sstever@eecs.umich.edu#include "cpu/kvm/vm.hh" 603101Sstever@eecs.umich.edu#endif 613101Sstever@eecs.umich.edu#include "cpu/base.hh" 6212563Sgabeblack@google.com#include "cpu/thread_context.hh" 6312563Sgabeblack@google.com#include "debug/Loader.hh" 643885Sbinkertn@umich.edu#include "debug/WorkItems.hh" 653885Sbinkertn@umich.edu#include "mem/abstract_mem.hh" 664762Snate@binkert.org#include "mem/physical.hh" 673885Sbinkertn@umich.edu#include "params/System.hh" 683885Sbinkertn@umich.edu#include "sim/byteswap.hh" 697528Ssteve.reinhardt@amd.com#include "sim/debug.hh" 703885Sbinkertn@umich.edu#include "sim/full_system.hh" 714380Sbinkertn@umich.edu 724167Sbinkertn@umich.edu/** 733102Sstever@eecs.umich.edu * To avoid linking errors with LTO, only include the header if we 743101Sstever@eecs.umich.edu * actually have a definition. 754762Snate@binkert.org */ 764762Snate@binkert.org#if THE_ISA != NULL_ISA 774762Snate@binkert.org#include "kern/kernel_stats.hh" 784762Snate@binkert.org 794762Snate@binkert.org#endif 804762Snate@binkert.org 814762Snate@binkert.orgusing namespace std; 824762Snate@binkert.orgusing namespace TheISA; 834762Snate@binkert.org 845033Smilesck@eecs.umich.eduvector<System *> System::systemList; 855033Smilesck@eecs.umich.edu 865033Smilesck@eecs.umich.eduint System::numSystemsRunning = 0; 875033Smilesck@eecs.umich.edu 885033Smilesck@eecs.umich.eduSystem::System(Params *p) 895033Smilesck@eecs.umich.edu : MemObject(p), _systemPort("system_port", this), 905033Smilesck@eecs.umich.edu _numContexts(0), 915033Smilesck@eecs.umich.edu multiThread(p->multi_thread), 925033Smilesck@eecs.umich.edu pagePtr(0), 935033Smilesck@eecs.umich.edu init_param(p->init_param), 943101Sstever@eecs.umich.edu physProxy(_systemPort, p->cache_line_size), 953101Sstever@eecs.umich.edu kernelSymtab(nullptr), 963101Sstever@eecs.umich.edu kernel(nullptr), 975033Smilesck@eecs.umich.edu loadAddrMask(p->load_addr_mask), 9810267SGeoffrey.Blake@arm.com loadAddrOffset(p->load_offset), 998596Ssteve.reinhardt@amd.com#if USE_KVM 1008596Ssteve.reinhardt@amd.com kvmVM(p->kvm_vm), 1018596Ssteve.reinhardt@amd.com#else 1028596Ssteve.reinhardt@amd.com kvmVM(nullptr), 1037673Snate@binkert.org#endif 1047673Snate@binkert.org physmem(name() + ".physmem", p->memories, p->mmap_using_noreserve), 1057673Snate@binkert.org memoryMode(p->mem_mode), 1067673Snate@binkert.org _cacheLineSize(p->cache_line_size), 10711988Sandreas.sandberg@arm.com workItemsBegin(0), 10811988Sandreas.sandberg@arm.com workItemsEnd(0), 10911988Sandreas.sandberg@arm.com numWorkIds(p->num_work_ids), 11011988Sandreas.sandberg@arm.com thermalModel(p->thermal_model), 1113101Sstever@eecs.umich.edu _params(p), 1123101Sstever@eecs.umich.edu totalNumInsts(0), 1133101Sstever@eecs.umich.edu instEventQueue("system instruction-based event queue") 1143101Sstever@eecs.umich.edu{ 1153101Sstever@eecs.umich.edu // add self to global system list 11610380SAndrew.Bardsley@arm.com systemList.push_back(this); 11710380SAndrew.Bardsley@arm.com 11810380SAndrew.Bardsley@arm.com#if USE_KVM 11910380SAndrew.Bardsley@arm.com if (kvmVM) { 12010380SAndrew.Bardsley@arm.com kvmVM->setSystem(this); 12110380SAndrew.Bardsley@arm.com } 12210458Sandreas.hansson@arm.com#endif 12310458Sandreas.hansson@arm.com 12410458Sandreas.hansson@arm.com if (FullSystem) { 12510458Sandreas.hansson@arm.com kernelSymtab = new SymbolTable; 12610458Sandreas.hansson@arm.com if (!debugSymbolTable) 12710458Sandreas.hansson@arm.com debugSymbolTable = new SymbolTable; 12810458Sandreas.hansson@arm.com } 12910458Sandreas.hansson@arm.com 13010458Sandreas.hansson@arm.com // check if the cache line size is a value known to work 13110458Sandreas.hansson@arm.com if (!(_cacheLineSize == 16 || _cacheLineSize == 32 || 13210458Sandreas.hansson@arm.com _cacheLineSize == 64 || _cacheLineSize == 128)) 13310458Sandreas.hansson@arm.com warn_once("Cache line size is neither 16, 32, 64 nor 128 bytes.\n"); 1343101Sstever@eecs.umich.edu 1353101Sstever@eecs.umich.edu // Get the generic system master IDs 1363101Sstever@eecs.umich.edu MasterID tmp_id M5_VAR_USED; 1373101Sstever@eecs.umich.edu tmp_id = getMasterId("writebacks"); 1383101Sstever@eecs.umich.edu assert(tmp_id == Request::wbMasterId); 13910267SGeoffrey.Blake@arm.com tmp_id = getMasterId("functional"); 14010267SGeoffrey.Blake@arm.com assert(tmp_id == Request::funcMasterId); 14110267SGeoffrey.Blake@arm.com tmp_id = getMasterId("interrupt"); 14210267SGeoffrey.Blake@arm.com assert(tmp_id == Request::intMasterId); 1433101Sstever@eecs.umich.edu 1443101Sstever@eecs.umich.edu if (FullSystem) { 1453101Sstever@eecs.umich.edu if (params()->kernel == "") { 1463101Sstever@eecs.umich.edu inform("No kernel set for full system simulation. " 1473101Sstever@eecs.umich.edu "Assuming you know what you're doing\n"); 1483101Sstever@eecs.umich.edu } else { 1493101Sstever@eecs.umich.edu // Get the kernel code 1503101Sstever@eecs.umich.edu kernel = createObjectFile(params()->kernel); 1513101Sstever@eecs.umich.edu inform("kernel located at: %s", params()->kernel); 1523101Sstever@eecs.umich.edu 1533101Sstever@eecs.umich.edu if (kernel == NULL) 1543101Sstever@eecs.umich.edu fatal("Could not load kernel file %s", params()->kernel); 1553101Sstever@eecs.umich.edu 1563101Sstever@eecs.umich.edu // setup entry points 1573101Sstever@eecs.umich.edu kernelStart = kernel->textBase(); 15813663Sandreas.sandberg@arm.com kernelEnd = kernel->bssBase() + kernel->bssSize(); 1593101Sstever@eecs.umich.edu kernelEntry = kernel->entryPoint(); 16013675Sandreas.sandberg@arm.com 1613101Sstever@eecs.umich.edu // If load_addr_mask is set to 0x0, then auto-calculate 1623101Sstever@eecs.umich.edu // the smallest mask to cover all kernel addresses so gem5 1633101Sstever@eecs.umich.edu // can relocate the kernel to a new offset. 1643101Sstever@eecs.umich.edu if (loadAddrMask == 0) { 16513675Sandreas.sandberg@arm.com Addr shift_amt = findMsbSet(kernelEnd - kernelStart) + 1; 1663101Sstever@eecs.umich.edu loadAddrMask = ((Addr)1 << shift_amt) - 1; 1673101Sstever@eecs.umich.edu } 1683101Sstever@eecs.umich.edu 1693101Sstever@eecs.umich.edu // load symbols 1703101Sstever@eecs.umich.edu if (!kernel->loadGlobalSymbols(kernelSymtab)) 17113663Sandreas.sandberg@arm.com fatal("could not load kernel symbols\n"); 1723101Sstever@eecs.umich.edu 1733101Sstever@eecs.umich.edu if (!kernel->loadLocalSymbols(kernelSymtab)) 17413663Sandreas.sandberg@arm.com fatal("could not load kernel local symbols\n"); 1753101Sstever@eecs.umich.edu 1763101Sstever@eecs.umich.edu if (!kernel->loadGlobalSymbols(debugSymbolTable)) 1773101Sstever@eecs.umich.edu fatal("could not load kernel symbols\n"); 1785033Smilesck@eecs.umich.edu 1796656Snate@binkert.org if (!kernel->loadLocalSymbols(debugSymbolTable)) 1805033Smilesck@eecs.umich.edu fatal("could not load kernel local symbols\n"); 1815033Smilesck@eecs.umich.edu 1825033Smilesck@eecs.umich.edu // Loading only needs to happen once and after memory system is 18313663Sandreas.sandberg@arm.com // connected so it will happen in initState() 18413663Sandreas.sandberg@arm.com } 1853101Sstever@eecs.umich.edu 18610267SGeoffrey.Blake@arm.com for (const auto &obj_name : p->kernel_extras) { 18710267SGeoffrey.Blake@arm.com inform("Loading additional kernel object: %s", obj_name); 18810267SGeoffrey.Blake@arm.com ObjectFile *obj = createObjectFile(obj_name); 18910267SGeoffrey.Blake@arm.com fatal_if(!obj, "Failed to additional kernel object '%s'.\n", 19010267SGeoffrey.Blake@arm.com obj_name); 19110267SGeoffrey.Blake@arm.com kernelExtras.push_back(obj); 19210267SGeoffrey.Blake@arm.com } 19310267SGeoffrey.Blake@arm.com } 19410267SGeoffrey.Blake@arm.com 19510267SGeoffrey.Blake@arm.com // increment the number of running systems 19610267SGeoffrey.Blake@arm.com numSystemsRunning++; 19710267SGeoffrey.Blake@arm.com 19810267SGeoffrey.Blake@arm.com // Set back pointers to the system in all memories 1993101Sstever@eecs.umich.edu for (int x = 0; x < params()->memories.size(); x++) 2003101Sstever@eecs.umich.edu params()->memories[x]->system(this); 2013101Sstever@eecs.umich.edu} 2023101Sstever@eecs.umich.edu 20313699Sandreas.sandberg@arm.comSystem::~System() 2043101Sstever@eecs.umich.edu{ 2053101Sstever@eecs.umich.edu delete kernelSymtab; 2063101Sstever@eecs.umich.edu delete kernel; 2073101Sstever@eecs.umich.edu 2083101Sstever@eecs.umich.edu for (uint32_t j = 0; j < numWorkIds; j++) 2093102Sstever@eecs.umich.edu delete workItemStats[j]; 2103101Sstever@eecs.umich.edu} 2113101Sstever@eecs.umich.edu 2123101Sstever@eecs.umich.eduvoid 21310267SGeoffrey.Blake@arm.comSystem::init() 21410267SGeoffrey.Blake@arm.com{ 21510267SGeoffrey.Blake@arm.com // check that the system port is connected 21610267SGeoffrey.Blake@arm.com if (!_systemPort.isConnected()) 21710267SGeoffrey.Blake@arm.com panic("System port on %s is not connected.\n", name()); 21810267SGeoffrey.Blake@arm.com} 21910267SGeoffrey.Blake@arm.com 2207673Snate@binkert.orgBaseMasterPort& 2218607Sgblack@eecs.umich.eduSystem::getMasterPort(const std::string &if_name, PortID idx) 2227673Snate@binkert.org{ 2233101Sstever@eecs.umich.edu // no need to distinguish at the moment (besides checking) 22411988Sandreas.sandberg@arm.com return _systemPort; 22511988Sandreas.sandberg@arm.com} 22611988Sandreas.sandberg@arm.com 2277673Snate@binkert.orgvoid 2287673Snate@binkert.orgSystem::setMemoryMode(Enums::MemoryMode mode) 2293101Sstever@eecs.umich.edu{ 2303101Sstever@eecs.umich.edu assert(drainState() == DrainState::Drained); 2313101Sstever@eecs.umich.edu memoryMode = mode; 2323101Sstever@eecs.umich.edu} 2333101Sstever@eecs.umich.edu 2343101Sstever@eecs.umich.edubool System::breakpoint() 2355033Smilesck@eecs.umich.edu{ 2365475Snate@binkert.org if (remoteGDB.size()) 23713663Sandreas.sandberg@arm.com return remoteGDB[0]->breakpoint(); 23813663Sandreas.sandberg@arm.com return false; 2395475Snate@binkert.org} 24010380SAndrew.Bardsley@arm.com 24110380SAndrew.Bardsley@arm.comContextID 24210380SAndrew.Bardsley@arm.comSystem::registerThreadContext(ThreadContext *tc, ContextID assigned) 2433101Sstever@eecs.umich.edu{ 2443101Sstever@eecs.umich.edu int id; 2453101Sstever@eecs.umich.edu if (assigned == InvalidContextID) { 2464762Snate@binkert.org for (id = 0; id < threadContexts.size(); id++) { 2474762Snate@binkert.org if (!threadContexts[id]) 2484762Snate@binkert.org break; 2493101Sstever@eecs.umich.edu } 25012050Snikos.nikoleris@arm.com 25112050Snikos.nikoleris@arm.com if (threadContexts.size() <= id) 25212050Snikos.nikoleris@arm.com threadContexts.resize(id + 1); 2538459SAli.Saidi@ARM.com } else { 2548459SAli.Saidi@ARM.com if (threadContexts.size() <= assigned) 25512050Snikos.nikoleris@arm.com threadContexts.resize(assigned + 1); 2563101Sstever@eecs.umich.edu id = assigned; 2577528Ssteve.reinhardt@amd.com } 2587528Ssteve.reinhardt@amd.com 2597528Ssteve.reinhardt@amd.com if (threadContexts[id]) 2607528Ssteve.reinhardt@amd.com fatal("Cannot have two CPUs with the same id (%d)\n", id); 2617528Ssteve.reinhardt@amd.com 2627528Ssteve.reinhardt@amd.com threadContexts[id] = tc; 2633101Sstever@eecs.umich.edu _numContexts++; 2647528Ssteve.reinhardt@amd.com 2657528Ssteve.reinhardt@amd.com#if THE_ISA != NULL_ISA 2667528Ssteve.reinhardt@amd.com int port = getRemoteGDBPort(); 2677528Ssteve.reinhardt@amd.com if (port) { 2687528Ssteve.reinhardt@amd.com RemoteGDB *rgdb = new RemoteGDB(this, tc); 2697528Ssteve.reinhardt@amd.com GDBListener *gdbl = new GDBListener(rgdb, port + id); 2707528Ssteve.reinhardt@amd.com gdbl->listen(); 2717528Ssteve.reinhardt@amd.com 2727528Ssteve.reinhardt@amd.com BaseCPU *cpu = tc->getCpuPtr(); 2737528Ssteve.reinhardt@amd.com if (cpu->waitForRemoteGDB()) { 2748321Ssteve.reinhardt@amd.com inform("%s: Waiting for a remote GDB connection on port %d.\n", 27512194Sgabeblack@google.com cpu->name(), gdbl->getPort()); 2767528Ssteve.reinhardt@amd.com 2777528Ssteve.reinhardt@amd.com gdbl->accept(); 2787528Ssteve.reinhardt@amd.com } 2797528Ssteve.reinhardt@amd.com if (remoteGDB.size() <= id) { 2807528Ssteve.reinhardt@amd.com remoteGDB.resize(id + 1); 2817528Ssteve.reinhardt@amd.com } 2827528Ssteve.reinhardt@amd.com 2837528Ssteve.reinhardt@amd.com remoteGDB[id] = rgdb; 2847528Ssteve.reinhardt@amd.com } 2857528Ssteve.reinhardt@amd.com#endif 2867528Ssteve.reinhardt@amd.com 2877528Ssteve.reinhardt@amd.com activeCpus.push_back(false); 2887528Ssteve.reinhardt@amd.com 2893101Sstever@eecs.umich.edu return id; 2908664SAli.Saidi@ARM.com} 2918664SAli.Saidi@ARM.com 2928664SAli.Saidi@ARM.comint 2938664SAli.Saidi@ARM.comSystem::numRunningContexts() 2948664SAli.Saidi@ARM.com{ 2958664SAli.Saidi@ARM.com int running = 0; 2969953Sgeoffrey.blake@arm.com for (int i = 0; i < _numContexts; ++i) { 2979953Sgeoffrey.blake@arm.com if (threadContexts[i]->status() != ThreadContext::Halted) 2989953Sgeoffrey.blake@arm.com ++running; 2999953Sgeoffrey.blake@arm.com } 3009953Sgeoffrey.blake@arm.com return running; 3019953Sgeoffrey.blake@arm.com} 3029953Sgeoffrey.blake@arm.com 3039953Sgeoffrey.blake@arm.comvoid 3049953Sgeoffrey.blake@arm.comSystem::initState() 3059953Sgeoffrey.blake@arm.com{ 3069953Sgeoffrey.blake@arm.com if (FullSystem) { 3079953Sgeoffrey.blake@arm.com for (int i = 0; i < threadContexts.size(); i++) 3089953Sgeoffrey.blake@arm.com TheISA::startupCPU(threadContexts[i], i); 30910267SGeoffrey.Blake@arm.com // Moved from the constructor to here since it relies on the 31010267SGeoffrey.Blake@arm.com // address map being resolved in the interconnect 31110267SGeoffrey.Blake@arm.com /** 31210267SGeoffrey.Blake@arm.com * Load the kernel code into memory 31310267SGeoffrey.Blake@arm.com */ 31410267SGeoffrey.Blake@arm.com if (params()->kernel != "") { 31510267SGeoffrey.Blake@arm.com if (params()->kernel_addr_check) { 31612563Sgabeblack@google.com // Validate kernel mapping before loading binary 31710267SGeoffrey.Blake@arm.com if (!(isMemAddr((kernelStart & loadAddrMask) + 31810267SGeoffrey.Blake@arm.com loadAddrOffset) && 31910267SGeoffrey.Blake@arm.com isMemAddr((kernelEnd & loadAddrMask) + 32010267SGeoffrey.Blake@arm.com loadAddrOffset))) { 32110267SGeoffrey.Blake@arm.com fatal("Kernel is mapped to invalid location (not memory). " 32210267SGeoffrey.Blake@arm.com "kernelStart 0x(%x) - kernelEnd 0x(%x) %#x:%#x\n", 32310267SGeoffrey.Blake@arm.com kernelStart, 32410267SGeoffrey.Blake@arm.com kernelEnd, (kernelStart & loadAddrMask) + 32510267SGeoffrey.Blake@arm.com loadAddrOffset, 32610267SGeoffrey.Blake@arm.com (kernelEnd & loadAddrMask) + loadAddrOffset); 32710267SGeoffrey.Blake@arm.com } 32810267SGeoffrey.Blake@arm.com } 3293101Sstever@eecs.umich.edu // Load program sections into memory 3303101Sstever@eecs.umich.edu kernel->loadSections(physProxy, loadAddrMask, loadAddrOffset); 3313101Sstever@eecs.umich.edu for (const auto &extra_kernel : kernelExtras) { 3323101Sstever@eecs.umich.edu extra_kernel->loadSections(physProxy, loadAddrMask, 3333101Sstever@eecs.umich.edu loadAddrOffset); 3343101Sstever@eecs.umich.edu } 3353101Sstever@eecs.umich.edu 33610364SGeoffrey.Blake@arm.com DPRINTF(Loader, "Kernel start = %#x\n", kernelStart); 33710364SGeoffrey.Blake@arm.com DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd); 33810364SGeoffrey.Blake@arm.com DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry); 33910364SGeoffrey.Blake@arm.com DPRINTF(Loader, "Kernel loaded...\n"); 3403101Sstever@eecs.umich.edu } 3414762Snate@binkert.org } 3424762Snate@binkert.org} 3434762Snate@binkert.org 3444762Snate@binkert.orgvoid 3457528Ssteve.reinhardt@amd.comSystem::replaceThreadContext(ThreadContext *tc, ContextID context_id) 3464762Snate@binkert.org{ 3474762Snate@binkert.org if (context_id >= threadContexts.size()) { 3484762Snate@binkert.org panic("replaceThreadContext: bad id, %d >= %d\n", 34910267SGeoffrey.Blake@arm.com context_id, threadContexts.size()); 35010267SGeoffrey.Blake@arm.com } 35110267SGeoffrey.Blake@arm.com 35210267SGeoffrey.Blake@arm.com threadContexts[context_id] = tc; 35310267SGeoffrey.Blake@arm.com if (context_id < remoteGDB.size()) 35410267SGeoffrey.Blake@arm.com remoteGDB[context_id]->replaceThreadContext(tc); 35510267SGeoffrey.Blake@arm.com} 35610267SGeoffrey.Blake@arm.com 35710267SGeoffrey.Blake@arm.combool 35810267SGeoffrey.Blake@arm.comSystem::validKvmEnvironment() const 35910267SGeoffrey.Blake@arm.com{ 36010267SGeoffrey.Blake@arm.com#if USE_KVM 36110267SGeoffrey.Blake@arm.com if (threadContexts.empty()) 36210267SGeoffrey.Blake@arm.com return false; 36310267SGeoffrey.Blake@arm.com 36410267SGeoffrey.Blake@arm.com for (auto tc : threadContexts) { 36510267SGeoffrey.Blake@arm.com if (dynamic_cast<BaseKvmCPU*>(tc->getCpuPtr()) == nullptr) { 36610267SGeoffrey.Blake@arm.com return false; 36710267SGeoffrey.Blake@arm.com } 36810267SGeoffrey.Blake@arm.com } 36910267SGeoffrey.Blake@arm.com return true; 37010267SGeoffrey.Blake@arm.com#else 37110267SGeoffrey.Blake@arm.com return false; 37210267SGeoffrey.Blake@arm.com#endif 37310267SGeoffrey.Blake@arm.com} 37410267SGeoffrey.Blake@arm.com 37510364SGeoffrey.Blake@arm.comAddr 37610364SGeoffrey.Blake@arm.comSystem::allocPhysPages(int npages) 37710267SGeoffrey.Blake@arm.com{ 37810267SGeoffrey.Blake@arm.com Addr return_addr = pagePtr << PageShift; 37910267SGeoffrey.Blake@arm.com pagePtr += npages; 38010267SGeoffrey.Blake@arm.com 38110267SGeoffrey.Blake@arm.com Addr next_return_addr = pagePtr << PageShift; 38210267SGeoffrey.Blake@arm.com 3837673Snate@binkert.org AddrRange m5opRange(0xffff0000, 0xffffffff); 3847673Snate@binkert.org if (m5opRange.contains(next_return_addr)) { 3857673Snate@binkert.org warn("Reached m5ops MMIO region\n"); 3863101Sstever@eecs.umich.edu return_addr = 0xffffffff; 38711988Sandreas.sandberg@arm.com pagePtr = 0xffffffff >> PageShift; 38811988Sandreas.sandberg@arm.com } 38911988Sandreas.sandberg@arm.com 39011988Sandreas.sandberg@arm.com if ((pagePtr << PageShift) > physmem.totalSize()) 3917673Snate@binkert.org fatal("Out of memory, please increase size of physical memory."); 3927673Snate@binkert.org return return_addr; 3933101Sstever@eecs.umich.edu} 3943101Sstever@eecs.umich.edu 3953101Sstever@eecs.umich.eduAddr 3963101Sstever@eecs.umich.eduSystem::memSize() const 3973101Sstever@eecs.umich.edu{ 3983101Sstever@eecs.umich.edu return physmem.totalSize(); 3993101Sstever@eecs.umich.edu} 4003101Sstever@eecs.umich.edu 4013101Sstever@eecs.umich.eduAddr 4023101Sstever@eecs.umich.eduSystem::freeMemSize() const 4033101Sstever@eecs.umich.edu{ 4043101Sstever@eecs.umich.edu return physmem.totalSize() - (pagePtr << PageShift); 4053101Sstever@eecs.umich.edu} 4063101Sstever@eecs.umich.edu 4073101Sstever@eecs.umich.edubool 4085033Smilesck@eecs.umich.eduSystem::isMemAddr(Addr addr) const 4095033Smilesck@eecs.umich.edu{ 4103101Sstever@eecs.umich.edu return physmem.isMemAddr(addr); 4113101Sstever@eecs.umich.edu} 4123101Sstever@eecs.umich.edu 4133101Sstever@eecs.umich.eduvoid 4143101Sstever@eecs.umich.eduSystem::drainResume() 4153101Sstever@eecs.umich.edu{ 4163101Sstever@eecs.umich.edu totalNumInsts = 0; 4173101Sstever@eecs.umich.edu} 4183101Sstever@eecs.umich.edu 4193101Sstever@eecs.umich.eduvoid 4203101Sstever@eecs.umich.eduSystem::serialize(CheckpointOut &cp) const 4213101Sstever@eecs.umich.edu{ 4223101Sstever@eecs.umich.edu if (FullSystem) 4233101Sstever@eecs.umich.edu kernelSymtab->serialize("kernel_symtab", cp); 4243101Sstever@eecs.umich.edu SERIALIZE_SCALAR(pagePtr); 4253101Sstever@eecs.umich.edu serializeSymtab(cp); 4263101Sstever@eecs.umich.edu 4273101Sstever@eecs.umich.edu // also serialize the memories in the system 4283101Sstever@eecs.umich.edu physmem.serializeSection(cp, "physmem"); 4293101Sstever@eecs.umich.edu} 4303101Sstever@eecs.umich.edu 4313101Sstever@eecs.umich.edu 4323101Sstever@eecs.umich.eduvoid 4333101Sstever@eecs.umich.eduSystem::unserialize(CheckpointIn &cp) 4343101Sstever@eecs.umich.edu{ 43510267SGeoffrey.Blake@arm.com if (FullSystem) 4367673Snate@binkert.org kernelSymtab->unserialize("kernel_symtab", cp); 4377673Snate@binkert.org UNSERIALIZE_SCALAR(pagePtr); 4387673Snate@binkert.org unserializeSymtab(cp); 4397673Snate@binkert.org 4407673Snate@binkert.org // also unserialize the memories in the system 44110267SGeoffrey.Blake@arm.com physmem.unserializeSection(cp, "physmem"); 44210267SGeoffrey.Blake@arm.com} 44310267SGeoffrey.Blake@arm.com 44410267SGeoffrey.Blake@arm.comvoid 44510458Sandreas.hansson@arm.comSystem::regStats() 44610458Sandreas.hansson@arm.com{ 44710458Sandreas.hansson@arm.com MemObject::regStats(); 44810458Sandreas.hansson@arm.com 44910458Sandreas.hansson@arm.com for (uint32_t j = 0; j < numWorkIds ; j++) { 4504762Snate@binkert.org workItemStats[j] = new Stats::Histogram(); 4514762Snate@binkert.org stringstream namestr; 4523101Sstever@eecs.umich.edu ccprintf(namestr, "work_item_type%d", j); 4533101Sstever@eecs.umich.edu workItemStats[j]->init(20) 4543101Sstever@eecs.umich.edu .name(name() + "." + namestr.str()) 4553101Sstever@eecs.umich.edu .desc("Run time stat for" + namestr.str()) 4563101Sstever@eecs.umich.edu .prereq(*workItemStats[j]); 4573101Sstever@eecs.umich.edu } 4583101Sstever@eecs.umich.edu} 4593101Sstever@eecs.umich.edu 4603101Sstever@eecs.umich.eduvoid 4613101Sstever@eecs.umich.eduSystem::workItemEnd(uint32_t tid, uint32_t workid) 4623101Sstever@eecs.umich.edu{ 4633714Sstever@eecs.umich.edu std::pair<uint32_t,uint32_t> p(tid, workid); 4643714Sstever@eecs.umich.edu if (!lastWorkItemStarted.count(p)) 4653714Sstever@eecs.umich.edu return; 4663714Sstever@eecs.umich.edu 4673714Sstever@eecs.umich.edu Tick samp = curTick() - lastWorkItemStarted[p]; 4683714Sstever@eecs.umich.edu DPRINTF(WorkItems, "Work item end: %d\t%d\t%lld\n", tid, workid, samp); 4693101Sstever@eecs.umich.edu 4703101Sstever@eecs.umich.edu if (workid >= numWorkIds) 4713101Sstever@eecs.umich.edu fatal("Got workid greater than specified in system configuration\n"); 4723101Sstever@eecs.umich.edu 4733101Sstever@eecs.umich.edu workItemStats[workid]->sample(samp); 4743101Sstever@eecs.umich.edu lastWorkItemStarted.erase(p); 4753101Sstever@eecs.umich.edu} 4763101Sstever@eecs.umich.edu 4773101Sstever@eecs.umich.eduvoid 4783101Sstever@eecs.umich.eduSystem::printSystems() 4793101Sstever@eecs.umich.edu{ 4803101Sstever@eecs.umich.edu ios::fmtflags flags(cerr.flags()); 4813101Sstever@eecs.umich.edu 4823101Sstever@eecs.umich.edu vector<System *>::iterator i = systemList.begin(); 4833101Sstever@eecs.umich.edu vector<System *>::iterator end = systemList.end(); 4843101Sstever@eecs.umich.edu for (; i != end; ++i) { 4853101Sstever@eecs.umich.edu System *sys = *i; 4863101Sstever@eecs.umich.edu cerr << "System " << sys->name() << ": " << hex << sys << endl; 4873101Sstever@eecs.umich.edu } 4883101Sstever@eecs.umich.edu 4893101Sstever@eecs.umich.edu cerr.flags(flags); 4903101Sstever@eecs.umich.edu} 4913101Sstever@eecs.umich.edu 4923101Sstever@eecs.umich.eduvoid 49310380SAndrew.Bardsley@arm.comprintSystems() 49410380SAndrew.Bardsley@arm.com{ 49510380SAndrew.Bardsley@arm.com System::printSystems(); 49610458Sandreas.hansson@arm.com} 49710458Sandreas.hansson@arm.com 49810458Sandreas.hansson@arm.comMasterID 49910458Sandreas.hansson@arm.comSystem::getMasterId(std::string master_name) 50010458Sandreas.hansson@arm.com{ 50110458Sandreas.hansson@arm.com // strip off system name if the string starts with it 50210458Sandreas.hansson@arm.com if (startswith(master_name, name())) 50310458Sandreas.hansson@arm.com master_name = master_name.erase(0, name().size() + 1); 50410458Sandreas.hansson@arm.com 50510458Sandreas.hansson@arm.com // CPUs in switch_cpus ask for ids again after switching 50610458Sandreas.hansson@arm.com for (int i = 0; i < masterIds.size(); i++) { 50710458Sandreas.hansson@arm.com if (masterIds[i] == master_name) { 50810458Sandreas.hansson@arm.com return i; 5093101Sstever@eecs.umich.edu } 5105033Smilesck@eecs.umich.edu } 5113101Sstever@eecs.umich.edu 5123101Sstever@eecs.umich.edu // Verify that the statistics haven't been enabled yet 5133101Sstever@eecs.umich.edu // Otherwise objects will have sized their stat buckets and 5143101Sstever@eecs.umich.edu // they will be too small 5153101Sstever@eecs.umich.edu 5163101Sstever@eecs.umich.edu if (Stats::enabled()) { 5173101Sstever@eecs.umich.edu fatal("Can't request a masterId after regStats(). " 5183101Sstever@eecs.umich.edu "You must do so in init().\n"); 5193101Sstever@eecs.umich.edu } 5203101Sstever@eecs.umich.edu 5213101Sstever@eecs.umich.edu masterIds.push_back(master_name); 5223101Sstever@eecs.umich.edu 5235822Ssaidi@eecs.umich.edu return masterIds.size() - 1; 5245822Ssaidi@eecs.umich.edu} 5253101Sstever@eecs.umich.edu 5263101Sstever@eecs.umich.edustd::string 5273101Sstever@eecs.umich.eduSystem::getMasterName(MasterID master_id) 5283101Sstever@eecs.umich.edu{ 5293101Sstever@eecs.umich.edu if (master_id >= masterIds.size()) 5303101Sstever@eecs.umich.edu fatal("Invalid master_id passed to getMasterName()\n"); 5313101Sstever@eecs.umich.edu 5323101Sstever@eecs.umich.edu return masterIds[master_id]; 5333101Sstever@eecs.umich.edu} 5343101Sstever@eecs.umich.edu 5353101Sstever@eecs.umich.eduSystem * 5363101Sstever@eecs.umich.eduSystemParams::create() 5373101Sstever@eecs.umich.edu{ 53810267SGeoffrey.Blake@arm.com return new System(this); 5393101Sstever@eecs.umich.edu} 5403101Sstever@eecs.umich.edu