mshr.cc revision 6216
17405SAli.Saidi@ARM.com/* 212667Schuan.zhu@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 37405SAli.Saidi@ARM.com * All rights reserved. 47405SAli.Saidi@ARM.com * 57405SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without 67405SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are 77405SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright 87405SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer; 97405SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright 107405SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the 117405SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution; 127405SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its 137405SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from 147405SAli.Saidi@ARM.com * this software without specific prior written permission. 157405SAli.Saidi@ARM.com * 167405SAli.Saidi@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177405SAli.Saidi@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187405SAli.Saidi@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197405SAli.Saidi@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207405SAli.Saidi@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 217405SAli.Saidi@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 227405SAli.Saidi@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237405SAli.Saidi@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247405SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257405SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 267405SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277405SAli.Saidi@ARM.com * 287405SAli.Saidi@ARM.com * Authors: Erik Hallnor 297405SAli.Saidi@ARM.com * Dave Greene 307405SAli.Saidi@ARM.com */ 317405SAli.Saidi@ARM.com 327405SAli.Saidi@ARM.com/** 337405SAli.Saidi@ARM.com * @file 347405SAli.Saidi@ARM.com * Miss Status and Handling Register (MSHR) definitions. 357405SAli.Saidi@ARM.com */ 367405SAli.Saidi@ARM.com 377405SAli.Saidi@ARM.com#include <algorithm> 387405SAli.Saidi@ARM.com#include <cassert> 397405SAli.Saidi@ARM.com#include <string> 407405SAli.Saidi@ARM.com#include <vector> 417405SAli.Saidi@ARM.com 4210461SAndreas.Sandberg@ARM.com#include "base/misc.hh" 439050Schander.sudanthi@arm.com#include "base/types.hh" 4412406Sgabeblack@google.com#include "mem/cache/cache.hh" 4512605Sgiacomo.travaglini@arm.com#include "mem/cache/mshr.hh" 4611793Sbrandon.potter@amd.com#include "sim/core.hh" 478887Sgeoffrey.blake@arm.com 488232Snate@binkert.orgusing namespace std; 498232Snate@binkert.org 5010844Sandreas.sandberg@arm.comMSHR::MSHR() 519384SAndreas.Sandberg@arm.com{ 527678Sgblack@eecs.umich.edu inService = false; 538059SAli.Saidi@ARM.com ntargets = 0; 548284SAli.Saidi@ARM.com threadNum = -1; 557405SAli.Saidi@ARM.com targets = new TargetList(); 567405SAli.Saidi@ARM.com deferredTargets = new TargetList(); 577405SAli.Saidi@ARM.com} 587405SAli.Saidi@ARM.com 599384SAndreas.Sandberg@arm.com 6010461SAndreas.Sandberg@ARM.comMSHR::TargetList::TargetList() 6110461SAndreas.Sandberg@ARM.com : needsExclusive(false), hasUpgrade(false) 6211165SRekai.GonzalezAlberquilla@arm.com{} 6312109SRekai.GonzalezAlberquilla@arm.com 6412714Sgiacomo.travaglini@arm.com 6512714Sgiacomo.travaglini@arm.cominline void 669384SAndreas.Sandberg@arm.comMSHR::TargetList::add(PacketPtr pkt, Tick readyTime, 6711770SCurtis.Dunham@arm.com Counter order, Target::Source source, bool markPending) 6810037SARM gem5 Developers{ 6910461SAndreas.Sandberg@ARM.com if (source != Target::FromSnoop) { 7010461SAndreas.Sandberg@ARM.com if (pkt->needsExclusive()) { 7110461SAndreas.Sandberg@ARM.com needsExclusive = true; 7210461SAndreas.Sandberg@ARM.com } 7310461SAndreas.Sandberg@ARM.com 7410461SAndreas.Sandberg@ARM.com if (pkt->cmd == MemCmd::UpgradeReq) { 7510609Sandreas.sandberg@arm.com hasUpgrade = true; 7610609Sandreas.sandberg@arm.com } 7710609Sandreas.sandberg@arm.com } 7810037SARM gem5 Developers 7910037SARM gem5 Developers if (markPending) { 8010037SARM gem5 Developers MSHR *mshr = dynamic_cast<MSHR*>(pkt->senderState); 8110037SARM gem5 Developers if (mshr != NULL) { 8211771SCurtis.Dunham@arm.com assert(!mshr->downstreamPending); 8310037SARM gem5 Developers mshr->downstreamPending = true; 8410037SARM gem5 Developers } 8510037SARM gem5 Developers } 8610037SARM gem5 Developers 8710037SARM gem5 Developers push_back(Target(pkt, readyTime, order, source, markPending)); 8810037SARM gem5 Developers} 8911771SCurtis.Dunham@arm.com 9010037SARM gem5 Developers 9110037SARM gem5 Developersvoid 9210037SARM gem5 DevelopersMSHR::TargetList::replaceUpgrades() 9310037SARM gem5 Developers{ 9410037SARM gem5 Developers if (!hasUpgrade) 9512477SCurtis.Dunham@arm.com return; 9610037SARM gem5 Developers 9710037SARM gem5 Developers Iterator end_i = end(); 989384SAndreas.Sandberg@arm.com for (Iterator i = begin(); i != end_i; ++i) { 999384SAndreas.Sandberg@arm.com if (i->pkt->cmd == MemCmd::UpgradeReq) { 1009384SAndreas.Sandberg@arm.com i->pkt->cmd = MemCmd::ReadExReq; 10112479SCurtis.Dunham@arm.com DPRINTF(Cache, "Replacing UpgradeReq with ReadExReq\n"); 10212479SCurtis.Dunham@arm.com } 1039384SAndreas.Sandberg@arm.com } 1049384SAndreas.Sandberg@arm.com 1059384SAndreas.Sandberg@arm.com hasUpgrade = false; 1069384SAndreas.Sandberg@arm.com} 1079384SAndreas.Sandberg@arm.com 1089384SAndreas.Sandberg@arm.com 1097427Sgblack@eecs.umich.eduvoid 1107427Sgblack@eecs.umich.eduMSHR::TargetList::clearDownstreamPending() 1117427Sgblack@eecs.umich.edu{ 1129385SAndreas.Sandberg@arm.com Iterator end_i = end(); 1139385SAndreas.Sandberg@arm.com for (Iterator i = begin(); i != end_i; ++i) { 1147427Sgblack@eecs.umich.edu if (i->markedPending) { 1157427Sgblack@eecs.umich.edu MSHR *mshr = dynamic_cast<MSHR*>(i->pkt->senderState); 11610037SARM gem5 Developers if (mshr != NULL) { 11710037SARM gem5 Developers mshr->clearDownstreamPending(); 11810037SARM gem5 Developers } 11910037SARM gem5 Developers } 12010037SARM gem5 Developers } 12110037SARM gem5 Developers} 12212690Sgiacomo.travaglini@arm.com 12312690Sgiacomo.travaglini@arm.com 12412690Sgiacomo.travaglini@arm.combool 12512690Sgiacomo.travaglini@arm.comMSHR::TargetList::checkFunctional(PacketPtr pkt) 12612690Sgiacomo.travaglini@arm.com{ 12712690Sgiacomo.travaglini@arm.com Iterator end_i = end(); 12812690Sgiacomo.travaglini@arm.com for (Iterator i = begin(); i != end_i; ++i) { 12912690Sgiacomo.travaglini@arm.com if (pkt->checkFunctional(i->pkt)) { 13012690Sgiacomo.travaglini@arm.com return true; 13112690Sgiacomo.travaglini@arm.com } 13212690Sgiacomo.travaglini@arm.com } 13312690Sgiacomo.travaglini@arm.com 13410037SARM gem5 Developers return false; 13510037SARM gem5 Developers} 13610037SARM gem5 Developers 13710037SARM gem5 Developers 13810037SARM gem5 Developersvoid 13910037SARM gem5 DevelopersMSHR::TargetList:: 14010037SARM gem5 Developersprint(std::ostream &os, int verbosity, const std::string &prefix) const 14110037SARM gem5 Developers{ 1427427Sgblack@eecs.umich.edu ConstIterator end_i = end(); 1437427Sgblack@eecs.umich.edu for (ConstIterator i = begin(); i != end_i; ++i) { 1447427Sgblack@eecs.umich.edu const char *s; 1457427Sgblack@eecs.umich.edu switch (i->source) { 1467427Sgblack@eecs.umich.edu case Target::FromCPU: s = "FromCPU"; 1477427Sgblack@eecs.umich.edu case Target::FromSnoop: s = "FromSnoop"; 14810037SARM gem5 Developers case Target::FromPrefetcher: s = "FromPrefetcher"; 14910037SARM gem5 Developers default: s = ""; 15010037SARM gem5 Developers } 15110037SARM gem5 Developers ccprintf(os, "%s%s: ", prefix, s); 1527427Sgblack@eecs.umich.edu i->pkt->print(os, verbosity, ""); 1537427Sgblack@eecs.umich.edu } 1547427Sgblack@eecs.umich.edu} 15510037SARM gem5 Developers 15610204SAli.Saidi@ARM.com 15710204SAli.Saidi@ARM.comvoid 15810037SARM gem5 DevelopersMSHR::allocate(Addr _addr, int _size, PacketPtr target, 1597427Sgblack@eecs.umich.edu Tick whenReady, Counter _order) 16010037SARM gem5 Developers{ 1617427Sgblack@eecs.umich.edu addr = _addr; 16210037SARM gem5 Developers size = _size; 1637427Sgblack@eecs.umich.edu readyTime = whenReady; 1647427Sgblack@eecs.umich.edu order = _order; 16510037SARM gem5 Developers assert(target); 1667427Sgblack@eecs.umich.edu isForward = false; 1677427Sgblack@eecs.umich.edu _isUncacheable = target->req->isUncacheable(); 1687427Sgblack@eecs.umich.edu inService = false; 1697427Sgblack@eecs.umich.edu downstreamPending = false; 1707427Sgblack@eecs.umich.edu threadNum = 0; 1717427Sgblack@eecs.umich.edu ntargets = 1; 1727427Sgblack@eecs.umich.edu assert(targets->isReset()); 1737427Sgblack@eecs.umich.edu // Don't know of a case where we would allocate a new MSHR for a 1747427Sgblack@eecs.umich.edu // snoop (mem-side request), so set source according to request here 1757427Sgblack@eecs.umich.edu Target::Source source = (target->cmd == MemCmd::HardPFReq) ? 1767427Sgblack@eecs.umich.edu Target::FromPrefetcher : Target::FromCPU; 1777427Sgblack@eecs.umich.edu targets->add(target, whenReady, _order, source, true); 1787427Sgblack@eecs.umich.edu assert(deferredTargets->isReset()); 1797427Sgblack@eecs.umich.edu pendingInvalidate = false; 1807427Sgblack@eecs.umich.edu pendingShared = false; 1817427Sgblack@eecs.umich.edu data = NULL; 1827427Sgblack@eecs.umich.edu} 1837427Sgblack@eecs.umich.edu 1847427Sgblack@eecs.umich.edu 1857427Sgblack@eecs.umich.eduvoid 1867427Sgblack@eecs.umich.eduMSHR::clearDownstreamPending() 1877427Sgblack@eecs.umich.edu{ 1887427Sgblack@eecs.umich.edu assert(downstreamPending); 1897436Sdam.sunwoo@arm.com downstreamPending = false; 1907436Sdam.sunwoo@arm.com // recursively clear flag on any MSHRs we will be forwarding 19110037SARM gem5 Developers // responses to 19210037SARM gem5 Developers targets->clearDownstreamPending(); 1937436Sdam.sunwoo@arm.com} 1947436Sdam.sunwoo@arm.com 1957436Sdam.sunwoo@arm.combool 1967436Sdam.sunwoo@arm.comMSHR::markInService() 1977436Sdam.sunwoo@arm.com{ 1987436Sdam.sunwoo@arm.com assert(!inService); 1997436Sdam.sunwoo@arm.com if (isForwardNoResponse()) { 2007436Sdam.sunwoo@arm.com // we just forwarded the request packet & don't expect a 2017436Sdam.sunwoo@arm.com // response, so get rid of it 2027436Sdam.sunwoo@arm.com assert(getNumTargets() == 1); 2037436Sdam.sunwoo@arm.com popTarget(); 2047436Sdam.sunwoo@arm.com return true; 20510037SARM gem5 Developers } 2067436Sdam.sunwoo@arm.com inService = true; 2077436Sdam.sunwoo@arm.com if (!downstreamPending) { 2087436Sdam.sunwoo@arm.com // let upstream caches know that the request has made it to a 2097436Sdam.sunwoo@arm.com // level where it's going to get a response 2107436Sdam.sunwoo@arm.com targets->clearDownstreamPending(); 2117436Sdam.sunwoo@arm.com } 2127436Sdam.sunwoo@arm.com return false; 2137436Sdam.sunwoo@arm.com} 2147436Sdam.sunwoo@arm.com 2157436Sdam.sunwoo@arm.com 2167436Sdam.sunwoo@arm.comvoid 2177436Sdam.sunwoo@arm.comMSHR::deallocate() 2187436Sdam.sunwoo@arm.com{ 2197436Sdam.sunwoo@arm.com assert(targets->empty()); 2207436Sdam.sunwoo@arm.com targets->resetFlags(); 2217436Sdam.sunwoo@arm.com assert(deferredTargets->isReset()); 2227644Sali.saidi@arm.com assert(ntargets == 0); 2238147SAli.Saidi@ARM.com inService = false; 2249385SAndreas.Sandberg@arm.com //allocIter = NULL; 2259385SAndreas.Sandberg@arm.com //readyIter = NULL; 22610037SARM gem5 Developers} 22710037SARM gem5 Developers 22810037SARM gem5 Developers/* 22910037SARM gem5 Developers * Adds a target to an MSHR 23010037SARM gem5 Developers */ 23110037SARM gem5 Developersvoid 23210037SARM gem5 DevelopersMSHR::allocateTarget(PacketPtr pkt, Tick whenReady, Counter _order) 23310037SARM gem5 Developers{ 23410037SARM gem5 Developers // if there's a request already in service for this MSHR, we will 23510037SARM gem5 Developers // have to defer the new target until after the response if any of 23610037SARM gem5 Developers // the following are true: 23710037SARM gem5 Developers // - there are other targets already deferred 23810037SARM gem5 Developers // - there's a pending invalidate to be applied after the response 23910037SARM gem5 Developers // comes back (but before this target is processed) 24010037SARM gem5 Developers // - the outstanding request is for a non-exclusive block and this 24110037SARM gem5 Developers // target requires an exclusive block 2428147SAli.Saidi@ARM.com 2437427Sgblack@eecs.umich.edu // assume we'd never issue a prefetch when we've got an 2447427Sgblack@eecs.umich.edu // outstanding miss 2457427Sgblack@eecs.umich.edu assert(pkt->cmd != MemCmd::HardPFReq); 24610037SARM gem5 Developers 24710037SARM gem5 Developers if (inService && 24810037SARM gem5 Developers (!deferredTargets->empty() || pendingInvalidate || 24910037SARM gem5 Developers (!targets->needsExclusive && pkt->needsExclusive()))) { 25010037SARM gem5 Developers // need to put on deferred list 25110037SARM gem5 Developers deferredTargets->add(pkt, whenReady, _order, Target::FromCPU, true); 25210037SARM gem5 Developers } else { 25310037SARM gem5 Developers // No request outstanding, or still OK to append to 25410037SARM gem5 Developers // outstanding request: append to regular target list. Only 25510037SARM gem5 Developers // mark pending if current request hasn't been issued yet 25610037SARM gem5 Developers // (isn't in service). 25710037SARM gem5 Developers targets->add(pkt, whenReady, _order, Target::FromCPU, !inService); 25810037SARM gem5 Developers } 25910037SARM gem5 Developers 26010037SARM gem5 Developers ++ntargets; 26110037SARM gem5 Developers} 26210037SARM gem5 Developers 26310037SARM gem5 Developersbool 26410037SARM gem5 DevelopersMSHR::handleSnoop(PacketPtr pkt, Counter _order) 26510037SARM gem5 Developers{ 26610037SARM gem5 Developers if (!inService || (pkt->isExpressSnoop() && downstreamPending)) { 26710037SARM gem5 Developers // Request has not been issued yet, or it's been issued 26810037SARM gem5 Developers // locally but is buffered unissued at some downstream cache 26910037SARM gem5 Developers // which is forwarding us this snoop. Either way, the packet 27010037SARM gem5 Developers // we're snooping logically precedes this MSHR's request, so 27110037SARM gem5 Developers // the snoop has no impact on the MSHR, but must be processed 27210037SARM gem5 Developers // in the standard way by the cache. The only exception is 27310037SARM gem5 Developers // that if we're an L2+ cache buffering an UpgradeReq from a 27410037SARM gem5 Developers // higher-level cache, and the snoop is invalidating, then our 27510037SARM gem5 Developers // buffered upgrades must be converted to read exclusives, 27610037SARM gem5 Developers // since the upper-level cache no longer has a valid copy. 27710037SARM gem5 Developers // That is, even though the upper-level cache got out on its 27810037SARM gem5 Developers // local bus first, some other invalidating transaction 27910037SARM gem5 Developers // reached the global bus before the upgrade did. 28010037SARM gem5 Developers if (pkt->needsExclusive()) { 28110037SARM gem5 Developers targets->replaceUpgrades(); 28211770SCurtis.Dunham@arm.com deferredTargets->replaceUpgrades(); 28310037SARM gem5 Developers } 28411574SCurtis.Dunham@arm.com 28511770SCurtis.Dunham@arm.com return false; 28611770SCurtis.Dunham@arm.com } 28710037SARM gem5 Developers 28811770SCurtis.Dunham@arm.com // From here on down, the request issued by this MSHR logically 28911770SCurtis.Dunham@arm.com // precedes the request we're snooping. 29010037SARM gem5 Developers 29110037SARM gem5 Developers if (pkt->needsExclusive()) { 29210037SARM gem5 Developers // snooped request still precedes the re-request we'll have to 29310037SARM gem5 Developers // issue for deferred targets, if any... 29410037SARM gem5 Developers deferredTargets->replaceUpgrades(); 29510037SARM gem5 Developers } 29610037SARM gem5 Developers 29710461SAndreas.Sandberg@ARM.com if (pendingInvalidate) { 29810461SAndreas.Sandberg@ARM.com // a prior snoop has already appended an invalidation, so 29910461SAndreas.Sandberg@ARM.com // logically we don't have the block anymore; no need for 30010461SAndreas.Sandberg@ARM.com // further snooping. 30110037SARM gem5 Developers return true; 30210037SARM gem5 Developers } 30310037SARM gem5 Developers 30410037SARM gem5 Developers if (targets->needsExclusive || pkt->needsExclusive()) { 30510037SARM gem5 Developers // actual target device (typ. PhysicalMemory) will delete the 30610037SARM gem5 Developers // packet on reception, so we need to save a copy here 30710461SAndreas.Sandberg@ARM.com PacketPtr cp_pkt = new Packet(pkt, true); 30810461SAndreas.Sandberg@ARM.com targets->add(cp_pkt, curTick, _order, Target::FromSnoop, 30910461SAndreas.Sandberg@ARM.com downstreamPending && targets->needsExclusive); 31010461SAndreas.Sandberg@ARM.com ++ntargets; 31110461SAndreas.Sandberg@ARM.com 31210037SARM gem5 Developers if (targets->needsExclusive) { 31310037SARM gem5 Developers // We're awaiting an exclusive copy, so ownership is pending. 31410037SARM gem5 Developers // It's up to us to respond once the data arrives. 31510037SARM gem5 Developers pkt->assertMemInhibit(); 31610037SARM gem5 Developers pkt->setSupplyExclusive(); 31711574SCurtis.Dunham@arm.com } else { 31810037SARM gem5 Developers // Someone else may respond before we get around to 31910037SARM gem5 Developers // processing this snoop, which means the copied request 32010037SARM gem5 Developers // pointer will no longer be valid 32111574SCurtis.Dunham@arm.com cp_pkt->req = NULL; 32210037SARM gem5 Developers } 32310037SARM gem5 Developers 32410037SARM gem5 Developers if (pkt->needsExclusive()) { 32510037SARM gem5 Developers // This transaction will take away our pending copy 32610037SARM gem5 Developers pendingInvalidate = true; 32710037SARM gem5 Developers } 32810037SARM gem5 Developers } else { 32910037SARM gem5 Developers // Read to a read: no conflict, so no need to record as 33010037SARM gem5 Developers // target, but make sure neither reader thinks he's getting an 33110037SARM gem5 Developers // exclusive copy 3327405SAli.Saidi@ARM.com pendingShared = true; 33310035Sandreas.hansson@arm.com pkt->assertShared(); 3347405SAli.Saidi@ARM.com } 3357405SAli.Saidi@ARM.com 3367614Sminkyu.jeong@arm.com return true; 33712478SCurtis.Dunham@arm.com} 33812478SCurtis.Dunham@arm.com 33912478SCurtis.Dunham@arm.com 34012478SCurtis.Dunham@arm.combool 34112478SCurtis.Dunham@arm.comMSHR::promoteDeferredTargets() 34212478SCurtis.Dunham@arm.com{ 34312478SCurtis.Dunham@arm.com assert(targets->empty()); 34412478SCurtis.Dunham@arm.com if (deferredTargets->empty()) { 34512478SCurtis.Dunham@arm.com return false; 34612478SCurtis.Dunham@arm.com } 34712478SCurtis.Dunham@arm.com 34812478SCurtis.Dunham@arm.com // swap targets & deferredTargets lists 34912478SCurtis.Dunham@arm.com TargetList *tmp = targets; 35012478SCurtis.Dunham@arm.com targets = deferredTargets; 35112478SCurtis.Dunham@arm.com deferredTargets = tmp; 35212478SCurtis.Dunham@arm.com 3537405SAli.Saidi@ARM.com assert(targets->size() == ntargets); 3547405SAli.Saidi@ARM.com 3557405SAli.Saidi@ARM.com // clear deferredTargets flags 3567405SAli.Saidi@ARM.com deferredTargets->resetFlags(); 3577405SAli.Saidi@ARM.com 3587405SAli.Saidi@ARM.com pendingInvalidate = false; 35910037SARM gem5 Developers pendingShared = false; 36010037SARM gem5 Developers order = targets->front().order; 36110037SARM gem5 Developers readyTime = std::max(curTick, targets->front().readyTime); 3629050Schander.sudanthi@arm.com 3637405SAli.Saidi@ARM.com return true; 36410037SARM gem5 Developers} 36510037SARM gem5 Developers 3667720Sgblack@eecs.umich.edu 3677720Sgblack@eecs.umich.eduvoid 3687405SAli.Saidi@ARM.comMSHR::handleFill(Packet *pkt, CacheBlk *blk) 3697405SAli.Saidi@ARM.com{ 3707757SAli.Saidi@ARM.com if (pendingShared) { 37110037SARM gem5 Developers // we snooped another read while this read was in 37210037SARM gem5 Developers // service... assert shared line on its behalf 37310037SARM gem5 Developers pkt->assertShared(); 37410037SARM gem5 Developers } 37510037SARM gem5 Developers 37610037SARM gem5 Developers if (!pkt->sharedAsserted() && !pendingInvalidate 37710037SARM gem5 Developers && deferredTargets->needsExclusive) { 37810037SARM gem5 Developers // We got an exclusive response, but we have deferred targets 37910037SARM gem5 Developers // which are waiting to request an exclusive copy (not because 38010037SARM gem5 Developers // of a pending invalidate). This can happen if the original 38110037SARM gem5 Developers // request was for a read-only (non-exclusive) block, but we 38210037SARM gem5 Developers // got an exclusive copy anyway because of the E part of the 38310037SARM gem5 Developers // MOESI/MESI protocol. Since we got the exclusive copy 38410037SARM gem5 Developers // there's no need to defer the targets, so move them up to 38510037SARM gem5 Developers // the regular target list. 38610037SARM gem5 Developers assert(!targets->needsExclusive); 38710037SARM gem5 Developers targets->needsExclusive = true; 38810037SARM gem5 Developers // if any of the deferred targets were upper-level cache 38910037SARM gem5 Developers // requests marked downstreamPending, need to clear that 39010037SARM gem5 Developers assert(!downstreamPending); // not pending here anymore 39110037SARM gem5 Developers deferredTargets->clearDownstreamPending(); 39210037SARM gem5 Developers // this clears out deferredTargets too 39310037SARM gem5 Developers targets->splice(targets->end(), *deferredTargets); 39410037SARM gem5 Developers deferredTargets->resetFlags(); 39510037SARM gem5 Developers } 39610037SARM gem5 Developers} 39710037SARM gem5 Developers 39810037SARM gem5 Developers 39910037SARM gem5 Developersbool 40010037SARM gem5 DevelopersMSHR::checkFunctional(PacketPtr pkt) 40110037SARM gem5 Developers{ 40210037SARM gem5 Developers // For printing, we treat the MSHR as a whole as single entity. 40310037SARM gem5 Developers // For other requests, we iterate over the individual targets 40412667Schuan.zhu@arm.com // since that's where the actual data lies. 40510037SARM gem5 Developers if (pkt->isPrint()) { 40610037SARM gem5 Developers pkt->checkFunctional(this, addr, size, NULL); 40710037SARM gem5 Developers return false; 40810037SARM gem5 Developers } else { 40910037SARM gem5 Developers return (targets->checkFunctional(pkt) || 41010037SARM gem5 Developers deferredTargets->checkFunctional(pkt)); 41110037SARM gem5 Developers } 41210037SARM gem5 Developers} 41310037SARM gem5 Developers 41410037SARM gem5 Developers 41510037SARM gem5 Developersvoid 41610037SARM gem5 DevelopersMSHR::print(std::ostream &os, int verbosity, const std::string &prefix) const 4178284SAli.Saidi@ARM.com{ 41810037SARM gem5 Developers ccprintf(os, "%s[%x:%x] %s %s %s state: %s %s %s %s\n", 41910037SARM gem5 Developers prefix, addr, addr+size-1, 42010037SARM gem5 Developers isForward ? "Forward" : "", 42110037SARM gem5 Developers isForwardNoResponse() ? "ForwNoResp" : "", 4229050Schander.sudanthi@arm.com needsExclusive() ? "Excl" : "", 42310037SARM gem5 Developers _isUncacheable ? "Unc" : "", 42410037SARM gem5 Developers inService ? "InSvc" : "", 42510037SARM gem5 Developers downstreamPending ? "DwnPend" : "", 42610037SARM gem5 Developers pendingInvalidate ? "PendInv" : "", 42710037SARM gem5 Developers pendingShared ? "PendShared" : ""); 42810037SARM gem5 Developers 42910037SARM gem5 Developers ccprintf(os, "%s Targets:\n", prefix); 43010037SARM gem5 Developers targets->print(os, verbosity, prefix + " "); 43110037SARM gem5 Developers if (!deferredTargets->empty()) { 43210037SARM gem5 Developers ccprintf(os, "%s Deferred Targets:\n", prefix); 43310037SARM gem5 Developers deferredTargets->print(os, verbosity, prefix + " "); 43410037SARM gem5 Developers } 43510037SARM gem5 Developers} 43610037SARM gem5 Developers 43710037SARM gem5 DevelopersMSHR::~MSHR() 43810037SARM gem5 Developers{ 43910037SARM gem5 Developers} 44010037SARM gem5 Developers