110399Sstephan.diestelhorst@arm.com/* 214005Stiago.muck@arm.com * Copyright (c) 2013-2016,2019 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 * 3711135Sandreas.hansson@arm.com * Authors: Stephan Diestelhorst 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#ifndef __MEM_SNOOP_FILTER_HH__ 4610399Sstephan.diestelhorst@arm.com#define __MEM_SNOOP_FILTER_HH__ 4710399Sstephan.diestelhorst@arm.com 4814005Stiago.muck@arm.com#include <bitset> 4911168Sandreas.hansson@arm.com#include <unordered_map> 5010399Sstephan.diestelhorst@arm.com#include <utility> 5110399Sstephan.diestelhorst@arm.com 5210399Sstephan.diestelhorst@arm.com#include "mem/packet.hh" 5310399Sstephan.diestelhorst@arm.com#include "mem/port.hh" 5410888Sandreas.hansson@arm.com#include "mem/qport.hh" 5510399Sstephan.diestelhorst@arm.com#include "params/SnoopFilter.hh" 5610399Sstephan.diestelhorst@arm.com#include "sim/sim_object.hh" 5710399Sstephan.diestelhorst@arm.com#include "sim/system.hh" 5810399Sstephan.diestelhorst@arm.com 5910399Sstephan.diestelhorst@arm.com/** 6010399Sstephan.diestelhorst@arm.com * This snoop filter keeps track of which connected port has a 6110399Sstephan.diestelhorst@arm.com * particular line of data. It can be queried (through lookup*) on 6210399Sstephan.diestelhorst@arm.com * memory requests from above (reads / writes / ...); and also from 6310399Sstephan.diestelhorst@arm.com * below (snoops). The snoop filter precisely knows about the location 6410399Sstephan.diestelhorst@arm.com * of lines "above" it through a map from cache line address to 6510399Sstephan.diestelhorst@arm.com * sharers/ports. The snoop filter ties into the flows of requests 6610399Sstephan.diestelhorst@arm.com * (when they succeed at the lower interface), regular responses from 6710399Sstephan.diestelhorst@arm.com * below and also responses from sideway's caches (in update*). This 6810399Sstephan.diestelhorst@arm.com * allows the snoop filter to model cache-line residency by snooping 6910399Sstephan.diestelhorst@arm.com * the messages. 7010399Sstephan.diestelhorst@arm.com * 7110399Sstephan.diestelhorst@arm.com * The tracking happens in two fields to be able to distinguish 7210399Sstephan.diestelhorst@arm.com * between in-flight requests (in requested) and already pulled in 7310399Sstephan.diestelhorst@arm.com * lines (in holder). This distinction is used for producing tighter 7410399Sstephan.diestelhorst@arm.com * assertions and tracking request completion. For safety, (requested 7510399Sstephan.diestelhorst@arm.com * | holder) should be notified and the requesting MSHRs will take 7610399Sstephan.diestelhorst@arm.com * care of ordering. 7710399Sstephan.diestelhorst@arm.com * 7810399Sstephan.diestelhorst@arm.com * Overall, some trickery is required because: 7910399Sstephan.diestelhorst@arm.com * (1) snoops are not followed by an ACK, but only evoke a response if 8010399Sstephan.diestelhorst@arm.com * they need to (hit dirty) 8110399Sstephan.diestelhorst@arm.com * (2) side-channel information is funnelled through direct modifications of 8210399Sstephan.diestelhorst@arm.com * pkt, instead of proper messages through the bus 8310399Sstephan.diestelhorst@arm.com * (3) there are no clean evict messages telling the snoop filter that a local, 8410399Sstephan.diestelhorst@arm.com * upper cache dropped a line, making the snoop filter pessimistic for now 8510399Sstephan.diestelhorst@arm.com * (4) ordering: there is no single point of order in the system. Instead, 8610399Sstephan.diestelhorst@arm.com * requesting MSHRs track order between local requests and remote snoops 8710399Sstephan.diestelhorst@arm.com */ 8810399Sstephan.diestelhorst@arm.comclass SnoopFilter : public SimObject { 8910399Sstephan.diestelhorst@arm.com public: 9014005Stiago.muck@arm.com 9114005Stiago.muck@arm.com // Change for systems with more than 256 ports tracked by this object 9214005Stiago.muck@arm.com static const int SNOOP_MASK_SIZE = 256; 9314005Stiago.muck@arm.com 9410888Sandreas.hansson@arm.com typedef std::vector<QueuedSlavePort*> SnoopList; 9510399Sstephan.diestelhorst@arm.com 9611131Sandreas.hansson@arm.com SnoopFilter (const SnoopFilterParams *p) : 9714122Sodanrc@yahoo.com.br SimObject(p), reqLookupResult(cachedLocations.end()), 9811132Sali.jafri@arm.com linesize(p->system->cacheLineSize()), lookupLatency(p->lookup_latency), 9911132Sali.jafri@arm.com maxEntryCount(p->max_capacity / p->system->cacheLineSize()) 10010399Sstephan.diestelhorst@arm.com { 10110399Sstephan.diestelhorst@arm.com } 10210399Sstephan.diestelhorst@arm.com 10310399Sstephan.diestelhorst@arm.com /** 10411135Sandreas.hansson@arm.com * Init a new snoop filter and tell it about all the slave ports 10511135Sandreas.hansson@arm.com * of the enclosing bus. 10610399Sstephan.diestelhorst@arm.com * 10711133Sandreas.hansson@arm.com * @param slave_ports Slave ports that the bus is attached to. 10810399Sstephan.diestelhorst@arm.com */ 10911133Sandreas.hansson@arm.com void setSlavePorts(const SnoopList& slave_ports) { 11011133Sandreas.hansson@arm.com localSlavePortIds.resize(slave_ports.size(), InvalidPortID); 11111133Sandreas.hansson@arm.com 11211133Sandreas.hansson@arm.com PortID id = 0; 11311133Sandreas.hansson@arm.com for (const auto& p : slave_ports) { 11411133Sandreas.hansson@arm.com // no need to track this port if it is not snooping 11511133Sandreas.hansson@arm.com if (p->isSnooping()) { 11611133Sandreas.hansson@arm.com slavePorts.push_back(p); 11711133Sandreas.hansson@arm.com localSlavePortIds[p->getId()] = id++; 11811133Sandreas.hansson@arm.com } 11911133Sandreas.hansson@arm.com } 12011133Sandreas.hansson@arm.com 12111133Sandreas.hansson@arm.com // make sure we can deal with this many ports 12214005Stiago.muck@arm.com fatal_if(id > SNOOP_MASK_SIZE, 12311133Sandreas.hansson@arm.com "Snoop filter only supports %d snooping ports, got %d\n", 12414005Stiago.muck@arm.com SNOOP_MASK_SIZE, id); 12510399Sstephan.diestelhorst@arm.com } 12610399Sstephan.diestelhorst@arm.com 12710399Sstephan.diestelhorst@arm.com /** 12811131Sandreas.hansson@arm.com * Lookup a request (from a slave port) in the snoop filter and 12911131Sandreas.hansson@arm.com * return a list of other slave ports that need forwarding of the 13011131Sandreas.hansson@arm.com * resulting snoops. Additionally, update the tracking structures 13111131Sandreas.hansson@arm.com * with new request information. Note that the caller must also 13211131Sandreas.hansson@arm.com * call finishRequest once it is known if the request needs to 13311131Sandreas.hansson@arm.com * retry or not. 13410399Sstephan.diestelhorst@arm.com * 13511135Sandreas.hansson@arm.com * @param cpkt Pointer to the request packet. Not changed. 13610399Sstephan.diestelhorst@arm.com * @param slave_port Slave port where the request came from. 13710399Sstephan.diestelhorst@arm.com * @return Pair of a vector of snoop target ports and lookup latency. 13810399Sstephan.diestelhorst@arm.com */ 13910399Sstephan.diestelhorst@arm.com std::pair<SnoopList, Cycles> lookupRequest(const Packet* cpkt, 14010399Sstephan.diestelhorst@arm.com const SlavePort& slave_port); 14110399Sstephan.diestelhorst@arm.com 14210399Sstephan.diestelhorst@arm.com /** 14311131Sandreas.hansson@arm.com * For an un-successful request, revert the change to the snoop 14411131Sandreas.hansson@arm.com * filter. Also take care of erasing any null entries. This method 14511131Sandreas.hansson@arm.com * relies on the result from lookupRequest being stored in 14611131Sandreas.hansson@arm.com * reqLookupResult. 14710399Sstephan.diestelhorst@arm.com * 14810399Sstephan.diestelhorst@arm.com * @param will_retry This request will retry on this bus / snoop filter 14911544Snikos.nikoleris@arm.com * @param addr Packet address, merely for sanity checking 15010399Sstephan.diestelhorst@arm.com */ 15111605Snikos.nikoleris@arm.com void finishRequest(bool will_retry, Addr addr, bool is_secure); 15210399Sstephan.diestelhorst@arm.com 15310399Sstephan.diestelhorst@arm.com /** 15411135Sandreas.hansson@arm.com * Handle an incoming snoop from below (the master port). These 15511135Sandreas.hansson@arm.com * can upgrade the tracking logic and may also benefit from 15611135Sandreas.hansson@arm.com * additional steering thanks to the snoop filter. 15711135Sandreas.hansson@arm.com * 15810399Sstephan.diestelhorst@arm.com * @param cpkt Pointer to const Packet containing the snoop. 15910399Sstephan.diestelhorst@arm.com * @return Pair with a vector of SlavePorts that need snooping and a lookup 16010399Sstephan.diestelhorst@arm.com * latency. 16110399Sstephan.diestelhorst@arm.com */ 16210399Sstephan.diestelhorst@arm.com std::pair<SnoopList, Cycles> lookupSnoop(const Packet* cpkt); 16310399Sstephan.diestelhorst@arm.com 16410399Sstephan.diestelhorst@arm.com /** 16511135Sandreas.hansson@arm.com * Let the snoop filter see any snoop responses that turn into 16611135Sandreas.hansson@arm.com * request responses and indicate cache to cache transfers. These 16711135Sandreas.hansson@arm.com * will update the corresponding state in the filter. 16810399Sstephan.diestelhorst@arm.com * 16910399Sstephan.diestelhorst@arm.com * @param cpkt Pointer to const Packet holding the snoop response. 17010399Sstephan.diestelhorst@arm.com * @param rsp_port SlavePort that sends the response. 17110399Sstephan.diestelhorst@arm.com * @param req_port SlavePort that made the original request and is the 17210399Sstephan.diestelhorst@arm.com * destination of the snoop response. 17310399Sstephan.diestelhorst@arm.com */ 17410399Sstephan.diestelhorst@arm.com void updateSnoopResponse(const Packet *cpkt, const SlavePort& rsp_port, 17510399Sstephan.diestelhorst@arm.com const SlavePort& req_port); 17610399Sstephan.diestelhorst@arm.com 17710399Sstephan.diestelhorst@arm.com /** 17811135Sandreas.hansson@arm.com * Pass snoop responses that travel downward through the snoop 17911135Sandreas.hansson@arm.com * filter and let them update the snoop filter state. No 18011135Sandreas.hansson@arm.com * additional routing happens. 18110399Sstephan.diestelhorst@arm.com * 18210399Sstephan.diestelhorst@arm.com * @param cpkt Pointer to const Packet holding the snoop response. 18310399Sstephan.diestelhorst@arm.com * @param rsp_port SlavePort that sends the response. 18411135Sandreas.hansson@arm.com * @param req_port MasterPort through which the response is forwarded. 18510399Sstephan.diestelhorst@arm.com */ 18610399Sstephan.diestelhorst@arm.com void updateSnoopForward(const Packet *cpkt, const SlavePort& rsp_port, 18710399Sstephan.diestelhorst@arm.com const MasterPort& req_port); 18810399Sstephan.diestelhorst@arm.com 18910399Sstephan.diestelhorst@arm.com /** 19011135Sandreas.hansson@arm.com * Update the snoop filter with a response from below (outer / 19111135Sandreas.hansson@arm.com * other cache, or memory) and update the tracking information in 19211135Sandreas.hansson@arm.com * the snoop filter. 19310399Sstephan.diestelhorst@arm.com * 19410399Sstephan.diestelhorst@arm.com * @param cpkt Pointer to const Packet holding the snoop response. 19511135Sandreas.hansson@arm.com * @param slave_port SlavePort that made the original request and 19611135Sandreas.hansson@arm.com * is the target of this response. 19710399Sstephan.diestelhorst@arm.com */ 19810399Sstephan.diestelhorst@arm.com void updateResponse(const Packet *cpkt, const SlavePort& slave_port); 19910399Sstephan.diestelhorst@arm.com 20011135Sandreas.hansson@arm.com virtual void regStats(); 20111135Sandreas.hansson@arm.com 20211135Sandreas.hansson@arm.com protected: 20311135Sandreas.hansson@arm.com 20410399Sstephan.diestelhorst@arm.com /** 20511135Sandreas.hansson@arm.com * The underlying type for the bitmask we use for tracking. This 20614005Stiago.muck@arm.com * limits the number of snooping ports supported per crossbar. 20711135Sandreas.hansson@arm.com */ 20814005Stiago.muck@arm.com typedef std::bitset<SNOOP_MASK_SIZE> SnoopMask; 20911135Sandreas.hansson@arm.com 21011135Sandreas.hansson@arm.com /** 21111135Sandreas.hansson@arm.com * Per cache line item tracking a bitmask of SlavePorts who have an 21211135Sandreas.hansson@arm.com * outstanding request to this line (requested) or already share a 21311135Sandreas.hansson@arm.com * cache line with this address (holder). 21411135Sandreas.hansson@arm.com */ 21511135Sandreas.hansson@arm.com struct SnoopItem { 21611135Sandreas.hansson@arm.com SnoopMask requested; 21711135Sandreas.hansson@arm.com SnoopMask holder; 21811135Sandreas.hansson@arm.com }; 21911135Sandreas.hansson@arm.com /** 22011135Sandreas.hansson@arm.com * HashMap of SnoopItems indexed by line address 22111135Sandreas.hansson@arm.com */ 22211168Sandreas.hansson@arm.com typedef std::unordered_map<Addr, SnoopItem> SnoopFilterCache; 22311135Sandreas.hansson@arm.com 22411135Sandreas.hansson@arm.com /** 22511135Sandreas.hansson@arm.com * Simple factory methods for standard return values. 22610399Sstephan.diestelhorst@arm.com */ 22710399Sstephan.diestelhorst@arm.com std::pair<SnoopList, Cycles> snoopAll(Cycles latency) const 22810399Sstephan.diestelhorst@arm.com { 22910399Sstephan.diestelhorst@arm.com return std::make_pair(slavePorts, latency); 23010399Sstephan.diestelhorst@arm.com } 23110399Sstephan.diestelhorst@arm.com std::pair<SnoopList, Cycles> snoopSelected(const SnoopList& slave_ports, 23210399Sstephan.diestelhorst@arm.com Cycles latency) const 23310399Sstephan.diestelhorst@arm.com { 23410399Sstephan.diestelhorst@arm.com return std::make_pair(slave_ports, latency); 23510399Sstephan.diestelhorst@arm.com } 23610399Sstephan.diestelhorst@arm.com std::pair<SnoopList, Cycles> snoopDown(Cycles latency) const 23710399Sstephan.diestelhorst@arm.com { 23810399Sstephan.diestelhorst@arm.com SnoopList empty; 23910399Sstephan.diestelhorst@arm.com return std::make_pair(empty , latency); 24010399Sstephan.diestelhorst@arm.com } 24110399Sstephan.diestelhorst@arm.com 24211129Sali.jafri@arm.com /** 24310399Sstephan.diestelhorst@arm.com * Convert a single port to a corresponding, one-hot bitmask 24410399Sstephan.diestelhorst@arm.com * @param port SlavePort that should be converted. 24510399Sstephan.diestelhorst@arm.com * @return One-hot bitmask corresponding to the port. 24610399Sstephan.diestelhorst@arm.com */ 24710399Sstephan.diestelhorst@arm.com SnoopMask portToMask(const SlavePort& port) const; 24810399Sstephan.diestelhorst@arm.com /** 24910399Sstephan.diestelhorst@arm.com * Converts a bitmask of ports into the corresponing list of ports 25010399Sstephan.diestelhorst@arm.com * @param ports SnoopMask of the requested ports 25110399Sstephan.diestelhorst@arm.com * @return SnoopList containing all the requested SlavePorts 25210399Sstephan.diestelhorst@arm.com */ 25310399Sstephan.diestelhorst@arm.com SnoopList maskToPortList(SnoopMask ports) const; 25410399Sstephan.diestelhorst@arm.com 25510399Sstephan.diestelhorst@arm.com private: 25611129Sali.jafri@arm.com 25711129Sali.jafri@arm.com /** 25811129Sali.jafri@arm.com * Removes snoop filter items which have no requesters and no holders. 25911129Sali.jafri@arm.com */ 26011129Sali.jafri@arm.com void eraseIfNullEntry(SnoopFilterCache::iterator& sf_it); 26111135Sandreas.hansson@arm.com 26210399Sstephan.diestelhorst@arm.com /** Simple hash set of cached addresses. */ 26311129Sali.jafri@arm.com SnoopFilterCache cachedLocations; 26414122Sodanrc@yahoo.com.br 26511129Sali.jafri@arm.com /** 26614122Sodanrc@yahoo.com.br * A request lookup must be followed by a call to finishRequest to inform 26714122Sodanrc@yahoo.com.br * the operation's success. If a retry is needed, however, all changes 26814122Sodanrc@yahoo.com.br * made to the snoop filter while performing the lookup must be undone. 26914122Sodanrc@yahoo.com.br * This structure keeps track of the state previous to such changes. 27011131Sandreas.hansson@arm.com */ 27114122Sodanrc@yahoo.com.br struct ReqLookupResult { 27214122Sodanrc@yahoo.com.br /** Iterator used to store the result from lookupRequest. */ 27314122Sodanrc@yahoo.com.br SnoopFilterCache::iterator it; 27414122Sodanrc@yahoo.com.br 27514122Sodanrc@yahoo.com.br /** 27614122Sodanrc@yahoo.com.br * Variable to temporarily store value of snoopfilter entry 27714122Sodanrc@yahoo.com.br * in case finishRequest needs to undo changes made in lookupRequest 27814122Sodanrc@yahoo.com.br * (because of crossbar retry) 27914122Sodanrc@yahoo.com.br */ 28014122Sodanrc@yahoo.com.br SnoopItem retryItem; 28114122Sodanrc@yahoo.com.br 28214122Sodanrc@yahoo.com.br /** 28314122Sodanrc@yahoo.com.br * The constructor must be informed of the internal cache's end 28414122Sodanrc@yahoo.com.br * iterator, so do not allow the compiler to implictly define it. 28514122Sodanrc@yahoo.com.br * 28614122Sodanrc@yahoo.com.br * @param end_it Iterator to the end of the internal cache. 28714122Sodanrc@yahoo.com.br */ 28814122Sodanrc@yahoo.com.br ReqLookupResult(SnoopFilterCache::iterator end_it) 28914122Sodanrc@yahoo.com.br : it(end_it), retryItem{0, 0} 29014122Sodanrc@yahoo.com.br { 29114122Sodanrc@yahoo.com.br } 29214122Sodanrc@yahoo.com.br ReqLookupResult() = delete; 29314122Sodanrc@yahoo.com.br } reqLookupResult; 29414122Sodanrc@yahoo.com.br 29511133Sandreas.hansson@arm.com /** List of all attached snooping slave ports. */ 29610399Sstephan.diestelhorst@arm.com SnoopList slavePorts; 29711133Sandreas.hansson@arm.com /** Track the mapping from port ids to the local mask ids. */ 29811133Sandreas.hansson@arm.com std::vector<PortID> localSlavePortIds; 29910399Sstephan.diestelhorst@arm.com /** Cache line size. */ 30010399Sstephan.diestelhorst@arm.com const unsigned linesize; 30110399Sstephan.diestelhorst@arm.com /** Latency for doing a lookup in the filter */ 30210399Sstephan.diestelhorst@arm.com const Cycles lookupLatency; 30311132Sali.jafri@arm.com /** Max capacity in terms of cache blocks tracked, for sanity checking */ 30411132Sali.jafri@arm.com const unsigned maxEntryCount; 30510403Sstephan.diestelhorst@arm.com 30611605Snikos.nikoleris@arm.com /** 30711605Snikos.nikoleris@arm.com * Use the lower bits of the address to keep track of the line status 30811605Snikos.nikoleris@arm.com */ 30911605Snikos.nikoleris@arm.com enum LineStatus { 31011605Snikos.nikoleris@arm.com /** block holds data from the secure memory space */ 31111605Snikos.nikoleris@arm.com LineSecure = 0x01, 31211605Snikos.nikoleris@arm.com }; 31311605Snikos.nikoleris@arm.com 31410403Sstephan.diestelhorst@arm.com /** Statistics */ 31510403Sstephan.diestelhorst@arm.com Stats::Scalar totRequests; 31610403Sstephan.diestelhorst@arm.com Stats::Scalar hitSingleRequests; 31710403Sstephan.diestelhorst@arm.com Stats::Scalar hitMultiRequests; 31810403Sstephan.diestelhorst@arm.com 31910403Sstephan.diestelhorst@arm.com Stats::Scalar totSnoops; 32010403Sstephan.diestelhorst@arm.com Stats::Scalar hitSingleSnoops; 32110403Sstephan.diestelhorst@arm.com Stats::Scalar hitMultiSnoops; 32210399Sstephan.diestelhorst@arm.com}; 32310399Sstephan.diestelhorst@arm.com 32410399Sstephan.diestelhorst@arm.cominline SnoopFilter::SnoopMask 32510399Sstephan.diestelhorst@arm.comSnoopFilter::portToMask(const SlavePort& port) const 32610399Sstephan.diestelhorst@arm.com{ 32711133Sandreas.hansson@arm.com assert(port.getId() != InvalidPortID); 32811133Sandreas.hansson@arm.com // if this is not a snooping port, return a zero mask 32911133Sandreas.hansson@arm.com return !port.isSnooping() ? 0 : 33011133Sandreas.hansson@arm.com ((SnoopMask)1) << localSlavePortIds[port.getId()]; 33110399Sstephan.diestelhorst@arm.com} 33210399Sstephan.diestelhorst@arm.com 33310399Sstephan.diestelhorst@arm.cominline SnoopFilter::SnoopList 33410399Sstephan.diestelhorst@arm.comSnoopFilter::maskToPortList(SnoopMask port_mask) const 33510399Sstephan.diestelhorst@arm.com{ 33610399Sstephan.diestelhorst@arm.com SnoopList res; 33711133Sandreas.hansson@arm.com for (const auto& p : slavePorts) 33814005Stiago.muck@arm.com if ((port_mask & portToMask(*p)).any()) 33911133Sandreas.hansson@arm.com res.push_back(p); 34010399Sstephan.diestelhorst@arm.com return res; 34110399Sstephan.diestelhorst@arm.com} 34211135Sandreas.hansson@arm.com 34310399Sstephan.diestelhorst@arm.com#endif // __MEM_SNOOP_FILTER_HH__ 344