coherent_xbar.hh revision 12351
17585SAli.Saidi@arm.com/*
27585SAli.Saidi@arm.com * Copyright (c) 2011-2015, 2017 ARM Limited
37585SAli.Saidi@arm.com * All rights reserved
47585SAli.Saidi@arm.com *
57585SAli.Saidi@arm.com * The license below extends only to copyright in the software and shall
67585SAli.Saidi@arm.com * not be construed as granting a license to any other intellectual
77585SAli.Saidi@arm.com * property including but not limited to intellectual property relating
87585SAli.Saidi@arm.com * to a hardware implementation of the functionality of the software
97585SAli.Saidi@arm.com * licensed hereunder.  You may use the software subject to the license
107585SAli.Saidi@arm.com * terms below provided that you ensure that this notice is replicated
117585SAli.Saidi@arm.com * unmodified and in its entirety in all distributions of the software,
127585SAli.Saidi@arm.com * modified or unmodified, in source code or in binary form.
137585SAli.Saidi@arm.com *
147585SAli.Saidi@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan
157585SAli.Saidi@arm.com * All rights reserved.
167585SAli.Saidi@arm.com *
177585SAli.Saidi@arm.com * Redistribution and use in source and binary forms, with or without
187585SAli.Saidi@arm.com * modification, are permitted provided that the following conditions are
197585SAli.Saidi@arm.com * met: redistributions of source code must retain the above copyright
207585SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer;
217585SAli.Saidi@arm.com * redistributions in binary form must reproduce the above copyright
227585SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer in the
237585SAli.Saidi@arm.com * documentation and/or other materials provided with the distribution;
247585SAli.Saidi@arm.com * neither the name of the copyright holders nor the names of its
257585SAli.Saidi@arm.com * contributors may be used to endorse or promote products derived from
267585SAli.Saidi@arm.com * this software without specific prior written permission.
277585SAli.Saidi@arm.com *
287585SAli.Saidi@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
297585SAli.Saidi@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
307585SAli.Saidi@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
317585SAli.Saidi@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
327585SAli.Saidi@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
337585SAli.Saidi@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
347585SAli.Saidi@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
357585SAli.Saidi@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
367585SAli.Saidi@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
377585SAli.Saidi@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
387585SAli.Saidi@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
397585SAli.Saidi@arm.com *
407585SAli.Saidi@arm.com * Authors: Ron Dreslinski
417585SAli.Saidi@arm.com *          Ali Saidi
427585SAli.Saidi@arm.com *          Andreas Hansson
437585SAli.Saidi@arm.com *          William Wang
447585SAli.Saidi@arm.com */
457585SAli.Saidi@arm.com
467585SAli.Saidi@arm.com/**
477585SAli.Saidi@arm.com * @file
487585SAli.Saidi@arm.com * Declaration of a coherent crossbar.
497585SAli.Saidi@arm.com */
507585SAli.Saidi@arm.com
517585SAli.Saidi@arm.com#ifndef __MEM_COHERENT_XBAR_HH__
527585SAli.Saidi@arm.com#define __MEM_COHERENT_XBAR_HH__
537585SAli.Saidi@arm.com
547585SAli.Saidi@arm.com#include <unordered_map>
557585SAli.Saidi@arm.com#include <unordered_set>
567585SAli.Saidi@arm.com
577585SAli.Saidi@arm.com#include "mem/snoop_filter.hh"
587585SAli.Saidi@arm.com#include "mem/xbar.hh"
597585SAli.Saidi@arm.com#include "params/CoherentXBar.hh"
607585SAli.Saidi@arm.com
617585SAli.Saidi@arm.com/**
627585SAli.Saidi@arm.com * A coherent crossbar connects a number of (potentially) snooping
637585SAli.Saidi@arm.com * masters and slaves, and routes the request and response packets
647585SAli.Saidi@arm.com * based on the address, and also forwards all requests to the
657585SAli.Saidi@arm.com * snoopers and deals with the snoop responses.
667585SAli.Saidi@arm.com *
677585SAli.Saidi@arm.com * The coherent crossbar can be used as a template for modelling QPI,
687585SAli.Saidi@arm.com * HyperTransport, ACE and coherent OCP buses, and is typically used
697585SAli.Saidi@arm.com * for the L1-to-L2 buses and as the main system interconnect.  @sa
707585SAli.Saidi@arm.com * \ref gem5MemorySystem "gem5 Memory System"
717585SAli.Saidi@arm.com */
727585SAli.Saidi@arm.comclass CoherentXBar : public BaseXBar
737585SAli.Saidi@arm.com{
747585SAli.Saidi@arm.com
757585SAli.Saidi@arm.com  protected:
767585SAli.Saidi@arm.com
777585SAli.Saidi@arm.com    /**
787585SAli.Saidi@arm.com     * Declare the layers of this crossbar, one vector for requests,
797585SAli.Saidi@arm.com     * one for responses, and one for snoop responses
807585SAli.Saidi@arm.com     */
817585SAli.Saidi@arm.com    std::vector<ReqLayer*> reqLayers;
827585SAli.Saidi@arm.com    std::vector<RespLayer*> respLayers;
837585SAli.Saidi@arm.com    std::vector<SnoopRespLayer*> snoopLayers;
847585SAli.Saidi@arm.com
857585SAli.Saidi@arm.com    /**
867585SAli.Saidi@arm.com     * Declaration of the coherent crossbar slave port type, one will
877585SAli.Saidi@arm.com     * be instantiated for each of the master ports connecting to the
887585SAli.Saidi@arm.com     * crossbar.
897585SAli.Saidi@arm.com     */
907585SAli.Saidi@arm.com    class CoherentXBarSlavePort : public QueuedSlavePort
917585SAli.Saidi@arm.com    {
927585SAli.Saidi@arm.com
937585SAli.Saidi@arm.com      private:
947585SAli.Saidi@arm.com
957585SAli.Saidi@arm.com        /** A reference to the crossbar to which this port belongs. */
967585SAli.Saidi@arm.com        CoherentXBar &xbar;
977585SAli.Saidi@arm.com
987585SAli.Saidi@arm.com        /** A normal packet queue used to store responses. */
997585SAli.Saidi@arm.com        RespPacketQueue queue;
1007585SAli.Saidi@arm.com
1017585SAli.Saidi@arm.com      public:
1027585SAli.Saidi@arm.com
1037585SAli.Saidi@arm.com        CoherentXBarSlavePort(const std::string &_name,
1047585SAli.Saidi@arm.com                             CoherentXBar &_xbar, PortID _id)
1057585SAli.Saidi@arm.com            : QueuedSlavePort(_name, &_xbar, queue, _id), xbar(_xbar),
1067585SAli.Saidi@arm.com              queue(_xbar, *this)
1077585SAli.Saidi@arm.com        { }
1087585SAli.Saidi@arm.com
1097585SAli.Saidi@arm.com      protected:
1107585SAli.Saidi@arm.com
1117585SAli.Saidi@arm.com        /**
1127585SAli.Saidi@arm.com         * When receiving a timing request, pass it to the crossbar.
1137585SAli.Saidi@arm.com         */
1147585SAli.Saidi@arm.com        virtual bool recvTimingReq(PacketPtr pkt)
1157585SAli.Saidi@arm.com        { return xbar.recvTimingReq(pkt, id); }
1167585SAli.Saidi@arm.com
1177585SAli.Saidi@arm.com        /**
1187585SAli.Saidi@arm.com         * When receiving a timing snoop response, pass it to the crossbar.
1197585SAli.Saidi@arm.com         */
1207585SAli.Saidi@arm.com        virtual bool recvTimingSnoopResp(PacketPtr pkt)
1217585SAli.Saidi@arm.com        { return xbar.recvTimingSnoopResp(pkt, id); }
1227585SAli.Saidi@arm.com
1237585SAli.Saidi@arm.com        /**
1247585SAli.Saidi@arm.com         * When receiving an atomic request, pass it to the crossbar.
1257585SAli.Saidi@arm.com         */
1267585SAli.Saidi@arm.com        virtual Tick recvAtomic(PacketPtr pkt)
1277585SAli.Saidi@arm.com        { return xbar.recvAtomic(pkt, id); }
1287585SAli.Saidi@arm.com
1297585SAli.Saidi@arm.com        /**
1307585SAli.Saidi@arm.com         * When receiving a functional request, pass it to the crossbar.
1317585SAli.Saidi@arm.com         */
1327585SAli.Saidi@arm.com        virtual void recvFunctional(PacketPtr pkt)
1337585SAli.Saidi@arm.com        { xbar.recvFunctional(pkt, id); }
1347585SAli.Saidi@arm.com
1357585SAli.Saidi@arm.com        /**
1367585SAli.Saidi@arm.com         * Return the union of all adress ranges seen by this crossbar.
1377585SAli.Saidi@arm.com         */
1387585SAli.Saidi@arm.com        virtual AddrRangeList getAddrRanges() const
1397585SAli.Saidi@arm.com        { return xbar.getAddrRanges(); }
1407585SAli.Saidi@arm.com
1417585SAli.Saidi@arm.com    };
1427585SAli.Saidi@arm.com
1437585SAli.Saidi@arm.com    /**
1447585SAli.Saidi@arm.com     * Declaration of the coherent crossbar master port type, one will be
1457585SAli.Saidi@arm.com     * instantiated for each of the slave interfaces connecting to the
1467585SAli.Saidi@arm.com     * crossbar.
1477585SAli.Saidi@arm.com     */
1487585SAli.Saidi@arm.com    class CoherentXBarMasterPort : public MasterPort
1497585SAli.Saidi@arm.com    {
1507585SAli.Saidi@arm.com      private:
1517585SAli.Saidi@arm.com        /** A reference to the crossbar to which this port belongs. */
1527585SAli.Saidi@arm.com        CoherentXBar &xbar;
1537585SAli.Saidi@arm.com
1547585SAli.Saidi@arm.com      public:
1557585SAli.Saidi@arm.com
1567585SAli.Saidi@arm.com        CoherentXBarMasterPort(const std::string &_name,
1577585SAli.Saidi@arm.com                              CoherentXBar &_xbar, PortID _id)
1587585SAli.Saidi@arm.com            : MasterPort(_name, &_xbar, _id), xbar(_xbar)
1597585SAli.Saidi@arm.com        { }
1607585SAli.Saidi@arm.com
1617585SAli.Saidi@arm.com      protected:
1627585SAli.Saidi@arm.com
1637585SAli.Saidi@arm.com        /**
1647585SAli.Saidi@arm.com         * Determine if this port should be considered a snooper. For
1657585SAli.Saidi@arm.com         * a coherent crossbar master port this is always true.
1667585SAli.Saidi@arm.com         *
1677585SAli.Saidi@arm.com         * @return a boolean that is true if this port is snooping
1687585SAli.Saidi@arm.com         */
1697585SAli.Saidi@arm.com        virtual bool isSnooping() const
1707585SAli.Saidi@arm.com        { return true; }
1717585SAli.Saidi@arm.com
1727585SAli.Saidi@arm.com        /**
1737585SAli.Saidi@arm.com         * When receiving a timing response, pass it to the crossbar.
1747585SAli.Saidi@arm.com         */
1757585SAli.Saidi@arm.com        virtual bool recvTimingResp(PacketPtr pkt)
1767585SAli.Saidi@arm.com        { return xbar.recvTimingResp(pkt, id); }
1777585SAli.Saidi@arm.com
1787585SAli.Saidi@arm.com        /**
1797585SAli.Saidi@arm.com         * When receiving a timing snoop request, pass it to the crossbar.
1807585SAli.Saidi@arm.com         */
1817585SAli.Saidi@arm.com        virtual void recvTimingSnoopReq(PacketPtr pkt)
1827585SAli.Saidi@arm.com        { return xbar.recvTimingSnoopReq(pkt, id); }
1837585SAli.Saidi@arm.com
1847585SAli.Saidi@arm.com        /**
1857585SAli.Saidi@arm.com         * When receiving an atomic snoop request, pass it to the crossbar.
1867585SAli.Saidi@arm.com         */
1877585SAli.Saidi@arm.com        virtual Tick recvAtomicSnoop(PacketPtr pkt)
1887585SAli.Saidi@arm.com        { return xbar.recvAtomicSnoop(pkt, id); }
1897585SAli.Saidi@arm.com
1907585SAli.Saidi@arm.com        /**
1917585SAli.Saidi@arm.com         * When receiving a functional snoop request, pass it to the crossbar.
1927585SAli.Saidi@arm.com         */
1937585SAli.Saidi@arm.com        virtual void recvFunctionalSnoop(PacketPtr pkt)
1947585SAli.Saidi@arm.com        { xbar.recvFunctionalSnoop(pkt, id); }
1957585SAli.Saidi@arm.com
1967585SAli.Saidi@arm.com        /** When reciving a range change from the peer port (at id),
1977585SAli.Saidi@arm.com            pass it to the crossbar. */
1987585SAli.Saidi@arm.com        virtual void recvRangeChange()
1997585SAli.Saidi@arm.com        { xbar.recvRangeChange(id); }
2007585SAli.Saidi@arm.com
2017585SAli.Saidi@arm.com        /** When reciving a retry from the peer port (at id),
2027585SAli.Saidi@arm.com            pass it to the crossbar. */
2037585SAli.Saidi@arm.com        virtual void recvReqRetry()
2047585SAli.Saidi@arm.com        { xbar.recvReqRetry(id); }
2057585SAli.Saidi@arm.com
2067585SAli.Saidi@arm.com    };
2077585SAli.Saidi@arm.com
2087585SAli.Saidi@arm.com    /**
2097585SAli.Saidi@arm.com     * Internal class to bridge between an incoming snoop response
2107585SAli.Saidi@arm.com     * from a slave port and forwarding it through an outgoing slave
2117585SAli.Saidi@arm.com     * port. It is effectively a dangling master port.
2127585SAli.Saidi@arm.com     */
2137585SAli.Saidi@arm.com    class SnoopRespPort : public MasterPort
2147585SAli.Saidi@arm.com    {
2157585SAli.Saidi@arm.com
2167585SAli.Saidi@arm.com      private:
2177585SAli.Saidi@arm.com
2187585SAli.Saidi@arm.com        /** The port which we mirror internally. */
2197585SAli.Saidi@arm.com        QueuedSlavePort& slavePort;
2207585SAli.Saidi@arm.com
2217585SAli.Saidi@arm.com      public:
2227585SAli.Saidi@arm.com
2237585SAli.Saidi@arm.com        /**
2247585SAli.Saidi@arm.com         * Create a snoop response port that mirrors a given slave port.
2257585SAli.Saidi@arm.com         */
2267585SAli.Saidi@arm.com        SnoopRespPort(QueuedSlavePort& slave_port, CoherentXBar& _xbar) :
2277585SAli.Saidi@arm.com            MasterPort(slave_port.name() + ".snoopRespPort", &_xbar),
2287585SAli.Saidi@arm.com            slavePort(slave_port) { }
2297585SAli.Saidi@arm.com
2307585SAli.Saidi@arm.com        /**
2317585SAli.Saidi@arm.com         * Override the sending of retries and pass them on through
2327585SAli.Saidi@arm.com         * the mirrored slave port.
2337585SAli.Saidi@arm.com         */
2347585SAli.Saidi@arm.com        void sendRetryResp() {
2357585SAli.Saidi@arm.com            // forward it as a snoop response retry
2367585SAli.Saidi@arm.com            slavePort.sendRetrySnoopResp();
2377585SAli.Saidi@arm.com        }
2387585SAli.Saidi@arm.com
2397585SAli.Saidi@arm.com        /**
2407585SAli.Saidi@arm.com         * Provided as necessary.
2417585SAli.Saidi@arm.com         */
2427585SAli.Saidi@arm.com        void recvReqRetry() { panic("SnoopRespPort should never see retry\n"); }
2437585SAli.Saidi@arm.com
2447585SAli.Saidi@arm.com        /**
2457585SAli.Saidi@arm.com         * Provided as necessary.
2467585SAli.Saidi@arm.com         */
2477585SAli.Saidi@arm.com        bool recvTimingResp(PacketPtr pkt)
2487585SAli.Saidi@arm.com        {
2497585SAli.Saidi@arm.com            panic("SnoopRespPort should never see timing response\n");
2507585SAli.Saidi@arm.com            return false;
2517585SAli.Saidi@arm.com        }
2527585SAli.Saidi@arm.com
2537585SAli.Saidi@arm.com    };
2547585SAli.Saidi@arm.com
2557585SAli.Saidi@arm.com    std::vector<SnoopRespPort*> snoopRespPorts;
2567585SAli.Saidi@arm.com
2577585SAli.Saidi@arm.com    std::vector<QueuedSlavePort*> snoopPorts;
2587585SAli.Saidi@arm.com
2597585SAli.Saidi@arm.com    /**
2607585SAli.Saidi@arm.com     * Store the outstanding requests that we are expecting snoop
2617585SAli.Saidi@arm.com     * responses from so we can determine which snoop responses we
2627585SAli.Saidi@arm.com     * generated and which ones were merely forwarded.
2637585SAli.Saidi@arm.com     */
2647585SAli.Saidi@arm.com    std::unordered_set<RequestPtr> outstandingSnoop;
2657585SAli.Saidi@arm.com
2667585SAli.Saidi@arm.com    /**
2677585SAli.Saidi@arm.com     * Store the outstanding cache maintenance that we are expecting
2687585SAli.Saidi@arm.com     * snoop responses from so we can determine when we received all
2697585SAli.Saidi@arm.com     * snoop responses and if any of the agents satisfied the request.
2707585SAli.Saidi@arm.com     */
2717585SAli.Saidi@arm.com    std::unordered_map<PacketId, PacketPtr> outstandingCMO;
2727585SAli.Saidi@arm.com
2737585SAli.Saidi@arm.com    /**
2747585SAli.Saidi@arm.com     * Keep a pointer to the system to be allow to querying memory system
2757585SAli.Saidi@arm.com     * properties.
2767585SAli.Saidi@arm.com     */
2777585SAli.Saidi@arm.com    System *system;
2787585SAli.Saidi@arm.com
2797585SAli.Saidi@arm.com    /** A snoop filter that tracks cache line residency and can restrict the
2807585SAli.Saidi@arm.com      * broadcast needed for probes.  NULL denotes an absent filter. */
2817585SAli.Saidi@arm.com    SnoopFilter *snoopFilter;
2827585SAli.Saidi@arm.com
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