timing.hh revision 10379
110259SAndrew.Bardsley@arm.com/*
213954Sgiacomo.gabrielli@arm.com * Copyright (c) 2012-2013 ARM Limited
310259SAndrew.Bardsley@arm.com * All rights reserved
410259SAndrew.Bardsley@arm.com *
510259SAndrew.Bardsley@arm.com * The license below extends only to copyright in the software and shall
610259SAndrew.Bardsley@arm.com * not be construed as granting a license to any other intellectual
710259SAndrew.Bardsley@arm.com * property including but not limited to intellectual property relating
810259SAndrew.Bardsley@arm.com * to a hardware implementation of the functionality of the software
910259SAndrew.Bardsley@arm.com * licensed hereunder.  You may use the software subject to the license
1010259SAndrew.Bardsley@arm.com * terms below provided that you ensure that this notice is replicated
1110259SAndrew.Bardsley@arm.com * unmodified and in its entirety in all distributions of the software,
1210259SAndrew.Bardsley@arm.com * modified or unmodified, in source code or in binary form.
1310259SAndrew.Bardsley@arm.com *
1410259SAndrew.Bardsley@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
1510259SAndrew.Bardsley@arm.com * All rights reserved.
1610259SAndrew.Bardsley@arm.com *
1710259SAndrew.Bardsley@arm.com * Redistribution and use in source and binary forms, with or without
1810259SAndrew.Bardsley@arm.com * modification, are permitted provided that the following conditions are
1910259SAndrew.Bardsley@arm.com * met: redistributions of source code must retain the above copyright
2010259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer;
2110259SAndrew.Bardsley@arm.com * redistributions in binary form must reproduce the above copyright
2210259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer in the
2310259SAndrew.Bardsley@arm.com * documentation and/or other materials provided with the distribution;
2410259SAndrew.Bardsley@arm.com * neither the name of the copyright holders nor the names of its
2510259SAndrew.Bardsley@arm.com * contributors may be used to endorse or promote products derived from
2610259SAndrew.Bardsley@arm.com * this software without specific prior written permission.
2710259SAndrew.Bardsley@arm.com *
2810259SAndrew.Bardsley@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2910259SAndrew.Bardsley@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3010259SAndrew.Bardsley@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3110259SAndrew.Bardsley@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3210259SAndrew.Bardsley@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3310259SAndrew.Bardsley@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3410259SAndrew.Bardsley@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3510259SAndrew.Bardsley@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3610259SAndrew.Bardsley@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3710259SAndrew.Bardsley@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3810259SAndrew.Bardsley@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3910259SAndrew.Bardsley@arm.com *
4011793Sbrandon.potter@amd.com * Authors: Steve Reinhardt
4111793Sbrandon.potter@amd.com */
4210259SAndrew.Bardsley@arm.com
4310259SAndrew.Bardsley@arm.com#ifndef __CPU_SIMPLE_TIMING_HH__
4410259SAndrew.Bardsley@arm.com#define __CPU_SIMPLE_TIMING_HH__
4510259SAndrew.Bardsley@arm.com
4610259SAndrew.Bardsley@arm.com#include "cpu/simple/base.hh"
4710259SAndrew.Bardsley@arm.com#include "cpu/translation.hh"
4810259SAndrew.Bardsley@arm.com#include "params/TimingSimpleCPU.hh"
4910259SAndrew.Bardsley@arm.com
5010259SAndrew.Bardsley@arm.comclass TimingSimpleCPU : public BaseSimpleCPU
5110259SAndrew.Bardsley@arm.com{
5210259SAndrew.Bardsley@arm.com  public:
5310259SAndrew.Bardsley@arm.com
5410259SAndrew.Bardsley@arm.com    TimingSimpleCPU(TimingSimpleCPUParams * params);
5510259SAndrew.Bardsley@arm.com    virtual ~TimingSimpleCPU();
5610259SAndrew.Bardsley@arm.com
5710259SAndrew.Bardsley@arm.com    virtual void init();
5810259SAndrew.Bardsley@arm.com
5910259SAndrew.Bardsley@arm.com  private:
6010259SAndrew.Bardsley@arm.com
6110259SAndrew.Bardsley@arm.com    /*
6210259SAndrew.Bardsley@arm.com     * If an access needs to be broken into fragments, currently at most two,
6310259SAndrew.Bardsley@arm.com     * the the following two classes are used as the sender state of the
6410259SAndrew.Bardsley@arm.com     * packets so the CPU can keep track of everything. In the main packet
6510259SAndrew.Bardsley@arm.com     * sender state, there's an array with a spot for each fragment. If a
6610259SAndrew.Bardsley@arm.com     * fragment has already been accepted by the CPU, aka isn't waiting for
6710259SAndrew.Bardsley@arm.com     * a retry, it's pointer is NULL. After each fragment has successfully
6810259SAndrew.Bardsley@arm.com     * been processed, the "outstanding" counter is decremented. Once the
6910259SAndrew.Bardsley@arm.com     * count is zero, the entire larger access is complete.
7010259SAndrew.Bardsley@arm.com     */
7110259SAndrew.Bardsley@arm.com    class SplitMainSenderState : public Packet::SenderState
7210259SAndrew.Bardsley@arm.com    {
7310259SAndrew.Bardsley@arm.com      public:
7410259SAndrew.Bardsley@arm.com        int outstanding;
7510259SAndrew.Bardsley@arm.com        PacketPtr fragments[2];
7610259SAndrew.Bardsley@arm.com
7710259SAndrew.Bardsley@arm.com        int
7810259SAndrew.Bardsley@arm.com        getPendingFragment()
7910259SAndrew.Bardsley@arm.com        {
8010259SAndrew.Bardsley@arm.com            if (fragments[0]) {
8110259SAndrew.Bardsley@arm.com                return 0;
8210259SAndrew.Bardsley@arm.com            } else if (fragments[1]) {
8310259SAndrew.Bardsley@arm.com                return 1;
8410259SAndrew.Bardsley@arm.com            } else {
8510259SAndrew.Bardsley@arm.com                return -1;
8610259SAndrew.Bardsley@arm.com            }
8710259SAndrew.Bardsley@arm.com        }
8810259SAndrew.Bardsley@arm.com    };
8910259SAndrew.Bardsley@arm.com
9011567Smitch.hayenga@arm.com    class SplitFragmentSenderState : public Packet::SenderState
9111567Smitch.hayenga@arm.com    {
9211567Smitch.hayenga@arm.com      public:
9311567Smitch.hayenga@arm.com        SplitFragmentSenderState(PacketPtr _bigPkt, int _index) :
9410259SAndrew.Bardsley@arm.com            bigPkt(_bigPkt), index(_index)
9510259SAndrew.Bardsley@arm.com        {}
9610259SAndrew.Bardsley@arm.com        PacketPtr bigPkt;
9710259SAndrew.Bardsley@arm.com        int index;
9810259SAndrew.Bardsley@arm.com
9910259SAndrew.Bardsley@arm.com        void
10010259SAndrew.Bardsley@arm.com        clearFromParent()
10110259SAndrew.Bardsley@arm.com        {
10210259SAndrew.Bardsley@arm.com            SplitMainSenderState * main_send_state =
10310259SAndrew.Bardsley@arm.com                dynamic_cast<SplitMainSenderState *>(bigPkt->senderState);
10410259SAndrew.Bardsley@arm.com            main_send_state->fragments[index] = NULL;
10510259SAndrew.Bardsley@arm.com        }
10610259SAndrew.Bardsley@arm.com    };
10710259SAndrew.Bardsley@arm.com
10810259SAndrew.Bardsley@arm.com    class FetchTranslation : public BaseTLB::Translation
10910259SAndrew.Bardsley@arm.com    {
11010259SAndrew.Bardsley@arm.com      protected:
11110259SAndrew.Bardsley@arm.com        TimingSimpleCPU *cpu;
11210259SAndrew.Bardsley@arm.com
11310259SAndrew.Bardsley@arm.com      public:
11410259SAndrew.Bardsley@arm.com        FetchTranslation(TimingSimpleCPU *_cpu)
11510259SAndrew.Bardsley@arm.com            : cpu(_cpu)
11610259SAndrew.Bardsley@arm.com        {}
11710259SAndrew.Bardsley@arm.com
11810259SAndrew.Bardsley@arm.com        void
11910259SAndrew.Bardsley@arm.com        markDelayed()
12010259SAndrew.Bardsley@arm.com        {
12110259SAndrew.Bardsley@arm.com            assert(cpu->_status == BaseSimpleCPU::Running);
12210259SAndrew.Bardsley@arm.com            cpu->_status = ITBWaitResponse;
12310259SAndrew.Bardsley@arm.com        }
12410259SAndrew.Bardsley@arm.com
12510259SAndrew.Bardsley@arm.com        void
12610259SAndrew.Bardsley@arm.com        finish(const Fault &fault, RequestPtr req, ThreadContext *tc,
12710259SAndrew.Bardsley@arm.com               BaseTLB::Mode mode)
12810259SAndrew.Bardsley@arm.com        {
12910259SAndrew.Bardsley@arm.com            cpu->sendFetch(fault, req, tc);
13010259SAndrew.Bardsley@arm.com        }
13110259SAndrew.Bardsley@arm.com    };
13210259SAndrew.Bardsley@arm.com    FetchTranslation fetchTranslation;
13310259SAndrew.Bardsley@arm.com
13410259SAndrew.Bardsley@arm.com    void sendData(RequestPtr req, uint8_t *data, uint64_t *res, bool read);
13510259SAndrew.Bardsley@arm.com    void sendSplitData(RequestPtr req1, RequestPtr req2, RequestPtr req,
13610259SAndrew.Bardsley@arm.com                       uint8_t *data, bool read);
13710259SAndrew.Bardsley@arm.com
13810259SAndrew.Bardsley@arm.com    void translationFault(const Fault &fault);
13910259SAndrew.Bardsley@arm.com
14010259SAndrew.Bardsley@arm.com    void buildPacket(PacketPtr &pkt, RequestPtr req, bool read);
14110259SAndrew.Bardsley@arm.com    void buildSplitPacket(PacketPtr &pkt1, PacketPtr &pkt2,
14210259SAndrew.Bardsley@arm.com            RequestPtr req1, RequestPtr req2, RequestPtr req,
14310259SAndrew.Bardsley@arm.com            uint8_t *data, bool read);
14410259SAndrew.Bardsley@arm.com
14510259SAndrew.Bardsley@arm.com    bool handleReadPacket(PacketPtr pkt);
14610259SAndrew.Bardsley@arm.com    // This function always implicitly uses dcache_pkt.
14710259SAndrew.Bardsley@arm.com    bool handleWritePacket();
14810259SAndrew.Bardsley@arm.com
14910814Sandreas.hansson@arm.com    /**
15010259SAndrew.Bardsley@arm.com     * A TimingCPUPort overrides the default behaviour of the
15110259SAndrew.Bardsley@arm.com     * recvTiming and recvRetry and implements events for the
15210259SAndrew.Bardsley@arm.com     * scheduling of handling of incoming packets in the following
15310259SAndrew.Bardsley@arm.com     * cycle.
15410259SAndrew.Bardsley@arm.com     */
15510259SAndrew.Bardsley@arm.com    class TimingCPUPort : public MasterPort
15610259SAndrew.Bardsley@arm.com    {
15710259SAndrew.Bardsley@arm.com      public:
15810259SAndrew.Bardsley@arm.com
15910259SAndrew.Bardsley@arm.com        TimingCPUPort(const std::string& _name, TimingSimpleCPU* _cpu)
16010259SAndrew.Bardsley@arm.com            : MasterPort(_name, _cpu), cpu(_cpu), retryEvent(this)
16110259SAndrew.Bardsley@arm.com        { }
16210259SAndrew.Bardsley@arm.com
16310259SAndrew.Bardsley@arm.com      protected:
16410259SAndrew.Bardsley@arm.com
16510259SAndrew.Bardsley@arm.com        /**
16610259SAndrew.Bardsley@arm.com         * Snooping a coherence request, do nothing.
16710259SAndrew.Bardsley@arm.com         */
16810259SAndrew.Bardsley@arm.com        virtual void recvTimingSnoopReq(PacketPtr pkt) {}
16911567Smitch.hayenga@arm.com
17011567Smitch.hayenga@arm.com        TimingSimpleCPU* cpu;
17111567Smitch.hayenga@arm.com
17210259SAndrew.Bardsley@arm.com        struct TickEvent : public Event
17311567Smitch.hayenga@arm.com        {
17411567Smitch.hayenga@arm.com            PacketPtr pkt;
17511567Smitch.hayenga@arm.com            TimingSimpleCPU *cpu;
17611567Smitch.hayenga@arm.com
17711567Smitch.hayenga@arm.com            TickEvent(TimingSimpleCPU *_cpu) : pkt(NULL), cpu(_cpu) {}
17811567Smitch.hayenga@arm.com            const char *description() const { return "Timing CPU tick"; }
17911567Smitch.hayenga@arm.com            void schedule(PacketPtr _pkt, Tick t);
18011567Smitch.hayenga@arm.com        };
18111567Smitch.hayenga@arm.com
18211567Smitch.hayenga@arm.com        EventWrapper<MasterPort, &MasterPort::sendRetry> retryEvent;
18311567Smitch.hayenga@arm.com    };
18411567Smitch.hayenga@arm.com
18511567Smitch.hayenga@arm.com    class IcachePort : public TimingCPUPort
18611567Smitch.hayenga@arm.com    {
18711567Smitch.hayenga@arm.com      public:
18811567Smitch.hayenga@arm.com
18911567Smitch.hayenga@arm.com        IcachePort(TimingSimpleCPU *_cpu)
19011567Smitch.hayenga@arm.com            : TimingCPUPort(_cpu->name() + ".icache_port", _cpu),
19110259SAndrew.Bardsley@arm.com              tickEvent(_cpu)
19210259SAndrew.Bardsley@arm.com        { }
19310259SAndrew.Bardsley@arm.com
19411567Smitch.hayenga@arm.com      protected:
19510259SAndrew.Bardsley@arm.com
19610259SAndrew.Bardsley@arm.com        virtual bool recvTimingResp(PacketPtr pkt);
19711567Smitch.hayenga@arm.com
19811567Smitch.hayenga@arm.com        virtual void recvRetry();
19910259SAndrew.Bardsley@arm.com
20011567Smitch.hayenga@arm.com        struct ITickEvent : public TickEvent
20110259SAndrew.Bardsley@arm.com        {
20210259SAndrew.Bardsley@arm.com
20310259SAndrew.Bardsley@arm.com            ITickEvent(TimingSimpleCPU *_cpu)
20410259SAndrew.Bardsley@arm.com                : TickEvent(_cpu) {}
20510259SAndrew.Bardsley@arm.com            void process();
20610259SAndrew.Bardsley@arm.com            const char *description() const { return "Timing CPU icache tick"; }
20711567Smitch.hayenga@arm.com        };
20810259SAndrew.Bardsley@arm.com
20911567Smitch.hayenga@arm.com        ITickEvent tickEvent;
21011567Smitch.hayenga@arm.com
21110259SAndrew.Bardsley@arm.com    };
21211567Smitch.hayenga@arm.com
21310259SAndrew.Bardsley@arm.com    class DcachePort : public TimingCPUPort
21410259SAndrew.Bardsley@arm.com    {
21510259SAndrew.Bardsley@arm.com      public:
21610259SAndrew.Bardsley@arm.com
21710259SAndrew.Bardsley@arm.com        DcachePort(TimingSimpleCPU *_cpu)
21810259SAndrew.Bardsley@arm.com            : TimingCPUPort(_cpu->name() + ".dcache_port", _cpu),
21910259SAndrew.Bardsley@arm.com              tickEvent(_cpu)
22010259SAndrew.Bardsley@arm.com        {
22110259SAndrew.Bardsley@arm.com           cacheBlockMask = ~(cpu->cacheLineSize() - 1);
22212489Sgiacomo.travaglini@arm.com        }
22312489Sgiacomo.travaglini@arm.com
22410259SAndrew.Bardsley@arm.com        Addr cacheBlockMask;
22510259SAndrew.Bardsley@arm.com      protected:
22610259SAndrew.Bardsley@arm.com
22710259SAndrew.Bardsley@arm.com        /** Snoop a coherence request, we need to check if this causes
22812489Sgiacomo.travaglini@arm.com         * a wakeup event on a cpu that is monitoring an address
22912489Sgiacomo.travaglini@arm.com         */
23010259SAndrew.Bardsley@arm.com        virtual void recvTimingSnoopReq(PacketPtr pkt);
23110259SAndrew.Bardsley@arm.com
23210259SAndrew.Bardsley@arm.com        virtual bool recvTimingResp(PacketPtr pkt);
23310259SAndrew.Bardsley@arm.com
23410259SAndrew.Bardsley@arm.com        virtual void recvRetry();
23510259SAndrew.Bardsley@arm.com
23610259SAndrew.Bardsley@arm.com        struct DTickEvent : public TickEvent
23710259SAndrew.Bardsley@arm.com        {
23810259SAndrew.Bardsley@arm.com            DTickEvent(TimingSimpleCPU *_cpu)
23910259SAndrew.Bardsley@arm.com                : TickEvent(_cpu) {}
24010259SAndrew.Bardsley@arm.com            void process();
24110259SAndrew.Bardsley@arm.com            const char *description() const { return "Timing CPU dcache tick"; }
24210259SAndrew.Bardsley@arm.com        };
24310259SAndrew.Bardsley@arm.com
24410259SAndrew.Bardsley@arm.com        DTickEvent tickEvent;
24510259SAndrew.Bardsley@arm.com
24610259SAndrew.Bardsley@arm.com    };
24710259SAndrew.Bardsley@arm.com
24810259SAndrew.Bardsley@arm.com    IcachePort icachePort;
24910259SAndrew.Bardsley@arm.com    DcachePort dcachePort;
25010259SAndrew.Bardsley@arm.com
25113647Sqtt2@cornell.edu    PacketPtr ifetch_pkt;
25213647Sqtt2@cornell.edu    PacketPtr dcache_pkt;
25313647Sqtt2@cornell.edu
25413647Sqtt2@cornell.edu    Tick previousCycle;
25513647Sqtt2@cornell.edu
25613647Sqtt2@cornell.edu  protected:
25713647Sqtt2@cornell.edu
25813647Sqtt2@cornell.edu     /** Return a reference to the data port. */
25910259SAndrew.Bardsley@arm.com    virtual MasterPort &getDataPort() { return dcachePort; }
26010259SAndrew.Bardsley@arm.com
26110259SAndrew.Bardsley@arm.com    /** Return a reference to the instruction port. */
26210259SAndrew.Bardsley@arm.com    virtual MasterPort &getInstPort() { return icachePort; }
26310259SAndrew.Bardsley@arm.com
26410259SAndrew.Bardsley@arm.com  public:
26510259SAndrew.Bardsley@arm.com
26610259SAndrew.Bardsley@arm.com    unsigned int drain(DrainManager *drain_manager);
26710259SAndrew.Bardsley@arm.com    void drainResume();
26810259SAndrew.Bardsley@arm.com
26910259SAndrew.Bardsley@arm.com    void switchOut();
27010259SAndrew.Bardsley@arm.com    void takeOverFrom(BaseCPU *oldCPU);
27110259SAndrew.Bardsley@arm.com
27210259SAndrew.Bardsley@arm.com    void verifyMemoryMode() const;
27310259SAndrew.Bardsley@arm.com
27410259SAndrew.Bardsley@arm.com    virtual void activateContext(ThreadID thread_num, Cycles delay);
27510259SAndrew.Bardsley@arm.com    virtual void suspendContext(ThreadID thread_num);
27610259SAndrew.Bardsley@arm.com
27710259SAndrew.Bardsley@arm.com    Fault readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags);
27810259SAndrew.Bardsley@arm.com
27910259SAndrew.Bardsley@arm.com    Fault writeMem(uint8_t *data, unsigned size,
28010259SAndrew.Bardsley@arm.com                   Addr addr, unsigned flags, uint64_t *res);
28110366Sandreas.hansson@arm.com
28210366Sandreas.hansson@arm.com    void fetch();
28310366Sandreas.hansson@arm.com    void sendFetch(const Fault &fault, RequestPtr req, ThreadContext *tc);
28410259SAndrew.Bardsley@arm.com    void completeIfetch(PacketPtr );
28510259SAndrew.Bardsley@arm.com    void completeDataAccess(PacketPtr pkt);
28610259SAndrew.Bardsley@arm.com    void advanceInst(const Fault &fault);
28710259SAndrew.Bardsley@arm.com
28810259SAndrew.Bardsley@arm.com    /** This function is used by the page table walker to determine if it could
28910259SAndrew.Bardsley@arm.com     * translate the a pending request or if the underlying request has been
29010259SAndrew.Bardsley@arm.com     * squashed. This always returns false for the simple timing CPU as it never
29110259SAndrew.Bardsley@arm.com     * executes any instructions speculatively.
29210259SAndrew.Bardsley@arm.com     * @ return Is the current instruction squashed?
29310259SAndrew.Bardsley@arm.com     */
29410259SAndrew.Bardsley@arm.com    bool isSquashed() const { return false; }
29510259SAndrew.Bardsley@arm.com
29610259SAndrew.Bardsley@arm.com    /**
29710259SAndrew.Bardsley@arm.com     * Print state of address in memory system via PrintReq (for
29811567Smitch.hayenga@arm.com     * debugging).
29910259SAndrew.Bardsley@arm.com     */
30010259SAndrew.Bardsley@arm.com    void printAddr(Addr a);
30110259SAndrew.Bardsley@arm.com
30210259SAndrew.Bardsley@arm.com    /**
30311567Smitch.hayenga@arm.com     * Finish a DTB translation.
30410259SAndrew.Bardsley@arm.com     * @param state The DTB translation state.
30510259SAndrew.Bardsley@arm.com     */
30610259SAndrew.Bardsley@arm.com    void finishTranslation(WholeTranslationState *state);
30710259SAndrew.Bardsley@arm.com
30810259SAndrew.Bardsley@arm.com  private:
30910259SAndrew.Bardsley@arm.com
31010259SAndrew.Bardsley@arm.com    typedef EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch> FetchEvent;
31111567Smitch.hayenga@arm.com    FetchEvent fetchEvent;
31210259SAndrew.Bardsley@arm.com
31310259SAndrew.Bardsley@arm.com    struct IprEvent : Event {
31410259SAndrew.Bardsley@arm.com        Packet *pkt;
31511567Smitch.hayenga@arm.com        TimingSimpleCPU *cpu;
31611567Smitch.hayenga@arm.com        IprEvent(Packet *_pkt, TimingSimpleCPU *_cpu, Tick t);
31710259SAndrew.Bardsley@arm.com        virtual void process();
31810259SAndrew.Bardsley@arm.com        virtual const char *description() const;
31911567Smitch.hayenga@arm.com    };
32010259SAndrew.Bardsley@arm.com
32110259SAndrew.Bardsley@arm.com    /**
32210259SAndrew.Bardsley@arm.com     * Check if a system is in a drained state.
32310259SAndrew.Bardsley@arm.com     *
32410259SAndrew.Bardsley@arm.com     * We need to drain if:
32510259SAndrew.Bardsley@arm.com     * <ul>
32610259SAndrew.Bardsley@arm.com     * <li>We are in the middle of a microcode sequence as some CPUs
32710259SAndrew.Bardsley@arm.com     *     (e.g., HW accelerated CPUs) can't be started in the middle
32810259SAndrew.Bardsley@arm.com     *     of a gem5 microcode sequence.
32910259SAndrew.Bardsley@arm.com     *
33010259SAndrew.Bardsley@arm.com     * <li>Stay at PC is true.
33110259SAndrew.Bardsley@arm.com     *
33210259SAndrew.Bardsley@arm.com     * <li>A fetch event is scheduled. Normally this would never be the
33310259SAndrew.Bardsley@arm.com     *     case with microPC() == 0, but right after a context is
33410259SAndrew.Bardsley@arm.com     *     activated it can happen.
33510259SAndrew.Bardsley@arm.com     * </ul>
33610259SAndrew.Bardsley@arm.com     */
33710259SAndrew.Bardsley@arm.com    bool isDrained() {
33810259SAndrew.Bardsley@arm.com        return microPC() == 0 && !stayAtPC && !fetchEvent.scheduled();
33910259SAndrew.Bardsley@arm.com    }
34013652Sqtt2@cornell.edu
34110259SAndrew.Bardsley@arm.com    /**
34210259SAndrew.Bardsley@arm.com     * Try to complete a drain request.
34310259SAndrew.Bardsley@arm.com     *
34410259SAndrew.Bardsley@arm.com     * @returns true if the CPU is drained, false otherwise.
34510259SAndrew.Bardsley@arm.com     */
34610259SAndrew.Bardsley@arm.com    bool tryCompleteDrain();
34710259SAndrew.Bardsley@arm.com
34810259SAndrew.Bardsley@arm.com    /**
34910259SAndrew.Bardsley@arm.com     * Drain manager to use when signaling drain completion
35010259SAndrew.Bardsley@arm.com     *
35110259SAndrew.Bardsley@arm.com     * This pointer is non-NULL when draining and NULL otherwise.
35210259SAndrew.Bardsley@arm.com     */
35310259SAndrew.Bardsley@arm.com    DrainManager *drainManager;
35410259SAndrew.Bardsley@arm.com};
35510259SAndrew.Bardsley@arm.com
35610259SAndrew.Bardsley@arm.com#endif // __CPU_SIMPLE_TIMING_HH__
35710259SAndrew.Bardsley@arm.com