mshr.cc revision 6216
17405SAli.Saidi@ARM.com/*
212667Schuan.zhu@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 <algorithm>
387405SAli.Saidi@ARM.com#include <cassert>
397405SAli.Saidi@ARM.com#include <string>
407405SAli.Saidi@ARM.com#include <vector>
417405SAli.Saidi@ARM.com
4210461SAndreas.Sandberg@ARM.com#include "base/misc.hh"
439050Schander.sudanthi@arm.com#include "base/types.hh"
4412406Sgabeblack@google.com#include "mem/cache/cache.hh"
4512605Sgiacomo.travaglini@arm.com#include "mem/cache/mshr.hh"
4611793Sbrandon.potter@amd.com#include "sim/core.hh"
478887Sgeoffrey.blake@arm.com
488232Snate@binkert.orgusing namespace std;
498232Snate@binkert.org
5010844Sandreas.sandberg@arm.comMSHR::MSHR()
519384SAndreas.Sandberg@arm.com{
527678Sgblack@eecs.umich.edu    inService = false;
538059SAli.Saidi@ARM.com    ntargets = 0;
548284SAli.Saidi@ARM.com    threadNum = -1;
557405SAli.Saidi@ARM.com    targets = new TargetList();
567405SAli.Saidi@ARM.com    deferredTargets = new TargetList();
577405SAli.Saidi@ARM.com}
587405SAli.Saidi@ARM.com
599384SAndreas.Sandberg@arm.com
6010461SAndreas.Sandberg@ARM.comMSHR::TargetList::TargetList()
6110461SAndreas.Sandberg@ARM.com    : needsExclusive(false), hasUpgrade(false)
6211165SRekai.GonzalezAlberquilla@arm.com{}
6312109SRekai.GonzalezAlberquilla@arm.com
6412714Sgiacomo.travaglini@arm.com
6512714Sgiacomo.travaglini@arm.cominline void
669384SAndreas.Sandberg@arm.comMSHR::TargetList::add(PacketPtr pkt, Tick readyTime,
6711770SCurtis.Dunham@arm.com                      Counter order, Target::Source source, bool markPending)
6810037SARM gem5 Developers{
6910461SAndreas.Sandberg@ARM.com    if (source != Target::FromSnoop) {
7010461SAndreas.Sandberg@ARM.com        if (pkt->needsExclusive()) {
7110461SAndreas.Sandberg@ARM.com            needsExclusive = true;
7210461SAndreas.Sandberg@ARM.com        }
7310461SAndreas.Sandberg@ARM.com
7410461SAndreas.Sandberg@ARM.com        if (pkt->cmd == MemCmd::UpgradeReq) {
7510609Sandreas.sandberg@arm.com            hasUpgrade = true;
7610609Sandreas.sandberg@arm.com        }
7710609Sandreas.sandberg@arm.com    }
7810037SARM gem5 Developers
7910037SARM gem5 Developers    if (markPending) {
8010037SARM gem5 Developers        MSHR *mshr = dynamic_cast<MSHR*>(pkt->senderState);
8110037SARM gem5 Developers        if (mshr != NULL) {
8211771SCurtis.Dunham@arm.com            assert(!mshr->downstreamPending);
8310037SARM gem5 Developers            mshr->downstreamPending = true;
8410037SARM gem5 Developers        }
8510037SARM gem5 Developers    }
8610037SARM gem5 Developers
8710037SARM gem5 Developers    push_back(Target(pkt, readyTime, order, source, markPending));
8810037SARM gem5 Developers}
8911771SCurtis.Dunham@arm.com
9010037SARM gem5 Developers
9110037SARM gem5 Developersvoid
9210037SARM gem5 DevelopersMSHR::TargetList::replaceUpgrades()
9310037SARM gem5 Developers{
9410037SARM gem5 Developers    if (!hasUpgrade)
9512477SCurtis.Dunham@arm.com        return;
9610037SARM gem5 Developers
9710037SARM gem5 Developers    Iterator end_i = end();
989384SAndreas.Sandberg@arm.com    for (Iterator i = begin(); i != end_i; ++i) {
999384SAndreas.Sandberg@arm.com        if (i->pkt->cmd == MemCmd::UpgradeReq) {
1009384SAndreas.Sandberg@arm.com            i->pkt->cmd = MemCmd::ReadExReq;
10112479SCurtis.Dunham@arm.com            DPRINTF(Cache, "Replacing UpgradeReq with ReadExReq\n");
10212479SCurtis.Dunham@arm.com        }
1039384SAndreas.Sandberg@arm.com    }
1049384SAndreas.Sandberg@arm.com
1059384SAndreas.Sandberg@arm.com    hasUpgrade = false;
1069384SAndreas.Sandberg@arm.com}
1079384SAndreas.Sandberg@arm.com
1089384SAndreas.Sandberg@arm.com
1097427Sgblack@eecs.umich.eduvoid
1107427Sgblack@eecs.umich.eduMSHR::TargetList::clearDownstreamPending()
1117427Sgblack@eecs.umich.edu{
1129385SAndreas.Sandberg@arm.com    Iterator end_i = end();
1139385SAndreas.Sandberg@arm.com    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);
11610037SARM gem5 Developers            if (mshr != NULL) {
11710037SARM gem5 Developers                mshr->clearDownstreamPending();
11810037SARM gem5 Developers            }
11910037SARM gem5 Developers        }
12010037SARM gem5 Developers    }
12110037SARM gem5 Developers}
12212690Sgiacomo.travaglini@arm.com
12312690Sgiacomo.travaglini@arm.com
12412690Sgiacomo.travaglini@arm.combool
12512690Sgiacomo.travaglini@arm.comMSHR::TargetList::checkFunctional(PacketPtr pkt)
12612690Sgiacomo.travaglini@arm.com{
12712690Sgiacomo.travaglini@arm.com    Iterator end_i = end();
12812690Sgiacomo.travaglini@arm.com    for (Iterator i = begin(); i != end_i; ++i) {
12912690Sgiacomo.travaglini@arm.com        if (pkt->checkFunctional(i->pkt)) {
13012690Sgiacomo.travaglini@arm.com            return true;
13112690Sgiacomo.travaglini@arm.com        }
13212690Sgiacomo.travaglini@arm.com    }
13312690Sgiacomo.travaglini@arm.com
13410037SARM gem5 Developers    return false;
13510037SARM gem5 Developers}
13610037SARM gem5 Developers
13710037SARM gem5 Developers
13810037SARM gem5 Developersvoid
13910037SARM gem5 DevelopersMSHR::TargetList::
14010037SARM gem5 Developersprint(std::ostream &os, int verbosity, const std::string &prefix) const
14110037SARM gem5 Developers{
1427427Sgblack@eecs.umich.edu    ConstIterator end_i = end();
1437427Sgblack@eecs.umich.edu    for (ConstIterator i = begin(); i != end_i; ++i) {
1447427Sgblack@eecs.umich.edu        const char *s;
1457427Sgblack@eecs.umich.edu        switch (i->source) {
1467427Sgblack@eecs.umich.edu          case Target::FromCPU: s = "FromCPU";
1477427Sgblack@eecs.umich.edu          case Target::FromSnoop: s = "FromSnoop";
14810037SARM gem5 Developers          case Target::FromPrefetcher: s = "FromPrefetcher";
14910037SARM gem5 Developers          default: s = "";
15010037SARM gem5 Developers        }
15110037SARM gem5 Developers        ccprintf(os, "%s%s: ", prefix, s);
1527427Sgblack@eecs.umich.edu        i->pkt->print(os, verbosity, "");
1537427Sgblack@eecs.umich.edu    }
1547427Sgblack@eecs.umich.edu}
15510037SARM gem5 Developers
15610204SAli.Saidi@ARM.com
15710204SAli.Saidi@ARM.comvoid
15810037SARM gem5 DevelopersMSHR::allocate(Addr _addr, int _size, PacketPtr target,
1597427Sgblack@eecs.umich.edu               Tick whenReady, Counter _order)
16010037SARM gem5 Developers{
1617427Sgblack@eecs.umich.edu    addr = _addr;
16210037SARM gem5 Developers    size = _size;
1637427Sgblack@eecs.umich.edu    readyTime = whenReady;
1647427Sgblack@eecs.umich.edu    order = _order;
16510037SARM gem5 Developers    assert(target);
1667427Sgblack@eecs.umich.edu    isForward = false;
1677427Sgblack@eecs.umich.edu    _isUncacheable = target->req->isUncacheable();
1687427Sgblack@eecs.umich.edu    inService = false;
1697427Sgblack@eecs.umich.edu    downstreamPending = false;
1707427Sgblack@eecs.umich.edu    threadNum = 0;
1717427Sgblack@eecs.umich.edu    ntargets = 1;
1727427Sgblack@eecs.umich.edu    assert(targets->isReset());
1737427Sgblack@eecs.umich.edu    // Don't know of a case where we would allocate a new MSHR for a
1747427Sgblack@eecs.umich.edu    // snoop (mem-side request), so set source according to request here
1757427Sgblack@eecs.umich.edu    Target::Source source = (target->cmd == MemCmd::HardPFReq) ?
1767427Sgblack@eecs.umich.edu        Target::FromPrefetcher : Target::FromCPU;
1777427Sgblack@eecs.umich.edu    targets->add(target, whenReady, _order, source, true);
1787427Sgblack@eecs.umich.edu    assert(deferredTargets->isReset());
1797427Sgblack@eecs.umich.edu    pendingInvalidate = false;
1807427Sgblack@eecs.umich.edu    pendingShared = false;
1817427Sgblack@eecs.umich.edu    data = NULL;
1827427Sgblack@eecs.umich.edu}
1837427Sgblack@eecs.umich.edu
1847427Sgblack@eecs.umich.edu
1857427Sgblack@eecs.umich.eduvoid
1867427Sgblack@eecs.umich.eduMSHR::clearDownstreamPending()
1877427Sgblack@eecs.umich.edu{
1887427Sgblack@eecs.umich.edu    assert(downstreamPending);
1897436Sdam.sunwoo@arm.com    downstreamPending = false;
1907436Sdam.sunwoo@arm.com    // recursively clear flag on any MSHRs we will be forwarding
19110037SARM gem5 Developers    // responses to
19210037SARM gem5 Developers    targets->clearDownstreamPending();
1937436Sdam.sunwoo@arm.com}
1947436Sdam.sunwoo@arm.com
1957436Sdam.sunwoo@arm.combool
1967436Sdam.sunwoo@arm.comMSHR::markInService()
1977436Sdam.sunwoo@arm.com{
1987436Sdam.sunwoo@arm.com    assert(!inService);
1997436Sdam.sunwoo@arm.com    if (isForwardNoResponse()) {
2007436Sdam.sunwoo@arm.com        // we just forwarded the request packet & don't expect a
2017436Sdam.sunwoo@arm.com        // response, so get rid of it
2027436Sdam.sunwoo@arm.com        assert(getNumTargets() == 1);
2037436Sdam.sunwoo@arm.com        popTarget();
2047436Sdam.sunwoo@arm.com        return true;
20510037SARM gem5 Developers    }
2067436Sdam.sunwoo@arm.com    inService = true;
2077436Sdam.sunwoo@arm.com    if (!downstreamPending) {
2087436Sdam.sunwoo@arm.com        // let upstream caches know that the request has made it to a
2097436Sdam.sunwoo@arm.com        // level where it's going to get a response
2107436Sdam.sunwoo@arm.com        targets->clearDownstreamPending();
2117436Sdam.sunwoo@arm.com    }
2127436Sdam.sunwoo@arm.com    return false;
2137436Sdam.sunwoo@arm.com}
2147436Sdam.sunwoo@arm.com
2157436Sdam.sunwoo@arm.com
2167436Sdam.sunwoo@arm.comvoid
2177436Sdam.sunwoo@arm.comMSHR::deallocate()
2187436Sdam.sunwoo@arm.com{
2197436Sdam.sunwoo@arm.com    assert(targets->empty());
2207436Sdam.sunwoo@arm.com    targets->resetFlags();
2217436Sdam.sunwoo@arm.com    assert(deferredTargets->isReset());
2227644Sali.saidi@arm.com    assert(ntargets == 0);
2238147SAli.Saidi@ARM.com    inService = false;
2249385SAndreas.Sandberg@arm.com    //allocIter = NULL;
2259385SAndreas.Sandberg@arm.com    //readyIter = NULL;
22610037SARM gem5 Developers}
22710037SARM gem5 Developers
22810037SARM gem5 Developers/*
22910037SARM gem5 Developers * Adds a target to an MSHR
23010037SARM gem5 Developers */
23110037SARM gem5 Developersvoid
23210037SARM gem5 DevelopersMSHR::allocateTarget(PacketPtr pkt, Tick whenReady, Counter _order)
23310037SARM gem5 Developers{
23410037SARM gem5 Developers    // if there's a request already in service for this MSHR, we will
23510037SARM gem5 Developers    // have to defer the new target until after the response if any of
23610037SARM gem5 Developers    // the following are true:
23710037SARM gem5 Developers    // - there are other targets already deferred
23810037SARM gem5 Developers    // - there's a pending invalidate to be applied after the response
23910037SARM gem5 Developers    //   comes back (but before this target is processed)
24010037SARM gem5 Developers    // - the outstanding request is for a non-exclusive block and this
24110037SARM gem5 Developers    //   target requires an exclusive block
2428147SAli.Saidi@ARM.com
2437427Sgblack@eecs.umich.edu    // assume we'd never issue a prefetch when we've got an
2447427Sgblack@eecs.umich.edu    // outstanding miss
2457427Sgblack@eecs.umich.edu    assert(pkt->cmd != MemCmd::HardPFReq);
24610037SARM gem5 Developers
24710037SARM gem5 Developers    if (inService &&
24810037SARM gem5 Developers        (!deferredTargets->empty() || pendingInvalidate ||
24910037SARM gem5 Developers         (!targets->needsExclusive && pkt->needsExclusive()))) {
25010037SARM gem5 Developers        // need to put on deferred list
25110037SARM gem5 Developers        deferredTargets->add(pkt, whenReady, _order, Target::FromCPU, true);
25210037SARM gem5 Developers    } else {
25310037SARM gem5 Developers        // No request outstanding, or still OK to append to
25410037SARM gem5 Developers        // outstanding request: append to regular target list.  Only
25510037SARM gem5 Developers        // mark pending if current request hasn't been issued yet
25610037SARM gem5 Developers        // (isn't in service).
25710037SARM gem5 Developers        targets->add(pkt, whenReady, _order, Target::FromCPU, !inService);
25810037SARM gem5 Developers    }
25910037SARM gem5 Developers
26010037SARM gem5 Developers    ++ntargets;
26110037SARM gem5 Developers}
26210037SARM gem5 Developers
26310037SARM gem5 Developersbool
26410037SARM gem5 DevelopersMSHR::handleSnoop(PacketPtr pkt, Counter _order)
26510037SARM gem5 Developers{
26610037SARM gem5 Developers    if (!inService || (pkt->isExpressSnoop() && downstreamPending)) {
26710037SARM gem5 Developers        // Request has not been issued yet, or it's been issued
26810037SARM gem5 Developers        // locally but is buffered unissued at some downstream cache
26910037SARM gem5 Developers        // which is forwarding us this snoop.  Either way, the packet
27010037SARM gem5 Developers        // we're snooping logically precedes this MSHR's request, so
27110037SARM gem5 Developers        // the snoop has no impact on the MSHR, but must be processed
27210037SARM gem5 Developers        // in the standard way by the cache.  The only exception is
27310037SARM gem5 Developers        // that if we're an L2+ cache buffering an UpgradeReq from a
27410037SARM gem5 Developers        // higher-level cache, and the snoop is invalidating, then our
27510037SARM gem5 Developers        // buffered upgrades must be converted to read exclusives,
27610037SARM gem5 Developers        // since the upper-level cache no longer has a valid copy.
27710037SARM gem5 Developers        // That is, even though the upper-level cache got out on its
27810037SARM gem5 Developers        // local bus first, some other invalidating transaction
27910037SARM gem5 Developers        // reached the global bus before the upgrade did.
28010037SARM gem5 Developers        if (pkt->needsExclusive()) {
28110037SARM gem5 Developers            targets->replaceUpgrades();
28211770SCurtis.Dunham@arm.com            deferredTargets->replaceUpgrades();
28310037SARM gem5 Developers        }
28411574SCurtis.Dunham@arm.com
28511770SCurtis.Dunham@arm.com        return false;
28611770SCurtis.Dunham@arm.com    }
28710037SARM gem5 Developers
28811770SCurtis.Dunham@arm.com    // From here on down, the request issued by this MSHR logically
28911770SCurtis.Dunham@arm.com    // precedes the request we're snooping.
29010037SARM gem5 Developers
29110037SARM gem5 Developers    if (pkt->needsExclusive()) {
29210037SARM gem5 Developers        // snooped request still precedes the re-request we'll have to
29310037SARM gem5 Developers        // issue for deferred targets, if any...
29410037SARM gem5 Developers        deferredTargets->replaceUpgrades();
29510037SARM gem5 Developers    }
29610037SARM gem5 Developers
29710461SAndreas.Sandberg@ARM.com    if (pendingInvalidate) {
29810461SAndreas.Sandberg@ARM.com        // a prior snoop has already appended an invalidation, so
29910461SAndreas.Sandberg@ARM.com        // logically we don't have the block anymore; no need for
30010461SAndreas.Sandberg@ARM.com        // further snooping.
30110037SARM gem5 Developers        return true;
30210037SARM gem5 Developers    }
30310037SARM gem5 Developers
30410037SARM gem5 Developers    if (targets->needsExclusive || pkt->needsExclusive()) {
30510037SARM gem5 Developers        // actual target device (typ. PhysicalMemory) will delete the
30610037SARM gem5 Developers        // packet on reception, so we need to save a copy here
30710461SAndreas.Sandberg@ARM.com        PacketPtr cp_pkt = new Packet(pkt, true);
30810461SAndreas.Sandberg@ARM.com        targets->add(cp_pkt, curTick, _order, Target::FromSnoop,
30910461SAndreas.Sandberg@ARM.com                     downstreamPending && targets->needsExclusive);
31010461SAndreas.Sandberg@ARM.com        ++ntargets;
31110461SAndreas.Sandberg@ARM.com
31210037SARM gem5 Developers        if (targets->needsExclusive) {
31310037SARM gem5 Developers            // We're awaiting an exclusive copy, so ownership is pending.
31410037SARM gem5 Developers            // It's up to us to respond once the data arrives.
31510037SARM gem5 Developers            pkt->assertMemInhibit();
31610037SARM gem5 Developers            pkt->setSupplyExclusive();
31711574SCurtis.Dunham@arm.com        } else {
31810037SARM gem5 Developers            // Someone else may respond before we get around to
31910037SARM gem5 Developers            // processing this snoop, which means the copied request
32010037SARM gem5 Developers            // pointer will no longer be valid
32111574SCurtis.Dunham@arm.com            cp_pkt->req = NULL;
32210037SARM gem5 Developers        }
32310037SARM gem5 Developers
32410037SARM gem5 Developers        if (pkt->needsExclusive()) {
32510037SARM gem5 Developers            // This transaction will take away our pending copy
32610037SARM gem5 Developers            pendingInvalidate = true;
32710037SARM gem5 Developers        }
32810037SARM gem5 Developers    } else {
32910037SARM gem5 Developers        // Read to a read: no conflict, so no need to record as
33010037SARM gem5 Developers        // target, but make sure neither reader thinks he's getting an
33110037SARM gem5 Developers        // exclusive copy
3327405SAli.Saidi@ARM.com        pendingShared = true;
33310035Sandreas.hansson@arm.com        pkt->assertShared();
3347405SAli.Saidi@ARM.com    }
3357405SAli.Saidi@ARM.com
3367614Sminkyu.jeong@arm.com    return true;
33712478SCurtis.Dunham@arm.com}
33812478SCurtis.Dunham@arm.com
33912478SCurtis.Dunham@arm.com
34012478SCurtis.Dunham@arm.combool
34112478SCurtis.Dunham@arm.comMSHR::promoteDeferredTargets()
34212478SCurtis.Dunham@arm.com{
34312478SCurtis.Dunham@arm.com    assert(targets->empty());
34412478SCurtis.Dunham@arm.com    if (deferredTargets->empty()) {
34512478SCurtis.Dunham@arm.com        return false;
34612478SCurtis.Dunham@arm.com    }
34712478SCurtis.Dunham@arm.com
34812478SCurtis.Dunham@arm.com    // swap targets & deferredTargets lists
34912478SCurtis.Dunham@arm.com    TargetList *tmp = targets;
35012478SCurtis.Dunham@arm.com    targets = deferredTargets;
35112478SCurtis.Dunham@arm.com    deferredTargets = tmp;
35212478SCurtis.Dunham@arm.com
3537405SAli.Saidi@ARM.com    assert(targets->size() == ntargets);
3547405SAli.Saidi@ARM.com
3557405SAli.Saidi@ARM.com    // clear deferredTargets flags
3567405SAli.Saidi@ARM.com    deferredTargets->resetFlags();
3577405SAli.Saidi@ARM.com
3587405SAli.Saidi@ARM.com    pendingInvalidate = false;
35910037SARM gem5 Developers    pendingShared = false;
36010037SARM gem5 Developers    order = targets->front().order;
36110037SARM gem5 Developers    readyTime = std::max(curTick, targets->front().readyTime);
3629050Schander.sudanthi@arm.com
3637405SAli.Saidi@ARM.com    return true;
36410037SARM gem5 Developers}
36510037SARM gem5 Developers
3667720Sgblack@eecs.umich.edu
3677720Sgblack@eecs.umich.eduvoid
3687405SAli.Saidi@ARM.comMSHR::handleFill(Packet *pkt, CacheBlk *blk)
3697405SAli.Saidi@ARM.com{
3707757SAli.Saidi@ARM.com    if (pendingShared) {
37110037SARM gem5 Developers        // we snooped another read while this read was in
37210037SARM gem5 Developers        // service... assert shared line on its behalf
37310037SARM gem5 Developers        pkt->assertShared();
37410037SARM gem5 Developers    }
37510037SARM gem5 Developers
37610037SARM gem5 Developers    if (!pkt->sharedAsserted() && !pendingInvalidate
37710037SARM gem5 Developers        && deferredTargets->needsExclusive) {
37810037SARM gem5 Developers        // We got an exclusive response, but we have deferred targets
37910037SARM gem5 Developers        // which are waiting to request an exclusive copy (not because
38010037SARM gem5 Developers        // of a pending invalidate).  This can happen if the original
38110037SARM gem5 Developers        // request was for a read-only (non-exclusive) block, but we
38210037SARM gem5 Developers        // got an exclusive copy anyway because of the E part of the
38310037SARM gem5 Developers        // MOESI/MESI protocol.  Since we got the exclusive copy
38410037SARM gem5 Developers        // there's no need to defer the targets, so move them up to
38510037SARM gem5 Developers        // the regular target list.
38610037SARM gem5 Developers        assert(!targets->needsExclusive);
38710037SARM gem5 Developers        targets->needsExclusive = true;
38810037SARM gem5 Developers        // if any of the deferred targets were upper-level cache
38910037SARM gem5 Developers        // requests marked downstreamPending, need to clear that
39010037SARM gem5 Developers        assert(!downstreamPending);  // not pending here anymore
39110037SARM gem5 Developers        deferredTargets->clearDownstreamPending();
39210037SARM gem5 Developers        // this clears out deferredTargets too
39310037SARM gem5 Developers        targets->splice(targets->end(), *deferredTargets);
39410037SARM gem5 Developers        deferredTargets->resetFlags();
39510037SARM gem5 Developers    }
39610037SARM gem5 Developers}
39710037SARM gem5 Developers
39810037SARM gem5 Developers
39910037SARM gem5 Developersbool
40010037SARM gem5 DevelopersMSHR::checkFunctional(PacketPtr pkt)
40110037SARM gem5 Developers{
40210037SARM gem5 Developers    // For printing, we treat the MSHR as a whole as single entity.
40310037SARM gem5 Developers    // For other requests, we iterate over the individual targets
40412667Schuan.zhu@arm.com    // since that's where the actual data lies.
40510037SARM gem5 Developers    if (pkt->isPrint()) {
40610037SARM gem5 Developers        pkt->checkFunctional(this, addr, size, NULL);
40710037SARM gem5 Developers        return false;
40810037SARM gem5 Developers    } else {
40910037SARM gem5 Developers        return (targets->checkFunctional(pkt) ||
41010037SARM gem5 Developers                deferredTargets->checkFunctional(pkt));
41110037SARM gem5 Developers    }
41210037SARM gem5 Developers}
41310037SARM gem5 Developers
41410037SARM gem5 Developers
41510037SARM gem5 Developersvoid
41610037SARM gem5 DevelopersMSHR::print(std::ostream &os, int verbosity, const std::string &prefix) const
4178284SAli.Saidi@ARM.com{
41810037SARM gem5 Developers    ccprintf(os, "%s[%x:%x] %s %s %s state: %s %s %s %s\n",
41910037SARM gem5 Developers             prefix, addr, addr+size-1,
42010037SARM gem5 Developers             isForward ? "Forward" : "",
42110037SARM gem5 Developers             isForwardNoResponse() ? "ForwNoResp" : "",
4229050Schander.sudanthi@arm.com             needsExclusive() ? "Excl" : "",
42310037SARM gem5 Developers             _isUncacheable ? "Unc" : "",
42410037SARM gem5 Developers             inService ? "InSvc" : "",
42510037SARM gem5 Developers             downstreamPending ? "DwnPend" : "",
42610037SARM gem5 Developers             pendingInvalidate ? "PendInv" : "",
42710037SARM gem5 Developers             pendingShared ? "PendShared" : "");
42810037SARM gem5 Developers
42910037SARM gem5 Developers    ccprintf(os, "%s  Targets:\n", prefix);
43010037SARM gem5 Developers    targets->print(os, verbosity, prefix + "    ");
43110037SARM gem5 Developers    if (!deferredTargets->empty()) {
43210037SARM gem5 Developers        ccprintf(os, "%s  Deferred Targets:\n", prefix);
43310037SARM gem5 Developers        deferredTargets->print(os, verbosity, prefix + "      ");
43410037SARM gem5 Developers    }
43510037SARM gem5 Developers}
43610037SARM gem5 Developers
43710037SARM gem5 DevelopersMSHR::~MSHR()
43810037SARM gem5 Developers{
43910037SARM gem5 Developers}
44010037SARM gem5 Developers