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