timing.hh revision 13954
17259Sgblack@eecs.umich.edu/*
212669Schuan.zhu@arm.com * Copyright (c) 2012-2013,2015,2018 ARM Limited
37259Sgblack@eecs.umich.edu * All rights reserved
47259Sgblack@eecs.umich.edu *
57259Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
67259Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
77259Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
87259Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
97259Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
107259Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
117259Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
127259Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
137259Sgblack@eecs.umich.edu *
147259Sgblack@eecs.umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan
157259Sgblack@eecs.umich.edu * All rights reserved.
167259Sgblack@eecs.umich.edu *
177259Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
187259Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
197259Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
207259Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
217259Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
227259Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
237259Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
247259Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
257259Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
267259Sgblack@eecs.umich.edu * this software without specific prior written permission.
277259Sgblack@eecs.umich.edu *
287259Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
297259Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
307259Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
317259Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
327259Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
337259Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
347259Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
357259Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
367259Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
377259Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
387405SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3910037SARM gem5 Developers *
407259Sgblack@eecs.umich.edu * Authors: Steve Reinhardt
417259Sgblack@eecs.umich.edu */
4211793Sbrandon.potter@amd.com
4311793Sbrandon.potter@amd.com#ifndef __CPU_SIMPLE_TIMING_HH__
4411939Snikos.nikoleris@arm.com#define __CPU_SIMPLE_TIMING_HH__
4511939Snikos.nikoleris@arm.com
467405SAli.Saidi@ARM.com#include "cpu/simple/base.hh"
4712334Sgabeblack@google.com#include "cpu/simple/exec_context.hh"
4810037SARM gem5 Developers#include "cpu/translation.hh"
4910828SGiacomo.Gabrielli@arm.com#include "params/TimingSimpleCPU.hh"
507259Sgblack@eecs.umich.edu
517259Sgblack@eecs.umich.educlass TimingSimpleCPU : public BaseSimpleCPU
527259Sgblack@eecs.umich.edu{
537259Sgblack@eecs.umich.edu  public:
547259Sgblack@eecs.umich.edu
558868SMatt.Horsnell@arm.com    TimingSimpleCPU(TimingSimpleCPUParams * params);
568868SMatt.Horsnell@arm.com    virtual ~TimingSimpleCPU();
578868SMatt.Horsnell@arm.com
588868SMatt.Horsnell@arm.com    void init() override;
5910037SARM gem5 Developers
608868SMatt.Horsnell@arm.com  private:
6110037SARM gem5 Developers
628868SMatt.Horsnell@arm.com    /*
6310037SARM gem5 Developers     * If an access needs to be broken into fragments, currently at most two,
6410037SARM gem5 Developers     * the the following two classes are used as the sender state of the
6510037SARM gem5 Developers     * packets so the CPU can keep track of everything. In the main packet
6610037SARM gem5 Developers     * sender state, there's an array with a spot for each fragment. If a
6710037SARM gem5 Developers     * fragment has already been accepted by the CPU, aka isn't waiting for
6810037SARM gem5 Developers     * a retry, it's pointer is NULL. After each fragment has successfully
6910037SARM gem5 Developers     * been processed, the "outstanding" counter is decremented. Once the
708868SMatt.Horsnell@arm.com     * count is zero, the entire larger access is complete.
7110037SARM gem5 Developers     */
7210037SARM gem5 Developers    class SplitMainSenderState : public Packet::SenderState
7310037SARM gem5 Developers    {
7410037SARM gem5 Developers      public:
7510037SARM gem5 Developers        int outstanding;
7610037SARM gem5 Developers        PacketPtr fragments[2];
7710037SARM gem5 Developers
7810037SARM gem5 Developers        int
7910037SARM gem5 Developers        getPendingFragment()
8010037SARM gem5 Developers        {
8110037SARM gem5 Developers            if (fragments[0]) {
829959Schander.sudanthi@arm.com                return 0;
8310037SARM gem5 Developers            } else if (fragments[1]) {
849959Schander.sudanthi@arm.com                return 1;
859959Schander.sudanthi@arm.com            } else {
869959Schander.sudanthi@arm.com                return -1;
879959Schander.sudanthi@arm.com            }
889959Schander.sudanthi@arm.com        }
899959Schander.sudanthi@arm.com    };
909959Schander.sudanthi@arm.com
919959Schander.sudanthi@arm.com    class SplitFragmentSenderState : public Packet::SenderState
929959Schander.sudanthi@arm.com    {
9310037SARM gem5 Developers      public:
949959Schander.sudanthi@arm.com        SplitFragmentSenderState(PacketPtr _bigPkt, int _index) :
9510037SARM gem5 Developers            bigPkt(_bigPkt), index(_index)
9610037SARM gem5 Developers        {}
9710037SARM gem5 Developers        PacketPtr bigPkt;
9810037SARM gem5 Developers        int index;
9910037SARM gem5 Developers
10010037SARM gem5 Developers        void
10110037SARM gem5 Developers        clearFromParent()
10210037SARM gem5 Developers        {
10310037SARM gem5 Developers            SplitMainSenderState * main_send_state =
10410037SARM gem5 Developers                dynamic_cast<SplitMainSenderState *>(bigPkt->senderState);
10510037SARM gem5 Developers            main_send_state->fragments[index] = NULL;
1068868SMatt.Horsnell@arm.com        }
10710037SARM gem5 Developers    };
10810037SARM gem5 Developers
10910037SARM gem5 Developers    class FetchTranslation : public BaseTLB::Translation
11010037SARM gem5 Developers    {
11110037SARM gem5 Developers      protected:
11210037SARM gem5 Developers        TimingSimpleCPU *cpu;
11310037SARM gem5 Developers
11410037SARM gem5 Developers      public:
11510037SARM gem5 Developers        FetchTranslation(TimingSimpleCPU *_cpu)
11610037SARM gem5 Developers            : cpu(_cpu)
11710037SARM gem5 Developers        {}
11810037SARM gem5 Developers
11910037SARM gem5 Developers        void
12010037SARM gem5 Developers        markDelayed()
12110037SARM gem5 Developers        {
1228868SMatt.Horsnell@arm.com            assert(cpu->_status == BaseSimpleCPU::Running);
12310037SARM gem5 Developers            cpu->_status = ITBWaitResponse;
12410037SARM gem5 Developers        }
12510037SARM gem5 Developers
12610037SARM gem5 Developers        void
12710037SARM gem5 Developers        finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc,
1288868SMatt.Horsnell@arm.com               BaseTLB::Mode mode)
12910037SARM gem5 Developers        {
13010037SARM gem5 Developers            cpu->sendFetch(fault, req, tc);
1318868SMatt.Horsnell@arm.com        }
1327259Sgblack@eecs.umich.edu    };
1337259Sgblack@eecs.umich.edu    FetchTranslation fetchTranslation;
1347259Sgblack@eecs.umich.edu
1357259Sgblack@eecs.umich.edu    void threadSnoop(PacketPtr pkt, ThreadID sender);
1367259Sgblack@eecs.umich.edu    void sendData(const RequestPtr &req,
1377259Sgblack@eecs.umich.edu                  uint8_t *data, uint64_t *res, bool read);
1387259Sgblack@eecs.umich.edu    void sendSplitData(const RequestPtr &req1, const RequestPtr &req2,
1397259Sgblack@eecs.umich.edu                       const RequestPtr &req,
1407259Sgblack@eecs.umich.edu                       uint8_t *data, bool read);
1417259Sgblack@eecs.umich.edu
1427259Sgblack@eecs.umich.edu    void translationFault(const Fault &fault);
1437259Sgblack@eecs.umich.edu
1447259Sgblack@eecs.umich.edu    PacketPtr buildPacket(const RequestPtr &req, bool read);
1457351Sgblack@eecs.umich.edu    void buildSplitPacket(PacketPtr &pkt1, PacketPtr &pkt2,
1467351Sgblack@eecs.umich.edu            const RequestPtr &req1, const RequestPtr &req2,
1477259Sgblack@eecs.umich.edu            const RequestPtr &req,
1487259Sgblack@eecs.umich.edu            uint8_t *data, bool read);
14910037SARM gem5 Developers
15010037SARM gem5 Developers    bool handleReadPacket(PacketPtr pkt);
1517259Sgblack@eecs.umich.edu    // This function always implicitly uses dcache_pkt.
1527259Sgblack@eecs.umich.edu    bool handleWritePacket();
1537259Sgblack@eecs.umich.edu
1547259Sgblack@eecs.umich.edu    /**
1557259Sgblack@eecs.umich.edu     * A TimingCPUPort overrides the default behaviour of the
1567259Sgblack@eecs.umich.edu     * recvTiming and recvRetry and implements events for the
1577259Sgblack@eecs.umich.edu     * scheduling of handling of incoming packets in the following
1587259Sgblack@eecs.umich.edu     * cycle.
1597259Sgblack@eecs.umich.edu     */
1607259Sgblack@eecs.umich.edu    class TimingCPUPort : public MasterPort
1617259Sgblack@eecs.umich.edu    {
1627259Sgblack@eecs.umich.edu      public:
1637259Sgblack@eecs.umich.edu
1647259Sgblack@eecs.umich.edu        TimingCPUPort(const std::string& _name, TimingSimpleCPU* _cpu)
1657259Sgblack@eecs.umich.edu            : MasterPort(_name, _cpu), cpu(_cpu),
1667259Sgblack@eecs.umich.edu              retryRespEvent([this]{ sendRetryResp(); }, name())
1677259Sgblack@eecs.umich.edu        { }
1687259Sgblack@eecs.umich.edu
1697259Sgblack@eecs.umich.edu      protected:
1707259Sgblack@eecs.umich.edu
1717259Sgblack@eecs.umich.edu        TimingSimpleCPU* cpu;
1727259Sgblack@eecs.umich.edu
1737259Sgblack@eecs.umich.edu        struct TickEvent : public Event
1747259Sgblack@eecs.umich.edu        {
1757259Sgblack@eecs.umich.edu            PacketPtr pkt;
1767259Sgblack@eecs.umich.edu            TimingSimpleCPU *cpu;
1777259Sgblack@eecs.umich.edu
1787259Sgblack@eecs.umich.edu            TickEvent(TimingSimpleCPU *_cpu) : pkt(NULL), cpu(_cpu) {}
1797259Sgblack@eecs.umich.edu            const char *description() const { return "Timing CPU tick"; }
1807259Sgblack@eecs.umich.edu            void schedule(PacketPtr _pkt, Tick t);
1817259Sgblack@eecs.umich.edu        };
1827259Sgblack@eecs.umich.edu
1837259Sgblack@eecs.umich.edu        EventFunctionWrapper retryRespEvent;
1847259Sgblack@eecs.umich.edu    };
1857259Sgblack@eecs.umich.edu
1867259Sgblack@eecs.umich.edu    class IcachePort : public TimingCPUPort
1877259Sgblack@eecs.umich.edu    {
1887259Sgblack@eecs.umich.edu      public:
1897259Sgblack@eecs.umich.edu
1907259Sgblack@eecs.umich.edu        IcachePort(TimingSimpleCPU *_cpu)
1917259Sgblack@eecs.umich.edu            : TimingCPUPort(_cpu->name() + ".icache_port", _cpu),
1927259Sgblack@eecs.umich.edu              tickEvent(_cpu)
1937259Sgblack@eecs.umich.edu        { }
1947259Sgblack@eecs.umich.edu
1957259Sgblack@eecs.umich.edu      protected:
1967259Sgblack@eecs.umich.edu
1977259Sgblack@eecs.umich.edu        virtual bool recvTimingResp(PacketPtr pkt);
1987259Sgblack@eecs.umich.edu
1997259Sgblack@eecs.umich.edu        virtual void recvReqRetry();
2007259Sgblack@eecs.umich.edu
2017259Sgblack@eecs.umich.edu        struct ITickEvent : public TickEvent
2027259Sgblack@eecs.umich.edu        {
2037259Sgblack@eecs.umich.edu
2047259Sgblack@eecs.umich.edu            ITickEvent(TimingSimpleCPU *_cpu)
2057259Sgblack@eecs.umich.edu                : TickEvent(_cpu) {}
2067259Sgblack@eecs.umich.edu            void process();
2077259Sgblack@eecs.umich.edu            const char *description() const { return "Timing CPU icache tick"; }
2087259Sgblack@eecs.umich.edu        };
2097259Sgblack@eecs.umich.edu
2107259Sgblack@eecs.umich.edu        ITickEvent tickEvent;
2117259Sgblack@eecs.umich.edu
2127259Sgblack@eecs.umich.edu    };
2137259Sgblack@eecs.umich.edu
2147259Sgblack@eecs.umich.edu    class DcachePort : public TimingCPUPort
21510037SARM gem5 Developers    {
21610037SARM gem5 Developers      public:
21710037SARM gem5 Developers
21810037SARM gem5 Developers        DcachePort(TimingSimpleCPU *_cpu)
21910037SARM gem5 Developers            : TimingCPUPort(_cpu->name() + ".dcache_port", _cpu),
22010037SARM gem5 Developers              tickEvent(_cpu)
22110037SARM gem5 Developers        {
22210037SARM gem5 Developers           cacheBlockMask = ~(cpu->cacheLineSize() - 1);
2237259Sgblack@eecs.umich.edu        }
2247259Sgblack@eecs.umich.edu
2257259Sgblack@eecs.umich.edu        Addr cacheBlockMask;
2267351Sgblack@eecs.umich.edu      protected:
2277351Sgblack@eecs.umich.edu
2287351Sgblack@eecs.umich.edu        /** Snoop a coherence request, we need to check if this causes
2297351Sgblack@eecs.umich.edu         * a wakeup event on a cpu that is monitoring an address
2307351Sgblack@eecs.umich.edu         */
2317351Sgblack@eecs.umich.edu        virtual void recvTimingSnoopReq(PacketPtr pkt);
2327351Sgblack@eecs.umich.edu        virtual void recvFunctionalSnoop(PacketPtr pkt);
2337351Sgblack@eecs.umich.edu
2347351Sgblack@eecs.umich.edu        virtual bool recvTimingResp(PacketPtr pkt);
2357351Sgblack@eecs.umich.edu
2367351Sgblack@eecs.umich.edu        virtual void recvReqRetry();
2377351Sgblack@eecs.umich.edu
2387351Sgblack@eecs.umich.edu        virtual bool isSnooping() const {
2397351Sgblack@eecs.umich.edu            return true;
2407351Sgblack@eecs.umich.edu        }
2417351Sgblack@eecs.umich.edu
2427351Sgblack@eecs.umich.edu        struct DTickEvent : public TickEvent
2437351Sgblack@eecs.umich.edu        {
2447351Sgblack@eecs.umich.edu            DTickEvent(TimingSimpleCPU *_cpu)
2457351Sgblack@eecs.umich.edu                : TickEvent(_cpu) {}
24610037SARM gem5 Developers            void process();
24710037SARM gem5 Developers            const char *description() const { return "Timing CPU dcache tick"; }
24810037SARM gem5 Developers        };
24910037SARM gem5 Developers
25010037SARM gem5 Developers        DTickEvent tickEvent;
25110037SARM gem5 Developers
25210037SARM gem5 Developers    };
25310037SARM gem5 Developers
25410037SARM gem5 Developers    void updateCycleCounts();
25510037SARM gem5 Developers
25610037SARM gem5 Developers    IcachePort icachePort;
25710037SARM gem5 Developers    DcachePort dcachePort;
25810037SARM gem5 Developers
25910037SARM gem5 Developers    PacketPtr ifetch_pkt;
26010037SARM gem5 Developers    PacketPtr dcache_pkt;
26110037SARM gem5 Developers
26210037SARM gem5 Developers    Cycles previousCycle;
26310037SARM gem5 Developers
26410037SARM gem5 Developers  protected:
26510037SARM gem5 Developers
2667351Sgblack@eecs.umich.edu     /** Return a reference to the data port. */
2677351Sgblack@eecs.umich.edu    MasterPort &getDataPort() override { return dcachePort; }
2687351Sgblack@eecs.umich.edu
2697406SAli.Saidi@ARM.com    /** Return a reference to the instruction port. */
2707259Sgblack@eecs.umich.edu    MasterPort &getInstPort() override { return icachePort; }
2717259Sgblack@eecs.umich.edu
2727351Sgblack@eecs.umich.edu  public:
2737259Sgblack@eecs.umich.edu
2747351Sgblack@eecs.umich.edu    DrainState drain() override;
2757351Sgblack@eecs.umich.edu    void drainResume() override;
2767351Sgblack@eecs.umich.edu
2777259Sgblack@eecs.umich.edu    void switchOut() override;
27810037SARM gem5 Developers    void takeOverFrom(BaseCPU *oldCPU) override;
27910037SARM gem5 Developers
28010037SARM gem5 Developers    void verifyMemoryMode() const override;
28110037SARM gem5 Developers
28210037SARM gem5 Developers    void activateContext(ThreadID thread_num) override;
2837259Sgblack@eecs.umich.edu    void suspendContext(ThreadID thread_num) override;
2847259Sgblack@eecs.umich.edu
2857351Sgblack@eecs.umich.edu    Fault initiateMemRead(Addr addr, unsigned size,
2867351Sgblack@eecs.umich.edu            Request::Flags flags,
2877351Sgblack@eecs.umich.edu            const std::vector<bool>& byteEnable =std::vector<bool>())
2887351Sgblack@eecs.umich.edu        override;
2897351Sgblack@eecs.umich.edu
2907259Sgblack@eecs.umich.edu    Fault writeMem(uint8_t *data, unsigned size,
2917259Sgblack@eecs.umich.edu                   Addr addr, Request::Flags flags, uint64_t *res,
2927259Sgblack@eecs.umich.edu                   const std::vector<bool>& byteEnable = std::vector<bool>())
2937259Sgblack@eecs.umich.edu        override;
2947259Sgblack@eecs.umich.edu
2957259Sgblack@eecs.umich.edu    Fault initiateMemAMO(Addr addr, unsigned size, Request::Flags flags,
2967259Sgblack@eecs.umich.edu                         AtomicOpFunctor *amo_op) override;
2977259Sgblack@eecs.umich.edu
2987259Sgblack@eecs.umich.edu    void fetch();
2997259Sgblack@eecs.umich.edu    void sendFetch(const Fault &fault,
3007259Sgblack@eecs.umich.edu                   const RequestPtr &req, ThreadContext *tc);
3017259Sgblack@eecs.umich.edu    void completeIfetch(PacketPtr );
3027259Sgblack@eecs.umich.edu    void completeDataAccess(PacketPtr pkt);
3037259Sgblack@eecs.umich.edu    void advanceInst(const Fault &fault);
3047259Sgblack@eecs.umich.edu
30510037SARM gem5 Developers    /** This function is used by the page table walker to determine if it could
30610037SARM gem5 Developers     * translate the a pending request or if the underlying request has been
30710037SARM gem5 Developers     * squashed. This always returns false for the simple timing CPU as it never
30810037SARM gem5 Developers     * executes any instructions speculatively.
30910037SARM gem5 Developers     * @ return Is the current instruction squashed?
31010037SARM gem5 Developers     */
31110037SARM gem5 Developers    bool isSquashed() const { return false; }
31210037SARM gem5 Developers
31310037SARM gem5 Developers    /**
3147259Sgblack@eecs.umich.edu     * Print state of address in memory system via PrintReq (for
3157259Sgblack@eecs.umich.edu     * debugging).
3167259Sgblack@eecs.umich.edu     */
3177351Sgblack@eecs.umich.edu    void printAddr(Addr a);
3187351Sgblack@eecs.umich.edu
3197259Sgblack@eecs.umich.edu    /**
3207351Sgblack@eecs.umich.edu     * Finish a DTB translation.
3217259Sgblack@eecs.umich.edu     * @param state The DTB translation state.
3227351Sgblack@eecs.umich.edu     */
3237259Sgblack@eecs.umich.edu    void finishTranslation(WholeTranslationState *state);
32410037SARM gem5 Developers
32510037SARM gem5 Developers  private:
32610037SARM gem5 Developers
32710037SARM gem5 Developers    EventFunctionWrapper fetchEvent;
32810037SARM gem5 Developers
32910037SARM gem5 Developers    struct IprEvent : Event {
33010037SARM gem5 Developers        Packet *pkt;
33110037SARM gem5 Developers        TimingSimpleCPU *cpu;
33210037SARM gem5 Developers        IprEvent(Packet *_pkt, TimingSimpleCPU *_cpu, Tick t);
3337259Sgblack@eecs.umich.edu        virtual void process();
3347259Sgblack@eecs.umich.edu        virtual const char *description() const;
3357259Sgblack@eecs.umich.edu    };
3367259Sgblack@eecs.umich.edu
3377259Sgblack@eecs.umich.edu    /**
3387259Sgblack@eecs.umich.edu     * Check if a system is in a drained state.
3397259Sgblack@eecs.umich.edu     *
3407259Sgblack@eecs.umich.edu     * We need to drain if:
3417259Sgblack@eecs.umich.edu     * <ul>
3427259Sgblack@eecs.umich.edu     * <li>We are in the middle of a microcode sequence as some CPUs
3437259Sgblack@eecs.umich.edu     *     (e.g., HW accelerated CPUs) can't be started in the middle
3447259Sgblack@eecs.umich.edu     *     of a gem5 microcode sequence.
3457259Sgblack@eecs.umich.edu     *
3467259Sgblack@eecs.umich.edu     * <li>Stay at PC is true.
3477259Sgblack@eecs.umich.edu     *
3487259Sgblack@eecs.umich.edu     * <li>A fetch event is scheduled. Normally this would never be the
3497259Sgblack@eecs.umich.edu     *     case with microPC() == 0, but right after a context is
3507259Sgblack@eecs.umich.edu     *     activated it can happen.
3517351Sgblack@eecs.umich.edu     * </ul>
3527351Sgblack@eecs.umich.edu     */
3537351Sgblack@eecs.umich.edu    bool isDrained() {
3547351Sgblack@eecs.umich.edu        SimpleExecContext& t_info = *threadInfo[curThread];
3557351Sgblack@eecs.umich.edu        SimpleThread* thread = t_info.thread;
3567259Sgblack@eecs.umich.edu
3577259Sgblack@eecs.umich.edu        return thread->microPC() == 0 && !t_info.stayAtPC &&
3587259Sgblack@eecs.umich.edu               !fetchEvent.scheduled();
3597259Sgblack@eecs.umich.edu    }
3607259Sgblack@eecs.umich.edu
3617259Sgblack@eecs.umich.edu    /**
3627259Sgblack@eecs.umich.edu     * Try to complete a drain request.
3637259Sgblack@eecs.umich.edu     *
3647259Sgblack@eecs.umich.edu     * @returns true if the CPU is drained, false otherwise.
3657259Sgblack@eecs.umich.edu     */
3667259Sgblack@eecs.umich.edu    bool tryCompleteDrain();
3677259Sgblack@eecs.umich.edu};
3687259Sgblack@eecs.umich.edu
3697259Sgblack@eecs.umich.edu#endif // __CPU_SIMPLE_TIMING_HH__
3707259Sgblack@eecs.umich.edu