cpu.hh revision 5529
17119Sgblack@eecs.umich.edu/*
27119Sgblack@eecs.umich.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan
310037SARM gem5 Developers * All rights reserved.
47119Sgblack@eecs.umich.edu *
57119Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
67119Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
77119Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
87119Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
97119Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
107119Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
117119Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
127119Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
137119Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
147119Sgblack@eecs.umich.edu * this software without specific prior written permission.
157119Sgblack@eecs.umich.edu *
167119Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
177119Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
187119Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
197119Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
207119Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
217119Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
227119Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
237119Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
247119Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
257119Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
267119Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
277119Sgblack@eecs.umich.edu *
287119Sgblack@eecs.umich.edu * Authors: Kevin Lim
297119Sgblack@eecs.umich.edu *          Korey Sewell
307119Sgblack@eecs.umich.edu */
317119Sgblack@eecs.umich.edu
327119Sgblack@eecs.umich.edu#ifndef __CPU_O3_CPU_HH__
337119Sgblack@eecs.umich.edu#define __CPU_O3_CPU_HH__
347119Sgblack@eecs.umich.edu
357119Sgblack@eecs.umich.edu#include <iostream>
367119Sgblack@eecs.umich.edu#include <list>
377119Sgblack@eecs.umich.edu#include <queue>
387119Sgblack@eecs.umich.edu#include <set>
397119Sgblack@eecs.umich.edu#include <vector>
407119Sgblack@eecs.umich.edu
4110037SARM gem5 Developers#include "arch/types.hh"
427119Sgblack@eecs.umich.edu#include "base/statistics.hh"
437119Sgblack@eecs.umich.edu#include "base/timebuf.hh"
447119Sgblack@eecs.umich.edu#include "config/full_system.hh"
457119Sgblack@eecs.umich.edu#include "config/use_checker.hh"
467119Sgblack@eecs.umich.edu#include "cpu/activity.hh"
477590Sgblack@eecs.umich.edu#include "cpu/base.hh"
487590Sgblack@eecs.umich.edu#include "cpu/simple_thread.hh"
497119Sgblack@eecs.umich.edu#include "cpu/o3/comm.hh"
507590Sgblack@eecs.umich.edu#include "cpu/o3/cpu_policy.hh"
517590Sgblack@eecs.umich.edu#include "cpu/o3/scoreboard.hh"
527590Sgblack@eecs.umich.edu#include "cpu/o3/thread_state.hh"
537590Sgblack@eecs.umich.edu//#include "cpu/o3/thread_context.hh"
547590Sgblack@eecs.umich.edu#include "sim/process.hh"
557590Sgblack@eecs.umich.edu
567590Sgblack@eecs.umich.edu#include "params/DerivO3CPU.hh"
577590Sgblack@eecs.umich.edu
587590Sgblack@eecs.umich.edutemplate <class>
597590Sgblack@eecs.umich.educlass Checker;
607590Sgblack@eecs.umich.educlass ThreadContext;
617590Sgblack@eecs.umich.edutemplate <class>
628203SAli.Saidi@ARM.comclass O3ThreadContext;
637590Sgblack@eecs.umich.edu
647590Sgblack@eecs.umich.educlass Checkpoint;
657590Sgblack@eecs.umich.educlass MemObject;
667590Sgblack@eecs.umich.educlass Process;
677590Sgblack@eecs.umich.edu
687590Sgblack@eecs.umich.educlass BaseCPUParams;
697590Sgblack@eecs.umich.edu
707590Sgblack@eecs.umich.educlass BaseO3CPU : public BaseCPU
717590Sgblack@eecs.umich.edu{
728140SMatt.Horsnell@arm.com    //Stuff that's pretty ISA independent will go here.
737590Sgblack@eecs.umich.edu  public:
747590Sgblack@eecs.umich.edu    BaseO3CPU(BaseCPUParams *params);
757590Sgblack@eecs.umich.edu
767590Sgblack@eecs.umich.edu    void regStats();
777590Sgblack@eecs.umich.edu
787590Sgblack@eecs.umich.edu    /** Sets this CPU's ID. */
797590Sgblack@eecs.umich.edu    void setCpuId(int id) { cpu_id = id; }
807590Sgblack@eecs.umich.edu
818140SMatt.Horsnell@arm.com    /** Reads this CPU's ID. */
8210037SARM gem5 Developers    int readCpuId() { return cpu_id; }
8310037SARM gem5 Developers
847590Sgblack@eecs.umich.edu  protected:
857590Sgblack@eecs.umich.edu    int cpu_id;
867590Sgblack@eecs.umich.edu};
877590Sgblack@eecs.umich.edu
887590Sgblack@eecs.umich.edu/**
897590Sgblack@eecs.umich.edu * FullO3CPU class, has each of the stages (fetch through commit)
907590Sgblack@eecs.umich.edu * within it, as well as all of the time buffers between stages.  The
917590Sgblack@eecs.umich.edu * tick() function for the CPU is defined here.
927590Sgblack@eecs.umich.edu */
937590Sgblack@eecs.umich.edutemplate <class Impl>
947590Sgblack@eecs.umich.educlass FullO3CPU : public BaseO3CPU
957590Sgblack@eecs.umich.edu{
967590Sgblack@eecs.umich.edu  public:
977590Sgblack@eecs.umich.edu    // Typedefs from the Impl here.
987590Sgblack@eecs.umich.edu    typedef typename Impl::CPUPol CPUPolicy;
997590Sgblack@eecs.umich.edu    typedef typename Impl::DynInstPtr DynInstPtr;
1007590Sgblack@eecs.umich.edu    typedef typename Impl::O3CPU O3CPU;
1017590Sgblack@eecs.umich.edu
1027590Sgblack@eecs.umich.edu    typedef O3ThreadState<Impl> Thread;
1037590Sgblack@eecs.umich.edu
1047590Sgblack@eecs.umich.edu    typedef typename std::list<DynInstPtr>::iterator ListIt;
1057590Sgblack@eecs.umich.edu
1067590Sgblack@eecs.umich.edu    friend class O3ThreadContext<Impl>;
1077590Sgblack@eecs.umich.edu
1087590Sgblack@eecs.umich.edu  public:
1097590Sgblack@eecs.umich.edu    enum Status {
1107590Sgblack@eecs.umich.edu        Running,
1118303SAli.Saidi@ARM.com        Idle,
1128303SAli.Saidi@ARM.com        Halted,
1138303SAli.Saidi@ARM.com        Blocked,
1148303SAli.Saidi@ARM.com        SwitchedOut
1158303SAli.Saidi@ARM.com    };
1168588Sgblack@eecs.umich.edu
1178588Sgblack@eecs.umich.edu    TheISA::ITB * itb;
1187590Sgblack@eecs.umich.edu    TheISA::DTB * dtb;
1197590Sgblack@eecs.umich.edu
1207590Sgblack@eecs.umich.edu    /** Overall CPU status. */
1217646Sgene.wu@arm.com    Status _status;
1228140SMatt.Horsnell@arm.com
1238140SMatt.Horsnell@arm.com    /** Per-thread status in CPU, used for SMT.  */
1247646Sgene.wu@arm.com    Status _threadStatus[Impl::MaxThreads];
1257646Sgene.wu@arm.com
1268140SMatt.Horsnell@arm.com  private:
1277590Sgblack@eecs.umich.edu    class TickEvent : public Event
1287590Sgblack@eecs.umich.edu    {
1297590Sgblack@eecs.umich.edu      private:
1307590Sgblack@eecs.umich.edu        /** Pointer to the CPU. */
1317590Sgblack@eecs.umich.edu        FullO3CPU<Impl> *cpu;
1327590Sgblack@eecs.umich.edu
1337646Sgene.wu@arm.com      public:
1347646Sgene.wu@arm.com        /** Constructs a tick event. */
1357646Sgene.wu@arm.com        TickEvent(FullO3CPU<Impl> *c);
1367646Sgene.wu@arm.com
1377646Sgene.wu@arm.com        /** Processes a tick event, calling tick() on the CPU. */
1388203SAli.Saidi@ARM.com        void process();
1398203SAli.Saidi@ARM.com        /** Returns the description of the tick event. */
1408203SAli.Saidi@ARM.com        const char *description() const;
1418203SAli.Saidi@ARM.com    };
1427590Sgblack@eecs.umich.edu
1437590Sgblack@eecs.umich.edu    /** The tick event used for scheduling CPU ticks. */
1447590Sgblack@eecs.umich.edu    TickEvent tickEvent;
1457590Sgblack@eecs.umich.edu
1468304SAli.Saidi@ARM.com    /** Schedule tick event, regardless of its current state. */
1477646Sgene.wu@arm.com    void scheduleTickEvent(int delay)
1487646Sgene.wu@arm.com    {
1497646Sgene.wu@arm.com        if (tickEvent.squashed())
1507646Sgene.wu@arm.com            tickEvent.reschedule(nextCycle(curTick + ticks(delay)));
1517646Sgene.wu@arm.com        else if (!tickEvent.scheduled())
1527646Sgene.wu@arm.com            tickEvent.schedule(nextCycle(curTick + ticks(delay)));
1537646Sgene.wu@arm.com    }
1547646Sgene.wu@arm.com
1557590Sgblack@eecs.umich.edu    /** Unschedule tick event, regardless of its current state. */
1567590Sgblack@eecs.umich.edu    void unscheduleTickEvent()
1577590Sgblack@eecs.umich.edu    {
1587590Sgblack@eecs.umich.edu        if (tickEvent.scheduled())
1597590Sgblack@eecs.umich.edu            tickEvent.squash();
1607590Sgblack@eecs.umich.edu    }
1617590Sgblack@eecs.umich.edu
1627590Sgblack@eecs.umich.edu    class ActivateThreadEvent : public Event
1637590Sgblack@eecs.umich.edu    {
1647590Sgblack@eecs.umich.edu      private:
16510037SARM gem5 Developers        /** Number of Thread to Activate */
1667590Sgblack@eecs.umich.edu        int tid;
1677590Sgblack@eecs.umich.edu
1687590Sgblack@eecs.umich.edu        /** Pointer to the CPU. */
1697725SAli.Saidi@ARM.com        FullO3CPU<Impl> *cpu;
1707725SAli.Saidi@ARM.com
1717590Sgblack@eecs.umich.edu      public:
1727725SAli.Saidi@ARM.com        /** Constructs the event. */
1737725SAli.Saidi@ARM.com        ActivateThreadEvent();
1747725SAli.Saidi@ARM.com
1757725SAli.Saidi@ARM.com        /** Initialize Event */
1767590Sgblack@eecs.umich.edu        void init(int thread_num, FullO3CPU<Impl> *thread_cpu);
1777590Sgblack@eecs.umich.edu
1787590Sgblack@eecs.umich.edu        /** Processes the event, calling activateThread() on the CPU. */
1797590Sgblack@eecs.umich.edu        void process();
1807590Sgblack@eecs.umich.edu
1817590Sgblack@eecs.umich.edu        /** Returns the description of the event. */
1827590Sgblack@eecs.umich.edu        const char *description() const;
1837590Sgblack@eecs.umich.edu    };
1847590Sgblack@eecs.umich.edu
1857590Sgblack@eecs.umich.edu    /** Schedule thread to activate , regardless of its current state. */
1867590Sgblack@eecs.umich.edu    void scheduleActivateThreadEvent(int tid, int delay)
1877590Sgblack@eecs.umich.edu    {
1887590Sgblack@eecs.umich.edu        // Schedule thread to activate, regardless of its current state.
1897590Sgblack@eecs.umich.edu        if (activateThreadEvent[tid].squashed())
1907590Sgblack@eecs.umich.edu            activateThreadEvent[tid].
1917644Sali.saidi@arm.com                reschedule(nextCycle(curTick + ticks(delay)));
1927644Sali.saidi@arm.com        else if (!activateThreadEvent[tid].scheduled())
1937644Sali.saidi@arm.com            activateThreadEvent[tid].
1947644Sali.saidi@arm.com                schedule(nextCycle(curTick + ticks(delay)));
1957590Sgblack@eecs.umich.edu    }
1967590Sgblack@eecs.umich.edu
1977590Sgblack@eecs.umich.edu    /** Unschedule actiavte thread event, regardless of its current state. */
1987725SAli.Saidi@ARM.com    void unscheduleActivateThreadEvent(int tid)
1997590Sgblack@eecs.umich.edu    {
2007590Sgblack@eecs.umich.edu        if (activateThreadEvent[tid].scheduled())
2018588Sgblack@eecs.umich.edu            activateThreadEvent[tid].squash();
2027590Sgblack@eecs.umich.edu    }
2037590Sgblack@eecs.umich.edu
2047590Sgblack@eecs.umich.edu    /** The tick event used for scheduling CPU ticks. */
2057590Sgblack@eecs.umich.edu    ActivateThreadEvent activateThreadEvent[Impl::MaxThreads];
2067590Sgblack@eecs.umich.edu
2077590Sgblack@eecs.umich.edu    class DeallocateContextEvent : public Event
2087590Sgblack@eecs.umich.edu    {
2097590Sgblack@eecs.umich.edu      private:
2107646Sgene.wu@arm.com        /** Number of Thread to deactivate */
2117646Sgene.wu@arm.com        int tid;
2127646Sgene.wu@arm.com
2137725SAli.Saidi@ARM.com        /** Should the thread be removed from the CPU? */
2147590Sgblack@eecs.umich.edu        bool remove;
2157590Sgblack@eecs.umich.edu
2167590Sgblack@eecs.umich.edu        /** Pointer to the CPU. */
2177590Sgblack@eecs.umich.edu        FullO3CPU<Impl> *cpu;
2187590Sgblack@eecs.umich.edu
2197646Sgene.wu@arm.com      public:
2207590Sgblack@eecs.umich.edu        /** Constructs the event. */
2217590Sgblack@eecs.umich.edu        DeallocateContextEvent();
2227590Sgblack@eecs.umich.edu
2237590Sgblack@eecs.umich.edu        /** Initialize Event */
2247590Sgblack@eecs.umich.edu        void init(int thread_num, FullO3CPU<Impl> *thread_cpu);
2257590Sgblack@eecs.umich.edu
2267590Sgblack@eecs.umich.edu        /** Processes the event, calling activateThread() on the CPU. */
2277646Sgene.wu@arm.com        void process();
2287590Sgblack@eecs.umich.edu
2297590Sgblack@eecs.umich.edu        /** Sets whether the thread should also be removed from the CPU. */
2307590Sgblack@eecs.umich.edu        void setRemove(bool _remove) { remove = _remove; }
2317590Sgblack@eecs.umich.edu
2327590Sgblack@eecs.umich.edu        /** Returns the description of the event. */
2337590Sgblack@eecs.umich.edu        const char *description() const;
2347590Sgblack@eecs.umich.edu    };
2357590Sgblack@eecs.umich.edu
2367590Sgblack@eecs.umich.edu    /** Schedule cpu to deallocate thread context.*/
2377590Sgblack@eecs.umich.edu    void scheduleDeallocateContextEvent(int tid, bool remove, int delay)
2387590Sgblack@eecs.umich.edu    {
2397590Sgblack@eecs.umich.edu        // Schedule thread to activate, regardless of its current state.
2407590Sgblack@eecs.umich.edu        if (deallocateContextEvent[tid].squashed())
2417593SAli.Saidi@arm.com            deallocateContextEvent[tid].
2427593SAli.Saidi@arm.com                reschedule(nextCycle(curTick + ticks(delay)));
2437593SAli.Saidi@arm.com        else if (!deallocateContextEvent[tid].scheduled())
2447590Sgblack@eecs.umich.edu            deallocateContextEvent[tid].
2457590Sgblack@eecs.umich.edu                schedule(nextCycle(curTick + ticks(delay)));
2467590Sgblack@eecs.umich.edu    }
2477590Sgblack@eecs.umich.edu
2487590Sgblack@eecs.umich.edu    /** Unschedule thread deallocation in CPU */
2497590Sgblack@eecs.umich.edu    void unscheduleDeallocateContextEvent(int tid)
2507590Sgblack@eecs.umich.edu    {
2517590Sgblack@eecs.umich.edu        if (deallocateContextEvent[tid].scheduled())
2527590Sgblack@eecs.umich.edu            deallocateContextEvent[tid].squash();
2537590Sgblack@eecs.umich.edu    }
2547590Sgblack@eecs.umich.edu
2557644Sali.saidi@arm.com    /** The tick event used for scheduling CPU ticks. */
2567644Sali.saidi@arm.com    DeallocateContextEvent deallocateContextEvent[Impl::MaxThreads];
2577644Sali.saidi@arm.com
2587644Sali.saidi@arm.com  public:
2597590Sgblack@eecs.umich.edu    /** Constructs a CPU with the given parameters. */
2607590Sgblack@eecs.umich.edu    FullO3CPU(O3CPU *o3_cpu, DerivO3CPUParams *params);
2617590Sgblack@eecs.umich.edu    /** Destructor. */
2627590Sgblack@eecs.umich.edu    ~FullO3CPU();
2637590Sgblack@eecs.umich.edu
2647590Sgblack@eecs.umich.edu    /** Registers statistics. */
2658588Sgblack@eecs.umich.edu    void fullCPURegStats();
2668588Sgblack@eecs.umich.edu
2677590Sgblack@eecs.umich.edu    void demapPage(Addr vaddr, uint64_t asn)
2687590Sgblack@eecs.umich.edu    {
2697590Sgblack@eecs.umich.edu        this->itb->demapPage(vaddr, asn);
2708588Sgblack@eecs.umich.edu        this->dtb->demapPage(vaddr, asn);
2718588Sgblack@eecs.umich.edu    }
2728588Sgblack@eecs.umich.edu
2737590Sgblack@eecs.umich.edu    void demapInstPage(Addr vaddr, uint64_t asn)
2747590Sgblack@eecs.umich.edu    {
2757590Sgblack@eecs.umich.edu        this->itb->demapPage(vaddr, asn);
2767590Sgblack@eecs.umich.edu    }
2777590Sgblack@eecs.umich.edu
2787590Sgblack@eecs.umich.edu    void demapDataPage(Addr vaddr, uint64_t asn)
2797646Sgene.wu@arm.com    {
2807646Sgene.wu@arm.com        this->dtb->demapPage(vaddr, asn);
2817646Sgene.wu@arm.com    }
2827646Sgene.wu@arm.com
2837119Sgblack@eecs.umich.edu    /** Translates instruction requestion. */
2847128Sgblack@eecs.umich.edu    Fault translateInstReq(RequestPtr &req, Thread *thread)
2857128Sgblack@eecs.umich.edu    {
2867128Sgblack@eecs.umich.edu        return this->itb->translate(req, thread->getTC());
2877590Sgblack@eecs.umich.edu    }
2887590Sgblack@eecs.umich.edu
2897590Sgblack@eecs.umich.edu    /** Translates data read request. */
2907590Sgblack@eecs.umich.edu    Fault translateDataReadReq(RequestPtr &req, Thread *thread)
2917590Sgblack@eecs.umich.edu    {
2927128Sgblack@eecs.umich.edu        return this->dtb->translate(req, thread->getTC(), false);
2937128Sgblack@eecs.umich.edu    }
2947128Sgblack@eecs.umich.edu
2957590Sgblack@eecs.umich.edu    /** Translates data write request. */
2967646Sgene.wu@arm.com    Fault translateDataWriteReq(RequestPtr &req, Thread *thread)
2977590Sgblack@eecs.umich.edu    {
2987590Sgblack@eecs.umich.edu        return this->dtb->translate(req, thread->getTC(), true);
2997128Sgblack@eecs.umich.edu    }
3007119Sgblack@eecs.umich.edu
3017590Sgblack@eecs.umich.edu    /** Returns a specific port. */
3027590Sgblack@eecs.umich.edu    Port *getPort(const std::string &if_name, int idx);
3037590Sgblack@eecs.umich.edu
3047590Sgblack@eecs.umich.edu    /** Ticks CPU, calling tick() on each stage, and checking the overall
3057590Sgblack@eecs.umich.edu     *  activity to see if the CPU should deschedule itself.
3067590Sgblack@eecs.umich.edu     */
3077590Sgblack@eecs.umich.edu    void tick();
3087590Sgblack@eecs.umich.edu
3097590Sgblack@eecs.umich.edu    /** Initialize the CPU */
3107590Sgblack@eecs.umich.edu    void init();
3117590Sgblack@eecs.umich.edu
3127590Sgblack@eecs.umich.edu    /** Returns the Number of Active Threads in the CPU */
3137119Sgblack@eecs.umich.edu    int numActiveThreads()
3147128Sgblack@eecs.umich.edu    { return activeThreads.size(); }
3157590Sgblack@eecs.umich.edu
3167590Sgblack@eecs.umich.edu    /** Add Thread to Active Threads List */
3177590Sgblack@eecs.umich.edu    void activateThread(unsigned tid);
3187590Sgblack@eecs.umich.edu
3197590Sgblack@eecs.umich.edu    /** Remove Thread from Active Threads List */
3207590Sgblack@eecs.umich.edu    void deactivateThread(unsigned tid);
3217590Sgblack@eecs.umich.edu
3227590Sgblack@eecs.umich.edu    /** Setup CPU to insert a thread's context */
3237590Sgblack@eecs.umich.edu    void insertThread(unsigned tid);
3247590Sgblack@eecs.umich.edu
3257590Sgblack@eecs.umich.edu    /** Remove all of a thread's context from CPU */
3267590Sgblack@eecs.umich.edu    void removeThread(unsigned tid);
3277128Sgblack@eecs.umich.edu
3287292Sgblack@eecs.umich.edu    /** Count the Total Instructions Committed in the CPU. */
3297590Sgblack@eecs.umich.edu    virtual Counter totalInstructions() const
3307590Sgblack@eecs.umich.edu    {
3317590Sgblack@eecs.umich.edu        Counter total(0);
3327590Sgblack@eecs.umich.edu
3337590Sgblack@eecs.umich.edu        for (int i=0; i < thread.size(); i++)
3347590Sgblack@eecs.umich.edu            total += thread[i]->numInst;
3357590Sgblack@eecs.umich.edu
3367590Sgblack@eecs.umich.edu        return total;
3377292Sgblack@eecs.umich.edu    }
3387725SAli.Saidi@ARM.com
3397725SAli.Saidi@ARM.com    /** Add Thread to Active Threads List. */
3407725SAli.Saidi@ARM.com    void activateContext(int tid, int delay);
3417725SAli.Saidi@ARM.com
3427725SAli.Saidi@ARM.com    /** Remove Thread from Active Threads List */
3437192Sgblack@eecs.umich.edu    void suspendContext(int tid);
3447119Sgblack@eecs.umich.edu
3457119Sgblack@eecs.umich.edu    /** Remove Thread from Active Threads List &&
3467119Sgblack@eecs.umich.edu     *  Possibly Remove Thread Context from CPU.
3477119Sgblack@eecs.umich.edu     */
3487119Sgblack@eecs.umich.edu    bool deallocateContext(int tid, bool remove, int delay = 1);
3497119Sgblack@eecs.umich.edu
3507119Sgblack@eecs.umich.edu    /** Remove Thread from Active Threads List &&
3517119Sgblack@eecs.umich.edu     *  Remove Thread Context from CPU.
3527119Sgblack@eecs.umich.edu     */
3537119Sgblack@eecs.umich.edu    void haltContext(int tid);
3547128Sgblack@eecs.umich.edu
3557128Sgblack@eecs.umich.edu    /** Activate a Thread When CPU Resources are Available. */
3567192Sgblack@eecs.umich.edu    void activateWhenReady(int tid);
3577292Sgblack@eecs.umich.edu
3587292Sgblack@eecs.umich.edu    /** Add or Remove a Thread Context in the CPU. */
3597725SAli.Saidi@ARM.com    void doContextSwitch();
3607725SAli.Saidi@ARM.com
3617725SAli.Saidi@ARM.com    /** Update The Order In Which We Process Threads. */
3627244Sgblack@eecs.umich.edu    void updateThreadPriority();
3637590Sgblack@eecs.umich.edu
3647590Sgblack@eecs.umich.edu    /** Serialize state. */
3657590Sgblack@eecs.umich.edu    virtual void serialize(std::ostream &os);
3667590Sgblack@eecs.umich.edu
3677336Sgblack@eecs.umich.edu    /** Unserialize from a checkpoint. */
3687590Sgblack@eecs.umich.edu    virtual void unserialize(Checkpoint *cp, const std::string &section);
3697590Sgblack@eecs.umich.edu
3707590Sgblack@eecs.umich.edu  public:
3717590Sgblack@eecs.umich.edu    /** Executes a syscall on this cycle.
3727119Sgblack@eecs.umich.edu     *  ---------------------------------------
373     *  Note: this is a virtual function. CPU-Specific
374     *  functionality defined in derived classes
375     */
376    virtual void syscall(int tid) { panic("Unimplemented!"); }
377
378    /** Starts draining the CPU's pipeline of all instructions in
379     * order to stop all memory accesses. */
380    virtual unsigned int drain(Event *drain_event);
381
382    /** Resumes execution after a drain. */
383    virtual void resume();
384
385    /** Signals to this CPU that a stage has completed switching out. */
386    void signalDrained();
387
388    /** Switches out this CPU. */
389    virtual void switchOut();
390
391    /** Takes over from another CPU. */
392    virtual void takeOverFrom(BaseCPU *oldCPU);
393
394    /** Get the current instruction sequence number, and increment it. */
395    InstSeqNum getAndIncrementInstSeq()
396    { return globalSeqNum++; }
397
398#if FULL_SYSTEM
399    /** Update the Virt and Phys ports of all ThreadContexts to
400     * reflect change in memory connections. */
401    void updateMemPorts();
402
403    /** Check if this address is a valid instruction address. */
404    bool validInstAddr(Addr addr) { return true; }
405
406    /** Check if this address is a valid data address. */
407    bool validDataAddr(Addr addr) { return true; }
408
409    /** Get instruction asid. */
410    int getInstAsid(unsigned tid)
411    { return regFile.miscRegs[tid].getInstAsid(); }
412
413    /** Get data asid. */
414    int getDataAsid(unsigned tid)
415    { return regFile.miscRegs[tid].getDataAsid(); }
416#else
417    /** Get instruction asid. */
418    int getInstAsid(unsigned tid)
419    { return thread[tid]->getInstAsid(); }
420
421    /** Get data asid. */
422    int getDataAsid(unsigned tid)
423    { return thread[tid]->getDataAsid(); }
424
425#endif
426
427    /** Register accessors.  Index refers to the physical register index. */
428    uint64_t readIntReg(int reg_idx);
429
430    TheISA::FloatReg readFloatReg(int reg_idx);
431
432    TheISA::FloatReg readFloatReg(int reg_idx, int width);
433
434    TheISA::FloatRegBits readFloatRegBits(int reg_idx);
435
436    TheISA::FloatRegBits readFloatRegBits(int reg_idx, int width);
437
438    void setIntReg(int reg_idx, uint64_t val);
439
440    void setFloatReg(int reg_idx, TheISA::FloatReg val);
441
442    void setFloatReg(int reg_idx, TheISA::FloatReg val, int width);
443
444    void setFloatRegBits(int reg_idx, TheISA::FloatRegBits val);
445
446    void setFloatRegBits(int reg_idx, TheISA::FloatRegBits val, int width);
447
448    uint64_t readArchIntReg(int reg_idx, unsigned tid);
449
450    float readArchFloatRegSingle(int reg_idx, unsigned tid);
451
452    double readArchFloatRegDouble(int reg_idx, unsigned tid);
453
454    uint64_t readArchFloatRegInt(int reg_idx, unsigned tid);
455
456    /** Architectural register accessors.  Looks up in the commit
457     * rename table to obtain the true physical index of the
458     * architected register first, then accesses that physical
459     * register.
460     */
461    void setArchIntReg(int reg_idx, uint64_t val, unsigned tid);
462
463    void setArchFloatRegSingle(int reg_idx, float val, unsigned tid);
464
465    void setArchFloatRegDouble(int reg_idx, double val, unsigned tid);
466
467    void setArchFloatRegInt(int reg_idx, uint64_t val, unsigned tid);
468
469    /** Reads the commit PC of a specific thread. */
470    Addr readPC(unsigned tid);
471
472    /** Sets the commit PC of a specific thread. */
473    void setPC(Addr new_PC, unsigned tid);
474
475    /** Reads the commit micro PC of a specific thread. */
476    Addr readMicroPC(unsigned tid);
477
478    /** Sets the commmit micro PC of a specific thread. */
479    void setMicroPC(Addr new_microPC, unsigned tid);
480
481    /** Reads the next PC of a specific thread. */
482    Addr readNextPC(unsigned tid);
483
484    /** Sets the next PC of a specific thread. */
485    void setNextPC(Addr val, unsigned tid);
486
487    /** Reads the next NPC of a specific thread. */
488    Addr readNextNPC(unsigned tid);
489
490    /** Sets the next NPC of a specific thread. */
491    void setNextNPC(Addr val, unsigned tid);
492
493    /** Reads the commit next micro PC of a specific thread. */
494    Addr readNextMicroPC(unsigned tid);
495
496    /** Sets the commit next micro PC of a specific thread. */
497    void setNextMicroPC(Addr val, unsigned tid);
498
499    /** Function to add instruction onto the head of the list of the
500     *  instructions.  Used when new instructions are fetched.
501     */
502    ListIt addInst(DynInstPtr &inst);
503
504    /** Function to tell the CPU that an instruction has completed. */
505    void instDone(unsigned tid);
506
507    /** Add Instructions to the CPU Remove List*/
508    void addToRemoveList(DynInstPtr &inst);
509
510    /** Remove an instruction from the front end of the list.  There's
511     *  no restriction on location of the instruction.
512     */
513    void removeFrontInst(DynInstPtr &inst);
514
515    /** Remove all instructions that are not currently in the ROB.
516     *  There's also an option to not squash delay slot instructions.*/
517    void removeInstsNotInROB(unsigned tid);
518
519    /** Remove all instructions younger than the given sequence number. */
520    void removeInstsUntil(const InstSeqNum &seq_num,unsigned tid);
521
522    /** Removes the instruction pointed to by the iterator. */
523    inline void squashInstIt(const ListIt &instIt, const unsigned &tid);
524
525    /** Cleans up all instructions on the remove list. */
526    void cleanUpRemovedInsts();
527
528    /** Debug function to print all instructions on the list. */
529    void dumpInsts();
530
531  public:
532    /** List of all the instructions in flight. */
533    std::list<DynInstPtr> instList;
534
535    /** List of all the instructions that will be removed at the end of this
536     *  cycle.
537     */
538    std::queue<ListIt> removeList;
539
540#ifdef DEBUG
541    /** Debug structure to keep track of the sequence numbers still in
542     * flight.
543     */
544    std::set<InstSeqNum> snList;
545#endif
546
547    /** Records if instructions need to be removed this cycle due to
548     *  being retired or squashed.
549     */
550    bool removeInstsThisCycle;
551
552  protected:
553    /** The fetch stage. */
554    typename CPUPolicy::Fetch fetch;
555
556    /** The decode stage. */
557    typename CPUPolicy::Decode decode;
558
559    /** The dispatch stage. */
560    typename CPUPolicy::Rename rename;
561
562    /** The issue/execute/writeback stages. */
563    typename CPUPolicy::IEW iew;
564
565    /** The commit stage. */
566    typename CPUPolicy::Commit commit;
567
568    /** The register file. */
569    typename CPUPolicy::RegFile regFile;
570
571    /** The free list. */
572    typename CPUPolicy::FreeList freeList;
573
574    /** The rename map. */
575    typename CPUPolicy::RenameMap renameMap[Impl::MaxThreads];
576
577    /** The commit rename map. */
578    typename CPUPolicy::RenameMap commitRenameMap[Impl::MaxThreads];
579
580    /** The re-order buffer. */
581    typename CPUPolicy::ROB rob;
582
583    /** Active Threads List */
584    std::list<unsigned> activeThreads;
585
586    /** Integer Register Scoreboard */
587    Scoreboard scoreboard;
588
589  public:
590    /** Enum to give each stage a specific index, so when calling
591     *  activateStage() or deactivateStage(), they can specify which stage
592     *  is being activated/deactivated.
593     */
594    enum StageIdx {
595        FetchIdx,
596        DecodeIdx,
597        RenameIdx,
598        IEWIdx,
599        CommitIdx,
600        NumStages };
601
602    /** Typedefs from the Impl to get the structs that each of the
603     *  time buffers should use.
604     */
605    typedef typename CPUPolicy::TimeStruct TimeStruct;
606
607    typedef typename CPUPolicy::FetchStruct FetchStruct;
608
609    typedef typename CPUPolicy::DecodeStruct DecodeStruct;
610
611    typedef typename CPUPolicy::RenameStruct RenameStruct;
612
613    typedef typename CPUPolicy::IEWStruct IEWStruct;
614
615    /** The main time buffer to do backwards communication. */
616    TimeBuffer<TimeStruct> timeBuffer;
617
618    /** The fetch stage's instruction queue. */
619    TimeBuffer<FetchStruct> fetchQueue;
620
621    /** The decode stage's instruction queue. */
622    TimeBuffer<DecodeStruct> decodeQueue;
623
624    /** The rename stage's instruction queue. */
625    TimeBuffer<RenameStruct> renameQueue;
626
627    /** The IEW stage's instruction queue. */
628    TimeBuffer<IEWStruct> iewQueue;
629
630  private:
631    /** The activity recorder; used to tell if the CPU has any
632     * activity remaining or if it can go to idle and deschedule
633     * itself.
634     */
635    ActivityRecorder activityRec;
636
637  public:
638    /** Records that there was time buffer activity this cycle. */
639    void activityThisCycle() { activityRec.activity(); }
640
641    /** Changes a stage's status to active within the activity recorder. */
642    void activateStage(const StageIdx idx)
643    { activityRec.activateStage(idx); }
644
645    /** Changes a stage's status to inactive within the activity recorder. */
646    void deactivateStage(const StageIdx idx)
647    { activityRec.deactivateStage(idx); }
648
649    /** Wakes the CPU, rescheduling the CPU if it's not already active. */
650    void wakeCPU();
651
652    /** Gets a free thread id. Use if thread ids change across system. */
653    int getFreeTid();
654
655  public:
656    /** Returns a pointer to a thread context. */
657    ThreadContext *tcBase(unsigned tid)
658    {
659        return thread[tid]->getTC();
660    }
661
662    /** The global sequence number counter. */
663    InstSeqNum globalSeqNum;//[Impl::MaxThreads];
664
665#if USE_CHECKER
666    /** Pointer to the checker, which can dynamically verify
667     * instruction results at run time.  This can be set to NULL if it
668     * is not being used.
669     */
670    Checker<DynInstPtr> *checker;
671#endif
672
673#if FULL_SYSTEM
674    /** Pointer to the system. */
675    System *system;
676
677    /** Pointer to physical memory. */
678    PhysicalMemory *physmem;
679#endif
680
681    /** Event to call process() on once draining has completed. */
682    Event *drainEvent;
683
684    /** Counter of how many stages have completed draining. */
685    int drainCount;
686
687    /** Pointers to all of the threads in the CPU. */
688    std::vector<Thread *> thread;
689
690    /** Whether or not the CPU should defer its registration. */
691    bool deferRegistration;
692
693    /** Is there a context switch pending? */
694    bool contextSwitch;
695
696    /** Threads Scheduled to Enter CPU */
697    std::list<int> cpuWaitList;
698
699    /** The cycle that the CPU was last running, used for statistics. */
700    Tick lastRunningCycle;
701
702    /** The cycle that the CPU was last activated by a new thread*/
703    Tick lastActivatedCycle;
704
705    /** Number of Threads CPU can process */
706    unsigned numThreads;
707
708    /** Mapping for system thread id to cpu id */
709    std::map<unsigned,unsigned> threadMap;
710
711    /** Available thread ids in the cpu*/
712    std::vector<unsigned> tids;
713
714    /** Stat for total number of times the CPU is descheduled. */
715    Stats::Scalar<> timesIdled;
716    /** Stat for total number of cycles the CPU spends descheduled. */
717    Stats::Scalar<> idleCycles;
718    /** Stat for the number of committed instructions per thread. */
719    Stats::Vector<> committedInsts;
720    /** Stat for the total number of committed instructions. */
721    Stats::Scalar<> totalCommittedInsts;
722    /** Stat for the CPI per thread. */
723    Stats::Formula cpi;
724    /** Stat for the total CPI. */
725    Stats::Formula totalCpi;
726    /** Stat for the IPC per thread. */
727    Stats::Formula ipc;
728    /** Stat for the total IPC. */
729    Stats::Formula totalIpc;
730};
731
732#endif // __CPU_O3_CPU_HH__
733