base.hh revision 11428:20264eb69fbf
111988Sandreas.sandberg@arm.com/* 28840Sandreas.hansson@arm.com * Copyright (c) 2011-2013 ARM Limited 38840Sandreas.hansson@arm.com * All rights reserved 48840Sandreas.hansson@arm.com * 58840Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 68840Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 78840Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 88840Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 98840Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 108840Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 118840Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 128840Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 132740SN/A * 149983Sstever@gmail.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 159983Sstever@gmail.com * Copyright (c) 2011 Regents of the University of California 161046SN/A * All rights reserved. 171046SN/A * 181046SN/A * Redistribution and use in source and binary forms, with or without 191046SN/A * modification, are permitted provided that the following conditions are 201046SN/A * met: redistributions of source code must retain the above copyright 211046SN/A * notice, this list of conditions and the following disclaimer; 221046SN/A * redistributions in binary form must reproduce the above copyright 231046SN/A * notice, this list of conditions and the following disclaimer in the 241046SN/A * documentation and/or other materials provided with the distribution; 251046SN/A * neither the name of the copyright holders nor the names of its 261046SN/A * contributors may be used to endorse or promote products derived from 271046SN/A * this software without specific prior written permission. 281046SN/A * 291046SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 301046SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 311046SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 321046SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 331046SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 341046SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 351046SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 361046SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 371046SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 381046SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 391046SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402665SN/A * 412665SN/A * Authors: Steve Reinhardt 422665SN/A * Nathan Binkert 438840Sandreas.hansson@arm.com * Rick Strong 4411988Sandreas.sandberg@arm.com */ 451046SN/A 465766Snate@binkert.org#ifndef __CPU_BASE_HH__ 478331Ssteve.reinhardt@amd.com#define __CPU_BASE_HH__ 4811988Sandreas.sandberg@arm.com 4911988Sandreas.sandberg@arm.com#include <vector> 501438SN/A 514762Snate@binkert.org// Before we do anything else, check if this build is the NULL ISA, 526654Snate@binkert.org// and if so stop here 5311988Sandreas.sandberg@arm.com#include "config/the_isa.hh" 543102Sstever@eecs.umich.edu#if THE_ISA == NULL_ISA 553102Sstever@eecs.umich.edu#include "arch/null/cpu_dummy.hh" 563102Sstever@eecs.umich.edu#else 573102Sstever@eecs.umich.edu#include "arch/interrupts.hh" 586654Snate@binkert.org#include "arch/isa_traits.hh" 593102Sstever@eecs.umich.edu#include "arch/microcode_rom.hh" 603102Sstever@eecs.umich.edu#include "base/statistics.hh" 617528Ssteve.reinhardt@amd.com#include "mem/mem_object.hh" 628839Sandreas.hansson@arm.com#include "sim/eventq.hh" 633102Sstever@eecs.umich.edu#include "sim/full_system.hh" 646654Snate@binkert.org#include "sim/insttracer.hh" 656654Snate@binkert.org#include "sim/probe/pmu.hh" 66679SN/A#include "sim/system.hh" 67679SN/A#include "debug/Mwait.hh" 68679SN/A 69679SN/Aclass BaseCPU; 70679SN/Astruct BaseCPUParams; 71679SN/Aclass CheckerCPU; 721692SN/Aclass ThreadContext; 73679SN/A 74679SN/Astruct AddressMonitor 75679SN/A{ 76679SN/A AddressMonitor(); 77679SN/A bool doMonitor(PacketPtr pkt); 78679SN/A 79679SN/A bool armed; 80679SN/A Addr vAddr; 81679SN/A Addr pAddr; 82679SN/A uint64_t val; 83679SN/A bool waiting; // 0=normal, 1=mwaiting 84679SN/A bool gotWakeup; 85679SN/A}; 86679SN/A 871692SN/Aclass CPUProgressEvent : public Event 88679SN/A{ 89679SN/A protected: 90679SN/A Tick _interval; 91679SN/A Counter lastNumInst; 92679SN/A BaseCPU *cpu; 93679SN/A bool _repeatEvent; 94679SN/A 95679SN/A public: 96679SN/A CPUProgressEvent(BaseCPU *_cpu, Tick ival = 0); 97679SN/A 98679SN/A void process(); 99679SN/A 100679SN/A void interval(Tick ival) { _interval = ival; } 101679SN/A Tick interval() { return _interval; } 102679SN/A 1032740SN/A void repeatEvent(bool repeat) { _repeatEvent = repeat; } 104679SN/A 105679SN/A virtual const char *description() const; 106679SN/A}; 1074762Snate@binkert.org 1084762Snate@binkert.orgclass BaseCPU : public MemObject 1094762Snate@binkert.org{ 1102738SN/A protected: 1112738SN/A 1122738SN/A /// Instruction count used for SPARC misc register 1139338SAndreas.Sandberg@arm.com /// @todo unify this with the counters that cpus individually keep 1149338SAndreas.Sandberg@arm.com Tick instCnt; 1159338SAndreas.Sandberg@arm.com 1167673Snate@binkert.org // every cpu has an id, put it in the base cpu 1177673Snate@binkert.org // Set at initialization, only time a cpuId might change is during a 1188331Ssteve.reinhardt@amd.com // takeover (which should be done from within the BaseCPU anyway, 1198331Ssteve.reinhardt@amd.com // therefore no setCpuId() method is provided 1207673Snate@binkert.org int _cpuId; 12110458Sandreas.hansson@arm.com 12210458Sandreas.hansson@arm.com /** Each cpu will have a socket ID that corresponds to its physical location 12310458Sandreas.hansson@arm.com * in the system. This is usually used to bucket cpu cores under single DVFS 12410458Sandreas.hansson@arm.com * domain. This information may also be required by the OS to identify the 12510458Sandreas.hansson@arm.com * cpu core grouping (as in the case of ARM via MPIDR register) 12610458Sandreas.hansson@arm.com */ 12710458Sandreas.hansson@arm.com const uint32_t _socketId; 12810458Sandreas.hansson@arm.com 12910458Sandreas.hansson@arm.com /** instruction side request id that must be placed in all requests */ 13010458Sandreas.hansson@arm.com MasterID _instMasterId; 13110458Sandreas.hansson@arm.com 13210458Sandreas.hansson@arm.com /** data side request id that must be placed in all requests */ 13310458Sandreas.hansson@arm.com MasterID _dataMasterId; 13410458Sandreas.hansson@arm.com 13510458Sandreas.hansson@arm.com /** An intrenal representation of a task identifier within gem5. This is 13610458Sandreas.hansson@arm.com * used so the CPU can add which taskId (which is an internal representation 13710458Sandreas.hansson@arm.com * of the OS process ID) to each request so components in the memory system 13810458Sandreas.hansson@arm.com * can track which process IDs are ultimately interacting with them 13910458Sandreas.hansson@arm.com */ 14010458Sandreas.hansson@arm.com uint32_t _taskId; 14110458Sandreas.hansson@arm.com 14210458Sandreas.hansson@arm.com /** The current OS process ID that is executing on this processor. This is 14310458Sandreas.hansson@arm.com * used to generate a taskId */ 14410458Sandreas.hansson@arm.com uint32_t _pid; 14510458Sandreas.hansson@arm.com 14610458Sandreas.hansson@arm.com /** Is the CPU switched out or active? */ 14710458Sandreas.hansson@arm.com bool _switchedOut; 14810458Sandreas.hansson@arm.com 14910458Sandreas.hansson@arm.com /** Cache the cache line size that we get from the system */ 15010458Sandreas.hansson@arm.com const unsigned int _cacheLineSize; 15110458Sandreas.hansson@arm.com 15210458Sandreas.hansson@arm.com public: 15310458Sandreas.hansson@arm.com 15410458Sandreas.hansson@arm.com /** 15510458Sandreas.hansson@arm.com * Purely virtual method that returns a reference to the data 15610458Sandreas.hansson@arm.com * port. All subclasses must implement this method. 15710458Sandreas.hansson@arm.com * 15810458Sandreas.hansson@arm.com * @return a reference to the data port 15910458Sandreas.hansson@arm.com */ 16010458Sandreas.hansson@arm.com virtual MasterPort &getDataPort() = 0; 16110458Sandreas.hansson@arm.com 16210458Sandreas.hansson@arm.com /** 16310458Sandreas.hansson@arm.com * Purely virtual method that returns a reference to the instruction 16410458Sandreas.hansson@arm.com * port. All subclasses must implement this method. 16510458Sandreas.hansson@arm.com * 16610458Sandreas.hansson@arm.com * @return a reference to the instruction port 16710458Sandreas.hansson@arm.com */ 16810458Sandreas.hansson@arm.com virtual MasterPort &getInstPort() = 0; 16910458Sandreas.hansson@arm.com 17010458Sandreas.hansson@arm.com /** Reads this CPU's ID. */ 17110458Sandreas.hansson@arm.com int cpuId() const { return _cpuId; } 17210458Sandreas.hansson@arm.com 17310458Sandreas.hansson@arm.com /** Reads this CPU's Socket ID. */ 17410458Sandreas.hansson@arm.com uint32_t socketId() const { return _socketId; } 17510458Sandreas.hansson@arm.com 17610458Sandreas.hansson@arm.com /** Reads this CPU's unique data requestor ID */ 17710458Sandreas.hansson@arm.com MasterID dataMasterId() { return _dataMasterId; } 17810458Sandreas.hansson@arm.com /** Reads this CPU's unique instruction requestor ID */ 17910458Sandreas.hansson@arm.com MasterID instMasterId() { return _instMasterId; } 18010458Sandreas.hansson@arm.com 18110458Sandreas.hansson@arm.com /** 18210458Sandreas.hansson@arm.com * Get a master port on this CPU. All CPUs have a data and 18310458Sandreas.hansson@arm.com * instruction port, and this method uses getDataPort and 18410458Sandreas.hansson@arm.com * getInstPort of the subclasses to resolve the two ports. 18510458Sandreas.hansson@arm.com * 18610458Sandreas.hansson@arm.com * @param if_name the port name 18710458Sandreas.hansson@arm.com * @param idx ignored index 18810458Sandreas.hansson@arm.com * 18910458Sandreas.hansson@arm.com * @return a reference to the port with the given name 19010458Sandreas.hansson@arm.com */ 19110458Sandreas.hansson@arm.com BaseMasterPort &getMasterPort(const std::string &if_name, 19210458Sandreas.hansson@arm.com PortID idx = InvalidPortID) override; 19310458Sandreas.hansson@arm.com 19410458Sandreas.hansson@arm.com /** Get cpu task id */ 19510458Sandreas.hansson@arm.com uint32_t taskId() const { return _taskId; } 19610458Sandreas.hansson@arm.com /** Set cpu task id */ 19710458Sandreas.hansson@arm.com void taskId(uint32_t id) { _taskId = id; } 19810458Sandreas.hansson@arm.com 19910458Sandreas.hansson@arm.com uint32_t getPid() const { return _pid; } 20010458Sandreas.hansson@arm.com void setPid(uint32_t pid) { _pid = pid; } 20110458Sandreas.hansson@arm.com 20210458Sandreas.hansson@arm.com inline void workItemBegin() { numWorkItemsStarted++; } 20310458Sandreas.hansson@arm.com inline void workItemEnd() { numWorkItemsCompleted++; } 20410458Sandreas.hansson@arm.com // @todo remove me after debugging with legion done 20510458Sandreas.hansson@arm.com Tick instCount() { return instCnt; } 20610458Sandreas.hansson@arm.com 20710458Sandreas.hansson@arm.com TheISA::MicrocodeRom microcodeRom; 20810458Sandreas.hansson@arm.com 20910458Sandreas.hansson@arm.com protected: 21010458Sandreas.hansson@arm.com std::vector<TheISA::Interrupts*> interrupts; 21110458Sandreas.hansson@arm.com 21210458Sandreas.hansson@arm.com public: 21310458Sandreas.hansson@arm.com TheISA::Interrupts * 21410458Sandreas.hansson@arm.com getInterruptController(ThreadID tid) 21510458Sandreas.hansson@arm.com { 21610458Sandreas.hansson@arm.com if (interrupts.empty()) 21710458Sandreas.hansson@arm.com return NULL; 21810458Sandreas.hansson@arm.com 21910458Sandreas.hansson@arm.com assert(interrupts.size() > tid); 22010458Sandreas.hansson@arm.com return interrupts[tid]; 22110458Sandreas.hansson@arm.com } 22210458Sandreas.hansson@arm.com 22310458Sandreas.hansson@arm.com virtual void wakeup(ThreadID tid) = 0; 22410458Sandreas.hansson@arm.com 22510458Sandreas.hansson@arm.com void 22610458Sandreas.hansson@arm.com postInterrupt(ThreadID tid, int int_num, int index) 22710458Sandreas.hansson@arm.com { 22810458Sandreas.hansson@arm.com interrupts[tid]->post(int_num, index); 22910458Sandreas.hansson@arm.com if (FullSystem) 23010458Sandreas.hansson@arm.com wakeup(tid); 23110458Sandreas.hansson@arm.com } 23210458Sandreas.hansson@arm.com 23310458Sandreas.hansson@arm.com void 23410458Sandreas.hansson@arm.com clearInterrupt(ThreadID tid, int int_num, int index) 23510458Sandreas.hansson@arm.com { 23610458Sandreas.hansson@arm.com interrupts[tid]->clear(int_num, index); 23710458Sandreas.hansson@arm.com } 23810458Sandreas.hansson@arm.com 23910458Sandreas.hansson@arm.com void 24010458Sandreas.hansson@arm.com clearInterrupts(ThreadID tid) 24110458Sandreas.hansson@arm.com { 24210458Sandreas.hansson@arm.com interrupts[tid]->clearAll(); 24310458Sandreas.hansson@arm.com } 24410458Sandreas.hansson@arm.com 24510458Sandreas.hansson@arm.com bool 24610458Sandreas.hansson@arm.com checkInterrupts(ThreadContext *tc) const 24710458Sandreas.hansson@arm.com { 24810458Sandreas.hansson@arm.com return FullSystem && interrupts[tc->threadId()]->checkInterrupts(tc); 24910458Sandreas.hansson@arm.com } 25010458Sandreas.hansson@arm.com 25110458Sandreas.hansson@arm.com class ProfileEvent : public Event 25210458Sandreas.hansson@arm.com { 25310458Sandreas.hansson@arm.com private: 25410458Sandreas.hansson@arm.com BaseCPU *cpu; 25510458Sandreas.hansson@arm.com Tick interval; 25610458Sandreas.hansson@arm.com 25710458Sandreas.hansson@arm.com public: 25810458Sandreas.hansson@arm.com ProfileEvent(BaseCPU *cpu, Tick interval); 25910458Sandreas.hansson@arm.com void process(); 26010458Sandreas.hansson@arm.com }; 26110458Sandreas.hansson@arm.com ProfileEvent *profileEvent; 26210458Sandreas.hansson@arm.com 26310458Sandreas.hansson@arm.com protected: 26410458Sandreas.hansson@arm.com std::vector<ThreadContext *> threadContexts; 26510458Sandreas.hansson@arm.com 26610458Sandreas.hansson@arm.com Trace::InstTracer * tracer; 26710458Sandreas.hansson@arm.com 26810458Sandreas.hansson@arm.com public: 26910458Sandreas.hansson@arm.com 27010458Sandreas.hansson@arm.com 27110458Sandreas.hansson@arm.com /** Invalid or unknown Pid. Possible when operating system is not present 27210458Sandreas.hansson@arm.com * or has not assigned a pid yet */ 27310458Sandreas.hansson@arm.com static const uint32_t invldPid = std::numeric_limits<uint32_t>::max(); 27410458Sandreas.hansson@arm.com 27510458Sandreas.hansson@arm.com // Mask to align PCs to MachInst sized boundaries 27610458Sandreas.hansson@arm.com static const Addr PCMask = ~((Addr)sizeof(TheISA::MachInst) - 1); 27710458Sandreas.hansson@arm.com 27810458Sandreas.hansson@arm.com /// Provide access to the tracer pointer 27910458Sandreas.hansson@arm.com Trace::InstTracer * getTracer() { return tracer; } 28010458Sandreas.hansson@arm.com 28110458Sandreas.hansson@arm.com /// Notify the CPU that the indicated context is now active. 28210458Sandreas.hansson@arm.com virtual void activateContext(ThreadID thread_num); 28310458Sandreas.hansson@arm.com 28410458Sandreas.hansson@arm.com /// Notify the CPU that the indicated context is now suspended. 28510458Sandreas.hansson@arm.com /// Check if possible to enter a lower power state 28610458Sandreas.hansson@arm.com virtual void suspendContext(ThreadID thread_num); 28710458Sandreas.hansson@arm.com 28810458Sandreas.hansson@arm.com /// Notify the CPU that the indicated context is now halted. 28910458Sandreas.hansson@arm.com virtual void haltContext(ThreadID thread_num) {} 29010458Sandreas.hansson@arm.com 29110458Sandreas.hansson@arm.com /// Given a Thread Context pointer return the thread num 29210458Sandreas.hansson@arm.com int findContext(ThreadContext *tc); 29310458Sandreas.hansson@arm.com 29410458Sandreas.hansson@arm.com /// Given a thread num get tho thread context for it 29510458Sandreas.hansson@arm.com virtual ThreadContext *getContext(int tn) { return threadContexts[tn]; } 29610458Sandreas.hansson@arm.com 29710458Sandreas.hansson@arm.com /// Get the number of thread contexts available 29810458Sandreas.hansson@arm.com unsigned numContexts() { return threadContexts.size(); } 29910458Sandreas.hansson@arm.com 30010458Sandreas.hansson@arm.com /// Convert ContextID to threadID 30110458Sandreas.hansson@arm.com ThreadID contextToThread(ContextID cid) 30210458Sandreas.hansson@arm.com { return static_cast<ThreadID>(cid - threadContexts[0]->contextId()); } 30310458Sandreas.hansson@arm.com 30410458Sandreas.hansson@arm.com public: 30510458Sandreas.hansson@arm.com typedef BaseCPUParams Params; 30610458Sandreas.hansson@arm.com const Params *params() const 30710458Sandreas.hansson@arm.com { return reinterpret_cast<const Params *>(_params); } 30810458Sandreas.hansson@arm.com BaseCPU(Params *params, bool is_checker = false); 30910458Sandreas.hansson@arm.com virtual ~BaseCPU(); 31010458Sandreas.hansson@arm.com 31110458Sandreas.hansson@arm.com void init() override; 31210458Sandreas.hansson@arm.com void startup() override; 31310458Sandreas.hansson@arm.com void regStats() override; 31410458Sandreas.hansson@arm.com 31510458Sandreas.hansson@arm.com void regProbePoints() override; 31610458Sandreas.hansson@arm.com 31710458Sandreas.hansson@arm.com void registerThreadContexts(); 31810458Sandreas.hansson@arm.com 31910458Sandreas.hansson@arm.com /** 32010458Sandreas.hansson@arm.com * Prepare for another CPU to take over execution. 32110458Sandreas.hansson@arm.com * 32210458Sandreas.hansson@arm.com * When this method exits, all internal state should have been 32310458Sandreas.hansson@arm.com * flushed. After the method returns, the simulator calls 32410458Sandreas.hansson@arm.com * takeOverFrom() on the new CPU with this CPU as its parameter. 32510458Sandreas.hansson@arm.com */ 32610458Sandreas.hansson@arm.com virtual void switchOut(); 32710458Sandreas.hansson@arm.com 32810458Sandreas.hansson@arm.com /** 32910458Sandreas.hansson@arm.com * Load the state of a CPU from the previous CPU object, invoked 33010458Sandreas.hansson@arm.com * on all new CPUs that are about to be switched in. 33110458Sandreas.hansson@arm.com * 33210458Sandreas.hansson@arm.com * A CPU model implementing this method is expected to initialize 33310458Sandreas.hansson@arm.com * its state from the old CPU and connect its memory (unless they 33410458Sandreas.hansson@arm.com * are already connected) to the memories connected to the old 33510458Sandreas.hansson@arm.com * CPU. 33610458Sandreas.hansson@arm.com * 33710458Sandreas.hansson@arm.com * @param cpu CPU to initialize read state from. 33810458Sandreas.hansson@arm.com */ 33910458Sandreas.hansson@arm.com virtual void takeOverFrom(BaseCPU *cpu); 34010458Sandreas.hansson@arm.com 34110458Sandreas.hansson@arm.com /** 34210458Sandreas.hansson@arm.com * Flush all TLBs in the CPU. 34310458Sandreas.hansson@arm.com * 34410458Sandreas.hansson@arm.com * This method is mainly used to flush stale translations when 34510458Sandreas.hansson@arm.com * switching CPUs. It is also exported to the Python world to 34610458Sandreas.hansson@arm.com * allow it to request a TLB flush after draining the CPU to make 34710458Sandreas.hansson@arm.com * it easier to compare traces when debugging 34810458Sandreas.hansson@arm.com * handover/checkpointing. 34910458Sandreas.hansson@arm.com */ 35010458Sandreas.hansson@arm.com void flushTLBs(); 35110458Sandreas.hansson@arm.com 35210458Sandreas.hansson@arm.com /** 35310458Sandreas.hansson@arm.com * Determine if the CPU is switched out. 35410458Sandreas.hansson@arm.com * 35510458Sandreas.hansson@arm.com * @return True if the CPU is switched out, false otherwise. 35610458Sandreas.hansson@arm.com */ 35710458Sandreas.hansson@arm.com bool switchedOut() const { return _switchedOut; } 35810458Sandreas.hansson@arm.com 35910458Sandreas.hansson@arm.com /** 36010458Sandreas.hansson@arm.com * Verify that the system is in a memory mode supported by the 36110458Sandreas.hansson@arm.com * CPU. 36210458Sandreas.hansson@arm.com * 36310458Sandreas.hansson@arm.com * Implementations are expected to query the system for the 36410458Sandreas.hansson@arm.com * current memory mode and ensure that it is what the CPU model 36510458Sandreas.hansson@arm.com * expects. If the check fails, the implementation should 36610458Sandreas.hansson@arm.com * terminate the simulation using fatal(). 36710458Sandreas.hansson@arm.com */ 36810458Sandreas.hansson@arm.com virtual void verifyMemoryMode() const { }; 36910458Sandreas.hansson@arm.com 37010458Sandreas.hansson@arm.com /** 37110458Sandreas.hansson@arm.com * Number of threads we're actually simulating (<= SMT_MAX_THREADS). 37210458Sandreas.hansson@arm.com * This is a constant for the duration of the simulation. 37310458Sandreas.hansson@arm.com */ 37410458Sandreas.hansson@arm.com ThreadID numThreads; 37510458Sandreas.hansson@arm.com 37610458Sandreas.hansson@arm.com /** 37710458Sandreas.hansson@arm.com * Vector of per-thread instruction-based event queues. Used for 37810458Sandreas.hansson@arm.com * scheduling events based on number of instructions committed by 37910458Sandreas.hansson@arm.com * a particular thread. 38010458Sandreas.hansson@arm.com */ 38110458Sandreas.hansson@arm.com EventQueue **comInstEventQueue; 38210458Sandreas.hansson@arm.com 38310458Sandreas.hansson@arm.com /** 38410458Sandreas.hansson@arm.com * Vector of per-thread load-based event queues. Used for 38510458Sandreas.hansson@arm.com * scheduling events based on number of loads committed by 38610458Sandreas.hansson@arm.com *a particular thread. 38710458Sandreas.hansson@arm.com */ 38810458Sandreas.hansson@arm.com EventQueue **comLoadEventQueue; 38910458Sandreas.hansson@arm.com 39010458Sandreas.hansson@arm.com System *system; 39110458Sandreas.hansson@arm.com 39210458Sandreas.hansson@arm.com /** 3932740SN/A * Get the cache line size of the system. 3942740SN/A */ 3952740SN/A inline unsigned int cacheLineSize() const { return _cacheLineSize; } 3962740SN/A 3971692SN/A /** 3981427SN/A * Serialize this object to the given output stream. 39911988Sandreas.sandberg@arm.com * 40011988Sandreas.sandberg@arm.com * @note CPU models should normally overload the serializeThread() 40111988Sandreas.sandberg@arm.com * method instead of the serialize() method as this provides a 40211988Sandreas.sandberg@arm.com * uniform data format for all CPU models and promotes better code 40311988Sandreas.sandberg@arm.com * reuse. 40411988Sandreas.sandberg@arm.com * 40511988Sandreas.sandberg@arm.com * @param os The stream to serialize to. 40611988Sandreas.sandberg@arm.com */ 40711988Sandreas.sandberg@arm.com void serialize(CheckpointOut &cp) const override; 40811988Sandreas.sandberg@arm.com 4091427SN/A /** 4107493Ssteve.reinhardt@amd.com * Reconstruct the state of this object from a checkpoint. 411679SN/A * 412679SN/A * @note CPU models should normally overload the 413679SN/A * unserializeThread() method instead of the unserialize() method 4142740SN/A * as this provides a uniform data format for all CPU models and 415679SN/A * promotes better code reuse. 416679SN/A 4171310SN/A * @param cp The checkpoint use. 4186654Snate@binkert.org * @param section The section name of this object. 4194762Snate@binkert.org */ 4202740SN/A void unserialize(CheckpointIn &cp) override; 4212740SN/A 4222740SN/A /** 4232740SN/A * Serialize a single thread. 4242740SN/A * 42511988Sandreas.sandberg@arm.com * @param os The stream to serialize to. 4262740SN/A * @param tid ID of the current thread. 42711988Sandreas.sandberg@arm.com */ 42811988Sandreas.sandberg@arm.com virtual void serializeThread(CheckpointOut &cp, ThreadID tid) const {}; 42911988Sandreas.sandberg@arm.com 43011988Sandreas.sandberg@arm.com /** 43111988Sandreas.sandberg@arm.com * Unserialize one thread. 4327673Snate@binkert.org * 4332740SN/A * @param cp The checkpoint use. 4342740SN/A * @param section The section name of this thread. 4352740SN/A * @param tid ID of the current thread. 4362740SN/A */ 4374762Snate@binkert.org virtual void unserializeThread(CheckpointIn &cp, ThreadID tid) {}; 4384762Snate@binkert.org 4399342SAndreas.Sandberg@arm.com virtual Counter totalInsts() const = 0; 4409342SAndreas.Sandberg@arm.com 44111988Sandreas.sandberg@arm.com virtual Counter totalOps() const = 0; 44211988Sandreas.sandberg@arm.com 44311988Sandreas.sandberg@arm.com /** 44411988Sandreas.sandberg@arm.com * Schedule an event that exits the simulation loops after a 44511988Sandreas.sandberg@arm.com * predefined number of instructions. 44611988Sandreas.sandberg@arm.com * 4472740SN/A * This method is usually called from the configuration script to 4484762Snate@binkert.org * get an exit event some time in the future. It is typically used 4494762Snate@binkert.org * when the script wants to simulate for a specific number of 4504762Snate@binkert.org * instructions rather than ticks. 4514762Snate@binkert.org * 452679SN/A * @param tid Thread monitor. 4532711SN/A * @param insts Number of instructions into the future. 454679SN/A * @param cause Cause to signal in the exit event. 4552711SN/A */ 4562711SN/A void scheduleInstStop(ThreadID tid, Counter insts, const char *cause); 4571692SN/A 4581310SN/A /** 4591427SN/A * Schedule an event that exits the simulation loops after a 4602740SN/A * predefined number of load operations. 4612740SN/A * 4622740SN/A * This method is usually called from the configuration script to 4632740SN/A * get an exit event some time in the future. It is typically used 4642740SN/A * when the script wants to simulate for a specific number of 4652740SN/A * loads rather than ticks. 4662740SN/A * 46710267SGeoffrey.Blake@arm.com * @param tid Thread monitor. 4687528Ssteve.reinhardt@amd.com * @param loads Number of load instructions into the future. 4693105Sstever@eecs.umich.edu * @param cause Cause to signal in the exit event. 4702740SN/A */ 4711310SN/A void scheduleLoadStop(ThreadID tid, Counter loads, const char *cause); 4729100SBrad.Beckmann@amd.com 4739100SBrad.Beckmann@amd.com /** 4749100SBrad.Beckmann@amd.com * Get the number of instructions executed by the specified thread 4759100SBrad.Beckmann@amd.com * on this CPU. Used by Python to control simulation. 4769100SBrad.Beckmann@amd.com * 4779100SBrad.Beckmann@amd.com * @param tid Thread monitor 4789100SBrad.Beckmann@amd.com * @return Number of instructions executed 4799100SBrad.Beckmann@amd.com */ 4809100SBrad.Beckmann@amd.com uint64_t getCurrentInstCount(ThreadID tid); 4811692SN/A 4821692SN/A public: 4831692SN/A /** 4842740SN/A * @{ 4852740SN/A * @name PMU Probe points. 4862740SN/A */ 4872740SN/A 4881692SN/A /** 4895610Snate@binkert.org * Helper method to trigger PMU probes for a committed 4901692SN/A * instruction. 4912740SN/A * 4921692SN/A * @param inst Instruction that just committed 49310267SGeoffrey.Blake@arm.com */ 4947528Ssteve.reinhardt@amd.com virtual void probeInstCommit(const StaticInstPtr &inst); 4953105Sstever@eecs.umich.edu 4962740SN/A /** 4972712SN/A * Helper method to instantiate probe points belonging to this 4985610Snate@binkert.org * object. 4995610Snate@binkert.org * 5001692SN/A * @param name Name of the probe point. 5014762Snate@binkert.org * @return A unique_ptr to the new probe point. 5024762Snate@binkert.org */ 5034762Snate@binkert.org ProbePoints::PMUUPtr pmuProbePoint(const char *name); 5045610Snate@binkert.org 5054762Snate@binkert.org /** CPU cycle counter */ 5065610Snate@binkert.org ProbePoints::PMUUPtr ppCycles; 5074859Snate@binkert.org 5089338SAndreas.Sandberg@arm.com /** 5099338SAndreas.Sandberg@arm.com * Instruction commit probe point. 5109338SAndreas.Sandberg@arm.com * 5119528Ssascha.bischoff@arm.com * This probe point is triggered whenever one or more instructions 5129338SAndreas.Sandberg@arm.com * are committed. It is normally triggered once for every 5132740SN/A * instruction. However, CPU models committing bundles of 5142740SN/A * instructions may call notify once for the entire bundle. 5152740SN/A */ 5162740SN/A ProbePoints::PMUUPtr ppRetiredInsts; 5172740SN/A 5182740SN/A /** Retired load instructions */ 5192740SN/A ProbePoints::PMUUPtr ppRetiredLoads; 5202740SN/A /** Retired store instructions */ 5211527SN/A ProbePoints::PMUUPtr ppRetiredStores; 5222740SN/A 5231585SN/A /** Retired branches (any type) */ 5241427SN/A ProbePoints::PMUUPtr ppRetiredBranches; 5252738SN/A 5262738SN/A /** @} */ 5273105Sstever@eecs.umich.edu 5282738SN/A 5291427SN/A 5301427SN/A // Function tracing 5311427SN/A private: 5321427SN/A bool functionTracingEnabled; 5331427SN/A std::ostream *functionTraceStream; 5341427SN/A Addr currentFunctionStart; 5351427SN/A Addr currentFunctionEnd; 5361427SN/A Tick functionEntryTick; 5371427SN/A void enableFunctionTrace(); 5381427SN/A void traceFunctionsInternal(Addr pc); 5391427SN/A 5401427SN/A private: 5417493Ssteve.reinhardt@amd.com static std::vector<BaseCPU *> cpuList; //!< Static global cpu list 5421427SN/A 5431427SN/A public: 5441427SN/A void traceFunctions(Addr pc) 5453100SN/A { 5463100SN/A if (functionTracingEnabled) 5473100SN/A traceFunctionsInternal(pc); 5483100SN/A } 5493100SN/A 5503100SN/A static int numSimulatedCPUs() { return cpuList.size(); } 5513105Sstever@eecs.umich.edu static Counter numSimulatedInsts() 5523105Sstever@eecs.umich.edu { 5533105Sstever@eecs.umich.edu Counter total = 0; 5543105Sstever@eecs.umich.edu 5553105Sstever@eecs.umich.edu int size = cpuList.size(); 55610267SGeoffrey.Blake@arm.com for (int i = 0; i < size; ++i) 5578321Ssteve.reinhardt@amd.com total += cpuList[i]->totalInsts(); 5583105Sstever@eecs.umich.edu 5593105Sstever@eecs.umich.edu return total; 5603105Sstever@eecs.umich.edu } 5613105Sstever@eecs.umich.edu 5623105Sstever@eecs.umich.edu static Counter numSimulatedOps() 5638321Ssteve.reinhardt@amd.com { 5648321Ssteve.reinhardt@amd.com Counter total = 0; 5658321Ssteve.reinhardt@amd.com 5668321Ssteve.reinhardt@amd.com int size = cpuList.size(); 5678321Ssteve.reinhardt@amd.com for (int i = 0; i < size; ++i) 56810267SGeoffrey.Blake@arm.com total += cpuList[i]->totalOps(); 56910267SGeoffrey.Blake@arm.com 57010267SGeoffrey.Blake@arm.com return total; 57110267SGeoffrey.Blake@arm.com } 57210267SGeoffrey.Blake@arm.com 5738321Ssteve.reinhardt@amd.com public: 5748321Ssteve.reinhardt@amd.com // Number of CPU cycles simulated 5758321Ssteve.reinhardt@amd.com Stats::Scalar numCycles; 5768321Ssteve.reinhardt@amd.com Stats::Scalar numWorkItemsStarted; 5778321Ssteve.reinhardt@amd.com Stats::Scalar numWorkItemsCompleted; 5788321Ssteve.reinhardt@amd.com 5798321Ssteve.reinhardt@amd.com private: 5808321Ssteve.reinhardt@amd.com std::vector<AddressMonitor> addressMonitor; 5818321Ssteve.reinhardt@amd.com 5823105Sstever@eecs.umich.edu public: 5833105Sstever@eecs.umich.edu void armMonitor(ThreadID tid, Addr address); 5843105Sstever@eecs.umich.edu bool mwait(ThreadID tid, PacketPtr pkt); 5853105Sstever@eecs.umich.edu void mwaitAtomic(ThreadID tid, ThreadContext *tc, TheISA::TLB *dtb); 5863105Sstever@eecs.umich.edu AddressMonitor *getCpuAddrMonitor(ThreadID tid) 5873105Sstever@eecs.umich.edu { 5883105Sstever@eecs.umich.edu assert(tid < numThreads); 5893105Sstever@eecs.umich.edu return &addressMonitor[tid]; 5903105Sstever@eecs.umich.edu } 5913105Sstever@eecs.umich.edu}; 5923105Sstever@eecs.umich.edu 5933105Sstever@eecs.umich.edu#endif // THE_ISA == NULL_ISA 5943105Sstever@eecs.umich.edu 5953105Sstever@eecs.umich.edu#endif // __CPU_BASE_HH__ 5963105Sstever@eecs.umich.edu