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