mshr.cc revision 5318
19651SAndreas.Sandberg@ARM.com/*
29651SAndreas.Sandberg@ARM.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
39651SAndreas.Sandberg@ARM.com * All rights reserved.
49651SAndreas.Sandberg@ARM.com *
59651SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without
69651SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are
79651SAndreas.Sandberg@ARM.com * met: redistributions of source code must retain the above copyright
89651SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer;
99651SAndreas.Sandberg@ARM.com * redistributions in binary form must reproduce the above copyright
109651SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer in the
119651SAndreas.Sandberg@ARM.com * documentation and/or other materials provided with the distribution;
129651SAndreas.Sandberg@ARM.com * neither the name of the copyright holders nor the names of its
139651SAndreas.Sandberg@ARM.com * contributors may be used to endorse or promote products derived from
149651SAndreas.Sandberg@ARM.com * this software without specific prior written permission.
159651SAndreas.Sandberg@ARM.com *
169651SAndreas.Sandberg@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
179651SAndreas.Sandberg@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
189651SAndreas.Sandberg@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
199651SAndreas.Sandberg@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
209651SAndreas.Sandberg@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
219651SAndreas.Sandberg@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
229651SAndreas.Sandberg@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
239651SAndreas.Sandberg@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
249651SAndreas.Sandberg@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
259651SAndreas.Sandberg@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
269651SAndreas.Sandberg@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
279651SAndreas.Sandberg@ARM.com *
289651SAndreas.Sandberg@ARM.com * Authors: Erik Hallnor
299651SAndreas.Sandberg@ARM.com *          Dave Greene
309651SAndreas.Sandberg@ARM.com */
319651SAndreas.Sandberg@ARM.com
329651SAndreas.Sandberg@ARM.com/**
339651SAndreas.Sandberg@ARM.com * @file
349651SAndreas.Sandberg@ARM.com * Miss Status and Handling Register (MSHR) definitions.
359651SAndreas.Sandberg@ARM.com */
369651SAndreas.Sandberg@ARM.com
379651SAndreas.Sandberg@ARM.com#include <assert.h>
389651SAndreas.Sandberg@ARM.com#include <string>
399651SAndreas.Sandberg@ARM.com#include <vector>
409651SAndreas.Sandberg@ARM.com#include <algorithm>
419651SAndreas.Sandberg@ARM.com
429651SAndreas.Sandberg@ARM.com#include "mem/cache/miss/mshr.hh"
439651SAndreas.Sandberg@ARM.com#include "sim/core.hh" // for curTick
449651SAndreas.Sandberg@ARM.com#include "sim/host.hh"
459651SAndreas.Sandberg@ARM.com#include "base/misc.hh"
469651SAndreas.Sandberg@ARM.com#include "mem/cache/cache.hh"
479651SAndreas.Sandberg@ARM.com
489651SAndreas.Sandberg@ARM.comusing namespace std;
499651SAndreas.Sandberg@ARM.com
509651SAndreas.Sandberg@ARM.comMSHR::MSHR()
519683Sandreas@sandberg.pp.se{
529651SAndreas.Sandberg@ARM.com    inService = false;
539651SAndreas.Sandberg@ARM.com    ntargets = 0;
549651SAndreas.Sandberg@ARM.com    threadNum = -1;
559651SAndreas.Sandberg@ARM.com    targets = new TargetList();
569651SAndreas.Sandberg@ARM.com    deferredTargets = new TargetList();
579651SAndreas.Sandberg@ARM.com}
589651SAndreas.Sandberg@ARM.com
599651SAndreas.Sandberg@ARM.com
609651SAndreas.Sandberg@ARM.comMSHR::TargetList::TargetList()
619651SAndreas.Sandberg@ARM.com    : needsExclusive(false), hasUpgrade(false)
629651SAndreas.Sandberg@ARM.com{}
639651SAndreas.Sandberg@ARM.com
649651SAndreas.Sandberg@ARM.com
659651SAndreas.Sandberg@ARM.cominline void
669651SAndreas.Sandberg@ARM.comMSHR::TargetList::add(PacketPtr pkt, Tick readyTime,
679651SAndreas.Sandberg@ARM.com                      Counter order, bool cpuSide, bool markPending)
689651SAndreas.Sandberg@ARM.com{
699651SAndreas.Sandberg@ARM.com    if (cpuSide) {
709651SAndreas.Sandberg@ARM.com        if (pkt->needsExclusive()) {
719651SAndreas.Sandberg@ARM.com            needsExclusive = true;
729651SAndreas.Sandberg@ARM.com        }
739651SAndreas.Sandberg@ARM.com
749651SAndreas.Sandberg@ARM.com        if (pkt->cmd == MemCmd::UpgradeReq) {
759651SAndreas.Sandberg@ARM.com            hasUpgrade = true;
769652SAndreas.Sandberg@ARM.com        }
779652SAndreas.Sandberg@ARM.com    }
789651SAndreas.Sandberg@ARM.com
799651SAndreas.Sandberg@ARM.com    if (markPending) {
809651SAndreas.Sandberg@ARM.com        MSHR *mshr = dynamic_cast<MSHR*>(pkt->senderState);
819651SAndreas.Sandberg@ARM.com        if (mshr != NULL) {
829655SAndreas.Sandberg@ARM.com            assert(!mshr->downstreamPending);
839651SAndreas.Sandberg@ARM.com            mshr->downstreamPending = true;
849651SAndreas.Sandberg@ARM.com        }
859651SAndreas.Sandberg@ARM.com    }
869651SAndreas.Sandberg@ARM.com
879651SAndreas.Sandberg@ARM.com    push_back(Target(pkt, readyTime, order, cpuSide, markPending));
889651SAndreas.Sandberg@ARM.com}
899651SAndreas.Sandberg@ARM.com
909651SAndreas.Sandberg@ARM.com
919651SAndreas.Sandberg@ARM.comvoid
929651SAndreas.Sandberg@ARM.comMSHR::TargetList::replaceUpgrades()
939651SAndreas.Sandberg@ARM.com{
949651SAndreas.Sandberg@ARM.com    if (!hasUpgrade)
959651SAndreas.Sandberg@ARM.com        return;
969651SAndreas.Sandberg@ARM.com
979651SAndreas.Sandberg@ARM.com    Iterator end_i = end();
989655SAndreas.Sandberg@ARM.com    for (Iterator i = begin(); i != end_i; ++i) {
999655SAndreas.Sandberg@ARM.com        if (i->pkt->cmd == MemCmd::UpgradeReq) {
1009655SAndreas.Sandberg@ARM.com            i->pkt->cmd = MemCmd::ReadExReq;
1019655SAndreas.Sandberg@ARM.com            DPRINTF(Cache, "Replacing UpgradeReq with ReadExReq\n");
1029655SAndreas.Sandberg@ARM.com        }
1039655SAndreas.Sandberg@ARM.com    }
1049655SAndreas.Sandberg@ARM.com
1059655SAndreas.Sandberg@ARM.com    hasUpgrade = false;
1069655SAndreas.Sandberg@ARM.com}
1079651SAndreas.Sandberg@ARM.com
1089651SAndreas.Sandberg@ARM.com
1099651SAndreas.Sandberg@ARM.comvoid
1109651SAndreas.Sandberg@ARM.comMSHR::TargetList::clearDownstreamPending()
1119651SAndreas.Sandberg@ARM.com{
1129651SAndreas.Sandberg@ARM.com    Iterator end_i = end();
1139651SAndreas.Sandberg@ARM.com    for (Iterator i = begin(); i != end_i; ++i) {
1149651SAndreas.Sandberg@ARM.com        if (i->markedPending) {
1159651SAndreas.Sandberg@ARM.com            MSHR *mshr = dynamic_cast<MSHR*>(i->pkt->senderState);
1169651SAndreas.Sandberg@ARM.com            if (mshr != NULL) {
1179651SAndreas.Sandberg@ARM.com                mshr->clearDownstreamPending();
1189651SAndreas.Sandberg@ARM.com            }
1199651SAndreas.Sandberg@ARM.com        }
1209651SAndreas.Sandberg@ARM.com    }
1219651SAndreas.Sandberg@ARM.com}
1229651SAndreas.Sandberg@ARM.com
1239651SAndreas.Sandberg@ARM.com
1249651SAndreas.Sandberg@ARM.combool
1259651SAndreas.Sandberg@ARM.comMSHR::TargetList::checkFunctional(PacketPtr pkt)
1269651SAndreas.Sandberg@ARM.com{
1279651SAndreas.Sandberg@ARM.com    Iterator end_i = end();
1289651SAndreas.Sandberg@ARM.com    for (Iterator i = begin(); i != end_i; ++i) {
1299651SAndreas.Sandberg@ARM.com        if (pkt->checkFunctional(i->pkt)) {
1309651SAndreas.Sandberg@ARM.com            return true;
1319651SAndreas.Sandberg@ARM.com        }
1329651SAndreas.Sandberg@ARM.com    }
1339651SAndreas.Sandberg@ARM.com
1349651SAndreas.Sandberg@ARM.com    return false;
1359651SAndreas.Sandberg@ARM.com}
1369690Sandreas@sandberg.pp.se
1379690Sandreas@sandberg.pp.se
1389690Sandreas@sandberg.pp.sevoid
1399651SAndreas.Sandberg@ARM.comMSHR::TargetList::
1409651SAndreas.Sandberg@ARM.comprint(std::ostream &os, int verbosity, const std::string &prefix) const
1419651SAndreas.Sandberg@ARM.com{
1429651SAndreas.Sandberg@ARM.com    ConstIterator end_i = end();
1439651SAndreas.Sandberg@ARM.com    for (ConstIterator i = begin(); i != end_i; ++i) {
1449651SAndreas.Sandberg@ARM.com        ccprintf(os, "%s%s: ", prefix, i->isCpuSide() ? "cpu" : "mem");
1459651SAndreas.Sandberg@ARM.com        i->pkt->print(os, verbosity, "");
1469651SAndreas.Sandberg@ARM.com    }
1479651SAndreas.Sandberg@ARM.com}
1489651SAndreas.Sandberg@ARM.com
1499651SAndreas.Sandberg@ARM.com
1509651SAndreas.Sandberg@ARM.comvoid
1519651SAndreas.Sandberg@ARM.comMSHR::allocate(Addr _addr, int _size, PacketPtr target,
1529651SAndreas.Sandberg@ARM.com               Tick whenReady, Counter _order)
1539651SAndreas.Sandberg@ARM.com{
1549651SAndreas.Sandberg@ARM.com    addr = _addr;
1559651SAndreas.Sandberg@ARM.com    size = _size;
1569651SAndreas.Sandberg@ARM.com    readyTime = whenReady;
1579651SAndreas.Sandberg@ARM.com    order = _order;
1589651SAndreas.Sandberg@ARM.com    assert(target);
1599651SAndreas.Sandberg@ARM.com    isCacheFill = false;
1609651SAndreas.Sandberg@ARM.com    _isUncacheable = target->req->isUncacheable();
1619651SAndreas.Sandberg@ARM.com    inService = false;
1629651SAndreas.Sandberg@ARM.com    downstreamPending = false;
1639651SAndreas.Sandberg@ARM.com    threadNum = 0;
1649651SAndreas.Sandberg@ARM.com    ntargets = 1;
1659690Sandreas@sandberg.pp.se    // Don't know of a case where we would allocate a new MSHR for a
1669690Sandreas@sandberg.pp.se    // snoop (mem-side request), so set cpuSide to true here.
1679690Sandreas@sandberg.pp.se    assert(targets->isReset());
1689651SAndreas.Sandberg@ARM.com    targets->add(target, whenReady, _order, true, true);
1699651SAndreas.Sandberg@ARM.com    assert(deferredTargets->isReset());
1709651SAndreas.Sandberg@ARM.com    pendingInvalidate = false;
1719651SAndreas.Sandberg@ARM.com    pendingShared = false;
1729651SAndreas.Sandberg@ARM.com    data = NULL;
1739651SAndreas.Sandberg@ARM.com}
1749651SAndreas.Sandberg@ARM.com
1759651SAndreas.Sandberg@ARM.com
1769651SAndreas.Sandberg@ARM.comvoid
1779651SAndreas.Sandberg@ARM.comMSHR::clearDownstreamPending()
1789651SAndreas.Sandberg@ARM.com{
1799651SAndreas.Sandberg@ARM.com    assert(downstreamPending);
1809651SAndreas.Sandberg@ARM.com    downstreamPending = false;
1819651SAndreas.Sandberg@ARM.com    // recursively clear flag on any MSHRs we will be forwarding
1829651SAndreas.Sandberg@ARM.com    // responses to
1839684Sandreas@sandberg.pp.se    targets->clearDownstreamPending();
1849684Sandreas@sandberg.pp.se}
1859684Sandreas@sandberg.pp.se
1869684Sandreas@sandberg.pp.sebool
1879684Sandreas@sandberg.pp.seMSHR::markInService()
1889651SAndreas.Sandberg@ARM.com{
1899651SAndreas.Sandberg@ARM.com    assert(!inService);
1909651SAndreas.Sandberg@ARM.com    if (isSimpleForward()) {
1919651SAndreas.Sandberg@ARM.com        // we just forwarded the request packet & don't expect a
1929651SAndreas.Sandberg@ARM.com        // response, so get rid of it
1939651SAndreas.Sandberg@ARM.com        assert(getNumTargets() == 1);
1949651SAndreas.Sandberg@ARM.com        popTarget();
1959651SAndreas.Sandberg@ARM.com        return true;
1969651SAndreas.Sandberg@ARM.com    }
1979651SAndreas.Sandberg@ARM.com    inService = true;
1989651SAndreas.Sandberg@ARM.com    if (!downstreamPending) {
1999651SAndreas.Sandberg@ARM.com        // let upstream caches know that the request has made it to a
2009651SAndreas.Sandberg@ARM.com        // level where it's going to get a response
2019651SAndreas.Sandberg@ARM.com        targets->clearDownstreamPending();
2029651SAndreas.Sandberg@ARM.com    }
2039651SAndreas.Sandberg@ARM.com    return false;
2049651SAndreas.Sandberg@ARM.com}
2059651SAndreas.Sandberg@ARM.com
2069651SAndreas.Sandberg@ARM.com
2079651SAndreas.Sandberg@ARM.comvoid
2089651SAndreas.Sandberg@ARM.comMSHR::deallocate()
2099651SAndreas.Sandberg@ARM.com{
2109651SAndreas.Sandberg@ARM.com    assert(targets->empty());
2119651SAndreas.Sandberg@ARM.com    targets->resetFlags();
2129651SAndreas.Sandberg@ARM.com    assert(deferredTargets->isReset());
2139651SAndreas.Sandberg@ARM.com    assert(ntargets == 0);
2149651SAndreas.Sandberg@ARM.com    inService = false;
2159651SAndreas.Sandberg@ARM.com    //allocIter = NULL;
2169651SAndreas.Sandberg@ARM.com    //readyIter = NULL;
2179651SAndreas.Sandberg@ARM.com}
2189651SAndreas.Sandberg@ARM.com
2199651SAndreas.Sandberg@ARM.com/*
2209651SAndreas.Sandberg@ARM.com * Adds a target to an MSHR
2219651SAndreas.Sandberg@ARM.com */
2229651SAndreas.Sandberg@ARM.comvoid
2239651SAndreas.Sandberg@ARM.comMSHR::allocateTarget(PacketPtr pkt, Tick whenReady, Counter _order)
2249651SAndreas.Sandberg@ARM.com{
2259651SAndreas.Sandberg@ARM.com    // if there's a request already in service for this MSHR, we will
2269651SAndreas.Sandberg@ARM.com    // have to defer the new target until after the response if any of
2279683Sandreas@sandberg.pp.se    // the following are true:
2289683Sandreas@sandberg.pp.se    // - there are other targets already deferred
2299683Sandreas@sandberg.pp.se    // - there's a pending invalidate to be applied after the response
2309683Sandreas@sandberg.pp.se    //   comes back (but before this target is processed)
2319683Sandreas@sandberg.pp.se    // - the outstanding request is for a non-exclusive block and this
2329652SAndreas.Sandberg@ARM.com    //   target requires an exclusive block
2339652SAndreas.Sandberg@ARM.com    if (inService &&
2349652SAndreas.Sandberg@ARM.com        (!deferredTargets->empty() || pendingInvalidate ||
2359651SAndreas.Sandberg@ARM.com         (!targets->needsExclusive && pkt->needsExclusive()))) {
2369651SAndreas.Sandberg@ARM.com        // need to put on deferred list
2379651SAndreas.Sandberg@ARM.com        deferredTargets->add(pkt, whenReady, _order, true, true);
2389651SAndreas.Sandberg@ARM.com    } else {
2399651SAndreas.Sandberg@ARM.com        // No request outstanding, or still OK to append to
2409651SAndreas.Sandberg@ARM.com        // outstanding request: append to regular target list.  Only
2419651SAndreas.Sandberg@ARM.com        // mark pending if current request hasn't been issued yet
2429651SAndreas.Sandberg@ARM.com        // (isn't in service).
2439651SAndreas.Sandberg@ARM.com        targets->add(pkt, whenReady, _order, true, !inService);
2449683Sandreas@sandberg.pp.se    }
2459683Sandreas@sandberg.pp.se
2469651SAndreas.Sandberg@ARM.com    ++ntargets;
2479651SAndreas.Sandberg@ARM.com}
2489651SAndreas.Sandberg@ARM.com
2499652SAndreas.Sandberg@ARM.combool
2509651SAndreas.Sandberg@ARM.comMSHR::handleSnoop(PacketPtr pkt, Counter _order)
2519651SAndreas.Sandberg@ARM.com{
2529651SAndreas.Sandberg@ARM.com    if (!inService || (pkt->isExpressSnoop() && downstreamPending)) {
2539651SAndreas.Sandberg@ARM.com        // Request has not been issued yet, or it's been issued
2549651SAndreas.Sandberg@ARM.com        // locally but is buffered unissued at some downstream cache
2559651SAndreas.Sandberg@ARM.com        // which is forwarding us this snoop.  Either way, the packet
2569651SAndreas.Sandberg@ARM.com        // we're snooping logically precedes this MSHR's request, so
2579651SAndreas.Sandberg@ARM.com        // the snoop has no impact on the MSHR, but must be processed
2589651SAndreas.Sandberg@ARM.com        // in the standard way by the cache.  The only exception is
2599651SAndreas.Sandberg@ARM.com        // that if we're an L2+ cache buffering an UpgradeReq from a
2609651SAndreas.Sandberg@ARM.com        // higher-level cache, and the snoop is invalidating, then our
2619651SAndreas.Sandberg@ARM.com        // buffered upgrades must be converted to read exclusives,
2629651SAndreas.Sandberg@ARM.com        // since the upper-level cache no longer has a valid copy.
2639651SAndreas.Sandberg@ARM.com        // That is, even though the upper-level cache got out on its
2649651SAndreas.Sandberg@ARM.com        // local bus first, some other invalidating transaction
2659651SAndreas.Sandberg@ARM.com        // reached the global bus before the upgrade did.
2669651SAndreas.Sandberg@ARM.com        if (pkt->needsExclusive()) {
2679651SAndreas.Sandberg@ARM.com            targets->replaceUpgrades();
2689651SAndreas.Sandberg@ARM.com            deferredTargets->replaceUpgrades();
2699651SAndreas.Sandberg@ARM.com        }
2709651SAndreas.Sandberg@ARM.com
2719651SAndreas.Sandberg@ARM.com        return false;
2729651SAndreas.Sandberg@ARM.com    }
2739651SAndreas.Sandberg@ARM.com
2749651SAndreas.Sandberg@ARM.com    // From here on down, the request issued by this MSHR logically
2759651SAndreas.Sandberg@ARM.com    // precedes the request we're snooping.
2769651SAndreas.Sandberg@ARM.com
2779651SAndreas.Sandberg@ARM.com    if (pkt->needsExclusive()) {
2789651SAndreas.Sandberg@ARM.com        // snooped request still precedes the re-request we'll have to
2799651SAndreas.Sandberg@ARM.com        // issue for deferred targets, if any...
2809651SAndreas.Sandberg@ARM.com        deferredTargets->replaceUpgrades();
2819651SAndreas.Sandberg@ARM.com    }
2829651SAndreas.Sandberg@ARM.com
2839651SAndreas.Sandberg@ARM.com    if (pendingInvalidate) {
2849651SAndreas.Sandberg@ARM.com        // a prior snoop has already appended an invalidation, so
2859651SAndreas.Sandberg@ARM.com        // logically we don't have the block anymore; no need for
2869651SAndreas.Sandberg@ARM.com        // further snooping.
2879651SAndreas.Sandberg@ARM.com        return true;
2889651SAndreas.Sandberg@ARM.com    }
2899651SAndreas.Sandberg@ARM.com
2909651SAndreas.Sandberg@ARM.com    if (targets->needsExclusive || pkt->needsExclusive()) {
2919651SAndreas.Sandberg@ARM.com        // actual target device (typ. PhysicalMemory) will delete the
2929651SAndreas.Sandberg@ARM.com        // packet on reception, so we need to save a copy here
2939651SAndreas.Sandberg@ARM.com        PacketPtr cp_pkt = new Packet(pkt, true);
2949651SAndreas.Sandberg@ARM.com        targets->add(cp_pkt, curTick, _order, false,
2959652SAndreas.Sandberg@ARM.com                     downstreamPending && targets->needsExclusive);
2969652SAndreas.Sandberg@ARM.com        ++ntargets;
2979652SAndreas.Sandberg@ARM.com
2989652SAndreas.Sandberg@ARM.com        if (targets->needsExclusive) {
2999652SAndreas.Sandberg@ARM.com            // We're awaiting an exclusive copy, so ownership is pending.
3009652SAndreas.Sandberg@ARM.com            // It's up to us to respond once the data arrives.
3019651SAndreas.Sandberg@ARM.com            pkt->assertMemInhibit();
3029651SAndreas.Sandberg@ARM.com            pkt->setSupplyExclusive();
3039651SAndreas.Sandberg@ARM.com        } else {
3049651SAndreas.Sandberg@ARM.com            // Someone else may respond before we get around to
3059651SAndreas.Sandberg@ARM.com            // processing this snoop, which means the copied request
3069651SAndreas.Sandberg@ARM.com            // pointer will no longer be valid
3079651SAndreas.Sandberg@ARM.com            cp_pkt->req = NULL;
3089651SAndreas.Sandberg@ARM.com        }
3099651SAndreas.Sandberg@ARM.com
3109651SAndreas.Sandberg@ARM.com        if (pkt->needsExclusive()) {
3119651SAndreas.Sandberg@ARM.com            // This transaction will take away our pending copy
3129651SAndreas.Sandberg@ARM.com            pendingInvalidate = true;
3139651SAndreas.Sandberg@ARM.com        }
3149651SAndreas.Sandberg@ARM.com    } else {
3159651SAndreas.Sandberg@ARM.com        // Read to a read: no conflict, so no need to record as
3169651SAndreas.Sandberg@ARM.com        // target, but make sure neither reader thinks he's getting an
3179651SAndreas.Sandberg@ARM.com        // exclusive copy
3189651SAndreas.Sandberg@ARM.com        pendingShared = true;
3199651SAndreas.Sandberg@ARM.com        pkt->assertShared();
3209651SAndreas.Sandberg@ARM.com    }
3219651SAndreas.Sandberg@ARM.com
3229651SAndreas.Sandberg@ARM.com    return true;
3239651SAndreas.Sandberg@ARM.com}
3249652SAndreas.Sandberg@ARM.com
3259652SAndreas.Sandberg@ARM.com
3269652SAndreas.Sandberg@ARM.combool
3279651SAndreas.Sandberg@ARM.comMSHR::promoteDeferredTargets()
3289651SAndreas.Sandberg@ARM.com{
3299651SAndreas.Sandberg@ARM.com    assert(targets->empty());
3309651SAndreas.Sandberg@ARM.com    if (deferredTargets->empty()) {
3319651SAndreas.Sandberg@ARM.com        return false;
3329651SAndreas.Sandberg@ARM.com    }
3339651SAndreas.Sandberg@ARM.com
3349651SAndreas.Sandberg@ARM.com    // swap targets & deferredTargets lists
3359651SAndreas.Sandberg@ARM.com    TargetList *tmp = targets;
3369651SAndreas.Sandberg@ARM.com    targets = deferredTargets;
3379651SAndreas.Sandberg@ARM.com    deferredTargets = tmp;
3389651SAndreas.Sandberg@ARM.com
3399651SAndreas.Sandberg@ARM.com    assert(targets->size() == ntargets);
3409651SAndreas.Sandberg@ARM.com
3419651SAndreas.Sandberg@ARM.com    // clear deferredTargets flags
3429651SAndreas.Sandberg@ARM.com    deferredTargets->resetFlags();
3439651SAndreas.Sandberg@ARM.com
3449651SAndreas.Sandberg@ARM.com    pendingInvalidate = false;
3459651SAndreas.Sandberg@ARM.com    pendingShared = false;
3469651SAndreas.Sandberg@ARM.com    order = targets->front().order;
3479651SAndreas.Sandberg@ARM.com    readyTime = std::max(curTick, targets->front().readyTime);
3489651SAndreas.Sandberg@ARM.com
3499651SAndreas.Sandberg@ARM.com    return true;
3509651SAndreas.Sandberg@ARM.com}
3519651SAndreas.Sandberg@ARM.com
3529651SAndreas.Sandberg@ARM.com
3539651SAndreas.Sandberg@ARM.comvoid
3549651SAndreas.Sandberg@ARM.comMSHR::handleFill(Packet *pkt, CacheBlk *blk)
3559651SAndreas.Sandberg@ARM.com{
3569651SAndreas.Sandberg@ARM.com    if (pendingShared) {
3579651SAndreas.Sandberg@ARM.com        // we snooped another read while this read was in
3589651SAndreas.Sandberg@ARM.com        // service... assert shared line on its behalf
3599651SAndreas.Sandberg@ARM.com        pkt->assertShared();
3609651SAndreas.Sandberg@ARM.com    }
3619651SAndreas.Sandberg@ARM.com
3629651SAndreas.Sandberg@ARM.com    if (!pkt->sharedAsserted() && !pendingInvalidate
3639651SAndreas.Sandberg@ARM.com        && deferredTargets->needsExclusive) {
3649651SAndreas.Sandberg@ARM.com        // We got an exclusive response, but we have deferred targets
3659651SAndreas.Sandberg@ARM.com        // which are waiting to request an exclusive copy (not because
3669651SAndreas.Sandberg@ARM.com        // of a pending invalidate).  This can happen if the original
3679651SAndreas.Sandberg@ARM.com        // request was for a read-only (non-exclusive) block, but we
3689651SAndreas.Sandberg@ARM.com        // got an exclusive copy anyway because of the E part of the
3699651SAndreas.Sandberg@ARM.com        // MOESI/MESI protocol.  Since we got the exclusive copy
3709651SAndreas.Sandberg@ARM.com        // there's no need to defer the targets, so move them up to
3719651SAndreas.Sandberg@ARM.com        // the regular target list.
3729651SAndreas.Sandberg@ARM.com        assert(!targets->needsExclusive);
3739651SAndreas.Sandberg@ARM.com        targets->needsExclusive = true;
3749651SAndreas.Sandberg@ARM.com        // if any of the deferred targets were upper-level cache
3759651SAndreas.Sandberg@ARM.com        // requests marked downstreamPending, need to clear that
3769651SAndreas.Sandberg@ARM.com        assert(!downstreamPending);  // not pending here anymore
3779651SAndreas.Sandberg@ARM.com        deferredTargets->clearDownstreamPending();
3789651SAndreas.Sandberg@ARM.com        // this clears out deferredTargets too
3799651SAndreas.Sandberg@ARM.com        targets->splice(targets->end(), *deferredTargets);
3809651SAndreas.Sandberg@ARM.com        deferredTargets->resetFlags();
3819651SAndreas.Sandberg@ARM.com    }
3829651SAndreas.Sandberg@ARM.com}
3839651SAndreas.Sandberg@ARM.com
3849651SAndreas.Sandberg@ARM.com
3859651SAndreas.Sandberg@ARM.combool
3869651SAndreas.Sandberg@ARM.comMSHR::checkFunctional(PacketPtr pkt)
3879651SAndreas.Sandberg@ARM.com{
3889651SAndreas.Sandberg@ARM.com    // For printing, we treat the MSHR as a whole as single entity.
3899651SAndreas.Sandberg@ARM.com    // For other requests, we iterate over the individual targets
3909651SAndreas.Sandberg@ARM.com    // since that's where the actual data lies.
3919651SAndreas.Sandberg@ARM.com    if (pkt->isPrint()) {
3929651SAndreas.Sandberg@ARM.com        pkt->checkFunctional(this, addr, size, NULL);
3939651SAndreas.Sandberg@ARM.com        return false;
3949651SAndreas.Sandberg@ARM.com    } else {
3959651SAndreas.Sandberg@ARM.com        return (targets->checkFunctional(pkt) ||
3969651SAndreas.Sandberg@ARM.com                deferredTargets->checkFunctional(pkt));
3979651SAndreas.Sandberg@ARM.com    }
3989651SAndreas.Sandberg@ARM.com}
3999651SAndreas.Sandberg@ARM.com
4009651SAndreas.Sandberg@ARM.com
4019651SAndreas.Sandberg@ARM.comvoid
4029651SAndreas.Sandberg@ARM.comMSHR::print(std::ostream &os, int verbosity, const std::string &prefix) const
4039651SAndreas.Sandberg@ARM.com{
4049651SAndreas.Sandberg@ARM.com    ccprintf(os, "%s[%x:%x] %s %s %s state: %s %s %s %s\n",
4059652SAndreas.Sandberg@ARM.com             prefix, addr, addr+size-1,
4069652SAndreas.Sandberg@ARM.com             isCacheFill ? "Fill" : "",
4079652SAndreas.Sandberg@ARM.com             needsExclusive() ? "Excl" : "",
4089652SAndreas.Sandberg@ARM.com             _isUncacheable ? "Unc" : "",
4099652SAndreas.Sandberg@ARM.com             inService ? "InSvc" : "",
4109652SAndreas.Sandberg@ARM.com             downstreamPending ? "DwnPend" : "",
4119652SAndreas.Sandberg@ARM.com             pendingInvalidate ? "PendInv" : "",
4129652SAndreas.Sandberg@ARM.com             pendingShared ? "PendShared" : "");
4139652SAndreas.Sandberg@ARM.com
4149651SAndreas.Sandberg@ARM.com    ccprintf(os, "%s  Targets:\n", prefix);
4159651SAndreas.Sandberg@ARM.com    targets->print(os, verbosity, prefix + "    ");
4169651SAndreas.Sandberg@ARM.com    if (!deferredTargets->empty()) {
4179651SAndreas.Sandberg@ARM.com        ccprintf(os, "%s  Deferred Targets:\n", prefix);
4189651SAndreas.Sandberg@ARM.com        deferredTargets->print(os, verbosity, prefix + "      ");
4199651SAndreas.Sandberg@ARM.com    }
4209651SAndreas.Sandberg@ARM.com}
4219651SAndreas.Sandberg@ARM.com
4229651SAndreas.Sandberg@ARM.comMSHR::~MSHR()
4239651SAndreas.Sandberg@ARM.com{
4249651SAndreas.Sandberg@ARM.com}
4259651SAndreas.Sandberg@ARM.com