mshr.hh revision 12727
12810SN/A/*
212599Snikos.nikoleris@arm.com * Copyright (c) 2012-2013, 2015-2016, 2018 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
5112727Snikos.nikoleris@arm.com#include <cassert>
5212727Snikos.nikoleris@arm.com#include <iosfwd>
534626SN/A#include <list>
5412727Snikos.nikoleris@arm.com#include <string>
554626SN/A
565314SN/A#include "base/printable.hh"
5712727Snikos.nikoleris@arm.com#include "base/types.hh"
5811375Sandreas.hansson@arm.com#include "mem/cache/queue_entry.hh"
5912727Snikos.nikoleris@arm.com#include "mem/packet.hh"
6012727Snikos.nikoleris@arm.com#include "sim/core.hh"
612810SN/A
6212724Snikos.nikoleris@arm.comclass BaseCache;
632810SN/A
642810SN/A/**
652810SN/A * Miss Status and handling Register. This class keeps all the information
663374SN/A * needed to handle a cache miss including a list of target requests.
679264Sdjordje.kovacevic@arm.com * @sa  \ref gem5MemorySystem "gem5 Memory System"
682810SN/A */
6911375Sandreas.hansson@arm.comclass MSHR : public QueueEntry, public Printable
704626SN/A{
714626SN/A
729725Sandreas.hansson@arm.com    /**
7311375Sandreas.hansson@arm.com     * Consider the queues friends to avoid making everything public.
749725Sandreas.hansson@arm.com     */
7511375Sandreas.hansson@arm.com    template<typename Entry>
7611375Sandreas.hansson@arm.com    friend class Queue;
779725Sandreas.hansson@arm.com    friend class MSHRQueue;
789725Sandreas.hansson@arm.com
799725Sandreas.hansson@arm.com  private:
809725Sandreas.hansson@arm.com
819725Sandreas.hansson@arm.com    /** Flag set by downstream caches */
829725Sandreas.hansson@arm.com    bool downstreamPending;
839725Sandreas.hansson@arm.com
8411284Sandreas.hansson@arm.com    /**
8511284Sandreas.hansson@arm.com     * Here we use one flag to track both if:
8611284Sandreas.hansson@arm.com     *
8711284Sandreas.hansson@arm.com     * 1. We are going to become owner or not, i.e., we will get the
8811284Sandreas.hansson@arm.com     * block in an ownership state (Owned or Modified) with BlkDirty
8911284Sandreas.hansson@arm.com     * set. This determines whether or not we are going to become the
9011284Sandreas.hansson@arm.com     * responder and ordering point for future requests that we snoop.
9111284Sandreas.hansson@arm.com     *
9211284Sandreas.hansson@arm.com     * 2. We know that we are going to get a writable block, i.e. we
9311284Sandreas.hansson@arm.com     * will get the block in writable state (Exclusive or Modified
9411284Sandreas.hansson@arm.com     * state) with BlkWritable set. That determines whether additional
9511284Sandreas.hansson@arm.com     * targets with needsWritable set will be able to be satisfied, or
9611284Sandreas.hansson@arm.com     * if not should be put on the deferred list to possibly wait for
9711284Sandreas.hansson@arm.com     * another request that does give us writable access.
9811284Sandreas.hansson@arm.com     *
9911284Sandreas.hansson@arm.com     * Condition 2 is actually just a shortcut that saves us from
10011284Sandreas.hansson@arm.com     * possibly building a deferred target list and calling
10111284Sandreas.hansson@arm.com     * promoteWritable() every time we get a writable block. Condition
10211284Sandreas.hansson@arm.com     * 1, tracking ownership, is what is important. However, we never
10311284Sandreas.hansson@arm.com     * receive ownership without marking the block dirty, and
10411284Sandreas.hansson@arm.com     * consequently use pendingModified to track both ownership and
10511284Sandreas.hansson@arm.com     * writability rather than having separate pendingDirty and
10611284Sandreas.hansson@arm.com     * pendingWritable flags.
10711284Sandreas.hansson@arm.com     */
10811284Sandreas.hansson@arm.com    bool pendingModified;
1099725Sandreas.hansson@arm.com
1109725Sandreas.hansson@arm.com    /** Did we snoop an invalidate while waiting for data? */
1119725Sandreas.hansson@arm.com    bool postInvalidate;
1129725Sandreas.hansson@arm.com
1139725Sandreas.hansson@arm.com    /** Did we snoop a read while waiting for data? */
1149725Sandreas.hansson@arm.com    bool postDowngrade;
1159725Sandreas.hansson@arm.com
1162810SN/A  public:
1174626SN/A
11811375Sandreas.hansson@arm.com    /** True if the entry is just a simple forward from an upper level */
11911375Sandreas.hansson@arm.com    bool isForward;
12011375Sandreas.hansson@arm.com
1214626SN/A    class Target {
1224626SN/A      public:
1235875Ssteve.reinhardt@amd.com
1245875Ssteve.reinhardt@amd.com        enum Source {
1255875Ssteve.reinhardt@amd.com            FromCPU,
1265875Ssteve.reinhardt@amd.com            FromSnoop,
1275875Ssteve.reinhardt@amd.com            FromPrefetcher
1285875Ssteve.reinhardt@amd.com        };
1295875Ssteve.reinhardt@amd.com
13010766Sandreas.hansson@arm.com        const Tick recvTime;  //!< Time when request was received (for stats)
13110766Sandreas.hansson@arm.com        const Tick readyTime; //!< Time when request is ready to be serviced
13210766Sandreas.hansson@arm.com        const Counter order;  //!< Global order (for memory consistency mgmt)
13310766Sandreas.hansson@arm.com        const PacketPtr pkt;  //!< Pending request packet.
13410766Sandreas.hansson@arm.com        const Source source;  //!< Request from cpu, memory, or prefetcher?
13511742Snikos.nikoleris@arm.com
13611742Snikos.nikoleris@arm.com        /**
13711742Snikos.nikoleris@arm.com         * We use this flag to track whether we have cleared the
13811742Snikos.nikoleris@arm.com         * downstreamPending flag for the MSHR of the cache above
13911742Snikos.nikoleris@arm.com         * where this packet originates from and guard noninitial
14011742Snikos.nikoleris@arm.com         * attempts to clear it.
14111742Snikos.nikoleris@arm.com         *
14211742Snikos.nikoleris@arm.com         * The flag markedPending needs to be updated when the
14311742Snikos.nikoleris@arm.com         * TargetList is in service which can be:
14411742Snikos.nikoleris@arm.com         * 1) during the Target instantiation if the MSHR is in
14511742Snikos.nikoleris@arm.com         * service and the target is not deferred,
14611742Snikos.nikoleris@arm.com         * 2) when the MSHR becomes in service if the target is not
14711742Snikos.nikoleris@arm.com         * deferred,
14811742Snikos.nikoleris@arm.com         * 3) or when the TargetList is promoted (deferredTargets ->
14911742Snikos.nikoleris@arm.com         * targets).
15011742Snikos.nikoleris@arm.com         */
15111742Snikos.nikoleris@arm.com        bool markedPending;
15211742Snikos.nikoleris@arm.com
15311741Snikos.nikoleris@arm.com        const bool allocOnFill;   //!< Should the response servicing this
15411741Snikos.nikoleris@arm.com                                  //!< target list allocate in the cache?
1554626SN/A
1565318SN/A        Target(PacketPtr _pkt, Tick _readyTime, Counter _order,
15711741Snikos.nikoleris@arm.com               Source _source, bool _markedPending, bool alloc_on_fill)
1587823Ssteve.reinhardt@amd.com            : recvTime(curTick()), readyTime(_readyTime), order(_order),
15911741Snikos.nikoleris@arm.com              pkt(_pkt), source(_source), markedPending(_markedPending),
16011741Snikos.nikoleris@arm.com              allocOnFill(alloc_on_fill)
1614626SN/A        {}
1624626SN/A    };
1634626SN/A
1644903SN/A    class TargetList : public std::list<Target> {
1654903SN/A
1664903SN/A      public:
16711284Sandreas.hansson@arm.com        bool needsWritable;
1684903SN/A        bool hasUpgrade;
16911741Snikos.nikoleris@arm.com        /** Set when the response should allocate on fill */
17011741Snikos.nikoleris@arm.com        bool allocOnFill;
17112715Snikos.nikoleris@arm.com        /**
17212715Snikos.nikoleris@arm.com         * Determine whether there was at least one non-snooping
17312715Snikos.nikoleris@arm.com         * target coming from another cache.
17412715Snikos.nikoleris@arm.com         */
17512715Snikos.nikoleris@arm.com        bool hasFromCache;
1764903SN/A
1774903SN/A        TargetList();
17811740Snikos.nikoleris@arm.com
17911740Snikos.nikoleris@arm.com        /**
18011740Snikos.nikoleris@arm.com         * Use the provided packet and the source to update the
18111740Snikos.nikoleris@arm.com         * flags of this TargetList.
18211740Snikos.nikoleris@arm.com         *
18311740Snikos.nikoleris@arm.com         * @param pkt Packet considered for the flag update
18411740Snikos.nikoleris@arm.com         * @param source Indicates the source of the packet
18511741Snikos.nikoleris@arm.com         * @param alloc_on_fill Whether the pkt would allocate on a fill
18611740Snikos.nikoleris@arm.com         */
18711741Snikos.nikoleris@arm.com        void updateFlags(PacketPtr pkt, Target::Source source,
18811741Snikos.nikoleris@arm.com                         bool alloc_on_fill);
18911740Snikos.nikoleris@arm.com
19012715Snikos.nikoleris@arm.com        void resetFlags() {
19112715Snikos.nikoleris@arm.com            needsWritable = false;
19212715Snikos.nikoleris@arm.com            hasUpgrade = false;
19312715Snikos.nikoleris@arm.com            allocOnFill = false;
19412715Snikos.nikoleris@arm.com            hasFromCache = false;
19512715Snikos.nikoleris@arm.com        }
19611740Snikos.nikoleris@arm.com
19711740Snikos.nikoleris@arm.com        /**
19811740Snikos.nikoleris@arm.com         * Goes through the list of targets and uses them to populate
19911740Snikos.nikoleris@arm.com         * the flags of this TargetList. When the function returns the
20011740Snikos.nikoleris@arm.com         * flags are consistent with the properties of packets in the
20111740Snikos.nikoleris@arm.com         * list.
20211740Snikos.nikoleris@arm.com         */
20311740Snikos.nikoleris@arm.com        void populateFlags();
20411740Snikos.nikoleris@arm.com
20511741Snikos.nikoleris@arm.com        /**
20611741Snikos.nikoleris@arm.com         * Tests if the flags of this TargetList have their default
20711741Snikos.nikoleris@arm.com         * values.
20811741Snikos.nikoleris@arm.com         */
20911741Snikos.nikoleris@arm.com        bool isReset() const {
21012715Snikos.nikoleris@arm.com            return !needsWritable && !hasUpgrade && !allocOnFill &&
21112715Snikos.nikoleris@arm.com                !hasFromCache;
21211741Snikos.nikoleris@arm.com        }
21311741Snikos.nikoleris@arm.com
21411741Snikos.nikoleris@arm.com        /**
21511741Snikos.nikoleris@arm.com         * Add the specified packet in the TargetList. This function
21611741Snikos.nikoleris@arm.com         * stores information related to the added packet and updates
21711741Snikos.nikoleris@arm.com         * accordingly the flags.
21811741Snikos.nikoleris@arm.com         *
21911741Snikos.nikoleris@arm.com         * @param pkt Packet considered for adding
22011741Snikos.nikoleris@arm.com         * @param readTime Tick at which the packet is processed by this cache
22111741Snikos.nikoleris@arm.com         * @param order A counter giving a unique id to each target
22211741Snikos.nikoleris@arm.com         * @param source Indicates the source agent of the packet
22311741Snikos.nikoleris@arm.com         * @param markPending Set for deferred targets or pending MSHRs
22411741Snikos.nikoleris@arm.com         * @param alloc_on_fill Whether it should allocate on a fill
22511741Snikos.nikoleris@arm.com         */
2265318SN/A        void add(PacketPtr pkt, Tick readyTime, Counter order,
22711741Snikos.nikoleris@arm.com                 Target::Source source, bool markPending,
22811741Snikos.nikoleris@arm.com                 bool alloc_on_fill);
22911357Sstephan.diestelhorst@arm.com
23011357Sstephan.diestelhorst@arm.com        /**
23111357Sstephan.diestelhorst@arm.com         * Convert upgrades to the equivalent request if the cache line they
23211357Sstephan.diestelhorst@arm.com         * refer to would have been invalid (Upgrade -> ReadEx, SC* -> Fail).
23311357Sstephan.diestelhorst@arm.com         * Used to rejig ordering between targets waiting on an MSHR. */
2344903SN/A        void replaceUpgrades();
23511357Sstephan.diestelhorst@arm.com
2364908SN/A        void clearDownstreamPending();
2374920SN/A        bool checkFunctional(PacketPtr pkt);
2385314SN/A        void print(std::ostream &os, int verbosity,
2395314SN/A                   const std::string &prefix) const;
2404903SN/A    };
2414903SN/A
2422810SN/A    /** A list of MSHRs. */
2432810SN/A    typedef std::list<MSHR *> List;
2442810SN/A    /** MSHR list iterator. */
2452810SN/A    typedef List::iterator Iterator;
2464903SN/A
2477667Ssteve.reinhardt@amd.com    /** The pending* and post* flags are only valid if inService is
2487667Ssteve.reinhardt@amd.com     *  true.  Using the accessor functions lets us detect if these
2497667Ssteve.reinhardt@amd.com     *  flags are accessed improperly.
2507667Ssteve.reinhardt@amd.com     */
2517667Ssteve.reinhardt@amd.com
25211284Sandreas.hansson@arm.com    /** True if we need to get a writable copy of the block. */
25311284Sandreas.hansson@arm.com    bool needsWritable() const { return targets.needsWritable; }
2549725Sandreas.hansson@arm.com
25512599Snikos.nikoleris@arm.com    bool isCleaning() const {
25612599Snikos.nikoleris@arm.com        PacketPtr pkt = targets.front().pkt;
25712599Snikos.nikoleris@arm.com        return pkt->isClean();
25812599Snikos.nikoleris@arm.com    }
25912599Snikos.nikoleris@arm.com
26011284Sandreas.hansson@arm.com    bool isPendingModified() const {
26111284Sandreas.hansson@arm.com        assert(inService); return pendingModified;
2627667Ssteve.reinhardt@amd.com    }
2637667Ssteve.reinhardt@amd.com
2647667Ssteve.reinhardt@amd.com    bool hasPostInvalidate() const {
2657667Ssteve.reinhardt@amd.com        assert(inService); return postInvalidate;
2667667Ssteve.reinhardt@amd.com    }
2677667Ssteve.reinhardt@amd.com
2687667Ssteve.reinhardt@amd.com    bool hasPostDowngrade() const {
2697667Ssteve.reinhardt@amd.com        assert(inService); return postDowngrade;
2707667Ssteve.reinhardt@amd.com    }
2714665SN/A
27212724Snikos.nikoleris@arm.com    bool sendPacket(BaseCache &cache);
27311375Sandreas.hansson@arm.com
27411741Snikos.nikoleris@arm.com    bool allocOnFill() const {
27511741Snikos.nikoleris@arm.com        return targets.allocOnFill;
27611741Snikos.nikoleris@arm.com    }
27712715Snikos.nikoleris@arm.com
27812715Snikos.nikoleris@arm.com    /**
27912715Snikos.nikoleris@arm.com     * Determine if there are non-deferred requests from other caches
28012715Snikos.nikoleris@arm.com     *
28112715Snikos.nikoleris@arm.com     * @return true if any of the targets is from another cache
28212715Snikos.nikoleris@arm.com     */
28312715Snikos.nikoleris@arm.com    bool hasFromCache() const {
28412715Snikos.nikoleris@arm.com        return targets.hasFromCache;
28512715Snikos.nikoleris@arm.com    }
28612715Snikos.nikoleris@arm.com
2879725Sandreas.hansson@arm.com  private:
2884668SN/A
2892810SN/A    /**
2902810SN/A     * Pointer to this MSHR on the ready list.
2912810SN/A     * @sa MissQueue, MSHRQueue::readyList
2922810SN/A     */
2932810SN/A    Iterator readyIter;
2944626SN/A
2952810SN/A    /**
2962810SN/A     * Pointer to this MSHR on the allocated list.
2972810SN/A     * @sa MissQueue, MSHRQueue::allocatedList
2982810SN/A     */
2992810SN/A    Iterator allocIter;
3002810SN/A
3013374SN/A    /** List of all requests that match the address */
3029725Sandreas.hansson@arm.com    TargetList targets;
3032810SN/A
3049725Sandreas.hansson@arm.com    TargetList deferredTargets;
3054665SN/A
3069725Sandreas.hansson@arm.com  public:
3074626SN/A
3082810SN/A    /**
3092810SN/A     * Allocate a miss to this MSHR.
31010764Sandreas.hansson@arm.com     * @param blk_addr The address of the block.
31110764Sandreas.hansson@arm.com     * @param blk_size The number of bytes to request.
31210764Sandreas.hansson@arm.com     * @param pkt The original miss.
31310764Sandreas.hansson@arm.com     * @param when_ready When should the MSHR be ready to act upon.
31410764Sandreas.hansson@arm.com     * @param _order The logical order of this MSHR
31511197Sandreas.hansson@arm.com     * @param alloc_on_fill Should the cache allocate a block on fill
3162810SN/A     */
31710764Sandreas.hansson@arm.com    void allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt,
31811197Sandreas.hansson@arm.com                  Tick when_ready, Counter _order, bool alloc_on_fill);
3192810SN/A
32011375Sandreas.hansson@arm.com    void markInService(bool pending_modified_resp);
3214908SN/A
3225318SN/A    void clearDownstreamPending();
3235318SN/A
3242810SN/A    /**
3252810SN/A     * Mark this MSHR as free.
3262810SN/A     */
3272810SN/A    void deallocate();
3282810SN/A
3292810SN/A    /**
3303374SN/A     * Add a request to the list of targets.
3312810SN/A     * @param target The target.
3322810SN/A     */
33311197Sandreas.hansson@arm.com    void allocateTarget(PacketPtr target, Tick when, Counter order,
33411197Sandreas.hansson@arm.com                        bool alloc_on_fill);
3354902SN/A    bool handleSnoop(PacketPtr target, Counter order);
3362810SN/A
3372810SN/A    /** A simple constructor. */
3382810SN/A    MSHR();
3392810SN/A
3402810SN/A    /**
3412810SN/A     * Returns the current number of allocated targets.
3422810SN/A     * @return The current number of allocated targets.
3432810SN/A     */
3449725Sandreas.hansson@arm.com    int getNumTargets() const
3459725Sandreas.hansson@arm.com    { return targets.size() + deferredTargets.size(); }
3462810SN/A
3472810SN/A    /**
34811742Snikos.nikoleris@arm.com     * Extracts the subset of the targets that can be serviced given a
34911742Snikos.nikoleris@arm.com     * received response. This function returns the targets list
35011742Snikos.nikoleris@arm.com     * unless the response is a ReadRespWithInvalidate. The
35111742Snikos.nikoleris@arm.com     * ReadRespWithInvalidate is only invalidating response that its
35211742Snikos.nikoleris@arm.com     * invalidation was not expected when the request (a
35311742Snikos.nikoleris@arm.com     * ReadSharedReq) was sent out. For ReadRespWithInvalidate we can
35411742Snikos.nikoleris@arm.com     * safely service only the first FromCPU target and all FromSnoop
35511742Snikos.nikoleris@arm.com     * targets (inform all snoopers that we no longer have the block).
35611742Snikos.nikoleris@arm.com     *
35711742Snikos.nikoleris@arm.com     * @param pkt The response from the downstream memory
35811742Snikos.nikoleris@arm.com     */
35911742Snikos.nikoleris@arm.com    TargetList extractServiceableTargets(PacketPtr pkt);
36011742Snikos.nikoleris@arm.com
36111742Snikos.nikoleris@arm.com    /**
3624899SN/A     * Returns true if there are targets left.
3634899SN/A     * @return true if there are targets
3644899SN/A     */
3659725Sandreas.hansson@arm.com    bool hasTargets() const { return !targets.empty(); }
3664899SN/A
3674899SN/A    /**
3682810SN/A     * Returns a reference to the first target.
3692810SN/A     * @return A pointer to the first target.
3702810SN/A     */
3719725Sandreas.hansson@arm.com    Target *getTarget()
3725730SSteve.Reinhardt@amd.com    {
3735730SSteve.Reinhardt@amd.com        assert(hasTargets());
3749725Sandreas.hansson@arm.com        return &targets.front();
3755730SSteve.Reinhardt@amd.com    }
3762810SN/A
3772810SN/A    /**
3782810SN/A     * Pop first target.
3792810SN/A     */
3802810SN/A    void popTarget()
3812810SN/A    {
3829725Sandreas.hansson@arm.com        targets.pop_front();
3832810SN/A    }
3842810SN/A
3854665SN/A    bool promoteDeferredTargets();
3864665SN/A
38711284Sandreas.hansson@arm.com    void promoteWritable();
3884668SN/A
3895314SN/A    bool checkFunctional(PacketPtr pkt);
3904920SN/A
3912810SN/A    /**
3925314SN/A     * Prints the contents of this MSHR for debugging.
3932810SN/A     */
3945314SN/A    void print(std::ostream &os,
3955314SN/A               int verbosity = 0,
3965314SN/A               const std::string &prefix = "") const;
3979663Suri.wiener@arm.com    /**
3989663Suri.wiener@arm.com     * A no-args wrapper of print(std::ostream...)  meant to be
3999663Suri.wiener@arm.com     * invoked from DPRINTFs avoiding string overheads in fast mode
4009663Suri.wiener@arm.com     *
4019663Suri.wiener@arm.com     * @return string with mshr fields + [deferred]targets
4029663Suri.wiener@arm.com     */
4039663Suri.wiener@arm.com    std::string print() const;
4042810SN/A};
4052810SN/A
40610764Sandreas.hansson@arm.com#endif // __MEM_CACHE_MSHR_HH__
407