mem-cache: Initialize all members of `QueuedPrefetcher::DeferredPacket`.
[gem5.git] / src / mem / cache / prefetch / base.hh
index fc027cb3beb4fc7440b48ad59073b1263f77edaf..77d2f3697e87ebb9619a2c41ac8fe8da22efdda2 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2013-2014 ARM Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2005 The Regents of The University of Michigan
  * All rights reserved.
  *
@@ -26,6 +38,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Authors: Ron Dreslinski
+ *          Mitch Hayenga
  */
 
 /**
  * Miss and writeback queue declarations.
  */
 
-#ifndef __MEM_CACHE_PREFETCH_BASE_PREFETCHER_HH__
-#define __MEM_CACHE_PREFETCH_BASE_PREFETCHER_HH__
+#ifndef __MEM_CACHE_PREFETCH_BASE_HH__
+#define __MEM_CACHE_PREFETCH_BASE_HH__
 
-#include <list>
+#include <cstdint>
 
+#include "arch/isa_traits.hh"
+#include "arch/generic/tlb.hh"
 #include "base/statistics.hh"
+#include "base/types.hh"
 #include "mem/packet.hh"
-#include "params/BaseCache.hh"
+#include "mem/request.hh"
+#include "sim/byteswap.hh"
+#include "sim/clocked_object.hh"
+#include "sim/probe/probe.hh"
 
 class BaseCache;
+struct BasePrefetcherParams;
 
-class BasePrefetcher
+class BasePrefetcher : public ClockedObject
 {
-  protected:
+    class PrefetchListener : public ProbeListenerArgBase<PacketPtr>
+    {
+      public:
+        PrefetchListener(BasePrefetcher &_parent, ProbeManager *pm,
+                         const std::string &name, bool _isFill = false,
+                         bool _miss = false)
+            : ProbeListenerArgBase(pm, name),
+              parent(_parent), isFill(_isFill), miss(_miss) {}
+        void notify(const PacketPtr &pkt) override;
+      protected:
+        BasePrefetcher &parent;
+        const bool isFill;
+        const bool miss;
+    };
+
+    std::vector<PrefetchListener *> listeners;
 
-    /** The Prefetch Queue. */
-    std::list<PacketPtr> pf;
+  public:
 
-    // PARAMETERS
+    /**
+     * Class containing the information needed by the prefetch to train and
+     * generate new prefetch requests.
+     */
+    class PrefetchInfo {
+        /** The address used to train and generate prefetches */
+        Addr address;
+        /** The program counter that generated this address. */
+        Addr pc;
+        /** The requestor ID that generated this address. */
+        MasterID masterId;
+        /** Validity bit for the PC of this address. */
+        bool validPC;
+        /** Whether this address targets the secure memory space. */
+        bool secure;
+        /** Size in bytes of the request triggering this event */
+        unsigned int size;
+        /** Whether this event comes from a write request */
+        bool write;
+        /** Physical address, needed because address can be virtual */
+        Addr paddress;
+        /** Whether this event comes from a cache miss */
+        bool cacheMiss;
+        /** Pointer to the associated request data */
+        uint8_t *data;
+
+      public:
+        /**
+         * Obtains the address value of this Prefetcher address.
+         * @return the addres value.
+         */
+        Addr getAddr() const
+        {
+            return address;
+        }
+
+        /**
+         * Returns true if the address targets the secure memory space.
+         * @return true if the address targets the secure memory space.
+         */
+        bool isSecure() const
+        {
+            return secure;
+        }
+
+        /**
+         * Returns the program counter that generated this request.
+         * @return the pc value
+         */
+        Addr getPC() const
+        {
+            assert(hasPC());
+            return pc;
+        }
+
+        /**
+         * Returns true if the associated program counter is valid
+         * @return true if the program counter has a valid value
+         */
+        bool hasPC() const
+        {
+            return validPC;
+        }
+
+        /**
+         * Gets the requestor ID that generated this address
+         * @return the requestor ID that generated this address
+         */
+        MasterID getMasterId() const
+        {
+            return masterId;
+        }
+
+        /**
+         * Gets the size of the request triggering this event
+         * @return the size in bytes of the request triggering this event
+         */
+        unsigned int getSize() const
+        {
+            return size;
+        }
+
+        /**
+         * Checks if the request that caused this prefetch event was a write
+         * request
+         * @return true if the request causing this event is a write request
+         */
+        bool isWrite() const
+        {
+            return write;
+        }
+
+        /**
+         * Gets the physical address of the request
+         * @return physical address of the request
+         */
+        Addr getPaddr() const
+        {
+            return paddress;
+        }
+
+        /**
+         * Check if this event comes from a cache miss
+         * @result true if this event comes from a cache miss
+         */
+        bool isCacheMiss() const
+        {
+            return cacheMiss;
+        }
+
+        /**
+         * Gets the associated data of the request triggering the event
+         * @param Byte ordering of the stored data
+         * @return the data
+         */
+        template <typename T>
+        inline T
+        get(ByteOrder endian) const
+        {
+            if (data == nullptr) {
+                panic("PrefetchInfo::get called with a request with no data.");
+            }
+            switch (endian) {
+                case BigEndianByteOrder:
+                    return betoh(*(T*)data);
+
+                case LittleEndianByteOrder:
+                    return letoh(*(T*)data);
+
+                default:
+                    panic("Illegal byte order in PrefetchInfo::get()\n");
+            };
+        }
+
+        /**
+         * Check for equality
+         * @param pfi PrefetchInfo to compare against
+         * @return True if this object and the provided one are equal
+         */
+        bool sameAddr(PrefetchInfo const &pfi) const
+        {
+            return this->getAddr() == pfi.getAddr() &&
+                this->isSecure() == pfi.isSecure();
+        }
+
+        /**
+         * Constructs a PrefetchInfo using a PacketPtr.
+         * @param pkt PacketPtr used to generate the PrefetchInfo
+         * @param addr the address value of the new object, this address is
+         *        used to train the prefetcher
+         * @param miss whether this event comes from a cache miss
+         */
+        PrefetchInfo(PacketPtr pkt, Addr addr, bool miss);
+
+        /**
+         * Constructs a PrefetchInfo using a new address value and
+         * another PrefetchInfo as a reference.
+         * @param pfi PrefetchInfo used to generate this new object
+         * @param addr the address value of the new object
+         */
+        PrefetchInfo(PrefetchInfo const &pfi, Addr addr);
+
+        ~PrefetchInfo()
+        {
+            delete[] data;
+        }
+    };
 
-    /** The number of MSHRs in the Prefetch Queue. */
-    const int size;
+  protected:
+
+    // PARAMETERS
 
     /** Pointr to the parent cache. */
     BaseCache* cache;
 
     /** The block size of the parent cache. */
-    int blkSize;
+    unsigned blkSize;
 
-    /** Do we prefetch across page boundaries. */
-    bool pageStop;
+    /** log_2(block size of the parent cache). */
+    unsigned lBlkSize;
 
-    /** Do we remove prefetches with later times than a new miss.*/
-    bool serialSquash;
+    /** Only consult prefetcher on cache misses? */
+    const bool onMiss;
 
-    /** Do we check if it is in the cache when inserting into buffer,
-        or removing.*/
-    bool cacheCheckPush;
+    /** Consult prefetcher on reads? */
+    const bool onRead;
 
-    /** Do we prefetch on only data reads, or on inst reads as well. */
-    bool onlyData;
+    /** Consult prefetcher on reads? */
+    const bool onWrite;
 
-    std::string _name;
+    /** Consult prefetcher on data accesses? */
+    const bool onData;
 
-  public:
+    /** Consult prefetcher on instruction accesses? */
+    const bool onInst;
+
+    /** Request id for prefetches */
+    const MasterID masterId;
+
+    const Addr pageBytes;
+
+    /** Prefetch on every access, not just misses */
+    const bool prefetchOnAccess;
+
+    /** Use Virtual Addresses for prefetching */
+    const bool useVirtualAddresses;
+
+    /**
+     * Determine if this access should be observed
+     * @param pkt The memory request causing the event
+     * @param miss whether this event comes from a cache miss
+     */
+    bool observeAccess(const PacketPtr &pkt, bool miss) const;
+
+    /** Determine if address is in cache */
+    bool inCache(Addr addr, bool is_secure) const;
+
+    /** Determine if address is in cache miss queue */
+    bool inMissQueue(Addr addr, bool is_secure) const;
+
+    bool hasBeenPrefetched(Addr addr, bool is_secure) const;
+
+    /** Determine if addresses are on the same page */
+    bool samePage(Addr a, Addr b) const;
+    /** Determine the address of the block in which a lays */
+    Addr blockAddress(Addr a) const;
+    /** Determine the address of a at block granularity */
+    Addr blockIndex(Addr a) const;
+    /** Determine the address of the page in which a lays */
+    Addr pageAddress(Addr a) const;
+    /** Determine the page-offset of a  */
+    Addr pageOffset(Addr a) const;
+    /** Build the address of the i-th block inside the page */
+    Addr pageIthBlockAddress(Addr page, uint32_t i) const;
 
-    Stats::Scalar pfIdentified;
-    Stats::Scalar pfMSHRHit;
-    Stats::Scalar pfCacheHit;
-    Stats::Scalar pfBufferHit;
-    Stats::Scalar pfRemovedFull;
-    Stats::Scalar pfRemovedMSHR;
     Stats::Scalar pfIssued;
-    Stats::Scalar pfSpanPage;
-    Stats::Scalar pfSquashed;
 
-    void regStats(const std::string &name);
+    /** Total prefetches issued */
+    uint64_t issuedPrefetches;
+    /** Total prefetches that has been useful */
+    uint64_t usefulPrefetches;
+
+    /** Registered tlb for address translations */
+    BaseTLB * tlb;
 
   public:
 
-    BasePrefetcher(const BaseCacheParams *p);
+    BasePrefetcher(const BasePrefetcherParams *p);
 
     virtual ~BasePrefetcher() {}
 
-    const std::string name() const { return _name; }
-
-    void setCache(BaseCache *_cache);
+    virtual void setCache(BaseCache *_cache);
 
     /**
      * Notify prefetcher of cache access (may be any access or just
      * misses, depending on cache parameters.)
-     * @retval Time of next prefetch availability, or 0 if none.
      */
-    Tick notify(PacketPtr &pkt, Tick time);
+    virtual void notify(const PacketPtr &pkt, const PrefetchInfo &pfi) = 0;
 
-    bool inCache(Addr addr);
+    /** Notify prefetcher of cache fill */
+    virtual void notifyFill(const PacketPtr &pkt)
+    {}
 
-    bool inMissQueue(Addr addr);
+    virtual PacketPtr getPacket() = 0;
 
-    PacketPtr getPacket();
+    virtual Tick nextPrefetchReadyTime() const = 0;
 
-    bool havePending()
-    {
-        return !pf.empty();
-    }
+    /**
+     * Register local statistics.
+     */
+    void regStats() override;
 
-    Tick nextPrefetchReadyTime()
-    {
-        return pf.empty() ? MaxTick : pf.front()->time;
-    }
+    /**
+     * Register probe points for this object.
+     */
+    void regProbeListeners() override;
 
-    virtual void calculatePrefetch(PacketPtr &pkt,
-                                   std::list<Addr> &addresses,
-                                   std::list<Tick> &delays) = 0;
+    /**
+     * Process a notification event from the ProbeListener.
+     * @param pkt The memory request causing the event
+     * @param miss whether this event comes from a cache miss
+     */
+    void probeNotify(const PacketPtr &pkt, bool miss);
 
-    std::list<PacketPtr>::iterator inPrefetch(Addr address);
+    /**
+     * Add a SimObject and a probe name to listen events from
+     * @param obj The SimObject pointer to listen from
+     * @param name The probe name
+     */
+    void addEventProbe(SimObject *obj, const char *name);
 
     /**
-     * Utility function: are addresses a and b on the same VM page?
+     * Add a BaseTLB object to be used whenever a translation is needed.
+     * This is generally required when the prefetcher is allowed to generate
+     * page crossing references and/or uses virtual addresses for training.
+     * @param tlb pointer to the BaseTLB object to add
      */
-    bool samePage(Addr a, Addr b);
+    void addTLB(BaseTLB *tlb);
 };
-
-
-#endif //__MEM_CACHE_PREFETCH_BASE_PREFETCHER_HH__
+#endif //__MEM_CACHE_PREFETCH_BASE_HH__