mshr.cc revision 7669:cc222ba29079
12810Srdreslin@umich.edu/* 212500Snikos.nikoleris@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 311051Sandreas.hansson@arm.com * Copyright (c) 2010 Advanced Micro Devices, Inc. 411051Sandreas.hansson@arm.com * All rights reserved. 511051Sandreas.hansson@arm.com * 611051Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 711051Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 811051Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 911051Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 1011051Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 1111051Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 1211051Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 1311051Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 1411051Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 1511051Sandreas.hansson@arm.com * this software without specific prior written permission. 162810Srdreslin@umich.edu * 172810Srdreslin@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 182810Srdreslin@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 192810Srdreslin@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 202810Srdreslin@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 212810Srdreslin@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 222810Srdreslin@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 232810Srdreslin@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 242810Srdreslin@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 252810Srdreslin@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 262810Srdreslin@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 272810Srdreslin@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282810Srdreslin@umich.edu * 292810Srdreslin@umich.edu * Authors: Erik Hallnor 302810Srdreslin@umich.edu * Dave Greene 312810Srdreslin@umich.edu */ 322810Srdreslin@umich.edu 332810Srdreslin@umich.edu/** 342810Srdreslin@umich.edu * @file 352810Srdreslin@umich.edu * Miss Status and Handling Register (MSHR) definitions. 362810Srdreslin@umich.edu */ 372810Srdreslin@umich.edu 382810Srdreslin@umich.edu#include <algorithm> 392810Srdreslin@umich.edu#include <cassert> 402810Srdreslin@umich.edu#include <string> 412810Srdreslin@umich.edu#include <vector> 4211051Sandreas.hansson@arm.com 4311051Sandreas.hansson@arm.com#include "base/misc.hh" 442810Srdreslin@umich.edu#include "base/types.hh" 4511051Sandreas.hansson@arm.com#include "mem/cache/cache.hh" 4611051Sandreas.hansson@arm.com#include "mem/cache/mshr.hh" 4712349Snikos.nikoleris@arm.com#include "sim/core.hh" 482810Srdreslin@umich.edu 492810Srdreslin@umich.eduusing namespace std; 502810Srdreslin@umich.edu 512810Srdreslin@umich.eduMSHR::MSHR() 5211051Sandreas.hansson@arm.com{ 532810Srdreslin@umich.edu inService = false; 542810Srdreslin@umich.edu ntargets = 0; 5511051Sandreas.hansson@arm.com threadNum = InvalidThreadID; 562810Srdreslin@umich.edu targets = new TargetList(); 5712724Snikos.nikoleris@arm.com deferredTargets = new TargetList(); 5812724Snikos.nikoleris@arm.com} 5912724Snikos.nikoleris@arm.com 6012334Sgabeblack@google.com 6112724Snikos.nikoleris@arm.comMSHR::TargetList::TargetList() 6211051Sandreas.hansson@arm.com : needsExclusive(false), hasUpgrade(false) 6311051Sandreas.hansson@arm.com{} 6411051Sandreas.hansson@arm.com 6511288Ssteve.reinhardt@amd.com 6612724Snikos.nikoleris@arm.cominline void 6713223Sodanrc@yahoo.com.brMSHR::TargetList::add(PacketPtr pkt, Tick readyTime, 6811051Sandreas.hansson@arm.com Counter order, Target::Source source, bool markPending) 6912724Snikos.nikoleris@arm.com{ 7012724Snikos.nikoleris@arm.com if (source != Target::FromSnoop) { 7112724Snikos.nikoleris@arm.com if (pkt->needsExclusive()) { 7212724Snikos.nikoleris@arm.com needsExclusive = true; 7311051Sandreas.hansson@arm.com } 7411053Sandreas.hansson@arm.com 7511053Sandreas.hansson@arm.com // StoreCondReq is effectively an upgrade if it's in an MSHR 7612724Snikos.nikoleris@arm.com // since it would have been failed already if we didn't have a 7711051Sandreas.hansson@arm.com // read-only copy 7811051Sandreas.hansson@arm.com if (pkt->isUpgrade() || pkt->cmd == MemCmd::StoreCondReq) { 7911051Sandreas.hansson@arm.com hasUpgrade = true; 8011051Sandreas.hansson@arm.com } 8111601Sandreas.hansson@arm.com } 8211601Sandreas.hansson@arm.com 8311051Sandreas.hansson@arm.com if (markPending) { 8412724Snikos.nikoleris@arm.com MSHR *mshr = dynamic_cast<MSHR*>(pkt->senderState); 8511051Sandreas.hansson@arm.com if (mshr != NULL) { 8612724Snikos.nikoleris@arm.com assert(!mshr->downstreamPending); 8711600Sandreas.hansson@arm.com mshr->downstreamPending = true; 8811600Sandreas.hansson@arm.com } 8911051Sandreas.hansson@arm.com } 9011051Sandreas.hansson@arm.com 9111051Sandreas.hansson@arm.com push_back(Target(pkt, readyTime, order, source, markPending)); 9211284Sandreas.hansson@arm.com} 9311051Sandreas.hansson@arm.com 9411051Sandreas.hansson@arm.com 9511051Sandreas.hansson@arm.comstatic void 9611602Sandreas.hansson@arm.comreplaceUpgrade(PacketPtr pkt) 9711051Sandreas.hansson@arm.com{ 9811051Sandreas.hansson@arm.com if (pkt->cmd == MemCmd::UpgradeReq) { 9911284Sandreas.hansson@arm.com pkt->cmd = MemCmd::ReadExReq; 10011051Sandreas.hansson@arm.com DPRINTF(Cache, "Replacing UpgradeReq with ReadExReq\n"); 10111284Sandreas.hansson@arm.com } else if (pkt->cmd == MemCmd::SCUpgradeReq) { 10211602Sandreas.hansson@arm.com pkt->cmd = MemCmd::SCUpgradeFailReq; 10311051Sandreas.hansson@arm.com DPRINTF(Cache, "Replacing SCUpgradeReq with SCUpgradeFailReq\n"); 10411051Sandreas.hansson@arm.com } else if (pkt->cmd == MemCmd::StoreCondReq) { 10511284Sandreas.hansson@arm.com pkt->cmd = MemCmd::StoreCondFailReq; 10611051Sandreas.hansson@arm.com DPRINTF(Cache, "Replacing StoreCondReq with StoreCondFailReq\n"); 10711284Sandreas.hansson@arm.com } 10811284Sandreas.hansson@arm.com} 10911284Sandreas.hansson@arm.com 11011051Sandreas.hansson@arm.com 11111051Sandreas.hansson@arm.comvoid 11211051Sandreas.hansson@arm.comMSHR::TargetList::replaceUpgrades() 11311284Sandreas.hansson@arm.com{ 11411284Sandreas.hansson@arm.com if (!hasUpgrade) 11511284Sandreas.hansson@arm.com return; 11611284Sandreas.hansson@arm.com 11711051Sandreas.hansson@arm.com Iterator end_i = end(); 11811051Sandreas.hansson@arm.com for (Iterator i = begin(); i != end_i; ++i) { 11911051Sandreas.hansson@arm.com replaceUpgrade(i->pkt); 12011284Sandreas.hansson@arm.com } 12111284Sandreas.hansson@arm.com 12211284Sandreas.hansson@arm.com hasUpgrade = false; 12311197Sandreas.hansson@arm.com} 12411601Sandreas.hansson@arm.com 12511601Sandreas.hansson@arm.com 12611601Sandreas.hansson@arm.comvoid 12711601Sandreas.hansson@arm.comMSHR::TargetList::clearDownstreamPending() 12811601Sandreas.hansson@arm.com{ 12911601Sandreas.hansson@arm.com Iterator end_i = end(); 13011601Sandreas.hansson@arm.com for (Iterator i = begin(); i != end_i; ++i) { 13111601Sandreas.hansson@arm.com if (i->markedPending) { 13211197Sandreas.hansson@arm.com MSHR *mshr = dynamic_cast<MSHR*>(i->pkt->senderState); 13311601Sandreas.hansson@arm.com if (mshr != NULL) { 13411601Sandreas.hansson@arm.com mshr->clearDownstreamPending(); 13511601Sandreas.hansson@arm.com } 13611601Sandreas.hansson@arm.com } 13711601Sandreas.hansson@arm.com } 13811601Sandreas.hansson@arm.com} 13911601Sandreas.hansson@arm.com 14011051Sandreas.hansson@arm.com 14111051Sandreas.hansson@arm.combool 14211051Sandreas.hansson@arm.comMSHR::TargetList::checkFunctional(PacketPtr pkt) 14311051Sandreas.hansson@arm.com{ 14411051Sandreas.hansson@arm.com Iterator end_i = end(); 14511284Sandreas.hansson@arm.com for (Iterator i = begin(); i != end_i; ++i) { 14611284Sandreas.hansson@arm.com if (pkt->checkFunctional(i->pkt)) { 14711051Sandreas.hansson@arm.com return true; 14811051Sandreas.hansson@arm.com } 14911051Sandreas.hansson@arm.com } 15011051Sandreas.hansson@arm.com 15111284Sandreas.hansson@arm.com return false; 15211051Sandreas.hansson@arm.com} 15311051Sandreas.hansson@arm.com 15411051Sandreas.hansson@arm.com 15511051Sandreas.hansson@arm.comvoid 15611051Sandreas.hansson@arm.comMSHR::TargetList:: 15711051Sandreas.hansson@arm.comprint(std::ostream &os, int verbosity, const std::string &prefix) const 15811051Sandreas.hansson@arm.com{ 15911051Sandreas.hansson@arm.com ConstIterator end_i = end(); 16011051Sandreas.hansson@arm.com for (ConstIterator i = begin(); i != end_i; ++i) { 16111051Sandreas.hansson@arm.com const char *s; 16211051Sandreas.hansson@arm.com switch (i->source) { 16311051Sandreas.hansson@arm.com case Target::FromCPU: s = "FromCPU"; 16411051Sandreas.hansson@arm.com case Target::FromSnoop: s = "FromSnoop"; 16511051Sandreas.hansson@arm.com case Target::FromPrefetcher: s = "FromPrefetcher"; 16611051Sandreas.hansson@arm.com default: s = ""; 16711051Sandreas.hansson@arm.com } 16811051Sandreas.hansson@arm.com ccprintf(os, "%s%s: ", prefix, s); 16912724Snikos.nikoleris@arm.com i->pkt->print(os, verbosity, ""); 17012724Snikos.nikoleris@arm.com } 17112724Snikos.nikoleris@arm.com} 17212724Snikos.nikoleris@arm.com 17312724Snikos.nikoleris@arm.com 17412724Snikos.nikoleris@arm.comvoid 17512724Snikos.nikoleris@arm.comMSHR::allocate(Addr _addr, int _size, PacketPtr target, 17611051Sandreas.hansson@arm.com Tick whenReady, Counter _order) 17711051Sandreas.hansson@arm.com{ 17811051Sandreas.hansson@arm.com addr = _addr; 17911051Sandreas.hansson@arm.com size = _size; 18012723Snikos.nikoleris@arm.com readyTime = whenReady; 18111051Sandreas.hansson@arm.com order = _order; 18211051Sandreas.hansson@arm.com assert(target); 18311484Snikos.nikoleris@arm.com isForward = false; 18411051Sandreas.hansson@arm.com _isUncacheable = target->req->isUncacheable(); 18511051Sandreas.hansson@arm.com inService = false; 18611051Sandreas.hansson@arm.com downstreamPending = false; 18711051Sandreas.hansson@arm.com threadNum = 0; 18811051Sandreas.hansson@arm.com ntargets = 1; 18912724Snikos.nikoleris@arm.com assert(targets->isReset()); 19011601Sandreas.hansson@arm.com // Don't know of a case where we would allocate a new MSHR for a 19111601Sandreas.hansson@arm.com // snoop (mem-side request), so set source according to request here 19211601Sandreas.hansson@arm.com Target::Source source = (target->cmd == MemCmd::HardPFReq) ? 19311051Sandreas.hansson@arm.com Target::FromPrefetcher : Target::FromCPU; 19411051Sandreas.hansson@arm.com targets->add(target, whenReady, _order, source, true); 19511051Sandreas.hansson@arm.com assert(deferredTargets->isReset()); 19611051Sandreas.hansson@arm.com data = NULL; 19711051Sandreas.hansson@arm.com} 19812345Snikos.nikoleris@arm.com 19912345Snikos.nikoleris@arm.com 20012345Snikos.nikoleris@arm.comvoid 20112345Snikos.nikoleris@arm.comMSHR::clearDownstreamPending() 20211051Sandreas.hansson@arm.com{ 20311051Sandreas.hansson@arm.com assert(downstreamPending); 20411051Sandreas.hansson@arm.com downstreamPending = false; 20511051Sandreas.hansson@arm.com // recursively clear flag on any MSHRs we will be forwarding 20611051Sandreas.hansson@arm.com // responses to 20711051Sandreas.hansson@arm.com targets->clearDownstreamPending(); 20811051Sandreas.hansson@arm.com} 20911199Sandreas.hansson@arm.com 21011199Sandreas.hansson@arm.combool 21111199Sandreas.hansson@arm.comMSHR::markInService(PacketPtr pkt) 21211199Sandreas.hansson@arm.com{ 21311199Sandreas.hansson@arm.com assert(!inService); 21411051Sandreas.hansson@arm.com if (isForwardNoResponse()) { 21512345Snikos.nikoleris@arm.com // we just forwarded the request packet & don't expect a 21612345Snikos.nikoleris@arm.com // response, so get rid of it 21711051Sandreas.hansson@arm.com assert(getNumTargets() == 1); 21811051Sandreas.hansson@arm.com popTarget(); 21911051Sandreas.hansson@arm.com return true; 22011051Sandreas.hansson@arm.com } 22111051Sandreas.hansson@arm.com inService = true; 22211051Sandreas.hansson@arm.com pendingDirty = (targets->needsExclusive || 22311051Sandreas.hansson@arm.com (!pkt->sharedAsserted() && pkt->memInhibitAsserted())); 22411051Sandreas.hansson@arm.com postInvalidate = postDowngrade = false; 22511051Sandreas.hansson@arm.com 22611051Sandreas.hansson@arm.com if (!downstreamPending) { 22711051Sandreas.hansson@arm.com // let upstream caches know that the request has made it to a 22811051Sandreas.hansson@arm.com // level where it's going to get a response 22911051Sandreas.hansson@arm.com targets->clearDownstreamPending(); 23011051Sandreas.hansson@arm.com } 23111051Sandreas.hansson@arm.com return false; 23211051Sandreas.hansson@arm.com} 23311051Sandreas.hansson@arm.com 23411130Sali.jafri@arm.com 23511130Sali.jafri@arm.comvoid 23611130Sali.jafri@arm.comMSHR::deallocate() 23711130Sali.jafri@arm.com{ 23811130Sali.jafri@arm.com assert(targets->empty()); 23911130Sali.jafri@arm.com targets->resetFlags(); 24011130Sali.jafri@arm.com assert(deferredTargets->isReset()); 24111130Sali.jafri@arm.com assert(ntargets == 0); 24211130Sali.jafri@arm.com inService = false; 24312345Snikos.nikoleris@arm.com} 24412345Snikos.nikoleris@arm.com 24511130Sali.jafri@arm.com/* 24611130Sali.jafri@arm.com * Adds a target to an MSHR 24711130Sali.jafri@arm.com */ 24811130Sali.jafri@arm.comvoid 24911130Sali.jafri@arm.comMSHR::allocateTarget(PacketPtr pkt, Tick whenReady, Counter _order) 25011130Sali.jafri@arm.com{ 25112724Snikos.nikoleris@arm.com // if there's a request already in service for this MSHR, we will 25211130Sali.jafri@arm.com // have to defer the new target until after the response if any of 25311130Sali.jafri@arm.com // the following are true: 25411130Sali.jafri@arm.com // - there are other targets already deferred 25511130Sali.jafri@arm.com // - there's a pending invalidate to be applied after the response 25611130Sali.jafri@arm.com // comes back (but before this target is processed) 25711130Sali.jafri@arm.com // - this target requires an exclusive block and either we're not 25812724Snikos.nikoleris@arm.com // getting an exclusive block back or we have already snooped 25911130Sali.jafri@arm.com // another read request that will downgrade our exclusive block 26011130Sali.jafri@arm.com // to shared 26111130Sali.jafri@arm.com 26211130Sali.jafri@arm.com // assume we'd never issue a prefetch when we've got an 26311130Sali.jafri@arm.com // outstanding miss 26411130Sali.jafri@arm.com assert(pkt->cmd != MemCmd::HardPFReq); 26511130Sali.jafri@arm.com 26611130Sali.jafri@arm.com if (inService && 26711130Sali.jafri@arm.com (!deferredTargets->empty() || hasPostInvalidate() || 26811051Sandreas.hansson@arm.com (pkt->needsExclusive() && 26911051Sandreas.hansson@arm.com (!isPendingDirty() || hasPostDowngrade() || isForward)))) { 27011051Sandreas.hansson@arm.com // need to put on deferred list 27111051Sandreas.hansson@arm.com if (hasPostInvalidate()) 27211744Snikos.nikoleris@arm.com replaceUpgrade(pkt); 27311051Sandreas.hansson@arm.com deferredTargets->add(pkt, whenReady, _order, Target::FromCPU, true); 27411276Sandreas.hansson@arm.com } else { 27511276Sandreas.hansson@arm.com // No request outstanding, or still OK to append to 27611276Sandreas.hansson@arm.com // outstanding request: append to regular target list. Only 27711276Sandreas.hansson@arm.com // mark pending if current request hasn't been issued yet 27811276Sandreas.hansson@arm.com // (isn't in service). 27911276Sandreas.hansson@arm.com targets->add(pkt, whenReady, _order, Target::FromCPU, !inService); 28011276Sandreas.hansson@arm.com } 28111276Sandreas.hansson@arm.com 28211276Sandreas.hansson@arm.com ++ntargets; 28311051Sandreas.hansson@arm.com} 28411276Sandreas.hansson@arm.com 28511276Sandreas.hansson@arm.combool 28611276Sandreas.hansson@arm.comMSHR::handleSnoop(PacketPtr pkt, Counter _order) 28711276Sandreas.hansson@arm.com{ 28811276Sandreas.hansson@arm.com if (!inService || (pkt->isExpressSnoop() && downstreamPending)) { 28911051Sandreas.hansson@arm.com // Request has not been issued yet, or it's been issued 29011051Sandreas.hansson@arm.com // locally but is buffered unissued at some downstream cache 29111051Sandreas.hansson@arm.com // which is forwarding us this snoop. Either way, the packet 29211051Sandreas.hansson@arm.com // we're snooping logically precedes this MSHR's request, so 29311051Sandreas.hansson@arm.com // the snoop has no impact on the MSHR, but must be processed 29411051Sandreas.hansson@arm.com // in the standard way by the cache. The only exception is 29511051Sandreas.hansson@arm.com // that if we're an L2+ cache buffering an UpgradeReq from a 29611051Sandreas.hansson@arm.com // higher-level cache, and the snoop is invalidating, then our 29711051Sandreas.hansson@arm.com // buffered upgrades must be converted to read exclusives, 29811051Sandreas.hansson@arm.com // since the upper-level cache no longer has a valid copy. 29911051Sandreas.hansson@arm.com // That is, even though the upper-level cache got out on its 30012724Snikos.nikoleris@arm.com // local bus first, some other invalidating transaction 30111051Sandreas.hansson@arm.com // reached the global bus before the upgrade did. 30211051Sandreas.hansson@arm.com if (pkt->needsExclusive()) { 30311051Sandreas.hansson@arm.com targets->replaceUpgrades(); 30411051Sandreas.hansson@arm.com deferredTargets->replaceUpgrades(); 30511051Sandreas.hansson@arm.com } 30611051Sandreas.hansson@arm.com 30711051Sandreas.hansson@arm.com return false; 30811051Sandreas.hansson@arm.com } 30911051Sandreas.hansson@arm.com 31011051Sandreas.hansson@arm.com // From here on down, the request issued by this MSHR logically 31111051Sandreas.hansson@arm.com // precedes the request we're snooping. 31211051Sandreas.hansson@arm.com if (pkt->needsExclusive()) { 31311051Sandreas.hansson@arm.com // snooped request still precedes the re-request we'll have to 31412630Snikos.nikoleris@arm.com // issue for deferred targets, if any... 31512720Snikos.nikoleris@arm.com deferredTargets->replaceUpgrades(); 31612720Snikos.nikoleris@arm.com } 31712720Snikos.nikoleris@arm.com 31812720Snikos.nikoleris@arm.com if (hasPostInvalidate()) { 31912720Snikos.nikoleris@arm.com // a prior snoop has already appended an invalidation, so 32012720Snikos.nikoleris@arm.com // logically we don't have the block anymore; no need for 32112720Snikos.nikoleris@arm.com // further snooping. 32212724Snikos.nikoleris@arm.com return true; 32312720Snikos.nikoleris@arm.com } 32412720Snikos.nikoleris@arm.com 32512720Snikos.nikoleris@arm.com if (isPendingDirty() || pkt->isInvalidate()) { 32612720Snikos.nikoleris@arm.com // We need to save and replay the packet in two cases: 32712720Snikos.nikoleris@arm.com // 1. We're awaiting an exclusive copy, so ownership is pending, 32812720Snikos.nikoleris@arm.com // and we need to respond after we receive data. 32912724Snikos.nikoleris@arm.com // 2. It's an invalidation (e.g., UpgradeReq), and we need 33012724Snikos.nikoleris@arm.com // to forward the snoop up the hierarchy after the current 33112724Snikos.nikoleris@arm.com // transaction completes. 33212724Snikos.nikoleris@arm.com 33312724Snikos.nikoleris@arm.com // Actual target device (typ. PhysicalMemory) will delete the 33412724Snikos.nikoleris@arm.com // packet on reception, so we need to save a copy here. 33512724Snikos.nikoleris@arm.com PacketPtr cp_pkt = new Packet(pkt, true); 33612724Snikos.nikoleris@arm.com targets->add(cp_pkt, curTick, _order, Target::FromSnoop, 33712724Snikos.nikoleris@arm.com downstreamPending && targets->needsExclusive); 33812724Snikos.nikoleris@arm.com ++ntargets; 33912724Snikos.nikoleris@arm.com 34012724Snikos.nikoleris@arm.com if (isPendingDirty()) { 34112724Snikos.nikoleris@arm.com pkt->assertMemInhibit(); 34212724Snikos.nikoleris@arm.com pkt->setSupplyExclusive(); 34312724Snikos.nikoleris@arm.com } 34412724Snikos.nikoleris@arm.com 34512724Snikos.nikoleris@arm.com if (pkt->needsExclusive()) { 34612724Snikos.nikoleris@arm.com // This transaction will take away our pending copy 34712724Snikos.nikoleris@arm.com postInvalidate = true; 34812724Snikos.nikoleris@arm.com } 34912724Snikos.nikoleris@arm.com } 35012724Snikos.nikoleris@arm.com 35112724Snikos.nikoleris@arm.com if (!pkt->needsExclusive()) { 35212724Snikos.nikoleris@arm.com // This transaction will get a read-shared copy, downgrading 35312724Snikos.nikoleris@arm.com // our copy if we had an exclusive one 35412720Snikos.nikoleris@arm.com postDowngrade = true; 35512720Snikos.nikoleris@arm.com pkt->assertShared(); 35612724Snikos.nikoleris@arm.com } 35712720Snikos.nikoleris@arm.com 35812720Snikos.nikoleris@arm.com return true; 35912720Snikos.nikoleris@arm.com} 36012720Snikos.nikoleris@arm.com 36112720Snikos.nikoleris@arm.com 36212720Snikos.nikoleris@arm.combool 36312720Snikos.nikoleris@arm.comMSHR::promoteDeferredTargets() 36412720Snikos.nikoleris@arm.com{ 36512720Snikos.nikoleris@arm.com assert(targets->empty()); 36612720Snikos.nikoleris@arm.com if (deferredTargets->empty()) { 36712720Snikos.nikoleris@arm.com return false; 36812720Snikos.nikoleris@arm.com } 36912720Snikos.nikoleris@arm.com 37012720Snikos.nikoleris@arm.com // swap targets & deferredTargets lists 37112720Snikos.nikoleris@arm.com TargetList *tmp = targets; 37212720Snikos.nikoleris@arm.com targets = deferredTargets; 37312720Snikos.nikoleris@arm.com deferredTargets = tmp; 37412720Snikos.nikoleris@arm.com 37512720Snikos.nikoleris@arm.com assert(targets->size() == ntargets); 37612720Snikos.nikoleris@arm.com 37712720Snikos.nikoleris@arm.com // clear deferredTargets flags 37812720Snikos.nikoleris@arm.com deferredTargets->resetFlags(); 37912720Snikos.nikoleris@arm.com 38012749Sgiacomo.travaglini@arm.com order = targets->front().order; 38112749Sgiacomo.travaglini@arm.com readyTime = std::max(curTick, targets->front().readyTime); 38212749Sgiacomo.travaglini@arm.com 38312749Sgiacomo.travaglini@arm.com return true; 38412720Snikos.nikoleris@arm.com} 38512720Snikos.nikoleris@arm.com 38612720Snikos.nikoleris@arm.com 38712720Snikos.nikoleris@arm.comvoid 38812720Snikos.nikoleris@arm.comMSHR::handleFill(Packet *pkt, CacheBlk *blk) 38912720Snikos.nikoleris@arm.com{ 39012720Snikos.nikoleris@arm.com if (!pkt->sharedAsserted() 39112720Snikos.nikoleris@arm.com && !(hasPostInvalidate() || hasPostDowngrade()) 39212720Snikos.nikoleris@arm.com && deferredTargets->needsExclusive) { 39312720Snikos.nikoleris@arm.com // We got an exclusive response, but we have deferred targets 39412724Snikos.nikoleris@arm.com // which are waiting to request an exclusive copy (not because 39512720Snikos.nikoleris@arm.com // of a pending invalidate). This can happen if the original 39612720Snikos.nikoleris@arm.com // request was for a read-only (non-exclusive) block, but we 39712720Snikos.nikoleris@arm.com // got an exclusive copy anyway because of the E part of the 39812720Snikos.nikoleris@arm.com // MOESI/MESI protocol. Since we got the exclusive copy 39912720Snikos.nikoleris@arm.com // there's no need to defer the targets, so move them up to 40012720Snikos.nikoleris@arm.com // the regular target list. 40112724Snikos.nikoleris@arm.com assert(!targets->needsExclusive); 40212720Snikos.nikoleris@arm.com targets->needsExclusive = true; 40312720Snikos.nikoleris@arm.com // if any of the deferred targets were upper-level cache 40412720Snikos.nikoleris@arm.com // requests marked downstreamPending, need to clear that 40511051Sandreas.hansson@arm.com assert(!downstreamPending); // not pending here anymore 40611051Sandreas.hansson@arm.com deferredTargets->clearDownstreamPending(); 40711830Sbaz21@cam.ac.uk // this clears out deferredTargets too 40811051Sandreas.hansson@arm.com targets->splice(targets->end(), *deferredTargets); 40911051Sandreas.hansson@arm.com deferredTargets->resetFlags(); 41011051Sandreas.hansson@arm.com } 41111284Sandreas.hansson@arm.com} 41211051Sandreas.hansson@arm.com 41311284Sandreas.hansson@arm.com 41411284Sandreas.hansson@arm.combool 41511744Snikos.nikoleris@arm.comMSHR::checkFunctional(PacketPtr pkt) 41611744Snikos.nikoleris@arm.com{ 41711051Sandreas.hansson@arm.com // For printing, we treat the MSHR as a whole as single entity. 41811284Sandreas.hansson@arm.com // For other requests, we iterate over the individual targets 41911284Sandreas.hansson@arm.com // since that's where the actual data lies. 42011284Sandreas.hansson@arm.com if (pkt->isPrint()) { 42111284Sandreas.hansson@arm.com pkt->checkFunctional(this, addr, size, NULL); 42211284Sandreas.hansson@arm.com return false; 42311334Sandreas.hansson@arm.com } else { 42411284Sandreas.hansson@arm.com return (targets->checkFunctional(pkt) || 42511334Sandreas.hansson@arm.com deferredTargets->checkFunctional(pkt)); 42611334Sandreas.hansson@arm.com } 42711334Sandreas.hansson@arm.com} 42811334Sandreas.hansson@arm.com 42911284Sandreas.hansson@arm.com 43011334Sandreas.hansson@arm.comvoid 43111334Sandreas.hansson@arm.comMSHR::print(std::ostream &os, int verbosity, const std::string &prefix) const 43211334Sandreas.hansson@arm.com{ 43311334Sandreas.hansson@arm.com ccprintf(os, "%s[%x:%x] %s %s %s state: %s %s %s %s\n", 43411334Sandreas.hansson@arm.com prefix, addr, addr+size-1, 43511334Sandreas.hansson@arm.com isForward ? "Forward" : "", 43611051Sandreas.hansson@arm.com isForwardNoResponse() ? "ForwNoResp" : "", 43711334Sandreas.hansson@arm.com needsExclusive() ? "Excl" : "", 43811334Sandreas.hansson@arm.com _isUncacheable ? "Unc" : "", 43911334Sandreas.hansson@arm.com inService ? "InSvc" : "", 44011334Sandreas.hansson@arm.com downstreamPending ? "DwnPend" : "", 44111051Sandreas.hansson@arm.com hasPostInvalidate() ? "PostInv" : "", 44211334Sandreas.hansson@arm.com hasPostDowngrade() ? "PostDowngr" : ""); 44311334Sandreas.hansson@arm.com 44411334Sandreas.hansson@arm.com ccprintf(os, "%s Targets:\n", prefix); 44511051Sandreas.hansson@arm.com targets->print(os, verbosity, prefix + " "); 44611334Sandreas.hansson@arm.com if (!deferredTargets->empty()) { 44711334Sandreas.hansson@arm.com ccprintf(os, "%s Deferred Targets:\n", prefix); 44811334Sandreas.hansson@arm.com deferredTargets->print(os, verbosity, prefix + " "); 44911334Sandreas.hansson@arm.com } 45011334Sandreas.hansson@arm.com} 45111334Sandreas.hansson@arm.com 45211334Sandreas.hansson@arm.comMSHR::~MSHR() 45311051Sandreas.hansson@arm.com{ 45411334Sandreas.hansson@arm.com} 45511334Sandreas.hansson@arm.com