mshr.cc revision 10424:a910aeb89098
110037SARM gem5 Developers/* 213506Sanouk.vanlaer@arm.com * Copyright (c) 2012-2013 ARM Limited 310037SARM gem5 Developers * All rights reserved. 410037SARM gem5 Developers * 510037SARM gem5 Developers * The license below extends only to copyright in the software and shall 610037SARM gem5 Developers * not be construed as granting a license to any other intellectual 710037SARM gem5 Developers * property including but not limited to intellectual property relating 810037SARM gem5 Developers * to a hardware implementation of the functionality of the software 910037SARM gem5 Developers * licensed hereunder. You may use the software subject to the license 1010037SARM gem5 Developers * terms below provided that you ensure that this notice is replicated 1110037SARM gem5 Developers * unmodified and in its entirety in all distributions of the software, 1210037SARM gem5 Developers * modified or unmodified, in source code or in binary form. 1310037SARM gem5 Developers * 1410037SARM gem5 Developers * Copyright (c) 2002-2005 The Regents of The University of Michigan 1510037SARM gem5 Developers * Copyright (c) 2010 Advanced Micro Devices, Inc. 1610037SARM gem5 Developers * All rights reserved. 1710037SARM gem5 Developers * 1810037SARM gem5 Developers * Redistribution and use in source and binary forms, with or without 1910037SARM gem5 Developers * modification, are permitted provided that the following conditions are 2010037SARM gem5 Developers * met: redistributions of source code must retain the above copyright 2110037SARM gem5 Developers * notice, this list of conditions and the following disclaimer; 2210037SARM gem5 Developers * redistributions in binary form must reproduce the above copyright 2310037SARM gem5 Developers * notice, this list of conditions and the following disclaimer in the 2410037SARM gem5 Developers * documentation and/or other materials provided with the distribution; 2510037SARM gem5 Developers * neither the name of the copyright holders nor the names of its 2610037SARM gem5 Developers * contributors may be used to endorse or promote products derived from 2710037SARM gem5 Developers * this software without specific prior written permission. 2810037SARM gem5 Developers * 2910037SARM gem5 Developers * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3010037SARM gem5 Developers * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3110037SARM gem5 Developers * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3210037SARM gem5 Developers * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3310037SARM gem5 Developers * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3410037SARM gem5 Developers * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3510037SARM gem5 Developers * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3610037SARM gem5 Developers * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3710037SARM gem5 Developers * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3810037SARM gem5 Developers * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3910037SARM gem5 Developers * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4011793Sbrandon.potter@amd.com * 4111793Sbrandon.potter@amd.com * Authors: Erik Hallnor 4210037SARM gem5 Developers * Dave Greene 4310037SARM gem5 Developers */ 4410037SARM gem5 Developers 4510037SARM gem5 Developers/** 4610037SARM gem5 Developers * @file 4710037SARM gem5 Developers * Miss Status and Handling Register (MSHR) definitions. 4810037SARM gem5 Developers */ 4910037SARM gem5 Developers 5013506Sanouk.vanlaer@arm.com#include <algorithm> 5113506Sanouk.vanlaer@arm.com#include <cassert> 5213506Sanouk.vanlaer@arm.com#include <string> 5310037SARM gem5 Developers#include <vector> 5410037SARM gem5 Developers 5512132Sspwilson2@wisc.edu#include "base/misc.hh" 5612132Sspwilson2@wisc.edu#include "base/types.hh" 5712132Sspwilson2@wisc.edu#include "debug/Cache.hh" 5810037SARM gem5 Developers#include "mem/cache/cache.hh" 5910037SARM gem5 Developers#include "mem/cache/mshr.hh" 6010037SARM gem5 Developers#include "sim/core.hh" 6110037SARM gem5 Developers 6210037SARM gem5 Developersusing namespace std; 6310037SARM gem5 Developers 6412092Sspwilson2@wisc.eduMSHR::MSHR() : readyTime(0), _isUncacheable(false), downstreamPending(false), 6512092Sspwilson2@wisc.edu pendingDirty(false), postInvalidate(false), 6612092Sspwilson2@wisc.edu postDowngrade(false), queue(NULL), order(0), addr(0), size(0), 6712092Sspwilson2@wisc.edu isSecure(false), inService(false), isForward(false), 6812092Sspwilson2@wisc.edu threadNum(InvalidThreadID), data(NULL) 6912092Sspwilson2@wisc.edu{ 7010037SARM gem5 Developers} 7110037SARM gem5 Developers 7210037SARM gem5 Developers 7310037SARM gem5 DevelopersMSHR::TargetList::TargetList() 7410037SARM gem5 Developers : needsExclusive(false), hasUpgrade(false) 7510037SARM gem5 Developers{} 7610037SARM gem5 Developers 7710037SARM gem5 Developers 7810037SARM gem5 Developersinline void 7910037SARM gem5 DevelopersMSHR::TargetList::add(PacketPtr pkt, Tick readyTime, 8010037SARM gem5 Developers Counter order, Target::Source source, bool markPending) 8110037SARM gem5 Developers{ 8210037SARM gem5 Developers if (source != Target::FromSnoop) { 8310037SARM gem5 Developers if (pkt->needsExclusive()) { 8410037SARM gem5 Developers needsExclusive = true; 8510037SARM gem5 Developers } 8610037SARM gem5 Developers 8710037SARM gem5 Developers // StoreCondReq is effectively an upgrade if it's in an MSHR 8810037SARM gem5 Developers // since it would have been failed already if we didn't have a 8910037SARM gem5 Developers // read-only copy 9010037SARM gem5 Developers if (pkt->isUpgrade() || pkt->cmd == MemCmd::StoreCondReq) { 9110037SARM gem5 Developers hasUpgrade = true; 9210037SARM gem5 Developers } 9310037SARM gem5 Developers } 9410037SARM gem5 Developers 9510037SARM gem5 Developers if (markPending) { 9610037SARM gem5 Developers // Iterate over the SenderState stack and see if we find 9710037SARM gem5 Developers // an MSHR entry. If we do, set the downstreamPending 9810037SARM gem5 Developers // flag. Otherwise, do nothing. 9910037SARM gem5 Developers MSHR *mshr = pkt->findNextSenderState<MSHR>(); 10010037SARM gem5 Developers if (mshr != NULL) { 10111005Sandreas.sandberg@arm.com assert(!mshr->downstreamPending); 10210037SARM gem5 Developers mshr->downstreamPending = true; 10310037SARM gem5 Developers } 10410037SARM gem5 Developers } 10510037SARM gem5 Developers 10610037SARM gem5 Developers push_back(Target(pkt, readyTime, order, source, markPending)); 10710037SARM gem5 Developers} 10810037SARM gem5 Developers 10913230Sgabeblack@google.com 11010037SARM gem5 Developersstatic void 11110037SARM gem5 DevelopersreplaceUpgrade(PacketPtr pkt) 11210037SARM gem5 Developers{ 11310037SARM gem5 Developers if (pkt->cmd == MemCmd::UpgradeReq) { 11413230Sgabeblack@google.com pkt->cmd = MemCmd::ReadExReq; 11510037SARM gem5 Developers DPRINTF(Cache, "Replacing UpgradeReq with ReadExReq\n"); 11610037SARM gem5 Developers } else if (pkt->cmd == MemCmd::SCUpgradeReq) { 11710037SARM gem5 Developers pkt->cmd = MemCmd::SCUpgradeFailReq; 11813230Sgabeblack@google.com DPRINTF(Cache, "Replacing SCUpgradeReq with SCUpgradeFailReq\n"); 11910037SARM gem5 Developers } else if (pkt->cmd == MemCmd::StoreCondReq) { 12010037SARM gem5 Developers pkt->cmd = MemCmd::StoreCondFailReq; 12110037SARM gem5 Developers DPRINTF(Cache, "Replacing StoreCondReq with StoreCondFailReq\n"); 12210037SARM gem5 Developers } 12310037SARM gem5 Developers} 12410037SARM gem5 Developers 12510037SARM gem5 Developers 12610037SARM gem5 Developersvoid 12710037SARM gem5 DevelopersMSHR::TargetList::replaceUpgrades() 12810037SARM gem5 Developers{ 12910037SARM gem5 Developers if (!hasUpgrade) 13013506Sanouk.vanlaer@arm.com return; 13113506Sanouk.vanlaer@arm.com 13213506Sanouk.vanlaer@arm.com Iterator end_i = end(); 13310037SARM gem5 Developers for (Iterator i = begin(); i != end_i; ++i) { 13410037SARM gem5 Developers replaceUpgrade(i->pkt); 13510037SARM gem5 Developers } 13610037SARM gem5 Developers 13710037SARM gem5 Developers hasUpgrade = false; 13810037SARM gem5 Developers} 13910037SARM gem5 Developers 14010037SARM gem5 Developers 14110037SARM gem5 Developersvoid 14210037SARM gem5 DevelopersMSHR::TargetList::clearDownstreamPending() 14310037SARM gem5 Developers{ 14410037SARM gem5 Developers Iterator end_i = end(); 14510037SARM gem5 Developers for (Iterator i = begin(); i != end_i; ++i) { 14610037SARM gem5 Developers if (i->markedPending) { 14710037SARM gem5 Developers // Iterate over the SenderState stack and see if we find 14811005Sandreas.sandberg@arm.com // an MSHR entry. If we find one, clear the 14910037SARM gem5 Developers // downstreamPending flag by calling 15010037SARM gem5 Developers // clearDownstreamPending(). This recursively clears the 15110037SARM gem5 Developers // downstreamPending flag in all caches this packet has 15210037SARM gem5 Developers // passed through. 15310037SARM gem5 Developers MSHR *mshr = i->pkt->findNextSenderState<MSHR>(); 15410037SARM gem5 Developers if (mshr != NULL) { 15510037SARM gem5 Developers mshr->clearDownstreamPending(); 15610037SARM gem5 Developers } 15710037SARM gem5 Developers } 15810037SARM gem5 Developers } 15910037SARM gem5 Developers} 16010037SARM gem5 Developers 16110037SARM gem5 Developers 16210037SARM gem5 Developersbool 16310037SARM gem5 DevelopersMSHR::TargetList::checkFunctional(PacketPtr pkt) 16410037SARM gem5 Developers{ 16510037SARM gem5 Developers Iterator end_i = end(); 16613230Sgabeblack@google.com for (Iterator i = begin(); i != end_i; ++i) { 16710037SARM gem5 Developers if (pkt->checkFunctional(i->pkt)) { 16810037SARM gem5 Developers return true; 16910037SARM gem5 Developers } 17013230Sgabeblack@google.com } 17110037SARM gem5 Developers 17210037SARM gem5 Developers return false; 17310037SARM gem5 Developers} 17413230Sgabeblack@google.com 17510037SARM gem5 Developers 17610037SARM gem5 Developersvoid 17710037SARM gem5 DevelopersMSHR::TargetList:: 17810037SARM gem5 Developersprint(std::ostream &os, int verbosity, const std::string &prefix) const 17910037SARM gem5 Developers{ 18010037SARM gem5 Developers ConstIterator end_i = end(); 18110037SARM gem5 Developers for (ConstIterator i = begin(); i != end_i; ++i) { 18210037SARM gem5 Developers const char *s; 18310037SARM gem5 Developers switch (i->source) { 18410037SARM gem5 Developers case Target::FromCPU: 18510037SARM gem5 Developers s = "FromCPU"; 18610037SARM gem5 Developers break; 18710037SARM gem5 Developers case Target::FromSnoop: 18813230Sgabeblack@google.com s = "FromSnoop"; 18910037SARM gem5 Developers break; 19010037SARM gem5 Developers case Target::FromPrefetcher: 19110037SARM gem5 Developers s = "FromPrefetcher"; 19213230Sgabeblack@google.com break; 19310037SARM gem5 Developers default: 19410037SARM gem5 Developers s = ""; 19510037SARM gem5 Developers break; 19613230Sgabeblack@google.com } 19710037SARM gem5 Developers ccprintf(os, "%s%s: ", prefix, s); 19810037SARM gem5 Developers i->pkt->print(os, verbosity, ""); 19910037SARM gem5 Developers } 20010037SARM gem5 Developers} 20110037SARM gem5 Developers 20210037SARM gem5 Developers 20310037SARM gem5 Developersvoid 20410037SARM gem5 DevelopersMSHR::allocate(Addr _addr, int _size, PacketPtr target, Tick whenReady, 20513230Sgabeblack@google.com Counter _order) 20610037SARM gem5 Developers{ 20710037SARM gem5 Developers addr = _addr; 20810037SARM gem5 Developers size = _size; 20910037SARM gem5 Developers isSecure = target->isSecure(); 21010037SARM gem5 Developers readyTime = whenReady; 21110037SARM gem5 Developers order = _order; 21210037SARM gem5 Developers assert(target); 21310037SARM gem5 Developers isForward = false; 21413230Sgabeblack@google.com _isUncacheable = target->req->isUncacheable(); 21510037SARM gem5 Developers inService = false; 21610037SARM gem5 Developers downstreamPending = false; 21710037SARM gem5 Developers threadNum = 0; 21810037SARM gem5 Developers assert(targets.isReset()); 21913230Sgabeblack@google.com // Don't know of a case where we would allocate a new MSHR for a 22010037SARM gem5 Developers // snoop (mem-side request), so set source according to request here 22110037SARM gem5 Developers Target::Source source = (target->cmd == MemCmd::HardPFReq) ? 22210037SARM gem5 Developers Target::FromPrefetcher : Target::FromCPU; 22310037SARM gem5 Developers targets.add(target, whenReady, _order, source, true); 22410037SARM gem5 Developers assert(deferredTargets.isReset()); 22510037SARM gem5 Developers data = NULL; 22613230Sgabeblack@google.com} 22710037SARM gem5 Developers 22810037SARM gem5 Developers 22910037SARM gem5 Developersvoid 23010037SARM gem5 DevelopersMSHR::clearDownstreamPending() 23110037SARM gem5 Developers{ 23210037SARM gem5 Developers assert(downstreamPending); 23310037SARM gem5 Developers downstreamPending = false; 23410037SARM gem5 Developers // recursively clear flag on any MSHRs we will be forwarding 23510037SARM gem5 Developers // responses to 23610037SARM gem5 Developers targets.clearDownstreamPending(); 23710037SARM gem5 Developers} 23810037SARM gem5 Developers 23910037SARM gem5 Developersbool 24010037SARM gem5 DevelopersMSHR::markInService(PacketPtr pkt) 24110037SARM gem5 Developers{ 24211005Sandreas.sandberg@arm.com assert(!inService); 24310037SARM gem5 Developers if (isForwardNoResponse()) { 24410037SARM gem5 Developers // we just forwarded the request packet & don't expect a 24510037SARM gem5 Developers // response, so get rid of it 24613230Sgabeblack@google.com assert(getNumTargets() == 1); 24713230Sgabeblack@google.com popTarget(); 24810037SARM gem5 Developers return true; 24910037SARM gem5 Developers } 25010037SARM gem5 Developers 25113230Sgabeblack@google.com assert(pkt != NULL); 25210037SARM gem5 Developers inService = true; 25310037SARM gem5 Developers pendingDirty = (targets.needsExclusive || 25413230Sgabeblack@google.com (!pkt->sharedAsserted() && pkt->memInhibitAsserted())); 25510037SARM gem5 Developers postInvalidate = postDowngrade = false; 25610037SARM gem5 Developers 25710037SARM gem5 Developers if (!downstreamPending) { 25810037SARM gem5 Developers // let upstream caches know that the request has made it to a 25910037SARM gem5 Developers // level where it's going to get a response 26013230Sgabeblack@google.com targets.clearDownstreamPending(); 26110037SARM gem5 Developers } 26210037SARM gem5 Developers return false; 26310037SARM gem5 Developers} 26410037SARM gem5 Developers 26510037SARM gem5 Developers 26610037SARM gem5 Developersvoid 26710037SARM gem5 DevelopersMSHR::deallocate() 26810037SARM gem5 Developers{ 26910037SARM gem5 Developers assert(targets.empty()); 27010037SARM gem5 Developers targets.resetFlags(); 27110037SARM gem5 Developers assert(deferredTargets.isReset()); 27210037SARM gem5 Developers inService = false; 27310037SARM gem5 Developers} 27410037SARM gem5 Developers 27513230Sgabeblack@google.com/* 27613230Sgabeblack@google.com * Adds a target to an MSHR 27710037SARM gem5 Developers */ 27810037SARM gem5 Developersvoid 27910037SARM gem5 DevelopersMSHR::allocateTarget(PacketPtr pkt, Tick whenReady, Counter _order) 28010037SARM gem5 Developers{ 28110037SARM gem5 Developers // if there's a request already in service for this MSHR, we will 28210037SARM gem5 Developers // have to defer the new target until after the response if any of 28310037SARM gem5 Developers // the following are true: 28410037SARM gem5 Developers // - there are other targets already deferred 28510037SARM gem5 Developers // - there's a pending invalidate to be applied after the response 28610037SARM gem5 Developers // comes back (but before this target is processed) 28710037SARM gem5 Developers // - this target requires an exclusive block and either we're not 28810037SARM gem5 Developers // getting an exclusive block back or we have already snooped 28910037SARM gem5 Developers // another read request that will downgrade our exclusive block 29010037SARM gem5 Developers // to shared 29111005Sandreas.sandberg@arm.com 29210037SARM gem5 Developers // assume we'd never issue a prefetch when we've got an 29313230Sgabeblack@google.com // outstanding miss 29413230Sgabeblack@google.com assert(pkt->cmd != MemCmd::HardPFReq); 29510037SARM gem5 Developers 29610037SARM gem5 Developers if (inService && 29710037SARM gem5 Developers (!deferredTargets.empty() || hasPostInvalidate() || 29810037SARM gem5 Developers (pkt->needsExclusive() && 29910037SARM gem5 Developers (!isPendingDirty() || hasPostDowngrade() || isForward)))) { 30010037SARM gem5 Developers // need to put on deferred list 30110037SARM gem5 Developers if (hasPostInvalidate()) 30210037SARM gem5 Developers replaceUpgrade(pkt); 30310037SARM gem5 Developers deferredTargets.add(pkt, whenReady, _order, Target::FromCPU, true); 30410037SARM gem5 Developers } else { 30510037SARM gem5 Developers // No request outstanding, or still OK to append to 30610037SARM gem5 Developers // outstanding request: append to regular target list. Only 30710037SARM gem5 Developers // mark pending if current request hasn't been issued yet 30810037SARM gem5 Developers // (isn't in service). 30910037SARM gem5 Developers targets.add(pkt, whenReady, _order, Target::FromCPU, !inService); 31013230Sgabeblack@google.com } 31110037SARM gem5 Developers} 31210037SARM gem5 Developers 31310037SARM gem5 Developersbool 31410037SARM gem5 DevelopersMSHR::handleSnoop(PacketPtr pkt, Counter _order) 31513230Sgabeblack@google.com{ 31610037SARM gem5 Developers DPRINTF(Cache, "%s for %s address %x size %d\n", __func__, 31710037SARM gem5 Developers pkt->cmdString(), pkt->getAddr(), pkt->getSize()); 31810037SARM gem5 Developers if (!inService || (pkt->isExpressSnoop() && downstreamPending)) { 31910037SARM gem5 Developers // Request has not been issued yet, or it's been issued 32010037SARM gem5 Developers // locally but is buffered unissued at some downstream cache 32110037SARM gem5 Developers // which is forwarding us this snoop. Either way, the packet 32210037SARM gem5 Developers // we're snooping logically precedes this MSHR's request, so 32310037SARM gem5 Developers // the snoop has no impact on the MSHR, but must be processed 32410037SARM gem5 Developers // in the standard way by the cache. The only exception is 32510037SARM gem5 Developers // that if we're an L2+ cache buffering an UpgradeReq from a 32610037SARM gem5 Developers // higher-level cache, and the snoop is invalidating, then our 32710037SARM gem5 Developers // buffered upgrades must be converted to read exclusives, 32810037SARM gem5 Developers // since the upper-level cache no longer has a valid copy. 32910037SARM gem5 Developers // That is, even though the upper-level cache got out on its 33010037SARM gem5 Developers // local bus first, some other invalidating transaction 33110037SARM gem5 Developers // reached the global bus before the upgrade did. 33210037SARM gem5 Developers if (pkt->needsExclusive()) { 33310037SARM gem5 Developers targets.replaceUpgrades(); 33410037SARM gem5 Developers deferredTargets.replaceUpgrades(); 33513230Sgabeblack@google.com } 33610037SARM gem5 Developers 33710037SARM gem5 Developers return false; 33810037SARM gem5 Developers } 33910037SARM gem5 Developers 34010037SARM gem5 Developers // From here on down, the request issued by this MSHR logically 34110037SARM gem5 Developers // precedes the request we're snooping. 34210037SARM gem5 Developers if (pkt->needsExclusive()) { 34310037SARM gem5 Developers // snooped request still precedes the re-request we'll have to 34410037SARM gem5 Developers // issue for deferred targets, if any... 34510037SARM gem5 Developers deferredTargets.replaceUpgrades(); 34610037SARM gem5 Developers } 34710037SARM gem5 Developers 34810037SARM gem5 Developers if (hasPostInvalidate()) { 34910037SARM gem5 Developers // a prior snoop has already appended an invalidation, so 35010037SARM gem5 Developers // logically we don't have the block anymore; no need for 35110037SARM gem5 Developers // further snooping. 35210037SARM gem5 Developers return true; 35310037SARM gem5 Developers } 35410037SARM gem5 Developers 35510037SARM gem5 Developers if (isPendingDirty() || pkt->isInvalidate()) { 35610037SARM gem5 Developers // We need to save and replay the packet in two cases: 35710037SARM gem5 Developers // 1. We're awaiting an exclusive copy, so ownership is pending, 35810037SARM gem5 Developers // and we need to respond after we receive data. 35910037SARM gem5 Developers // 2. It's an invalidation (e.g., UpgradeReq), and we need 36010037SARM gem5 Developers // to forward the snoop up the hierarchy after the current 36110037SARM gem5 Developers // transaction completes. 36210037SARM gem5 Developers 36310037SARM gem5 Developers // Actual target device (typ. a memory) will delete the 36410037SARM gem5 Developers // packet on reception, so we need to save a copy here. 36510037SARM gem5 Developers PacketPtr cp_pkt = new Packet(pkt, true); 36610037SARM gem5 Developers targets.add(cp_pkt, curTick(), _order, Target::FromSnoop, 36710037SARM gem5 Developers downstreamPending && targets.needsExclusive); 36810037SARM gem5 Developers 36910037SARM gem5 Developers if (isPendingDirty()) { 37010037SARM gem5 Developers pkt->assertMemInhibit(); 37110037SARM gem5 Developers pkt->setSupplyExclusive(); 37210037SARM gem5 Developers } 37310037SARM gem5 Developers 37410037SARM gem5 Developers if (pkt->needsExclusive()) { 37510037SARM gem5 Developers // This transaction will take away our pending copy 37610037SARM gem5 Developers postInvalidate = true; 37710037SARM gem5 Developers } 37810037SARM gem5 Developers } 37912132Sspwilson2@wisc.edu 38012132Sspwilson2@wisc.edu if (!pkt->needsExclusive()) { 38112132Sspwilson2@wisc.edu // This transaction will get a read-shared copy, downgrading 38212132Sspwilson2@wisc.edu // our copy if we had an exclusive one 38312132Sspwilson2@wisc.edu postDowngrade = true; 38412132Sspwilson2@wisc.edu pkt->assertShared(); 38512132Sspwilson2@wisc.edu } 38610037SARM gem5 Developers 38710037SARM gem5 Developers return true; 38810037SARM gem5 Developers} 38910037SARM gem5 Developers 39010037SARM gem5 Developers 39110037SARM gem5 Developersbool 39210037SARM gem5 DevelopersMSHR::promoteDeferredTargets() 39310037SARM gem5 Developers{ 39410037SARM gem5 Developers assert(targets.empty()); 39510037SARM gem5 Developers if (deferredTargets.empty()) { 39610037SARM gem5 Developers return false; 39710037SARM gem5 Developers } 39810037SARM gem5 Developers 39910037SARM gem5 Developers // swap targets & deferredTargets lists 40010037SARM gem5 Developers std::swap(targets, deferredTargets); 40110037SARM gem5 Developers 40210037SARM gem5 Developers // clear deferredTargets flags 40310037SARM gem5 Developers deferredTargets.resetFlags(); 40411005Sandreas.sandberg@arm.com 40510037SARM gem5 Developers order = targets.front().order; 40610037SARM gem5 Developers readyTime = std::max(curTick(), targets.front().readyTime); 40710037SARM gem5 Developers 40810037SARM gem5 Developers return true; 40910037SARM gem5 Developers} 41010037SARM gem5 Developers 41110037SARM gem5 Developers 41210037SARM gem5 Developersvoid 41310037SARM gem5 DevelopersMSHR::handleFill(Packet *pkt, CacheBlk *blk) 41410037SARM gem5 Developers{ 41510037SARM gem5 Developers if (!pkt->sharedAsserted() 41610037SARM gem5 Developers && !(hasPostInvalidate() || hasPostDowngrade()) 41710037SARM gem5 Developers && deferredTargets.needsExclusive) { 41810037SARM gem5 Developers // We got an exclusive response, but we have deferred targets 41910037SARM gem5 Developers // which are waiting to request an exclusive copy (not because 42010037SARM gem5 Developers // of a pending invalidate). This can happen if the original 42110037SARM gem5 Developers // request was for a read-only (non-exclusive) block, but we 42210037SARM gem5 Developers // got an exclusive copy anyway because of the E part of the 42310037SARM gem5 Developers // MOESI/MESI protocol. Since we got the exclusive copy 42410037SARM gem5 Developers // there's no need to defer the targets, so move them up to 42510037SARM gem5 Developers // the regular target list. 42610037SARM gem5 Developers assert(!targets.needsExclusive); 42710037SARM gem5 Developers targets.needsExclusive = true; 42810037SARM gem5 Developers // if any of the deferred targets were upper-level cache 42910037SARM gem5 Developers // requests marked downstreamPending, need to clear that 43010037SARM gem5 Developers assert(!downstreamPending); // not pending here anymore 43110037SARM gem5 Developers deferredTargets.clearDownstreamPending(); 43210037SARM gem5 Developers // this clears out deferredTargets too 43310037SARM gem5 Developers targets.splice(targets.end(), deferredTargets); 43410037SARM gem5 Developers deferredTargets.resetFlags(); 43510037SARM gem5 Developers } 43610037SARM gem5 Developers} 43710037SARM gem5 Developers 43810037SARM gem5 Developers 43910037SARM gem5 Developersbool 44010037SARM gem5 DevelopersMSHR::checkFunctional(PacketPtr pkt) 44110037SARM gem5 Developers{ 44210037SARM gem5 Developers // For printing, we treat the MSHR as a whole as single entity. 44310037SARM gem5 Developers // For other requests, we iterate over the individual targets 44410037SARM gem5 Developers // since that's where the actual data lies. 44510037SARM gem5 Developers if (pkt->isPrint()) { 44610037SARM gem5 Developers pkt->checkFunctional(this, addr, isSecure, size, NULL); 44710037SARM gem5 Developers return false; 44810037SARM gem5 Developers } else { 44910037SARM gem5 Developers return (targets.checkFunctional(pkt) || 45010037SARM gem5 Developers deferredTargets.checkFunctional(pkt)); 45110037SARM gem5 Developers } 45210037SARM gem5 Developers} 45310037SARM gem5 Developers 45410037SARM gem5 Developers 45510037SARM gem5 Developersvoid 45610037SARM gem5 DevelopersMSHR::print(std::ostream &os, int verbosity, const std::string &prefix) const 45710037SARM gem5 Developers{ 45810905Sandreas.sandberg@arm.com ccprintf(os, "%s[%x:%x](%s) %s %s %s state: %s %s %s %s %s\n", 45910037SARM gem5 Developers prefix, addr, addr+size-1, 46010037SARM gem5 Developers isSecure ? "s" : "ns", 46110037SARM gem5 Developers isForward ? "Forward" : "", 46210037SARM gem5 Developers isForwardNoResponse() ? "ForwNoResp" : "", 46310037SARM gem5 Developers needsExclusive() ? "Excl" : "", 46410037SARM gem5 Developers _isUncacheable ? "Unc" : "", 46510037SARM gem5 Developers inService ? "InSvc" : "", 46610037SARM gem5 Developers downstreamPending ? "DwnPend" : "", 46710037SARM gem5 Developers hasPostInvalidate() ? "PostInv" : "", 46810037SARM gem5 Developers hasPostDowngrade() ? "PostDowngr" : ""); 46910037SARM gem5 Developers 47010037SARM gem5 Developers ccprintf(os, "%s Targets:\n", prefix); 47110037SARM gem5 Developers targets.print(os, verbosity, prefix + " "); 47210037SARM gem5 Developers if (!deferredTargets.empty()) { 47310037SARM gem5 Developers ccprintf(os, "%s Deferred Targets:\n", prefix); 47410037SARM gem5 Developers deferredTargets.print(os, verbosity, prefix + " "); 47510037SARM gem5 Developers } 47610037SARM gem5 Developers} 47710037SARM gem5 Developers 47810905Sandreas.sandberg@arm.comstd::string 47910905Sandreas.sandberg@arm.comMSHR::print() const 48010905Sandreas.sandberg@arm.com{ 48110037SARM gem5 Developers ostringstream str; 48210905Sandreas.sandberg@arm.com print(str); 48310905Sandreas.sandberg@arm.com return str.str(); 48410905Sandreas.sandberg@arm.com} 48510905Sandreas.sandberg@arm.com