mshr.hh revision 10679
12810SN/A/* 29725Sandreas.hansson@arm.com * Copyright (c) 2012-2013 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 482810SN/A#ifndef __MSHR_HH__ 492810SN/A#define __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 839725Sandreas.hansson@arm.com /** Will we have a dirty copy after this request? */ 849725Sandreas.hansson@arm.com bool pendingDirty; 859725Sandreas.hansson@arm.com 869725Sandreas.hansson@arm.com /** Did we snoop an invalidate while waiting for data? */ 879725Sandreas.hansson@arm.com bool postInvalidate; 889725Sandreas.hansson@arm.com 899725Sandreas.hansson@arm.com /** Did we snoop a read while waiting for data? */ 909725Sandreas.hansson@arm.com bool postDowngrade; 919725Sandreas.hansson@arm.com 922810SN/A public: 934626SN/A 944626SN/A class Target { 954626SN/A public: 965875Ssteve.reinhardt@amd.com 975875Ssteve.reinhardt@amd.com enum Source { 985875Ssteve.reinhardt@amd.com FromCPU, 995875Ssteve.reinhardt@amd.com FromSnoop, 1005875Ssteve.reinhardt@amd.com FromPrefetcher 1015875Ssteve.reinhardt@amd.com }; 1025875Ssteve.reinhardt@amd.com 1034871SN/A Tick recvTime; //!< Time when request was received (for stats) 1044871SN/A Tick readyTime; //!< Time when request is ready to be serviced 1054666SN/A Counter order; //!< Global order (for memory consistency mgmt) 1064626SN/A PacketPtr pkt; //!< Pending request packet. 1075875Ssteve.reinhardt@amd.com Source source; //!< Did request come from cpu, memory, or prefetcher? 1085318SN/A bool markedPending; //!< Did we mark upstream MSHR 1095318SN/A //!< as downstreamPending? 1104626SN/A 1115318SN/A Target(PacketPtr _pkt, Tick _readyTime, Counter _order, 1125875Ssteve.reinhardt@amd.com Source _source, bool _markedPending) 1137823Ssteve.reinhardt@amd.com : recvTime(curTick()), readyTime(_readyTime), order(_order), 1145875Ssteve.reinhardt@amd.com pkt(_pkt), source(_source), markedPending(_markedPending) 1154626SN/A {} 1164626SN/A }; 1174626SN/A 1184903SN/A class TargetList : public std::list<Target> { 1194903SN/A /** Target list iterator. */ 1204903SN/A typedef std::list<Target>::iterator Iterator; 1215314SN/A typedef std::list<Target>::const_iterator ConstIterator; 1224903SN/A 1234903SN/A public: 1244903SN/A bool needsExclusive; 1254903SN/A bool hasUpgrade; 1264903SN/A 1274903SN/A TargetList(); 1284903SN/A void resetFlags() { needsExclusive = hasUpgrade = false; } 1294903SN/A bool isReset() { return !needsExclusive && !hasUpgrade; } 1305318SN/A void add(PacketPtr pkt, Tick readyTime, Counter order, 1315875Ssteve.reinhardt@amd.com Target::Source source, bool markPending); 1324903SN/A void replaceUpgrades(); 1334908SN/A void clearDownstreamPending(); 1344920SN/A bool checkFunctional(PacketPtr pkt); 1355314SN/A void print(std::ostream &os, int verbosity, 1365314SN/A const std::string &prefix) const; 1374903SN/A }; 1384903SN/A 1392810SN/A /** A list of MSHRs. */ 1402810SN/A typedef std::list<MSHR *> List; 1412810SN/A /** MSHR list iterator. */ 1422810SN/A typedef List::iterator Iterator; 1432810SN/A /** MSHR list const_iterator. */ 1442810SN/A typedef List::const_iterator ConstIterator; 1452810SN/A 1464626SN/A /** Pointer to queue containing this MSHR. */ 1474626SN/A MSHRQueue *queue; 1484626SN/A 1494666SN/A /** Order number assigned by the miss queue. */ 1504666SN/A Counter order; 1514666SN/A 1524626SN/A /** Address of the request. */ 1532810SN/A Addr addr; 1544626SN/A 1554626SN/A /** Size of the request. */ 1564626SN/A int size; 1574626SN/A 15810028SGiacomo.Gabrielli@arm.com /** True if the request targets the secure memory space. */ 15910028SGiacomo.Gabrielli@arm.com bool isSecure; 16010028SGiacomo.Gabrielli@arm.com 1613374SN/A /** True if the request has been sent to the bus. */ 1622810SN/A bool inService; 1634626SN/A 1645730SSteve.Reinhardt@amd.com /** True if the request is just a simple forward from an upper level */ 1655730SSteve.Reinhardt@amd.com bool isForward; 1664903SN/A 1677667Ssteve.reinhardt@amd.com /** The pending* and post* flags are only valid if inService is 1687667Ssteve.reinhardt@amd.com * true. Using the accessor functions lets us detect if these 1697667Ssteve.reinhardt@amd.com * flags are accessed improperly. 1707667Ssteve.reinhardt@amd.com */ 1717667Ssteve.reinhardt@amd.com 1729725Sandreas.hansson@arm.com /** True if we need to get an exclusive copy of the block. */ 1739725Sandreas.hansson@arm.com bool needsExclusive() const { return targets.needsExclusive; } 1749725Sandreas.hansson@arm.com 1757667Ssteve.reinhardt@amd.com bool isPendingDirty() const { 1767667Ssteve.reinhardt@amd.com assert(inService); return pendingDirty; 1777667Ssteve.reinhardt@amd.com } 1787667Ssteve.reinhardt@amd.com 1797667Ssteve.reinhardt@amd.com bool hasPostInvalidate() const { 1807667Ssteve.reinhardt@amd.com assert(inService); return postInvalidate; 1817667Ssteve.reinhardt@amd.com } 1827667Ssteve.reinhardt@amd.com 1837667Ssteve.reinhardt@amd.com bool hasPostDowngrade() const { 1847667Ssteve.reinhardt@amd.com assert(inService); return postDowngrade; 1857667Ssteve.reinhardt@amd.com } 1864665SN/A 1872810SN/A /** Thread number of the miss. */ 1886221Snate@binkert.org ThreadID threadNum; 1892810SN/A 1909725Sandreas.hansson@arm.com private: 1914668SN/A 1924668SN/A /** Data buffer (if needed). Currently used only for pending 1934668SN/A * upgrade handling. */ 1944668SN/A uint8_t *data; 1954668SN/A 1962810SN/A /** 1972810SN/A * Pointer to this MSHR on the ready list. 1982810SN/A * @sa MissQueue, MSHRQueue::readyList 1992810SN/A */ 2002810SN/A Iterator readyIter; 2014626SN/A 2022810SN/A /** 2032810SN/A * Pointer to this MSHR on the allocated list. 2042810SN/A * @sa MissQueue, MSHRQueue::allocatedList 2052810SN/A */ 2062810SN/A Iterator allocIter; 2072810SN/A 2083374SN/A /** List of all requests that match the address */ 2099725Sandreas.hansson@arm.com TargetList targets; 2102810SN/A 2119725Sandreas.hansson@arm.com TargetList deferredTargets; 2124665SN/A 2139725Sandreas.hansson@arm.com public: 2144626SN/A 2159725Sandreas.hansson@arm.com bool isUncacheable() const { return _isUncacheable; } 2164626SN/A 2172810SN/A /** 2182810SN/A * Allocate a miss to this MSHR. 2193374SN/A * @param cmd The requesting command. 2202810SN/A * @param addr The address of the miss. 2212810SN/A * @param asid The address space id of the miss. 2223374SN/A * @param size The number of bytes to request. 2232982SN/A * @param pkt The original miss. 2242810SN/A */ 2254666SN/A void allocate(Addr addr, int size, PacketPtr pkt, 2264666SN/A Tick when, Counter _order); 2272810SN/A 22810679Sandreas.hansson@arm.com bool markInService(bool pending_dirty_resp); 2294908SN/A 2305318SN/A void clearDownstreamPending(); 2315318SN/A 2322810SN/A /** 2332810SN/A * Mark this MSHR as free. 2342810SN/A */ 2352810SN/A void deallocate(); 2362810SN/A 2372810SN/A /** 2383374SN/A * Add a request to the list of targets. 2392810SN/A * @param target The target. 2402810SN/A */ 2414666SN/A void allocateTarget(PacketPtr target, Tick when, Counter order); 2424902SN/A bool handleSnoop(PacketPtr target, Counter order); 2432810SN/A 2442810SN/A /** A simple constructor. */ 2452810SN/A MSHR(); 2462810SN/A 2472810SN/A /** 2482810SN/A * Returns the current number of allocated targets. 2492810SN/A * @return The current number of allocated targets. 2502810SN/A */ 2519725Sandreas.hansson@arm.com int getNumTargets() const 2529725Sandreas.hansson@arm.com { return targets.size() + deferredTargets.size(); } 2532810SN/A 2542810SN/A /** 2554899SN/A * Returns true if there are targets left. 2564899SN/A * @return true if there are targets 2574899SN/A */ 2589725Sandreas.hansson@arm.com bool hasTargets() const { return !targets.empty(); } 2594899SN/A 2604899SN/A /** 2612810SN/A * Returns a reference to the first target. 2622810SN/A * @return A pointer to the first target. 2632810SN/A */ 2649725Sandreas.hansson@arm.com Target *getTarget() 2655730SSteve.Reinhardt@amd.com { 2665730SSteve.Reinhardt@amd.com assert(hasTargets()); 2679725Sandreas.hansson@arm.com return &targets.front(); 2685730SSteve.Reinhardt@amd.com } 2692810SN/A 2702810SN/A /** 2712810SN/A * Pop first target. 2722810SN/A */ 2732810SN/A void popTarget() 2742810SN/A { 2759725Sandreas.hansson@arm.com targets.pop_front(); 2762810SN/A } 2772810SN/A 2785730SSteve.Reinhardt@amd.com bool isForwardNoResponse() const 2792810SN/A { 2804630SN/A if (getNumTargets() != 1) 2814630SN/A return false; 2829725Sandreas.hansson@arm.com const Target *tgt = &targets.front(); 2835875Ssteve.reinhardt@amd.com return tgt->source == Target::FromCPU && !tgt->pkt->needsResponse(); 2842810SN/A } 2852810SN/A 2864665SN/A bool promoteDeferredTargets(); 2874665SN/A 2884671SN/A void handleFill(Packet *pkt, CacheBlk *blk); 2894668SN/A 2905314SN/A bool checkFunctional(PacketPtr pkt); 2914920SN/A 2922810SN/A /** 2935314SN/A * Prints the contents of this MSHR for debugging. 2942810SN/A */ 2955314SN/A void print(std::ostream &os, 2965314SN/A int verbosity = 0, 2975314SN/A const std::string &prefix = "") const; 2989663Suri.wiener@arm.com /** 2999663Suri.wiener@arm.com * A no-args wrapper of print(std::ostream...) meant to be 3009663Suri.wiener@arm.com * invoked from DPRINTFs avoiding string overheads in fast mode 3019663Suri.wiener@arm.com * 3029663Suri.wiener@arm.com * @return string with mshr fields + [deferred]targets 3039663Suri.wiener@arm.com */ 3049663Suri.wiener@arm.com std::string print() const; 3052810SN/A}; 3062810SN/A 3072810SN/A#endif //__MSHR_HH__ 308