mshr.hh revision 11357
12810SN/A/* 210764Sandreas.hansson@arm.com * Copyright (c) 2012-2013, 2015 ARM Limited 39663Suri.wiener@arm.com * All rights reserved. 49663Suri.wiener@arm.com * 59663Suri.wiener@arm.com * The license below extends only to copyright in the software and shall 69663Suri.wiener@arm.com * not be construed as granting a license to any other intellectual 79663Suri.wiener@arm.com * property including but not limited to intellectual property relating 89663Suri.wiener@arm.com * to a hardware implementation of the functionality of the software 99663Suri.wiener@arm.com * licensed hereunder. You may use the software subject to the license 109663Suri.wiener@arm.com * terms below provided that you ensure that this notice is replicated 119663Suri.wiener@arm.com * unmodified and in its entirety in all distributions of the software, 129663Suri.wiener@arm.com * modified or unmodified, in source code or in binary form. 139663Suri.wiener@arm.com * 142810SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 152810SN/A * All rights reserved. 162810SN/A * 172810SN/A * Redistribution and use in source and binary forms, with or without 182810SN/A * modification, are permitted provided that the following conditions are 192810SN/A * met: redistributions of source code must retain the above copyright 202810SN/A * notice, this list of conditions and the following disclaimer; 212810SN/A * redistributions in binary form must reproduce the above copyright 222810SN/A * notice, this list of conditions and the following disclaimer in the 232810SN/A * documentation and/or other materials provided with the distribution; 242810SN/A * neither the name of the copyright holders nor the names of its 252810SN/A * contributors may be used to endorse or promote products derived from 262810SN/A * this software without specific prior written permission. 272810SN/A * 282810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 312810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 322810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 332810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 342810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 352810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 372810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 382810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 392810SN/A * 402810SN/A * Authors: Erik Hallnor 412810SN/A */ 422810SN/A 432810SN/A/** 442810SN/A * @file 452810SN/A * Miss Status and Handling Register (MSHR) declaration. 462810SN/A */ 472810SN/A 4810764Sandreas.hansson@arm.com#ifndef __MEM_CACHE_MSHR_HH__ 4910764Sandreas.hansson@arm.com#define __MEM_CACHE_MSHR_HH__ 502810SN/A 514626SN/A#include <list> 524626SN/A 535314SN/A#include "base/printable.hh" 542810SN/A#include "mem/packet.hh" 552810SN/A 564626SN/Aclass CacheBlk; 574626SN/Aclass MSHRQueue; 582810SN/A 592810SN/A/** 602810SN/A * Miss Status and handling Register. This class keeps all the information 613374SN/A * needed to handle a cache miss including a list of target requests. 629264Sdjordje.kovacevic@arm.com * @sa \ref gem5MemorySystem "gem5 Memory System" 632810SN/A */ 645314SN/Aclass MSHR : public Packet::SenderState, public Printable 654626SN/A{ 664626SN/A 679725Sandreas.hansson@arm.com /** 689725Sandreas.hansson@arm.com * Consider the MSHRQueue a friend to avoid making everything public 699725Sandreas.hansson@arm.com */ 709725Sandreas.hansson@arm.com friend class MSHRQueue; 719725Sandreas.hansson@arm.com 729725Sandreas.hansson@arm.com private: 739725Sandreas.hansson@arm.com 749725Sandreas.hansson@arm.com /** Cycle when ready to issue */ 759725Sandreas.hansson@arm.com Tick readyTime; 769725Sandreas.hansson@arm.com 779725Sandreas.hansson@arm.com /** True if the request is uncacheable */ 789725Sandreas.hansson@arm.com bool _isUncacheable; 799725Sandreas.hansson@arm.com 809725Sandreas.hansson@arm.com /** Flag set by downstream caches */ 819725Sandreas.hansson@arm.com bool downstreamPending; 829725Sandreas.hansson@arm.com 8311284Sandreas.hansson@arm.com /** 8411284Sandreas.hansson@arm.com * Here we use one flag to track both if: 8511284Sandreas.hansson@arm.com * 8611284Sandreas.hansson@arm.com * 1. We are going to become owner or not, i.e., we will get the 8711284Sandreas.hansson@arm.com * block in an ownership state (Owned or Modified) with BlkDirty 8811284Sandreas.hansson@arm.com * set. This determines whether or not we are going to become the 8911284Sandreas.hansson@arm.com * responder and ordering point for future requests that we snoop. 9011284Sandreas.hansson@arm.com * 9111284Sandreas.hansson@arm.com * 2. We know that we are going to get a writable block, i.e. we 9211284Sandreas.hansson@arm.com * will get the block in writable state (Exclusive or Modified 9311284Sandreas.hansson@arm.com * state) with BlkWritable set. That determines whether additional 9411284Sandreas.hansson@arm.com * targets with needsWritable set will be able to be satisfied, or 9511284Sandreas.hansson@arm.com * if not should be put on the deferred list to possibly wait for 9611284Sandreas.hansson@arm.com * another request that does give us writable access. 9711284Sandreas.hansson@arm.com * 9811284Sandreas.hansson@arm.com * Condition 2 is actually just a shortcut that saves us from 9911284Sandreas.hansson@arm.com * possibly building a deferred target list and calling 10011284Sandreas.hansson@arm.com * promoteWritable() every time we get a writable block. Condition 10111284Sandreas.hansson@arm.com * 1, tracking ownership, is what is important. However, we never 10211284Sandreas.hansson@arm.com * receive ownership without marking the block dirty, and 10311284Sandreas.hansson@arm.com * consequently use pendingModified to track both ownership and 10411284Sandreas.hansson@arm.com * writability rather than having separate pendingDirty and 10511284Sandreas.hansson@arm.com * pendingWritable flags. 10611284Sandreas.hansson@arm.com */ 10711284Sandreas.hansson@arm.com bool pendingModified; 1089725Sandreas.hansson@arm.com 1099725Sandreas.hansson@arm.com /** Did we snoop an invalidate while waiting for data? */ 1109725Sandreas.hansson@arm.com bool postInvalidate; 1119725Sandreas.hansson@arm.com 1129725Sandreas.hansson@arm.com /** Did we snoop a read while waiting for data? */ 1139725Sandreas.hansson@arm.com bool postDowngrade; 1149725Sandreas.hansson@arm.com 1152810SN/A public: 1164626SN/A 1174626SN/A class Target { 1184626SN/A public: 1195875Ssteve.reinhardt@amd.com 1205875Ssteve.reinhardt@amd.com enum Source { 1215875Ssteve.reinhardt@amd.com FromCPU, 1225875Ssteve.reinhardt@amd.com FromSnoop, 1235875Ssteve.reinhardt@amd.com FromPrefetcher 1245875Ssteve.reinhardt@amd.com }; 1255875Ssteve.reinhardt@amd.com 12610766Sandreas.hansson@arm.com const Tick recvTime; //!< Time when request was received (for stats) 12710766Sandreas.hansson@arm.com const Tick readyTime; //!< Time when request is ready to be serviced 12810766Sandreas.hansson@arm.com const Counter order; //!< Global order (for memory consistency mgmt) 12910766Sandreas.hansson@arm.com const PacketPtr pkt; //!< Pending request packet. 13010766Sandreas.hansson@arm.com const Source source; //!< Request from cpu, memory, or prefetcher? 13110766Sandreas.hansson@arm.com const bool markedPending; //!< Did we mark upstream MSHR 13210766Sandreas.hansson@arm.com //!< as downstreamPending? 1334626SN/A 1345318SN/A Target(PacketPtr _pkt, Tick _readyTime, Counter _order, 1355875Ssteve.reinhardt@amd.com Source _source, bool _markedPending) 1367823Ssteve.reinhardt@amd.com : recvTime(curTick()), readyTime(_readyTime), order(_order), 1375875Ssteve.reinhardt@amd.com pkt(_pkt), source(_source), markedPending(_markedPending) 1384626SN/A {} 1394626SN/A }; 1404626SN/A 1414903SN/A class TargetList : public std::list<Target> { 1424903SN/A 1434903SN/A public: 14411284Sandreas.hansson@arm.com bool needsWritable; 1454903SN/A bool hasUpgrade; 1464903SN/A 1474903SN/A TargetList(); 14811284Sandreas.hansson@arm.com void resetFlags() { needsWritable = hasUpgrade = false; } 14911284Sandreas.hansson@arm.com bool isReset() const { return !needsWritable && !hasUpgrade; } 1505318SN/A void add(PacketPtr pkt, Tick readyTime, Counter order, 1515875Ssteve.reinhardt@amd.com Target::Source source, bool markPending); 15211357Sstephan.diestelhorst@arm.com 15311357Sstephan.diestelhorst@arm.com /** 15411357Sstephan.diestelhorst@arm.com * Convert upgrades to the equivalent request if the cache line they 15511357Sstephan.diestelhorst@arm.com * refer to would have been invalid (Upgrade -> ReadEx, SC* -> Fail). 15611357Sstephan.diestelhorst@arm.com * Used to rejig ordering between targets waiting on an MSHR. */ 1574903SN/A void replaceUpgrades(); 15811357Sstephan.diestelhorst@arm.com 1594908SN/A void clearDownstreamPending(); 1604920SN/A bool checkFunctional(PacketPtr pkt); 1615314SN/A void print(std::ostream &os, int verbosity, 1625314SN/A const std::string &prefix) const; 1634903SN/A }; 1644903SN/A 1652810SN/A /** A list of MSHRs. */ 1662810SN/A typedef std::list<MSHR *> List; 1672810SN/A /** MSHR list iterator. */ 1682810SN/A typedef List::iterator Iterator; 1692810SN/A /** MSHR list const_iterator. */ 1702810SN/A typedef List::const_iterator ConstIterator; 1712810SN/A 1724626SN/A /** Pointer to queue containing this MSHR. */ 1734626SN/A MSHRQueue *queue; 1744626SN/A 1754666SN/A /** Order number assigned by the miss queue. */ 1764666SN/A Counter order; 1774666SN/A 17810764Sandreas.hansson@arm.com /** Block aligned address of the MSHR. */ 17910764Sandreas.hansson@arm.com Addr blkAddr; 1804626SN/A 18110764Sandreas.hansson@arm.com /** Block size of the cache. */ 18210764Sandreas.hansson@arm.com unsigned blkSize; 1834626SN/A 18410028SGiacomo.Gabrielli@arm.com /** True if the request targets the secure memory space. */ 18510028SGiacomo.Gabrielli@arm.com bool isSecure; 18610028SGiacomo.Gabrielli@arm.com 1873374SN/A /** True if the request has been sent to the bus. */ 1882810SN/A bool inService; 1894626SN/A 1905730SSteve.Reinhardt@amd.com /** True if the request is just a simple forward from an upper level */ 1915730SSteve.Reinhardt@amd.com bool isForward; 1924903SN/A 19311197Sandreas.hansson@arm.com /** Keep track of whether we should allocate on fill or not */ 19411197Sandreas.hansson@arm.com bool allocOnFill; 19511197Sandreas.hansson@arm.com 1967667Ssteve.reinhardt@amd.com /** The pending* and post* flags are only valid if inService is 1977667Ssteve.reinhardt@amd.com * true. Using the accessor functions lets us detect if these 1987667Ssteve.reinhardt@amd.com * flags are accessed improperly. 1997667Ssteve.reinhardt@amd.com */ 2007667Ssteve.reinhardt@amd.com 20111284Sandreas.hansson@arm.com /** True if we need to get a writable copy of the block. */ 20211284Sandreas.hansson@arm.com bool needsWritable() const { return targets.needsWritable; } 2039725Sandreas.hansson@arm.com 20411284Sandreas.hansson@arm.com bool isPendingModified() const { 20511284Sandreas.hansson@arm.com assert(inService); return pendingModified; 2067667Ssteve.reinhardt@amd.com } 2077667Ssteve.reinhardt@amd.com 2087667Ssteve.reinhardt@amd.com bool hasPostInvalidate() const { 2097667Ssteve.reinhardt@amd.com assert(inService); return postInvalidate; 2107667Ssteve.reinhardt@amd.com } 2117667Ssteve.reinhardt@amd.com 2127667Ssteve.reinhardt@amd.com bool hasPostDowngrade() const { 2137667Ssteve.reinhardt@amd.com assert(inService); return postDowngrade; 2147667Ssteve.reinhardt@amd.com } 2154665SN/A 2169725Sandreas.hansson@arm.com private: 2174668SN/A 2184668SN/A /** Data buffer (if needed). Currently used only for pending 2194668SN/A * upgrade handling. */ 2204668SN/A uint8_t *data; 2214668SN/A 2222810SN/A /** 2232810SN/A * Pointer to this MSHR on the ready list. 2242810SN/A * @sa MissQueue, MSHRQueue::readyList 2252810SN/A */ 2262810SN/A Iterator readyIter; 2274626SN/A 2282810SN/A /** 2292810SN/A * Pointer to this MSHR on the allocated list. 2302810SN/A * @sa MissQueue, MSHRQueue::allocatedList 2312810SN/A */ 2322810SN/A Iterator allocIter; 2332810SN/A 2343374SN/A /** List of all requests that match the address */ 2359725Sandreas.hansson@arm.com TargetList targets; 2362810SN/A 2379725Sandreas.hansson@arm.com TargetList deferredTargets; 2384665SN/A 2399725Sandreas.hansson@arm.com public: 2404626SN/A 2419725Sandreas.hansson@arm.com bool isUncacheable() const { return _isUncacheable; } 2424626SN/A 2432810SN/A /** 2442810SN/A * Allocate a miss to this MSHR. 24510764Sandreas.hansson@arm.com * @param blk_addr The address of the block. 24610764Sandreas.hansson@arm.com * @param blk_size The number of bytes to request. 24710764Sandreas.hansson@arm.com * @param pkt The original miss. 24810764Sandreas.hansson@arm.com * @param when_ready When should the MSHR be ready to act upon. 24910764Sandreas.hansson@arm.com * @param _order The logical order of this MSHR 25011197Sandreas.hansson@arm.com * @param alloc_on_fill Should the cache allocate a block on fill 2512810SN/A */ 25210764Sandreas.hansson@arm.com void allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt, 25311197Sandreas.hansson@arm.com Tick when_ready, Counter _order, bool alloc_on_fill); 2542810SN/A 25511284Sandreas.hansson@arm.com bool markInService(bool pending_modified_resp); 2564908SN/A 2575318SN/A void clearDownstreamPending(); 2585318SN/A 2592810SN/A /** 2602810SN/A * Mark this MSHR as free. 2612810SN/A */ 2622810SN/A void deallocate(); 2632810SN/A 2642810SN/A /** 2653374SN/A * Add a request to the list of targets. 2662810SN/A * @param target The target. 2672810SN/A */ 26811197Sandreas.hansson@arm.com void allocateTarget(PacketPtr target, Tick when, Counter order, 26911197Sandreas.hansson@arm.com bool alloc_on_fill); 2704902SN/A bool handleSnoop(PacketPtr target, Counter order); 2712810SN/A 2722810SN/A /** A simple constructor. */ 2732810SN/A MSHR(); 2742810SN/A 2752810SN/A /** 2762810SN/A * Returns the current number of allocated targets. 2772810SN/A * @return The current number of allocated targets. 2782810SN/A */ 2799725Sandreas.hansson@arm.com int getNumTargets() const 2809725Sandreas.hansson@arm.com { return targets.size() + deferredTargets.size(); } 2812810SN/A 2822810SN/A /** 2834899SN/A * Returns true if there are targets left. 2844899SN/A * @return true if there are targets 2854899SN/A */ 2869725Sandreas.hansson@arm.com bool hasTargets() const { return !targets.empty(); } 2874899SN/A 2884899SN/A /** 2892810SN/A * Returns a reference to the first target. 2902810SN/A * @return A pointer to the first target. 2912810SN/A */ 2929725Sandreas.hansson@arm.com Target *getTarget() 2935730SSteve.Reinhardt@amd.com { 2945730SSteve.Reinhardt@amd.com assert(hasTargets()); 2959725Sandreas.hansson@arm.com return &targets.front(); 2965730SSteve.Reinhardt@amd.com } 2972810SN/A 2982810SN/A /** 2992810SN/A * Pop first target. 3002810SN/A */ 3012810SN/A void popTarget() 3022810SN/A { 3039725Sandreas.hansson@arm.com targets.pop_front(); 3042810SN/A } 3052810SN/A 3065730SSteve.Reinhardt@amd.com bool isForwardNoResponse() const 3072810SN/A { 3084630SN/A if (getNumTargets() != 1) 3094630SN/A return false; 3109725Sandreas.hansson@arm.com const Target *tgt = &targets.front(); 3115875Ssteve.reinhardt@amd.com return tgt->source == Target::FromCPU && !tgt->pkt->needsResponse(); 3122810SN/A } 3132810SN/A 3144665SN/A bool promoteDeferredTargets(); 3154665SN/A 31611284Sandreas.hansson@arm.com void promoteWritable(); 3174668SN/A 3185314SN/A bool checkFunctional(PacketPtr pkt); 3194920SN/A 3202810SN/A /** 3215314SN/A * Prints the contents of this MSHR for debugging. 3222810SN/A */ 3235314SN/A void print(std::ostream &os, 3245314SN/A int verbosity = 0, 3255314SN/A const std::string &prefix = "") const; 3269663Suri.wiener@arm.com /** 3279663Suri.wiener@arm.com * A no-args wrapper of print(std::ostream...) meant to be 3289663Suri.wiener@arm.com * invoked from DPRINTFs avoiding string overheads in fast mode 3299663Suri.wiener@arm.com * 3309663Suri.wiener@arm.com * @return string with mshr fields + [deferred]targets 3319663Suri.wiener@arm.com */ 3329663Suri.wiener@arm.com std::string print() const; 3332810SN/A}; 3342810SN/A 33510764Sandreas.hansson@arm.com#endif // __MEM_CACHE_MSHR_HH__ 336