mshr.cc revision 10502:f2f1dbfd505e
112027Sjungma@eit.uni-kl.de/*
212027Sjungma@eit.uni-kl.de * Copyright (c) 2012-2013 ARM Limited
312027Sjungma@eit.uni-kl.de * All rights reserved.
412027Sjungma@eit.uni-kl.de *
512027Sjungma@eit.uni-kl.de * The license below extends only to copyright in the software and shall
612027Sjungma@eit.uni-kl.de * not be construed as granting a license to any other intellectual
712027Sjungma@eit.uni-kl.de * property including but not limited to intellectual property relating
812027Sjungma@eit.uni-kl.de * to a hardware implementation of the functionality of the software
912027Sjungma@eit.uni-kl.de * licensed hereunder.  You may use the software subject to the license
1012027Sjungma@eit.uni-kl.de * terms below provided that you ensure that this notice is replicated
1112027Sjungma@eit.uni-kl.de * unmodified and in its entirety in all distributions of the software,
1212027Sjungma@eit.uni-kl.de * modified or unmodified, in source code or in binary form.
1312027Sjungma@eit.uni-kl.de *
1412027Sjungma@eit.uni-kl.de * Copyright (c) 2002-2005 The Regents of The University of Michigan
1512027Sjungma@eit.uni-kl.de * Copyright (c) 2010 Advanced Micro Devices, Inc.
1612027Sjungma@eit.uni-kl.de * All rights reserved.
1712027Sjungma@eit.uni-kl.de *
1812027Sjungma@eit.uni-kl.de * Redistribution and use in source and binary forms, with or without
1912027Sjungma@eit.uni-kl.de * modification, are permitted provided that the following conditions are
2012027Sjungma@eit.uni-kl.de * met: redistributions of source code must retain the above copyright
2112027Sjungma@eit.uni-kl.de * notice, this list of conditions and the following disclaimer;
2212027Sjungma@eit.uni-kl.de * redistributions in binary form must reproduce the above copyright
2312027Sjungma@eit.uni-kl.de * notice, this list of conditions and the following disclaimer in the
2412027Sjungma@eit.uni-kl.de * documentation and/or other materials provided with the distribution;
2512027Sjungma@eit.uni-kl.de * neither the name of the copyright holders nor the names of its
2612027Sjungma@eit.uni-kl.de * contributors may be used to endorse or promote products derived from
2712027Sjungma@eit.uni-kl.de * this software without specific prior written permission.
2812027Sjungma@eit.uni-kl.de *
2912027Sjungma@eit.uni-kl.de * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3012027Sjungma@eit.uni-kl.de * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3112027Sjungma@eit.uni-kl.de * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3212027Sjungma@eit.uni-kl.de * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3312027Sjungma@eit.uni-kl.de * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3412027Sjungma@eit.uni-kl.de * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3512027Sjungma@eit.uni-kl.de * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3612027Sjungma@eit.uni-kl.de * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3712027Sjungma@eit.uni-kl.de * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3812027Sjungma@eit.uni-kl.de * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3912027Sjungma@eit.uni-kl.de * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4012027Sjungma@eit.uni-kl.de *
4112027Sjungma@eit.uni-kl.de * Authors: Erik Hallnor
4212027Sjungma@eit.uni-kl.de *          Dave Greene
4312027Sjungma@eit.uni-kl.de */
4412027Sjungma@eit.uni-kl.de
4512027Sjungma@eit.uni-kl.de/**
4612027Sjungma@eit.uni-kl.de * @file
4712027Sjungma@eit.uni-kl.de * Miss Status and Handling Register (MSHR) definitions.
4812027Sjungma@eit.uni-kl.de */
4912027Sjungma@eit.uni-kl.de
5012027Sjungma@eit.uni-kl.de#include <algorithm>
5112027Sjungma@eit.uni-kl.de#include <cassert>
5212027Sjungma@eit.uni-kl.de#include <string>
5312027Sjungma@eit.uni-kl.de#include <vector>
5412027Sjungma@eit.uni-kl.de
5512027Sjungma@eit.uni-kl.de#include "base/misc.hh"
5612027Sjungma@eit.uni-kl.de#include "base/types.hh"
5712027Sjungma@eit.uni-kl.de#include "debug/Cache.hh"
5812027Sjungma@eit.uni-kl.de#include "mem/cache/cache.hh"
5912027Sjungma@eit.uni-kl.de#include "mem/cache/mshr.hh"
6012027Sjungma@eit.uni-kl.de#include "sim/core.hh"
6112027Sjungma@eit.uni-kl.de
6212027Sjungma@eit.uni-kl.deusing namespace std;
6312027Sjungma@eit.uni-kl.de
6412027Sjungma@eit.uni-kl.deMSHR::MSHR() : readyTime(0), _isUncacheable(false), downstreamPending(false),
6512027Sjungma@eit.uni-kl.de               pendingDirty(false), postInvalidate(false), postDowngrade(false),
6612027Sjungma@eit.uni-kl.de               _isObsolete(false), queue(NULL), order(0), addr(0), size(0),
6712027Sjungma@eit.uni-kl.de               isSecure(false), inService(false), isForward(false),
6812027Sjungma@eit.uni-kl.de               threadNum(InvalidThreadID), data(NULL)
6912027Sjungma@eit.uni-kl.de{
7012027Sjungma@eit.uni-kl.de}
7112027Sjungma@eit.uni-kl.de
7212027Sjungma@eit.uni-kl.de
7312027Sjungma@eit.uni-kl.deMSHR::TargetList::TargetList()
7412027Sjungma@eit.uni-kl.de    : needsExclusive(false), hasUpgrade(false)
7512027Sjungma@eit.uni-kl.de{}
7612027Sjungma@eit.uni-kl.de
7712027Sjungma@eit.uni-kl.de
7812027Sjungma@eit.uni-kl.deinline void
7912027Sjungma@eit.uni-kl.deMSHR::TargetList::add(PacketPtr pkt, Tick readyTime,
8012027Sjungma@eit.uni-kl.de                      Counter order, Target::Source source, bool markPending)
8112027Sjungma@eit.uni-kl.de{
8212027Sjungma@eit.uni-kl.de    if (source != Target::FromSnoop) {
8312027Sjungma@eit.uni-kl.de        if (pkt->needsExclusive()) {
8412027Sjungma@eit.uni-kl.de            needsExclusive = true;
8512027Sjungma@eit.uni-kl.de        }
8612027Sjungma@eit.uni-kl.de
8712027Sjungma@eit.uni-kl.de        // StoreCondReq is effectively an upgrade if it's in an MSHR
8812027Sjungma@eit.uni-kl.de        // since it would have been failed already if we didn't have a
8912027Sjungma@eit.uni-kl.de        // read-only copy
9012027Sjungma@eit.uni-kl.de        if (pkt->isUpgrade() || pkt->cmd == MemCmd::StoreCondReq) {
9112027Sjungma@eit.uni-kl.de            hasUpgrade = true;
9212027Sjungma@eit.uni-kl.de        }
9312027Sjungma@eit.uni-kl.de    }
9412027Sjungma@eit.uni-kl.de
9512027Sjungma@eit.uni-kl.de    if (markPending) {
9612027Sjungma@eit.uni-kl.de        // Iterate over the SenderState stack and see if we find
9712027Sjungma@eit.uni-kl.de        // an MSHR entry. If we do, set the downstreamPending
9812027Sjungma@eit.uni-kl.de        // flag. Otherwise, do nothing.
9912027Sjungma@eit.uni-kl.de        MSHR *mshr = pkt->findNextSenderState<MSHR>();
10012027Sjungma@eit.uni-kl.de        if (mshr != NULL) {
10112027Sjungma@eit.uni-kl.de            assert(!mshr->downstreamPending);
10212027Sjungma@eit.uni-kl.de            mshr->downstreamPending = true;
10312027Sjungma@eit.uni-kl.de        }
10412027Sjungma@eit.uni-kl.de    }
10512027Sjungma@eit.uni-kl.de
10612027Sjungma@eit.uni-kl.de    push_back(Target(pkt, readyTime, order, source, markPending));
10712027Sjungma@eit.uni-kl.de}
10812027Sjungma@eit.uni-kl.de
10912027Sjungma@eit.uni-kl.de
11012027Sjungma@eit.uni-kl.destatic void
11112027Sjungma@eit.uni-kl.dereplaceUpgrade(PacketPtr pkt)
11212027Sjungma@eit.uni-kl.de{
11312027Sjungma@eit.uni-kl.de    if (pkt->cmd == MemCmd::UpgradeReq) {
11412027Sjungma@eit.uni-kl.de        pkt->cmd = MemCmd::ReadExReq;
11512027Sjungma@eit.uni-kl.de        DPRINTF(Cache, "Replacing UpgradeReq with ReadExReq\n");
11612027Sjungma@eit.uni-kl.de    } else if (pkt->cmd == MemCmd::SCUpgradeReq) {
11712027Sjungma@eit.uni-kl.de        pkt->cmd = MemCmd::SCUpgradeFailReq;
11812027Sjungma@eit.uni-kl.de        DPRINTF(Cache, "Replacing SCUpgradeReq with SCUpgradeFailReq\n");
11912027Sjungma@eit.uni-kl.de    } else if (pkt->cmd == MemCmd::StoreCondReq) {
12012027Sjungma@eit.uni-kl.de        pkt->cmd = MemCmd::StoreCondFailReq;
12112027Sjungma@eit.uni-kl.de        DPRINTF(Cache, "Replacing StoreCondReq with StoreCondFailReq\n");
12212027Sjungma@eit.uni-kl.de    }
12312027Sjungma@eit.uni-kl.de}
12412027Sjungma@eit.uni-kl.de
12512027Sjungma@eit.uni-kl.de
12612027Sjungma@eit.uni-kl.devoid
12712027Sjungma@eit.uni-kl.deMSHR::TargetList::replaceUpgrades()
12812027Sjungma@eit.uni-kl.de{
12912027Sjungma@eit.uni-kl.de    if (!hasUpgrade)
13012027Sjungma@eit.uni-kl.de        return;
13112027Sjungma@eit.uni-kl.de
13212027Sjungma@eit.uni-kl.de    Iterator end_i = end();
13312027Sjungma@eit.uni-kl.de    for (Iterator i = begin(); i != end_i; ++i) {
13412027Sjungma@eit.uni-kl.de        replaceUpgrade(i->pkt);
13512027Sjungma@eit.uni-kl.de    }
13612027Sjungma@eit.uni-kl.de
13712027Sjungma@eit.uni-kl.de    hasUpgrade = false;
13812027Sjungma@eit.uni-kl.de}
13912027Sjungma@eit.uni-kl.de
14012027Sjungma@eit.uni-kl.de
14112027Sjungma@eit.uni-kl.devoid
14212027Sjungma@eit.uni-kl.deMSHR::TargetList::clearDownstreamPending()
14312027Sjungma@eit.uni-kl.de{
14412027Sjungma@eit.uni-kl.de    Iterator end_i = end();
14512027Sjungma@eit.uni-kl.de    for (Iterator i = begin(); i != end_i; ++i) {
14612027Sjungma@eit.uni-kl.de        if (i->markedPending) {
14712027Sjungma@eit.uni-kl.de            // Iterate over the SenderState stack and see if we find
14812027Sjungma@eit.uni-kl.de            // an MSHR entry. If we find one, clear the
14912027Sjungma@eit.uni-kl.de            // downstreamPending flag by calling
15012027Sjungma@eit.uni-kl.de            // clearDownstreamPending(). This recursively clears the
15112027Sjungma@eit.uni-kl.de            // downstreamPending flag in all caches this packet has
15212027Sjungma@eit.uni-kl.de            // passed through.
15312027Sjungma@eit.uni-kl.de            MSHR *mshr = i->pkt->findNextSenderState<MSHR>();
15412027Sjungma@eit.uni-kl.de            if (mshr != NULL) {
15512027Sjungma@eit.uni-kl.de                mshr->clearDownstreamPending();
15612027Sjungma@eit.uni-kl.de            }
15712027Sjungma@eit.uni-kl.de        }
15812027Sjungma@eit.uni-kl.de    }
15912027Sjungma@eit.uni-kl.de}
16012027Sjungma@eit.uni-kl.de
16112027Sjungma@eit.uni-kl.de
16212027Sjungma@eit.uni-kl.debool
16312027Sjungma@eit.uni-kl.deMSHR::TargetList::checkFunctional(PacketPtr pkt)
16412027Sjungma@eit.uni-kl.de{
16512027Sjungma@eit.uni-kl.de    Iterator end_i = end();
16612027Sjungma@eit.uni-kl.de    for (Iterator i = begin(); i != end_i; ++i) {
16712027Sjungma@eit.uni-kl.de        if (pkt->checkFunctional(i->pkt)) {
16812027Sjungma@eit.uni-kl.de            return true;
16912027Sjungma@eit.uni-kl.de        }
17012027Sjungma@eit.uni-kl.de    }
17112027Sjungma@eit.uni-kl.de
17212027Sjungma@eit.uni-kl.de    return false;
17312027Sjungma@eit.uni-kl.de}
17412027Sjungma@eit.uni-kl.de
17512027Sjungma@eit.uni-kl.de
17612027Sjungma@eit.uni-kl.devoid
17712027Sjungma@eit.uni-kl.deMSHR::TargetList::
17812027Sjungma@eit.uni-kl.deprint(std::ostream &os, int verbosity, const std::string &prefix) const
17912027Sjungma@eit.uni-kl.de{
18012027Sjungma@eit.uni-kl.de    ConstIterator end_i = end();
18112027Sjungma@eit.uni-kl.de    for (ConstIterator i = begin(); i != end_i; ++i) {
18212027Sjungma@eit.uni-kl.de        const char *s;
18312027Sjungma@eit.uni-kl.de        switch (i->source) {
18412027Sjungma@eit.uni-kl.de          case Target::FromCPU:
18512027Sjungma@eit.uni-kl.de            s = "FromCPU";
18612027Sjungma@eit.uni-kl.de            break;
18712027Sjungma@eit.uni-kl.de          case Target::FromSnoop:
18812027Sjungma@eit.uni-kl.de            s = "FromSnoop";
18912027Sjungma@eit.uni-kl.de            break;
19012027Sjungma@eit.uni-kl.de          case Target::FromPrefetcher:
19112027Sjungma@eit.uni-kl.de            s = "FromPrefetcher";
19212027Sjungma@eit.uni-kl.de            break;
19312027Sjungma@eit.uni-kl.de          default:
19412027Sjungma@eit.uni-kl.de            s = "";
19512027Sjungma@eit.uni-kl.de            break;
19612027Sjungma@eit.uni-kl.de        }
19712027Sjungma@eit.uni-kl.de        ccprintf(os, "%s%s: ", prefix, s);
19812027Sjungma@eit.uni-kl.de        i->pkt->print(os, verbosity, "");
19912027Sjungma@eit.uni-kl.de    }
20012027Sjungma@eit.uni-kl.de}
20112027Sjungma@eit.uni-kl.de
20212027Sjungma@eit.uni-kl.de
20312027Sjungma@eit.uni-kl.devoid
20412027Sjungma@eit.uni-kl.deMSHR::allocate(Addr _addr, int _size, PacketPtr target, Tick whenReady,
20512027Sjungma@eit.uni-kl.de               Counter _order)
20612027Sjungma@eit.uni-kl.de{
20712027Sjungma@eit.uni-kl.de    addr = _addr;
20812027Sjungma@eit.uni-kl.de    size = _size;
20912027Sjungma@eit.uni-kl.de    isSecure = target->isSecure();
21012027Sjungma@eit.uni-kl.de    readyTime = whenReady;
21112027Sjungma@eit.uni-kl.de    order = _order;
21212027Sjungma@eit.uni-kl.de    assert(target);
21312027Sjungma@eit.uni-kl.de    isForward = false;
21412027Sjungma@eit.uni-kl.de    _isUncacheable = target->req->isUncacheable();
21512027Sjungma@eit.uni-kl.de    inService = false;
21612027Sjungma@eit.uni-kl.de    downstreamPending = false;
21712027Sjungma@eit.uni-kl.de    _isObsolete = false;
21812027Sjungma@eit.uni-kl.de    threadNum = 0;
21912027Sjungma@eit.uni-kl.de    assert(targets.isReset());
22012027Sjungma@eit.uni-kl.de    // Don't know of a case where we would allocate a new MSHR for a
22112027Sjungma@eit.uni-kl.de    // snoop (mem-side request), so set source according to request here
22212027Sjungma@eit.uni-kl.de    Target::Source source = (target->cmd == MemCmd::HardPFReq) ?
22312027Sjungma@eit.uni-kl.de        Target::FromPrefetcher : Target::FromCPU;
22412027Sjungma@eit.uni-kl.de    targets.add(target, whenReady, _order, source, true);
22512027Sjungma@eit.uni-kl.de    assert(deferredTargets.isReset());
22612027Sjungma@eit.uni-kl.de    data = NULL;
22712027Sjungma@eit.uni-kl.de}
22812027Sjungma@eit.uni-kl.de
22912027Sjungma@eit.uni-kl.de
23012027Sjungma@eit.uni-kl.devoid
23112027Sjungma@eit.uni-kl.deMSHR::clearDownstreamPending()
23212027Sjungma@eit.uni-kl.de{
23312027Sjungma@eit.uni-kl.de    assert(downstreamPending);
23412027Sjungma@eit.uni-kl.de    downstreamPending = false;
23512027Sjungma@eit.uni-kl.de    // recursively clear flag on any MSHRs we will be forwarding
23612027Sjungma@eit.uni-kl.de    // responses to
23712027Sjungma@eit.uni-kl.de    targets.clearDownstreamPending();
23812027Sjungma@eit.uni-kl.de}
23912027Sjungma@eit.uni-kl.de
24012027Sjungma@eit.uni-kl.debool
24112027Sjungma@eit.uni-kl.deMSHR::markInService(PacketPtr pkt)
24212027Sjungma@eit.uni-kl.de{
24312027Sjungma@eit.uni-kl.de    assert(!inService);
24412027Sjungma@eit.uni-kl.de    if (isForwardNoResponse()) {
24512027Sjungma@eit.uni-kl.de        // we just forwarded the request packet & don't expect a
24612027Sjungma@eit.uni-kl.de        // response, so get rid of it
24712027Sjungma@eit.uni-kl.de        assert(getNumTargets() == 1);
24812027Sjungma@eit.uni-kl.de        popTarget();
24912027Sjungma@eit.uni-kl.de        return true;
25012027Sjungma@eit.uni-kl.de    }
25112027Sjungma@eit.uni-kl.de
25212027Sjungma@eit.uni-kl.de    assert(pkt != NULL);
25312027Sjungma@eit.uni-kl.de    inService = true;
25412027Sjungma@eit.uni-kl.de    pendingDirty = (targets.needsExclusive ||
25512027Sjungma@eit.uni-kl.de                    (!pkt->sharedAsserted() && pkt->memInhibitAsserted()));
25612027Sjungma@eit.uni-kl.de    postInvalidate = postDowngrade = false;
25712027Sjungma@eit.uni-kl.de
25812027Sjungma@eit.uni-kl.de    if (!downstreamPending) {
25912027Sjungma@eit.uni-kl.de        // let upstream caches know that the request has made it to a
26012027Sjungma@eit.uni-kl.de        // level where it's going to get a response
26112027Sjungma@eit.uni-kl.de        targets.clearDownstreamPending();
26212027Sjungma@eit.uni-kl.de    }
26312027Sjungma@eit.uni-kl.de    return false;
26412027Sjungma@eit.uni-kl.de}
26512027Sjungma@eit.uni-kl.de
26612027Sjungma@eit.uni-kl.de
26712027Sjungma@eit.uni-kl.devoid
26812027Sjungma@eit.uni-kl.deMSHR::deallocate()
26912027Sjungma@eit.uni-kl.de{
27012027Sjungma@eit.uni-kl.de    assert(targets.empty());
27112027Sjungma@eit.uni-kl.de    targets.resetFlags();
27212027Sjungma@eit.uni-kl.de    assert(deferredTargets.isReset());
27312027Sjungma@eit.uni-kl.de    inService = false;
27412027Sjungma@eit.uni-kl.de}
27512027Sjungma@eit.uni-kl.de
27612027Sjungma@eit.uni-kl.de/*
27712027Sjungma@eit.uni-kl.de * Adds a target to an MSHR
27812027Sjungma@eit.uni-kl.de */
27912027Sjungma@eit.uni-kl.devoid
28012027Sjungma@eit.uni-kl.deMSHR::allocateTarget(PacketPtr pkt, Tick whenReady, Counter _order)
28112027Sjungma@eit.uni-kl.de{
28212027Sjungma@eit.uni-kl.de    // if there's a request already in service for this MSHR, we will
28312027Sjungma@eit.uni-kl.de    // have to defer the new target until after the response if any of
28412027Sjungma@eit.uni-kl.de    // the following are true:
28512027Sjungma@eit.uni-kl.de    // - there are other targets already deferred
28612027Sjungma@eit.uni-kl.de    // - there's a pending invalidate to be applied after the response
28712027Sjungma@eit.uni-kl.de    //   comes back (but before this target is processed)
28812027Sjungma@eit.uni-kl.de    // - this target requires an exclusive block and either we're not
28912027Sjungma@eit.uni-kl.de    //   getting an exclusive block back or we have already snooped
29012027Sjungma@eit.uni-kl.de    //   another read request that will downgrade our exclusive block
29112027Sjungma@eit.uni-kl.de    //   to shared
29212027Sjungma@eit.uni-kl.de
29312027Sjungma@eit.uni-kl.de    // assume we'd never issue a prefetch when we've got an
29412027Sjungma@eit.uni-kl.de    // outstanding miss
29512027Sjungma@eit.uni-kl.de    assert(pkt->cmd != MemCmd::HardPFReq);
29612027Sjungma@eit.uni-kl.de
29712027Sjungma@eit.uni-kl.de    if (inService &&
29812027Sjungma@eit.uni-kl.de        (!deferredTargets.empty() || hasPostInvalidate() ||
29912027Sjungma@eit.uni-kl.de         (pkt->needsExclusive() &&
30012027Sjungma@eit.uni-kl.de          (!isPendingDirty() || hasPostDowngrade() || isForward)))) {
30112027Sjungma@eit.uni-kl.de        // need to put on deferred list
30212027Sjungma@eit.uni-kl.de        if (hasPostInvalidate())
30312027Sjungma@eit.uni-kl.de            replaceUpgrade(pkt);
30412027Sjungma@eit.uni-kl.de        deferredTargets.add(pkt, whenReady, _order, Target::FromCPU, true);
30512027Sjungma@eit.uni-kl.de    } else {
30612027Sjungma@eit.uni-kl.de        // No request outstanding, or still OK to append to
30712027Sjungma@eit.uni-kl.de        // outstanding request: append to regular target list.  Only
30812027Sjungma@eit.uni-kl.de        // mark pending if current request hasn't been issued yet
30912027Sjungma@eit.uni-kl.de        // (isn't in service).
31012027Sjungma@eit.uni-kl.de        targets.add(pkt, whenReady, _order, Target::FromCPU, !inService);
31112027Sjungma@eit.uni-kl.de    }
31212027Sjungma@eit.uni-kl.de}
31312027Sjungma@eit.uni-kl.de
31412027Sjungma@eit.uni-kl.debool
31512027Sjungma@eit.uni-kl.deMSHR::handleSnoop(PacketPtr pkt, Counter _order)
31612027Sjungma@eit.uni-kl.de{
31712027Sjungma@eit.uni-kl.de    DPRINTF(Cache, "%s for %s address %x size %d\n", __func__,
31812027Sjungma@eit.uni-kl.de            pkt->cmdString(), pkt->getAddr(), pkt->getSize());
31912027Sjungma@eit.uni-kl.de    if (!inService || (pkt->isExpressSnoop() && downstreamPending)) {
32012027Sjungma@eit.uni-kl.de        // Request has not been issued yet, or it's been issued
32112027Sjungma@eit.uni-kl.de        // locally but is buffered unissued at some downstream cache
32212027Sjungma@eit.uni-kl.de        // which is forwarding us this snoop.  Either way, the packet
32312027Sjungma@eit.uni-kl.de        // we're snooping logically precedes this MSHR's request, so
32412027Sjungma@eit.uni-kl.de        // the snoop has no impact on the MSHR, but must be processed
32512027Sjungma@eit.uni-kl.de        // in the standard way by the cache.  The only exception is
32612027Sjungma@eit.uni-kl.de        // that if we're an L2+ cache buffering an UpgradeReq from a
32712027Sjungma@eit.uni-kl.de        // higher-level cache, and the snoop is invalidating, then our
32812027Sjungma@eit.uni-kl.de        // buffered upgrades must be converted to read exclusives,
32912027Sjungma@eit.uni-kl.de        // since the upper-level cache no longer has a valid copy.
33012027Sjungma@eit.uni-kl.de        // That is, even though the upper-level cache got out on its
33112027Sjungma@eit.uni-kl.de        // local bus first, some other invalidating transaction
33212027Sjungma@eit.uni-kl.de        // reached the global bus before the upgrade did.
33312027Sjungma@eit.uni-kl.de        if (pkt->needsExclusive()) {
33412027Sjungma@eit.uni-kl.de            targets.replaceUpgrades();
33512027Sjungma@eit.uni-kl.de            deferredTargets.replaceUpgrades();
33612027Sjungma@eit.uni-kl.de        }
33712027Sjungma@eit.uni-kl.de
33812027Sjungma@eit.uni-kl.de        return false;
33912027Sjungma@eit.uni-kl.de    }
34012027Sjungma@eit.uni-kl.de
34112027Sjungma@eit.uni-kl.de    // From here on down, the request issued by this MSHR logically
34212027Sjungma@eit.uni-kl.de    // precedes the request we're snooping.
34312027Sjungma@eit.uni-kl.de    if (pkt->needsExclusive()) {
34412027Sjungma@eit.uni-kl.de        // snooped request still precedes the re-request we'll have to
34512027Sjungma@eit.uni-kl.de        // issue for deferred targets, if any...
34612027Sjungma@eit.uni-kl.de        deferredTargets.replaceUpgrades();
34712027Sjungma@eit.uni-kl.de    }
34812027Sjungma@eit.uni-kl.de
34912027Sjungma@eit.uni-kl.de    if (hasPostInvalidate()) {
35012027Sjungma@eit.uni-kl.de        // a prior snoop has already appended an invalidation, so
35112027Sjungma@eit.uni-kl.de        // logically we don't have the block anymore; no need for
35212027Sjungma@eit.uni-kl.de        // further snooping.
35312027Sjungma@eit.uni-kl.de        return true;
35412027Sjungma@eit.uni-kl.de    }
35512027Sjungma@eit.uni-kl.de
35612027Sjungma@eit.uni-kl.de    if (isPendingDirty() || pkt->isInvalidate()) {
35712027Sjungma@eit.uni-kl.de        // We need to save and replay the packet in two cases:
35812027Sjungma@eit.uni-kl.de        // 1. We're awaiting an exclusive copy, so ownership is pending,
35912027Sjungma@eit.uni-kl.de        //    and we need to respond after we receive data.
36012027Sjungma@eit.uni-kl.de        // 2. It's an invalidation (e.g., UpgradeReq), and we need
36112027Sjungma@eit.uni-kl.de        //    to forward the snoop up the hierarchy after the current
36212027Sjungma@eit.uni-kl.de        //    transaction completes.
36312027Sjungma@eit.uni-kl.de
36412027Sjungma@eit.uni-kl.de        // Actual target device (typ. a memory) will delete the
36512027Sjungma@eit.uni-kl.de        // packet on reception, so we need to save a copy here.
36612027Sjungma@eit.uni-kl.de        PacketPtr cp_pkt = new Packet(pkt, true);
36712027Sjungma@eit.uni-kl.de        targets.add(cp_pkt, curTick(), _order, Target::FromSnoop,
36812027Sjungma@eit.uni-kl.de                     downstreamPending && targets.needsExclusive);
36912027Sjungma@eit.uni-kl.de
37012027Sjungma@eit.uni-kl.de        if (isPendingDirty()) {
37112027Sjungma@eit.uni-kl.de            pkt->assertMemInhibit();
37212027Sjungma@eit.uni-kl.de            pkt->setSupplyExclusive();
37312027Sjungma@eit.uni-kl.de        }
37412027Sjungma@eit.uni-kl.de
37512027Sjungma@eit.uni-kl.de        if (pkt->needsExclusive()) {
37612027Sjungma@eit.uni-kl.de            // This transaction will take away our pending copy
37712027Sjungma@eit.uni-kl.de            postInvalidate = true;
37812027Sjungma@eit.uni-kl.de        }
37912027Sjungma@eit.uni-kl.de    }
38012027Sjungma@eit.uni-kl.de
38112027Sjungma@eit.uni-kl.de    if (!pkt->needsExclusive()) {
38212027Sjungma@eit.uni-kl.de        // This transaction will get a read-shared copy, downgrading
38312027Sjungma@eit.uni-kl.de        // our copy if we had an exclusive one
38412027Sjungma@eit.uni-kl.de        postDowngrade = true;
38512027Sjungma@eit.uni-kl.de        pkt->assertShared();
38612027Sjungma@eit.uni-kl.de    }
38712027Sjungma@eit.uni-kl.de
38812027Sjungma@eit.uni-kl.de    return true;
38912027Sjungma@eit.uni-kl.de}
39012027Sjungma@eit.uni-kl.de
39112027Sjungma@eit.uni-kl.de
39212027Sjungma@eit.uni-kl.debool
39312027Sjungma@eit.uni-kl.deMSHR::promoteDeferredTargets()
39412027Sjungma@eit.uni-kl.de{
39512027Sjungma@eit.uni-kl.de    assert(targets.empty());
39612027Sjungma@eit.uni-kl.de    if (deferredTargets.empty()) {
39712027Sjungma@eit.uni-kl.de        return false;
39812027Sjungma@eit.uni-kl.de    }
39912027Sjungma@eit.uni-kl.de
40012027Sjungma@eit.uni-kl.de    // swap targets & deferredTargets lists
40112027Sjungma@eit.uni-kl.de    std::swap(targets, deferredTargets);
40212027Sjungma@eit.uni-kl.de
40312027Sjungma@eit.uni-kl.de    // clear deferredTargets flags
40412027Sjungma@eit.uni-kl.de    deferredTargets.resetFlags();
40512027Sjungma@eit.uni-kl.de
40612027Sjungma@eit.uni-kl.de    order = targets.front().order;
40712027Sjungma@eit.uni-kl.de    readyTime = std::max(curTick(), targets.front().readyTime);
40812027Sjungma@eit.uni-kl.de
40912027Sjungma@eit.uni-kl.de    return true;
41012027Sjungma@eit.uni-kl.de}
41112027Sjungma@eit.uni-kl.de
41212027Sjungma@eit.uni-kl.de
41312027Sjungma@eit.uni-kl.devoid
41412027Sjungma@eit.uni-kl.deMSHR::handleFill(Packet *pkt, CacheBlk *blk)
41512027Sjungma@eit.uni-kl.de{
41612027Sjungma@eit.uni-kl.de    if (!pkt->sharedAsserted()
41712027Sjungma@eit.uni-kl.de        && !(hasPostInvalidate() || hasPostDowngrade())
41812027Sjungma@eit.uni-kl.de        && deferredTargets.needsExclusive) {
41912027Sjungma@eit.uni-kl.de        // We got an exclusive response, but we have deferred targets
42012027Sjungma@eit.uni-kl.de        // which are waiting to request an exclusive copy (not because
42112027Sjungma@eit.uni-kl.de        // of a pending invalidate).  This can happen if the original
42212027Sjungma@eit.uni-kl.de        // request was for a read-only (non-exclusive) block, but we
42312027Sjungma@eit.uni-kl.de        // got an exclusive copy anyway because of the E part of the
42412027Sjungma@eit.uni-kl.de        // MOESI/MESI protocol.  Since we got the exclusive copy
42512027Sjungma@eit.uni-kl.de        // there's no need to defer the targets, so move them up to
42612027Sjungma@eit.uni-kl.de        // the regular target list.
42712027Sjungma@eit.uni-kl.de        assert(!targets.needsExclusive);
42812027Sjungma@eit.uni-kl.de        targets.needsExclusive = true;
42912027Sjungma@eit.uni-kl.de        // if any of the deferred targets were upper-level cache
43012027Sjungma@eit.uni-kl.de        // requests marked downstreamPending, need to clear that
43112027Sjungma@eit.uni-kl.de        assert(!downstreamPending);  // not pending here anymore
43212027Sjungma@eit.uni-kl.de        deferredTargets.clearDownstreamPending();
43312027Sjungma@eit.uni-kl.de        // this clears out deferredTargets too
43412027Sjungma@eit.uni-kl.de        targets.splice(targets.end(), deferredTargets);
43512027Sjungma@eit.uni-kl.de        deferredTargets.resetFlags();
43612027Sjungma@eit.uni-kl.de    }
43712027Sjungma@eit.uni-kl.de}
43812027Sjungma@eit.uni-kl.de
43912027Sjungma@eit.uni-kl.de
44012027Sjungma@eit.uni-kl.debool
44112027Sjungma@eit.uni-kl.deMSHR::checkFunctional(PacketPtr pkt)
44212027Sjungma@eit.uni-kl.de{
44312027Sjungma@eit.uni-kl.de    // For printing, we treat the MSHR as a whole as single entity.
44412027Sjungma@eit.uni-kl.de    // For other requests, we iterate over the individual targets
44512027Sjungma@eit.uni-kl.de    // since that's where the actual data lies.
44612027Sjungma@eit.uni-kl.de    if (pkt->isPrint()) {
44712027Sjungma@eit.uni-kl.de        pkt->checkFunctional(this, addr, isSecure, size, NULL);
44812027Sjungma@eit.uni-kl.de        return false;
44912027Sjungma@eit.uni-kl.de    } else {
45012027Sjungma@eit.uni-kl.de        return (targets.checkFunctional(pkt) ||
45112027Sjungma@eit.uni-kl.de                deferredTargets.checkFunctional(pkt));
45212027Sjungma@eit.uni-kl.de    }
45312027Sjungma@eit.uni-kl.de}
45412027Sjungma@eit.uni-kl.de
45512027Sjungma@eit.uni-kl.de
45612027Sjungma@eit.uni-kl.devoid
45712027Sjungma@eit.uni-kl.deMSHR::print(std::ostream &os, int verbosity, const std::string &prefix) const
45812027Sjungma@eit.uni-kl.de{
45912027Sjungma@eit.uni-kl.de    ccprintf(os, "%s[%x:%x](%s) %s %s %s state: %s %s %s %s %s\n",
46012027Sjungma@eit.uni-kl.de             prefix, addr, addr+size-1,
46112027Sjungma@eit.uni-kl.de             isSecure ? "s" : "ns",
46212027Sjungma@eit.uni-kl.de             isForward ? "Forward" : "",
46312027Sjungma@eit.uni-kl.de             isForwardNoResponse() ? "ForwNoResp" : "",
46412027Sjungma@eit.uni-kl.de             needsExclusive() ? "Excl" : "",
46512027Sjungma@eit.uni-kl.de             _isUncacheable ? "Unc" : "",
46612027Sjungma@eit.uni-kl.de             inService ? "InSvc" : "",
46712027Sjungma@eit.uni-kl.de             downstreamPending ? "DwnPend" : "",
46812027Sjungma@eit.uni-kl.de             hasPostInvalidate() ? "PostInv" : "",
46912027Sjungma@eit.uni-kl.de             hasPostDowngrade() ? "PostDowngr" : "");
47012027Sjungma@eit.uni-kl.de
47112027Sjungma@eit.uni-kl.de    ccprintf(os, "%s  Targets:\n", prefix);
47212027Sjungma@eit.uni-kl.de    targets.print(os, verbosity, prefix + "    ");
47312027Sjungma@eit.uni-kl.de    if (!deferredTargets.empty()) {
47412027Sjungma@eit.uni-kl.de        ccprintf(os, "%s  Deferred Targets:\n", prefix);
47512027Sjungma@eit.uni-kl.de        deferredTargets.print(os, verbosity, prefix + "      ");
47612027Sjungma@eit.uni-kl.de    }
47712027Sjungma@eit.uni-kl.de}
47812027Sjungma@eit.uni-kl.de
47912027Sjungma@eit.uni-kl.destd::string
48012027Sjungma@eit.uni-kl.deMSHR::print() const
48112027Sjungma@eit.uni-kl.de{
48212027Sjungma@eit.uni-kl.de    ostringstream str;
48312027Sjungma@eit.uni-kl.de    print(str);
48412027Sjungma@eit.uni-kl.de    return str.str();
48512027Sjungma@eit.uni-kl.de}
48612027Sjungma@eit.uni-kl.de