mshr.hh revision 7823
12810SN/A/* 22810SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 32810SN/A * All rights reserved. 42810SN/A * 52810SN/A * Redistribution and use in source and binary forms, with or without 62810SN/A * modification, are permitted provided that the following conditions are 72810SN/A * met: redistributions of source code must retain the above copyright 82810SN/A * notice, this list of conditions and the following disclaimer; 92810SN/A * redistributions in binary form must reproduce the above copyright 102810SN/A * notice, this list of conditions and the following disclaimer in the 112810SN/A * documentation and/or other materials provided with the distribution; 122810SN/A * neither the name of the copyright holders nor the names of its 132810SN/A * contributors may be used to endorse or promote products derived from 142810SN/A * this software without specific prior written permission. 152810SN/A * 162810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272810SN/A * 282810SN/A * Authors: Erik Hallnor 292810SN/A */ 302810SN/A 312810SN/A/** 322810SN/A * @file 332810SN/A * Miss Status and Handling Register (MSHR) declaration. 342810SN/A */ 352810SN/A 362810SN/A#ifndef __MSHR_HH__ 372810SN/A#define __MSHR_HH__ 382810SN/A 394626SN/A#include <list> 404626SN/A 415314SN/A#include "base/printable.hh" 422810SN/A#include "mem/packet.hh" 432810SN/A 444626SN/Aclass CacheBlk; 454626SN/Aclass MSHRQueue; 462810SN/A 472810SN/A/** 482810SN/A * Miss Status and handling Register. This class keeps all the information 493374SN/A * needed to handle a cache miss including a list of target requests. 502810SN/A */ 515314SN/Aclass MSHR : public Packet::SenderState, public Printable 524626SN/A{ 534626SN/A 542810SN/A public: 554626SN/A 564626SN/A class Target { 574626SN/A public: 585875Ssteve.reinhardt@amd.com 595875Ssteve.reinhardt@amd.com enum Source { 605875Ssteve.reinhardt@amd.com FromCPU, 615875Ssteve.reinhardt@amd.com FromSnoop, 625875Ssteve.reinhardt@amd.com FromPrefetcher 635875Ssteve.reinhardt@amd.com }; 645875Ssteve.reinhardt@amd.com 654871SN/A Tick recvTime; //!< Time when request was received (for stats) 664871SN/A Tick readyTime; //!< Time when request is ready to be serviced 674666SN/A Counter order; //!< Global order (for memory consistency mgmt) 684626SN/A PacketPtr pkt; //!< Pending request packet. 695875Ssteve.reinhardt@amd.com Source source; //!< Did request come from cpu, memory, or prefetcher? 705318SN/A bool markedPending; //!< Did we mark upstream MSHR 715318SN/A //!< as downstreamPending? 724626SN/A 735318SN/A Target(PacketPtr _pkt, Tick _readyTime, Counter _order, 745875Ssteve.reinhardt@amd.com Source _source, bool _markedPending) 757823Ssteve.reinhardt@amd.com : recvTime(curTick()), readyTime(_readyTime), order(_order), 765875Ssteve.reinhardt@amd.com pkt(_pkt), source(_source), markedPending(_markedPending) 774626SN/A {} 784626SN/A }; 794626SN/A 804903SN/A class TargetList : public std::list<Target> { 814903SN/A /** Target list iterator. */ 824903SN/A typedef std::list<Target>::iterator Iterator; 835314SN/A typedef std::list<Target>::const_iterator ConstIterator; 844903SN/A 854903SN/A public: 864903SN/A bool needsExclusive; 874903SN/A bool hasUpgrade; 884903SN/A 894903SN/A TargetList(); 904903SN/A void resetFlags() { needsExclusive = hasUpgrade = false; } 914903SN/A bool isReset() { return !needsExclusive && !hasUpgrade; } 925318SN/A void add(PacketPtr pkt, Tick readyTime, Counter order, 935875Ssteve.reinhardt@amd.com Target::Source source, bool markPending); 944903SN/A void replaceUpgrades(); 954908SN/A void clearDownstreamPending(); 964920SN/A bool checkFunctional(PacketPtr pkt); 975314SN/A void print(std::ostream &os, int verbosity, 985314SN/A const std::string &prefix) const; 994903SN/A }; 1004903SN/A 1012810SN/A /** A list of MSHRs. */ 1022810SN/A typedef std::list<MSHR *> List; 1032810SN/A /** MSHR list iterator. */ 1042810SN/A typedef List::iterator Iterator; 1052810SN/A /** MSHR list const_iterator. */ 1062810SN/A typedef List::const_iterator ConstIterator; 1072810SN/A 1084626SN/A /** Pointer to queue containing this MSHR. */ 1094626SN/A MSHRQueue *queue; 1104626SN/A 1114666SN/A /** Cycle when ready to issue */ 1124871SN/A Tick readyTime; 1134666SN/A 1144666SN/A /** Order number assigned by the miss queue. */ 1154666SN/A Counter order; 1164666SN/A 1174626SN/A /** Address of the request. */ 1182810SN/A Addr addr; 1194626SN/A 1204626SN/A /** Size of the request. */ 1214626SN/A int size; 1224626SN/A 1233374SN/A /** True if the request has been sent to the bus. */ 1242810SN/A bool inService; 1254626SN/A 1265730SSteve.Reinhardt@amd.com /** True if the request is just a simple forward from an upper level */ 1275730SSteve.Reinhardt@amd.com bool isForward; 1284903SN/A 1294626SN/A /** True if we need to get an exclusive copy of the block. */ 1305314SN/A bool needsExclusive() const { return targets->needsExclusive; } 1314665SN/A 1324626SN/A /** True if the request is uncacheable */ 1334626SN/A bool _isUncacheable; 1344626SN/A 1354908SN/A bool downstreamPending; 1364908SN/A 1377667Ssteve.reinhardt@amd.com /** The pending* and post* flags are only valid if inService is 1387667Ssteve.reinhardt@amd.com * true. Using the accessor functions lets us detect if these 1397667Ssteve.reinhardt@amd.com * flags are accessed improperly. 1407667Ssteve.reinhardt@amd.com */ 1417667Ssteve.reinhardt@amd.com 1427667Ssteve.reinhardt@amd.com /** Will we have a dirty copy after this request? */ 1437667Ssteve.reinhardt@amd.com bool pendingDirty; 1447667Ssteve.reinhardt@amd.com bool isPendingDirty() const { 1457667Ssteve.reinhardt@amd.com assert(inService); return pendingDirty; 1467667Ssteve.reinhardt@amd.com } 1477667Ssteve.reinhardt@amd.com 1487667Ssteve.reinhardt@amd.com /** Did we snoop an invalidate while waiting for data? */ 1497667Ssteve.reinhardt@amd.com bool postInvalidate; 1507667Ssteve.reinhardt@amd.com bool hasPostInvalidate() const { 1517667Ssteve.reinhardt@amd.com assert(inService); return postInvalidate; 1527667Ssteve.reinhardt@amd.com } 1537667Ssteve.reinhardt@amd.com 1547667Ssteve.reinhardt@amd.com /** Did we snoop a read while waiting for data? */ 1557667Ssteve.reinhardt@amd.com bool postDowngrade; 1567667Ssteve.reinhardt@amd.com bool hasPostDowngrade() const { 1577667Ssteve.reinhardt@amd.com assert(inService); return postDowngrade; 1587667Ssteve.reinhardt@amd.com } 1594665SN/A 1602810SN/A /** Thread number of the miss. */ 1616221Snate@binkert.org ThreadID threadNum; 1622810SN/A /** The number of currently allocated targets. */ 1636227Snate@binkert.org unsigned short ntargets; 1642810SN/A 1654668SN/A 1664668SN/A /** Data buffer (if needed). Currently used only for pending 1674668SN/A * upgrade handling. */ 1684668SN/A uint8_t *data; 1694668SN/A 1702810SN/A /** 1712810SN/A * Pointer to this MSHR on the ready list. 1722810SN/A * @sa MissQueue, MSHRQueue::readyList 1732810SN/A */ 1742810SN/A Iterator readyIter; 1754626SN/A 1762810SN/A /** 1772810SN/A * Pointer to this MSHR on the allocated list. 1782810SN/A * @sa MissQueue, MSHRQueue::allocatedList 1792810SN/A */ 1802810SN/A Iterator allocIter; 1812810SN/A 1822810SN/Aprivate: 1833374SN/A /** List of all requests that match the address */ 1844903SN/A TargetList *targets; 1852810SN/A 1864903SN/A TargetList *deferredTargets; 1874665SN/A 1882810SN/Apublic: 1894626SN/A 1904626SN/A bool isUncacheable() { return _isUncacheable; } 1914626SN/A 1922810SN/A /** 1932810SN/A * Allocate a miss to this MSHR. 1943374SN/A * @param cmd The requesting command. 1952810SN/A * @param addr The address of the miss. 1962810SN/A * @param asid The address space id of the miss. 1973374SN/A * @param size The number of bytes to request. 1982982SN/A * @param pkt The original miss. 1992810SN/A */ 2004666SN/A void allocate(Addr addr, int size, PacketPtr pkt, 2014666SN/A Tick when, Counter _order); 2022810SN/A 2037667Ssteve.reinhardt@amd.com bool markInService(PacketPtr pkt); 2044908SN/A 2055318SN/A void clearDownstreamPending(); 2065318SN/A 2072810SN/A /** 2082810SN/A * Mark this MSHR as free. 2092810SN/A */ 2102810SN/A void deallocate(); 2112810SN/A 2122810SN/A /** 2133374SN/A * Add a request to the list of targets. 2142810SN/A * @param target The target. 2152810SN/A */ 2164666SN/A void allocateTarget(PacketPtr target, Tick when, Counter order); 2174902SN/A bool handleSnoop(PacketPtr target, Counter order); 2182810SN/A 2192810SN/A /** A simple constructor. */ 2202810SN/A MSHR(); 2212810SN/A /** A simple destructor. */ 2222810SN/A ~MSHR(); 2232810SN/A 2242810SN/A /** 2252810SN/A * Returns the current number of allocated targets. 2262810SN/A * @return The current number of allocated targets. 2272810SN/A */ 2285730SSteve.Reinhardt@amd.com int getNumTargets() const { return ntargets; } 2292810SN/A 2302810SN/A /** 2312810SN/A * Returns a pointer to the target list. 2322810SN/A * @return a pointer to the target list. 2332810SN/A */ 2344903SN/A TargetList *getTargetList() { return targets; } 2352810SN/A 2362810SN/A /** 2374899SN/A * Returns true if there are targets left. 2384899SN/A * @return true if there are targets 2394899SN/A */ 2405730SSteve.Reinhardt@amd.com bool hasTargets() const { return !targets->empty(); } 2414899SN/A 2424899SN/A /** 2432810SN/A * Returns a reference to the first target. 2442810SN/A * @return A pointer to the first target. 2452810SN/A */ 2465730SSteve.Reinhardt@amd.com Target *getTarget() const 2475730SSteve.Reinhardt@amd.com { 2485730SSteve.Reinhardt@amd.com assert(hasTargets()); 2495730SSteve.Reinhardt@amd.com return &targets->front(); 2505730SSteve.Reinhardt@amd.com } 2512810SN/A 2522810SN/A /** 2532810SN/A * Pop first target. 2542810SN/A */ 2552810SN/A void popTarget() 2562810SN/A { 2572810SN/A --ntargets; 2584903SN/A targets->pop_front(); 2592810SN/A } 2602810SN/A 2615730SSteve.Reinhardt@amd.com bool isForwardNoResponse() const 2622810SN/A { 2634630SN/A if (getNumTargets() != 1) 2644630SN/A return false; 2654630SN/A Target *tgt = getTarget(); 2665875Ssteve.reinhardt@amd.com return tgt->source == Target::FromCPU && !tgt->pkt->needsResponse(); 2672810SN/A } 2682810SN/A 2694665SN/A bool promoteDeferredTargets(); 2704665SN/A 2714671SN/A void handleFill(Packet *pkt, CacheBlk *blk); 2724668SN/A 2735314SN/A bool checkFunctional(PacketPtr pkt); 2744920SN/A 2752810SN/A /** 2765314SN/A * Prints the contents of this MSHR for debugging. 2772810SN/A */ 2785314SN/A void print(std::ostream &os, 2795314SN/A int verbosity = 0, 2805314SN/A const std::string &prefix = "") const; 2812810SN/A}; 2822810SN/A 2832810SN/A#endif //__MSHR_HH__ 284