mshr.hh revision 11375:f98df9231cdd
12SN/A/* 21762SN/A * Copyright (c) 2012-2013, 2015-2016 ARM Limited 32SN/A * All rights reserved. 42SN/A * 52SN/A * The license below extends only to copyright in the software and shall 62SN/A * not be construed as granting a license to any other intellectual 72SN/A * property including but not limited to intellectual property relating 82SN/A * to a hardware implementation of the functionality of the software 92SN/A * licensed hereunder. You may use the software subject to the license 102SN/A * terms below provided that you ensure that this notice is replicated 112SN/A * unmodified and in its entirety in all distributions of the software, 122SN/A * modified or unmodified, in source code or in binary form. 132SN/A * 142SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 152SN/A * All rights reserved. 162SN/A * 172SN/A * Redistribution and use in source and binary forms, with or without 182SN/A * modification, are permitted provided that the following conditions are 192SN/A * met: redistributions of source code must retain the above copyright 202SN/A * notice, this list of conditions and the following disclaimer; 212SN/A * redistributions in binary form must reproduce the above copyright 222SN/A * notice, this list of conditions and the following disclaimer in the 232SN/A * documentation and/or other materials provided with the distribution; 242SN/A * neither the name of the copyright holders nor the names of its 252SN/A * contributors may be used to endorse or promote products derived from 262SN/A * this software without specific prior written permission. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 302SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 311464SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 321464SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 332SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 342SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 352SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 372972Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 387680Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 396658Snate@binkert.org * 4056SN/A * Authors: Erik Hallnor 412439SN/A */ 4256SN/A 436216Snate@binkert.org/** 442410SN/A * @file 457678Sgblack@eecs.umich.edu * Miss Status and Handling Register (MSHR) declaration. 462SN/A */ 472SN/A 481061SN/A#ifndef __MEM_CACHE_MSHR_HH__ 492296SN/A#define __MEM_CACHE_MSHR_HH__ 502296SN/A 512680Sktlim@umich.edu#include <list> 52705SN/A 532623SN/A#include "base/printable.hh" 541464SN/A#include "mem/cache/queue_entry.hh" 555597Sgblack@eecs.umich.edu 565597Sgblack@eecs.umich.educlass Cache; 575597Sgblack@eecs.umich.edu 585865Sksewell@umich.edu/** 595865Sksewell@umich.edu * Miss Status and handling Register. This class keeps all the information 602296SN/A * needed to handle a cache miss including a list of target requests. 612312SN/A * @sa \ref gem5MemorySystem "gem5 Memory System" 62716SN/A */ 632623SN/Aclass MSHR : public QueueEntry, public Printable 642623SN/A{ 651128SN/A 662SN/A /** 674572Sacolyte@umich.edu * Consider the queues friends to avoid making everything public. 682SN/A */ 692SN/A template<typename Entry> 702SN/A friend class Queue; 712SN/A friend class MSHRQueue; 722SN/A 735677Sgblack@eecs.umich.edu private: 743271Sgblack@eecs.umich.edu 755665Sgblack@eecs.umich.edu /** Flag set by downstream caches */ 765665Sgblack@eecs.umich.edu bool downstreamPending; 775665Sgblack@eecs.umich.edu 785665Sgblack@eecs.umich.edu /** 795665Sgblack@eecs.umich.edu * Here we use one flag to track both if: 805665Sgblack@eecs.umich.edu * 815665Sgblack@eecs.umich.edu * 1. We are going to become owner or not, i.e., we will get the 825665Sgblack@eecs.umich.edu * block in an ownership state (Owned or Modified) with BlkDirty 835665Sgblack@eecs.umich.edu * set. This determines whether or not we are going to become the 845665Sgblack@eecs.umich.edu * responder and ordering point for future requests that we snoop. 855665Sgblack@eecs.umich.edu * 865665Sgblack@eecs.umich.edu * 2. We know that we are going to get a writable block, i.e. we 875665Sgblack@eecs.umich.edu * will get the block in writable state (Exclusive or Modified 885665Sgblack@eecs.umich.edu * state) with BlkWritable set. That determines whether additional 895665Sgblack@eecs.umich.edu * targets with needsWritable set will be able to be satisfied, or 905665Sgblack@eecs.umich.edu * if not should be put on the deferred list to possibly wait for 915665Sgblack@eecs.umich.edu * another request that does give us writable access. 925665Sgblack@eecs.umich.edu * 935665Sgblack@eecs.umich.edu * Condition 2 is actually just a shortcut that saves us from 945665Sgblack@eecs.umich.edu * possibly building a deferred target list and calling 952SN/A * promoteWritable() every time we get a writable block. Condition 962SN/A * 1, tracking ownership, is what is important. However, we never 972SN/A * receive ownership without marking the block dirty, and 982SN/A * consequently use pendingModified to track both ownership and 992SN/A * writability rather than having separate pendingDirty and 1002SN/A * pendingWritable flags. 1012SN/A */ 1022SN/A bool pendingModified; 1032SN/A 1042SN/A /** Did we snoop an invalidate while waiting for data? */ 1057619Sgblack@eecs.umich.edu bool postInvalidate; 1062SN/A 1072SN/A /** Did we snoop a read while waiting for data? */ 1082SN/A bool postDowngrade; 1092SN/A 1102SN/A public: 1112SN/A 1122SN/A /** True if the entry is just a simple forward from an upper level */ 1132SN/A bool isForward; 1142SN/A 1152SN/A class Target { 1162SN/A public: 117753SN/A 1182SN/A enum Source { 1192SN/A FromCPU, 1202SN/A FromSnoop, 121512SN/A FromPrefetcher 122512SN/A }; 123512SN/A 124512SN/A const Tick recvTime; //!< Time when request was received (for stats) 125512SN/A const Tick readyTime; //!< Time when request is ready to be serviced 126512SN/A const Counter order; //!< Global order (for memory consistency mgmt) 1272SN/A const PacketPtr pkt; //!< Pending request packet. 1282SN/A const Source source; //!< Request from cpu, memory, or prefetcher? 1295543Ssaidi@eecs.umich.edu const bool markedPending; //!< Did we mark upstream MSHR 1302SN/A //!< as downstreamPending? 1315543Ssaidi@eecs.umich.edu 1325543Ssaidi@eecs.umich.edu Target(PacketPtr _pkt, Tick _readyTime, Counter _order, 1332SN/A Source _source, bool _markedPending) 1345543Ssaidi@eecs.umich.edu : recvTime(curTick()), readyTime(_readyTime), order(_order), 1355543Ssaidi@eecs.umich.edu pkt(_pkt), source(_source), markedPending(_markedPending) 1365543Ssaidi@eecs.umich.edu {} 1372336SN/A }; 1385222Sksewell@umich.edu 1395543Ssaidi@eecs.umich.edu class TargetList : public std::list<Target> { 1405543Ssaidi@eecs.umich.edu 141593SN/A public: 1422SN/A bool needsWritable; 1435543Ssaidi@eecs.umich.edu bool hasUpgrade; 1445543Ssaidi@eecs.umich.edu 1455543Ssaidi@eecs.umich.edu TargetList(); 1465543Ssaidi@eecs.umich.edu void resetFlags() { needsWritable = hasUpgrade = false; } 1475543Ssaidi@eecs.umich.edu bool isReset() const { return !needsWritable && !hasUpgrade; } 1485543Ssaidi@eecs.umich.edu void add(PacketPtr pkt, Tick readyTime, Counter order, 1495543Ssaidi@eecs.umich.edu Target::Source source, bool markPending); 1502SN/A 1512135SN/A /** 1522135SN/A * Convert upgrades to the equivalent request if the cache line they 1535543Ssaidi@eecs.umich.edu * refer to would have been invalid (Upgrade -> ReadEx, SC* -> Fail). 154512SN/A * Used to rejig ordering between targets waiting on an MSHR. */ 1555543Ssaidi@eecs.umich.edu void replaceUpgrades(); 156512SN/A 1572103SN/A void clearDownstreamPending(); 1582103SN/A bool checkFunctional(PacketPtr pkt); 1595543Ssaidi@eecs.umich.edu void print(std::ostream &os, int verbosity, 1605543Ssaidi@eecs.umich.edu const std::string &prefix) const; 1615922Sgblack@eecs.umich.edu }; 1625222Sksewell@umich.edu 1632SN/A /** A list of MSHRs. */ 164725SN/A typedef std::list<MSHR *> List; 1652336SN/A /** MSHR list iterator. */ 1662227SN/A typedef List::iterator Iterator; 1672336SN/A 1682336SN/A /** Keep track of whether we should allocate on fill or not */ 169725SN/A bool allocOnFill; 1704828Sgblack@eecs.umich.edu 1714828Sgblack@eecs.umich.edu /** The pending* and post* flags are only valid if inService is 1724828Sgblack@eecs.umich.edu * true. Using the accessor functions lets us detect if these 1733271Sgblack@eecs.umich.edu * flags are accessed improperly. 1744539Sgblack@eecs.umich.edu */ 1755543Ssaidi@eecs.umich.edu 1765543Ssaidi@eecs.umich.edu /** True if we need to get a writable copy of the block. */ 1775543Ssaidi@eecs.umich.edu bool needsWritable() const { return targets.needsWritable; } 1785543Ssaidi@eecs.umich.edu 1793271Sgblack@eecs.umich.edu bool isPendingModified() const { 1805543Ssaidi@eecs.umich.edu assert(inService); return pendingModified; 1815222Sksewell@umich.edu } 1823271Sgblack@eecs.umich.edu 1832SN/A bool hasPostInvalidate() const { 1842SN/A assert(inService); return postInvalidate; 1852SN/A } 1867619Sgblack@eecs.umich.edu 1877619Sgblack@eecs.umich.edu bool hasPostDowngrade() const { 1882SN/A assert(inService); return postDowngrade; 1892SN/A } 1902SN/A 1912SN/A bool sendPacket(Cache &cache); 1922SN/A 1932SN/A private: 1942SN/A 1952SN/A /** 1962SN/A * Pointer to this MSHR on the ready list. 1972SN/A * @sa MissQueue, MSHRQueue::readyList 1982SN/A */ 1992SN/A Iterator readyIter; 2002SN/A 2012SN/A /** 2022SN/A * Pointer to this MSHR on the allocated list. 2032SN/A * @sa MissQueue, MSHRQueue::allocatedList 2042SN/A */ 2052SN/A Iterator allocIter; 2062SN/A 2072SN/A /** List of all requests that match the address */ 2082SN/A TargetList targets; 2092SN/A 2102SN/A TargetList deferredTargets; 2112SN/A 2122SN/A public: 2132SN/A 2142SN/A /** 2152SN/A * Allocate a miss to this MSHR. 2162SN/A * @param blk_addr The address of the block. 2172SN/A * @param blk_size The number of bytes to request. 2182SN/A * @param pkt The original miss. 2192SN/A * @param when_ready When should the MSHR be ready to act upon. 2202SN/A * @param _order The logical order of this MSHR 2212SN/A * @param alloc_on_fill Should the cache allocate a block on fill 2222SN/A */ 2232SN/A void allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt, 2242SN/A Tick when_ready, Counter _order, bool alloc_on_fill); 2252SN/A 2262SN/A void markInService(bool pending_modified_resp); 2272SN/A 2282SN/A void clearDownstreamPending(); 2292SN/A 2302SN/A /** 2312SN/A * Mark this MSHR as free. 2322SN/A */ 2332SN/A void deallocate(); 2342SN/A 2352SN/A /** 2362SN/A * Add a request to the list of targets. 2372SN/A * @param target The target. 2382SN/A */ 2392SN/A void allocateTarget(PacketPtr target, Tick when, Counter order, 2402SN/A bool alloc_on_fill); 2412SN/A bool handleSnoop(PacketPtr target, Counter order); 2425543Ssaidi@eecs.umich.edu 2432SN/A /** A simple constructor. */ 2445543Ssaidi@eecs.umich.edu MSHR(); 2455543Ssaidi@eecs.umich.edu 2465543Ssaidi@eecs.umich.edu /** 2475543Ssaidi@eecs.umich.edu * Returns the current number of allocated targets. 2482SN/A * @return The current number of allocated targets. 2492SN/A */ 250593SN/A int getNumTargets() const 2512SN/A { return targets.size() + deferredTargets.size(); } 2525543Ssaidi@eecs.umich.edu 2535543Ssaidi@eecs.umich.edu /** 2542SN/A * Returns true if there are targets left. 2555543Ssaidi@eecs.umich.edu * @return true if there are targets 2565543Ssaidi@eecs.umich.edu */ 2575543Ssaidi@eecs.umich.edu bool hasTargets() const { return !targets.empty(); } 2585543Ssaidi@eecs.umich.edu 2592SN/A /** 2605543Ssaidi@eecs.umich.edu * Returns a reference to the first target. 2615543Ssaidi@eecs.umich.edu * @return A pointer to the first target. 2622935Sksewell@umich.edu */ 2632SN/A Target *getTarget() 2642SN/A { 2652103SN/A assert(hasTargets()); 2662103SN/A return &targets.front(); 2672103SN/A } 2682103SN/A 2692103SN/A /** 270512SN/A * Pop first target. 271512SN/A */ 272725SN/A void popTarget() 2732296SN/A { 2742336SN/A targets.pop_front(); 2752312SN/A } 2764828Sgblack@eecs.umich.edu 2774539Sgblack@eecs.umich.edu bool promoteDeferredTargets(); 2784539Sgblack@eecs.umich.edu 2793271Sgblack@eecs.umich.edu void promoteWritable(); 2804539Sgblack@eecs.umich.edu 2814539Sgblack@eecs.umich.edu bool checkFunctional(PacketPtr pkt); 2823271Sgblack@eecs.umich.edu 2833271Sgblack@eecs.umich.edu /** 2842SN/A * Prints the contents of this MSHR for debugging. 2852SN/A */ 2865335Shines@cs.fsu.edu void print(std::ostream &os, 2872SN/A int verbosity = 0, 2882SN/A const std::string &prefix = "") const; 2892SN/A /** 2902SN/A * A no-args wrapper of print(std::ostream...) meant to be 2912SN/A * invoked from DPRINTFs avoiding string overheads in fast mode 2922SN/A * 2932SN/A * @return string with mshr fields + [deferred]targets 2942SN/A */ 2952SN/A std::string print() const; 2962SN/A}; 2972SN/A 2982SN/A#endif // __MEM_CACHE_MSHR_HH__ 2992SN/A