mshr.hh revision 10764
12810SN/A/*
210764Sandreas.hansson@arm.com * Copyright (c) 2012-2013, 2015 ARM Limited
39663Suri.wiener@arm.com * All rights reserved.
49663Suri.wiener@arm.com *
59663Suri.wiener@arm.com * The license below extends only to copyright in the software and shall
69663Suri.wiener@arm.com * not be construed as granting a license to any other intellectual
79663Suri.wiener@arm.com * property including but not limited to intellectual property relating
89663Suri.wiener@arm.com * to a hardware implementation of the functionality of the software
99663Suri.wiener@arm.com * licensed hereunder.  You may use the software subject to the license
109663Suri.wiener@arm.com * terms below provided that you ensure that this notice is replicated
119663Suri.wiener@arm.com * unmodified and in its entirety in all distributions of the software,
129663Suri.wiener@arm.com * modified or unmodified, in source code or in binary form.
139663Suri.wiener@arm.com *
142810SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
152810SN/A * All rights reserved.
162810SN/A *
172810SN/A * Redistribution and use in source and binary forms, with or without
182810SN/A * modification, are permitted provided that the following conditions are
192810SN/A * met: redistributions of source code must retain the above copyright
202810SN/A * notice, this list of conditions and the following disclaimer;
212810SN/A * redistributions in binary form must reproduce the above copyright
222810SN/A * notice, this list of conditions and the following disclaimer in the
232810SN/A * documentation and/or other materials provided with the distribution;
242810SN/A * neither the name of the copyright holders nor the names of its
252810SN/A * contributors may be used to endorse or promote products derived from
262810SN/A * this software without specific prior written permission.
272810SN/A *
282810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392810SN/A *
402810SN/A * Authors: Erik Hallnor
412810SN/A */
422810SN/A
432810SN/A/**
442810SN/A * @file
452810SN/A * Miss Status and Handling Register (MSHR) declaration.
462810SN/A */
472810SN/A
4810764Sandreas.hansson@arm.com#ifndef __MEM_CACHE_MSHR_HH__
4910764Sandreas.hansson@arm.com#define __MEM_CACHE_MSHR_HH__
502810SN/A
514626SN/A#include <list>
524626SN/A
535314SN/A#include "base/printable.hh"
542810SN/A#include "mem/packet.hh"
552810SN/A
564626SN/Aclass CacheBlk;
574626SN/Aclass MSHRQueue;
582810SN/A
592810SN/A/**
602810SN/A * Miss Status and handling Register. This class keeps all the information
613374SN/A * needed to handle a cache miss including a list of target requests.
629264Sdjordje.kovacevic@arm.com * @sa  \ref gem5MemorySystem "gem5 Memory System"
632810SN/A */
645314SN/Aclass MSHR : public Packet::SenderState, public Printable
654626SN/A{
664626SN/A
679725Sandreas.hansson@arm.com    /**
689725Sandreas.hansson@arm.com     * Consider the MSHRQueue a friend to avoid making everything public
699725Sandreas.hansson@arm.com     */
709725Sandreas.hansson@arm.com    friend class MSHRQueue;
719725Sandreas.hansson@arm.com
729725Sandreas.hansson@arm.com  private:
739725Sandreas.hansson@arm.com
749725Sandreas.hansson@arm.com    /** Cycle when ready to issue */
759725Sandreas.hansson@arm.com    Tick readyTime;
769725Sandreas.hansson@arm.com
779725Sandreas.hansson@arm.com    /** True if the request is uncacheable */
789725Sandreas.hansson@arm.com    bool _isUncacheable;
799725Sandreas.hansson@arm.com
809725Sandreas.hansson@arm.com    /** Flag set by downstream caches */
819725Sandreas.hansson@arm.com    bool downstreamPending;
829725Sandreas.hansson@arm.com
839725Sandreas.hansson@arm.com    /** Will we have a dirty copy after this request? */
849725Sandreas.hansson@arm.com    bool pendingDirty;
859725Sandreas.hansson@arm.com
869725Sandreas.hansson@arm.com    /** Did we snoop an invalidate while waiting for data? */
879725Sandreas.hansson@arm.com    bool postInvalidate;
889725Sandreas.hansson@arm.com
899725Sandreas.hansson@arm.com    /** Did we snoop a read while waiting for data? */
909725Sandreas.hansson@arm.com    bool postDowngrade;
919725Sandreas.hansson@arm.com
922810SN/A  public:
934626SN/A
944626SN/A    class Target {
954626SN/A      public:
965875Ssteve.reinhardt@amd.com
975875Ssteve.reinhardt@amd.com        enum Source {
985875Ssteve.reinhardt@amd.com            FromCPU,
995875Ssteve.reinhardt@amd.com            FromSnoop,
1005875Ssteve.reinhardt@amd.com            FromPrefetcher
1015875Ssteve.reinhardt@amd.com        };
1025875Ssteve.reinhardt@amd.com
1034871SN/A        Tick recvTime;  //!< Time when request was received (for stats)
1044871SN/A        Tick readyTime; //!< Time when request is ready to be serviced
1054666SN/A        Counter order;  //!< Global order (for memory consistency mgmt)
1064626SN/A        PacketPtr pkt;  //!< Pending request packet.
1075875Ssteve.reinhardt@amd.com        Source source;  //!< Did request come from cpu, memory, or prefetcher?
1085318SN/A        bool markedPending; //!< Did we mark upstream MSHR
1095318SN/A                            //!<  as downstreamPending?
1104626SN/A
1115318SN/A        Target(PacketPtr _pkt, Tick _readyTime, Counter _order,
1125875Ssteve.reinhardt@amd.com               Source _source, bool _markedPending)
1137823Ssteve.reinhardt@amd.com            : recvTime(curTick()), readyTime(_readyTime), order(_order),
1145875Ssteve.reinhardt@amd.com              pkt(_pkt), source(_source), markedPending(_markedPending)
1154626SN/A        {}
1164626SN/A    };
1174626SN/A
1184903SN/A    class TargetList : public std::list<Target> {
1194903SN/A        /** Target list iterator. */
1204903SN/A        typedef std::list<Target>::iterator Iterator;
1215314SN/A        typedef std::list<Target>::const_iterator ConstIterator;
1224903SN/A
1234903SN/A      public:
1244903SN/A        bool needsExclusive;
1254903SN/A        bool hasUpgrade;
1264903SN/A
1274903SN/A        TargetList();
1284903SN/A        void resetFlags() { needsExclusive = hasUpgrade = false; }
1294903SN/A        bool isReset()    { return !needsExclusive && !hasUpgrade; }
1305318SN/A        void add(PacketPtr pkt, Tick readyTime, Counter order,
1315875Ssteve.reinhardt@amd.com                 Target::Source source, bool markPending);
1324903SN/A        void replaceUpgrades();
1334908SN/A        void clearDownstreamPending();
1344920SN/A        bool checkFunctional(PacketPtr pkt);
1355314SN/A        void print(std::ostream &os, int verbosity,
1365314SN/A                   const std::string &prefix) const;
1374903SN/A    };
1384903SN/A
1392810SN/A    /** A list of MSHRs. */
1402810SN/A    typedef std::list<MSHR *> List;
1412810SN/A    /** MSHR list iterator. */
1422810SN/A    typedef List::iterator Iterator;
1432810SN/A    /** MSHR list const_iterator. */
1442810SN/A    typedef List::const_iterator ConstIterator;
1452810SN/A
1464626SN/A    /** Pointer to queue containing this MSHR. */
1474626SN/A    MSHRQueue *queue;
1484626SN/A
1494666SN/A    /** Order number assigned by the miss queue. */
1504666SN/A    Counter order;
1514666SN/A
15210764Sandreas.hansson@arm.com    /** Block aligned address of the MSHR. */
15310764Sandreas.hansson@arm.com    Addr blkAddr;
1544626SN/A
15510764Sandreas.hansson@arm.com    /** Block size of the cache. */
15610764Sandreas.hansson@arm.com    unsigned blkSize;
1574626SN/A
15810028SGiacomo.Gabrielli@arm.com    /** True if the request targets the secure memory space. */
15910028SGiacomo.Gabrielli@arm.com    bool isSecure;
16010028SGiacomo.Gabrielli@arm.com
1613374SN/A    /** True if the request has been sent to the bus. */
1622810SN/A    bool inService;
1634626SN/A
1645730SSteve.Reinhardt@amd.com    /** True if the request is just a simple forward from an upper level */
1655730SSteve.Reinhardt@amd.com    bool isForward;
1664903SN/A
1677667Ssteve.reinhardt@amd.com    /** The pending* and post* flags are only valid if inService is
1687667Ssteve.reinhardt@amd.com     *  true.  Using the accessor functions lets us detect if these
1697667Ssteve.reinhardt@amd.com     *  flags are accessed improperly.
1707667Ssteve.reinhardt@amd.com     */
1717667Ssteve.reinhardt@amd.com
1729725Sandreas.hansson@arm.com    /** True if we need to get an exclusive copy of the block. */
1739725Sandreas.hansson@arm.com    bool needsExclusive() const { return targets.needsExclusive; }
1749725Sandreas.hansson@arm.com
1757667Ssteve.reinhardt@amd.com    bool isPendingDirty() const {
1767667Ssteve.reinhardt@amd.com        assert(inService); return pendingDirty;
1777667Ssteve.reinhardt@amd.com    }
1787667Ssteve.reinhardt@amd.com
1797667Ssteve.reinhardt@amd.com    bool hasPostInvalidate() const {
1807667Ssteve.reinhardt@amd.com        assert(inService); return postInvalidate;
1817667Ssteve.reinhardt@amd.com    }
1827667Ssteve.reinhardt@amd.com
1837667Ssteve.reinhardt@amd.com    bool hasPostDowngrade() const {
1847667Ssteve.reinhardt@amd.com        assert(inService); return postDowngrade;
1857667Ssteve.reinhardt@amd.com    }
1864665SN/A
1872810SN/A    /** Thread number of the miss. */
1886221Snate@binkert.org    ThreadID threadNum;
1892810SN/A
1909725Sandreas.hansson@arm.com  private:
1914668SN/A
1924668SN/A    /** Data buffer (if needed).  Currently used only for pending
1934668SN/A     * upgrade handling. */
1944668SN/A    uint8_t *data;
1954668SN/A
1962810SN/A    /**
1972810SN/A     * Pointer to this MSHR on the ready list.
1982810SN/A     * @sa MissQueue, MSHRQueue::readyList
1992810SN/A     */
2002810SN/A    Iterator readyIter;
2014626SN/A
2022810SN/A    /**
2032810SN/A     * Pointer to this MSHR on the allocated list.
2042810SN/A     * @sa MissQueue, MSHRQueue::allocatedList
2052810SN/A     */
2062810SN/A    Iterator allocIter;
2072810SN/A
2083374SN/A    /** List of all requests that match the address */
2099725Sandreas.hansson@arm.com    TargetList targets;
2102810SN/A
2119725Sandreas.hansson@arm.com    TargetList deferredTargets;
2124665SN/A
2139725Sandreas.hansson@arm.com  public:
2144626SN/A
2159725Sandreas.hansson@arm.com    bool isUncacheable() const { return _isUncacheable; }
2164626SN/A
2172810SN/A    /**
2182810SN/A     * Allocate a miss to this MSHR.
21910764Sandreas.hansson@arm.com     * @param blk_addr The address of the block.
22010764Sandreas.hansson@arm.com     * @param blk_size The number of bytes to request.
22110764Sandreas.hansson@arm.com     * @param pkt The original miss.
22210764Sandreas.hansson@arm.com     * @param when_ready When should the MSHR be ready to act upon.
22310764Sandreas.hansson@arm.com     * @param _order The logical order of this MSHR
2242810SN/A     */
22510764Sandreas.hansson@arm.com    void allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt,
22610764Sandreas.hansson@arm.com                  Tick when_ready, Counter _order);
2272810SN/A
22810679Sandreas.hansson@arm.com    bool markInService(bool pending_dirty_resp);
2294908SN/A
2305318SN/A    void clearDownstreamPending();
2315318SN/A
2322810SN/A    /**
2332810SN/A     * Mark this MSHR as free.
2342810SN/A     */
2352810SN/A    void deallocate();
2362810SN/A
2372810SN/A    /**
2383374SN/A     * Add a request to the list of targets.
2392810SN/A     * @param target The target.
2402810SN/A     */
2414666SN/A    void allocateTarget(PacketPtr target, Tick when, Counter order);
2424902SN/A    bool handleSnoop(PacketPtr target, Counter order);
2432810SN/A
2442810SN/A    /** A simple constructor. */
2452810SN/A    MSHR();
2462810SN/A
2472810SN/A    /**
2482810SN/A     * Returns the current number of allocated targets.
2492810SN/A     * @return The current number of allocated targets.
2502810SN/A     */
2519725Sandreas.hansson@arm.com    int getNumTargets() const
2529725Sandreas.hansson@arm.com    { return targets.size() + deferredTargets.size(); }
2532810SN/A
2542810SN/A    /**
2554899SN/A     * Returns true if there are targets left.
2564899SN/A     * @return true if there are targets
2574899SN/A     */
2589725Sandreas.hansson@arm.com    bool hasTargets() const { return !targets.empty(); }
2594899SN/A
2604899SN/A    /**
2612810SN/A     * Returns a reference to the first target.
2622810SN/A     * @return A pointer to the first target.
2632810SN/A     */
2649725Sandreas.hansson@arm.com    Target *getTarget()
2655730SSteve.Reinhardt@amd.com    {
2665730SSteve.Reinhardt@amd.com        assert(hasTargets());
2679725Sandreas.hansson@arm.com        return &targets.front();
2685730SSteve.Reinhardt@amd.com    }
2692810SN/A
2702810SN/A    /**
2712810SN/A     * Pop first target.
2722810SN/A     */
2732810SN/A    void popTarget()
2742810SN/A    {
2759725Sandreas.hansson@arm.com        targets.pop_front();
2762810SN/A    }
2772810SN/A
2785730SSteve.Reinhardt@amd.com    bool isForwardNoResponse() const
2792810SN/A    {
2804630SN/A        if (getNumTargets() != 1)
2814630SN/A            return false;
2829725Sandreas.hansson@arm.com        const Target *tgt = &targets.front();
2835875Ssteve.reinhardt@amd.com        return tgt->source == Target::FromCPU && !tgt->pkt->needsResponse();
2842810SN/A    }
2852810SN/A
2864665SN/A    bool promoteDeferredTargets();
2874665SN/A
2884671SN/A    void handleFill(Packet *pkt, CacheBlk *blk);
2894668SN/A
2905314SN/A    bool checkFunctional(PacketPtr pkt);
2914920SN/A
2922810SN/A    /**
2935314SN/A     * Prints the contents of this MSHR for debugging.
2942810SN/A     */
2955314SN/A    void print(std::ostream &os,
2965314SN/A               int verbosity = 0,
2975314SN/A               const std::string &prefix = "") const;
2989663Suri.wiener@arm.com    /**
2999663Suri.wiener@arm.com     * A no-args wrapper of print(std::ostream...)  meant to be
3009663Suri.wiener@arm.com     * invoked from DPRINTFs avoiding string overheads in fast mode
3019663Suri.wiener@arm.com     *
3029663Suri.wiener@arm.com     * @return string with mshr fields + [deferred]targets
3039663Suri.wiener@arm.com     */
3049663Suri.wiener@arm.com    std::string print() const;
3052810SN/A};
3062810SN/A
30710764Sandreas.hansson@arm.com#endif // __MEM_CACHE_MSHR_HH__
308