12SN/A/* 212276Sanouk.vanlaer@arm.com * Copyright (c) 2011-2013, 2017 ARM Limited 38707Sandreas.hansson@arm.com * All rights reserved 48707Sandreas.hansson@arm.com * 58707Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 68707Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 78707Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 88707Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 98707Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 108707Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 118707Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 128707Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 138707Sandreas.hansson@arm.com * 141762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 157897Shestness@cs.utexas.edu * Copyright (c) 2011 Regents of the University of California 162SN/A * All rights reserved. 172SN/A * 182SN/A * Redistribution and use in source and binary forms, with or without 192SN/A * modification, are permitted provided that the following conditions are 202SN/A * met: redistributions of source code must retain the above copyright 212SN/A * notice, this list of conditions and the following disclaimer; 222SN/A * redistributions in binary form must reproduce the above copyright 232SN/A * notice, this list of conditions and the following disclaimer in the 242SN/A * documentation and/or other materials provided with the distribution; 252SN/A * neither the name of the copyright holders nor the names of its 262SN/A * contributors may be used to endorse or promote products derived from 272SN/A * this software without specific prior written permission. 282SN/A * 292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 302SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 312SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 322SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 332SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 342SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 352SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 362SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 372SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 382SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 392SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402665Ssaidi@eecs.umich.edu * 412665Ssaidi@eecs.umich.edu * Authors: Steve Reinhardt 422665Ssaidi@eecs.umich.edu * Nathan Binkert 437897Shestness@cs.utexas.edu * Rick Strong 442SN/A */ 452SN/A 461717SN/A#ifndef __CPU_BASE_HH__ 471717SN/A#define __CPU_BASE_HH__ 482SN/A 492SN/A#include <vector> 502SN/A 519850Sandreas.hansson@arm.com// Before we do anything else, check if this build is the NULL ISA, 529850Sandreas.hansson@arm.com// and if so stop here 539850Sandreas.hansson@arm.com#include "config/the_isa.hh" 549850Sandreas.hansson@arm.com#if THE_ISA == NULL_ISA 559850Sandreas.hansson@arm.com#include "arch/null/cpu_dummy.hh" 569850Sandreas.hansson@arm.com#else 578745Sgblack@eecs.umich.edu#include "arch/interrupts.hh" 584182Sgblack@eecs.umich.edu#include "arch/isa_traits.hh" 595664Sgblack@eecs.umich.edu#include "arch/microcode_rom.hh" 60707SN/A#include "base/statistics.hh" 6113892Sgabeblack@google.com#include "sim/clocked_object.hh" 6256SN/A#include "sim/eventq.hh" 638779Sgblack@eecs.umich.edu#include "sim/full_system.hh" 644776Sgblack@eecs.umich.edu#include "sim/insttracer.hh" 6510464SAndreas.Sandberg@ARM.com#include "sim/probe/pmu.hh" 6612284Sjose.marinho@arm.com#include "sim/probe/probe.hh" 679814Sandreas.hansson@arm.com#include "sim/system.hh" 6810529Smorr@cs.wisc.edu#include "debug/Mwait.hh" 692SN/A 7010529Smorr@cs.wisc.educlass BaseCPU; 718901Sandreas.hansson@arm.comstruct BaseCPUParams; 722315SN/Aclass CheckerCPU; 732680Sktlim@umich.educlass ThreadContext; 742SN/A 7510529Smorr@cs.wisc.edustruct AddressMonitor 7610529Smorr@cs.wisc.edu{ 7710529Smorr@cs.wisc.edu AddressMonitor(); 7810529Smorr@cs.wisc.edu bool doMonitor(PacketPtr pkt); 7910529Smorr@cs.wisc.edu 8010529Smorr@cs.wisc.edu bool armed; 8110529Smorr@cs.wisc.edu Addr vAddr; 8210529Smorr@cs.wisc.edu Addr pAddr; 8310529Smorr@cs.wisc.edu uint64_t val; 8410529Smorr@cs.wisc.edu bool waiting; // 0=normal, 1=mwaiting 8510529Smorr@cs.wisc.edu bool gotWakeup; 8610529Smorr@cs.wisc.edu}; 8710529Smorr@cs.wisc.edu 882356SN/Aclass CPUProgressEvent : public Event 892356SN/A{ 902356SN/A protected: 916144Sksewell@umich.edu Tick _interval; 922356SN/A Counter lastNumInst; 932356SN/A BaseCPU *cpu; 946144Sksewell@umich.edu bool _repeatEvent; 952356SN/A 962356SN/A public: 976144Sksewell@umich.edu CPUProgressEvent(BaseCPU *_cpu, Tick ival = 0); 982356SN/A 992356SN/A void process(); 1002356SN/A 1016144Sksewell@umich.edu void interval(Tick ival) { _interval = ival; } 1026144Sksewell@umich.edu Tick interval() { return _interval; } 1036144Sksewell@umich.edu 1046144Sksewell@umich.edu void repeatEvent(bool repeat) { _repeatEvent = repeat; } 1056144Sksewell@umich.edu 1065336Shines@cs.fsu.edu virtual const char *description() const; 1072356SN/A}; 1082356SN/A 10913892Sgabeblack@google.comclass BaseCPU : public ClockedObject 1102SN/A{ 1111634SN/A protected: 1129157Sandreas.hansson@arm.com 11310662SAli.Saidi@ARM.com /// Instruction count used for SPARC misc register 11410662SAli.Saidi@ARM.com /// @todo unify this with the counters that cpus individually keep 1153814Ssaidi@eecs.umich.edu Tick instCnt; 11610662SAli.Saidi@ARM.com 1175712Shsul@eecs.umich.edu // every cpu has an id, put it in the base cpu 1185712Shsul@eecs.umich.edu // Set at initialization, only time a cpuId might change is during a 1195715Shsul@eecs.umich.edu // takeover (which should be done from within the BaseCPU anyway, 1205712Shsul@eecs.umich.edu // therefore no setCpuId() method is provided 1215712Shsul@eecs.umich.edu int _cpuId; 1221634SN/A 12310190Sakash.bagdia@arm.com /** Each cpu will have a socket ID that corresponds to its physical location 12410190Sakash.bagdia@arm.com * in the system. This is usually used to bucket cpu cores under single DVFS 12510190Sakash.bagdia@arm.com * domain. This information may also be required by the OS to identify the 12610190Sakash.bagdia@arm.com * cpu core grouping (as in the case of ARM via MPIDR register) 12710190Sakash.bagdia@arm.com */ 12810190Sakash.bagdia@arm.com const uint32_t _socketId; 12910190Sakash.bagdia@arm.com 1308832SAli.Saidi@ARM.com /** instruction side request id that must be placed in all requests */ 1318832SAli.Saidi@ARM.com MasterID _instMasterId; 1328832SAli.Saidi@ARM.com 1338832SAli.Saidi@ARM.com /** data side request id that must be placed in all requests */ 1348832SAli.Saidi@ARM.com MasterID _dataMasterId; 1358832SAli.Saidi@ARM.com 1369332Sdam.sunwoo@arm.com /** An intrenal representation of a task identifier within gem5. This is 1379332Sdam.sunwoo@arm.com * used so the CPU can add which taskId (which is an internal representation 1389332Sdam.sunwoo@arm.com * of the OS process ID) to each request so components in the memory system 1399332Sdam.sunwoo@arm.com * can track which process IDs are ultimately interacting with them 1409332Sdam.sunwoo@arm.com */ 1419332Sdam.sunwoo@arm.com uint32_t _taskId; 1429332Sdam.sunwoo@arm.com 1439332Sdam.sunwoo@arm.com /** The current OS process ID that is executing on this processor. This is 1449332Sdam.sunwoo@arm.com * used to generate a taskId */ 1459332Sdam.sunwoo@arm.com uint32_t _pid; 1469332Sdam.sunwoo@arm.com 1479430SAndreas.Sandberg@ARM.com /** Is the CPU switched out or active? */ 1489430SAndreas.Sandberg@ARM.com bool _switchedOut; 1499430SAndreas.Sandberg@ARM.com 1509814Sandreas.hansson@arm.com /** Cache the cache line size that we get from the system */ 1519814Sandreas.hansson@arm.com const unsigned int _cacheLineSize; 1529814Sandreas.hansson@arm.com 1531634SN/A public: 1548850Sandreas.hansson@arm.com 1558850Sandreas.hansson@arm.com /** 1568850Sandreas.hansson@arm.com * Purely virtual method that returns a reference to the data 1578850Sandreas.hansson@arm.com * port. All subclasses must implement this method. 1588850Sandreas.hansson@arm.com * 1598850Sandreas.hansson@arm.com * @return a reference to the data port 1608850Sandreas.hansson@arm.com */ 16114198Sgabeblack@google.com virtual Port &getDataPort() = 0; 1628850Sandreas.hansson@arm.com 1638850Sandreas.hansson@arm.com /** 16414197Sgabeblack@google.com * Returns a sendFunctional delegate for use with port proxies. 16514197Sgabeblack@google.com */ 16614197Sgabeblack@google.com virtual PortProxy::SendFunctionalFunc 16714197Sgabeblack@google.com getSendFunctional() 16814197Sgabeblack@google.com { 16914198Sgabeblack@google.com auto port = dynamic_cast<MasterPort *>(&getDataPort()); 17014198Sgabeblack@google.com assert(port); 17114198Sgabeblack@google.com return [port](PacketPtr pkt)->void { port->sendFunctional(pkt); }; 17214197Sgabeblack@google.com } 17314197Sgabeblack@google.com 17414197Sgabeblack@google.com /** 1758850Sandreas.hansson@arm.com * Purely virtual method that returns a reference to the instruction 1768850Sandreas.hansson@arm.com * port. All subclasses must implement this method. 1778850Sandreas.hansson@arm.com * 1788850Sandreas.hansson@arm.com * @return a reference to the instruction port 1798850Sandreas.hansson@arm.com */ 18014198Sgabeblack@google.com virtual Port &getInstPort() = 0; 1818850Sandreas.hansson@arm.com 1825712Shsul@eecs.umich.edu /** Reads this CPU's ID. */ 18310110Sandreas.hansson@arm.com int cpuId() const { return _cpuId; } 1845712Shsul@eecs.umich.edu 18510190Sakash.bagdia@arm.com /** Reads this CPU's Socket ID. */ 18610190Sakash.bagdia@arm.com uint32_t socketId() const { return _socketId; } 18710190Sakash.bagdia@arm.com 1888832SAli.Saidi@ARM.com /** Reads this CPU's unique data requestor ID */ 18913954Sgiacomo.gabrielli@arm.com MasterID dataMasterId() const { return _dataMasterId; } 1908832SAli.Saidi@ARM.com /** Reads this CPU's unique instruction requestor ID */ 19113954Sgiacomo.gabrielli@arm.com MasterID instMasterId() const { return _instMasterId; } 1928832SAli.Saidi@ARM.com 1938850Sandreas.hansson@arm.com /** 19413784Sgabeblack@google.com * Get a port on this CPU. All CPUs have a data and 1958926Sandreas.hansson@arm.com * instruction port, and this method uses getDataPort and 1968926Sandreas.hansson@arm.com * getInstPort of the subclasses to resolve the two ports. 1978850Sandreas.hansson@arm.com * 1988850Sandreas.hansson@arm.com * @param if_name the port name 1998850Sandreas.hansson@arm.com * @param idx ignored index 2008850Sandreas.hansson@arm.com * 2018922Swilliam.wang@arm.com * @return a reference to the port with the given name 2028850Sandreas.hansson@arm.com */ 20313784Sgabeblack@google.com Port &getPort(const std::string &if_name, 20413784Sgabeblack@google.com PortID idx=InvalidPortID) override; 2058850Sandreas.hansson@arm.com 2069332Sdam.sunwoo@arm.com /** Get cpu task id */ 2079332Sdam.sunwoo@arm.com uint32_t taskId() const { return _taskId; } 2089332Sdam.sunwoo@arm.com /** Set cpu task id */ 2099332Sdam.sunwoo@arm.com void taskId(uint32_t id) { _taskId = id; } 2109332Sdam.sunwoo@arm.com 2119332Sdam.sunwoo@arm.com uint32_t getPid() const { return _pid; } 2129332Sdam.sunwoo@arm.com void setPid(uint32_t pid) { _pid = pid; } 2139332Sdam.sunwoo@arm.com 2147914SBrad.Beckmann@amd.com inline void workItemBegin() { numWorkItemsStarted++; } 2157914SBrad.Beckmann@amd.com inline void workItemEnd() { numWorkItemsCompleted++; } 2163814Ssaidi@eecs.umich.edu // @todo remove me after debugging with legion done 2173814Ssaidi@eecs.umich.edu Tick instCount() { return instCnt; } 2181634SN/A 2195664Sgblack@eecs.umich.edu TheISA::MicrocodeRom microcodeRom; 2205664Sgblack@eecs.umich.edu 2212SN/A protected: 22211150Smitch.hayenga@arm.com std::vector<TheISA::Interrupts*> interrupts; 2232SN/A 2242SN/A public: 2255645Sgblack@eecs.umich.edu TheISA::Interrupts * 22611150Smitch.hayenga@arm.com getInterruptController(ThreadID tid) 2275645Sgblack@eecs.umich.edu { 22811150Smitch.hayenga@arm.com if (interrupts.empty()) 22911150Smitch.hayenga@arm.com return NULL; 23011150Smitch.hayenga@arm.com 23111150Smitch.hayenga@arm.com assert(interrupts.size() > tid); 23211150Smitch.hayenga@arm.com return interrupts[tid]; 2335645Sgblack@eecs.umich.edu } 2345645Sgblack@eecs.umich.edu 23511151Smitch.hayenga@arm.com virtual void wakeup(ThreadID tid) = 0; 2365807Snate@binkert.org 2375807Snate@binkert.org void 23811150Smitch.hayenga@arm.com postInterrupt(ThreadID tid, int int_num, int index) 2395807Snate@binkert.org { 24011150Smitch.hayenga@arm.com interrupts[tid]->post(int_num, index); 2418779Sgblack@eecs.umich.edu if (FullSystem) 24211151Smitch.hayenga@arm.com wakeup(tid); 2435807Snate@binkert.org } 2445807Snate@binkert.org 2455807Snate@binkert.org void 24611150Smitch.hayenga@arm.com clearInterrupt(ThreadID tid, int int_num, int index) 2475807Snate@binkert.org { 24811150Smitch.hayenga@arm.com interrupts[tid]->clear(int_num, index); 2495807Snate@binkert.org } 2505807Snate@binkert.org 2515807Snate@binkert.org void 25211150Smitch.hayenga@arm.com clearInterrupts(ThreadID tid) 2535807Snate@binkert.org { 25411150Smitch.hayenga@arm.com interrupts[tid]->clearAll(); 2555807Snate@binkert.org } 2562SN/A 2575704Snate@binkert.org bool 2585704Snate@binkert.org checkInterrupts(ThreadContext *tc) const 2595704Snate@binkert.org { 26011150Smitch.hayenga@arm.com return FullSystem && interrupts[tc->threadId()]->checkInterrupts(tc); 2615704Snate@binkert.org } 2621917SN/A 26312127Sspwilson2@wisc.edu void processProfileEvent(); 26412127Sspwilson2@wisc.edu EventFunctionWrapper * profileEvent; 2652SN/A 2662SN/A protected: 2672680Sktlim@umich.edu std::vector<ThreadContext *> threadContexts; 2682SN/A 2694776Sgblack@eecs.umich.edu Trace::InstTracer * tracer; 2704776Sgblack@eecs.umich.edu 2712SN/A public: 272393SN/A 27311050Sandreas.hansson@arm.com 27411050Sandreas.hansson@arm.com /** Invalid or unknown Pid. Possible when operating system is not present 27511050Sandreas.hansson@arm.com * or has not assigned a pid yet */ 27611050Sandreas.hansson@arm.com static const uint32_t invldPid = std::numeric_limits<uint32_t>::max(); 27711050Sandreas.hansson@arm.com 2787764Sgblack@eecs.umich.edu // Mask to align PCs to MachInst sized boundaries 2797764Sgblack@eecs.umich.edu static const Addr PCMask = ~((Addr)sizeof(TheISA::MachInst) - 1); 2807764Sgblack@eecs.umich.edu 2814776Sgblack@eecs.umich.edu /// Provide access to the tracer pointer 2824776Sgblack@eecs.umich.edu Trace::InstTracer * getTracer() { return tracer; } 2834776Sgblack@eecs.umich.edu 28410407Smitch.hayenga@arm.com /// Notify the CPU that the indicated context is now active. 28511526Sdavid.guillen@arm.com virtual void activateContext(ThreadID thread_num); 286393SN/A 287393SN/A /// Notify the CPU that the indicated context is now suspended. 28811526Sdavid.guillen@arm.com /// Check if possible to enter a lower power state 28911526Sdavid.guillen@arm.com virtual void suspendContext(ThreadID thread_num); 290393SN/A 291393SN/A /// Notify the CPU that the indicated context is now halted. 29212284Sjose.marinho@arm.com virtual void haltContext(ThreadID thread_num); 2932SN/A 2944000Ssaidi@eecs.umich.edu /// Given a Thread Context pointer return the thread num 2954000Ssaidi@eecs.umich.edu int findContext(ThreadContext *tc); 2964000Ssaidi@eecs.umich.edu 2974000Ssaidi@eecs.umich.edu /// Given a thread num get tho thread context for it 2989652SAndreas.Sandberg@ARM.com virtual ThreadContext *getContext(int tn) { return threadContexts[tn]; } 2994000Ssaidi@eecs.umich.edu 30010030SAli.Saidi@ARM.com /// Get the number of thread contexts available 30114016SAndrea.Mondelli@ucf.edu unsigned numContexts() { 30214016SAndrea.Mondelli@ucf.edu return static_cast<unsigned>(threadContexts.size()); 30314016SAndrea.Mondelli@ucf.edu } 30410030SAli.Saidi@ARM.com 30511435Smitch.hayenga@arm.com /// Convert ContextID to threadID 30611435Smitch.hayenga@arm.com ThreadID contextToThread(ContextID cid) 30711435Smitch.hayenga@arm.com { return static_cast<ThreadID>(cid - threadContexts[0]->contextId()); } 30811435Smitch.hayenga@arm.com 3092SN/A public: 3105529Snate@binkert.org typedef BaseCPUParams Params; 3115529Snate@binkert.org const Params *params() const 3125529Snate@binkert.org { return reinterpret_cast<const Params *>(_params); } 3138876Sandreas.hansson@arm.com BaseCPU(Params *params, bool is_checker = false); 3141191SN/A virtual ~BaseCPU(); 3152SN/A 31611169Sandreas.hansson@arm.com void init() override; 31711169Sandreas.hansson@arm.com void startup() override; 31811169Sandreas.hansson@arm.com void regStats() override; 3192SN/A 32011168Sandreas.hansson@arm.com void regProbePoints() override; 32110464SAndreas.Sandberg@ARM.com 3222680Sktlim@umich.edu void registerThreadContexts(); 323180SN/A 32412276Sanouk.vanlaer@arm.com // Functions to deschedule and reschedule the events to enter the 32512276Sanouk.vanlaer@arm.com // power gating sleep before and after checkpoiting respectively. 32612276Sanouk.vanlaer@arm.com void deschedulePowerGatingEvent(); 32712276Sanouk.vanlaer@arm.com void schedulePowerGatingEvent(); 32812276Sanouk.vanlaer@arm.com 3299254SAndreas.Sandberg@arm.com /** 3309254SAndreas.Sandberg@arm.com * Prepare for another CPU to take over execution. 3319254SAndreas.Sandberg@arm.com * 3329254SAndreas.Sandberg@arm.com * When this method exits, all internal state should have been 3339254SAndreas.Sandberg@arm.com * flushed. After the method returns, the simulator calls 3349254SAndreas.Sandberg@arm.com * takeOverFrom() on the new CPU with this CPU as its parameter. 3359254SAndreas.Sandberg@arm.com */ 3362798Sktlim@umich.edu virtual void switchOut(); 337180SN/A 3389254SAndreas.Sandberg@arm.com /** 3399254SAndreas.Sandberg@arm.com * Load the state of a CPU from the previous CPU object, invoked 3409254SAndreas.Sandberg@arm.com * on all new CPUs that are about to be switched in. 3419254SAndreas.Sandberg@arm.com * 3429254SAndreas.Sandberg@arm.com * A CPU model implementing this method is expected to initialize 3439254SAndreas.Sandberg@arm.com * its state from the old CPU and connect its memory (unless they 3449254SAndreas.Sandberg@arm.com * are already connected) to the memories connected to the old 3459254SAndreas.Sandberg@arm.com * CPU. 3469254SAndreas.Sandberg@arm.com * 3479254SAndreas.Sandberg@arm.com * @param cpu CPU to initialize read state from. 3489254SAndreas.Sandberg@arm.com */ 3499254SAndreas.Sandberg@arm.com virtual void takeOverFrom(BaseCPU *cpu); 350180SN/A 351124SN/A /** 3529446SAndreas.Sandberg@ARM.com * Flush all TLBs in the CPU. 3539446SAndreas.Sandberg@ARM.com * 3549446SAndreas.Sandberg@ARM.com * This method is mainly used to flush stale translations when 3559446SAndreas.Sandberg@ARM.com * switching CPUs. It is also exported to the Python world to 3569446SAndreas.Sandberg@ARM.com * allow it to request a TLB flush after draining the CPU to make 3579446SAndreas.Sandberg@ARM.com * it easier to compare traces when debugging 3589446SAndreas.Sandberg@ARM.com * handover/checkpointing. 3599446SAndreas.Sandberg@ARM.com */ 3609446SAndreas.Sandberg@ARM.com void flushTLBs(); 3619446SAndreas.Sandberg@ARM.com 3629446SAndreas.Sandberg@ARM.com /** 3639430SAndreas.Sandberg@ARM.com * Determine if the CPU is switched out. 3649430SAndreas.Sandberg@ARM.com * 3659430SAndreas.Sandberg@ARM.com * @return True if the CPU is switched out, false otherwise. 3669430SAndreas.Sandberg@ARM.com */ 3679430SAndreas.Sandberg@ARM.com bool switchedOut() const { return _switchedOut; } 3689430SAndreas.Sandberg@ARM.com 3699430SAndreas.Sandberg@ARM.com /** 3709523SAndreas.Sandberg@ARM.com * Verify that the system is in a memory mode supported by the 3719523SAndreas.Sandberg@ARM.com * CPU. 3729523SAndreas.Sandberg@ARM.com * 3739523SAndreas.Sandberg@ARM.com * Implementations are expected to query the system for the 3749523SAndreas.Sandberg@ARM.com * current memory mode and ensure that it is what the CPU model 3759523SAndreas.Sandberg@ARM.com * expects. If the check fails, the implementation should 3769523SAndreas.Sandberg@ARM.com * terminate the simulation using fatal(). 3779523SAndreas.Sandberg@ARM.com */ 3789523SAndreas.Sandberg@ARM.com virtual void verifyMemoryMode() const { }; 3799523SAndreas.Sandberg@ARM.com 3809523SAndreas.Sandberg@ARM.com /** 381124SN/A * Number of threads we're actually simulating (<= SMT_MAX_THREADS). 382124SN/A * This is a constant for the duration of the simulation. 383124SN/A */ 3846221Snate@binkert.org ThreadID numThreads; 3852SN/A 386124SN/A /** 387124SN/A * Vector of per-thread instruction-based event queues. Used for 388124SN/A * scheduling events based on number of instructions committed by 389124SN/A * a particular thread. 390124SN/A */ 391503SN/A EventQueue **comInstEventQueue; 3922SN/A 393124SN/A /** 394124SN/A * Vector of per-thread load-based event queues. Used for 395124SN/A * scheduling events based on number of loads committed by 396124SN/A *a particular thread. 397124SN/A */ 398124SN/A EventQueue **comLoadEventQueue; 399124SN/A 4002SN/A System *system; 401921SN/A 402921SN/A /** 4039814Sandreas.hansson@arm.com * Get the cache line size of the system. 4049814Sandreas.hansson@arm.com */ 4059814Sandreas.hansson@arm.com inline unsigned int cacheLineSize() const { return _cacheLineSize; } 4069814Sandreas.hansson@arm.com 4079814Sandreas.hansson@arm.com /** 408921SN/A * Serialize this object to the given output stream. 4099448SAndreas.Sandberg@ARM.com * 4109448SAndreas.Sandberg@ARM.com * @note CPU models should normally overload the serializeThread() 4119448SAndreas.Sandberg@ARM.com * method instead of the serialize() method as this provides a 4129448SAndreas.Sandberg@ARM.com * uniform data format for all CPU models and promotes better code 4139448SAndreas.Sandberg@ARM.com * reuse. 4149448SAndreas.Sandberg@ARM.com * 41514016SAndrea.Mondelli@ucf.edu * @param cp The stream to serialize to. 416921SN/A */ 41711168Sandreas.hansson@arm.com void serialize(CheckpointOut &cp) const override; 418921SN/A 419921SN/A /** 420921SN/A * Reconstruct the state of this object from a checkpoint. 4219448SAndreas.Sandberg@ARM.com * 4229448SAndreas.Sandberg@ARM.com * @note CPU models should normally overload the 4239448SAndreas.Sandberg@ARM.com * unserializeThread() method instead of the unserialize() method 4249448SAndreas.Sandberg@ARM.com * as this provides a uniform data format for all CPU models and 4259448SAndreas.Sandberg@ARM.com * promotes better code reuse. 4269448SAndreas.Sandberg@ARM.com 427921SN/A * @param cp The checkpoint use. 428921SN/A */ 42911168Sandreas.hansson@arm.com void unserialize(CheckpointIn &cp) override; 430921SN/A 431124SN/A /** 4329448SAndreas.Sandberg@ARM.com * Serialize a single thread. 4339448SAndreas.Sandberg@ARM.com * 43414016SAndrea.Mondelli@ucf.edu * @param cp The stream to serialize to. 4359448SAndreas.Sandberg@ARM.com * @param tid ID of the current thread. 4369448SAndreas.Sandberg@ARM.com */ 43710905Sandreas.sandberg@arm.com virtual void serializeThread(CheckpointOut &cp, ThreadID tid) const {}; 4389448SAndreas.Sandberg@ARM.com 4399448SAndreas.Sandberg@ARM.com /** 4409448SAndreas.Sandberg@ARM.com * Unserialize one thread. 4419448SAndreas.Sandberg@ARM.com * 4429448SAndreas.Sandberg@ARM.com * @param cp The checkpoint use. 4439448SAndreas.Sandberg@ARM.com * @param tid ID of the current thread. 4449448SAndreas.Sandberg@ARM.com */ 44510905Sandreas.sandberg@arm.com virtual void unserializeThread(CheckpointIn &cp, ThreadID tid) {}; 4469448SAndreas.Sandberg@ARM.com 4478834Satgutier@umich.edu virtual Counter totalInsts() const = 0; 4488834Satgutier@umich.edu 4498834Satgutier@umich.edu virtual Counter totalOps() const = 0; 450707SN/A 4519749Sandreas@sandberg.pp.se /** 4529749Sandreas@sandberg.pp.se * Schedule an event that exits the simulation loops after a 4539749Sandreas@sandberg.pp.se * predefined number of instructions. 4549749Sandreas@sandberg.pp.se * 4559749Sandreas@sandberg.pp.se * This method is usually called from the configuration script to 4569749Sandreas@sandberg.pp.se * get an exit event some time in the future. It is typically used 4579749Sandreas@sandberg.pp.se * when the script wants to simulate for a specific number of 4589749Sandreas@sandberg.pp.se * instructions rather than ticks. 4599749Sandreas@sandberg.pp.se * 4609749Sandreas@sandberg.pp.se * @param tid Thread monitor. 4619749Sandreas@sandberg.pp.se * @param insts Number of instructions into the future. 4629749Sandreas@sandberg.pp.se * @param cause Cause to signal in the exit event. 4639749Sandreas@sandberg.pp.se */ 4649749Sandreas@sandberg.pp.se void scheduleInstStop(ThreadID tid, Counter insts, const char *cause); 4659749Sandreas@sandberg.pp.se 4669749Sandreas@sandberg.pp.se /** 4679749Sandreas@sandberg.pp.se * Schedule an event that exits the simulation loops after a 4689749Sandreas@sandberg.pp.se * predefined number of load operations. 4699749Sandreas@sandberg.pp.se * 4709749Sandreas@sandberg.pp.se * This method is usually called from the configuration script to 4719749Sandreas@sandberg.pp.se * get an exit event some time in the future. It is typically used 4729749Sandreas@sandberg.pp.se * when the script wants to simulate for a specific number of 4739749Sandreas@sandberg.pp.se * loads rather than ticks. 4749749Sandreas@sandberg.pp.se * 4759749Sandreas@sandberg.pp.se * @param tid Thread monitor. 4769749Sandreas@sandberg.pp.se * @param loads Number of load instructions into the future. 4779749Sandreas@sandberg.pp.se * @param cause Cause to signal in the exit event. 4789749Sandreas@sandberg.pp.se */ 4799749Sandreas@sandberg.pp.se void scheduleLoadStop(ThreadID tid, Counter loads, const char *cause); 4809749Sandreas@sandberg.pp.se 48111415SGeoffrey.Blake@arm.com /** 48211415SGeoffrey.Blake@arm.com * Get the number of instructions executed by the specified thread 48311415SGeoffrey.Blake@arm.com * on this CPU. Used by Python to control simulation. 48411415SGeoffrey.Blake@arm.com * 48511415SGeoffrey.Blake@arm.com * @param tid Thread monitor 48611415SGeoffrey.Blake@arm.com * @return Number of instructions executed 48711415SGeoffrey.Blake@arm.com */ 48811415SGeoffrey.Blake@arm.com uint64_t getCurrentInstCount(ThreadID tid); 48911415SGeoffrey.Blake@arm.com 49010464SAndreas.Sandberg@ARM.com public: 49110464SAndreas.Sandberg@ARM.com /** 49210464SAndreas.Sandberg@ARM.com * @{ 49310464SAndreas.Sandberg@ARM.com * @name PMU Probe points. 49410464SAndreas.Sandberg@ARM.com */ 49510464SAndreas.Sandberg@ARM.com 49610464SAndreas.Sandberg@ARM.com /** 49710464SAndreas.Sandberg@ARM.com * Helper method to trigger PMU probes for a committed 49810464SAndreas.Sandberg@ARM.com * instruction. 49910464SAndreas.Sandberg@ARM.com * 50010464SAndreas.Sandberg@ARM.com * @param inst Instruction that just committed 50113818Sjavier.bueno@metempsy.com * @param pc PC of the instruction that just committed 50210464SAndreas.Sandberg@ARM.com */ 50313818Sjavier.bueno@metempsy.com virtual void probeInstCommit(const StaticInstPtr &inst, Addr pc); 50410464SAndreas.Sandberg@ARM.com 50512284Sjose.marinho@arm.com protected: 50610464SAndreas.Sandberg@ARM.com /** 50710464SAndreas.Sandberg@ARM.com * Helper method to instantiate probe points belonging to this 50810464SAndreas.Sandberg@ARM.com * object. 50910464SAndreas.Sandberg@ARM.com * 51010464SAndreas.Sandberg@ARM.com * @param name Name of the probe point. 51110464SAndreas.Sandberg@ARM.com * @return A unique_ptr to the new probe point. 51210464SAndreas.Sandberg@ARM.com */ 51310464SAndreas.Sandberg@ARM.com ProbePoints::PMUUPtr pmuProbePoint(const char *name); 51410464SAndreas.Sandberg@ARM.com 51510464SAndreas.Sandberg@ARM.com /** 51610464SAndreas.Sandberg@ARM.com * Instruction commit probe point. 51710464SAndreas.Sandberg@ARM.com * 51810464SAndreas.Sandberg@ARM.com * This probe point is triggered whenever one or more instructions 51910464SAndreas.Sandberg@ARM.com * are committed. It is normally triggered once for every 52010464SAndreas.Sandberg@ARM.com * instruction. However, CPU models committing bundles of 52110464SAndreas.Sandberg@ARM.com * instructions may call notify once for the entire bundle. 52210464SAndreas.Sandberg@ARM.com */ 52310464SAndreas.Sandberg@ARM.com ProbePoints::PMUUPtr ppRetiredInsts; 52413818Sjavier.bueno@metempsy.com ProbePoints::PMUUPtr ppRetiredInstsPC; 52510464SAndreas.Sandberg@ARM.com 52610464SAndreas.Sandberg@ARM.com /** Retired load instructions */ 52710464SAndreas.Sandberg@ARM.com ProbePoints::PMUUPtr ppRetiredLoads; 52810464SAndreas.Sandberg@ARM.com /** Retired store instructions */ 52910464SAndreas.Sandberg@ARM.com ProbePoints::PMUUPtr ppRetiredStores; 53010464SAndreas.Sandberg@ARM.com 53110464SAndreas.Sandberg@ARM.com /** Retired branches (any type) */ 53210464SAndreas.Sandberg@ARM.com ProbePoints::PMUUPtr ppRetiredBranches; 53310464SAndreas.Sandberg@ARM.com 53412284Sjose.marinho@arm.com /** CPU cycle counter even if any thread Context is suspended*/ 53512284Sjose.marinho@arm.com ProbePoints::PMUUPtr ppAllCycles; 53612284Sjose.marinho@arm.com 53712284Sjose.marinho@arm.com /** CPU cycle counter, only counts if any thread contexts is active **/ 53812284Sjose.marinho@arm.com ProbePoints::PMUUPtr ppActiveCycles; 53912284Sjose.marinho@arm.com 54012284Sjose.marinho@arm.com /** 54112284Sjose.marinho@arm.com * ProbePoint that signals transitions of threadContexts sets. 54212284Sjose.marinho@arm.com * The ProbePoint reports information through it bool parameter. 54312284Sjose.marinho@arm.com * - If the parameter is true then the last enabled threadContext of the 54412284Sjose.marinho@arm.com * CPU object was disabled. 54512284Sjose.marinho@arm.com * - If the parameter is false then a threadContext was enabled, all the 54612284Sjose.marinho@arm.com * remaining threadContexts are disabled. 54712284Sjose.marinho@arm.com */ 54812284Sjose.marinho@arm.com ProbePointArg<bool> *ppSleeping; 54910464SAndreas.Sandberg@ARM.com /** @} */ 55010464SAndreas.Sandberg@ARM.com 55112284Sjose.marinho@arm.com enum CPUState { 55212284Sjose.marinho@arm.com CPU_STATE_ON, 55312284Sjose.marinho@arm.com CPU_STATE_SLEEP, 55412284Sjose.marinho@arm.com CPU_STATE_WAKEUP 55512284Sjose.marinho@arm.com }; 55610464SAndreas.Sandberg@ARM.com 55712284Sjose.marinho@arm.com Cycles previousCycle; 55812284Sjose.marinho@arm.com CPUState previousState; 55912284Sjose.marinho@arm.com 56012284Sjose.marinho@arm.com /** base method keeping track of cycle progression **/ 56112284Sjose.marinho@arm.com inline void updateCycleCounters(CPUState state) 56212284Sjose.marinho@arm.com { 56312284Sjose.marinho@arm.com uint32_t delta = curCycle() - previousCycle; 56412284Sjose.marinho@arm.com 56512284Sjose.marinho@arm.com if (previousState == CPU_STATE_ON) { 56612284Sjose.marinho@arm.com ppActiveCycles->notify(delta); 56712284Sjose.marinho@arm.com } 56812284Sjose.marinho@arm.com 56912284Sjose.marinho@arm.com switch (state) 57012284Sjose.marinho@arm.com { 57112284Sjose.marinho@arm.com case CPU_STATE_WAKEUP: 57212284Sjose.marinho@arm.com ppSleeping->notify(false); 57312284Sjose.marinho@arm.com break; 57412284Sjose.marinho@arm.com case CPU_STATE_SLEEP: 57512284Sjose.marinho@arm.com ppSleeping->notify(true); 57612284Sjose.marinho@arm.com break; 57712284Sjose.marinho@arm.com default: 57812284Sjose.marinho@arm.com break; 57912284Sjose.marinho@arm.com } 58012284Sjose.marinho@arm.com 58112284Sjose.marinho@arm.com ppAllCycles->notify(delta); 58212284Sjose.marinho@arm.com 58312284Sjose.marinho@arm.com previousCycle = curCycle(); 58412284Sjose.marinho@arm.com previousState = state; 58512284Sjose.marinho@arm.com } 58610464SAndreas.Sandberg@ARM.com 5871191SN/A // Function tracing 5881191SN/A private: 5891191SN/A bool functionTracingEnabled; 5901191SN/A std::ostream *functionTraceStream; 5911191SN/A Addr currentFunctionStart; 5921191SN/A Addr currentFunctionEnd; 5931191SN/A Tick functionEntryTick; 5941191SN/A void enableFunctionTrace(); 5951191SN/A void traceFunctionsInternal(Addr pc); 5961191SN/A 5978662SAli.Saidi@ARM.com private: 5988662SAli.Saidi@ARM.com static std::vector<BaseCPU *> cpuList; //!< Static global cpu list 5998662SAli.Saidi@ARM.com 6008662SAli.Saidi@ARM.com public: 6011191SN/A void traceFunctions(Addr pc) 6021191SN/A { 6031191SN/A if (functionTracingEnabled) 6041191SN/A traceFunctionsInternal(pc); 6051191SN/A } 6061191SN/A 6072SN/A static int numSimulatedCPUs() { return cpuList.size(); } 6088834Satgutier@umich.edu static Counter numSimulatedInsts() 609707SN/A { 610707SN/A Counter total = 0; 611707SN/A 612707SN/A int size = cpuList.size(); 613707SN/A for (int i = 0; i < size; ++i) 6148834Satgutier@umich.edu total += cpuList[i]->totalInsts(); 6158834Satgutier@umich.edu 6168834Satgutier@umich.edu return total; 6178834Satgutier@umich.edu } 6188834Satgutier@umich.edu 6198834Satgutier@umich.edu static Counter numSimulatedOps() 6208834Satgutier@umich.edu { 6218834Satgutier@umich.edu Counter total = 0; 6228834Satgutier@umich.edu 6238834Satgutier@umich.edu int size = cpuList.size(); 6248834Satgutier@umich.edu for (int i = 0; i < size; ++i) 6258834Satgutier@umich.edu total += cpuList[i]->totalOps(); 626707SN/A 627707SN/A return total; 628707SN/A } 629707SN/A 630707SN/A public: 631707SN/A // Number of CPU cycles simulated 6325999Snate@binkert.org Stats::Scalar numCycles; 6337914SBrad.Beckmann@amd.com Stats::Scalar numWorkItemsStarted; 6347914SBrad.Beckmann@amd.com Stats::Scalar numWorkItemsCompleted; 63510529Smorr@cs.wisc.edu 63610529Smorr@cs.wisc.edu private: 63711148Smitch.hayenga@arm.com std::vector<AddressMonitor> addressMonitor; 63810529Smorr@cs.wisc.edu 63910529Smorr@cs.wisc.edu public: 64011148Smitch.hayenga@arm.com void armMonitor(ThreadID tid, Addr address); 64111148Smitch.hayenga@arm.com bool mwait(ThreadID tid, PacketPtr pkt); 64212406Sgabeblack@google.com void mwaitAtomic(ThreadID tid, ThreadContext *tc, BaseTLB *dtb); 64311148Smitch.hayenga@arm.com AddressMonitor *getCpuAddrMonitor(ThreadID tid) 64411148Smitch.hayenga@arm.com { 64511148Smitch.hayenga@arm.com assert(tid < numThreads); 64611148Smitch.hayenga@arm.com return &addressMonitor[tid]; 64711148Smitch.hayenga@arm.com } 64811877Sbrandon.potter@amd.com 64912122Sjose.marinho@arm.com bool waitForRemoteGDB() const; 65012122Sjose.marinho@arm.com 65111877Sbrandon.potter@amd.com Cycles syscallRetryLatency; 65212277Sjose.marinho@arm.com 65312276Sanouk.vanlaer@arm.com // Enables CPU to enter power gating on a configurable cycle count 65412276Sanouk.vanlaer@arm.com protected: 65512277Sjose.marinho@arm.com void enterPwrGating(); 65612277Sjose.marinho@arm.com 65712276Sanouk.vanlaer@arm.com const Cycles pwrGatingLatency; 65812277Sjose.marinho@arm.com const bool powerGatingOnIdle; 65912276Sanouk.vanlaer@arm.com EventFunctionWrapper enterPwrGatingEvent; 6602SN/A}; 6612SN/A 6629850Sandreas.hansson@arm.com#endif // THE_ISA == NULL_ISA 6639850Sandreas.hansson@arm.com 6641717SN/A#endif // __CPU_BASE_HH__ 665