mshr.hh revision 12792
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(); 23712791Snikos.nikoleris@arm.com void clearDownstreamPending(iterator begin, iterator end); 2384920SN/A bool checkFunctional(PacketPtr pkt); 2395314SN/A void print(std::ostream &os, int verbosity, 2405314SN/A const std::string &prefix) const; 2414903SN/A }; 2424903SN/A 2432810SN/A /** A list of MSHRs. */ 2442810SN/A typedef std::list<MSHR *> List; 2452810SN/A /** MSHR list iterator. */ 2462810SN/A typedef List::iterator Iterator; 2474903SN/A 2487667Ssteve.reinhardt@amd.com /** The pending* and post* flags are only valid if inService is 2497667Ssteve.reinhardt@amd.com * true. Using the accessor functions lets us detect if these 2507667Ssteve.reinhardt@amd.com * flags are accessed improperly. 2517667Ssteve.reinhardt@amd.com */ 2527667Ssteve.reinhardt@amd.com 25311284Sandreas.hansson@arm.com /** True if we need to get a writable copy of the block. */ 25411284Sandreas.hansson@arm.com bool needsWritable() const { return targets.needsWritable; } 2559725Sandreas.hansson@arm.com 25612599Snikos.nikoleris@arm.com bool isCleaning() const { 25712599Snikos.nikoleris@arm.com PacketPtr pkt = targets.front().pkt; 25812599Snikos.nikoleris@arm.com return pkt->isClean(); 25912599Snikos.nikoleris@arm.com } 26012599Snikos.nikoleris@arm.com 26111284Sandreas.hansson@arm.com bool isPendingModified() const { 26211284Sandreas.hansson@arm.com assert(inService); return pendingModified; 2637667Ssteve.reinhardt@amd.com } 2647667Ssteve.reinhardt@amd.com 2657667Ssteve.reinhardt@amd.com bool hasPostInvalidate() const { 2667667Ssteve.reinhardt@amd.com assert(inService); return postInvalidate; 2677667Ssteve.reinhardt@amd.com } 2687667Ssteve.reinhardt@amd.com 2697667Ssteve.reinhardt@amd.com bool hasPostDowngrade() const { 2707667Ssteve.reinhardt@amd.com assert(inService); return postDowngrade; 2717667Ssteve.reinhardt@amd.com } 2724665SN/A 27312724Snikos.nikoleris@arm.com bool sendPacket(BaseCache &cache); 27411375Sandreas.hansson@arm.com 27511741Snikos.nikoleris@arm.com bool allocOnFill() const { 27611741Snikos.nikoleris@arm.com return targets.allocOnFill; 27711741Snikos.nikoleris@arm.com } 27812715Snikos.nikoleris@arm.com 27912715Snikos.nikoleris@arm.com /** 28012715Snikos.nikoleris@arm.com * Determine if there are non-deferred requests from other caches 28112715Snikos.nikoleris@arm.com * 28212715Snikos.nikoleris@arm.com * @return true if any of the targets is from another cache 28312715Snikos.nikoleris@arm.com */ 28412715Snikos.nikoleris@arm.com bool hasFromCache() const { 28512715Snikos.nikoleris@arm.com return targets.hasFromCache; 28612715Snikos.nikoleris@arm.com } 28712715Snikos.nikoleris@arm.com 2889725Sandreas.hansson@arm.com private: 2894668SN/A 2902810SN/A /** 2912810SN/A * Pointer to this MSHR on the ready list. 2922810SN/A * @sa MissQueue, MSHRQueue::readyList 2932810SN/A */ 2942810SN/A Iterator readyIter; 2954626SN/A 2962810SN/A /** 2972810SN/A * Pointer to this MSHR on the allocated list. 2982810SN/A * @sa MissQueue, MSHRQueue::allocatedList 2992810SN/A */ 3002810SN/A Iterator allocIter; 3012810SN/A 3023374SN/A /** List of all requests that match the address */ 3039725Sandreas.hansson@arm.com TargetList targets; 3042810SN/A 3059725Sandreas.hansson@arm.com TargetList deferredTargets; 3064665SN/A 3079725Sandreas.hansson@arm.com public: 3084626SN/A 3092810SN/A /** 3102810SN/A * Allocate a miss to this MSHR. 31110764Sandreas.hansson@arm.com * @param blk_addr The address of the block. 31210764Sandreas.hansson@arm.com * @param blk_size The number of bytes to request. 31310764Sandreas.hansson@arm.com * @param pkt The original miss. 31410764Sandreas.hansson@arm.com * @param when_ready When should the MSHR be ready to act upon. 31510764Sandreas.hansson@arm.com * @param _order The logical order of this MSHR 31611197Sandreas.hansson@arm.com * @param alloc_on_fill Should the cache allocate a block on fill 3172810SN/A */ 31810764Sandreas.hansson@arm.com void allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt, 31911197Sandreas.hansson@arm.com Tick when_ready, Counter _order, bool alloc_on_fill); 3202810SN/A 32111375Sandreas.hansson@arm.com void markInService(bool pending_modified_resp); 3224908SN/A 3235318SN/A void clearDownstreamPending(); 3245318SN/A 3252810SN/A /** 3262810SN/A * Mark this MSHR as free. 3272810SN/A */ 3282810SN/A void deallocate(); 3292810SN/A 3302810SN/A /** 3313374SN/A * Add a request to the list of targets. 3322810SN/A * @param target The target. 3332810SN/A */ 33411197Sandreas.hansson@arm.com void allocateTarget(PacketPtr target, Tick when, Counter order, 33511197Sandreas.hansson@arm.com bool alloc_on_fill); 3364902SN/A bool handleSnoop(PacketPtr target, Counter order); 3372810SN/A 3382810SN/A /** A simple constructor. */ 3392810SN/A MSHR(); 3402810SN/A 3412810SN/A /** 3422810SN/A * Returns the current number of allocated targets. 3432810SN/A * @return The current number of allocated targets. 3442810SN/A */ 3459725Sandreas.hansson@arm.com int getNumTargets() const 3469725Sandreas.hansson@arm.com { return targets.size() + deferredTargets.size(); } 3472810SN/A 3482810SN/A /** 34911742Snikos.nikoleris@arm.com * Extracts the subset of the targets that can be serviced given a 35011742Snikos.nikoleris@arm.com * received response. This function returns the targets list 35111742Snikos.nikoleris@arm.com * unless the response is a ReadRespWithInvalidate. The 35211742Snikos.nikoleris@arm.com * ReadRespWithInvalidate is only invalidating response that its 35311742Snikos.nikoleris@arm.com * invalidation was not expected when the request (a 35411742Snikos.nikoleris@arm.com * ReadSharedReq) was sent out. For ReadRespWithInvalidate we can 35511742Snikos.nikoleris@arm.com * safely service only the first FromCPU target and all FromSnoop 35611742Snikos.nikoleris@arm.com * targets (inform all snoopers that we no longer have the block). 35711742Snikos.nikoleris@arm.com * 35811742Snikos.nikoleris@arm.com * @param pkt The response from the downstream memory 35911742Snikos.nikoleris@arm.com */ 36011742Snikos.nikoleris@arm.com TargetList extractServiceableTargets(PacketPtr pkt); 36111742Snikos.nikoleris@arm.com 36211742Snikos.nikoleris@arm.com /** 3634899SN/A * Returns true if there are targets left. 3644899SN/A * @return true if there are targets 3654899SN/A */ 3669725Sandreas.hansson@arm.com bool hasTargets() const { return !targets.empty(); } 3674899SN/A 3684899SN/A /** 3692810SN/A * Returns a reference to the first target. 3702810SN/A * @return A pointer to the first target. 3712810SN/A */ 3729725Sandreas.hansson@arm.com Target *getTarget() 3735730SSteve.Reinhardt@amd.com { 3745730SSteve.Reinhardt@amd.com assert(hasTargets()); 3759725Sandreas.hansson@arm.com return &targets.front(); 3765730SSteve.Reinhardt@amd.com } 3772810SN/A 3782810SN/A /** 3792810SN/A * Pop first target. 3802810SN/A */ 3812810SN/A void popTarget() 3822810SN/A { 3839725Sandreas.hansson@arm.com targets.pop_front(); 3842810SN/A } 3852810SN/A 3864665SN/A bool promoteDeferredTargets(); 3874665SN/A 38812792Snikos.nikoleris@arm.com /** 38912792Snikos.nikoleris@arm.com * Promotes deferred targets that do not require writable 39012792Snikos.nikoleris@arm.com * 39112792Snikos.nikoleris@arm.com * Requests in the deferred target list are moved to the target 39212792Snikos.nikoleris@arm.com * list up until the first target that is a cache maintenance 39312792Snikos.nikoleris@arm.com * operation or needs a writable copy of the block 39412792Snikos.nikoleris@arm.com */ 39511284Sandreas.hansson@arm.com void promoteWritable(); 3964668SN/A 3975314SN/A bool checkFunctional(PacketPtr pkt); 3984920SN/A 3992810SN/A /** 4005314SN/A * Prints the contents of this MSHR for debugging. 4012810SN/A */ 4025314SN/A void print(std::ostream &os, 4035314SN/A int verbosity = 0, 4045314SN/A const std::string &prefix = "") const; 4059663Suri.wiener@arm.com /** 4069663Suri.wiener@arm.com * A no-args wrapper of print(std::ostream...) meant to be 4079663Suri.wiener@arm.com * invoked from DPRINTFs avoiding string overheads in fast mode 4089663Suri.wiener@arm.com * 4099663Suri.wiener@arm.com * @return string with mshr fields + [deferred]targets 4109663Suri.wiener@arm.com */ 4119663Suri.wiener@arm.com std::string print() const; 4122810SN/A}; 4132810SN/A 41410764Sandreas.hansson@arm.com#endif // __MEM_CACHE_MSHR_HH__ 415