mshr.hh revision 11375:f98df9231cdd
12SN/A/*
21762SN/A * Copyright (c) 2012-2013, 2015-2016 ARM Limited
32SN/A * All rights reserved.
42SN/A *
52SN/A * The license below extends only to copyright in the software and shall
62SN/A * not be construed as granting a license to any other intellectual
72SN/A * property including but not limited to intellectual property relating
82SN/A * to a hardware implementation of the functionality of the software
92SN/A * licensed hereunder.  You may use the software subject to the license
102SN/A * terms below provided that you ensure that this notice is replicated
112SN/A * unmodified and in its entirety in all distributions of the software,
122SN/A * modified or unmodified, in source code or in binary form.
132SN/A *
142SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
152SN/A * All rights reserved.
162SN/A *
172SN/A * Redistribution and use in source and binary forms, with or without
182SN/A * modification, are permitted provided that the following conditions are
192SN/A * met: redistributions of source code must retain the above copyright
202SN/A * notice, this list of conditions and the following disclaimer;
212SN/A * redistributions in binary form must reproduce the above copyright
222SN/A * notice, this list of conditions and the following disclaimer in the
232SN/A * documentation and/or other materials provided with the distribution;
242SN/A * neither the name of the copyright holders nor the names of its
252SN/A * contributors may be used to endorse or promote products derived from
262SN/A * this software without specific prior written permission.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
311464SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
321464SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372972Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
387680Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
396658Snate@binkert.org *
4056SN/A * Authors: Erik Hallnor
412439SN/A */
4256SN/A
436216Snate@binkert.org/**
442410SN/A * @file
457678Sgblack@eecs.umich.edu * Miss Status and Handling Register (MSHR) declaration.
462SN/A */
472SN/A
481061SN/A#ifndef __MEM_CACHE_MSHR_HH__
492296SN/A#define __MEM_CACHE_MSHR_HH__
502296SN/A
512680Sktlim@umich.edu#include <list>
52705SN/A
532623SN/A#include "base/printable.hh"
541464SN/A#include "mem/cache/queue_entry.hh"
555597Sgblack@eecs.umich.edu
565597Sgblack@eecs.umich.educlass Cache;
575597Sgblack@eecs.umich.edu
585865Sksewell@umich.edu/**
595865Sksewell@umich.edu * Miss Status and handling Register. This class keeps all the information
602296SN/A * needed to handle a cache miss including a list of target requests.
612312SN/A * @sa  \ref gem5MemorySystem "gem5 Memory System"
62716SN/A */
632623SN/Aclass MSHR : public QueueEntry, public Printable
642623SN/A{
651128SN/A
662SN/A    /**
674572Sacolyte@umich.edu     * Consider the queues friends to avoid making everything public.
682SN/A     */
692SN/A    template<typename Entry>
702SN/A    friend class Queue;
712SN/A    friend class MSHRQueue;
722SN/A
735677Sgblack@eecs.umich.edu  private:
743271Sgblack@eecs.umich.edu
755665Sgblack@eecs.umich.edu    /** Flag set by downstream caches */
765665Sgblack@eecs.umich.edu    bool downstreamPending;
775665Sgblack@eecs.umich.edu
785665Sgblack@eecs.umich.edu    /**
795665Sgblack@eecs.umich.edu     * Here we use one flag to track both if:
805665Sgblack@eecs.umich.edu     *
815665Sgblack@eecs.umich.edu     * 1. We are going to become owner or not, i.e., we will get the
825665Sgblack@eecs.umich.edu     * block in an ownership state (Owned or Modified) with BlkDirty
835665Sgblack@eecs.umich.edu     * set. This determines whether or not we are going to become the
845665Sgblack@eecs.umich.edu     * responder and ordering point for future requests that we snoop.
855665Sgblack@eecs.umich.edu     *
865665Sgblack@eecs.umich.edu     * 2. We know that we are going to get a writable block, i.e. we
875665Sgblack@eecs.umich.edu     * will get the block in writable state (Exclusive or Modified
885665Sgblack@eecs.umich.edu     * state) with BlkWritable set. That determines whether additional
895665Sgblack@eecs.umich.edu     * targets with needsWritable set will be able to be satisfied, or
905665Sgblack@eecs.umich.edu     * if not should be put on the deferred list to possibly wait for
915665Sgblack@eecs.umich.edu     * another request that does give us writable access.
925665Sgblack@eecs.umich.edu     *
935665Sgblack@eecs.umich.edu     * Condition 2 is actually just a shortcut that saves us from
945665Sgblack@eecs.umich.edu     * possibly building a deferred target list and calling
952SN/A     * promoteWritable() every time we get a writable block. Condition
962SN/A     * 1, tracking ownership, is what is important. However, we never
972SN/A     * receive ownership without marking the block dirty, and
982SN/A     * consequently use pendingModified to track both ownership and
992SN/A     * writability rather than having separate pendingDirty and
1002SN/A     * pendingWritable flags.
1012SN/A     */
1022SN/A    bool pendingModified;
1032SN/A
1042SN/A    /** Did we snoop an invalidate while waiting for data? */
1057619Sgblack@eecs.umich.edu    bool postInvalidate;
1062SN/A
1072SN/A    /** Did we snoop a read while waiting for data? */
1082SN/A    bool postDowngrade;
1092SN/A
1102SN/A  public:
1112SN/A
1122SN/A    /** True if the entry is just a simple forward from an upper level */
1132SN/A    bool isForward;
1142SN/A
1152SN/A    class Target {
1162SN/A      public:
117753SN/A
1182SN/A        enum Source {
1192SN/A            FromCPU,
1202SN/A            FromSnoop,
121512SN/A            FromPrefetcher
122512SN/A        };
123512SN/A
124512SN/A        const Tick recvTime;  //!< Time when request was received (for stats)
125512SN/A        const Tick readyTime; //!< Time when request is ready to be serviced
126512SN/A        const Counter order;  //!< Global order (for memory consistency mgmt)
1272SN/A        const PacketPtr pkt;  //!< Pending request packet.
1282SN/A        const Source source;  //!< Request from cpu, memory, or prefetcher?
1295543Ssaidi@eecs.umich.edu        const bool markedPending; //!< Did we mark upstream MSHR
1302SN/A                                  //!< as downstreamPending?
1315543Ssaidi@eecs.umich.edu
1325543Ssaidi@eecs.umich.edu        Target(PacketPtr _pkt, Tick _readyTime, Counter _order,
1332SN/A               Source _source, bool _markedPending)
1345543Ssaidi@eecs.umich.edu            : recvTime(curTick()), readyTime(_readyTime), order(_order),
1355543Ssaidi@eecs.umich.edu              pkt(_pkt), source(_source), markedPending(_markedPending)
1365543Ssaidi@eecs.umich.edu        {}
1372336SN/A    };
1385222Sksewell@umich.edu
1395543Ssaidi@eecs.umich.edu    class TargetList : public std::list<Target> {
1405543Ssaidi@eecs.umich.edu
141593SN/A      public:
1422SN/A        bool needsWritable;
1435543Ssaidi@eecs.umich.edu        bool hasUpgrade;
1445543Ssaidi@eecs.umich.edu
1455543Ssaidi@eecs.umich.edu        TargetList();
1465543Ssaidi@eecs.umich.edu        void resetFlags() { needsWritable = hasUpgrade = false; }
1475543Ssaidi@eecs.umich.edu        bool isReset() const { return !needsWritable && !hasUpgrade; }
1485543Ssaidi@eecs.umich.edu        void add(PacketPtr pkt, Tick readyTime, Counter order,
1495543Ssaidi@eecs.umich.edu                 Target::Source source, bool markPending);
1502SN/A
1512135SN/A        /**
1522135SN/A         * Convert upgrades to the equivalent request if the cache line they
1535543Ssaidi@eecs.umich.edu         * refer to would have been invalid (Upgrade -> ReadEx, SC* -> Fail).
154512SN/A         * Used to rejig ordering between targets waiting on an MSHR. */
1555543Ssaidi@eecs.umich.edu        void replaceUpgrades();
156512SN/A
1572103SN/A        void clearDownstreamPending();
1582103SN/A        bool checkFunctional(PacketPtr pkt);
1595543Ssaidi@eecs.umich.edu        void print(std::ostream &os, int verbosity,
1605543Ssaidi@eecs.umich.edu                   const std::string &prefix) const;
1615922Sgblack@eecs.umich.edu    };
1625222Sksewell@umich.edu
1632SN/A    /** A list of MSHRs. */
164725SN/A    typedef std::list<MSHR *> List;
1652336SN/A    /** MSHR list iterator. */
1662227SN/A    typedef List::iterator Iterator;
1672336SN/A
1682336SN/A    /** Keep track of whether we should allocate on fill or not */
169725SN/A    bool allocOnFill;
1704828Sgblack@eecs.umich.edu
1714828Sgblack@eecs.umich.edu    /** The pending* and post* flags are only valid if inService is
1724828Sgblack@eecs.umich.edu     *  true.  Using the accessor functions lets us detect if these
1733271Sgblack@eecs.umich.edu     *  flags are accessed improperly.
1744539Sgblack@eecs.umich.edu     */
1755543Ssaidi@eecs.umich.edu
1765543Ssaidi@eecs.umich.edu    /** True if we need to get a writable copy of the block. */
1775543Ssaidi@eecs.umich.edu    bool needsWritable() const { return targets.needsWritable; }
1785543Ssaidi@eecs.umich.edu
1793271Sgblack@eecs.umich.edu    bool isPendingModified() const {
1805543Ssaidi@eecs.umich.edu        assert(inService); return pendingModified;
1815222Sksewell@umich.edu    }
1823271Sgblack@eecs.umich.edu
1832SN/A    bool hasPostInvalidate() const {
1842SN/A        assert(inService); return postInvalidate;
1852SN/A    }
1867619Sgblack@eecs.umich.edu
1877619Sgblack@eecs.umich.edu    bool hasPostDowngrade() const {
1882SN/A        assert(inService); return postDowngrade;
1892SN/A    }
1902SN/A
1912SN/A    bool sendPacket(Cache &cache);
1922SN/A
1932SN/A  private:
1942SN/A
1952SN/A    /**
1962SN/A     * Pointer to this MSHR on the ready list.
1972SN/A     * @sa MissQueue, MSHRQueue::readyList
1982SN/A     */
1992SN/A    Iterator readyIter;
2002SN/A
2012SN/A    /**
2022SN/A     * Pointer to this MSHR on the allocated list.
2032SN/A     * @sa MissQueue, MSHRQueue::allocatedList
2042SN/A     */
2052SN/A    Iterator allocIter;
2062SN/A
2072SN/A    /** List of all requests that match the address */
2082SN/A    TargetList targets;
2092SN/A
2102SN/A    TargetList deferredTargets;
2112SN/A
2122SN/A  public:
2132SN/A
2142SN/A    /**
2152SN/A     * Allocate a miss to this MSHR.
2162SN/A     * @param blk_addr The address of the block.
2172SN/A     * @param blk_size The number of bytes to request.
2182SN/A     * @param pkt The original miss.
2192SN/A     * @param when_ready When should the MSHR be ready to act upon.
2202SN/A     * @param _order The logical order of this MSHR
2212SN/A     * @param alloc_on_fill Should the cache allocate a block on fill
2222SN/A     */
2232SN/A    void allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt,
2242SN/A                  Tick when_ready, Counter _order, bool alloc_on_fill);
2252SN/A
2262SN/A    void markInService(bool pending_modified_resp);
2272SN/A
2282SN/A    void clearDownstreamPending();
2292SN/A
2302SN/A    /**
2312SN/A     * Mark this MSHR as free.
2322SN/A     */
2332SN/A    void deallocate();
2342SN/A
2352SN/A    /**
2362SN/A     * Add a request to the list of targets.
2372SN/A     * @param target The target.
2382SN/A     */
2392SN/A    void allocateTarget(PacketPtr target, Tick when, Counter order,
2402SN/A                        bool alloc_on_fill);
2412SN/A    bool handleSnoop(PacketPtr target, Counter order);
2425543Ssaidi@eecs.umich.edu
2432SN/A    /** A simple constructor. */
2445543Ssaidi@eecs.umich.edu    MSHR();
2455543Ssaidi@eecs.umich.edu
2465543Ssaidi@eecs.umich.edu    /**
2475543Ssaidi@eecs.umich.edu     * Returns the current number of allocated targets.
2482SN/A     * @return The current number of allocated targets.
2492SN/A     */
250593SN/A    int getNumTargets() const
2512SN/A    { return targets.size() + deferredTargets.size(); }
2525543Ssaidi@eecs.umich.edu
2535543Ssaidi@eecs.umich.edu    /**
2542SN/A     * Returns true if there are targets left.
2555543Ssaidi@eecs.umich.edu     * @return true if there are targets
2565543Ssaidi@eecs.umich.edu     */
2575543Ssaidi@eecs.umich.edu    bool hasTargets() const { return !targets.empty(); }
2585543Ssaidi@eecs.umich.edu
2592SN/A    /**
2605543Ssaidi@eecs.umich.edu     * Returns a reference to the first target.
2615543Ssaidi@eecs.umich.edu     * @return A pointer to the first target.
2622935Sksewell@umich.edu     */
2632SN/A    Target *getTarget()
2642SN/A    {
2652103SN/A        assert(hasTargets());
2662103SN/A        return &targets.front();
2672103SN/A    }
2682103SN/A
2692103SN/A    /**
270512SN/A     * Pop first target.
271512SN/A     */
272725SN/A    void popTarget()
2732296SN/A    {
2742336SN/A        targets.pop_front();
2752312SN/A    }
2764828Sgblack@eecs.umich.edu
2774539Sgblack@eecs.umich.edu    bool promoteDeferredTargets();
2784539Sgblack@eecs.umich.edu
2793271Sgblack@eecs.umich.edu    void promoteWritable();
2804539Sgblack@eecs.umich.edu
2814539Sgblack@eecs.umich.edu    bool checkFunctional(PacketPtr pkt);
2823271Sgblack@eecs.umich.edu
2833271Sgblack@eecs.umich.edu    /**
2842SN/A     * Prints the contents of this MSHR for debugging.
2852SN/A     */
2865335Shines@cs.fsu.edu    void print(std::ostream &os,
2872SN/A               int verbosity = 0,
2882SN/A               const std::string &prefix = "") const;
2892SN/A    /**
2902SN/A     * A no-args wrapper of print(std::ostream...)  meant to be
2912SN/A     * invoked from DPRINTFs avoiding string overheads in fast mode
2922SN/A     *
2932SN/A     * @return string with mshr fields + [deferred]targets
2942SN/A     */
2952SN/A    std::string print() const;
2962SN/A};
2972SN/A
2982SN/A#endif // __MEM_CACHE_MSHR_HH__
2992SN/A