cpu.hh revision 9523
12SN/A/* 21762SN/A * Copyright (c) 2011-2012 ARM Limited 32SN/A * All rights reserved 42SN/A * 52SN/A * The license below extends only to copyright in the software and shall 62SN/A * not be construed as granting a license to any other intellectual 72SN/A * property including but not limited to intellectual property relating 82SN/A * to a hardware implementation of the functionality of the software 92SN/A * licensed hereunder. You may use the software subject to the license 102SN/A * terms below provided that you ensure that this notice is replicated 112SN/A * unmodified and in its entirety in all distributions of the software, 122SN/A * modified or unmodified, in source code or in binary form. 132SN/A * 142SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 152SN/A * 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 272665Ssaidi@eecs.umich.edu * this software without specific prior written permission. 282665Ssaidi@eecs.umich.edu * 292665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 302665Ssaidi@eecs.umich.edu * "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 383971Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3956SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4056SN/A * 411158SN/A * Authors: Kevin Lim 42146SN/A * Korey Sewell 431858SN/A * Rick Strong 442680Sktlim@umich.edu */ 452378SN/A 462522SN/A#ifndef __CPU_O3_CPU_HH__ 472401SN/A#define __CPU_O3_CPU_HH__ 485154Sgblack@eecs.umich.edu 494762Snate@binkert.org#include <iostream> 50360SN/A#include <list> 514434Ssaidi@eecs.umich.edu#include <queue> 52695SN/A#include <set> 532093SN/A#include <vector> 542378SN/A 552SN/A#include "arch/types.hh" 562715Sstever@eecs.umich.edu#include "base/statistics.hh" 572715Sstever@eecs.umich.edu#include "config/the_isa.hh" 582715Sstever@eecs.umich.edu#include "cpu/o3/comm.hh" 592715Sstever@eecs.umich.edu#include "cpu/o3/cpu_policy.hh" 602715Sstever@eecs.umich.edu#include "cpu/o3/scoreboard.hh" 612715Sstever@eecs.umich.edu#include "cpu/o3/thread_state.hh" 622715Sstever@eecs.umich.edu#include "cpu/activity.hh" 632715Sstever@eecs.umich.edu#include "cpu/base.hh" 642715Sstever@eecs.umich.edu#include "cpu/simple_thread.hh" 654157Sgblack@eecs.umich.edu#include "cpu/timebuf.hh" 664166Sgblack@eecs.umich.edu//#include "cpu/o3/thread_context.hh" 672715Sstever@eecs.umich.edu#include "params/DerivO3CPU.hh" 682715Sstever@eecs.umich.edu#include "sim/process.hh" 692715Sstever@eecs.umich.edu 702715Sstever@eecs.umich.edutemplate <class> 712715Sstever@eecs.umich.educlass Checker; 722SN/Aclass ThreadContext; 732107SN/Atemplate <class> 742SN/Aclass O3ThreadContext; 752SN/A 762SN/Aclass Checkpoint; 772SN/Aclass MemObject; 782SN/Aclass Process; 792SN/A 801858SN/Astruct BaseCPUParams; 81360SN/A 822SN/Aclass BaseO3CPU : public BaseCPU 832SN/A{ 842SN/A //Stuff that's pretty ISA independent will go here. 852SN/A public: 862SN/A BaseO3CPU(BaseCPUParams *params); 875154Sgblack@eecs.umich.edu 885154Sgblack@eecs.umich.edu void regStats(); 895154Sgblack@eecs.umich.edu}; 902SN/A 915154Sgblack@eecs.umich.edu/** 925154Sgblack@eecs.umich.edu * FullO3CPU class, has each of the stages (fetch through commit) 935154Sgblack@eecs.umich.edu * within it, as well as all of the time buffers between stages. The 945154Sgblack@eecs.umich.edu * tick() function for the CPU is defined here. 955154Sgblack@eecs.umich.edu */ 965154Sgblack@eecs.umich.edutemplate <class Impl> 975154Sgblack@eecs.umich.educlass FullO3CPU : public BaseO3CPU 985154Sgblack@eecs.umich.edu{ 995154Sgblack@eecs.umich.edu public: 1005154Sgblack@eecs.umich.edu // Typedefs from the Impl here. 1015154Sgblack@eecs.umich.edu typedef typename Impl::CPUPol CPUPolicy; 1025154Sgblack@eecs.umich.edu typedef typename Impl::DynInstPtr DynInstPtr; 1035154Sgblack@eecs.umich.edu typedef typename Impl::O3CPU O3CPU; 1045154Sgblack@eecs.umich.edu 1055154Sgblack@eecs.umich.edu typedef O3ThreadState<Impl> ImplState; 1065154Sgblack@eecs.umich.edu typedef O3ThreadState<Impl> Thread; 1075154Sgblack@eecs.umich.edu 1085154Sgblack@eecs.umich.edu typedef typename std::list<DynInstPtr>::iterator ListIt; 1095154Sgblack@eecs.umich.edu 1105154Sgblack@eecs.umich.edu friend class O3ThreadContext<Impl>; 1115154Sgblack@eecs.umich.edu 1125154Sgblack@eecs.umich.edu public: 1135154Sgblack@eecs.umich.edu enum Status { 1145154Sgblack@eecs.umich.edu Running, 1154997Sgblack@eecs.umich.edu Idle, 1162SN/A Halted, 1172SN/A Blocked, 1182SN/A SwitchedOut 1192SN/A }; 1202SN/A 1212SN/A TheISA::TLB * itb; 1222SN/A TheISA::TLB * dtb; 1232SN/A 1242SN/A /** Overall CPU status. */ 1252SN/A Status _status; 1261450SN/A 1271514SN/A private: 1282378SN/A 1292SN/A /** 1302SN/A * IcachePort class for instruction fetch. 1312SN/A */ 1322378SN/A class IcachePort : public CpuPort 1332SN/A { 1342SN/A protected: 1352SN/A /** Pointer to fetch. */ 136729SN/A DefaultFetch<Impl> *fetch; 1372SN/A 1382SN/A public: 1392SN/A /** Default constructor. */ 1402SN/A IcachePort(DefaultFetch<Impl> *_fetch, FullO3CPU<Impl>* _cpu) 1412SN/A : CpuPort(_cpu->name() + ".icache_port", _cpu), fetch(_fetch) 1422SN/A { } 1432SN/A 1442SN/A protected: 1452SN/A 1462SN/A /** Timing version of receive. Handles setting fetch to the 1472SN/A * proper status to start fetching. */ 1482SN/A virtual bool recvTimingResp(PacketPtr pkt); 1492SN/A virtual void recvTimingSnoopReq(PacketPtr pkt) { } 1502SN/A 1512SN/A /** Handles doing a retry of a failed fetch. */ 1522SN/A virtual void recvRetry(); 1532SN/A }; 1542SN/A 1552SN/A /** 1562SN/A * DcachePort class for the load/store queue. 1572SN/A */ 1582SN/A class DcachePort : public CpuPort 1592SN/A { 1602SN/A protected: 1612SN/A 1622SN/A /** Pointer to LSQ. */ 1632SN/A LSQ<Impl> *lsq; 1642SN/A 1652SN/A public: 1662SN/A /** Default constructor. */ 1672SN/A DcachePort(LSQ<Impl> *_lsq, FullO3CPU<Impl>* _cpu) 1682SN/A : CpuPort(_cpu->name() + ".dcache_port", _cpu), lsq(_lsq) 1692SN/A { } 1702SN/A 1712SN/A protected: 1722SN/A 1732SN/A /** Timing version of receive. Handles writing back and 1742SN/A * completing the load or store that has returned from 1752SN/A * memory. */ 1762SN/A virtual bool recvTimingResp(PacketPtr pkt); 177180SN/A virtual void recvTimingSnoopReq(PacketPtr pkt); 1782680Sktlim@umich.edu 1792SN/A /** Handles doing a retry of the previous send. */ 180180SN/A virtual void recvRetry(); 1812680Sktlim@umich.edu 1822680Sktlim@umich.edu /** 183180SN/A * As this CPU requires snooping to maintain the load store queue 1845109Sgblack@eecs.umich.edu * change the behaviour from the base CPU port. 1855109Sgblack@eecs.umich.edu * 1865109Sgblack@eecs.umich.edu * @return true since we have to snoop 1873971Sgblack@eecs.umich.edu */ 1883971Sgblack@eecs.umich.edu virtual bool isSnooping() const { return true; } 1895109Sgblack@eecs.umich.edu }; 1903971Sgblack@eecs.umich.edu 1912378SN/A class TickEvent : public Event 192180SN/A { 1932SN/A private: 1942SN/A /** Pointer to the CPU. */ 1951395SN/A FullO3CPU<Impl> *cpu; 1961395SN/A 1971395SN/A public: 1982680Sktlim@umich.edu /** Constructs a tick event. */ 1992378SN/A TickEvent(FullO3CPU<Impl> *c); 2002378SN/A 2012680Sktlim@umich.edu /** Processes a tick event, calling tick() on the CPU. */ 2022680Sktlim@umich.edu void process(); 2031395SN/A /** Returns the description of the tick event. */ 2041634SN/A const char *description() const; 2052680Sktlim@umich.edu }; 2062462SN/A 2072519SN/A /** The tick event used for scheduling CPU ticks. */ 2082519SN/A TickEvent tickEvent; 2094434Ssaidi@eecs.umich.edu 2104434Ssaidi@eecs.umich.edu /** Schedule tick event, regardless of its current state. */ 2112519SN/A void scheduleTickEvent(Cycles delay) 2122519SN/A { 2131395SN/A if (tickEvent.squashed()) 2142SN/A reschedule(tickEvent, clockEdge(delay)); 215180SN/A else if (!tickEvent.scheduled()) 2162680Sktlim@umich.edu schedule(tickEvent, clockEdge(delay)); 217180SN/A } 2182680Sktlim@umich.edu 2192680Sktlim@umich.edu /** Unschedule tick event, regardless of its current state. */ 2202680Sktlim@umich.edu void unscheduleTickEvent() 221180SN/A { 222180SN/A if (tickEvent.scheduled()) 2232680Sktlim@umich.edu tickEvent.squash(); 224180SN/A } 225180SN/A 2262SN/A class ActivateThreadEvent : public Event 2272SN/A { 2282SN/A private: 2292SN/A /** Number of Thread to Activate */ 2302SN/A ThreadID tid; 2312SN/A 2322SN/A /** Pointer to the CPU. */ 2332SN/A FullO3CPU<Impl> *cpu; 2342SN/A 2352SN/A public: 2362SN/A /** Constructs the event. */ 2372SN/A ActivateThreadEvent(); 2382SN/A 2391970SN/A /** Initialize Event */ 2402SN/A void init(int thread_num, FullO3CPU<Impl> *thread_cpu); 2412SN/A 2422SN/A /** Processes the event, calling activateThread() on the CPU. */ 2432SN/A void process(); 2442SN/A 2452SN/A /** Returns the description of the event. */ 2461970SN/A const char *description() const; 2471970SN/A }; 2481970SN/A 2491970SN/A /** Schedule thread to activate , regardless of its current state. */ 2501970SN/A void 2512SN/A scheduleActivateThreadEvent(ThreadID tid, Cycles delay) 2522SN/A { 2531970SN/A // Schedule thread to activate, regardless of its current state. 2541970SN/A if (activateThreadEvent[tid].squashed()) 2552SN/A reschedule(activateThreadEvent[tid], 2561970SN/A clockEdge(delay)); 2571970SN/A else if (!activateThreadEvent[tid].scheduled()) { 2581970SN/A Tick when = clockEdge(delay); 2591970SN/A 2601970SN/A // Check if the deallocateEvent is also scheduled, and make 2611970SN/A // sure they do not happen at same time causing a sleep that 2621970SN/A // is never woken from. 2631970SN/A if (deallocateContextEvent[tid].scheduled() && 2641970SN/A deallocateContextEvent[tid].when() == when) { 2652SN/A when++; 2662SN/A } 2672SN/A 2682SN/A schedule(activateThreadEvent[tid], when); 2692SN/A } 2702SN/A } 2712SN/A 2722SN/A /** Unschedule actiavte thread event, regardless of its current state. */ 2732SN/A void 2742SN/A unscheduleActivateThreadEvent(ThreadID tid) 2752SN/A { 2762SN/A if (activateThreadEvent[tid].scheduled()) 2772SN/A activateThreadEvent[tid].squash(); 2784434Ssaidi@eecs.umich.edu } 2794434Ssaidi@eecs.umich.edu 2804434Ssaidi@eecs.umich.edu /** The tick event used for scheduling CPU ticks. */ 2814434Ssaidi@eecs.umich.edu ActivateThreadEvent activateThreadEvent[Impl::MaxThreads]; 2824434Ssaidi@eecs.umich.edu 2834434Ssaidi@eecs.umich.edu class DeallocateContextEvent : public Event 2844434Ssaidi@eecs.umich.edu { 2854434Ssaidi@eecs.umich.edu private: 2864434Ssaidi@eecs.umich.edu /** Number of Thread to deactivate */ 2874434Ssaidi@eecs.umich.edu ThreadID tid; 2884434Ssaidi@eecs.umich.edu 2895154Sgblack@eecs.umich.edu /** Should the thread be removed from the CPU? */ 2905154Sgblack@eecs.umich.edu bool remove; 2915154Sgblack@eecs.umich.edu 2925154Sgblack@eecs.umich.edu /** Pointer to the CPU. */ 2935154Sgblack@eecs.umich.edu FullO3CPU<Impl> *cpu; 2945154Sgblack@eecs.umich.edu 2955154Sgblack@eecs.umich.edu public: 2965154Sgblack@eecs.umich.edu /** Constructs the event. */ 2975154Sgblack@eecs.umich.edu DeallocateContextEvent(); 2985154Sgblack@eecs.umich.edu 2994434Ssaidi@eecs.umich.edu /** Initialize Event */ 3004434Ssaidi@eecs.umich.edu void init(int thread_num, FullO3CPU<Impl> *thread_cpu); 3014434Ssaidi@eecs.umich.edu 3024434Ssaidi@eecs.umich.edu /** Processes the event, calling activateThread() on the CPU. */ 3034434Ssaidi@eecs.umich.edu void process(); 3043311Ssaidi@eecs.umich.edu 3053311Ssaidi@eecs.umich.edu /** Sets whether the thread should also be removed from the CPU. */ 3063311Ssaidi@eecs.umich.edu void setRemove(bool _remove) { remove = _remove; } 3073311Ssaidi@eecs.umich.edu 3083311Ssaidi@eecs.umich.edu /** Returns the description of the event. */ 3093311Ssaidi@eecs.umich.edu const char *description() const; 3103311Ssaidi@eecs.umich.edu }; 3113311Ssaidi@eecs.umich.edu 3123311Ssaidi@eecs.umich.edu /** Schedule cpu to deallocate thread context.*/ 3133311Ssaidi@eecs.umich.edu void 3143311Ssaidi@eecs.umich.edu scheduleDeallocateContextEvent(ThreadID tid, bool remove, Cycles delay) 3153311Ssaidi@eecs.umich.edu { 3163311Ssaidi@eecs.umich.edu // Schedule thread to activate, regardless of its current state. 3173311Ssaidi@eecs.umich.edu if (deallocateContextEvent[tid].squashed()) 3183311Ssaidi@eecs.umich.edu reschedule(deallocateContextEvent[tid], 3193311Ssaidi@eecs.umich.edu clockEdge(delay)); 3203311Ssaidi@eecs.umich.edu else if (!deallocateContextEvent[tid].scheduled()) 3213311Ssaidi@eecs.umich.edu schedule(deallocateContextEvent[tid], 3223311Ssaidi@eecs.umich.edu clockEdge(delay)); 3233311Ssaidi@eecs.umich.edu } 3243311Ssaidi@eecs.umich.edu 3253311Ssaidi@eecs.umich.edu /** Unschedule thread deallocation in CPU */ 3263311Ssaidi@eecs.umich.edu void 3273311Ssaidi@eecs.umich.edu unscheduleDeallocateContextEvent(ThreadID tid) 3283311Ssaidi@eecs.umich.edu { 3293311Ssaidi@eecs.umich.edu if (deallocateContextEvent[tid].scheduled()) 3303311Ssaidi@eecs.umich.edu deallocateContextEvent[tid].squash(); 3313311Ssaidi@eecs.umich.edu } 3323311Ssaidi@eecs.umich.edu 3333311Ssaidi@eecs.umich.edu /** The tick event used for scheduling CPU ticks. */ 3343311Ssaidi@eecs.umich.edu DeallocateContextEvent deallocateContextEvent[Impl::MaxThreads]; 3353311Ssaidi@eecs.umich.edu 3363311Ssaidi@eecs.umich.edu /** 3373311Ssaidi@eecs.umich.edu * Check if the pipeline has drained and signal the DrainManager. 3383311Ssaidi@eecs.umich.edu * 3392SN/A * This method checks if a drain has been requested and if the CPU 3402SN/A * has drained successfully (i.e., there are no instructions in 3412SN/A * the pipeline). If the CPU has drained, it deschedules the tick 3422SN/A * event and signals the drain manager. 3432SN/A * 3442SN/A * @return False if a drain hasn't been requested or the CPU 3452SN/A * hasn't drained, true otherwise. 3462SN/A */ 34712SN/A bool tryDrain(); 3485154Sgblack@eecs.umich.edu 3495154Sgblack@eecs.umich.edu /** 3505154Sgblack@eecs.umich.edu * Perform sanity checks after a drain. 3512SN/A * 3525154Sgblack@eecs.umich.edu * This method is called from drain() when it has determined that 3535154Sgblack@eecs.umich.edu * the CPU is fully drained when gem5 is compiled with the NDEBUG 3545154Sgblack@eecs.umich.edu * macro undefined. The intention of this method is to do more 3555154Sgblack@eecs.umich.edu * extensive tests than the isDrained() method to weed out any 3565154Sgblack@eecs.umich.edu * draining bugs. 3575154Sgblack@eecs.umich.edu */ 3583114Sgblack@eecs.umich.edu void drainSanityCheck() const; 3595154Sgblack@eecs.umich.edu 36012SN/A /** Check if a system is in a drained state. */ 3611158SN/A bool isDrained() const; 3621158SN/A 3631158SN/A public: 3641158SN/A /** Constructs a CPU with the given parameters. */ 3651158SN/A FullO3CPU(DerivO3CPUParams *params); 3661158SN/A /** Destructor. */ 3671158SN/A ~FullO3CPU(); 3681158SN/A 3691158SN/A /** Registers statistics. */ 3701158SN/A void regStats(); 3711158SN/A 3722378SN/A void demapPage(Addr vaddr, uint64_t asn) 3731158SN/A { 3742378SN/A this->itb->demapPage(vaddr, asn); 3752474SN/A this->dtb->demapPage(vaddr, asn); 3762378SN/A } 3772378SN/A 37812SN/A void demapInstPage(Addr vaddr, uint64_t asn) 3792378SN/A { 3802378SN/A this->itb->demapPage(vaddr, asn); 38112SN/A } 38212SN/A 3832474SN/A void demapDataPage(Addr vaddr, uint64_t asn) 3842474SN/A { 38512SN/A this->dtb->demapPage(vaddr, asn); 38612SN/A } 38712SN/A 38812SN/A /** Ticks CPU, calling tick() on each stage, and checking the overall 38912SN/A * activity to see if the CPU should deschedule itself. 39012SN/A */ 39112SN/A void tick(); 39212SN/A 39312SN/A /** Initialize the CPU */ 39412SN/A void init(); 39512SN/A 3963005Sstever@eecs.umich.edu void startup(); 3973005Sstever@eecs.umich.edu 39812SN/A /** Returns the Number of Active Threads in the CPU */ 39912SN/A int numActiveThreads() 40012SN/A { return activeThreads.size(); } 40112SN/A 4022800Ssaidi@eecs.umich.edu /** Add Thread to Active Threads List */ 40312SN/A void activateThread(ThreadID tid); 4042378SN/A 4052800Ssaidi@eecs.umich.edu /** Remove Thread from Active Threads List */ 40612SN/A void deactivateThread(ThreadID tid); 40712SN/A 4082523SN/A /** Setup CPU to insert a thread's context */ 40912SN/A void insertThread(ThreadID tid); 41012SN/A 41112SN/A /** Remove all of a thread's context from CPU */ 41212SN/A void removeThread(ThreadID tid); 41312SN/A 41412SN/A /** Count the Total Instructions Committed in the CPU. */ 4152474SN/A virtual Counter totalInsts() const; 4162474SN/A 4172474SN/A /** Count the Total Ops (including micro ops) committed in the CPU. */ 4182474SN/A virtual Counter totalOps() const; 4192474SN/A 4202474SN/A /** Add Thread to Active Threads List. */ 4212474SN/A void activateContext(ThreadID tid, Cycles delay); 4222474SN/A 42312SN/A /** Remove Thread from Active Threads List */ 4242378SN/A void suspendContext(ThreadID tid); 4252378SN/A 42612SN/A /** Remove Thread from Active Threads List && 4274772Sgblack@eecs.umich.edu * Possibly Remove Thread Context from CPU. 4284772Sgblack@eecs.umich.edu */ 4294772Sgblack@eecs.umich.edu bool scheduleDeallocateContext(ThreadID tid, bool remove, 4302680Sktlim@umich.edu Cycles delay = Cycles(1)); 4312451SN/A 4322451SN/A /** Remove Thread from Active Threads List && 4332680Sktlim@umich.edu * Remove Thread Context from CPU. 4342680Sktlim@umich.edu */ 4352817Sksewell@umich.edu void haltContext(ThreadID tid); 4362817Sksewell@umich.edu 4372680Sktlim@umich.edu /** Activate a Thread When CPU Resources are Available. */ 4382817Sksewell@umich.edu void activateWhenReady(ThreadID tid); 4392378SN/A 4402378SN/A /** Add or Remove a Thread Context in the CPU. */ 4412SN/A void doContextSwitch(); 4422SN/A 4432093SN/A /** Update The Order In Which We Process Threads. */ 4442680Sktlim@umich.edu void updateThreadPriority(); 4452093SN/A 4462093SN/A /** Is the CPU draining? */ 4472093SN/A bool isDraining() const { return getDrainState() == Drainable::Draining; } 4482093SN/A 4492093SN/A void serializeThread(std::ostream &os, ThreadID tid); 4502093SN/A 4512093SN/A void unserializeThread(Checkpoint *cp, const std::string §ion, 4522680Sktlim@umich.edu ThreadID tid); 4532093SN/A 4542SN/A public: 4552715Sstever@eecs.umich.edu /** Executes a syscall. 4565154Sgblack@eecs.umich.edu * @todo: Determine if this needs to be virtual. 4572715Sstever@eecs.umich.edu */ 4582715Sstever@eecs.umich.edu void syscall(int64_t callnum, ThreadID tid); 4592715Sstever@eecs.umich.edu 4605154Sgblack@eecs.umich.edu /** Starts draining the CPU's pipeline of all instructions in 4615154Sgblack@eecs.umich.edu * order to stop all memory accesses. */ 4622715Sstever@eecs.umich.edu unsigned int drain(DrainManager *drain_manager); 4632715Sstever@eecs.umich.edu 4642715Sstever@eecs.umich.edu /** Resumes execution after a drain. */ 4652715Sstever@eecs.umich.edu void drainResume(); 4662715Sstever@eecs.umich.edu 4673917Ssaidi@eecs.umich.edu /** 4683917Ssaidi@eecs.umich.edu * Commit has reached a safe point to drain a thread. 4695070Ssaidi@eecs.umich.edu * 4703917Ssaidi@eecs.umich.edu * Commit calls this method to inform the pipeline that it has 4713917Ssaidi@eecs.umich.edu * reached a point where it is not executed microcode and is about 4725089Sgblack@eecs.umich.edu * to squash uncommitted instructions to fully drain the pipeline. 4735070Ssaidi@eecs.umich.edu */ 4745089Sgblack@eecs.umich.edu void commitDrained(ThreadID tid); 4755089Sgblack@eecs.umich.edu 4765089Sgblack@eecs.umich.edu /** Switches out this CPU. */ 4775070Ssaidi@eecs.umich.edu virtual void switchOut(); 4782715Sstever@eecs.umich.edu 4792715Sstever@eecs.umich.edu /** Takes over from another CPU. */ 4802715Sstever@eecs.umich.edu virtual void takeOverFrom(BaseCPU *oldCPU); 4812715Sstever@eecs.umich.edu 4825154Sgblack@eecs.umich.edu void verifyMemoryMode() const; 4832715Sstever@eecs.umich.edu 4842715Sstever@eecs.umich.edu /** Get the current instruction sequence number, and increment it. */ 4852715Sstever@eecs.umich.edu InstSeqNum getAndIncrementInstSeq() 4865154Sgblack@eecs.umich.edu { return globalSeqNum++; } 4872715Sstever@eecs.umich.edu 4882715Sstever@eecs.umich.edu /** Traps to handle given fault. */ 4892715Sstever@eecs.umich.edu void trap(Fault fault, ThreadID tid, StaticInstPtr inst); 4902715Sstever@eecs.umich.edu 4912715Sstever@eecs.umich.edu /** HW return from error interrupt. */ 4922715Sstever@eecs.umich.edu Fault hwrei(ThreadID tid); 4934111Sgblack@eecs.umich.edu 4942715Sstever@eecs.umich.edu bool simPalCheck(int palFunc, ThreadID tid); 4952715Sstever@eecs.umich.edu 4962715Sstever@eecs.umich.edu /** Returns the Fault for any valid interrupt. */ 4974111Sgblack@eecs.umich.edu Fault getInterrupts(); 4985154Sgblack@eecs.umich.edu 4994111Sgblack@eecs.umich.edu /** Processes any an interrupt fault. */ 5005154Sgblack@eecs.umich.edu void processInterrupts(Fault interrupt); 5014111Sgblack@eecs.umich.edu 5022715Sstever@eecs.umich.edu /** Halts the CPU. */ 5032715Sstever@eecs.umich.edu void halt() { panic("Halt not implemented!\n"); } 5042715Sstever@eecs.umich.edu 5052715Sstever@eecs.umich.edu /** Check if this address is a valid instruction address. */ 5065154Sgblack@eecs.umich.edu bool validInstAddr(Addr addr) { return true; } 5072715Sstever@eecs.umich.edu 5082715Sstever@eecs.umich.edu /** Check if this address is a valid data address. */ 5092715Sstever@eecs.umich.edu bool validDataAddr(Addr addr) { return true; } 5102715Sstever@eecs.umich.edu 5114157Sgblack@eecs.umich.edu /** Register accessors. Index refers to the physical register index. */ 5124157Sgblack@eecs.umich.edu 5134166Sgblack@eecs.umich.edu /** Reads a miscellaneous register. */ 5144157Sgblack@eecs.umich.edu TheISA::MiscReg readMiscRegNoEffect(int misc_reg, ThreadID tid); 5154166Sgblack@eecs.umich.edu 5165154Sgblack@eecs.umich.edu /** Reads a misc. register, including any side effects the read 5174166Sgblack@eecs.umich.edu * might have as defined by the architecture. 5184157Sgblack@eecs.umich.edu */ 5194157Sgblack@eecs.umich.edu TheISA::MiscReg readMiscReg(int misc_reg, ThreadID tid); 5204157Sgblack@eecs.umich.edu 5212715Sstever@eecs.umich.edu /** Sets a miscellaneous register. */ 5222715Sstever@eecs.umich.edu void setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val, 5232715Sstever@eecs.umich.edu ThreadID tid); 5242715Sstever@eecs.umich.edu 5252715Sstever@eecs.umich.edu /** Sets a misc. register, including any side effects the write 5265154Sgblack@eecs.umich.edu * might have as defined by the architecture. 5272715Sstever@eecs.umich.edu */ 5282715Sstever@eecs.umich.edu void setMiscReg(int misc_reg, const TheISA::MiscReg &val, 5292715Sstever@eecs.umich.edu ThreadID tid); 5302715Sstever@eecs.umich.edu 5312715Sstever@eecs.umich.edu uint64_t readIntReg(int reg_idx); 5322715Sstever@eecs.umich.edu 5332715Sstever@eecs.umich.edu TheISA::FloatReg readFloatReg(int reg_idx); 5342715Sstever@eecs.umich.edu 5352715Sstever@eecs.umich.edu TheISA::FloatRegBits readFloatRegBits(int reg_idx); 5362715Sstever@eecs.umich.edu 5372715Sstever@eecs.umich.edu void setIntReg(int reg_idx, uint64_t val); 5382715Sstever@eecs.umich.edu 5392715Sstever@eecs.umich.edu void setFloatReg(int reg_idx, TheISA::FloatReg val); 5402715Sstever@eecs.umich.edu 5412715Sstever@eecs.umich.edu void setFloatRegBits(int reg_idx, TheISA::FloatRegBits val); 5424762Snate@binkert.org 5434762Snate@binkert.org uint64_t readArchIntReg(int reg_idx, ThreadID tid); 5442715Sstever@eecs.umich.edu 5455154Sgblack@eecs.umich.edu float readArchFloatReg(int reg_idx, ThreadID tid); 5462715Sstever@eecs.umich.edu 547 uint64_t readArchFloatRegInt(int reg_idx, ThreadID tid); 548 549 /** Architectural register accessors. Looks up in the commit 550 * rename table to obtain the true physical index of the 551 * architected register first, then accesses that physical 552 * register. 553 */ 554 void setArchIntReg(int reg_idx, uint64_t val, ThreadID tid); 555 556 void setArchFloatReg(int reg_idx, float val, ThreadID tid); 557 558 void setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid); 559 560 /** Sets the commit PC state of a specific thread. */ 561 void pcState(const TheISA::PCState &newPCState, ThreadID tid); 562 563 /** Reads the commit PC state of a specific thread. */ 564 TheISA::PCState pcState(ThreadID tid); 565 566 /** Reads the commit PC of a specific thread. */ 567 Addr instAddr(ThreadID tid); 568 569 /** Reads the commit micro PC of a specific thread. */ 570 MicroPC microPC(ThreadID tid); 571 572 /** Reads the next PC of a specific thread. */ 573 Addr nextInstAddr(ThreadID tid); 574 575 /** Initiates a squash of all in-flight instructions for a given 576 * thread. The source of the squash is an external update of 577 * state through the TC. 578 */ 579 void squashFromTC(ThreadID tid); 580 581 /** Function to add instruction onto the head of the list of the 582 * instructions. Used when new instructions are fetched. 583 */ 584 ListIt addInst(DynInstPtr &inst); 585 586 /** Function to tell the CPU that an instruction has completed. */ 587 void instDone(ThreadID tid, DynInstPtr &inst); 588 589 /** Remove an instruction from the front end of the list. There's 590 * no restriction on location of the instruction. 591 */ 592 void removeFrontInst(DynInstPtr &inst); 593 594 /** Remove all instructions that are not currently in the ROB. 595 * There's also an option to not squash delay slot instructions.*/ 596 void removeInstsNotInROB(ThreadID tid); 597 598 /** Remove all instructions younger than the given sequence number. */ 599 void removeInstsUntil(const InstSeqNum &seq_num, ThreadID tid); 600 601 /** Removes the instruction pointed to by the iterator. */ 602 inline void squashInstIt(const ListIt &instIt, ThreadID tid); 603 604 /** Cleans up all instructions on the remove list. */ 605 void cleanUpRemovedInsts(); 606 607 /** Debug function to print all instructions on the list. */ 608 void dumpInsts(); 609 610 public: 611#ifndef NDEBUG 612 /** Count of total number of dynamic instructions in flight. */ 613 int instcount; 614#endif 615 616 /** List of all the instructions in flight. */ 617 std::list<DynInstPtr> instList; 618 619 /** List of all the instructions that will be removed at the end of this 620 * cycle. 621 */ 622 std::queue<ListIt> removeList; 623 624#ifdef DEBUG 625 /** Debug structure to keep track of the sequence numbers still in 626 * flight. 627 */ 628 std::set<InstSeqNum> snList; 629#endif 630 631 /** Records if instructions need to be removed this cycle due to 632 * being retired or squashed. 633 */ 634 bool removeInstsThisCycle; 635 636 protected: 637 /** The fetch stage. */ 638 typename CPUPolicy::Fetch fetch; 639 640 /** The decode stage. */ 641 typename CPUPolicy::Decode decode; 642 643 /** The dispatch stage. */ 644 typename CPUPolicy::Rename rename; 645 646 /** The issue/execute/writeback stages. */ 647 typename CPUPolicy::IEW iew; 648 649 /** The commit stage. */ 650 typename CPUPolicy::Commit commit; 651 652 /** The register file. */ 653 typename CPUPolicy::RegFile regFile; 654 655 /** The free list. */ 656 typename CPUPolicy::FreeList freeList; 657 658 /** The rename map. */ 659 typename CPUPolicy::RenameMap renameMap[Impl::MaxThreads]; 660 661 /** The commit rename map. */ 662 typename CPUPolicy::RenameMap commitRenameMap[Impl::MaxThreads]; 663 664 /** The re-order buffer. */ 665 typename CPUPolicy::ROB rob; 666 667 /** Active Threads List */ 668 std::list<ThreadID> activeThreads; 669 670 /** Integer Register Scoreboard */ 671 Scoreboard scoreboard; 672 673 std::vector<TheISA::ISA *> isa; 674 675 /** Instruction port. Note that it has to appear after the fetch stage. */ 676 IcachePort icachePort; 677 678 /** Data port. Note that it has to appear after the iew stages */ 679 DcachePort dcachePort; 680 681 public: 682 /** Enum to give each stage a specific index, so when calling 683 * activateStage() or deactivateStage(), they can specify which stage 684 * is being activated/deactivated. 685 */ 686 enum StageIdx { 687 FetchIdx, 688 DecodeIdx, 689 RenameIdx, 690 IEWIdx, 691 CommitIdx, 692 NumStages }; 693 694 /** Typedefs from the Impl to get the structs that each of the 695 * time buffers should use. 696 */ 697 typedef typename CPUPolicy::TimeStruct TimeStruct; 698 699 typedef typename CPUPolicy::FetchStruct FetchStruct; 700 701 typedef typename CPUPolicy::DecodeStruct DecodeStruct; 702 703 typedef typename CPUPolicy::RenameStruct RenameStruct; 704 705 typedef typename CPUPolicy::IEWStruct IEWStruct; 706 707 /** The main time buffer to do backwards communication. */ 708 TimeBuffer<TimeStruct> timeBuffer; 709 710 /** The fetch stage's instruction queue. */ 711 TimeBuffer<FetchStruct> fetchQueue; 712 713 /** The decode stage's instruction queue. */ 714 TimeBuffer<DecodeStruct> decodeQueue; 715 716 /** The rename stage's instruction queue. */ 717 TimeBuffer<RenameStruct> renameQueue; 718 719 /** The IEW stage's instruction queue. */ 720 TimeBuffer<IEWStruct> iewQueue; 721 722 private: 723 /** The activity recorder; used to tell if the CPU has any 724 * activity remaining or if it can go to idle and deschedule 725 * itself. 726 */ 727 ActivityRecorder activityRec; 728 729 public: 730 /** Records that there was time buffer activity this cycle. */ 731 void activityThisCycle() { activityRec.activity(); } 732 733 /** Changes a stage's status to active within the activity recorder. */ 734 void activateStage(const StageIdx idx) 735 { activityRec.activateStage(idx); } 736 737 /** Changes a stage's status to inactive within the activity recorder. */ 738 void deactivateStage(const StageIdx idx) 739 { activityRec.deactivateStage(idx); } 740 741 /** Wakes the CPU, rescheduling the CPU if it's not already active. */ 742 void wakeCPU(); 743 744 virtual void wakeup(); 745 746 /** Gets a free thread id. Use if thread ids change across system. */ 747 ThreadID getFreeTid(); 748 749 public: 750 /** Returns a pointer to a thread context. */ 751 ThreadContext * 752 tcBase(ThreadID tid) 753 { 754 return thread[tid]->getTC(); 755 } 756 757 /** The global sequence number counter. */ 758 InstSeqNum globalSeqNum;//[Impl::MaxThreads]; 759 760 /** Pointer to the checker, which can dynamically verify 761 * instruction results at run time. This can be set to NULL if it 762 * is not being used. 763 */ 764 Checker<Impl> *checker; 765 766 /** Pointer to the system. */ 767 System *system; 768 769 /** DrainManager to notify when draining has completed. */ 770 DrainManager *drainManager; 771 772 /** Pointers to all of the threads in the CPU. */ 773 std::vector<Thread *> thread; 774 775 /** Is there a context switch pending? */ 776 bool contextSwitch; 777 778 /** Threads Scheduled to Enter CPU */ 779 std::list<int> cpuWaitList; 780 781 /** The cycle that the CPU was last running, used for statistics. */ 782 Cycles lastRunningCycle; 783 784 /** The cycle that the CPU was last activated by a new thread*/ 785 Tick lastActivatedCycle; 786 787 /** Mapping for system thread id to cpu id */ 788 std::map<ThreadID, unsigned> threadMap; 789 790 /** Available thread ids in the cpu*/ 791 std::vector<ThreadID> tids; 792 793 /** CPU read function, forwards read to LSQ. */ 794 Fault read(RequestPtr &req, RequestPtr &sreqLow, RequestPtr &sreqHigh, 795 uint8_t *data, int load_idx) 796 { 797 return this->iew.ldstQueue.read(req, sreqLow, sreqHigh, 798 data, load_idx); 799 } 800 801 /** CPU write function, forwards write to LSQ. */ 802 Fault write(RequestPtr &req, RequestPtr &sreqLow, RequestPtr &sreqHigh, 803 uint8_t *data, int store_idx) 804 { 805 return this->iew.ldstQueue.write(req, sreqLow, sreqHigh, 806 data, store_idx); 807 } 808 809 /** Used by the fetch unit to get a hold of the instruction port. */ 810 virtual CpuPort &getInstPort() { return icachePort; } 811 812 /** Get the dcache port (used to find block size for translations). */ 813 virtual CpuPort &getDataPort() { return dcachePort; } 814 815 /** Stat for total number of times the CPU is descheduled. */ 816 Stats::Scalar timesIdled; 817 /** Stat for total number of cycles the CPU spends descheduled. */ 818 Stats::Scalar idleCycles; 819 /** Stat for total number of cycles the CPU spends descheduled due to a 820 * quiesce operation or waiting for an interrupt. */ 821 Stats::Scalar quiesceCycles; 822 /** Stat for the number of committed instructions per thread. */ 823 Stats::Vector committedInsts; 824 /** Stat for the number of committed ops (including micro ops) per thread. */ 825 Stats::Vector committedOps; 826 /** Stat for the total number of committed instructions. */ 827 Stats::Scalar totalCommittedInsts; 828 /** Stat for the CPI per thread. */ 829 Stats::Formula cpi; 830 /** Stat for the total CPI. */ 831 Stats::Formula totalCpi; 832 /** Stat for the IPC per thread. */ 833 Stats::Formula ipc; 834 /** Stat for the total IPC. */ 835 Stats::Formula totalIpc; 836 837 //number of integer register file accesses 838 Stats::Scalar intRegfileReads; 839 Stats::Scalar intRegfileWrites; 840 //number of float register file accesses 841 Stats::Scalar fpRegfileReads; 842 Stats::Scalar fpRegfileWrites; 843 //number of misc 844 Stats::Scalar miscRegfileReads; 845 Stats::Scalar miscRegfileWrites; 846}; 847 848#endif // __CPU_O3_CPU_HH__ 849