mshr.hh revision 11740
16313Sgblack@eecs.umich.edu/*
26313Sgblack@eecs.umich.edu * Copyright (c) 2012-2013, 2015-2016 ARM Limited
36313Sgblack@eecs.umich.edu * All rights reserved.
46313Sgblack@eecs.umich.edu *
56313Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
66313Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
76313Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
86313Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
96313Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
106313Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
116313Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
126313Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
136313Sgblack@eecs.umich.edu *
146313Sgblack@eecs.umich.edu * Copyright (c) 2002-2005 The Regents of The University of Michigan
156313Sgblack@eecs.umich.edu * All rights reserved.
166313Sgblack@eecs.umich.edu *
176313Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
186313Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
196313Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
206313Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
216313Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
226313Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
236313Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
246313Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
256313Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
266313Sgblack@eecs.umich.edu * this software without specific prior written permission.
276313Sgblack@eecs.umich.edu *
286313Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
296313Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
306313Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
316313Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
326334Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
336334Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
346334Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
356334Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
366334Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
376313Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
386313Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
396313Sgblack@eecs.umich.edu *
406313Sgblack@eecs.umich.edu * Authors: Erik Hallnor
416313Sgblack@eecs.umich.edu */
426334Sgblack@eecs.umich.edu
436334Sgblack@eecs.umich.edu/**
446334Sgblack@eecs.umich.edu * @file
456334Sgblack@eecs.umich.edu * Miss Status and Handling Register (MSHR) declaration.
466334Sgblack@eecs.umich.edu */
476334Sgblack@eecs.umich.edu
486334Sgblack@eecs.umich.edu#ifndef __MEM_CACHE_MSHR_HH__
496334Sgblack@eecs.umich.edu#define __MEM_CACHE_MSHR_HH__
506334Sgblack@eecs.umich.edu
516334Sgblack@eecs.umich.edu#include <list>
526334Sgblack@eecs.umich.edu
536334Sgblack@eecs.umich.edu#include "base/printable.hh"
546334Sgblack@eecs.umich.edu#include "mem/cache/queue_entry.hh"
556334Sgblack@eecs.umich.edu
566334Sgblack@eecs.umich.educlass Cache;
576334Sgblack@eecs.umich.edu
586334Sgblack@eecs.umich.edu/**
596334Sgblack@eecs.umich.edu * Miss Status and handling Register. This class keeps all the information
606334Sgblack@eecs.umich.edu * needed to handle a cache miss including a list of target requests.
616334Sgblack@eecs.umich.edu * @sa  \ref gem5MemorySystem "gem5 Memory System"
626334Sgblack@eecs.umich.edu */
636334Sgblack@eecs.umich.educlass MSHR : public QueueEntry, public Printable
646334Sgblack@eecs.umich.edu{
656334Sgblack@eecs.umich.edu
666334Sgblack@eecs.umich.edu    /**
676334Sgblack@eecs.umich.edu     * Consider the queues friends to avoid making everything public.
686334Sgblack@eecs.umich.edu     */
696334Sgblack@eecs.umich.edu    template<typename Entry>
706334Sgblack@eecs.umich.edu    friend class Queue;
716334Sgblack@eecs.umich.edu    friend class MSHRQueue;
726334Sgblack@eecs.umich.edu
736334Sgblack@eecs.umich.edu  private:
746334Sgblack@eecs.umich.edu
756334Sgblack@eecs.umich.edu    /** Flag set by downstream caches */
766334Sgblack@eecs.umich.edu    bool downstreamPending;
776334Sgblack@eecs.umich.edu
786334Sgblack@eecs.umich.edu    /**
796334Sgblack@eecs.umich.edu     * Here we use one flag to track both if:
806334Sgblack@eecs.umich.edu     *
816334Sgblack@eecs.umich.edu     * 1. We are going to become owner or not, i.e., we will get the
826334Sgblack@eecs.umich.edu     * block in an ownership state (Owned or Modified) with BlkDirty
836334Sgblack@eecs.umich.edu     * set. This determines whether or not we are going to become the
846334Sgblack@eecs.umich.edu     * responder and ordering point for future requests that we snoop.
856334Sgblack@eecs.umich.edu     *
866334Sgblack@eecs.umich.edu     * 2. We know that we are going to get a writable block, i.e. we
876334Sgblack@eecs.umich.edu     * will get the block in writable state (Exclusive or Modified
886334Sgblack@eecs.umich.edu     * state) with BlkWritable set. That determines whether additional
896334Sgblack@eecs.umich.edu     * targets with needsWritable set will be able to be satisfied, or
906334Sgblack@eecs.umich.edu     * if not should be put on the deferred list to possibly wait for
916334Sgblack@eecs.umich.edu     * another request that does give us writable access.
926334Sgblack@eecs.umich.edu     *
936334Sgblack@eecs.umich.edu     * Condition 2 is actually just a shortcut that saves us from
946334Sgblack@eecs.umich.edu     * possibly building a deferred target list and calling
956334Sgblack@eecs.umich.edu     * promoteWritable() every time we get a writable block. Condition
966334Sgblack@eecs.umich.edu     * 1, tracking ownership, is what is important. However, we never
976334Sgblack@eecs.umich.edu     * receive ownership without marking the block dirty, and
986334Sgblack@eecs.umich.edu     * consequently use pendingModified to track both ownership and
996334Sgblack@eecs.umich.edu     * writability rather than having separate pendingDirty and
1006313Sgblack@eecs.umich.edu     * pendingWritable flags.
1016334Sgblack@eecs.umich.edu     */
1026313Sgblack@eecs.umich.edu    bool pendingModified;
1036334Sgblack@eecs.umich.edu
1046334Sgblack@eecs.umich.edu    /** Did we snoop an invalidate while waiting for data? */
1056334Sgblack@eecs.umich.edu    bool postInvalidate;
1066334Sgblack@eecs.umich.edu
1076334Sgblack@eecs.umich.edu    /** Did we snoop a read while waiting for data? */
1086334Sgblack@eecs.umich.edu    bool postDowngrade;
1096334Sgblack@eecs.umich.edu
1106334Sgblack@eecs.umich.edu  public:
1116334Sgblack@eecs.umich.edu
1126334Sgblack@eecs.umich.edu    /** True if the entry is just a simple forward from an upper level */
1136334Sgblack@eecs.umich.edu    bool isForward;
1146334Sgblack@eecs.umich.edu
1156334Sgblack@eecs.umich.edu    class Target {
1166334Sgblack@eecs.umich.edu      public:
1176334Sgblack@eecs.umich.edu
1186334Sgblack@eecs.umich.edu        enum Source {
1196334Sgblack@eecs.umich.edu            FromCPU,
1206334Sgblack@eecs.umich.edu            FromSnoop,
1216334Sgblack@eecs.umich.edu            FromPrefetcher
1226334Sgblack@eecs.umich.edu        };
1236334Sgblack@eecs.umich.edu
1246334Sgblack@eecs.umich.edu        const Tick recvTime;  //!< Time when request was received (for stats)
1256334Sgblack@eecs.umich.edu        const Tick readyTime; //!< Time when request is ready to be serviced
1266334Sgblack@eecs.umich.edu        const Counter order;  //!< Global order (for memory consistency mgmt)
1276334Sgblack@eecs.umich.edu        const PacketPtr pkt;  //!< Pending request packet.
1286334Sgblack@eecs.umich.edu        const Source source;  //!< Request from cpu, memory, or prefetcher?
1296334Sgblack@eecs.umich.edu        const bool markedPending; //!< Did we mark upstream MSHR
1306334Sgblack@eecs.umich.edu                                  //!< as downstreamPending?
1316334Sgblack@eecs.umich.edu
1326334Sgblack@eecs.umich.edu        Target(PacketPtr _pkt, Tick _readyTime, Counter _order,
1336334Sgblack@eecs.umich.edu               Source _source, bool _markedPending)
1346334Sgblack@eecs.umich.edu            : recvTime(curTick()), readyTime(_readyTime), order(_order),
1356334Sgblack@eecs.umich.edu              pkt(_pkt), source(_source), markedPending(_markedPending)
1366334Sgblack@eecs.umich.edu        {}
1376334Sgblack@eecs.umich.edu    };
1386334Sgblack@eecs.umich.edu
1396334Sgblack@eecs.umich.edu    class TargetList : public std::list<Target> {
1406334Sgblack@eecs.umich.edu
1416334Sgblack@eecs.umich.edu      public:
1426334Sgblack@eecs.umich.edu        bool needsWritable;
1436334Sgblack@eecs.umich.edu        bool hasUpgrade;
1446334Sgblack@eecs.umich.edu
1456334Sgblack@eecs.umich.edu        TargetList();
1466334Sgblack@eecs.umich.edu
1476334Sgblack@eecs.umich.edu        /**
1486334Sgblack@eecs.umich.edu         * Use the provided packet and the source to update the
1496334Sgblack@eecs.umich.edu         * flags of this TargetList.
1506334Sgblack@eecs.umich.edu         *
1516334Sgblack@eecs.umich.edu         * @param pkt Packet considered for the flag update
1526334Sgblack@eecs.umich.edu         * @param source Indicates the source of the packet
1536334Sgblack@eecs.umich.edu         */
1546334Sgblack@eecs.umich.edu        void updateFlags(PacketPtr pkt, Target::Source source);
1556334Sgblack@eecs.umich.edu
1566334Sgblack@eecs.umich.edu        void resetFlags() { needsWritable = hasUpgrade = false; }
1576334Sgblack@eecs.umich.edu
1586334Sgblack@eecs.umich.edu        /**
1596334Sgblack@eecs.umich.edu         * Goes through the list of targets and uses them to populate
1606334Sgblack@eecs.umich.edu         * the flags of this TargetList. When the function returns the
1616334Sgblack@eecs.umich.edu         * flags are consistent with the properties of packets in the
1626334Sgblack@eecs.umich.edu         * list.
1636334Sgblack@eecs.umich.edu         */
1646334Sgblack@eecs.umich.edu        void populateFlags();
1656334Sgblack@eecs.umich.edu
1666334Sgblack@eecs.umich.edu        bool isReset() const { return !needsWritable && !hasUpgrade; }
1676334Sgblack@eecs.umich.edu        void add(PacketPtr pkt, Tick readyTime, Counter order,
1686334Sgblack@eecs.umich.edu                 Target::Source source, bool markPending);
1696334Sgblack@eecs.umich.edu
1706334Sgblack@eecs.umich.edu        /**
1716334Sgblack@eecs.umich.edu         * Convert upgrades to the equivalent request if the cache line they
1726334Sgblack@eecs.umich.edu         * refer to would have been invalid (Upgrade -> ReadEx, SC* -> Fail).
1736334Sgblack@eecs.umich.edu         * Used to rejig ordering between targets waiting on an MSHR. */
1746334Sgblack@eecs.umich.edu        void replaceUpgrades();
1756334Sgblack@eecs.umich.edu
1766334Sgblack@eecs.umich.edu        void clearDownstreamPending();
1776334Sgblack@eecs.umich.edu        bool checkFunctional(PacketPtr pkt);
1786334Sgblack@eecs.umich.edu        void print(std::ostream &os, int verbosity,
1796334Sgblack@eecs.umich.edu                   const std::string &prefix) const;
1806334Sgblack@eecs.umich.edu    };
1816334Sgblack@eecs.umich.edu
1826334Sgblack@eecs.umich.edu    /** A list of MSHRs. */
1836334Sgblack@eecs.umich.edu    typedef std::list<MSHR *> List;
1846334Sgblack@eecs.umich.edu    /** MSHR list iterator. */
1856334Sgblack@eecs.umich.edu    typedef List::iterator Iterator;
1866334Sgblack@eecs.umich.edu
1876334Sgblack@eecs.umich.edu    /** Keep track of whether we should allocate on fill or not */
1886334Sgblack@eecs.umich.edu    bool allocOnFill;
1896334Sgblack@eecs.umich.edu
1906334Sgblack@eecs.umich.edu    /** The pending* and post* flags are only valid if inService is
1916334Sgblack@eecs.umich.edu     *  true.  Using the accessor functions lets us detect if these
1926334Sgblack@eecs.umich.edu     *  flags are accessed improperly.
1936334Sgblack@eecs.umich.edu     */
1946334Sgblack@eecs.umich.edu
1956334Sgblack@eecs.umich.edu    /** True if we need to get a writable copy of the block. */
1966334Sgblack@eecs.umich.edu    bool needsWritable() const { return targets.needsWritable; }
1976334Sgblack@eecs.umich.edu
1986334Sgblack@eecs.umich.edu    bool isPendingModified() const {
1996334Sgblack@eecs.umich.edu        assert(inService); return pendingModified;
2006334Sgblack@eecs.umich.edu    }
2016334Sgblack@eecs.umich.edu
2026334Sgblack@eecs.umich.edu    bool hasPostInvalidate() const {
2036334Sgblack@eecs.umich.edu        assert(inService); return postInvalidate;
2046334Sgblack@eecs.umich.edu    }
2056334Sgblack@eecs.umich.edu
2066334Sgblack@eecs.umich.edu    bool hasPostDowngrade() const {
2076334Sgblack@eecs.umich.edu        assert(inService); return postDowngrade;
2086334Sgblack@eecs.umich.edu    }
2096334Sgblack@eecs.umich.edu
2106334Sgblack@eecs.umich.edu    bool sendPacket(Cache &cache);
2116334Sgblack@eecs.umich.edu
2126334Sgblack@eecs.umich.edu  private:
2136334Sgblack@eecs.umich.edu
2146334Sgblack@eecs.umich.edu    /**
2156334Sgblack@eecs.umich.edu     * Pointer to this MSHR on the ready list.
2166334Sgblack@eecs.umich.edu     * @sa MissQueue, MSHRQueue::readyList
2176334Sgblack@eecs.umich.edu     */
2186334Sgblack@eecs.umich.edu    Iterator readyIter;
2196334Sgblack@eecs.umich.edu
2206334Sgblack@eecs.umich.edu    /**
2216334Sgblack@eecs.umich.edu     * Pointer to this MSHR on the allocated list.
2226334Sgblack@eecs.umich.edu     * @sa MissQueue, MSHRQueue::allocatedList
2236334Sgblack@eecs.umich.edu     */
2246334Sgblack@eecs.umich.edu    Iterator allocIter;
2256334Sgblack@eecs.umich.edu
2266334Sgblack@eecs.umich.edu    /** List of all requests that match the address */
2276334Sgblack@eecs.umich.edu    TargetList targets;
2286334Sgblack@eecs.umich.edu
2296334Sgblack@eecs.umich.edu    TargetList deferredTargets;
2306334Sgblack@eecs.umich.edu
2316334Sgblack@eecs.umich.edu  public:
2326334Sgblack@eecs.umich.edu
2336334Sgblack@eecs.umich.edu    /**
2346334Sgblack@eecs.umich.edu     * Allocate a miss to this MSHR.
2356334Sgblack@eecs.umich.edu     * @param blk_addr The address of the block.
2366334Sgblack@eecs.umich.edu     * @param blk_size The number of bytes to request.
2376334Sgblack@eecs.umich.edu     * @param pkt The original miss.
2386334Sgblack@eecs.umich.edu     * @param when_ready When should the MSHR be ready to act upon.
2396334Sgblack@eecs.umich.edu     * @param _order The logical order of this MSHR
2406334Sgblack@eecs.umich.edu     * @param alloc_on_fill Should the cache allocate a block on fill
2416334Sgblack@eecs.umich.edu     */
2426334Sgblack@eecs.umich.edu    void allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt,
2436334Sgblack@eecs.umich.edu                  Tick when_ready, Counter _order, bool alloc_on_fill);
2446334Sgblack@eecs.umich.edu
2456334Sgblack@eecs.umich.edu    void markInService(bool pending_modified_resp);
2466334Sgblack@eecs.umich.edu
2476334Sgblack@eecs.umich.edu    void clearDownstreamPending();
2486334Sgblack@eecs.umich.edu
2496334Sgblack@eecs.umich.edu    /**
2506334Sgblack@eecs.umich.edu     * Mark this MSHR as free.
2516334Sgblack@eecs.umich.edu     */
2526334Sgblack@eecs.umich.edu    void deallocate();
2536334Sgblack@eecs.umich.edu
2546334Sgblack@eecs.umich.edu    /**
2556334Sgblack@eecs.umich.edu     * Add a request to the list of targets.
2566334Sgblack@eecs.umich.edu     * @param target The target.
2576334Sgblack@eecs.umich.edu     */
2586334Sgblack@eecs.umich.edu    void allocateTarget(PacketPtr target, Tick when, Counter order,
2596334Sgblack@eecs.umich.edu                        bool alloc_on_fill);
2606334Sgblack@eecs.umich.edu    bool handleSnoop(PacketPtr target, Counter order);
2616334Sgblack@eecs.umich.edu
2626334Sgblack@eecs.umich.edu    /** A simple constructor. */
2636334Sgblack@eecs.umich.edu    MSHR();
2646334Sgblack@eecs.umich.edu
2656334Sgblack@eecs.umich.edu    /**
2666334Sgblack@eecs.umich.edu     * Returns the current number of allocated targets.
2676334Sgblack@eecs.umich.edu     * @return The current number of allocated targets.
2686334Sgblack@eecs.umich.edu     */
2696334Sgblack@eecs.umich.edu    int getNumTargets() const
2706334Sgblack@eecs.umich.edu    { return targets.size() + deferredTargets.size(); }
2716334Sgblack@eecs.umich.edu
2726334Sgblack@eecs.umich.edu    /**
2736334Sgblack@eecs.umich.edu     * Returns true if there are targets left.
2746334Sgblack@eecs.umich.edu     * @return true if there are targets
2756334Sgblack@eecs.umich.edu     */
2766334Sgblack@eecs.umich.edu    bool hasTargets() const { return !targets.empty(); }
2776334Sgblack@eecs.umich.edu
2786334Sgblack@eecs.umich.edu    /**
2796334Sgblack@eecs.umich.edu     * Returns a reference to the first target.
2806334Sgblack@eecs.umich.edu     * @return A pointer to the first target.
2816334Sgblack@eecs.umich.edu     */
2826334Sgblack@eecs.umich.edu    Target *getTarget()
2836334Sgblack@eecs.umich.edu    {
2846334Sgblack@eecs.umich.edu        assert(hasTargets());
2856334Sgblack@eecs.umich.edu        return &targets.front();
2866334Sgblack@eecs.umich.edu    }
2876334Sgblack@eecs.umich.edu
2886334Sgblack@eecs.umich.edu    /**
2896334Sgblack@eecs.umich.edu     * Pop first target.
2906334Sgblack@eecs.umich.edu     */
2916334Sgblack@eecs.umich.edu    void popTarget()
2926334Sgblack@eecs.umich.edu    {
2936334Sgblack@eecs.umich.edu        targets.pop_front();
2946334Sgblack@eecs.umich.edu    }
2956334Sgblack@eecs.umich.edu
2966334Sgblack@eecs.umich.edu    bool promoteDeferredTargets();
2976334Sgblack@eecs.umich.edu
2986334Sgblack@eecs.umich.edu    void promoteWritable();
2996334Sgblack@eecs.umich.edu
3006334Sgblack@eecs.umich.edu    bool checkFunctional(PacketPtr pkt);
3016334Sgblack@eecs.umich.edu
3026334Sgblack@eecs.umich.edu    /**
3036334Sgblack@eecs.umich.edu     * Prints the contents of this MSHR for debugging.
3046334Sgblack@eecs.umich.edu     */
3056334Sgblack@eecs.umich.edu    void print(std::ostream &os,
3066334Sgblack@eecs.umich.edu               int verbosity = 0,
3076334Sgblack@eecs.umich.edu               const std::string &prefix = "") const;
3086334Sgblack@eecs.umich.edu    /**
3096334Sgblack@eecs.umich.edu     * A no-args wrapper of print(std::ostream...)  meant to be
3106334Sgblack@eecs.umich.edu     * invoked from DPRINTFs avoiding string overheads in fast mode
3116334Sgblack@eecs.umich.edu     *
3126334Sgblack@eecs.umich.edu     * @return string with mshr fields + [deferred]targets
3136334Sgblack@eecs.umich.edu     */
3146334Sgblack@eecs.umich.edu    std::string print() const;
3156334Sgblack@eecs.umich.edu};
3166334Sgblack@eecs.umich.edu
3176334Sgblack@eecs.umich.edu#endif // __MEM_CACHE_MSHR_HH__
3186334Sgblack@eecs.umich.edu