snoop_filter.cc revision 10821
110399Sstephan.diestelhorst@arm.com/* 210399Sstephan.diestelhorst@arm.com * Copyright (c) 2013 ARM Limited 310399Sstephan.diestelhorst@arm.com * All rights reserved 410399Sstephan.diestelhorst@arm.com * 510399Sstephan.diestelhorst@arm.com * The license below extends only to copyright in the software and shall 610399Sstephan.diestelhorst@arm.com * not be construed as granting a license to any other intellectual 710399Sstephan.diestelhorst@arm.com * property including but not limited to intellectual property relating 810399Sstephan.diestelhorst@arm.com * to a hardware implementation of the functionality of the software 910399Sstephan.diestelhorst@arm.com * licensed hereunder. You may use the software subject to the license 1010399Sstephan.diestelhorst@arm.com * terms below provided that you ensure that this notice is replicated 1110399Sstephan.diestelhorst@arm.com * unmodified and in its entirety in all distributions of the software, 1210399Sstephan.diestelhorst@arm.com * modified or unmodified, in source code or in binary form. 1310399Sstephan.diestelhorst@arm.com * 1410399Sstephan.diestelhorst@arm.com * Redistribution and use in source and binary forms, with or without 1510399Sstephan.diestelhorst@arm.com * modification, are permitted provided that the following conditions are 1610399Sstephan.diestelhorst@arm.com * met: redistributions of source code must retain the above copyright 1710399Sstephan.diestelhorst@arm.com * notice, this list of conditions and the following disclaimer; 1810399Sstephan.diestelhorst@arm.com * redistributions in binary form must reproduce the above copyright 1910399Sstephan.diestelhorst@arm.com * notice, this list of conditions and the following disclaimer in the 2010399Sstephan.diestelhorst@arm.com * documentation and/or other materials provided with the distribution; 2110399Sstephan.diestelhorst@arm.com * neither the name of the copyright holders nor the names of its 2210399Sstephan.diestelhorst@arm.com * contributors may be used to endorse or promote products derived from 2310399Sstephan.diestelhorst@arm.com * this software without specific prior written permission. 2410399Sstephan.diestelhorst@arm.com * 2510399Sstephan.diestelhorst@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610399Sstephan.diestelhorst@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710399Sstephan.diestelhorst@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810399Sstephan.diestelhorst@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910399Sstephan.diestelhorst@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010399Sstephan.diestelhorst@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110399Sstephan.diestelhorst@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210399Sstephan.diestelhorst@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310399Sstephan.diestelhorst@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410399Sstephan.diestelhorst@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510399Sstephan.diestelhorst@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610399Sstephan.diestelhorst@arm.com * 3710399Sstephan.diestelhorst@arm.com * Authors: Stephan Diestelhorst <stephan.diestelhorst@arm.com> 3810399Sstephan.diestelhorst@arm.com */ 3910399Sstephan.diestelhorst@arm.com 4010399Sstephan.diestelhorst@arm.com/** 4110399Sstephan.diestelhorst@arm.com * @file 4210399Sstephan.diestelhorst@arm.com * Definition of a snoop filter. 4310399Sstephan.diestelhorst@arm.com */ 4410399Sstephan.diestelhorst@arm.com 4510399Sstephan.diestelhorst@arm.com#include "base/misc.hh" 4610399Sstephan.diestelhorst@arm.com#include "base/trace.hh" 4710399Sstephan.diestelhorst@arm.com#include "debug/SnoopFilter.hh" 4810399Sstephan.diestelhorst@arm.com#include "mem/snoop_filter.hh" 4910399Sstephan.diestelhorst@arm.com#include "sim/system.hh" 5010399Sstephan.diestelhorst@arm.com 5110399Sstephan.diestelhorst@arm.comstd::pair<SnoopFilter::SnoopList, Cycles> 5210399Sstephan.diestelhorst@arm.comSnoopFilter::lookupRequest(const Packet* cpkt, const SlavePort& slave_port) 5310399Sstephan.diestelhorst@arm.com{ 5410399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: packet src %s addr 0x%x cmd %s\n", 5510399Sstephan.diestelhorst@arm.com __func__, slave_port.name(), cpkt->getAddr(), cpkt->cmdString()); 5610399Sstephan.diestelhorst@arm.com 5710399Sstephan.diestelhorst@arm.com Addr line_addr = cpkt->getAddr() & ~(linesize - 1); 5810399Sstephan.diestelhorst@arm.com SnoopMask req_port = portToMask(slave_port); 5910403Sstephan.diestelhorst@arm.com auto sf_it = cachedLocations.find(line_addr); 6010403Sstephan.diestelhorst@arm.com bool is_hit = (sf_it != cachedLocations.end()); 6110403Sstephan.diestelhorst@arm.com // Create a new element through operator[] and modify in-place 6210403Sstephan.diestelhorst@arm.com SnoopItem& sf_item = is_hit ? sf_it->second : cachedLocations[line_addr]; 6310403Sstephan.diestelhorst@arm.com SnoopMask interested = sf_item.holder | sf_item.requested; 6410403Sstephan.diestelhorst@arm.com 6510403Sstephan.diestelhorst@arm.com totRequests++; 6610403Sstephan.diestelhorst@arm.com if (is_hit) { 6710403Sstephan.diestelhorst@arm.com // Single bit set -> value is a power of two 6810403Sstephan.diestelhorst@arm.com if (isPow2(interested)) 6910403Sstephan.diestelhorst@arm.com hitSingleRequests++; 7010403Sstephan.diestelhorst@arm.com else 7110403Sstephan.diestelhorst@arm.com hitMultiRequests++; 7210403Sstephan.diestelhorst@arm.com } 7310399Sstephan.diestelhorst@arm.com 7410399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: SF value %x.%x\n", 7510399Sstephan.diestelhorst@arm.com __func__, sf_item.requested, sf_item.holder); 7610399Sstephan.diestelhorst@arm.com 7710821Sandreas.hansson@arm.com if (!cpkt->req->isUncacheable() && cpkt->needsResponse()) { 7810399Sstephan.diestelhorst@arm.com if (!cpkt->memInhibitAsserted()) { 7910399Sstephan.diestelhorst@arm.com // Max one request per address per port 8010399Sstephan.diestelhorst@arm.com panic_if(sf_item.requested & req_port, "double request :( "\ 8110399Sstephan.diestelhorst@arm.com "SF value %x.%x\n", sf_item.requested, sf_item.holder); 8210399Sstephan.diestelhorst@arm.com 8310399Sstephan.diestelhorst@arm.com // Mark in-flight requests to distinguish later on 8410399Sstephan.diestelhorst@arm.com sf_item.requested |= req_port; 8510399Sstephan.diestelhorst@arm.com } else { 8610399Sstephan.diestelhorst@arm.com // NOTE: The memInhibit might have been asserted by a cache closer 8710399Sstephan.diestelhorst@arm.com // to the CPU, already -> the response will not be seen by this 8810399Sstephan.diestelhorst@arm.com // filter -> we do not need to keep the in-flight request, but make 8910399Sstephan.diestelhorst@arm.com // sure that we know that that cluster has a copy 9010399Sstephan.diestelhorst@arm.com panic_if(!(sf_item.holder & req_port), "Need to hold the value!"); 9110399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: not marking request. SF value %x.%x\n", 9210399Sstephan.diestelhorst@arm.com __func__, sf_item.requested, sf_item.holder); 9310399Sstephan.diestelhorst@arm.com } 9410399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n", 9510399Sstephan.diestelhorst@arm.com __func__, sf_item.requested, sf_item.holder); 9610399Sstephan.diestelhorst@arm.com } 9710403Sstephan.diestelhorst@arm.com return snoopSelected(maskToPortList(interested & ~req_port), lookupLatency); 9810399Sstephan.diestelhorst@arm.com} 9910399Sstephan.diestelhorst@arm.com 10010399Sstephan.diestelhorst@arm.comvoid 10110399Sstephan.diestelhorst@arm.comSnoopFilter::updateRequest(const Packet* cpkt, const SlavePort& slave_port, 10210399Sstephan.diestelhorst@arm.com bool will_retry) 10310399Sstephan.diestelhorst@arm.com{ 10410399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: packet src %s addr 0x%x cmd %s\n", 10510399Sstephan.diestelhorst@arm.com __func__, slave_port.name(), cpkt->getAddr(), cpkt->cmdString()); 10610399Sstephan.diestelhorst@arm.com 10710821Sandreas.hansson@arm.com if (cpkt->req->isUncacheable()) 10810821Sandreas.hansson@arm.com return; 10910821Sandreas.hansson@arm.com 11010399Sstephan.diestelhorst@arm.com Addr line_addr = cpkt->getAddr() & ~(linesize - 1); 11110399Sstephan.diestelhorst@arm.com SnoopMask req_port = portToMask(slave_port); 11210399Sstephan.diestelhorst@arm.com SnoopItem& sf_item = cachedLocations[line_addr]; 11310399Sstephan.diestelhorst@arm.com 11410399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: old SF value %x.%x retry: %i\n", 11510399Sstephan.diestelhorst@arm.com __func__, sf_item.requested, sf_item.holder, will_retry); 11610399Sstephan.diestelhorst@arm.com 11710399Sstephan.diestelhorst@arm.com if (will_retry) { 11810399Sstephan.diestelhorst@arm.com // Unmark a request that will come again. 11910399Sstephan.diestelhorst@arm.com sf_item.requested &= ~req_port; 12010399Sstephan.diestelhorst@arm.com return; 12110399Sstephan.diestelhorst@arm.com } 12210399Sstephan.diestelhorst@arm.com 12310399Sstephan.diestelhorst@arm.com // will_retry == false 12410399Sstephan.diestelhorst@arm.com if (!cpkt->needsResponse()) { 12510399Sstephan.diestelhorst@arm.com // Packets that will not evoke a response but still need updates of the 12610399Sstephan.diestelhorst@arm.com // snoop filter; WRITEBACKs for now only 12710399Sstephan.diestelhorst@arm.com if (cpkt->cmd == MemCmd::Writeback) { 12810399Sstephan.diestelhorst@arm.com // make sure that the sender actually had the line 12910399Sstephan.diestelhorst@arm.com panic_if(sf_item.requested & req_port, "double request :( "\ 13010399Sstephan.diestelhorst@arm.com "SF value %x.%x\n", sf_item.requested, sf_item.holder); 13110399Sstephan.diestelhorst@arm.com panic_if(!(sf_item.holder & req_port), "requester %x is not a "\ 13210399Sstephan.diestelhorst@arm.com "holder :( SF value %x.%x\n", req_port, 13310399Sstephan.diestelhorst@arm.com sf_item.requested, sf_item.holder); 13410399Sstephan.diestelhorst@arm.com // Writebacks -> the sender does not have the line anymore 13510399Sstephan.diestelhorst@arm.com sf_item.holder &= ~req_port; 13610399Sstephan.diestelhorst@arm.com } else { 13710399Sstephan.diestelhorst@arm.com assert(0 == "Handle non-writeback, here"); 13810399Sstephan.diestelhorst@arm.com } 13910399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n", 14010399Sstephan.diestelhorst@arm.com __func__, sf_item.requested, sf_item.holder); 14110399Sstephan.diestelhorst@arm.com } 14210399Sstephan.diestelhorst@arm.com} 14310399Sstephan.diestelhorst@arm.com 14410399Sstephan.diestelhorst@arm.comstd::pair<SnoopFilter::SnoopList, Cycles> 14510399Sstephan.diestelhorst@arm.comSnoopFilter::lookupSnoop(const Packet* cpkt) 14610399Sstephan.diestelhorst@arm.com{ 14710399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: packet addr 0x%x cmd %s\n", 14810399Sstephan.diestelhorst@arm.com __func__, cpkt->getAddr(), cpkt->cmdString()); 14910399Sstephan.diestelhorst@arm.com 15010399Sstephan.diestelhorst@arm.com assert(cpkt->isRequest()); 15110399Sstephan.diestelhorst@arm.com 15210399Sstephan.diestelhorst@arm.com // Broadcast / filter upward snoops 15310399Sstephan.diestelhorst@arm.com const bool filter_upward = true; // @todo: Make configurable 15410399Sstephan.diestelhorst@arm.com 15510399Sstephan.diestelhorst@arm.com if (!filter_upward) 15610399Sstephan.diestelhorst@arm.com return snoopAll(lookupLatency); 15710399Sstephan.diestelhorst@arm.com 15810399Sstephan.diestelhorst@arm.com Addr line_addr = cpkt->getAddr() & ~(linesize - 1); 15910403Sstephan.diestelhorst@arm.com auto sf_it = cachedLocations.find(line_addr); 16010403Sstephan.diestelhorst@arm.com bool is_hit = (sf_it != cachedLocations.end()); 16110403Sstephan.diestelhorst@arm.com // Create a new element through operator[] and modify in-place 16210403Sstephan.diestelhorst@arm.com SnoopItem& sf_item = is_hit ? sf_it->second : cachedLocations[line_addr]; 16310399Sstephan.diestelhorst@arm.com 16410399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n", 16510399Sstephan.diestelhorst@arm.com __func__, sf_item.requested, sf_item.holder); 16610399Sstephan.diestelhorst@arm.com 16710399Sstephan.diestelhorst@arm.com SnoopMask interested = (sf_item.holder | sf_item.requested); 16810403Sstephan.diestelhorst@arm.com 16910403Sstephan.diestelhorst@arm.com totSnoops++; 17010403Sstephan.diestelhorst@arm.com if (is_hit) { 17110403Sstephan.diestelhorst@arm.com // Single bit set -> value is a power of two 17210403Sstephan.diestelhorst@arm.com if (isPow2(interested)) 17310403Sstephan.diestelhorst@arm.com hitSingleSnoops++; 17410403Sstephan.diestelhorst@arm.com else 17510403Sstephan.diestelhorst@arm.com hitMultiSnoops++; 17610403Sstephan.diestelhorst@arm.com } 17710403Sstephan.diestelhorst@arm.com 17810399Sstephan.diestelhorst@arm.com assert(cpkt->isInvalidate() == cpkt->needsExclusive()); 17910399Sstephan.diestelhorst@arm.com if (cpkt->isInvalidate() && !sf_item.requested) { 18010399Sstephan.diestelhorst@arm.com // Early clear of the holder, if no other request is currently going on 18110399Sstephan.diestelhorst@arm.com // @todo: This should possibly be updated even though we do not filter 18210399Sstephan.diestelhorst@arm.com // upward snoops 18310399Sstephan.diestelhorst@arm.com sf_item.holder = 0; 18410399Sstephan.diestelhorst@arm.com } 18510399Sstephan.diestelhorst@arm.com 18610399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: new SF value %x.%x interest: %x \n", 18710399Sstephan.diestelhorst@arm.com __func__, sf_item.requested, sf_item.holder, interested); 18810399Sstephan.diestelhorst@arm.com 18910399Sstephan.diestelhorst@arm.com return snoopSelected(maskToPortList(interested), lookupLatency); 19010399Sstephan.diestelhorst@arm.com} 19110399Sstephan.diestelhorst@arm.com 19210399Sstephan.diestelhorst@arm.comvoid 19310399Sstephan.diestelhorst@arm.comSnoopFilter::updateSnoopResponse(const Packet* cpkt, 19410399Sstephan.diestelhorst@arm.com const SlavePort& rsp_port, 19510399Sstephan.diestelhorst@arm.com const SlavePort& req_port) 19610399Sstephan.diestelhorst@arm.com{ 19710399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: packet rsp %s req %s addr 0x%x cmd %s\n", 19810399Sstephan.diestelhorst@arm.com __func__, rsp_port.name(), req_port.name(), cpkt->getAddr(), 19910399Sstephan.diestelhorst@arm.com cpkt->cmdString()); 20010399Sstephan.diestelhorst@arm.com 20110821Sandreas.hansson@arm.com assert(cpkt->isResponse()); 20210821Sandreas.hansson@arm.com assert(cpkt->memInhibitAsserted()); 20310821Sandreas.hansson@arm.com 20410821Sandreas.hansson@arm.com if (cpkt->req->isUncacheable()) 20510821Sandreas.hansson@arm.com return; 20610821Sandreas.hansson@arm.com 20710399Sstephan.diestelhorst@arm.com Addr line_addr = cpkt->getAddr() & ~(linesize - 1); 20810399Sstephan.diestelhorst@arm.com SnoopMask rsp_mask = portToMask(rsp_port); 20910399Sstephan.diestelhorst@arm.com SnoopMask req_mask = portToMask(req_port); 21010399Sstephan.diestelhorst@arm.com SnoopItem& sf_item = cachedLocations[line_addr]; 21110399Sstephan.diestelhorst@arm.com 21210399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n", 21310399Sstephan.diestelhorst@arm.com __func__, sf_item.requested, sf_item.holder); 21410399Sstephan.diestelhorst@arm.com 21510399Sstephan.diestelhorst@arm.com // The source should have the line 21610399Sstephan.diestelhorst@arm.com panic_if(!(sf_item.holder & rsp_mask), "SF value %x.%x does not have "\ 21710399Sstephan.diestelhorst@arm.com "the line\n", sf_item.requested, sf_item.holder); 21810399Sstephan.diestelhorst@arm.com 21910399Sstephan.diestelhorst@arm.com // The destination should have had a request in 22010399Sstephan.diestelhorst@arm.com panic_if(!(sf_item.requested & req_mask), "SF value %x.%x missing "\ 22110399Sstephan.diestelhorst@arm.com "the original request\n", sf_item.requested, sf_item.holder); 22210399Sstephan.diestelhorst@arm.com 22310399Sstephan.diestelhorst@arm.com // Update the residency of the cache line. 22410399Sstephan.diestelhorst@arm.com if (cpkt->needsExclusive() || !cpkt->sharedAsserted()) { 22510399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: dropping %x because needs: %i shared: %i "\ 22610399Sstephan.diestelhorst@arm.com "SF val: %x.%x\n", __func__, rsp_mask, 22710399Sstephan.diestelhorst@arm.com cpkt->needsExclusive(), cpkt->sharedAsserted(), 22810399Sstephan.diestelhorst@arm.com sf_item.requested, sf_item.holder); 22910399Sstephan.diestelhorst@arm.com 23010399Sstephan.diestelhorst@arm.com sf_item.holder &= ~rsp_mask; 23110399Sstephan.diestelhorst@arm.com // The snoop filter does not see any ACKs from non-responding sharers 23210399Sstephan.diestelhorst@arm.com // that have been invalidated :( So below assert would be nice, but.. 23310399Sstephan.diestelhorst@arm.com //assert(sf_item.holder == 0); 23410399Sstephan.diestelhorst@arm.com sf_item.holder = 0; 23510399Sstephan.diestelhorst@arm.com } 23610399Sstephan.diestelhorst@arm.com assert(cpkt->cmd != MemCmd::Writeback); 23710399Sstephan.diestelhorst@arm.com sf_item.holder |= req_mask; 23810399Sstephan.diestelhorst@arm.com sf_item.requested &= ~req_mask; 23910399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n", 24010399Sstephan.diestelhorst@arm.com __func__, sf_item.requested, sf_item.holder); 24110399Sstephan.diestelhorst@arm.com} 24210399Sstephan.diestelhorst@arm.com 24310399Sstephan.diestelhorst@arm.comvoid 24410399Sstephan.diestelhorst@arm.comSnoopFilter::updateSnoopForward(const Packet* cpkt, 24510399Sstephan.diestelhorst@arm.com const SlavePort& rsp_port, const MasterPort& req_port) 24610399Sstephan.diestelhorst@arm.com{ 24710399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: packet rsp %s req %s addr 0x%x cmd %s\n", 24810399Sstephan.diestelhorst@arm.com __func__, rsp_port.name(), req_port.name(), cpkt->getAddr(), 24910399Sstephan.diestelhorst@arm.com cpkt->cmdString()); 25010399Sstephan.diestelhorst@arm.com 25110399Sstephan.diestelhorst@arm.com Addr line_addr = cpkt->getAddr() & ~(linesize - 1); 25210399Sstephan.diestelhorst@arm.com SnoopItem& sf_item = cachedLocations[line_addr]; 25310399Sstephan.diestelhorst@arm.com SnoopMask rsp_mask M5_VAR_USED = portToMask(rsp_port); 25410399Sstephan.diestelhorst@arm.com 25510399Sstephan.diestelhorst@arm.com assert(cpkt->isResponse()); 25610399Sstephan.diestelhorst@arm.com assert(cpkt->memInhibitAsserted()); 25710399Sstephan.diestelhorst@arm.com 25810399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n", 25910399Sstephan.diestelhorst@arm.com __func__, sf_item.requested, sf_item.holder); 26010399Sstephan.diestelhorst@arm.com 26110399Sstephan.diestelhorst@arm.com // Remote (to this snoop filter) snoops update the filter already when they 26210399Sstephan.diestelhorst@arm.com // arrive from below, because we may not see any response. 26310399Sstephan.diestelhorst@arm.com if (cpkt->needsExclusive()) { 26410399Sstephan.diestelhorst@arm.com // If the request to this snoop response hit an in-flight transaction, 26510399Sstephan.diestelhorst@arm.com // the holder was not reset -> no assertion & do that here, now! 26610399Sstephan.diestelhorst@arm.com //assert(sf_item.holder == 0); 26710399Sstephan.diestelhorst@arm.com sf_item.holder = 0; 26810399Sstephan.diestelhorst@arm.com } 26910399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n", 27010399Sstephan.diestelhorst@arm.com __func__, sf_item.requested, sf_item.holder); 27110399Sstephan.diestelhorst@arm.com} 27210399Sstephan.diestelhorst@arm.com 27310399Sstephan.diestelhorst@arm.comvoid 27410399Sstephan.diestelhorst@arm.comSnoopFilter::updateResponse(const Packet* cpkt, const SlavePort& slave_port) 27510399Sstephan.diestelhorst@arm.com{ 27610399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: packet src %s addr 0x%x cmd %s\n", 27710399Sstephan.diestelhorst@arm.com __func__, slave_port.name(), cpkt->getAddr(), cpkt->cmdString()); 27810399Sstephan.diestelhorst@arm.com 27910821Sandreas.hansson@arm.com assert(cpkt->isResponse()); 28010821Sandreas.hansson@arm.com 28110821Sandreas.hansson@arm.com if (cpkt->req->isUncacheable()) 28210821Sandreas.hansson@arm.com return; 28310821Sandreas.hansson@arm.com 28410399Sstephan.diestelhorst@arm.com Addr line_addr = cpkt->getAddr() & ~(linesize - 1); 28510399Sstephan.diestelhorst@arm.com SnoopMask slave_mask = portToMask(slave_port); 28610399Sstephan.diestelhorst@arm.com SnoopItem& sf_item = cachedLocations[line_addr]; 28710399Sstephan.diestelhorst@arm.com 28810399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: old SF value %x.%x\n", 28910399Sstephan.diestelhorst@arm.com __func__, sf_item.requested, sf_item.holder); 29010399Sstephan.diestelhorst@arm.com 29110399Sstephan.diestelhorst@arm.com // Make sure we have seen the actual request, too 29210399Sstephan.diestelhorst@arm.com panic_if(!(sf_item.requested & slave_mask), "SF value %x.%x missing "\ 29310399Sstephan.diestelhorst@arm.com "request bit\n", sf_item.requested, sf_item.holder); 29410399Sstephan.diestelhorst@arm.com 29510399Sstephan.diestelhorst@arm.com // Update the residency of the cache line. 29610399Sstephan.diestelhorst@arm.com if (cpkt->needsExclusive() || !cpkt->sharedAsserted()) 29710399Sstephan.diestelhorst@arm.com sf_item.holder = 0; 29810399Sstephan.diestelhorst@arm.com sf_item.holder |= slave_mask; 29910399Sstephan.diestelhorst@arm.com sf_item.requested &= ~slave_mask; 30010399Sstephan.diestelhorst@arm.com DPRINTF(SnoopFilter, "%s: new SF value %x.%x\n", 30110399Sstephan.diestelhorst@arm.com __func__, sf_item.requested, sf_item.holder); 30210399Sstephan.diestelhorst@arm.com} 30310399Sstephan.diestelhorst@arm.com 30410403Sstephan.diestelhorst@arm.comvoid 30510403Sstephan.diestelhorst@arm.comSnoopFilter::regStats() 30610403Sstephan.diestelhorst@arm.com{ 30710403Sstephan.diestelhorst@arm.com totRequests 30810403Sstephan.diestelhorst@arm.com .name(name() + ".tot_requests") 30910403Sstephan.diestelhorst@arm.com .desc("Total number of requests made to the snoop filter."); 31010403Sstephan.diestelhorst@arm.com 31110403Sstephan.diestelhorst@arm.com hitSingleRequests 31210403Sstephan.diestelhorst@arm.com .name(name() + ".hit_single_requests") 31310403Sstephan.diestelhorst@arm.com .desc("Number of requests hitting in the snoop filter with a single "\ 31410403Sstephan.diestelhorst@arm.com "holder of the requested data."); 31510403Sstephan.diestelhorst@arm.com 31610403Sstephan.diestelhorst@arm.com hitMultiRequests 31710403Sstephan.diestelhorst@arm.com .name(name() + ".hit_multi_requests") 31810403Sstephan.diestelhorst@arm.com .desc("Number of requests hitting in the snoop filter with multiple "\ 31910403Sstephan.diestelhorst@arm.com "(>1) holders of the requested data."); 32010403Sstephan.diestelhorst@arm.com 32110403Sstephan.diestelhorst@arm.com totSnoops 32210403Sstephan.diestelhorst@arm.com .name(name() + ".tot_snoops") 32310403Sstephan.diestelhorst@arm.com .desc("Total number of snoops made to the snoop filter."); 32410403Sstephan.diestelhorst@arm.com 32510403Sstephan.diestelhorst@arm.com hitSingleSnoops 32610403Sstephan.diestelhorst@arm.com .name(name() + ".hit_single_snoops") 32710403Sstephan.diestelhorst@arm.com .desc("Number of snoops hitting in the snoop filter with a single "\ 32810403Sstephan.diestelhorst@arm.com "holder of the requested data."); 32910403Sstephan.diestelhorst@arm.com 33010403Sstephan.diestelhorst@arm.com hitMultiSnoops 33110403Sstephan.diestelhorst@arm.com .name(name() + ".hit_multi_snoops") 33210403Sstephan.diestelhorst@arm.com .desc("Number of snoops hitting in the snoop filter with multiple "\ 33310403Sstephan.diestelhorst@arm.com "(>1) holders of the requested data."); 33410403Sstephan.diestelhorst@arm.com} 33510403Sstephan.diestelhorst@arm.com 33610399Sstephan.diestelhorst@arm.comSnoopFilter * 33710399Sstephan.diestelhorst@arm.comSnoopFilterParams::create() 33810399Sstephan.diestelhorst@arm.com{ 33910399Sstephan.diestelhorst@arm.com return new SnoopFilter(this); 34010399Sstephan.diestelhorst@arm.com} 341