mshr.cc revision 10424
1360SN/A/* 210850SGiacomo.Gabrielli@arm.com * Copyright (c) 2012-2013 ARM Limited 310796Sbrandon.potter@amd.com * All rights reserved. 410027SChris.Adeniyi-Jones@arm.com * 510027SChris.Adeniyi-Jones@arm.com * The license below extends only to copyright in the software and shall 610027SChris.Adeniyi-Jones@arm.com * not be construed as granting a license to any other intellectual 710027SChris.Adeniyi-Jones@arm.com * property including but not limited to intellectual property relating 810027SChris.Adeniyi-Jones@arm.com * to a hardware implementation of the functionality of the software 910027SChris.Adeniyi-Jones@arm.com * licensed hereunder. You may use the software subject to the license 1010027SChris.Adeniyi-Jones@arm.com * terms below provided that you ensure that this notice is replicated 1110027SChris.Adeniyi-Jones@arm.com * unmodified and in its entirety in all distributions of the software, 1210027SChris.Adeniyi-Jones@arm.com * modified or unmodified, in source code or in binary form. 1310027SChris.Adeniyi-Jones@arm.com * 1410027SChris.Adeniyi-Jones@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 151458SN/A * Copyright (c) 2010 Advanced Micro Devices, Inc. 16360SN/A * All rights reserved. 17360SN/A * 18360SN/A * Redistribution and use in source and binary forms, with or without 19360SN/A * modification, are permitted provided that the following conditions are 20360SN/A * met: redistributions of source code must retain the above copyright 21360SN/A * notice, this list of conditions and the following disclaimer; 22360SN/A * redistributions in binary form must reproduce the above copyright 23360SN/A * notice, this list of conditions and the following disclaimer in the 24360SN/A * documentation and/or other materials provided with the distribution; 25360SN/A * neither the name of the copyright holders nor the names of its 26360SN/A * contributors may be used to endorse or promote products derived from 27360SN/A * this software without specific prior written permission. 28360SN/A * 29360SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30360SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31360SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32360SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33360SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34360SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35360SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36360SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37360SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38360SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39360SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402665Ssaidi@eecs.umich.edu * 412665Ssaidi@eecs.umich.edu * Authors: Erik Hallnor 422665Ssaidi@eecs.umich.edu * Dave Greene 43360SN/A */ 44360SN/A 451354SN/A/** 461354SN/A * @file 47360SN/A * Miss Status and Handling Register (MSHR) definitions. 4812018Sandreas.sandberg@arm.com */ 4912018Sandreas.sandberg@arm.com 5012018Sandreas.sandberg@arm.com#include <algorithm> 5112018Sandreas.sandberg@arm.com#include <cassert> 5212018Sandreas.sandberg@arm.com#include <string> 5312018Sandreas.sandberg@arm.com#include <vector> 5412018Sandreas.sandberg@arm.com 552064SN/A#include "base/misc.hh" 56360SN/A#include "base/types.hh" 57360SN/A#include "debug/Cache.hh" 58360SN/A#include "mem/cache/cache.hh" 59360SN/A#include "mem/cache/mshr.hh" 60360SN/A#include "sim/core.hh" 61360SN/A 6213936SAndrea.Mondelli@ucf.eduusing namespace std; 6313933Sbrandon.potter@amd.com 6413933Sbrandon.potter@amd.comMSHR::MSHR() : readyTime(0), _isUncacheable(false), downstreamPending(false), 6513933Sbrandon.potter@amd.com pendingDirty(false), postInvalidate(false), 6613936SAndrea.Mondelli@ucf.edu postDowngrade(false), queue(NULL), order(0), addr(0), size(0), 6713936SAndrea.Mondelli@ucf.edu isSecure(false), inService(false), isForward(false), 6813936SAndrea.Mondelli@ucf.edu threadNum(InvalidThreadID), data(NULL) 6913933Sbrandon.potter@amd.com{ 7013933Sbrandon.potter@amd.com} 711809SN/A 7211800Sbrandon.potter@amd.com 7311392Sbrandon.potter@amd.comMSHR::TargetList::TargetList() 741809SN/A : needsExclusive(false), hasUpgrade(false) 7511392Sbrandon.potter@amd.com{} 7613902Sbrandon.potter@amd.com 7713570Sbrandon.potter@amd.com 7813902Sbrandon.potter@amd.cominline void 7911383Sbrandon.potter@amd.comMSHR::TargetList::add(PacketPtr pkt, Tick readyTime, 8013568Sbrandon.potter@amd.com Counter order, Target::Source source, bool markPending) 813113Sgblack@eecs.umich.edu{ 828229Snate@binkert.org if (source != Target::FromSnoop) { 8313570Sbrandon.potter@amd.com if (pkt->needsExclusive()) { 848229Snate@binkert.org needsExclusive = true; 8511594Santhony.gutierrez@amd.com } 867075Snate@binkert.org 878229Snate@binkert.org // StoreCondReq is effectively an upgrade if it's in an MSHR 8811856Sbrandon.potter@amd.com // since it would have been failed already if we didn't have a 897075Snate@binkert.org // read-only copy 90360SN/A if (pkt->isUpgrade() || pkt->cmd == MemCmd::StoreCondReq) { 9112461Sgabeblack@google.com hasUpgrade = true; 9211886Sbrandon.potter@amd.com } 9311800Sbrandon.potter@amd.com } 9411392Sbrandon.potter@amd.com 9512334Sgabeblack@google.com if (markPending) { 961354SN/A // Iterate over the SenderState stack and see if we find 976216Snate@binkert.org // an MSHR entry. If we do, set the downstreamPending 986658Snate@binkert.org // flag. Otherwise, do nothing. 992474SN/A MSHR *mshr = pkt->findNextSenderState<MSHR>(); 1002680Sktlim@umich.edu if (mshr != NULL) { 1018229Snate@binkert.org assert(!mshr->downstreamPending); 10211886Sbrandon.potter@amd.com mshr->downstreamPending = true; 10310496Ssteve.reinhardt@amd.com } 10411911SBrandon.Potter@amd.com } 1058229Snate@binkert.org 10611794Sbrandon.potter@amd.com push_back(Target(pkt, readyTime, order, source, markPending)); 10711886Sbrandon.potter@amd.com} 10810497Ssteve.reinhardt@amd.com 10911794Sbrandon.potter@amd.com 110360SN/Astatic void 11113629SAndrea.Mondelli@ucf.edureplaceUpgrade(PacketPtr pkt) 11213629SAndrea.Mondelli@ucf.edu{ 11313629SAndrea.Mondelli@ucf.edu if (pkt->cmd == MemCmd::UpgradeReq) { 11413629SAndrea.Mondelli@ucf.edu pkt->cmd = MemCmd::ReadExReq; 115360SN/A DPRINTF(Cache, "Replacing UpgradeReq with ReadExReq\n"); 116360SN/A } else if (pkt->cmd == MemCmd::SCUpgradeReq) { 117360SN/A pkt->cmd = MemCmd::SCUpgradeFailReq; 118360SN/A DPRINTF(Cache, "Replacing SCUpgradeReq with SCUpgradeFailReq\n"); 119360SN/A } else if (pkt->cmd == MemCmd::StoreCondReq) { 120360SN/A pkt->cmd = MemCmd::StoreCondFailReq; 121360SN/A DPRINTF(Cache, "Replacing StoreCondReq with StoreCondFailReq\n"); 122360SN/A } 12313933Sbrandon.potter@amd.com} 124360SN/A 125378SN/A 12613995Sbrandon.potter@amd.comvoid 127378SN/AMSHR::TargetList::replaceUpgrades() 128378SN/A{ 129378SN/A if (!hasUpgrade) 130378SN/A return; 131378SN/A 13213995Sbrandon.potter@amd.com Iterator end_i = end(); 133360SN/A for (Iterator i = begin(); i != end_i; ++i) { 13411760Sbrandon.potter@amd.com replaceUpgrade(i->pkt); 13513995Sbrandon.potter@amd.com } 13611760Sbrandon.potter@amd.com 1376109Ssanchezd@stanford.edu hasUpgrade = false; 13813995Sbrandon.potter@amd.com} 139378SN/A 1406109Ssanchezd@stanford.edu 14113995Sbrandon.potter@amd.comvoid 1426109Ssanchezd@stanford.eduMSHR::TargetList::clearDownstreamPending() 14311886Sbrandon.potter@amd.com{ 14413995Sbrandon.potter@amd.com Iterator end_i = end(); 14511886Sbrandon.potter@amd.com for (Iterator i = begin(); i != end_i; ++i) { 146378SN/A if (i->markedPending) { 14713995Sbrandon.potter@amd.com // Iterate over the SenderState stack and see if we find 148378SN/A // an MSHR entry. If we find one, clear the 1495748SSteve.Reinhardt@amd.com // downstreamPending flag by calling 15013995Sbrandon.potter@amd.com // clearDownstreamPending(). This recursively clears the 151378SN/A // downstreamPending flag in all caches this packet has 152378SN/A // passed through. 15313995Sbrandon.potter@amd.com MSHR *mshr = i->pkt->findNextSenderState<MSHR>(); 154378SN/A if (mshr != NULL) { 155378SN/A mshr->clearDownstreamPending(); 15613995Sbrandon.potter@amd.com } 157378SN/A } 1584118Sgblack@eecs.umich.edu } 15913995Sbrandon.potter@amd.com} 1604118Sgblack@eecs.umich.edu 161378SN/A 16213995Sbrandon.potter@amd.combool 163378SN/AMSHR::TargetList::checkFunctional(PacketPtr pkt) 16413568Sbrandon.potter@amd.com{ 16513995Sbrandon.potter@amd.com Iterator end_i = end(); 16613568Sbrandon.potter@amd.com for (Iterator i = begin(); i != end_i; ++i) { 167378SN/A if (pkt->checkFunctional(i->pkt)) { 16813995Sbrandon.potter@amd.com return true; 169360SN/A } 1705513SMichael.Adler@intel.com } 17113995Sbrandon.potter@amd.com 1725513SMichael.Adler@intel.com return false; 17310203SAli.Saidi@ARM.com} 17413995Sbrandon.potter@amd.com 17510203SAli.Saidi@ARM.com 17613995Sbrandon.potter@amd.comvoid 1775513SMichael.Adler@intel.comMSHR::TargetList:: 178511SN/Aprint(std::ostream &os, int verbosity, const std::string &prefix) const 17913995Sbrandon.potter@amd.com{ 18010633Smichaelupton@gmail.com ConstIterator end_i = end(); 18113995Sbrandon.potter@amd.com for (ConstIterator i = begin(); i != end_i; ++i) { 182511SN/A const char *s; 18312795Smattdsinclair@gmail.com switch (i->source) { 18413995Sbrandon.potter@amd.com case Target::FromCPU: 18512795Smattdsinclair@gmail.com s = "FromCPU"; 18612796Smattdsinclair@gmail.com break; 18713995Sbrandon.potter@amd.com case Target::FromSnoop: 18812796Smattdsinclair@gmail.com s = "FromSnoop"; 1895513SMichael.Adler@intel.com break; 19013995Sbrandon.potter@amd.com case Target::FromPrefetcher: 1915513SMichael.Adler@intel.com s = "FromPrefetcher"; 19213031Sbrandon.potter@amd.com break; 19313995Sbrandon.potter@amd.com default: 19413031Sbrandon.potter@amd.com s = ""; 19513031Sbrandon.potter@amd.com break; 19613995Sbrandon.potter@amd.com } 19713031Sbrandon.potter@amd.com ccprintf(os, "%s%s: ", prefix, s); 19813031Sbrandon.potter@amd.com i->pkt->print(os, verbosity, ""); 19913995Sbrandon.potter@amd.com } 20013031Sbrandon.potter@amd.com} 201511SN/A 20213995Sbrandon.potter@amd.com 2031706SN/Avoid 2041706SN/AMSHR::allocate(Addr _addr, int _size, PacketPtr target, Tick whenReady, 2051706SN/A Counter _order) 20613995Sbrandon.potter@amd.com{ 2071706SN/A addr = _addr; 2081706SN/A size = _size; 2091706SN/A isSecure = target->isSecure(); 21013995Sbrandon.potter@amd.com readyTime = whenReady; 2111706SN/A order = _order; 212511SN/A assert(target); 2136703Svince@csl.cornell.edu isForward = false; 21413995Sbrandon.potter@amd.com _isUncacheable = target->req->isUncacheable(); 2156703Svince@csl.cornell.edu inService = false; 2166685Stjones1@inf.ed.ac.uk downstreamPending = false; 21713995Sbrandon.potter@amd.com threadNum = 0; 2186685Stjones1@inf.ed.ac.uk assert(targets.isReset()); 2196685Stjones1@inf.ed.ac.uk // Don't know of a case where we would allocate a new MSHR for a 2205513SMichael.Adler@intel.com // snoop (mem-side request), so set source according to request here 22113995Sbrandon.potter@amd.com Target::Source source = (target->cmd == MemCmd::HardPFReq) ? 2225513SMichael.Adler@intel.com Target::FromPrefetcher : Target::FromCPU; 22311885Sbrandon.potter@amd.com targets.add(target, whenReady, _order, source, true); 22413995Sbrandon.potter@amd.com assert(deferredTargets.isReset()); 2255513SMichael.Adler@intel.com data = NULL; 2261999SN/A} 22713995Sbrandon.potter@amd.com 2281999SN/A 22911885Sbrandon.potter@amd.comvoid 23013995Sbrandon.potter@amd.comMSHR::clearDownstreamPending() 2311999SN/A{ 2321999SN/A assert(downstreamPending); 23313995Sbrandon.potter@amd.com downstreamPending = false; 2341999SN/A // recursively clear flag on any MSHRs we will be forwarding 2353079Sstever@eecs.umich.edu // responses to 23613995Sbrandon.potter@amd.com targets.clearDownstreamPending(); 2373079Sstever@eecs.umich.edu} 23811908SBrandon.Potter@amd.com 23913995Sbrandon.potter@amd.combool 24011908SBrandon.Potter@amd.comMSHR::markInService(PacketPtr pkt) 24111875Sbrandon.potter@amd.com{ 24213995Sbrandon.potter@amd.com assert(!inService); 2432093SN/A if (isForwardNoResponse()) { 2442687Sksewell@umich.edu // we just forwarded the request packet & don't expect a 24513995Sbrandon.potter@amd.com // response, so get rid of it 2462687Sksewell@umich.edu assert(getNumTargets() == 1); 2472238SN/A popTarget(); 24813995Sbrandon.potter@amd.com return true; 2492238SN/A } 25011908SBrandon.Potter@amd.com 25113995Sbrandon.potter@amd.com assert(pkt != NULL); 25211908SBrandon.Potter@amd.com inService = true; 25311908SBrandon.Potter@amd.com pendingDirty = (targets.needsExclusive || 25413995Sbrandon.potter@amd.com (!pkt->sharedAsserted() && pkt->memInhibitAsserted())); 25513995Sbrandon.potter@amd.com postInvalidate = postDowngrade = false; 25611908SBrandon.Potter@amd.com 2572238SN/A if (!downstreamPending) { 25813995Sbrandon.potter@amd.com // let upstream caches know that the request has made it to a 2592238SN/A // level where it's going to get a response 26013571Sbrandon.potter@amd.com targets.clearDownstreamPending(); 26113995Sbrandon.potter@amd.com } 26213571Sbrandon.potter@amd.com return false; 26313568Sbrandon.potter@amd.com} 26413995Sbrandon.potter@amd.com 26513568Sbrandon.potter@amd.com 26613568Sbrandon.potter@amd.comvoid 26713995Sbrandon.potter@amd.comMSHR::deallocate() 26813568Sbrandon.potter@amd.com{ 26913568Sbrandon.potter@amd.com assert(targets.empty()); 27013995Sbrandon.potter@amd.com targets.resetFlags(); 27113568Sbrandon.potter@amd.com assert(deferredTargets.isReset()); 27213448Sciro.santilli@arm.com inService = false; 27313031Sbrandon.potter@amd.com} 27413995Sbrandon.potter@amd.com 27513448Sciro.santilli@arm.com/* 27613031Sbrandon.potter@amd.com * Adds a target to an MSHR 27713539Sjavier.setoain@arm.com */ 27813539Sjavier.setoain@arm.comvoid 27913995Sbrandon.potter@amd.comMSHR::allocateTarget(PacketPtr pkt, Tick whenReady, Counter _order) 28013539Sjavier.setoain@arm.com{ 28113539Sjavier.setoain@arm.com // if there's a request already in service for this MSHR, we will 28213569Sbrandon.potter@amd.com // have to defer the new target until after the response if any of 28313995Sbrandon.potter@amd.com // the following are true: 28413569Sbrandon.potter@amd.com // - there are other targets already deferred 28513569Sbrandon.potter@amd.com // - there's a pending invalidate to be applied after the response 28613995Sbrandon.potter@amd.com // comes back (but before this target is processed) 28713569Sbrandon.potter@amd.com // - this target requires an exclusive block and either we're not 28813569Sbrandon.potter@amd.com // getting an exclusive block back or we have already snooped 28913995Sbrandon.potter@amd.com // another read request that will downgrade our exclusive block 29013569Sbrandon.potter@amd.com // to shared 29113569Sbrandon.potter@amd.com 29213995Sbrandon.potter@amd.com // assume we'd never issue a prefetch when we've got an 29313569Sbrandon.potter@amd.com // outstanding miss 29413031Sbrandon.potter@amd.com assert(pkt->cmd != MemCmd::HardPFReq); 29513995Sbrandon.potter@amd.com 2962238SN/A if (inService && 2972238SN/A (!deferredTargets.empty() || hasPostInvalidate() || 29813995Sbrandon.potter@amd.com (pkt->needsExclusive() && 2992238SN/A (!isPendingDirty() || hasPostDowngrade() || isForward)))) { 3002238SN/A // need to put on deferred list 30113995Sbrandon.potter@amd.com if (hasPostInvalidate()) 3022238SN/A replaceUpgrade(pkt); 3032238SN/A deferredTargets.add(pkt, whenReady, _order, Target::FromCPU, true); 30413995Sbrandon.potter@amd.com } else { 3052238SN/A // No request outstanding, or still OK to append to 3062238SN/A // outstanding request: append to regular target list. Only 30713995Sbrandon.potter@amd.com // mark pending if current request hasn't been issued yet 3082238SN/A // (isn't in service). 3099455Smitch.hayenga+gem5@gmail.com targets.add(pkt, whenReady, _order, Target::FromCPU, !inService); 31013995Sbrandon.potter@amd.com } 31113995Sbrandon.potter@amd.com} 31211851Sbrandon.potter@amd.com 3139455Smitch.hayenga+gem5@gmail.combool 31413571Sbrandon.potter@amd.comMSHR::handleSnoop(PacketPtr pkt, Counter _order) 31513995Sbrandon.potter@amd.com{ 31613571Sbrandon.potter@amd.com DPRINTF(Cache, "%s for %s address %x size %d\n", __func__, 31713571Sbrandon.potter@amd.com pkt->cmdString(), pkt->getAddr(), pkt->getSize()); 31813995Sbrandon.potter@amd.com if (!inService || (pkt->isExpressSnoop() && downstreamPending)) { 31913571Sbrandon.potter@amd.com // Request has not been issued yet, or it's been issued 32013571Sbrandon.potter@amd.com // locally but is buffered unissued at some downstream cache 32113995Sbrandon.potter@amd.com // which is forwarding us this snoop. Either way, the packet 32213571Sbrandon.potter@amd.com // we're snooping logically precedes this MSHR's request, so 3239112Smarc.orr@gmail.com // the snoop has no impact on the MSHR, but must be processed 32411906SBrandon.Potter@amd.com // in the standard way by the cache. The only exception is 32511906SBrandon.Potter@amd.com // that if we're an L2+ cache buffering an UpgradeReq from a 3269112Smarc.orr@gmail.com // higher-level cache, and the snoop is invalidating, then our 3279112Smarc.orr@gmail.com // buffered upgrades must be converted to read exclusives, 32813995Sbrandon.potter@amd.com // since the upper-level cache no longer has a valid copy. 3299112Smarc.orr@gmail.com // That is, even though the upper-level cache got out on its 33011911SBrandon.Potter@amd.com // local bus first, some other invalidating transaction 3319112Smarc.orr@gmail.com // reached the global bus before the upgrade did. 33211911SBrandon.Potter@amd.com if (pkt->needsExclusive()) { 33313995Sbrandon.potter@amd.com targets.replaceUpgrades(); 33413995Sbrandon.potter@amd.com deferredTargets.replaceUpgrades(); 33511911SBrandon.Potter@amd.com } 33611911SBrandon.Potter@amd.com 33711911SBrandon.Potter@amd.com return false; 33813642Sqtt2@cornell.edu } 33913642Sqtt2@cornell.edu 34013642Sqtt2@cornell.edu // From here on down, the request issued by this MSHR logically 3419112Smarc.orr@gmail.com // precedes the request we're snooping. 34211911SBrandon.Potter@amd.com if (pkt->needsExclusive()) { 34311911SBrandon.Potter@amd.com // snooped request still precedes the re-request we'll have to 34411911SBrandon.Potter@amd.com // issue for deferred targets, if any... 34511911SBrandon.Potter@amd.com deferredTargets.replaceUpgrades(); 3469238Slluc.alvarez@bsc.es } 34713642Sqtt2@cornell.edu 3489112Smarc.orr@gmail.com if (hasPostInvalidate()) { 34911911SBrandon.Potter@amd.com // a prior snoop has already appended an invalidation, so 3509112Smarc.orr@gmail.com // logically we don't have the block anymore; no need for 35113642Sqtt2@cornell.edu // further snooping. 35211911SBrandon.Potter@amd.com return true; 35311911SBrandon.Potter@amd.com } 35411911SBrandon.Potter@amd.com 35511911SBrandon.Potter@amd.com if (isPendingDirty() || pkt->isInvalidate()) { 3569112Smarc.orr@gmail.com // We need to save and replay the packet in two cases: 35711911SBrandon.Potter@amd.com // 1. We're awaiting an exclusive copy, so ownership is pending, 35811911SBrandon.Potter@amd.com // and we need to respond after we receive data. 35911911SBrandon.Potter@amd.com // 2. It's an invalidation (e.g., UpgradeReq), and we need 36011911SBrandon.Potter@amd.com // to forward the snoop up the hierarchy after the current 36111911SBrandon.Potter@amd.com // transaction completes. 36211911SBrandon.Potter@amd.com 3639112Smarc.orr@gmail.com // Actual target device (typ. a memory) will delete the 3649112Smarc.orr@gmail.com // packet on reception, so we need to save a copy here. 36513642Sqtt2@cornell.edu PacketPtr cp_pkt = new Packet(pkt, true); 36613642Sqtt2@cornell.edu targets.add(cp_pkt, curTick(), _order, Target::FromSnoop, 36713642Sqtt2@cornell.edu downstreamPending && targets.needsExclusive); 36813642Sqtt2@cornell.edu 36913642Sqtt2@cornell.edu if (isPendingDirty()) { 37011911SBrandon.Potter@amd.com pkt->assertMemInhibit(); 3719112Smarc.orr@gmail.com pkt->setSupplyExclusive(); 37211911SBrandon.Potter@amd.com } 37311911SBrandon.Potter@amd.com 37413642Sqtt2@cornell.edu if (pkt->needsExclusive()) { 37513642Sqtt2@cornell.edu // This transaction will take away our pending copy 37613650Smw828@cornell.edu postInvalidate = true; 37713650Smw828@cornell.edu } 37813650Smw828@cornell.edu } 37913650Smw828@cornell.edu 38013650Smw828@cornell.edu if (!pkt->needsExclusive()) { 38113650Smw828@cornell.edu // This transaction will get a read-shared copy, downgrading 38213650Smw828@cornell.edu // our copy if we had an exclusive one 38313650Smw828@cornell.edu postDowngrade = true; 38413650Smw828@cornell.edu pkt->assertShared(); 38513650Smw828@cornell.edu } 38613650Smw828@cornell.edu 38713650Smw828@cornell.edu return true; 38813650Smw828@cornell.edu} 38913650Smw828@cornell.edu 39013651Smw828@cornell.edu 39113651Smw828@cornell.edubool 39213651Smw828@cornell.eduMSHR::promoteDeferredTargets() 39313651Smw828@cornell.edu{ 39413651Smw828@cornell.edu assert(targets.empty()); 39513651Smw828@cornell.edu if (deferredTargets.empty()) { 39613651Smw828@cornell.edu return false; 39713651Smw828@cornell.edu } 39813651Smw828@cornell.edu 39913651Smw828@cornell.edu // swap targets & deferredTargets lists 40013651Smw828@cornell.edu std::swap(targets, deferredTargets); 40113651Smw828@cornell.edu 40213651Smw828@cornell.edu // clear deferredTargets flags 40313651Smw828@cornell.edu deferredTargets.resetFlags(); 40413651Smw828@cornell.edu 40513651Smw828@cornell.edu order = targets.front().order; 40613651Smw828@cornell.edu readyTime = std::max(curTick(), targets.front().readyTime); 40713651Smw828@cornell.edu 40813651Smw828@cornell.edu return true; 40913651Smw828@cornell.edu} 41013651Smw828@cornell.edu 41113651Smw828@cornell.edu 41213651Smw828@cornell.eduvoid 41313651Smw828@cornell.eduMSHR::handleFill(Packet *pkt, CacheBlk *blk) 41413651Smw828@cornell.edu{ 41513651Smw828@cornell.edu if (!pkt->sharedAsserted() 41613651Smw828@cornell.edu && !(hasPostInvalidate() || hasPostDowngrade()) 41713651Smw828@cornell.edu && deferredTargets.needsExclusive) { 41813651Smw828@cornell.edu // We got an exclusive response, but we have deferred targets 41913651Smw828@cornell.edu // which are waiting to request an exclusive copy (not because 42013651Smw828@cornell.edu // of a pending invalidate). This can happen if the original 42113651Smw828@cornell.edu // request was for a read-only (non-exclusive) block, but we 42213651Smw828@cornell.edu // got an exclusive copy anyway because of the E part of the 42313651Smw828@cornell.edu // MOESI/MESI protocol. Since we got the exclusive copy 42413651Smw828@cornell.edu // there's no need to defer the targets, so move them up to 42513651Smw828@cornell.edu // the regular target list. 42613651Smw828@cornell.edu assert(!targets.needsExclusive); 42713651Smw828@cornell.edu targets.needsExclusive = true; 42813651Smw828@cornell.edu // if any of the deferred targets were upper-level cache 42913651Smw828@cornell.edu // requests marked downstreamPending, need to clear that 43013651Smw828@cornell.edu assert(!downstreamPending); // not pending here anymore 43113651Smw828@cornell.edu deferredTargets.clearDownstreamPending(); 43213651Smw828@cornell.edu // this clears out deferredTargets too 43313651Smw828@cornell.edu targets.splice(targets.end(), deferredTargets); 43413651Smw828@cornell.edu deferredTargets.resetFlags(); 43513651Smw828@cornell.edu } 43613651Smw828@cornell.edu} 43713651Smw828@cornell.edu 43813651Smw828@cornell.edu 43913651Smw828@cornell.edubool 44013651Smw828@cornell.eduMSHR::checkFunctional(PacketPtr pkt) 44113651Smw828@cornell.edu{ 44213651Smw828@cornell.edu // For printing, we treat the MSHR as a whole as single entity. 44313651Smw828@cornell.edu // For other requests, we iterate over the individual targets 44413651Smw828@cornell.edu // since that's where the actual data lies. 44513651Smw828@cornell.edu if (pkt->isPrint()) { 44613651Smw828@cornell.edu pkt->checkFunctional(this, addr, isSecure, size, NULL); 44713651Smw828@cornell.edu return false; 44813651Smw828@cornell.edu } else { 44913651Smw828@cornell.edu return (targets.checkFunctional(pkt) || 45013651Smw828@cornell.edu deferredTargets.checkFunctional(pkt)); 45113651Smw828@cornell.edu } 45213651Smw828@cornell.edu} 45313651Smw828@cornell.edu 45413651Smw828@cornell.edu 45513651Smw828@cornell.eduvoid 45613651Smw828@cornell.eduMSHR::print(std::ostream &os, int verbosity, const std::string &prefix) const 45713651Smw828@cornell.edu{ 45813651Smw828@cornell.edu ccprintf(os, "%s[%x:%x](%s) %s %s %s state: %s %s %s %s %s\n", 45913651Smw828@cornell.edu prefix, addr, addr+size-1, 46013651Smw828@cornell.edu isSecure ? "s" : "ns", 4619112Smarc.orr@gmail.com isForward ? "Forward" : "", 46211911SBrandon.Potter@amd.com isForwardNoResponse() ? "ForwNoResp" : "", 46311911SBrandon.Potter@amd.com needsExclusive() ? "Excl" : "", 4649112Smarc.orr@gmail.com _isUncacheable ? "Unc" : "", 4659112Smarc.orr@gmail.com inService ? "InSvc" : "", 4662238SN/A downstreamPending ? "DwnPend" : "", 4672238SN/A hasPostInvalidate() ? "PostInv" : "", 4682238SN/A hasPostDowngrade() ? "PostDowngr" : ""); 46913995Sbrandon.potter@amd.com 4702238SN/A ccprintf(os, "%s Targets:\n", prefix); 4712238SN/A targets.print(os, verbosity, prefix + " "); 47213995Sbrandon.potter@amd.com if (!deferredTargets.empty()) { 4732238SN/A ccprintf(os, "%s Deferred Targets:\n", prefix); 4742238SN/A deferredTargets.print(os, verbosity, prefix + " "); 47513995Sbrandon.potter@amd.com } 4762238SN/A} 4772238SN/A 47813995Sbrandon.potter@amd.comstd::string 4792238SN/AMSHR::print() const 4802238SN/A{ 4811354SN/A ostringstream str; 4821354SN/A print(str); 48310796Sbrandon.potter@amd.com return str.str(); 48410796Sbrandon.potter@amd.com} 4851354SN/A