system.hh revision 10467
19651SAndreas.Sandberg@ARM.com/* 29651SAndreas.Sandberg@ARM.com * Copyright (c) 2012, 2014 ARM Limited 39651SAndreas.Sandberg@ARM.com * All rights reserved 49651SAndreas.Sandberg@ARM.com * 59651SAndreas.Sandberg@ARM.com * The license below extends only to copyright in the software and shall 69651SAndreas.Sandberg@ARM.com * not be construed as granting a license to any other intellectual 79651SAndreas.Sandberg@ARM.com * property including but not limited to intellectual property relating 89651SAndreas.Sandberg@ARM.com * to a hardware implementation of the functionality of the software 99651SAndreas.Sandberg@ARM.com * licensed hereunder. You may use the software subject to the license 109651SAndreas.Sandberg@ARM.com * terms below provided that you ensure that this notice is replicated 119651SAndreas.Sandberg@ARM.com * unmodified and in its entirety in all distributions of the software, 129651SAndreas.Sandberg@ARM.com * modified or unmodified, in source code or in binary form. 139651SAndreas.Sandberg@ARM.com * 149651SAndreas.Sandberg@ARM.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 159651SAndreas.Sandberg@ARM.com * Copyright (c) 2011 Regents of the University of California 169651SAndreas.Sandberg@ARM.com * All rights reserved. 179651SAndreas.Sandberg@ARM.com * 189651SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without 199651SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are 209651SAndreas.Sandberg@ARM.com * met: redistributions of source code must retain the above copyright 219651SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer; 229651SAndreas.Sandberg@ARM.com * redistributions in binary form must reproduce the above copyright 239651SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer in the 249651SAndreas.Sandberg@ARM.com * documentation and/or other materials provided with the distribution; 259651SAndreas.Sandberg@ARM.com * neither the name of the copyright holders nor the names of its 269651SAndreas.Sandberg@ARM.com * contributors may be used to endorse or promote products derived from 279651SAndreas.Sandberg@ARM.com * this software without specific prior written permission. 289651SAndreas.Sandberg@ARM.com * 299651SAndreas.Sandberg@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 309651SAndreas.Sandberg@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 319651SAndreas.Sandberg@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 329651SAndreas.Sandberg@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 339651SAndreas.Sandberg@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 349651SAndreas.Sandberg@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 359651SAndreas.Sandberg@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 369651SAndreas.Sandberg@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 379651SAndreas.Sandberg@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 389651SAndreas.Sandberg@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 399651SAndreas.Sandberg@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 409651SAndreas.Sandberg@ARM.com * 419651SAndreas.Sandberg@ARM.com * Authors: Steve Reinhardt 429651SAndreas.Sandberg@ARM.com * Lisa Hsu 439651SAndreas.Sandberg@ARM.com * Nathan Binkert 449651SAndreas.Sandberg@ARM.com * Rick Strong 459651SAndreas.Sandberg@ARM.com */ 469651SAndreas.Sandberg@ARM.com 479651SAndreas.Sandberg@ARM.com#ifndef __SYSTEM_HH__ 489651SAndreas.Sandberg@ARM.com#define __SYSTEM_HH__ 499651SAndreas.Sandberg@ARM.com 509651SAndreas.Sandberg@ARM.com#include <string> 519651SAndreas.Sandberg@ARM.com#include <utility> 529651SAndreas.Sandberg@ARM.com#include <vector> 539651SAndreas.Sandberg@ARM.com 549651SAndreas.Sandberg@ARM.com#include "arch/isa_traits.hh" 559651SAndreas.Sandberg@ARM.com#include "base/loader/symtab.hh" 569651SAndreas.Sandberg@ARM.com#include "base/misc.hh" 579651SAndreas.Sandberg@ARM.com#include "base/statistics.hh" 589651SAndreas.Sandberg@ARM.com#include "config/the_isa.hh" 599651SAndreas.Sandberg@ARM.com#include "cpu/pc_event.hh" 609651SAndreas.Sandberg@ARM.com#include "enums/MemoryMode.hh" 619651SAndreas.Sandberg@ARM.com#include "kern/system_events.hh" 629651SAndreas.Sandberg@ARM.com#include "mem/mem_object.hh" 639651SAndreas.Sandberg@ARM.com#include "mem/port.hh" 649651SAndreas.Sandberg@ARM.com#include "mem/port_proxy.hh" 659651SAndreas.Sandberg@ARM.com#include "mem/physical.hh" 669651SAndreas.Sandberg@ARM.com#include "params/System.hh" 679651SAndreas.Sandberg@ARM.com 689651SAndreas.Sandberg@ARM.comclass BaseCPU; 699651SAndreas.Sandberg@ARM.comclass BaseRemoteGDB; 709651SAndreas.Sandberg@ARM.comclass GDBListener; 719651SAndreas.Sandberg@ARM.comclass ObjectFile; 729651SAndreas.Sandberg@ARM.comclass Platform; 739651SAndreas.Sandberg@ARM.comclass ThreadContext; 749651SAndreas.Sandberg@ARM.com 759652SAndreas.Sandberg@ARM.comclass System : public MemObject 769652SAndreas.Sandberg@ARM.com{ 779651SAndreas.Sandberg@ARM.com private: 789651SAndreas.Sandberg@ARM.com 799651SAndreas.Sandberg@ARM.com /** 809651SAndreas.Sandberg@ARM.com * Private class for the system port which is only used as a 819651SAndreas.Sandberg@ARM.com * master for debug access and for non-structural entities that do 829651SAndreas.Sandberg@ARM.com * not have a port of their own. 839651SAndreas.Sandberg@ARM.com */ 849651SAndreas.Sandberg@ARM.com class SystemPort : public MasterPort 859651SAndreas.Sandberg@ARM.com { 869651SAndreas.Sandberg@ARM.com public: 879651SAndreas.Sandberg@ARM.com 889651SAndreas.Sandberg@ARM.com /** 899651SAndreas.Sandberg@ARM.com * Create a system port with a name and an owner. 909651SAndreas.Sandberg@ARM.com */ 919651SAndreas.Sandberg@ARM.com SystemPort(const std::string &_name, MemObject *_owner) 929651SAndreas.Sandberg@ARM.com : MasterPort(_name, _owner) 939651SAndreas.Sandberg@ARM.com { } 949651SAndreas.Sandberg@ARM.com bool recvTimingResp(PacketPtr pkt) 959651SAndreas.Sandberg@ARM.com { panic("SystemPort does not receive timing!\n"); return false; } 969651SAndreas.Sandberg@ARM.com void recvRetry() 979651SAndreas.Sandberg@ARM.com { panic("SystemPort does not expect retry!\n"); } 989651SAndreas.Sandberg@ARM.com }; 999651SAndreas.Sandberg@ARM.com 1009651SAndreas.Sandberg@ARM.com SystemPort _systemPort; 1019651SAndreas.Sandberg@ARM.com 1029651SAndreas.Sandberg@ARM.com public: 1039651SAndreas.Sandberg@ARM.com 1049651SAndreas.Sandberg@ARM.com /** 1059651SAndreas.Sandberg@ARM.com * After all objects have been created and all ports are 1069651SAndreas.Sandberg@ARM.com * connected, check that the system port is connected. 1079651SAndreas.Sandberg@ARM.com */ 1089651SAndreas.Sandberg@ARM.com virtual void init(); 1099651SAndreas.Sandberg@ARM.com 1109651SAndreas.Sandberg@ARM.com /** 1119651SAndreas.Sandberg@ARM.com * Get a reference to the system port that can be used by 1129651SAndreas.Sandberg@ARM.com * non-structural simulation objects like processes or threads, or 1139651SAndreas.Sandberg@ARM.com * external entities like loaders and debuggers, etc, to access 1149651SAndreas.Sandberg@ARM.com * the memory system. 1159651SAndreas.Sandberg@ARM.com * 1169651SAndreas.Sandberg@ARM.com * @return a reference to the system port we own 1179651SAndreas.Sandberg@ARM.com */ 1189651SAndreas.Sandberg@ARM.com MasterPort& getSystemPort() { return _systemPort; } 1199651SAndreas.Sandberg@ARM.com 1209651SAndreas.Sandberg@ARM.com /** 1219651SAndreas.Sandberg@ARM.com * Additional function to return the Port of a memory object. 1229651SAndreas.Sandberg@ARM.com */ 1239651SAndreas.Sandberg@ARM.com BaseMasterPort& getMasterPort(const std::string &if_name, 1249651SAndreas.Sandberg@ARM.com PortID idx = InvalidPortID); 1259651SAndreas.Sandberg@ARM.com 1269651SAndreas.Sandberg@ARM.com /** @{ */ 1279651SAndreas.Sandberg@ARM.com /** 1289651SAndreas.Sandberg@ARM.com * Is the system in atomic mode? 1299651SAndreas.Sandberg@ARM.com * 1309651SAndreas.Sandberg@ARM.com * There are currently two different atomic memory modes: 1319651SAndreas.Sandberg@ARM.com * 'atomic', which supports caches; and 'atomic_noncaching', which 1329651SAndreas.Sandberg@ARM.com * bypasses caches. The latter is used by hardware virtualized 1339651SAndreas.Sandberg@ARM.com * CPUs. SimObjects are expected to use Port::sendAtomic() and 1349651SAndreas.Sandberg@ARM.com * Port::recvAtomic() when accessing memory in this mode. 1359651SAndreas.Sandberg@ARM.com */ 1369651SAndreas.Sandberg@ARM.com bool isAtomicMode() const { 1379651SAndreas.Sandberg@ARM.com return memoryMode == Enums::atomic || 1389651SAndreas.Sandberg@ARM.com memoryMode == Enums::atomic_noncaching; 1399651SAndreas.Sandberg@ARM.com } 1409651SAndreas.Sandberg@ARM.com 1419651SAndreas.Sandberg@ARM.com /** 1429651SAndreas.Sandberg@ARM.com * Is the system in timing mode? 1439651SAndreas.Sandberg@ARM.com * 1449651SAndreas.Sandberg@ARM.com * SimObjects are expected to use Port::sendTiming() and 1459651SAndreas.Sandberg@ARM.com * Port::recvTiming() when accessing memory in this mode. 1469651SAndreas.Sandberg@ARM.com */ 1479651SAndreas.Sandberg@ARM.com bool isTimingMode() const { 1489651SAndreas.Sandberg@ARM.com return memoryMode == Enums::timing; 1499651SAndreas.Sandberg@ARM.com } 1509651SAndreas.Sandberg@ARM.com 1519651SAndreas.Sandberg@ARM.com /** 1529651SAndreas.Sandberg@ARM.com * Should caches be bypassed? 1539651SAndreas.Sandberg@ARM.com * 1549651SAndreas.Sandberg@ARM.com * Some CPUs need to bypass caches to allow direct memory 1559651SAndreas.Sandberg@ARM.com * accesses, which is required for hardware virtualization. 1569651SAndreas.Sandberg@ARM.com */ 1579651SAndreas.Sandberg@ARM.com bool bypassCaches() const { 1589651SAndreas.Sandberg@ARM.com return memoryMode == Enums::atomic_noncaching; 1599651SAndreas.Sandberg@ARM.com } 1609651SAndreas.Sandberg@ARM.com /** @} */ 1619651SAndreas.Sandberg@ARM.com 1629651SAndreas.Sandberg@ARM.com /** @{ */ 1639651SAndreas.Sandberg@ARM.com /** 1649651SAndreas.Sandberg@ARM.com * Get the memory mode of the system. 1659651SAndreas.Sandberg@ARM.com * 1669651SAndreas.Sandberg@ARM.com * \warn This should only be used by the Python world. The C++ 1679651SAndreas.Sandberg@ARM.com * world should use one of the query functions above 1689651SAndreas.Sandberg@ARM.com * (isAtomicMode(), isTimingMode(), bypassCaches()). 1699651SAndreas.Sandberg@ARM.com */ 1709651SAndreas.Sandberg@ARM.com Enums::MemoryMode getMemoryMode() const { return memoryMode; } 1719651SAndreas.Sandberg@ARM.com 1729651SAndreas.Sandberg@ARM.com /** 1739651SAndreas.Sandberg@ARM.com * Change the memory mode of the system. 1749651SAndreas.Sandberg@ARM.com * 1759651SAndreas.Sandberg@ARM.com * \warn This should only be called by the Python! 1769651SAndreas.Sandberg@ARM.com * 1779651SAndreas.Sandberg@ARM.com * @param mode Mode to change to (atomic/timing/...) 1789651SAndreas.Sandberg@ARM.com */ 1799651SAndreas.Sandberg@ARM.com void setMemoryMode(Enums::MemoryMode mode); 1809651SAndreas.Sandberg@ARM.com /** @} */ 1819651SAndreas.Sandberg@ARM.com 1829651SAndreas.Sandberg@ARM.com /** 1839651SAndreas.Sandberg@ARM.com * Get the cache line size of the system. 1849651SAndreas.Sandberg@ARM.com */ 1859651SAndreas.Sandberg@ARM.com unsigned int cacheLineSize() const { return _cacheLineSize; } 1869651SAndreas.Sandberg@ARM.com 1879651SAndreas.Sandberg@ARM.com#if THE_ISA != NULL_ISA 1889651SAndreas.Sandberg@ARM.com PCEventQueue pcEventQueue; 1899651SAndreas.Sandberg@ARM.com#endif 1909651SAndreas.Sandberg@ARM.com 1919651SAndreas.Sandberg@ARM.com std::vector<ThreadContext *> threadContexts; 1929651SAndreas.Sandberg@ARM.com int _numContexts; 1939651SAndreas.Sandberg@ARM.com 1949651SAndreas.Sandberg@ARM.com ThreadContext *getThreadContext(ThreadID tid) 1959651SAndreas.Sandberg@ARM.com { 1969651SAndreas.Sandberg@ARM.com return threadContexts[tid]; 1979651SAndreas.Sandberg@ARM.com } 1989651SAndreas.Sandberg@ARM.com 1999651SAndreas.Sandberg@ARM.com int numContexts() 2009651SAndreas.Sandberg@ARM.com { 2019651SAndreas.Sandberg@ARM.com assert(_numContexts == (int)threadContexts.size()); 2029651SAndreas.Sandberg@ARM.com return _numContexts; 2039651SAndreas.Sandberg@ARM.com } 2049651SAndreas.Sandberg@ARM.com 2059651SAndreas.Sandberg@ARM.com /** Return number of running (non-halted) thread contexts in 2069651SAndreas.Sandberg@ARM.com * system. These threads could be Active or Suspended. */ 2079651SAndreas.Sandberg@ARM.com int numRunningContexts(); 2089651SAndreas.Sandberg@ARM.com 2099652SAndreas.Sandberg@ARM.com Addr pagePtr; 2109652SAndreas.Sandberg@ARM.com 2119652SAndreas.Sandberg@ARM.com uint64_t init_param; 2129651SAndreas.Sandberg@ARM.com 2139651SAndreas.Sandberg@ARM.com /** Port to physical memory used for writing object files into ram at 2149651SAndreas.Sandberg@ARM.com * boot.*/ 2159651SAndreas.Sandberg@ARM.com PortProxy physProxy; 2169651SAndreas.Sandberg@ARM.com 2179651SAndreas.Sandberg@ARM.com /** kernel symbol table */ 2189651SAndreas.Sandberg@ARM.com SymbolTable *kernelSymtab; 2199651SAndreas.Sandberg@ARM.com 2209651SAndreas.Sandberg@ARM.com /** Object pointer for the kernel code */ 2219651SAndreas.Sandberg@ARM.com ObjectFile *kernel; 2229651SAndreas.Sandberg@ARM.com 2239651SAndreas.Sandberg@ARM.com /** Begining of kernel code */ 2249652SAndreas.Sandberg@ARM.com Addr kernelStart; 2259651SAndreas.Sandberg@ARM.com 2269651SAndreas.Sandberg@ARM.com /** End of kernel code */ 2279651SAndreas.Sandberg@ARM.com Addr kernelEnd; 2289651SAndreas.Sandberg@ARM.com 2299651SAndreas.Sandberg@ARM.com /** Entry point in the kernel to start at */ 2309651SAndreas.Sandberg@ARM.com Addr kernelEntry; 2319651SAndreas.Sandberg@ARM.com 2329651SAndreas.Sandberg@ARM.com /** Mask that should be anded for binary/symbol loading. 2339651SAndreas.Sandberg@ARM.com * This allows one two different OS requirements for the same ISA to be 2349651SAndreas.Sandberg@ARM.com * handled. Some OSes are compiled for a virtual address and need to be 2359651SAndreas.Sandberg@ARM.com * loaded into physical memory that starts at address 0, while other 2369651SAndreas.Sandberg@ARM.com * bare metal tools generate images that start at address 0. 2379651SAndreas.Sandberg@ARM.com */ 2389651SAndreas.Sandberg@ARM.com Addr loadAddrMask; 2399651SAndreas.Sandberg@ARM.com 2409651SAndreas.Sandberg@ARM.com /** Offset that should be used for binary/symbol loading. 2419651SAndreas.Sandberg@ARM.com * This further allows more flexibily than the loadAddrMask allows alone in 2429651SAndreas.Sandberg@ARM.com * loading kernels and similar. The loadAddrOffset is applied after the 2439651SAndreas.Sandberg@ARM.com * loadAddrMask. 2449651SAndreas.Sandberg@ARM.com */ 2459651SAndreas.Sandberg@ARM.com Addr loadAddrOffset; 2469651SAndreas.Sandberg@ARM.com 2479651SAndreas.Sandberg@ARM.com protected: 2489651SAndreas.Sandberg@ARM.com uint64_t nextPID; 2499651SAndreas.Sandberg@ARM.com 2509651SAndreas.Sandberg@ARM.com public: 2519651SAndreas.Sandberg@ARM.com uint64_t allocatePID() 2529651SAndreas.Sandberg@ARM.com { 2539651SAndreas.Sandberg@ARM.com return nextPID++; 2549651SAndreas.Sandberg@ARM.com } 2559651SAndreas.Sandberg@ARM.com 2569651SAndreas.Sandberg@ARM.com /** Get a pointer to access the physical memory of the system */ 2579651SAndreas.Sandberg@ARM.com PhysicalMemory& getPhysMem() { return physmem; } 2589651SAndreas.Sandberg@ARM.com 2599651SAndreas.Sandberg@ARM.com /** Amount of physical memory that is still free */ 2609651SAndreas.Sandberg@ARM.com Addr freeMemSize() const; 2619651SAndreas.Sandberg@ARM.com 2629651SAndreas.Sandberg@ARM.com /** Amount of physical memory that exists */ 2639651SAndreas.Sandberg@ARM.com Addr memSize() const; 2649651SAndreas.Sandberg@ARM.com 2659651SAndreas.Sandberg@ARM.com /** 2669651SAndreas.Sandberg@ARM.com * Check if a physical address is within a range of a memory that 2679651SAndreas.Sandberg@ARM.com * is part of the global address map. 2689651SAndreas.Sandberg@ARM.com * 2699651SAndreas.Sandberg@ARM.com * @param addr A physical address 2709652SAndreas.Sandberg@ARM.com * @return Whether the address corresponds to a memory 2719652SAndreas.Sandberg@ARM.com */ 2729652SAndreas.Sandberg@ARM.com bool isMemAddr(Addr addr) const; 2739652SAndreas.Sandberg@ARM.com 2749652SAndreas.Sandberg@ARM.com /** 2759652SAndreas.Sandberg@ARM.com * Get the architecture. 2769651SAndreas.Sandberg@ARM.com */ 2779651SAndreas.Sandberg@ARM.com Arch getArch() const { return Arch::TheISA; } 2789651SAndreas.Sandberg@ARM.com 2799651SAndreas.Sandberg@ARM.com /** 2809651SAndreas.Sandberg@ARM.com * Get the page bytes for the ISA. 2819651SAndreas.Sandberg@ARM.com */ 2829651SAndreas.Sandberg@ARM.com Addr getPageBytes() const { return TheISA::PageBytes; } 2839651SAndreas.Sandberg@ARM.com 2849651SAndreas.Sandberg@ARM.com /** 2859651SAndreas.Sandberg@ARM.com * Get the number of bits worth of in-page adress for the ISA. 2869651SAndreas.Sandberg@ARM.com */ 2879651SAndreas.Sandberg@ARM.com Addr getPageShift() const { return TheISA::PageShift; } 2889651SAndreas.Sandberg@ARM.com 2899651SAndreas.Sandberg@ARM.com protected: 2909651SAndreas.Sandberg@ARM.com 2919651SAndreas.Sandberg@ARM.com PhysicalMemory physmem; 2929651SAndreas.Sandberg@ARM.com 2939651SAndreas.Sandberg@ARM.com Enums::MemoryMode memoryMode; 2949651SAndreas.Sandberg@ARM.com 2959651SAndreas.Sandberg@ARM.com const unsigned int _cacheLineSize; 2969651SAndreas.Sandberg@ARM.com 2979651SAndreas.Sandberg@ARM.com uint64_t workItemsBegin; 2989651SAndreas.Sandberg@ARM.com uint64_t workItemsEnd; 2999652SAndreas.Sandberg@ARM.com uint32_t numWorkIds; 3009652SAndreas.Sandberg@ARM.com std::vector<bool> activeCpus; 3019652SAndreas.Sandberg@ARM.com 3029651SAndreas.Sandberg@ARM.com /** This array is a per-sytem list of all devices capable of issuing a 3039651SAndreas.Sandberg@ARM.com * memory system request and an associated string for each master id. 3049651SAndreas.Sandberg@ARM.com * It's used to uniquely id any master in the system by name for things 3059651SAndreas.Sandberg@ARM.com * like cache statistics. 3069651SAndreas.Sandberg@ARM.com */ 3079651SAndreas.Sandberg@ARM.com std::vector<std::string> masterIds; 3089651SAndreas.Sandberg@ARM.com 3099651SAndreas.Sandberg@ARM.com public: 3109651SAndreas.Sandberg@ARM.com 3119651SAndreas.Sandberg@ARM.com /** Request an id used to create a request object in the system. All objects 3129651SAndreas.Sandberg@ARM.com * that intend to issues requests into the memory system must request an id 3139651SAndreas.Sandberg@ARM.com * in the init() phase of startup. All master ids must be fixed by the 3149651SAndreas.Sandberg@ARM.com * regStats() phase that immediately preceeds it. This allows objects in the 3159651SAndreas.Sandberg@ARM.com * memory system to understand how many masters may exist and 3169651SAndreas.Sandberg@ARM.com * appropriately name the bins of their per-master stats before the stats 3179651SAndreas.Sandberg@ARM.com * are finalized 3189651SAndreas.Sandberg@ARM.com */ 3199651SAndreas.Sandberg@ARM.com MasterID getMasterId(std::string req_name); 3209651SAndreas.Sandberg@ARM.com 3219651SAndreas.Sandberg@ARM.com /** Get the name of an object for a given request id. 3229651SAndreas.Sandberg@ARM.com */ 3239651SAndreas.Sandberg@ARM.com std::string getMasterName(MasterID master_id); 3249651SAndreas.Sandberg@ARM.com 3259651SAndreas.Sandberg@ARM.com /** Get the number of masters registered in the system */ 3269651SAndreas.Sandberg@ARM.com MasterID maxMasters() 3279651SAndreas.Sandberg@ARM.com { 3289651SAndreas.Sandberg@ARM.com return masterIds.size(); 3299651SAndreas.Sandberg@ARM.com } 3309651SAndreas.Sandberg@ARM.com 3319651SAndreas.Sandberg@ARM.com virtual void regStats(); 3329651SAndreas.Sandberg@ARM.com /** 3339651SAndreas.Sandberg@ARM.com * Called by pseudo_inst to track the number of work items started by this 3349651SAndreas.Sandberg@ARM.com * system. 3359651SAndreas.Sandberg@ARM.com */ 3369651SAndreas.Sandberg@ARM.com uint64_t 3379651SAndreas.Sandberg@ARM.com incWorkItemsBegin() 3389651SAndreas.Sandberg@ARM.com { 3399651SAndreas.Sandberg@ARM.com return ++workItemsBegin; 3409651SAndreas.Sandberg@ARM.com } 3419651SAndreas.Sandberg@ARM.com 3429651SAndreas.Sandberg@ARM.com /** 3439651SAndreas.Sandberg@ARM.com * Called by pseudo_inst to track the number of work items completed by 3449651SAndreas.Sandberg@ARM.com * this system. 3459651SAndreas.Sandberg@ARM.com */ 3469651SAndreas.Sandberg@ARM.com uint64_t 3479651SAndreas.Sandberg@ARM.com incWorkItemsEnd() 3489651SAndreas.Sandberg@ARM.com { 3499651SAndreas.Sandberg@ARM.com return ++workItemsEnd; 3509651SAndreas.Sandberg@ARM.com } 3519651SAndreas.Sandberg@ARM.com 3529651SAndreas.Sandberg@ARM.com /** 3539651SAndreas.Sandberg@ARM.com * Called by pseudo_inst to mark the cpus actively executing work items. 3549651SAndreas.Sandberg@ARM.com * Returns the total number of cpus that have executed work item begin or 3559651SAndreas.Sandberg@ARM.com * ends. 3569651SAndreas.Sandberg@ARM.com */ 3579651SAndreas.Sandberg@ARM.com int 3589651SAndreas.Sandberg@ARM.com markWorkItem(int index) 3599651SAndreas.Sandberg@ARM.com { 3609651SAndreas.Sandberg@ARM.com int count = 0; 3619651SAndreas.Sandberg@ARM.com assert(index < activeCpus.size()); 3629651SAndreas.Sandberg@ARM.com activeCpus[index] = true; 3639651SAndreas.Sandberg@ARM.com for (std::vector<bool>::iterator i = activeCpus.begin(); 3649651SAndreas.Sandberg@ARM.com i < activeCpus.end(); i++) { 3659651SAndreas.Sandberg@ARM.com if (*i) count++; 3669651SAndreas.Sandberg@ARM.com } 3679651SAndreas.Sandberg@ARM.com return count; 3689651SAndreas.Sandberg@ARM.com } 3699651SAndreas.Sandberg@ARM.com 3709651SAndreas.Sandberg@ARM.com inline void workItemBegin(uint32_t tid, uint32_t workid) 3719651SAndreas.Sandberg@ARM.com { 3729651SAndreas.Sandberg@ARM.com std::pair<uint32_t,uint32_t> p(tid, workid); 3739651SAndreas.Sandberg@ARM.com lastWorkItemStarted[p] = curTick(); 3749651SAndreas.Sandberg@ARM.com } 3759651SAndreas.Sandberg@ARM.com 3769651SAndreas.Sandberg@ARM.com void workItemEnd(uint32_t tid, uint32_t workid); 3779651SAndreas.Sandberg@ARM.com 3789651SAndreas.Sandberg@ARM.com /** 3799651SAndreas.Sandberg@ARM.com * Fix up an address used to match PCs for hooking simulator 3809652SAndreas.Sandberg@ARM.com * events on to target function executions. See comment in 3819652SAndreas.Sandberg@ARM.com * system.cc for details. 3829652SAndreas.Sandberg@ARM.com */ 3839652SAndreas.Sandberg@ARM.com virtual Addr fixFuncEventAddr(Addr addr) 3849652SAndreas.Sandberg@ARM.com { 3859652SAndreas.Sandberg@ARM.com panic("Base fixFuncEventAddr not implemented.\n"); 3869652SAndreas.Sandberg@ARM.com } 3879652SAndreas.Sandberg@ARM.com 3889652SAndreas.Sandberg@ARM.com /** @{ */ 3899651SAndreas.Sandberg@ARM.com /** 3909651SAndreas.Sandberg@ARM.com * Add a function-based event to the given function, to be looked 3919651SAndreas.Sandberg@ARM.com * up in the specified symbol table. 3929651SAndreas.Sandberg@ARM.com * 3939651SAndreas.Sandberg@ARM.com * The ...OrPanic flavor of the method causes the simulator to 3949651SAndreas.Sandberg@ARM.com * panic if the symbol can't be found. 3959651SAndreas.Sandberg@ARM.com * 3969651SAndreas.Sandberg@ARM.com * @param symtab Symbol table to use for look up. 3979651SAndreas.Sandberg@ARM.com * @param lbl Function to hook the event to. 3989651SAndreas.Sandberg@ARM.com * @param desc Description to be passed to the event. 3999651SAndreas.Sandberg@ARM.com * @param args Arguments to be forwarded to the event constructor. 4009651SAndreas.Sandberg@ARM.com */ 4019651SAndreas.Sandberg@ARM.com template <class T, typename... Args> 4029651SAndreas.Sandberg@ARM.com T *addFuncEvent(const SymbolTable *symtab, const char *lbl, 4039651SAndreas.Sandberg@ARM.com const std::string &desc, Args... args) 4049651SAndreas.Sandberg@ARM.com { 4059651SAndreas.Sandberg@ARM.com Addr addr M5_VAR_USED = 0; // initialize only to avoid compiler warning 4069651SAndreas.Sandberg@ARM.com 4079651SAndreas.Sandberg@ARM.com#if THE_ISA != NULL_ISA 4089651SAndreas.Sandberg@ARM.com if (symtab->findAddress(lbl, addr)) { 4099651SAndreas.Sandberg@ARM.com T *ev = new T(&pcEventQueue, desc, fixFuncEventAddr(addr), 4109651SAndreas.Sandberg@ARM.com std::forward<Args>(args)...); 4119651SAndreas.Sandberg@ARM.com return ev; 4129651SAndreas.Sandberg@ARM.com } 4139651SAndreas.Sandberg@ARM.com#endif 4149651SAndreas.Sandberg@ARM.com 4159651SAndreas.Sandberg@ARM.com return NULL; 4169651SAndreas.Sandberg@ARM.com } 4179651SAndreas.Sandberg@ARM.com 4189651SAndreas.Sandberg@ARM.com template <class T> 4199651SAndreas.Sandberg@ARM.com T *addFuncEvent(const SymbolTable *symtab, const char *lbl) 4209651SAndreas.Sandberg@ARM.com { 4219651SAndreas.Sandberg@ARM.com return addFuncEvent<T>(symtab, lbl, lbl); 4229651SAndreas.Sandberg@ARM.com } 4239651SAndreas.Sandberg@ARM.com 4249651SAndreas.Sandberg@ARM.com template <class T, typename... Args> 4259651SAndreas.Sandberg@ARM.com T *addFuncEventOrPanic(const SymbolTable *symtab, const char *lbl, 4269651SAndreas.Sandberg@ARM.com Args... args) 4279651SAndreas.Sandberg@ARM.com { 4289651SAndreas.Sandberg@ARM.com T *e(addFuncEvent<T>(symtab, lbl, std::forward<Args>(args)...)); 4299651SAndreas.Sandberg@ARM.com if (!e) 4309651SAndreas.Sandberg@ARM.com panic("Failed to find symbol '%s'", lbl); 4319651SAndreas.Sandberg@ARM.com return e; 4329651SAndreas.Sandberg@ARM.com } 4339651SAndreas.Sandberg@ARM.com /** @} */ 4349651SAndreas.Sandberg@ARM.com 4359651SAndreas.Sandberg@ARM.com /** @{ */ 4369651SAndreas.Sandberg@ARM.com /** 4379651SAndreas.Sandberg@ARM.com * Add a function-based event to a kernel symbol. 4389652SAndreas.Sandberg@ARM.com * 4399652SAndreas.Sandberg@ARM.com * These functions work like their addFuncEvent() and 4409652SAndreas.Sandberg@ARM.com * addFuncEventOrPanic() counterparts. The only difference is that 4419652SAndreas.Sandberg@ARM.com * they automatically use the kernel symbol table. All arguments 4429652SAndreas.Sandberg@ARM.com * are forwarded to the underlying method. 4439652SAndreas.Sandberg@ARM.com * 4449652SAndreas.Sandberg@ARM.com * @see addFuncEvent() 4459651SAndreas.Sandberg@ARM.com * @see addFuncEventOrPanic() 4469651SAndreas.Sandberg@ARM.com * 4479651SAndreas.Sandberg@ARM.com * @param lbl Function to hook the event to. 4489651SAndreas.Sandberg@ARM.com * @param args Arguments to be passed to addFuncEvent 4499651SAndreas.Sandberg@ARM.com */ 4509651SAndreas.Sandberg@ARM.com template <class T, typename... Args> 4519651SAndreas.Sandberg@ARM.com T *addKernelFuncEvent(const char *lbl, Args... args) 4529651SAndreas.Sandberg@ARM.com { 4539651SAndreas.Sandberg@ARM.com return addFuncEvent<T>(kernelSymtab, lbl, 4549651SAndreas.Sandberg@ARM.com std::forward<Args>(args)...); 4559651SAndreas.Sandberg@ARM.com } 4569651SAndreas.Sandberg@ARM.com 4579651SAndreas.Sandberg@ARM.com template <class T, typename... Args> 4589651SAndreas.Sandberg@ARM.com T *addKernelFuncEventOrPanic(const char *lbl, Args... args) 4599651SAndreas.Sandberg@ARM.com { 4609651SAndreas.Sandberg@ARM.com T *e(addFuncEvent<T>(kernelSymtab, lbl, 4619651SAndreas.Sandberg@ARM.com std::forward<Args>(args)...)); 4629651SAndreas.Sandberg@ARM.com if (!e) 4639651SAndreas.Sandberg@ARM.com panic("Failed to find kernel symbol '%s'", lbl); 4649651SAndreas.Sandberg@ARM.com return e; 4659651SAndreas.Sandberg@ARM.com } 4669651SAndreas.Sandberg@ARM.com /** @} */ 4679651SAndreas.Sandberg@ARM.com 4689651SAndreas.Sandberg@ARM.com public: 4699651SAndreas.Sandberg@ARM.com std::vector<BaseRemoteGDB *> remoteGDB; 4709651SAndreas.Sandberg@ARM.com std::vector<GDBListener *> gdbListen; 4719651SAndreas.Sandberg@ARM.com bool breakpoint(); 4729651SAndreas.Sandberg@ARM.com 4739651SAndreas.Sandberg@ARM.com public: 4749651SAndreas.Sandberg@ARM.com typedef SystemParams Params; 4759651SAndreas.Sandberg@ARM.com 4769651SAndreas.Sandberg@ARM.com protected: 4779651SAndreas.Sandberg@ARM.com Params *_params; 4789651SAndreas.Sandberg@ARM.com 4799651SAndreas.Sandberg@ARM.com public: 4809651SAndreas.Sandberg@ARM.com System(Params *p); 4819651SAndreas.Sandberg@ARM.com ~System(); 4829651SAndreas.Sandberg@ARM.com 4839651SAndreas.Sandberg@ARM.com void initState(); 4849651SAndreas.Sandberg@ARM.com 4859651SAndreas.Sandberg@ARM.com const Params *params() const { return (const Params *)_params; } 4869651SAndreas.Sandberg@ARM.com 4879651SAndreas.Sandberg@ARM.com public: 4889651SAndreas.Sandberg@ARM.com 4899651SAndreas.Sandberg@ARM.com /** 4909651SAndreas.Sandberg@ARM.com * Returns the addess the kernel starts at. 4919651SAndreas.Sandberg@ARM.com * @return address the kernel starts at 4929651SAndreas.Sandberg@ARM.com */ 4939651SAndreas.Sandberg@ARM.com Addr getKernelStart() const { return kernelStart; } 4949651SAndreas.Sandberg@ARM.com 4959651SAndreas.Sandberg@ARM.com /** 4969651SAndreas.Sandberg@ARM.com * Returns the addess the kernel ends at. 4979651SAndreas.Sandberg@ARM.com * @return address the kernel ends at 4989651SAndreas.Sandberg@ARM.com */ 4999651SAndreas.Sandberg@ARM.com Addr getKernelEnd() const { return kernelEnd; } 5009651SAndreas.Sandberg@ARM.com 5019651SAndreas.Sandberg@ARM.com /** 5029651SAndreas.Sandberg@ARM.com * Returns the addess the entry point to the kernel code. 5039651SAndreas.Sandberg@ARM.com * @return entry point of the kernel code 5049651SAndreas.Sandberg@ARM.com */ 5059651SAndreas.Sandberg@ARM.com Addr getKernelEntry() const { return kernelEntry; } 5069651SAndreas.Sandberg@ARM.com 5079651SAndreas.Sandberg@ARM.com /// Allocate npages contiguous unused physical pages 5089651SAndreas.Sandberg@ARM.com /// @return Starting address of first page 5099651SAndreas.Sandberg@ARM.com Addr allocPhysPages(int npages); 5109651SAndreas.Sandberg@ARM.com 5119651SAndreas.Sandberg@ARM.com int registerThreadContext(ThreadContext *tc, int assigned=-1); 5129651SAndreas.Sandberg@ARM.com void replaceThreadContext(ThreadContext *tc, int context_id); 5139651SAndreas.Sandberg@ARM.com 5149651SAndreas.Sandberg@ARM.com void serialize(std::ostream &os); 5159651SAndreas.Sandberg@ARM.com void unserialize(Checkpoint *cp, const std::string §ion); 5169651SAndreas.Sandberg@ARM.com 5179651SAndreas.Sandberg@ARM.com unsigned int drain(DrainManager *dm); 5189651SAndreas.Sandberg@ARM.com void drainResume(); 5199651SAndreas.Sandberg@ARM.com 5209651SAndreas.Sandberg@ARM.com public: 5219651SAndreas.Sandberg@ARM.com Counter totalNumInsts; 5229651SAndreas.Sandberg@ARM.com EventQueue instEventQueue; 5239651SAndreas.Sandberg@ARM.com std::map<std::pair<uint32_t,uint32_t>, Tick> lastWorkItemStarted; 5249651SAndreas.Sandberg@ARM.com std::map<uint32_t, Stats::Histogram*> workItemStats; 5259651SAndreas.Sandberg@ARM.com 5269651SAndreas.Sandberg@ARM.com //////////////////////////////////////////// 5279651SAndreas.Sandberg@ARM.com // 5289651SAndreas.Sandberg@ARM.com // STATIC GLOBAL SYSTEM LIST 5299651SAndreas.Sandberg@ARM.com // 5309651SAndreas.Sandberg@ARM.com //////////////////////////////////////////// 5319651SAndreas.Sandberg@ARM.com 5329651SAndreas.Sandberg@ARM.com static std::vector<System *> systemList; 5339651SAndreas.Sandberg@ARM.com static int numSystemsRunning; 5349651SAndreas.Sandberg@ARM.com 5359651SAndreas.Sandberg@ARM.com static void printSystems(); 5369651SAndreas.Sandberg@ARM.com 5379651SAndreas.Sandberg@ARM.com // For futex system call 5389651SAndreas.Sandberg@ARM.com std::map<uint64_t, std::list<ThreadContext *> * > futexMap; 5399651SAndreas.Sandberg@ARM.com 5409651SAndreas.Sandberg@ARM.com protected: 5419651SAndreas.Sandberg@ARM.com 5429651SAndreas.Sandberg@ARM.com /** 5439651SAndreas.Sandberg@ARM.com * If needed, serialize additional symbol table entries for a 5449651SAndreas.Sandberg@ARM.com * specific subclass of this sytem. Currently this is used by 5459651SAndreas.Sandberg@ARM.com * Alpha and MIPS. 5469651SAndreas.Sandberg@ARM.com * 5479651SAndreas.Sandberg@ARM.com * @param os stream to serialize to 5489651SAndreas.Sandberg@ARM.com */ 5499651SAndreas.Sandberg@ARM.com virtual void serializeSymtab(std::ostream &os) {} 5509651SAndreas.Sandberg@ARM.com 5519651SAndreas.Sandberg@ARM.com /** 5529651SAndreas.Sandberg@ARM.com * If needed, unserialize additional symbol table entries for a 5539651SAndreas.Sandberg@ARM.com * specific subclass of this system. 5549651SAndreas.Sandberg@ARM.com * 5559651SAndreas.Sandberg@ARM.com * @param cp checkpoint to unserialize from 5569651SAndreas.Sandberg@ARM.com * @param section relevant section in the checkpoint 5579651SAndreas.Sandberg@ARM.com */ 5589651SAndreas.Sandberg@ARM.com virtual void unserializeSymtab(Checkpoint *cp, 5599651SAndreas.Sandberg@ARM.com const std::string §ion) {} 5609651SAndreas.Sandberg@ARM.com 5619651SAndreas.Sandberg@ARM.com}; 5629651SAndreas.Sandberg@ARM.com 5639651SAndreas.Sandberg@ARM.comvoid printSystems(); 5649651SAndreas.Sandberg@ARM.com 5659651SAndreas.Sandberg@ARM.com#endif // __SYSTEM_HH__ 5669651SAndreas.Sandberg@ARM.com