coherent_xbar.hh revision 12351:17eaa27bef22
113531Sjairo.balart@metempsy.com/*
214167Sgiacomo.travaglini@arm.com * Copyright (c) 2011-2015, 2017 ARM Limited
314167Sgiacomo.travaglini@arm.com * All rights reserved
414167Sgiacomo.travaglini@arm.com *
514167Sgiacomo.travaglini@arm.com * The license below extends only to copyright in the software and shall
614167Sgiacomo.travaglini@arm.com * not be construed as granting a license to any other intellectual
714167Sgiacomo.travaglini@arm.com * property including but not limited to intellectual property relating
814167Sgiacomo.travaglini@arm.com * to a hardware implementation of the functionality of the software
914167Sgiacomo.travaglini@arm.com * licensed hereunder.  You may use the software subject to the license
1014167Sgiacomo.travaglini@arm.com * terms below provided that you ensure that this notice is replicated
1114167Sgiacomo.travaglini@arm.com * unmodified and in its entirety in all distributions of the software,
1214167Sgiacomo.travaglini@arm.com * modified or unmodified, in source code or in binary form.
1314167Sgiacomo.travaglini@arm.com *
1413531Sjairo.balart@metempsy.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
1513531Sjairo.balart@metempsy.com * All rights reserved.
1613531Sjairo.balart@metempsy.com *
1713531Sjairo.balart@metempsy.com * Redistribution and use in source and binary forms, with or without
1813531Sjairo.balart@metempsy.com * modification, are permitted provided that the following conditions are
1913531Sjairo.balart@metempsy.com * met: redistributions of source code must retain the above copyright
2013531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer;
2113531Sjairo.balart@metempsy.com * redistributions in binary form must reproduce the above copyright
2213531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer in the
2313531Sjairo.balart@metempsy.com * documentation and/or other materials provided with the distribution;
2413531Sjairo.balart@metempsy.com * neither the name of the copyright holders nor the names of its
2513531Sjairo.balart@metempsy.com * contributors may be used to endorse or promote products derived from
2613531Sjairo.balart@metempsy.com * this software without specific prior written permission.
2713531Sjairo.balart@metempsy.com *
2813531Sjairo.balart@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2913531Sjairo.balart@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3013531Sjairo.balart@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3113531Sjairo.balart@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3213531Sjairo.balart@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3313531Sjairo.balart@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3413531Sjairo.balart@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3513531Sjairo.balart@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3613531Sjairo.balart@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3713531Sjairo.balart@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3813531Sjairo.balart@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3913531Sjairo.balart@metempsy.com *
4013531Sjairo.balart@metempsy.com * Authors: Ron Dreslinski
4113531Sjairo.balart@metempsy.com *          Ali Saidi
4213531Sjairo.balart@metempsy.com *          Andreas Hansson
4313531Sjairo.balart@metempsy.com *          William Wang
4413531Sjairo.balart@metempsy.com */
4513531Sjairo.balart@metempsy.com
4613531Sjairo.balart@metempsy.com/**
4713531Sjairo.balart@metempsy.com * @file
4813531Sjairo.balart@metempsy.com * Declaration of a coherent crossbar.
4913531Sjairo.balart@metempsy.com */
5013531Sjairo.balart@metempsy.com
5113531Sjairo.balart@metempsy.com#ifndef __MEM_COHERENT_XBAR_HH__
5213531Sjairo.balart@metempsy.com#define __MEM_COHERENT_XBAR_HH__
5313531Sjairo.balart@metempsy.com
5413531Sjairo.balart@metempsy.com#include <unordered_map>
5513531Sjairo.balart@metempsy.com#include <unordered_set>
5613531Sjairo.balart@metempsy.com
5713531Sjairo.balart@metempsy.com#include "mem/snoop_filter.hh"
5813531Sjairo.balart@metempsy.com#include "mem/xbar.hh"
5913531Sjairo.balart@metempsy.com#include "params/CoherentXBar.hh"
6013531Sjairo.balart@metempsy.com
6113531Sjairo.balart@metempsy.com/**
6213531Sjairo.balart@metempsy.com * A coherent crossbar connects a number of (potentially) snooping
6313531Sjairo.balart@metempsy.com * masters and slaves, and routes the request and response packets
6413531Sjairo.balart@metempsy.com * based on the address, and also forwards all requests to the
6513531Sjairo.balart@metempsy.com * snoopers and deals with the snoop responses.
6613531Sjairo.balart@metempsy.com *
6713531Sjairo.balart@metempsy.com * The coherent crossbar can be used as a template for modelling QPI,
6813531Sjairo.balart@metempsy.com * HyperTransport, ACE and coherent OCP buses, and is typically used
6913531Sjairo.balart@metempsy.com * for the L1-to-L2 buses and as the main system interconnect.  @sa
7013531Sjairo.balart@metempsy.com * \ref gem5MemorySystem "gem5 Memory System"
7113531Sjairo.balart@metempsy.com */
7213531Sjairo.balart@metempsy.comclass CoherentXBar : public BaseXBar
7313531Sjairo.balart@metempsy.com{
7413531Sjairo.balart@metempsy.com
7513531Sjairo.balart@metempsy.com  protected:
7613531Sjairo.balart@metempsy.com
7713531Sjairo.balart@metempsy.com    /**
7813531Sjairo.balart@metempsy.com     * Declare the layers of this crossbar, one vector for requests,
7913531Sjairo.balart@metempsy.com     * one for responses, and one for snoop responses
8013531Sjairo.balart@metempsy.com     */
8113531Sjairo.balart@metempsy.com    std::vector<ReqLayer*> reqLayers;
8213531Sjairo.balart@metempsy.com    std::vector<RespLayer*> respLayers;
8313531Sjairo.balart@metempsy.com    std::vector<SnoopRespLayer*> snoopLayers;
8413531Sjairo.balart@metempsy.com
8513531Sjairo.balart@metempsy.com    /**
8613531Sjairo.balart@metempsy.com     * Declaration of the coherent crossbar slave port type, one will
8713531Sjairo.balart@metempsy.com     * be instantiated for each of the master ports connecting to the
8813531Sjairo.balart@metempsy.com     * crossbar.
8913531Sjairo.balart@metempsy.com     */
9013531Sjairo.balart@metempsy.com    class CoherentXBarSlavePort : public QueuedSlavePort
9113531Sjairo.balart@metempsy.com    {
9213531Sjairo.balart@metempsy.com
9313531Sjairo.balart@metempsy.com      private:
9413531Sjairo.balart@metempsy.com
9513531Sjairo.balart@metempsy.com        /** A reference to the crossbar to which this port belongs. */
9613531Sjairo.balart@metempsy.com        CoherentXBar &xbar;
9713531Sjairo.balart@metempsy.com
9813531Sjairo.balart@metempsy.com        /** A normal packet queue used to store responses. */
9913531Sjairo.balart@metempsy.com        RespPacketQueue queue;
10013531Sjairo.balart@metempsy.com
10113531Sjairo.balart@metempsy.com      public:
10213531Sjairo.balart@metempsy.com
10313531Sjairo.balart@metempsy.com        CoherentXBarSlavePort(const std::string &_name,
10413531Sjairo.balart@metempsy.com                             CoherentXBar &_xbar, PortID _id)
10513531Sjairo.balart@metempsy.com            : QueuedSlavePort(_name, &_xbar, queue, _id), xbar(_xbar),
10613531Sjairo.balart@metempsy.com              queue(_xbar, *this)
10713531Sjairo.balart@metempsy.com        { }
10813531Sjairo.balart@metempsy.com
10913531Sjairo.balart@metempsy.com      protected:
11013531Sjairo.balart@metempsy.com
11113531Sjairo.balart@metempsy.com        /**
11213531Sjairo.balart@metempsy.com         * When receiving a timing request, pass it to the crossbar.
11313531Sjairo.balart@metempsy.com         */
11413531Sjairo.balart@metempsy.com        virtual bool recvTimingReq(PacketPtr pkt)
11513531Sjairo.balart@metempsy.com        { return xbar.recvTimingReq(pkt, id); }
11613531Sjairo.balart@metempsy.com
11713531Sjairo.balart@metempsy.com        /**
11813531Sjairo.balart@metempsy.com         * When receiving a timing snoop response, pass it to the crossbar.
11913531Sjairo.balart@metempsy.com         */
12013531Sjairo.balart@metempsy.com        virtual bool recvTimingSnoopResp(PacketPtr pkt)
12113756Sjairo.balart@metempsy.com        { return xbar.recvTimingSnoopResp(pkt, id); }
12213756Sjairo.balart@metempsy.com
12313756Sjairo.balart@metempsy.com        /**
12413756Sjairo.balart@metempsy.com         * When receiving an atomic request, pass it to the crossbar.
12513756Sjairo.balart@metempsy.com         */
12613756Sjairo.balart@metempsy.com        virtual Tick recvAtomic(PacketPtr pkt)
12713756Sjairo.balart@metempsy.com        { return xbar.recvAtomic(pkt, id); }
12813531Sjairo.balart@metempsy.com
12913531Sjairo.balart@metempsy.com        /**
13013756Sjairo.balart@metempsy.com         * When receiving a functional request, pass it to the crossbar.
13113756Sjairo.balart@metempsy.com         */
13213531Sjairo.balart@metempsy.com        virtual void recvFunctional(PacketPtr pkt)
13313756Sjairo.balart@metempsy.com        { xbar.recvFunctional(pkt, id); }
13413756Sjairo.balart@metempsy.com
13513756Sjairo.balart@metempsy.com        /**
13613531Sjairo.balart@metempsy.com         * Return the union of all adress ranges seen by this crossbar.
13713531Sjairo.balart@metempsy.com         */
13813531Sjairo.balart@metempsy.com        virtual AddrRangeList getAddrRanges() const
13913531Sjairo.balart@metempsy.com        { return xbar.getAddrRanges(); }
14013531Sjairo.balart@metempsy.com
14113531Sjairo.balart@metempsy.com    };
14213531Sjairo.balart@metempsy.com
14313531Sjairo.balart@metempsy.com    /**
14413531Sjairo.balart@metempsy.com     * Declaration of the coherent crossbar master port type, one will be
14513531Sjairo.balart@metempsy.com     * instantiated for each of the slave interfaces connecting to the
14613531Sjairo.balart@metempsy.com     * crossbar.
14713531Sjairo.balart@metempsy.com     */
14813531Sjairo.balart@metempsy.com    class CoherentXBarMasterPort : public MasterPort
14913531Sjairo.balart@metempsy.com    {
15013531Sjairo.balart@metempsy.com      private:
15113531Sjairo.balart@metempsy.com        /** A reference to the crossbar to which this port belongs. */
15214167Sgiacomo.travaglini@arm.com        CoherentXBar &xbar;
15314167Sgiacomo.travaglini@arm.com
15414167Sgiacomo.travaglini@arm.com      public:
15514167Sgiacomo.travaglini@arm.com
15614167Sgiacomo.travaglini@arm.com        CoherentXBarMasterPort(const std::string &_name,
15714167Sgiacomo.travaglini@arm.com                              CoherentXBar &_xbar, PortID _id)
15813531Sjairo.balart@metempsy.com            : MasterPort(_name, &_xbar, _id), xbar(_xbar)
15913531Sjairo.balart@metempsy.com        { }
16013531Sjairo.balart@metempsy.com
16113927Sgiacomo.travaglini@arm.com      protected:
16213531Sjairo.balart@metempsy.com
16313756Sjairo.balart@metempsy.com        /**
16413531Sjairo.balart@metempsy.com         * Determine if this port should be considered a snooper. For
16513756Sjairo.balart@metempsy.com         * a coherent crossbar master port this is always true.
16613756Sjairo.balart@metempsy.com         *
16713756Sjairo.balart@metempsy.com         * @return a boolean that is true if this port is snooping
16813756Sjairo.balart@metempsy.com         */
16913531Sjairo.balart@metempsy.com        virtual bool isSnooping() const
17013756Sjairo.balart@metempsy.com        { return true; }
17113756Sjairo.balart@metempsy.com
17213531Sjairo.balart@metempsy.com        /**
17313531Sjairo.balart@metempsy.com         * When receiving a timing response, pass it to the crossbar.
17413531Sjairo.balart@metempsy.com         */
17513531Sjairo.balart@metempsy.com        virtual bool recvTimingResp(PacketPtr pkt)
17613531Sjairo.balart@metempsy.com        { return xbar.recvTimingResp(pkt, id); }
17713531Sjairo.balart@metempsy.com
17813531Sjairo.balart@metempsy.com        /**
17913531Sjairo.balart@metempsy.com         * When receiving a timing snoop request, pass it to the crossbar.
18013531Sjairo.balart@metempsy.com         */
18113531Sjairo.balart@metempsy.com        virtual void recvTimingSnoopReq(PacketPtr pkt)
18213531Sjairo.balart@metempsy.com        { return xbar.recvTimingSnoopReq(pkt, id); }
18313531Sjairo.balart@metempsy.com
18413531Sjairo.balart@metempsy.com        /**
18513531Sjairo.balart@metempsy.com         * When receiving an atomic snoop request, pass it to the crossbar.
18613531Sjairo.balart@metempsy.com         */
18713531Sjairo.balart@metempsy.com        virtual Tick recvAtomicSnoop(PacketPtr pkt)
18813531Sjairo.balart@metempsy.com        { return xbar.recvAtomicSnoop(pkt, id); }
18913531Sjairo.balart@metempsy.com
19013531Sjairo.balart@metempsy.com        /**
19113531Sjairo.balart@metempsy.com         * When receiving a functional snoop request, pass it to the crossbar.
19213531Sjairo.balart@metempsy.com         */
19313531Sjairo.balart@metempsy.com        virtual void recvFunctionalSnoop(PacketPtr pkt)
19413531Sjairo.balart@metempsy.com        { xbar.recvFunctionalSnoop(pkt, id); }
19513531Sjairo.balart@metempsy.com
19613531Sjairo.balart@metempsy.com        /** When reciving a range change from the peer port (at id),
19713531Sjairo.balart@metempsy.com            pass it to the crossbar. */
19813531Sjairo.balart@metempsy.com        virtual void recvRangeChange()
19913531Sjairo.balart@metempsy.com        { xbar.recvRangeChange(id); }
20013531Sjairo.balart@metempsy.com
20113531Sjairo.balart@metempsy.com        /** When reciving a retry from the peer port (at id),
20213531Sjairo.balart@metempsy.com            pass it to the crossbar. */
20313531Sjairo.balart@metempsy.com        virtual void recvReqRetry()
20413756Sjairo.balart@metempsy.com        { xbar.recvReqRetry(id); }
20513531Sjairo.balart@metempsy.com
20613813Sgiacomo.travaglini@arm.com    };
20713531Sjairo.balart@metempsy.com
20813531Sjairo.balart@metempsy.com    /**
20913531Sjairo.balart@metempsy.com     * Internal class to bridge between an incoming snoop response
21013531Sjairo.balart@metempsy.com     * from a slave port and forwarding it through an outgoing slave
21113531Sjairo.balart@metempsy.com     * port. It is effectively a dangling master port.
21213531Sjairo.balart@metempsy.com     */
21313531Sjairo.balart@metempsy.com    class SnoopRespPort : public MasterPort
21413531Sjairo.balart@metempsy.com    {
21513813Sgiacomo.travaglini@arm.com
21613531Sjairo.balart@metempsy.com      private:
21713531Sjairo.balart@metempsy.com
21813531Sjairo.balart@metempsy.com        /** The port which we mirror internally. */
21913531Sjairo.balart@metempsy.com        QueuedSlavePort& slavePort;
22013756Sjairo.balart@metempsy.com
22113756Sjairo.balart@metempsy.com      public:
22213756Sjairo.balart@metempsy.com
22313756Sjairo.balart@metempsy.com        /**
22413756Sjairo.balart@metempsy.com         * Create a snoop response port that mirrors a given slave port.
22513531Sjairo.balart@metempsy.com         */
22613756Sjairo.balart@metempsy.com        SnoopRespPort(QueuedSlavePort& slave_port, CoherentXBar& _xbar) :
22713756Sjairo.balart@metempsy.com            MasterPort(slave_port.name() + ".snoopRespPort", &_xbar),
22813756Sjairo.balart@metempsy.com            slavePort(slave_port) { }
22913756Sjairo.balart@metempsy.com
23013756Sjairo.balart@metempsy.com        /**
23113756Sjairo.balart@metempsy.com         * Override the sending of retries and pass them on through
23213756Sjairo.balart@metempsy.com         * the mirrored slave port.
23313756Sjairo.balart@metempsy.com         */
23413756Sjairo.balart@metempsy.com        void sendRetryResp() {
23513756Sjairo.balart@metempsy.com            // forward it as a snoop response retry
23613756Sjairo.balart@metempsy.com            slavePort.sendRetrySnoopResp();
23713531Sjairo.balart@metempsy.com        }
23813531Sjairo.balart@metempsy.com
23913531Sjairo.balart@metempsy.com        /**
240         * Provided as necessary.
241         */
242        void recvReqRetry() { panic("SnoopRespPort should never see retry\n"); }
243
244        /**
245         * Provided as necessary.
246         */
247        bool recvTimingResp(PacketPtr pkt)
248        {
249            panic("SnoopRespPort should never see timing response\n");
250            return false;
251        }
252
253    };
254
255    std::vector<SnoopRespPort*> snoopRespPorts;
256
257    std::vector<QueuedSlavePort*> snoopPorts;
258
259    /**
260     * Store the outstanding requests that we are expecting snoop
261     * responses from so we can determine which snoop responses we
262     * generated and which ones were merely forwarded.
263     */
264    std::unordered_set<RequestPtr> outstandingSnoop;
265
266    /**
267     * Store the outstanding cache maintenance that we are expecting
268     * snoop responses from so we can determine when we received all
269     * snoop responses and if any of the agents satisfied the request.
270     */
271    std::unordered_map<PacketId, PacketPtr> outstandingCMO;
272
273    /**
274     * Keep a pointer to the system to be allow to querying memory system
275     * properties.
276     */
277    System *system;
278
279    /** A snoop filter that tracks cache line residency and can restrict the
280      * broadcast needed for probes.  NULL denotes an absent filter. */
281    SnoopFilter *snoopFilter;
282
283    /** Cycles of snoop response latency.*/
284    const Cycles snoopResponseLatency;
285
286    /** Is this crossbar the point of coherency? **/
287    const bool pointOfCoherency;
288
289    /** Is this crossbar the point of unification? **/
290    const bool pointOfUnification;
291
292    /**
293     * Upstream caches need this packet until true is returned, so
294     * hold it for deletion until a subsequent call
295     */
296    std::unique_ptr<Packet> pendingDelete;
297
298    /** Function called by the port when the crossbar is recieving a Timing
299      request packet.*/
300    bool recvTimingReq(PacketPtr pkt, PortID slave_port_id);
301
302    /** Function called by the port when the crossbar is recieving a Timing
303      response packet.*/
304    bool recvTimingResp(PacketPtr pkt, PortID master_port_id);
305
306    /** Function called by the port when the crossbar is recieving a timing
307        snoop request.*/
308    void recvTimingSnoopReq(PacketPtr pkt, PortID master_port_id);
309
310    /** Function called by the port when the crossbar is recieving a timing
311        snoop response.*/
312    bool recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id);
313
314    /** Timing function called by port when it is once again able to process
315     * requests. */
316    void recvReqRetry(PortID master_port_id);
317
318    /**
319     * Forward a timing packet to our snoopers, potentially excluding
320     * one of the connected coherent masters to avoid sending a packet
321     * back to where it came from.
322     *
323     * @param pkt Packet to forward
324     * @param exclude_slave_port_id Id of slave port to exclude
325     */
326    void forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id) {
327        forwardTiming(pkt, exclude_slave_port_id, snoopPorts);
328    }
329
330    /**
331     * Forward a timing packet to a selected list of snoopers, potentially
332     * excluding one of the connected coherent masters to avoid sending a packet
333     * back to where it came from.
334     *
335     * @param pkt Packet to forward
336     * @param exclude_slave_port_id Id of slave port to exclude
337     * @param dests Vector of destination ports for the forwarded pkt
338     */
339    void forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id,
340                       const std::vector<QueuedSlavePort*>& dests);
341
342    /** Function called by the port when the crossbar is recieving a Atomic
343      transaction.*/
344    Tick recvAtomic(PacketPtr pkt, PortID slave_port_id);
345
346    /** Function called by the port when the crossbar is recieving an
347        atomic snoop transaction.*/
348    Tick recvAtomicSnoop(PacketPtr pkt, PortID master_port_id);
349
350    /**
351     * Forward an atomic packet to our snoopers, potentially excluding
352     * one of the connected coherent masters to avoid sending a packet
353     * back to where it came from.
354     *
355     * @param pkt Packet to forward
356     * @param exclude_slave_port_id Id of slave port to exclude
357     *
358     * @return a pair containing the snoop response and snoop latency
359     */
360    std::pair<MemCmd, Tick> forwardAtomic(PacketPtr pkt,
361                                          PortID exclude_slave_port_id)
362    {
363        return forwardAtomic(pkt, exclude_slave_port_id, InvalidPortID,
364                             snoopPorts);
365    }
366
367    /**
368     * Forward an atomic packet to a selected list of snoopers, potentially
369     * excluding one of the connected coherent masters to avoid sending a packet
370     * back to where it came from.
371     *
372     * @param pkt Packet to forward
373     * @param exclude_slave_port_id Id of slave port to exclude
374     * @param source_master_port_id Id of the master port for snoops from below
375     * @param dests Vector of destination ports for the forwarded pkt
376     *
377     * @return a pair containing the snoop response and snoop latency
378     */
379    std::pair<MemCmd, Tick> forwardAtomic(PacketPtr pkt,
380                                          PortID exclude_slave_port_id,
381                                          PortID source_master_port_id,
382                                          const std::vector<QueuedSlavePort*>&
383                                          dests);
384
385    /** Function called by the port when the crossbar is recieving a Functional
386        transaction.*/
387    void recvFunctional(PacketPtr pkt, PortID slave_port_id);
388
389    /** Function called by the port when the crossbar is recieving a functional
390        snoop transaction.*/
391    void recvFunctionalSnoop(PacketPtr pkt, PortID master_port_id);
392
393    /**
394     * Forward a functional packet to our snoopers, potentially
395     * excluding one of the connected coherent masters to avoid
396     * sending a packet back to where it came from.
397     *
398     * @param pkt Packet to forward
399     * @param exclude_slave_port_id Id of slave port to exclude
400     */
401    void forwardFunctional(PacketPtr pkt, PortID exclude_slave_port_id);
402
403    /**
404     * Determine if the crossbar should sink the packet, as opposed to
405     * forwarding it, or responding.
406     */
407    bool sinkPacket(const PacketPtr pkt) const;
408
409    /**
410     * Determine if the crossbar should forward the packet, as opposed to
411     * responding to it.
412     */
413    bool forwardPacket(const PacketPtr pkt);
414
415    /**
416     * Determine if the packet's destination is the memory below
417     *
418     * The memory below is the destination for a cache mainteance
419     * operation to the Point of Coherence/Unification if this is the
420     * Point of Coherence/Unification.
421     *
422     * @param pkt The processed packet
423     *
424     * @return Whether the memory below is the destination for the packet
425     */
426    bool isDestination(const PacketPtr pkt) const
427    {
428        return (pkt->req->isToPOC() && pointOfCoherency) ||
429            (pkt->req->isToPOU() && pointOfUnification);
430    }
431
432    Stats::Scalar snoops;
433    Stats::Scalar snoopTraffic;
434    Stats::Distribution snoopFanout;
435
436  public:
437
438    virtual void init();
439
440    CoherentXBar(const CoherentXBarParams *p);
441
442    virtual ~CoherentXBar();
443
444    virtual void regStats();
445};
446
447#endif //__MEM_COHERENT_XBAR_HH__
448