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