/* * 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. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer; * redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution; * neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Ron Dreslinski * Mitch Hayenga */ /** * @file * Miss and writeback queue declarations. */ #ifndef __MEM_CACHE_PREFETCH_BASE_HH__ #define __MEM_CACHE_PREFETCH_BASE_HH__ #include #include "arch/isa_traits.hh" #include "base/statistics.hh" #include "base/types.hh" #include "mem/packet.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 : public ClockedObject { class PrefetchListener : public ProbeListenerArgBase { 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 listeners; public: /** * 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 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; } }; protected: // PARAMETERS /** Pointr to the parent cache. */ BaseCache* cache; /** The block size of the parent cache. */ unsigned blkSize; /** log_2(block size of the parent cache). */ unsigned lBlkSize; /** Only consult prefetcher on cache misses? */ const bool onMiss; /** Consult prefetcher on reads? */ const bool onRead; /** Consult prefetcher on reads? */ const bool onWrite; /** Consult prefetcher on data accesses? */ const bool onData; /** 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 pfIssued; /** Total prefetches issued */ uint64_t issuedPrefetches; /** Total prefetches that has been useful */ uint64_t usefulPrefetches; public: BasePrefetcher(const BasePrefetcherParams *p); virtual ~BasePrefetcher() {} virtual void setCache(BaseCache *_cache); /** * Notify prefetcher of cache access (may be any access or just * misses, depending on cache parameters.) */ virtual void notify(const PacketPtr &pkt, const PrefetchInfo &pfi) = 0; /** Notify prefetcher of cache fill */ virtual void notifyFill(const PacketPtr &pkt) {} virtual PacketPtr getPacket() = 0; virtual Tick nextPrefetchReadyTime() const = 0; /** * Register local statistics. */ void regStats() override; /** * Register probe points for this object. */ void regProbeListeners() override; /** * 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); /** * 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); }; #endif //__MEM_CACHE_PREFETCH_BASE_HH__