/*
 * 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 <cstdint>

#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<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;

  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 <typename T>
        inline T
        get(ByteOrder endian = TheISA::GuestByteOrder) 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() {}

    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__
