mshr.hh revision 12823
113996Sgiacomo.travaglini@arm.com/*
213996Sgiacomo.travaglini@arm.com * Copyright (c) 2012-2013, 2015-2016, 2018 ARM Limited
313996Sgiacomo.travaglini@arm.com * All rights reserved.
413996Sgiacomo.travaglini@arm.com *
513996Sgiacomo.travaglini@arm.com * The license below extends only to copyright in the software and shall
613996Sgiacomo.travaglini@arm.com * not be construed as granting a license to any other intellectual
713996Sgiacomo.travaglini@arm.com * property including but not limited to intellectual property relating
813996Sgiacomo.travaglini@arm.com * to a hardware implementation of the functionality of the software
913996Sgiacomo.travaglini@arm.com * licensed hereunder.  You may use the software subject to the license
1013996Sgiacomo.travaglini@arm.com * terms below provided that you ensure that this notice is replicated
1113996Sgiacomo.travaglini@arm.com * unmodified and in its entirety in all distributions of the software,
1213996Sgiacomo.travaglini@arm.com * modified or unmodified, in source code or in binary form.
1313996Sgiacomo.travaglini@arm.com *
1413996Sgiacomo.travaglini@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
1513996Sgiacomo.travaglini@arm.com * All rights reserved.
1613996Sgiacomo.travaglini@arm.com *
1713996Sgiacomo.travaglini@arm.com * Redistribution and use in source and binary forms, with or without
1813996Sgiacomo.travaglini@arm.com * modification, are permitted provided that the following conditions are
1913996Sgiacomo.travaglini@arm.com * met: redistributions of source code must retain the above copyright
2013996Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer;
2113996Sgiacomo.travaglini@arm.com * redistributions in binary form must reproduce the above copyright
2213996Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer in the
2313996Sgiacomo.travaglini@arm.com * documentation and/or other materials provided with the distribution;
2413996Sgiacomo.travaglini@arm.com * neither the name of the copyright holders nor the names of its
2513996Sgiacomo.travaglini@arm.com * contributors may be used to endorse or promote products derived from
2613996Sgiacomo.travaglini@arm.com * this software without specific prior written permission.
2713996Sgiacomo.travaglini@arm.com *
2813996Sgiacomo.travaglini@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2913996Sgiacomo.travaglini@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3013996Sgiacomo.travaglini@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3113996Sgiacomo.travaglini@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3213996Sgiacomo.travaglini@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3313996Sgiacomo.travaglini@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3413996Sgiacomo.travaglini@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3513996Sgiacomo.travaglini@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3613996Sgiacomo.travaglini@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3713996Sgiacomo.travaglini@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3813996Sgiacomo.travaglini@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3913996Sgiacomo.travaglini@arm.com *
4013996Sgiacomo.travaglini@arm.com * Authors: Erik Hallnor
4113996Sgiacomo.travaglini@arm.com */
4213996Sgiacomo.travaglini@arm.com
4313996Sgiacomo.travaglini@arm.com/**
4413996Sgiacomo.travaglini@arm.com * @file
4513996Sgiacomo.travaglini@arm.com * Miss Status and Handling Register (MSHR) declaration.
4613996Sgiacomo.travaglini@arm.com */
4713996Sgiacomo.travaglini@arm.com
4813996Sgiacomo.travaglini@arm.com#ifndef __MEM_CACHE_MSHR_HH__
4913996Sgiacomo.travaglini@arm.com#define __MEM_CACHE_MSHR_HH__
5013996Sgiacomo.travaglini@arm.com
5113996Sgiacomo.travaglini@arm.com#include <cassert>
5213996Sgiacomo.travaglini@arm.com#include <iosfwd>
5313996Sgiacomo.travaglini@arm.com#include <list>
5413996Sgiacomo.travaglini@arm.com#include <string>
5514181Sgiacomo.travaglini@arm.com
5614181Sgiacomo.travaglini@arm.com#include "base/printable.hh"
5713996Sgiacomo.travaglini@arm.com#include "base/types.hh"
5813996Sgiacomo.travaglini@arm.com#include "mem/cache/queue_entry.hh"
5913996Sgiacomo.travaglini@arm.com#include "mem/packet.hh"
6013996Sgiacomo.travaglini@arm.com#include "sim/core.hh"
6113996Sgiacomo.travaglini@arm.com
6213996Sgiacomo.travaglini@arm.comclass BaseCache;
6313996Sgiacomo.travaglini@arm.com
6413996Sgiacomo.travaglini@arm.com/**
6513996Sgiacomo.travaglini@arm.com * Miss Status and handling Register. This class keeps all the information
6613996Sgiacomo.travaglini@arm.com * needed to handle a cache miss including a list of target requests.
6713996Sgiacomo.travaglini@arm.com * @sa  \ref gem5MemorySystem "gem5 Memory System"
6813996Sgiacomo.travaglini@arm.com */
6913996Sgiacomo.travaglini@arm.comclass MSHR : public QueueEntry, public Printable
7013996Sgiacomo.travaglini@arm.com{
7113996Sgiacomo.travaglini@arm.com
7213996Sgiacomo.travaglini@arm.com    /**
7313996Sgiacomo.travaglini@arm.com     * Consider the queues friends to avoid making everything public.
7413996Sgiacomo.travaglini@arm.com     */
7513996Sgiacomo.travaglini@arm.com    template<typename Entry>
7613996Sgiacomo.travaglini@arm.com    friend class Queue;
7713996Sgiacomo.travaglini@arm.com    friend class MSHRQueue;
7813996Sgiacomo.travaglini@arm.com
7913996Sgiacomo.travaglini@arm.com  private:
8013996Sgiacomo.travaglini@arm.com
8113996Sgiacomo.travaglini@arm.com    /** Flag set by downstream caches */
8213996Sgiacomo.travaglini@arm.com    bool downstreamPending;
8313996Sgiacomo.travaglini@arm.com
8413996Sgiacomo.travaglini@arm.com    /**
8513996Sgiacomo.travaglini@arm.com     * Here we use one flag to track both if:
8613996Sgiacomo.travaglini@arm.com     *
8713996Sgiacomo.travaglini@arm.com     * 1. We are going to become owner or not, i.e., we will get the
8813996Sgiacomo.travaglini@arm.com     * block in an ownership state (Owned or Modified) with BlkDirty
8913996Sgiacomo.travaglini@arm.com     * set. This determines whether or not we are going to become the
9013996Sgiacomo.travaglini@arm.com     * responder and ordering point for future requests that we snoop.
9113996Sgiacomo.travaglini@arm.com     *
9213996Sgiacomo.travaglini@arm.com     * 2. We know that we are going to get a writable block, i.e. we
9313996Sgiacomo.travaglini@arm.com     * will get the block in writable state (Exclusive or Modified
9413996Sgiacomo.travaglini@arm.com     * state) with BlkWritable set. That determines whether additional
9513996Sgiacomo.travaglini@arm.com     * targets with needsWritable set will be able to be satisfied, or
9613996Sgiacomo.travaglini@arm.com     * if not should be put on the deferred list to possibly wait for
9713996Sgiacomo.travaglini@arm.com     * another request that does give us writable access.
9813996Sgiacomo.travaglini@arm.com     *
9913996Sgiacomo.travaglini@arm.com     * Condition 2 is actually just a shortcut that saves us from
10013996Sgiacomo.travaglini@arm.com     * possibly building a deferred target list and calling
10113996Sgiacomo.travaglini@arm.com     * promoteWritable() every time we get a writable block. Condition
10213996Sgiacomo.travaglini@arm.com     * 1, tracking ownership, is what is important. However, we never
10313996Sgiacomo.travaglini@arm.com     * receive ownership without marking the block dirty, and
10413996Sgiacomo.travaglini@arm.com     * consequently use pendingModified to track both ownership and
10513996Sgiacomo.travaglini@arm.com     * writability rather than having separate pendingDirty and
10613996Sgiacomo.travaglini@arm.com     * pendingWritable flags.
10713996Sgiacomo.travaglini@arm.com     */
10813996Sgiacomo.travaglini@arm.com    bool pendingModified;
10913996Sgiacomo.travaglini@arm.com
11013996Sgiacomo.travaglini@arm.com    /** Did we snoop an invalidate while waiting for data? */
11113996Sgiacomo.travaglini@arm.com    bool postInvalidate;
11213996Sgiacomo.travaglini@arm.com
11313996Sgiacomo.travaglini@arm.com    /** Did we snoop a read while waiting for data? */
11413996Sgiacomo.travaglini@arm.com    bool postDowngrade;
11513996Sgiacomo.travaglini@arm.com
11613996Sgiacomo.travaglini@arm.com  public:
11713996Sgiacomo.travaglini@arm.com
11813996Sgiacomo.travaglini@arm.com    /** True if the entry is just a simple forward from an upper level */
11913996Sgiacomo.travaglini@arm.com    bool isForward;
12013996Sgiacomo.travaglini@arm.com
12113996Sgiacomo.travaglini@arm.com    class Target {
12213996Sgiacomo.travaglini@arm.com      public:
12313996Sgiacomo.travaglini@arm.com
12413996Sgiacomo.travaglini@arm.com        enum Source {
12513996Sgiacomo.travaglini@arm.com            FromCPU,
12613996Sgiacomo.travaglini@arm.com            FromSnoop,
12713996Sgiacomo.travaglini@arm.com            FromPrefetcher
12813996Sgiacomo.travaglini@arm.com        };
12913996Sgiacomo.travaglini@arm.com
13013996Sgiacomo.travaglini@arm.com        const Tick recvTime;  //!< Time when request was received (for stats)
13113996Sgiacomo.travaglini@arm.com        const Tick readyTime; //!< Time when request is ready to be serviced
13213996Sgiacomo.travaglini@arm.com        const Counter order;  //!< Global order (for memory consistency mgmt)
13313996Sgiacomo.travaglini@arm.com        const PacketPtr pkt;  //!< Pending request packet.
13413996Sgiacomo.travaglini@arm.com        const Source source;  //!< Request from cpu, memory, or prefetcher?
13513996Sgiacomo.travaglini@arm.com
13613996Sgiacomo.travaglini@arm.com        /**
13713996Sgiacomo.travaglini@arm.com         * We use this flag to track whether we have cleared the
13813996Sgiacomo.travaglini@arm.com         * downstreamPending flag for the MSHR of the cache above
13913996Sgiacomo.travaglini@arm.com         * where this packet originates from and guard noninitial
14013996Sgiacomo.travaglini@arm.com         * attempts to clear it.
14113996Sgiacomo.travaglini@arm.com         *
14213996Sgiacomo.travaglini@arm.com         * The flag markedPending needs to be updated when the
14313996Sgiacomo.travaglini@arm.com         * TargetList is in service which can be:
14413996Sgiacomo.travaglini@arm.com         * 1) during the Target instantiation if the MSHR is in
14513996Sgiacomo.travaglini@arm.com         * service and the target is not deferred,
14613996Sgiacomo.travaglini@arm.com         * 2) when the MSHR becomes in service if the target is not
14713996Sgiacomo.travaglini@arm.com         * deferred,
14813996Sgiacomo.travaglini@arm.com         * 3) or when the TargetList is promoted (deferredTargets ->
14914188Sgiacomo.travaglini@arm.com         * targets).
15013996Sgiacomo.travaglini@arm.com         */
15113996Sgiacomo.travaglini@arm.com        bool markedPending;
15213996Sgiacomo.travaglini@arm.com
15313996Sgiacomo.travaglini@arm.com        const bool allocOnFill;   //!< Should the response servicing this
15413996Sgiacomo.travaglini@arm.com                                  //!< target list allocate in the cache?
15513996Sgiacomo.travaglini@arm.com
15613996Sgiacomo.travaglini@arm.com        Target(PacketPtr _pkt, Tick _readyTime, Counter _order,
15713996Sgiacomo.travaglini@arm.com               Source _source, bool _markedPending, bool alloc_on_fill)
15813996Sgiacomo.travaglini@arm.com            : recvTime(curTick()), readyTime(_readyTime), order(_order),
15913996Sgiacomo.travaglini@arm.com              pkt(_pkt), source(_source), markedPending(_markedPending),
16014188Sgiacomo.travaglini@arm.com              allocOnFill(alloc_on_fill)
16113996Sgiacomo.travaglini@arm.com        {}
16213996Sgiacomo.travaglini@arm.com    };
16313996Sgiacomo.travaglini@arm.com
16413996Sgiacomo.travaglini@arm.com    class TargetList : public std::list<Target> {
16513996Sgiacomo.travaglini@arm.com
16613996Sgiacomo.travaglini@arm.com      public:
16713996Sgiacomo.travaglini@arm.com        bool needsWritable;
16813996Sgiacomo.travaglini@arm.com        bool hasUpgrade;
16913996Sgiacomo.travaglini@arm.com        /** Set when the response should allocate on fill */
17013996Sgiacomo.travaglini@arm.com        bool allocOnFill;
17113996Sgiacomo.travaglini@arm.com        /**
17214188Sgiacomo.travaglini@arm.com         * Determine whether there was at least one non-snooping
17313996Sgiacomo.travaglini@arm.com         * target coming from another cache.
17413996Sgiacomo.travaglini@arm.com         */
17513996Sgiacomo.travaglini@arm.com        bool hasFromCache;
17613996Sgiacomo.travaglini@arm.com
17713996Sgiacomo.travaglini@arm.com        TargetList();
17813996Sgiacomo.travaglini@arm.com
17913996Sgiacomo.travaglini@arm.com        /**
18013996Sgiacomo.travaglini@arm.com         * Use the provided packet and the source to update the
18113996Sgiacomo.travaglini@arm.com         * flags of this TargetList.
18214188Sgiacomo.travaglini@arm.com         *
18313996Sgiacomo.travaglini@arm.com         * @param pkt Packet considered for the flag update
18414188Sgiacomo.travaglini@arm.com         * @param source Indicates the source of the packet
18513996Sgiacomo.travaglini@arm.com         * @param alloc_on_fill Whether the pkt would allocate on a fill
18613996Sgiacomo.travaglini@arm.com         */
18713996Sgiacomo.travaglini@arm.com        void updateFlags(PacketPtr pkt, Target::Source source,
18813996Sgiacomo.travaglini@arm.com                         bool alloc_on_fill);
18913996Sgiacomo.travaglini@arm.com
19013996Sgiacomo.travaglini@arm.com        void resetFlags() {
19113996Sgiacomo.travaglini@arm.com            needsWritable = false;
19213996Sgiacomo.travaglini@arm.com            hasUpgrade = false;
19313996Sgiacomo.travaglini@arm.com            allocOnFill = false;
19413996Sgiacomo.travaglini@arm.com            hasFromCache = false;
19513996Sgiacomo.travaglini@arm.com        }
19614188Sgiacomo.travaglini@arm.com
19714188Sgiacomo.travaglini@arm.com        /**
19813996Sgiacomo.travaglini@arm.com         * Goes through the list of targets and uses them to populate
19913996Sgiacomo.travaglini@arm.com         * the flags of this TargetList. When the function returns the
20013996Sgiacomo.travaglini@arm.com         * flags are consistent with the properties of packets in the
20113996Sgiacomo.travaglini@arm.com         * list.
20213996Sgiacomo.travaglini@arm.com         */
20313996Sgiacomo.travaglini@arm.com        void populateFlags();
20413996Sgiacomo.travaglini@arm.com
20513996Sgiacomo.travaglini@arm.com        /**
20613996Sgiacomo.travaglini@arm.com         * Tests if the flags of this TargetList have their default
20713996Sgiacomo.travaglini@arm.com         * values.
20814188Sgiacomo.travaglini@arm.com         */
20913996Sgiacomo.travaglini@arm.com        bool isReset() const {
21014188Sgiacomo.travaglini@arm.com            return !needsWritable && !hasUpgrade && !allocOnFill &&
21113996Sgiacomo.travaglini@arm.com                !hasFromCache;
21213996Sgiacomo.travaglini@arm.com        }
21313996Sgiacomo.travaglini@arm.com
21413996Sgiacomo.travaglini@arm.com        /**
21513996Sgiacomo.travaglini@arm.com         * Add the specified packet in the TargetList. This function
21613996Sgiacomo.travaglini@arm.com         * stores information related to the added packet and updates
21713996Sgiacomo.travaglini@arm.com         * accordingly the flags.
21813996Sgiacomo.travaglini@arm.com         *
21913996Sgiacomo.travaglini@arm.com         * @param pkt Packet considered for adding
22013996Sgiacomo.travaglini@arm.com         * @param readTime Tick at which the packet is processed by this cache
22113996Sgiacomo.travaglini@arm.com         * @param order A counter giving a unique id to each target
22213996Sgiacomo.travaglini@arm.com         * @param source Indicates the source agent of the packet
22314181Sgiacomo.travaglini@arm.com         * @param markPending Set for deferred targets or pending MSHRs
22413996Sgiacomo.travaglini@arm.com         * @param alloc_on_fill Whether it should allocate on a fill
22513996Sgiacomo.travaglini@arm.com         */
22613996Sgiacomo.travaglini@arm.com        void add(PacketPtr pkt, Tick readyTime, Counter order,
22713996Sgiacomo.travaglini@arm.com                 Target::Source source, bool markPending,
22813996Sgiacomo.travaglini@arm.com                 bool alloc_on_fill);
22913996Sgiacomo.travaglini@arm.com
23014181Sgiacomo.travaglini@arm.com        /**
23114181Sgiacomo.travaglini@arm.com         * Convert upgrades to the equivalent request if the cache line they
23213996Sgiacomo.travaglini@arm.com         * refer to would have been invalid (Upgrade -> ReadEx, SC* -> Fail).
23313996Sgiacomo.travaglini@arm.com         * Used to rejig ordering between targets waiting on an MSHR. */
23413996Sgiacomo.travaglini@arm.com        void replaceUpgrades();
23513996Sgiacomo.travaglini@arm.com
23613996Sgiacomo.travaglini@arm.com        void clearDownstreamPending();
23713996Sgiacomo.travaglini@arm.com        void clearDownstreamPending(iterator begin, iterator end);
23813996Sgiacomo.travaglini@arm.com        bool trySatisfyFunctional(PacketPtr pkt);
23913996Sgiacomo.travaglini@arm.com        void print(std::ostream &os, int verbosity,
24013996Sgiacomo.travaglini@arm.com                   const std::string &prefix) const;
24113996Sgiacomo.travaglini@arm.com    };
24213996Sgiacomo.travaglini@arm.com
24313996Sgiacomo.travaglini@arm.com    /** A list of MSHRs. */
24413996Sgiacomo.travaglini@arm.com    typedef std::list<MSHR *> List;
24513996Sgiacomo.travaglini@arm.com    /** MSHR list iterator. */
24613996Sgiacomo.travaglini@arm.com    typedef List::iterator Iterator;
24713996Sgiacomo.travaglini@arm.com
24813996Sgiacomo.travaglini@arm.com    /** The pending* and post* flags are only valid if inService is
24913996Sgiacomo.travaglini@arm.com     *  true.  Using the accessor functions lets us detect if these
25013996Sgiacomo.travaglini@arm.com     *  flags are accessed improperly.
25113996Sgiacomo.travaglini@arm.com     */
25213996Sgiacomo.travaglini@arm.com
25313996Sgiacomo.travaglini@arm.com    /** True if we need to get a writable copy of the block. */
25413996Sgiacomo.travaglini@arm.com    bool needsWritable() const { return targets.needsWritable; }
25513996Sgiacomo.travaglini@arm.com
25613996Sgiacomo.travaglini@arm.com    bool isCleaning() const {
25713996Sgiacomo.travaglini@arm.com        PacketPtr pkt = targets.front().pkt;
25813996Sgiacomo.travaglini@arm.com        return pkt->isClean();
25913996Sgiacomo.travaglini@arm.com    }
26013996Sgiacomo.travaglini@arm.com
26113996Sgiacomo.travaglini@arm.com    bool isPendingModified() const {
26213996Sgiacomo.travaglini@arm.com        assert(inService); return pendingModified;
26313996Sgiacomo.travaglini@arm.com    }
26413996Sgiacomo.travaglini@arm.com
26513996Sgiacomo.travaglini@arm.com    bool hasPostInvalidate() const {
26613996Sgiacomo.travaglini@arm.com        assert(inService); return postInvalidate;
26713996Sgiacomo.travaglini@arm.com    }
26813996Sgiacomo.travaglini@arm.com
26913996Sgiacomo.travaglini@arm.com    bool hasPostDowngrade() const {
27013996Sgiacomo.travaglini@arm.com        assert(inService); return postDowngrade;
27113996Sgiacomo.travaglini@arm.com    }
27213996Sgiacomo.travaglini@arm.com
27313996Sgiacomo.travaglini@arm.com    bool sendPacket(BaseCache &cache);
27413996Sgiacomo.travaglini@arm.com
27513996Sgiacomo.travaglini@arm.com    bool allocOnFill() const {
27613996Sgiacomo.travaglini@arm.com        return targets.allocOnFill;
27713996Sgiacomo.travaglini@arm.com    }
27813996Sgiacomo.travaglini@arm.com
27913996Sgiacomo.travaglini@arm.com    /**
28013996Sgiacomo.travaglini@arm.com     * Determine if there are non-deferred requests from other caches
28113996Sgiacomo.travaglini@arm.com     *
28213996Sgiacomo.travaglini@arm.com     * @return true if any of the targets is from another cache
28313996Sgiacomo.travaglini@arm.com     */
28413996Sgiacomo.travaglini@arm.com    bool hasFromCache() const {
28513996Sgiacomo.travaglini@arm.com        return targets.hasFromCache;
28613996Sgiacomo.travaglini@arm.com    }
28713996Sgiacomo.travaglini@arm.com
28813996Sgiacomo.travaglini@arm.com  private:
28913996Sgiacomo.travaglini@arm.com    /**
29013996Sgiacomo.travaglini@arm.com     * Promotes deferred targets that satisfy a predicate
29113996Sgiacomo.travaglini@arm.com     *
29213996Sgiacomo.travaglini@arm.com     * Deferred targets are promoted to the target list if they
29313996Sgiacomo.travaglini@arm.com     * satisfy a given condition. The operation stops at the first
29413996Sgiacomo.travaglini@arm.com     * deferred target that doesn't satisfy the condition.
29513996Sgiacomo.travaglini@arm.com     *
29613996Sgiacomo.travaglini@arm.com     * @param pred A condition on a Target
29713996Sgiacomo.travaglini@arm.com     */
29813996Sgiacomo.travaglini@arm.com    void promoteIf(const std::function<bool (Target &)>& pred);
29913996Sgiacomo.travaglini@arm.com
30013996Sgiacomo.travaglini@arm.com    /**
30113996Sgiacomo.travaglini@arm.com     * Pointer to this MSHR on the ready list.
30213996Sgiacomo.travaglini@arm.com     * @sa MissQueue, MSHRQueue::readyList
30313996Sgiacomo.travaglini@arm.com     */
30413996Sgiacomo.travaglini@arm.com    Iterator readyIter;
30513996Sgiacomo.travaglini@arm.com
30613996Sgiacomo.travaglini@arm.com    /**
30713996Sgiacomo.travaglini@arm.com     * Pointer to this MSHR on the allocated list.
30813996Sgiacomo.travaglini@arm.com     * @sa MissQueue, MSHRQueue::allocatedList
30913996Sgiacomo.travaglini@arm.com     */
31013996Sgiacomo.travaglini@arm.com    Iterator allocIter;
31113996Sgiacomo.travaglini@arm.com
31213996Sgiacomo.travaglini@arm.com    /** List of all requests that match the address */
31313996Sgiacomo.travaglini@arm.com    TargetList targets;
31413996Sgiacomo.travaglini@arm.com
31513996Sgiacomo.travaglini@arm.com    TargetList deferredTargets;
31613996Sgiacomo.travaglini@arm.com
31714181Sgiacomo.travaglini@arm.com  public:
31814181Sgiacomo.travaglini@arm.com
31913996Sgiacomo.travaglini@arm.com    /**
32013996Sgiacomo.travaglini@arm.com     * Allocate a miss to this MSHR.
32113996Sgiacomo.travaglini@arm.com     * @param blk_addr The address of the block.
32213996Sgiacomo.travaglini@arm.com     * @param blk_size The number of bytes to request.
32313996Sgiacomo.travaglini@arm.com     * @param pkt The original miss.
32414181Sgiacomo.travaglini@arm.com     * @param when_ready When should the MSHR be ready to act upon.
32514181Sgiacomo.travaglini@arm.com     * @param _order The logical order of this MSHR
32614181Sgiacomo.travaglini@arm.com     * @param alloc_on_fill Should the cache allocate a block on fill
32713996Sgiacomo.travaglini@arm.com     */
32813996Sgiacomo.travaglini@arm.com    void allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt,
32913996Sgiacomo.travaglini@arm.com                  Tick when_ready, Counter _order, bool alloc_on_fill);
33013996Sgiacomo.travaglini@arm.com
33113996Sgiacomo.travaglini@arm.com    void markInService(bool pending_modified_resp);
33213996Sgiacomo.travaglini@arm.com
33313996Sgiacomo.travaglini@arm.com    void clearDownstreamPending();
33413996Sgiacomo.travaglini@arm.com
33513996Sgiacomo.travaglini@arm.com    /**
33613996Sgiacomo.travaglini@arm.com     * Mark this MSHR as free.
33713996Sgiacomo.travaglini@arm.com     */
33813996Sgiacomo.travaglini@arm.com    void deallocate();
33913996Sgiacomo.travaglini@arm.com
34013996Sgiacomo.travaglini@arm.com    /**
34113996Sgiacomo.travaglini@arm.com     * Add a request to the list of targets.
34213996Sgiacomo.travaglini@arm.com     * @param target The target.
34313996Sgiacomo.travaglini@arm.com     */
34413996Sgiacomo.travaglini@arm.com    void allocateTarget(PacketPtr target, Tick when, Counter order,
34513996Sgiacomo.travaglini@arm.com                        bool alloc_on_fill);
34613996Sgiacomo.travaglini@arm.com    bool handleSnoop(PacketPtr target, Counter order);
34713996Sgiacomo.travaglini@arm.com
34813996Sgiacomo.travaglini@arm.com    /** A simple constructor. */
34913996Sgiacomo.travaglini@arm.com    MSHR();
35013996Sgiacomo.travaglini@arm.com
35113996Sgiacomo.travaglini@arm.com    /**
35213996Sgiacomo.travaglini@arm.com     * Returns the current number of allocated targets.
35313996Sgiacomo.travaglini@arm.com     * @return The current number of allocated targets.
35413996Sgiacomo.travaglini@arm.com     */
35513996Sgiacomo.travaglini@arm.com    int getNumTargets() const
35613996Sgiacomo.travaglini@arm.com    { return targets.size() + deferredTargets.size(); }
35713996Sgiacomo.travaglini@arm.com
35813996Sgiacomo.travaglini@arm.com    /**
35913996Sgiacomo.travaglini@arm.com     * Extracts the subset of the targets that can be serviced given a
36013996Sgiacomo.travaglini@arm.com     * received response. This function returns the targets list
36113996Sgiacomo.travaglini@arm.com     * unless the response is a ReadRespWithInvalidate. The
36213996Sgiacomo.travaglini@arm.com     * ReadRespWithInvalidate is only invalidating response that its
36313996Sgiacomo.travaglini@arm.com     * invalidation was not expected when the request (a
36413996Sgiacomo.travaglini@arm.com     * ReadSharedReq) was sent out. For ReadRespWithInvalidate we can
36513996Sgiacomo.travaglini@arm.com     * safely service only the first FromCPU target and all FromSnoop
36613996Sgiacomo.travaglini@arm.com     * targets (inform all snoopers that we no longer have the block).
36713996Sgiacomo.travaglini@arm.com     *
36813996Sgiacomo.travaglini@arm.com     * @param pkt The response from the downstream memory
36913996Sgiacomo.travaglini@arm.com     */
37013996Sgiacomo.travaglini@arm.com    TargetList extractServiceableTargets(PacketPtr pkt);
37113996Sgiacomo.travaglini@arm.com
37213996Sgiacomo.travaglini@arm.com    /**
37313996Sgiacomo.travaglini@arm.com     * Returns true if there are targets left.
37413996Sgiacomo.travaglini@arm.com     * @return true if there are targets
37513996Sgiacomo.travaglini@arm.com     */
37613996Sgiacomo.travaglini@arm.com    bool hasTargets() const { return !targets.empty(); }
37713996Sgiacomo.travaglini@arm.com
37813996Sgiacomo.travaglini@arm.com    /**
37913996Sgiacomo.travaglini@arm.com     * Returns a reference to the first target.
38013996Sgiacomo.travaglini@arm.com     * @return A pointer to the first target.
38113996Sgiacomo.travaglini@arm.com     */
38213996Sgiacomo.travaglini@arm.com    Target *getTarget()
38313996Sgiacomo.travaglini@arm.com    {
38413996Sgiacomo.travaglini@arm.com        assert(hasTargets());
38513996Sgiacomo.travaglini@arm.com        return &targets.front();
38613996Sgiacomo.travaglini@arm.com    }
38713996Sgiacomo.travaglini@arm.com
38813996Sgiacomo.travaglini@arm.com    /**
38913996Sgiacomo.travaglini@arm.com     * Pop first target.
39013996Sgiacomo.travaglini@arm.com     */
39113996Sgiacomo.travaglini@arm.com    void popTarget()
39213996Sgiacomo.travaglini@arm.com    {
39313996Sgiacomo.travaglini@arm.com        targets.pop_front();
39413996Sgiacomo.travaglini@arm.com    }
39513996Sgiacomo.travaglini@arm.com
39613996Sgiacomo.travaglini@arm.com    bool promoteDeferredTargets();
39713996Sgiacomo.travaglini@arm.com
39813996Sgiacomo.travaglini@arm.com    /**
39913996Sgiacomo.travaglini@arm.com     * Promotes deferred targets that do not require writable
40013996Sgiacomo.travaglini@arm.com     *
40113996Sgiacomo.travaglini@arm.com     * Move targets from the deferred targets list to the target list
40213996Sgiacomo.travaglini@arm.com     * starting from the first deferred target until the first target
40313996Sgiacomo.travaglini@arm.com     * that is a cache maintenance operation or needs a writable copy
40413996Sgiacomo.travaglini@arm.com     * of the block
40513996Sgiacomo.travaglini@arm.com     */
40613996Sgiacomo.travaglini@arm.com    void promoteReadable();
40713996Sgiacomo.travaglini@arm.com
40813996Sgiacomo.travaglini@arm.com    /**
40913996Sgiacomo.travaglini@arm.com     * Promotes deferred targets that do not require writable
41013996Sgiacomo.travaglini@arm.com     *
41113996Sgiacomo.travaglini@arm.com     * Requests in the deferred target list are moved to the target
41213996Sgiacomo.travaglini@arm.com     * list up until the first target that is a cache maintenance
41313996Sgiacomo.travaglini@arm.com     * operation or needs a writable copy of the block
41413996Sgiacomo.travaglini@arm.com     */
41513996Sgiacomo.travaglini@arm.com    void promoteWritable();
41613996Sgiacomo.travaglini@arm.com
41713996Sgiacomo.travaglini@arm.com    bool trySatisfyFunctional(PacketPtr pkt);
41813996Sgiacomo.travaglini@arm.com
41913996Sgiacomo.travaglini@arm.com    /**
42013996Sgiacomo.travaglini@arm.com     * Prints the contents of this MSHR for debugging.
42113996Sgiacomo.travaglini@arm.com     */
42213996Sgiacomo.travaglini@arm.com    void print(std::ostream &os,
42313996Sgiacomo.travaglini@arm.com               int verbosity = 0,
42413996Sgiacomo.travaglini@arm.com               const std::string &prefix = "") const;
42513996Sgiacomo.travaglini@arm.com    /**
42613996Sgiacomo.travaglini@arm.com     * A no-args wrapper of print(std::ostream...)  meant to be
42713996Sgiacomo.travaglini@arm.com     * invoked from DPRINTFs avoiding string overheads in fast mode
42813996Sgiacomo.travaglini@arm.com     *
42913996Sgiacomo.travaglini@arm.com     * @return string with mshr fields + [deferred]targets
43013996Sgiacomo.travaglini@arm.com     */
43113996Sgiacomo.travaglini@arm.com    std::string print() const;
43213996Sgiacomo.travaglini@arm.com};
43313996Sgiacomo.travaglini@arm.com
43413996Sgiacomo.travaglini@arm.com#endif // __MEM_CACHE_MSHR_HH__
43513996Sgiacomo.travaglini@arm.com