/*
 * Copyright (c) 2011-2015 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * For use for simulation and test purposes only
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of the copyright holder 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 HOLDER 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.
 */

#ifndef __GPU_TLB_HH__
#define __GPU_TLB_HH__

#include <fstream>
#include <list>
#include <queue>
#include <string>
#include <vector>

#include "arch/generic/tlb.hh"
#include "arch/x86/pagetable.hh"
#include "arch/x86/pagetable_walker.hh"
#include "arch/x86/regs/segment.hh"
#include "base/callback.hh"
#include "base/logging.hh"
#include "base/statistics.hh"
#include "gpu-compute/compute_unit.hh"
#include "mem/port.hh"
#include "mem/request.hh"
#include "params/X86GPUTLB.hh"
#include "sim/clocked_object.hh"
#include "sim/sim_object.hh"

class BaseTLB;
class Packet;
class ThreadContext;

namespace X86ISA
{
    class GpuTLB : public ClockedObject
    {
      protected:
        friend class Walker;

        typedef std::list<TlbEntry*> EntryList;

        uint32_t configAddress;

        // TLB clock: will inherit clock from shader's clock period in terms
        // of nuber of ticks of curTime (aka global simulation clock)
        // The assignment of TLB clock from shader clock is done in the python
        // config files.
        int clock;

      public:
        // clock related functions ; maps to-and-from Simulation ticks and
        // object clocks.
        Tick frequency() const { return SimClock::Frequency / clock; }

        Tick
        ticks(int numCycles) const
        {
            return (Tick)clock * numCycles;
        }

        Tick curCycle() const { return curTick() / clock; }
        Tick tickToCycles(Tick val) const { return val / clock;}

        typedef X86GPUTLBParams Params;
        GpuTLB(const Params *p);
        ~GpuTLB();

        typedef enum BaseTLB::Mode Mode;

        class Translation
        {
          public:
            virtual ~Translation() { }

            /**
             * Signal that the translation has been delayed due to a hw page
             * table walk.
             */
            virtual void markDelayed() = 0;

            /**
             * The memory for this object may be dynamically allocated, and it
             * may be responsible for cleaning itslef up which will happen in
             * this function. Once it's called the object is no longer valid.
             */
            virtual void finish(Fault fault, const RequestPtr &req,
                                ThreadContext *tc, Mode mode) = 0;
        };

        void dumpAll();
        TlbEntry *lookup(Addr va, bool update_lru=true);
        void setConfigAddress(uint32_t addr);

      protected:
        EntryList::iterator lookupIt(Addr va, bool update_lru=true);
        Walker *walker;

      public:
        Walker *getWalker();
        void invalidateAll();
        void invalidateNonGlobal();
        void demapPage(Addr va, uint64_t asn);

      protected:
        int size;
        int assoc;
        int numSets;

        /**
         *  true if this is a fully-associative TLB
         */
        bool FA;
        Addr setMask;

        /**
         * Allocation Policy: true if we always allocate on a hit, false
         * otherwise. Default is true.
         */
        bool allocationPolicy;

        /**
         * if true, then this is not the last level TLB
         */
        bool hasMemSidePort;

        /**
         * Print out accessDistance stats. One stat file
         * per TLB.
         */
        bool accessDistance;

        std::vector<TlbEntry> tlb;

        /*
         * It's a per-set list. As long as we have not reached
         * the full capacity of the given set, grab an entry from
         * the freeList.
         */
        std::vector<EntryList> freeList;

        /**
         * An entryList per set is the equivalent of an LRU stack;
         * it's used to guide replacement decisions. The head of the list
         * contains the MRU TLB entry of the given set. If the freeList
         * for this set is empty, the last element of the list
         * is evicted (i.e., dropped on the floor).
         */
        std::vector<EntryList> entryList;

        Fault translateInt(bool read, const RequestPtr &req,
                           ThreadContext *tc);

        Fault translate(const RequestPtr &req, ThreadContext *tc,
                Translation *translation, Mode mode, bool &delayedResponse,
                bool timing, int &latency);

      public:
        // latencies for a TLB hit, miss and page fault
        int hitLatency;
        int missLatency1;
        int missLatency2;

        // local_stats are as seen from the TLB
        // without taking into account coalescing
        Stats::Scalar localNumTLBAccesses;
        Stats::Scalar localNumTLBHits;
        Stats::Scalar localNumTLBMisses;
        Stats::Formula localTLBMissRate;

        // global_stats are as seen from the
        // CU's perspective taking into account
        // all coalesced requests.
        Stats::Scalar globalNumTLBAccesses;
        Stats::Scalar globalNumTLBHits;
        Stats::Scalar globalNumTLBMisses;
        Stats::Formula globalTLBMissRate;

        // from the CU perspective (global)
        Stats::Scalar accessCycles;
        // from the CU perspective (global)
        Stats::Scalar pageTableCycles;
        Stats::Scalar numUniquePages;
        // from the perspective of this TLB
        Stats::Scalar localCycles;
        // from the perspective of this TLB
        Stats::Formula localLatency;
        // I take the avg. per page and then
        // the avg. over all pages.
        Stats::Scalar avgReuseDistance;

        void regStats() override;
        void updatePageFootprint(Addr virt_page_addr);
        void printAccessPattern();


        Fault translateAtomic(const RequestPtr &req, ThreadContext *tc,
                              Mode mode, int &latency);

        void translateTiming(const RequestPtr &req, ThreadContext *tc,
                             Translation *translation, Mode mode,
                             int &latency);

        Tick doMmuRegRead(ThreadContext *tc, Packet *pkt);
        Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt);

        TlbEntry *insert(Addr vpn, TlbEntry &entry);

        // Checkpointing
        virtual void serialize(CheckpointOut& cp) const override;
        virtual void unserialize(CheckpointIn& cp) override;
        void issueTranslation();
        enum tlbOutcome {TLB_HIT, TLB_MISS, PAGE_WALK, MISS_RETURN};
        bool tlbLookup(const RequestPtr &req,
                       ThreadContext *tc, bool update_stats);

        void handleTranslationReturn(Addr addr, tlbOutcome outcome,
                                     PacketPtr pkt);

        void handleFuncTranslationReturn(PacketPtr pkt, tlbOutcome outcome);

        void pagingProtectionChecks(ThreadContext *tc, PacketPtr pkt,
                                    TlbEntry *tlb_entry, Mode mode);

        void updatePhysAddresses(Addr virt_page_addr, TlbEntry *tlb_entry,
                                 Addr phys_page_addr);

        void issueTLBLookup(PacketPtr pkt);

        // CpuSidePort is the TLB Port closer to the CPU/CU side
        class CpuSidePort : public SlavePort
        {
          public:
            CpuSidePort(const std::string &_name, GpuTLB * gpu_TLB,
                        PortID _index)
                : SlavePort(_name, gpu_TLB), tlb(gpu_TLB), index(_index) { }

          protected:
            GpuTLB *tlb;
            int index;

            virtual bool recvTimingReq(PacketPtr pkt);
            virtual Tick recvAtomic(PacketPtr pkt) { return 0; }
            virtual void recvFunctional(PacketPtr pkt);
            virtual void recvRangeChange() { }
            virtual void recvReqRetry();
            virtual void recvRespRetry() { panic("recvRespRetry called"); }
            virtual AddrRangeList getAddrRanges() const;
        };

        /**
         * MemSidePort is the TLB Port closer to the memory side
         * If this is a last level TLB then this port will not be connected.
         *
         * Future action item: if we ever do real page walks, then this port
         * should be connected to a RubyPort.
         */
        class MemSidePort : public MasterPort
        {
          public:
            MemSidePort(const std::string &_name, GpuTLB * gpu_TLB,
                        PortID _index)
                : MasterPort(_name, gpu_TLB), tlb(gpu_TLB), index(_index) { }

            std::deque<PacketPtr> retries;

          protected:
            GpuTLB *tlb;
            int index;

            virtual bool recvTimingResp(PacketPtr pkt);
            virtual Tick recvAtomic(PacketPtr pkt) { return 0; }
            virtual void recvFunctional(PacketPtr pkt) { }
            virtual void recvRangeChange() { }
            virtual void recvReqRetry();
        };

        // TLB ports on the cpu Side
        std::vector<CpuSidePort*> cpuSidePort;
        // TLB ports on the memory side
        std::vector<MemSidePort*> memSidePort;

        Port &getPort(const std::string &if_name,
                      PortID idx=InvalidPortID) override;

        /**
         * TLB TranslationState: this currently is a somewhat bastardization of
         * the usage of SenderState, whereby the receiver of a packet is not
         * usually supposed to need to look at the contents of the senderState,
         * you're really only supposed to look at what you pushed on, pop it
         * off, and send it back.
         *
         * However, since there is state that we want to pass to the TLBs using
         * the send/recv Timing/Functional/etc. APIs, which don't allow for new
         * arguments, we need a common TLB senderState to pass between TLBs,
         * both "forwards" and "backwards."
         *
         * So, basically, the rule is that any packet received by a TLB port
         * (cpuside OR memside) must be safely castable to a TranslationState.
         */

        struct TranslationState : public Packet::SenderState
        {
            // TLB mode, read or write
            Mode tlbMode;
            // Thread context associated with this req
            ThreadContext *tc;

            /*
            * TLB entry to be populated and passed back and filled in
            * previous TLBs.  Equivalent to the data cache concept of
            * "data return."
            */
            TlbEntry *tlbEntry;
            // Is this a TLB prefetch request?
            bool prefetch;
            // When was the req for this translation issued
            uint64_t issueTime;
            // Remember where this came from
            std::vector<SlavePort*>ports;

            // keep track of #uncoalesced reqs per packet per TLB level;
            // reqCnt per level >= reqCnt higher level
            std::vector<int> reqCnt;
            // TLB level this packet hit in; 0 if it hit in the page table
            int hitLevel;
            Packet::SenderState *saved;

            TranslationState(Mode tlb_mode, ThreadContext *_tc,
                             bool _prefetch=false,
                             Packet::SenderState *_saved=nullptr)
                : tlbMode(tlb_mode), tc(_tc), tlbEntry(nullptr),
                  prefetch(_prefetch), issueTime(0),
                  hitLevel(0),saved(_saved) { }
        };

        // maximum number of permitted coalesced requests per cycle
        int maxCoalescedReqs;

        // Current number of outstandings coalesced requests.
        // Should be <= maxCoalescedReqs
        int outstandingReqs;

        /**
         * A TLBEvent is scheduled after the TLB lookup and helps us take the
         * appropriate actions:
         *  (e.g., update TLB on a hit,
         *  send request to lower level TLB on a miss,
         *  or start a page walk if this was the last-level TLB).
         */
        void translationReturn(Addr virtPageAddr, tlbOutcome outcome,
                               PacketPtr pkt);

        class TLBEvent : public Event
        {
            private:
                GpuTLB *tlb;
                Addr virtPageAddr;
                /**
                 * outcome can be TLB_HIT, TLB_MISS, or PAGE_WALK
                 */
                tlbOutcome outcome;
                PacketPtr pkt;

            public:
                TLBEvent(GpuTLB *_tlb, Addr _addr, tlbOutcome outcome,
                        PacketPtr _pkt);

                void process();
                const char *description() const;

                // updateOutcome updates the tlbOutcome of a TLBEvent
                void updateOutcome(tlbOutcome _outcome);
                Addr getTLBEventVaddr();
        };

        std::unordered_map<Addr, TLBEvent*> translationReturnEvent;

        // this FIFO queue keeps track of the virt. page addresses
        // that are pending cleanup
        std::queue<Addr> cleanupQueue;

        // the cleanupEvent is scheduled after a TLBEvent triggers in order to
        // free memory and do the required clean-up
        void cleanup();

        EventFunctionWrapper cleanupEvent;

        /**
         * This hash map will use the virtual page address as a key
         * and will keep track of total number of accesses per page
         */

        struct AccessInfo
        {
            unsigned int lastTimeAccessed; // last access to this page
            unsigned int accessesPerPage;
            // need to divide it by accessesPerPage at the end
            unsigned int totalReuseDistance;

            /**
             * The field below will help us compute the access distance,
             * that is the number of (coalesced) TLB accesses that
             * happened in between each access to this page
             *
             * localTLBAccesses[x] is the value of localTLBNumAccesses
             * when the page <Addr> was accessed for the <x>th time
             */
            std::vector<unsigned int> localTLBAccesses;
            unsigned int sumDistance;
            unsigned int meanDistance;
        };

        typedef std::unordered_map<Addr, AccessInfo> AccessPatternTable;
        AccessPatternTable TLBFootprint;

        // Called at the end of simulation to dump page access stats.
        void exitCallback();

        EventFunctionWrapper exitEvent;
    };
}

#endif // __GPU_TLB_HH__
