mshr.cc revision 5318
17405SAli.Saidi@ARM.com/* 27405SAli.Saidi@ARM.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 37405SAli.Saidi@ARM.com * All rights reserved. 47405SAli.Saidi@ARM.com * 57405SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without 67405SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are 77405SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright 87405SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer; 97405SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright 107405SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the 117405SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution; 127405SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its 137405SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from 147405SAli.Saidi@ARM.com * this software without specific prior written permission. 157405SAli.Saidi@ARM.com * 167405SAli.Saidi@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177405SAli.Saidi@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187405SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197405SAli.Saidi@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207405SAli.Saidi@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 217405SAli.Saidi@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 227405SAli.Saidi@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237405SAli.Saidi@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247405SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257405SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 267405SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277405SAli.Saidi@ARM.com * 287405SAli.Saidi@ARM.com * Authors: Erik Hallnor 297405SAli.Saidi@ARM.com * Dave Greene 307405SAli.Saidi@ARM.com */ 317405SAli.Saidi@ARM.com 327405SAli.Saidi@ARM.com/** 337405SAli.Saidi@ARM.com * @file 347405SAli.Saidi@ARM.com * Miss Status and Handling Register (MSHR) definitions. 357405SAli.Saidi@ARM.com */ 367405SAli.Saidi@ARM.com 377405SAli.Saidi@ARM.com#include <assert.h> 387405SAli.Saidi@ARM.com#include <string> 397405SAli.Saidi@ARM.com#include <vector> 407405SAli.Saidi@ARM.com#include <algorithm> 417405SAli.Saidi@ARM.com 427405SAli.Saidi@ARM.com#include "mem/cache/miss/mshr.hh" 437405SAli.Saidi@ARM.com#include "sim/core.hh" // for curTick 447405SAli.Saidi@ARM.com#include "sim/host.hh" 457405SAli.Saidi@ARM.com#include "base/misc.hh" 467427Sgblack@eecs.umich.edu#include "mem/cache/cache.hh" 477427Sgblack@eecs.umich.edu 487427Sgblack@eecs.umich.eduusing namespace std; 497427Sgblack@eecs.umich.edu 507427Sgblack@eecs.umich.eduMSHR::MSHR() 517427Sgblack@eecs.umich.edu{ 527427Sgblack@eecs.umich.edu inService = false; 537427Sgblack@eecs.umich.edu ntargets = 0; 547427Sgblack@eecs.umich.edu threadNum = -1; 557427Sgblack@eecs.umich.edu targets = new TargetList(); 567427Sgblack@eecs.umich.edu deferredTargets = new TargetList(); 577427Sgblack@eecs.umich.edu} 587427Sgblack@eecs.umich.edu 597427Sgblack@eecs.umich.edu 607427Sgblack@eecs.umich.eduMSHR::TargetList::TargetList() 617427Sgblack@eecs.umich.edu : needsExclusive(false), hasUpgrade(false) 627427Sgblack@eecs.umich.edu{} 637427Sgblack@eecs.umich.edu 647427Sgblack@eecs.umich.edu 657427Sgblack@eecs.umich.eduinline void 667427Sgblack@eecs.umich.eduMSHR::TargetList::add(PacketPtr pkt, Tick readyTime, 677427Sgblack@eecs.umich.edu Counter order, bool cpuSide, bool markPending) 687427Sgblack@eecs.umich.edu{ 697427Sgblack@eecs.umich.edu if (cpuSide) { 707427Sgblack@eecs.umich.edu if (pkt->needsExclusive()) { 717427Sgblack@eecs.umich.edu needsExclusive = true; 727427Sgblack@eecs.umich.edu } 737427Sgblack@eecs.umich.edu 747427Sgblack@eecs.umich.edu if (pkt->cmd == MemCmd::UpgradeReq) { 757427Sgblack@eecs.umich.edu hasUpgrade = true; 767427Sgblack@eecs.umich.edu } 777427Sgblack@eecs.umich.edu } 787427Sgblack@eecs.umich.edu 797427Sgblack@eecs.umich.edu if (markPending) { 807427Sgblack@eecs.umich.edu MSHR *mshr = dynamic_cast<MSHR*>(pkt->senderState); 817427Sgblack@eecs.umich.edu if (mshr != NULL) { 827427Sgblack@eecs.umich.edu assert(!mshr->downstreamPending); 837427Sgblack@eecs.umich.edu mshr->downstreamPending = true; 847427Sgblack@eecs.umich.edu } 857427Sgblack@eecs.umich.edu } 867427Sgblack@eecs.umich.edu 877427Sgblack@eecs.umich.edu push_back(Target(pkt, readyTime, order, cpuSide, markPending)); 887427Sgblack@eecs.umich.edu} 897427Sgblack@eecs.umich.edu 907427Sgblack@eecs.umich.edu 917427Sgblack@eecs.umich.eduvoid 927427Sgblack@eecs.umich.eduMSHR::TargetList::replaceUpgrades() 937427Sgblack@eecs.umich.edu{ 947427Sgblack@eecs.umich.edu if (!hasUpgrade) 957427Sgblack@eecs.umich.edu return; 967427Sgblack@eecs.umich.edu 977427Sgblack@eecs.umich.edu Iterator end_i = end(); 987427Sgblack@eecs.umich.edu for (Iterator i = begin(); i != end_i; ++i) { 997427Sgblack@eecs.umich.edu if (i->pkt->cmd == MemCmd::UpgradeReq) { 1007427Sgblack@eecs.umich.edu i->pkt->cmd = MemCmd::ReadExReq; 1017427Sgblack@eecs.umich.edu DPRINTF(Cache, "Replacing UpgradeReq with ReadExReq\n"); 1027427Sgblack@eecs.umich.edu } 1037427Sgblack@eecs.umich.edu } 1047427Sgblack@eecs.umich.edu 1057427Sgblack@eecs.umich.edu hasUpgrade = false; 1067427Sgblack@eecs.umich.edu} 1077427Sgblack@eecs.umich.edu 1087427Sgblack@eecs.umich.edu 1097427Sgblack@eecs.umich.eduvoid 1107427Sgblack@eecs.umich.eduMSHR::TargetList::clearDownstreamPending() 1117427Sgblack@eecs.umich.edu{ 1127427Sgblack@eecs.umich.edu Iterator end_i = end(); 1137427Sgblack@eecs.umich.edu for (Iterator i = begin(); i != end_i; ++i) { 1147427Sgblack@eecs.umich.edu if (i->markedPending) { 1157427Sgblack@eecs.umich.edu MSHR *mshr = dynamic_cast<MSHR*>(i->pkt->senderState); 1167427Sgblack@eecs.umich.edu if (mshr != NULL) { 1177427Sgblack@eecs.umich.edu mshr->clearDownstreamPending(); 1187427Sgblack@eecs.umich.edu } 1197427Sgblack@eecs.umich.edu } 1207436Sdam.sunwoo@arm.com } 1217436Sdam.sunwoo@arm.com} 1227436Sdam.sunwoo@arm.com 1237436Sdam.sunwoo@arm.com 1247436Sdam.sunwoo@arm.combool 1257436Sdam.sunwoo@arm.comMSHR::TargetList::checkFunctional(PacketPtr pkt) 1267436Sdam.sunwoo@arm.com{ 1277436Sdam.sunwoo@arm.com Iterator end_i = end(); 1287436Sdam.sunwoo@arm.com for (Iterator i = begin(); i != end_i; ++i) { 1297436Sdam.sunwoo@arm.com if (pkt->checkFunctional(i->pkt)) { 1307436Sdam.sunwoo@arm.com return true; 1317436Sdam.sunwoo@arm.com } 1327436Sdam.sunwoo@arm.com } 1337436Sdam.sunwoo@arm.com 1347436Sdam.sunwoo@arm.com return false; 1357436Sdam.sunwoo@arm.com} 1367436Sdam.sunwoo@arm.com 1377436Sdam.sunwoo@arm.com 1387436Sdam.sunwoo@arm.comvoid 1397436Sdam.sunwoo@arm.comMSHR::TargetList:: 1407436Sdam.sunwoo@arm.comprint(std::ostream &os, int verbosity, const std::string &prefix) const 1417436Sdam.sunwoo@arm.com{ 1427436Sdam.sunwoo@arm.com ConstIterator end_i = end(); 1437436Sdam.sunwoo@arm.com for (ConstIterator i = begin(); i != end_i; ++i) { 1447436Sdam.sunwoo@arm.com ccprintf(os, "%s%s: ", prefix, i->isCpuSide() ? "cpu" : "mem"); 1457436Sdam.sunwoo@arm.com i->pkt->print(os, verbosity, ""); 1467436Sdam.sunwoo@arm.com } 1477436Sdam.sunwoo@arm.com} 1487436Sdam.sunwoo@arm.com 1497436Sdam.sunwoo@arm.com 1507436Sdam.sunwoo@arm.comvoid 1517436Sdam.sunwoo@arm.comMSHR::allocate(Addr _addr, int _size, PacketPtr target, 1527427Sgblack@eecs.umich.edu Tick whenReady, Counter _order) 1537427Sgblack@eecs.umich.edu{ 1547427Sgblack@eecs.umich.edu addr = _addr; 1557405SAli.Saidi@ARM.com size = _size; 1567405SAli.Saidi@ARM.com readyTime = whenReady; 1577405SAli.Saidi@ARM.com order = _order; 1587405SAli.Saidi@ARM.com assert(target); 1597405SAli.Saidi@ARM.com isCacheFill = false; 1607405SAli.Saidi@ARM.com _isUncacheable = target->req->isUncacheable(); 1617405SAli.Saidi@ARM.com inService = false; 1627405SAli.Saidi@ARM.com downstreamPending = false; 1637405SAli.Saidi@ARM.com threadNum = 0; 1647405SAli.Saidi@ARM.com ntargets = 1; 1657405SAli.Saidi@ARM.com // Don't know of a case where we would allocate a new MSHR for a 1667405SAli.Saidi@ARM.com // snoop (mem-side request), so set cpuSide to true here. 1677405SAli.Saidi@ARM.com assert(targets->isReset()); 1687405SAli.Saidi@ARM.com targets->add(target, whenReady, _order, true, true); 1697405SAli.Saidi@ARM.com assert(deferredTargets->isReset()); 1707405SAli.Saidi@ARM.com pendingInvalidate = false; 1717405SAli.Saidi@ARM.com pendingShared = false; 1727405SAli.Saidi@ARM.com data = NULL; 1737405SAli.Saidi@ARM.com} 1747405SAli.Saidi@ARM.com 1757405SAli.Saidi@ARM.com 1767405SAli.Saidi@ARM.comvoid 1777405SAli.Saidi@ARM.comMSHR::clearDownstreamPending() 1787405SAli.Saidi@ARM.com{ 1797405SAli.Saidi@ARM.com assert(downstreamPending); 1807405SAli.Saidi@ARM.com downstreamPending = false; 1817405SAli.Saidi@ARM.com // recursively clear flag on any MSHRs we will be forwarding 1827405SAli.Saidi@ARM.com // responses to 1837405SAli.Saidi@ARM.com targets->clearDownstreamPending(); 1847405SAli.Saidi@ARM.com} 1857405SAli.Saidi@ARM.com 1867405SAli.Saidi@ARM.combool 1877405SAli.Saidi@ARM.comMSHR::markInService() 1887405SAli.Saidi@ARM.com{ 1897405SAli.Saidi@ARM.com assert(!inService); 1907405SAli.Saidi@ARM.com if (isSimpleForward()) { 1917405SAli.Saidi@ARM.com // we just forwarded the request packet & don't expect a 1927405SAli.Saidi@ARM.com // response, so get rid of it 1937405SAli.Saidi@ARM.com assert(getNumTargets() == 1); 1947405SAli.Saidi@ARM.com popTarget(); 1957405SAli.Saidi@ARM.com return true; 1967405SAli.Saidi@ARM.com } 1977405SAli.Saidi@ARM.com inService = true; 1987405SAli.Saidi@ARM.com if (!downstreamPending) { 1997405SAli.Saidi@ARM.com // let upstream caches know that the request has made it to a 2007405SAli.Saidi@ARM.com // level where it's going to get a response 2017405SAli.Saidi@ARM.com targets->clearDownstreamPending(); 2027405SAli.Saidi@ARM.com } 2037405SAli.Saidi@ARM.com return false; 2047405SAli.Saidi@ARM.com} 2057405SAli.Saidi@ARM.com 2067405SAli.Saidi@ARM.com 2077405SAli.Saidi@ARM.comvoid 2087405SAli.Saidi@ARM.comMSHR::deallocate() 2097405SAli.Saidi@ARM.com{ 2107405SAli.Saidi@ARM.com assert(targets->empty()); 2117405SAli.Saidi@ARM.com targets->resetFlags(); 2127405SAli.Saidi@ARM.com assert(deferredTargets->isReset()); 2137405SAli.Saidi@ARM.com assert(ntargets == 0); 2147588SAli.Saidi@arm.com inService = false; 2157588SAli.Saidi@arm.com //allocIter = NULL; 2167588SAli.Saidi@arm.com //readyIter = NULL; 2177583SAli.Saidi@arm.com} 2187583SAli.Saidi@arm.com 2197583SAli.Saidi@arm.com/* 2207583SAli.Saidi@arm.com * Adds a target to an MSHR 2217583SAli.Saidi@arm.com */ 2227583SAli.Saidi@arm.comvoid 2237583SAli.Saidi@arm.comMSHR::allocateTarget(PacketPtr pkt, Tick whenReady, Counter _order) 2247583SAli.Saidi@arm.com{ 2257583SAli.Saidi@arm.com // if there's a request already in service for this MSHR, we will 2267583SAli.Saidi@arm.com // have to defer the new target until after the response if any of 2277583SAli.Saidi@arm.com // the following are true: 2287583SAli.Saidi@arm.com // - there are other targets already deferred 2297583SAli.Saidi@arm.com // - there's a pending invalidate to be applied after the response 2307583SAli.Saidi@arm.com // comes back (but before this target is processed) 2317405SAli.Saidi@ARM.com // - the outstanding request is for a non-exclusive block and this 2327405SAli.Saidi@ARM.com // target requires an exclusive block 2337405SAli.Saidi@ARM.com if (inService && 2347405SAli.Saidi@ARM.com (!deferredTargets->empty() || pendingInvalidate || 2357405SAli.Saidi@ARM.com (!targets->needsExclusive && pkt->needsExclusive()))) { 2367405SAli.Saidi@ARM.com // need to put on deferred list 2377405SAli.Saidi@ARM.com deferredTargets->add(pkt, whenReady, _order, true, true); 2387405SAli.Saidi@ARM.com } else { 2397405SAli.Saidi@ARM.com // No request outstanding, or still OK to append to 2407405SAli.Saidi@ARM.com // outstanding request: append to regular target list. Only 2417405SAli.Saidi@ARM.com // mark pending if current request hasn't been issued yet 2427405SAli.Saidi@ARM.com // (isn't in service). 2437405SAli.Saidi@ARM.com targets->add(pkt, whenReady, _order, true, !inService); 2447405SAli.Saidi@ARM.com } 2457405SAli.Saidi@ARM.com 2467405SAli.Saidi@ARM.com ++ntargets; 2477405SAli.Saidi@ARM.com} 2487405SAli.Saidi@ARM.com 2497405SAli.Saidi@ARM.combool 2507405SAli.Saidi@ARM.comMSHR::handleSnoop(PacketPtr pkt, Counter _order) 2517405SAli.Saidi@ARM.com{ 2527405SAli.Saidi@ARM.com if (!inService || (pkt->isExpressSnoop() && downstreamPending)) { 2537405SAli.Saidi@ARM.com // Request has not been issued yet, or it's been issued 2547405SAli.Saidi@ARM.com // locally but is buffered unissued at some downstream cache 2557405SAli.Saidi@ARM.com // which is forwarding us this snoop. Either way, the packet 2567405SAli.Saidi@ARM.com // we're snooping logically precedes this MSHR's request, so 2577405SAli.Saidi@ARM.com // the snoop has no impact on the MSHR, but must be processed 2587405SAli.Saidi@ARM.com // in the standard way by the cache. The only exception is 2597405SAli.Saidi@ARM.com // that if we're an L2+ cache buffering an UpgradeReq from a 2607405SAli.Saidi@ARM.com // higher-level cache, and the snoop is invalidating, then our 2617405SAli.Saidi@ARM.com // buffered upgrades must be converted to read exclusives, 2627405SAli.Saidi@ARM.com // since the upper-level cache no longer has a valid copy. 2637405SAli.Saidi@ARM.com // That is, even though the upper-level cache got out on its 2647405SAli.Saidi@ARM.com // local bus first, some other invalidating transaction 2657405SAli.Saidi@ARM.com // reached the global bus before the upgrade did. 2667405SAli.Saidi@ARM.com if (pkt->needsExclusive()) { 2677405SAli.Saidi@ARM.com targets->replaceUpgrades(); 2687405SAli.Saidi@ARM.com deferredTargets->replaceUpgrades(); 2697405SAli.Saidi@ARM.com } 2707405SAli.Saidi@ARM.com 2717405SAli.Saidi@ARM.com return false; 2727405SAli.Saidi@ARM.com } 2737405SAli.Saidi@ARM.com 2747405SAli.Saidi@ARM.com // From here on down, the request issued by this MSHR logically 2757405SAli.Saidi@ARM.com // precedes the request we're snooping. 2767405SAli.Saidi@ARM.com 2777405SAli.Saidi@ARM.com if (pkt->needsExclusive()) { 2787405SAli.Saidi@ARM.com // snooped request still precedes the re-request we'll have to 2797405SAli.Saidi@ARM.com // issue for deferred targets, if any... 2807405SAli.Saidi@ARM.com deferredTargets->replaceUpgrades(); 2817405SAli.Saidi@ARM.com } 2827405SAli.Saidi@ARM.com 2837405SAli.Saidi@ARM.com if (pendingInvalidate) { 2847405SAli.Saidi@ARM.com // a prior snoop has already appended an invalidation, so 2857405SAli.Saidi@ARM.com // logically we don't have the block anymore; no need for 2867405SAli.Saidi@ARM.com // further snooping. 2877408Sgblack@eecs.umich.edu return true; 2887405SAli.Saidi@ARM.com } 2897405SAli.Saidi@ARM.com 2907405SAli.Saidi@ARM.com if (targets->needsExclusive || pkt->needsExclusive()) { 2917408Sgblack@eecs.umich.edu // actual target device (typ. PhysicalMemory) will delete the 2927408Sgblack@eecs.umich.edu // packet on reception, so we need to save a copy here 2937408Sgblack@eecs.umich.edu PacketPtr cp_pkt = new Packet(pkt, true); 2947408Sgblack@eecs.umich.edu targets->add(cp_pkt, curTick, _order, false, 2957408Sgblack@eecs.umich.edu downstreamPending && targets->needsExclusive); 2967408Sgblack@eecs.umich.edu ++ntargets; 2977408Sgblack@eecs.umich.edu 2987408Sgblack@eecs.umich.edu if (targets->needsExclusive) { 2997408Sgblack@eecs.umich.edu // We're awaiting an exclusive copy, so ownership is pending. 3007408Sgblack@eecs.umich.edu // It's up to us to respond once the data arrives. 3017408Sgblack@eecs.umich.edu pkt->assertMemInhibit(); 3027408Sgblack@eecs.umich.edu pkt->setSupplyExclusive(); 3037405SAli.Saidi@ARM.com } else { 3047408Sgblack@eecs.umich.edu // Someone else may respond before we get around to 3057408Sgblack@eecs.umich.edu // processing this snoop, which means the copied request 3067408Sgblack@eecs.umich.edu // pointer will no longer be valid 3077408Sgblack@eecs.umich.edu cp_pkt->req = NULL; 3087408Sgblack@eecs.umich.edu } 3097408Sgblack@eecs.umich.edu 3107408Sgblack@eecs.umich.edu if (pkt->needsExclusive()) { 3117408Sgblack@eecs.umich.edu // This transaction will take away our pending copy 3127408Sgblack@eecs.umich.edu pendingInvalidate = true; 3137408Sgblack@eecs.umich.edu } 3147408Sgblack@eecs.umich.edu } else { 3157408Sgblack@eecs.umich.edu // Read to a read: no conflict, so no need to record as 3167408Sgblack@eecs.umich.edu // target, but make sure neither reader thinks he's getting an 3177408Sgblack@eecs.umich.edu // exclusive copy 3187408Sgblack@eecs.umich.edu pendingShared = true; 3197408Sgblack@eecs.umich.edu pkt->assertShared(); 3207408Sgblack@eecs.umich.edu } 3217408Sgblack@eecs.umich.edu 3227408Sgblack@eecs.umich.edu return true; 3237408Sgblack@eecs.umich.edu} 3247408Sgblack@eecs.umich.edu 3257408Sgblack@eecs.umich.edu 3267408Sgblack@eecs.umich.edubool 3277408Sgblack@eecs.umich.eduMSHR::promoteDeferredTargets() 3287408Sgblack@eecs.umich.edu{ 3297408Sgblack@eecs.umich.edu assert(targets->empty()); 3307408Sgblack@eecs.umich.edu if (deferredTargets->empty()) { 3317408Sgblack@eecs.umich.edu return false; 3327408Sgblack@eecs.umich.edu } 3337408Sgblack@eecs.umich.edu 3347408Sgblack@eecs.umich.edu // swap targets & deferredTargets lists 3357408Sgblack@eecs.umich.edu TargetList *tmp = targets; 3367408Sgblack@eecs.umich.edu targets = deferredTargets; 3377408Sgblack@eecs.umich.edu deferredTargets = tmp; 3387408Sgblack@eecs.umich.edu 3397408Sgblack@eecs.umich.edu assert(targets->size() == ntargets); 3407408Sgblack@eecs.umich.edu 3417408Sgblack@eecs.umich.edu // clear deferredTargets flags 3427408Sgblack@eecs.umich.edu deferredTargets->resetFlags(); 3437408Sgblack@eecs.umich.edu 3447408Sgblack@eecs.umich.edu pendingInvalidate = false; 3457408Sgblack@eecs.umich.edu pendingShared = false; 3467408Sgblack@eecs.umich.edu order = targets->front().order; 3477408Sgblack@eecs.umich.edu readyTime = std::max(curTick, targets->front().readyTime); 3487408Sgblack@eecs.umich.edu 3497408Sgblack@eecs.umich.edu return true; 3507408Sgblack@eecs.umich.edu} 3517408Sgblack@eecs.umich.edu 3527408Sgblack@eecs.umich.edu 3537408Sgblack@eecs.umich.eduvoid 3547408Sgblack@eecs.umich.eduMSHR::handleFill(Packet *pkt, CacheBlk *blk) 3557408Sgblack@eecs.umich.edu{ 3567408Sgblack@eecs.umich.edu if (pendingShared) { 3577408Sgblack@eecs.umich.edu // we snooped another read while this read was in 3587408Sgblack@eecs.umich.edu // service... assert shared line on its behalf 3597408Sgblack@eecs.umich.edu pkt->assertShared(); 3607408Sgblack@eecs.umich.edu } 3617408Sgblack@eecs.umich.edu 3627408Sgblack@eecs.umich.edu if (!pkt->sharedAsserted() && !pendingInvalidate 3637408Sgblack@eecs.umich.edu && deferredTargets->needsExclusive) { 3647408Sgblack@eecs.umich.edu // We got an exclusive response, but we have deferred targets 3657408Sgblack@eecs.umich.edu // which are waiting to request an exclusive copy (not because 3667408Sgblack@eecs.umich.edu // of a pending invalidate). This can happen if the original 3677408Sgblack@eecs.umich.edu // request was for a read-only (non-exclusive) block, but we 3687408Sgblack@eecs.umich.edu // got an exclusive copy anyway because of the E part of the 3697408Sgblack@eecs.umich.edu // MOESI/MESI protocol. Since we got the exclusive copy 3707408Sgblack@eecs.umich.edu // there's no need to defer the targets, so move them up to 3717408Sgblack@eecs.umich.edu // the regular target list. 3727408Sgblack@eecs.umich.edu assert(!targets->needsExclusive); 3737408Sgblack@eecs.umich.edu targets->needsExclusive = true; 3747408Sgblack@eecs.umich.edu // if any of the deferred targets were upper-level cache 3757408Sgblack@eecs.umich.edu // requests marked downstreamPending, need to clear that 3767408Sgblack@eecs.umich.edu assert(!downstreamPending); // not pending here anymore 3777408Sgblack@eecs.umich.edu deferredTargets->clearDownstreamPending(); 3787408Sgblack@eecs.umich.edu // this clears out deferredTargets too 3797408Sgblack@eecs.umich.edu targets->splice(targets->end(), *deferredTargets); 3807408Sgblack@eecs.umich.edu deferredTargets->resetFlags(); 3817408Sgblack@eecs.umich.edu } 3827408Sgblack@eecs.umich.edu} 3837408Sgblack@eecs.umich.edu 3847408Sgblack@eecs.umich.edu 3857408Sgblack@eecs.umich.edubool 3867408Sgblack@eecs.umich.eduMSHR::checkFunctional(PacketPtr pkt) 3877408Sgblack@eecs.umich.edu{ 3887408Sgblack@eecs.umich.edu // For printing, we treat the MSHR as a whole as single entity. 3897408Sgblack@eecs.umich.edu // For other requests, we iterate over the individual targets 3907408Sgblack@eecs.umich.edu // since that's where the actual data lies. 3917408Sgblack@eecs.umich.edu if (pkt->isPrint()) { 3927408Sgblack@eecs.umich.edu pkt->checkFunctional(this, addr, size, NULL); 3937408Sgblack@eecs.umich.edu return false; 3947408Sgblack@eecs.umich.edu } else { 3957408Sgblack@eecs.umich.edu return (targets->checkFunctional(pkt) || 3967408Sgblack@eecs.umich.edu deferredTargets->checkFunctional(pkt)); 3977408Sgblack@eecs.umich.edu } 3987408Sgblack@eecs.umich.edu} 3997408Sgblack@eecs.umich.edu 4007408Sgblack@eecs.umich.edu 4017408Sgblack@eecs.umich.eduvoid 4027408Sgblack@eecs.umich.eduMSHR::print(std::ostream &os, int verbosity, const std::string &prefix) const 4037408Sgblack@eecs.umich.edu{ 4047408Sgblack@eecs.umich.edu ccprintf(os, "%s[%x:%x] %s %s %s state: %s %s %s %s\n", 4057408Sgblack@eecs.umich.edu prefix, addr, addr+size-1, 4067408Sgblack@eecs.umich.edu isCacheFill ? "Fill" : "", 4077408Sgblack@eecs.umich.edu needsExclusive() ? "Excl" : "", 4087408Sgblack@eecs.umich.edu _isUncacheable ? "Unc" : "", 4097408Sgblack@eecs.umich.edu inService ? "InSvc" : "", 4107408Sgblack@eecs.umich.edu downstreamPending ? "DwnPend" : "", 4117408Sgblack@eecs.umich.edu pendingInvalidate ? "PendInv" : "", 4127405SAli.Saidi@ARM.com pendingShared ? "PendShared" : ""); 4137583SAli.Saidi@arm.com 4147583SAli.Saidi@arm.com ccprintf(os, "%s Targets:\n", prefix); 4157583SAli.Saidi@arm.com targets->print(os, verbosity, prefix + " "); 4167583SAli.Saidi@arm.com if (!deferredTargets->empty()) { 4177583SAli.Saidi@arm.com ccprintf(os, "%s Deferred Targets:\n", prefix); 4187583SAli.Saidi@arm.com deferredTargets->print(os, verbosity, prefix + " "); 4197583SAli.Saidi@arm.com } 4207583SAli.Saidi@arm.com} 4217583SAli.Saidi@arm.com 4227436Sdam.sunwoo@arm.comMSHR::~MSHR() 4237436Sdam.sunwoo@arm.com{ 4247436Sdam.sunwoo@arm.com} 4257436Sdam.sunwoo@arm.com