base.hh revision 5712
11060SN/A/* 22702SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 31060SN/A * All rights reserved. 41060SN/A * 51060SN/A * Redistribution and use in source and binary forms, with or without 61060SN/A * modification, are permitted provided that the following conditions are 71060SN/A * met: redistributions of source code must retain the above copyright 81060SN/A * notice, this list of conditions and the following disclaimer; 91060SN/A * redistributions in binary form must reproduce the above copyright 101060SN/A * notice, this list of conditions and the following disclaimer in the 111060SN/A * documentation and/or other materials provided with the distribution; 121060SN/A * neither the name of the copyright holders nor the names of its 131060SN/A * contributors may be used to endorse or promote products derived from 141060SN/A * this software without specific prior written permission. 151060SN/A * 161060SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171060SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181060SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191060SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201060SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211060SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221060SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231060SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241060SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251060SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261060SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665SN/A * 282665SN/A * Authors: Steve Reinhardt 291060SN/A * Nathan Binkert 301060SN/A */ 311060SN/A 322292SN/A#ifndef __CPU_BASE_HH__ 331060SN/A#define __CPU_BASE_HH__ 341060SN/A 351060SN/A#include <vector> 361060SN/A 371061SN/A#include "arch/isa_traits.hh" 386658Snate@binkert.org#include "arch/microcode_rom.hh" 396658Snate@binkert.org#include "base/statistics.hh" 401060SN/A#include "config/full_system.hh" 412669SN/A#include "sim/eventq.hh" 426658Snate@binkert.org#include "sim/insttracer.hh" 431060SN/A#include "mem/mem_object.hh" 441060SN/A 451060SN/A#if FULL_SYSTEM 461060SN/A#include "arch/interrupts.hh" 471060SN/A#endif 481060SN/A 491060SN/Aclass BaseCPUParams; 501060SN/Aclass BranchPred; 512292SN/Aclass CheckerCPU; 522292SN/Aclass ThreadContext; 531060SN/Aclass System; 542292SN/Aclass Port; 551060SN/A 561060SN/Anamespace TheISA 572292SN/A{ 582292SN/A class Predecoder; 592292SN/A} 601060SN/A 611060SN/Aclass CPUProgressEvent : public Event 621060SN/A{ 631061SN/A protected: 644636Sgblack@eecs.umich.edu Tick interval; 653801Sgblack@eecs.umich.edu Counter lastNumInst; 664636Sgblack@eecs.umich.edu BaseCPU *cpu; 673794Sgblack@eecs.umich.edu 684636Sgblack@eecs.umich.edu public: 693794Sgblack@eecs.umich.edu CPUProgressEvent(BaseCPU *_cpu, Tick ival); 704636Sgblack@eecs.umich.edu 711060SN/A void process(); 721464SN/A 731061SN/A virtual const char *description() const; 744636Sgblack@eecs.umich.edu}; 754654Sgblack@eecs.umich.edu 764636Sgblack@eecs.umich.educlass BaseCPU : public MemObject 771464SN/A{ 784636Sgblack@eecs.umich.edu protected: 794636Sgblack@eecs.umich.edu // CPU's clock period in terms of the number of ticks of curTime. 804636Sgblack@eecs.umich.edu Tick clock; 814636Sgblack@eecs.umich.edu // @todo remove me after debugging with legion done 824636Sgblack@eecs.umich.edu Tick instCnt; 834636Sgblack@eecs.umich.edu // every cpu has an id, put it in the base cpu 844636Sgblack@eecs.umich.edu // Set at initialization, only time a cpuId might change is during a 854636Sgblack@eecs.umich.edu // takeover (which should be done from within the BaseCPU anyway, 864636Sgblack@eecs.umich.edu // therefore no setCpuId() method is provided 874636Sgblack@eecs.umich.edu int _cpuId; 881464SN/A 893794Sgblack@eecs.umich.edu public: 904636Sgblack@eecs.umich.edu /** Reads this CPU's ID. */ 914636Sgblack@eecs.umich.edu int cpuId() { return _cpuId; } 924636Sgblack@eecs.umich.edu 934636Sgblack@eecs.umich.edu// Tick currentTick; 944636Sgblack@eecs.umich.edu inline Tick frequency() const { return Clock::Frequency / clock; } 954636Sgblack@eecs.umich.edu inline Tick ticks(int numCycles) const { return clock * numCycles; } 964636Sgblack@eecs.umich.edu inline Tick curCycle() const { return curTick / clock; } 974636Sgblack@eecs.umich.edu inline Tick tickToCycles(Tick val) const { return val / clock; } 984636Sgblack@eecs.umich.edu // @todo remove me after debugging with legion done 994636Sgblack@eecs.umich.edu Tick instCount() { return instCnt; } 1004636Sgblack@eecs.umich.edu 1014636Sgblack@eecs.umich.edu /** The next cycle the CPU should be scheduled, given a cache 1024636Sgblack@eecs.umich.edu * access or quiesce event returning on this cycle. This function 1034654Sgblack@eecs.umich.edu * may return curTick if the CPU should run on the current cycle. 1044636Sgblack@eecs.umich.edu */ 1054636Sgblack@eecs.umich.edu Tick nextCycle(); 1064636Sgblack@eecs.umich.edu 1074636Sgblack@eecs.umich.edu /** The next cycle the CPU should be scheduled, given a cache 1084654Sgblack@eecs.umich.edu * access or quiesce event returning on the given Tick. This 1094636Sgblack@eecs.umich.edu * function may return curTick if the CPU should run on the 1104636Sgblack@eecs.umich.edu * current cycle. 1114636Sgblack@eecs.umich.edu * @param begin_tick The tick that the event is completing on. 1124636Sgblack@eecs.umich.edu */ 1134636Sgblack@eecs.umich.edu Tick nextCycle(Tick begin_tick); 1144636Sgblack@eecs.umich.edu 1154636Sgblack@eecs.umich.edu TheISA::MicrocodeRom microcodeRom; 1164636Sgblack@eecs.umich.edu 1174636Sgblack@eecs.umich.edu#if FULL_SYSTEM 1184636Sgblack@eecs.umich.edu protected: 1194636Sgblack@eecs.umich.edu TheISA::Interrupts *interrupts; 1204636Sgblack@eecs.umich.edu 1214636Sgblack@eecs.umich.edu public: 1224636Sgblack@eecs.umich.edu TheISA::Interrupts * 1234636Sgblack@eecs.umich.edu getInterruptController() 1243794Sgblack@eecs.umich.edu { 1251464SN/A return interrupts; 1261464SN/A } 1271464SN/A 1281464SN/A virtual void postInterrupt(int int_num, int index); 1291464SN/A virtual void clearInterrupt(int int_num, int index); 1302107SN/A virtual void clearInterrupts(); 1311464SN/A 1321464SN/A bool 1332292SN/A checkInterrupts(ThreadContext *tc) const 1341464SN/A { 1351464SN/A return interrupts->checkInterrupts(tc); 1361464SN/A } 1371464SN/A 1381464SN/A class ProfileEvent : public Event 1391464SN/A { 1401464SN/A private: 1412678SN/A BaseCPU *cpu; 1422669SN/A Tick interval; 1434032Sktlim@umich.edu 1442669SN/A public: 1451060SN/A ProfileEvent(BaseCPU *cpu, Tick interval); 1464032Sktlim@umich.edu void process(); 1474032Sktlim@umich.edu }; 1481060SN/A ProfileEvent *profileEvent; 1491060SN/A#endif 1502702SN/A 1513326Sktlim@umich.edu protected: 1522702SN/A std::vector<ThreadContext *> threadContexts; 1532731SN/A std::vector<TheISA::Predecoder *> predecoders; 1542731SN/A 1551464SN/A Trace::InstTracer * tracer; 1562292SN/A 1577597Sminkyu.jeong@arm.com public: 1582731SN/A 1592292SN/A /// Provide access to the tracer pointer 1602292SN/A Trace::InstTracer * getTracer() { return tracer; } 1612292SN/A 1621060SN/A /// Notify the CPU that the indicated context is now active. The 1631060SN/A /// delay parameter indicates the number of ticks to wait before 1641464SN/A /// executing (typically 0 or 1). 1651060SN/A virtual void activateContext(int thread_num, int delay) {} 1661060SN/A 1671060SN/A /// Notify the CPU that the indicated context is now suspended. 1682698SN/A virtual void suspendContext(int thread_num) {} 1692292SN/A 1701060SN/A /// Notify the CPU that the indicated context is now deallocated. 1715737Scws3k@cs.virginia.edu virtual void deallocateContext(int thread_num) {} 1725737Scws3k@cs.virginia.edu 1731060SN/A /// Notify the CPU that the indicated context is now halted. 1745737Scws3k@cs.virginia.edu virtual void haltContext(int thread_num) {} 1755375Svilas.sridharan@gmail.com 1762292SN/A /// Given a Thread Context pointer return the thread num 1772292SN/A int findContext(ThreadContext *tc); 1782292SN/A 1795737Scws3k@cs.virginia.edu /// Given a thread num get tho thread context for it 1802292SN/A ThreadContext *getContext(int tn) { return threadContexts[tn]; } 1812292SN/A 1825737Scws3k@cs.virginia.edu public: 1835737Scws3k@cs.virginia.edu typedef BaseCPUParams Params; 1845737Scws3k@cs.virginia.edu const Params *params() const 1855737Scws3k@cs.virginia.edu { return reinterpret_cast<const Params *>(_params); } 1862292SN/A BaseCPU(Params *params); 1872292SN/A virtual ~BaseCPU(); 1882292SN/A 1892292SN/A virtual void init(); 1901060SN/A virtual void startup(); 1911060SN/A virtual void regStats(); 1921061SN/A 1931060SN/A virtual void activateWhenReady(int tid) {}; 1941060SN/A 1952678SN/A void registerThreadContexts(); 1962678SN/A 1972292SN/A /// Prepare for another CPU to take over execution. When it is 1982292SN/A /// is ready (drained pipe) it signals the sampler. 1992292SN/A virtual void switchOut(); 2002292SN/A 2012292SN/A /// Take over execution from the given CPU. Used for warm-up and 2022292SN/A /// sampling. 2032348SN/A virtual void takeOverFrom(BaseCPU *, Port *ic, Port *dc); 2042348SN/A 2055737Scws3k@cs.virginia.edu /** 2065737Scws3k@cs.virginia.edu * Number of threads we're actually simulating (<= SMT_MAX_THREADS). 2072292SN/A * This is a constant for the duration of the simulation. 2085737Scws3k@cs.virginia.edu */ 2095737Scws3k@cs.virginia.edu int number_of_threads; 2105737Scws3k@cs.virginia.edu 2115737Scws3k@cs.virginia.edu TheISA::CoreSpecific coreParams; //ISA-Specific Params That Set Up State in Core 2122292SN/A 2132292SN/A /** 2142292SN/A * Vector of per-thread instruction-based event queues. Used for 2151060SN/A * scheduling events based on number of instructions committed by 2161464SN/A * a particular thread. 2172292SN/A */ 2182292SN/A EventQueue **comInstEventQueue; 2192292SN/A 2202292SN/A /** 2212292SN/A * Vector of per-thread load-based event queues. Used for 2222292SN/A * scheduling events based on number of loads committed by 2232292SN/A *a particular thread. 2242292SN/A */ 2252292SN/A EventQueue **comLoadEventQueue; 2262292SN/A 2272292SN/A System *system; 2282292SN/A 2292292SN/A Tick phase; 2302292SN/A 2312292SN/A#if FULL_SYSTEM 2322292SN/A /** 2331061SN/A * Serialize this object to the given output stream. 2341060SN/A * @param os The stream to serialize to. 2351060SN/A */ 2361060SN/A virtual void serialize(std::ostream &os); 2371060SN/A 2381060SN/A /** 2391060SN/A * Reconstruct the state of this object from a checkpoint. 2402669SN/A * @param cp The checkpoint use. 2411060SN/A * @param section The section name of this object 2422292SN/A */ 2431060SN/A virtual void unserialize(Checkpoint *cp, const std::string §ion); 2441060SN/A 2451060SN/A#endif 2462090SN/A 2471060SN/A /** 2481060SN/A * Return pointer to CPU's branch predictor (NULL if none). 2492292SN/A * @return Branch predictor pointer. 2501060SN/A */ 2513172Sstever@eecs.umich.edu virtual BranchPred *getBranchPred() { return NULL; }; 2521060SN/A 2531060SN/A virtual Counter totalInstructions() const { return 0; } 2541060SN/A 2551060SN/A // Function tracing 2561060SN/A private: 2571060SN/A bool functionTracingEnabled; 2581060SN/A std::ostream *functionTraceStream; 2591060SN/A Addr currentFunctionStart; 2601060SN/A Addr currentFunctionEnd; 2611060SN/A Tick functionEntryTick; 2621060SN/A void enableFunctionTrace(); 2631060SN/A void traceFunctionsInternal(Addr pc); 2641060SN/A 2651060SN/A protected: 2661060SN/A void traceFunctions(Addr pc) 2671060SN/A { 2682669SN/A if (functionTracingEnabled) 2691060SN/A traceFunctionsInternal(pc); 2701060SN/A } 2711061SN/A 2721060SN/A private: 2731060SN/A static std::vector<BaseCPU *> cpuList; //!< Static global cpu list 2741060SN/A 2752702SN/A public: 2761060SN/A static int numSimulatedCPUs() { return cpuList.size(); } 2771060SN/A static Counter numSimulatedInstructions() 2781060SN/A { 2791060SN/A Counter total = 0; 2801060SN/A 2811061SN/A int size = cpuList.size(); 2822132SN/A for (int i = 0; i < size; ++i) 2831060SN/A total += cpuList[i]->totalInstructions(); 2841060SN/A 2852702SN/A return total; 2862669SN/A } 2871060SN/A 2881060SN/A public: 2891060SN/A // Number of CPU cycles simulated 2901060SN/A Stats::Scalar<> numCycles; 2911060SN/A}; 2921061SN/A 2932132SN/A#endif // __CPU_BASE_HH__ 2941060SN/A