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