gpu_tlb.hh revision 12717
14997Sgblack@eecs.umich.edu/*
25417Sgblack@eecs.umich.edu * Copyright (c) 2011-2015 Advanced Micro Devices, Inc.
34997Sgblack@eecs.umich.edu * All rights reserved.
44997Sgblack@eecs.umich.edu *
54997Sgblack@eecs.umich.edu * For use for simulation and test purposes only
64997Sgblack@eecs.umich.edu *
74997Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
84997Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are met:
94997Sgblack@eecs.umich.edu *
104997Sgblack@eecs.umich.edu * 1. Redistributions of source code must retain the above copyright notice,
114997Sgblack@eecs.umich.edu * this list of conditions and the following disclaimer.
124997Sgblack@eecs.umich.edu *
134997Sgblack@eecs.umich.edu * 2. Redistributions in binary form must reproduce the above copyright notice,
144997Sgblack@eecs.umich.edu * this list of conditions and the following disclaimer in the documentation
154997Sgblack@eecs.umich.edu * and/or other materials provided with the distribution.
164997Sgblack@eecs.umich.edu *
174997Sgblack@eecs.umich.edu * 3. Neither the name of the copyright holder nor the names of its
184997Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from this
194997Sgblack@eecs.umich.edu * software without specific prior written permission.
204997Sgblack@eecs.umich.edu *
214997Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
224997Sgblack@eecs.umich.edu * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
234997Sgblack@eecs.umich.edu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
244997Sgblack@eecs.umich.edu * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
254997Sgblack@eecs.umich.edu * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
264997Sgblack@eecs.umich.edu * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
274997Sgblack@eecs.umich.edu * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
284997Sgblack@eecs.umich.edu * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
294997Sgblack@eecs.umich.edu * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
304997Sgblack@eecs.umich.edu * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
314997Sgblack@eecs.umich.edu * POSSIBILITY OF SUCH DAMAGE.
324997Sgblack@eecs.umich.edu *
334997Sgblack@eecs.umich.edu * Authors: Lisa Hsu
344997Sgblack@eecs.umich.edu */
354997Sgblack@eecs.umich.edu
364997Sgblack@eecs.umich.edu#ifndef __GPU_TLB_HH__
374997Sgblack@eecs.umich.edu#define __GPU_TLB_HH__
384997Sgblack@eecs.umich.edu
394997Sgblack@eecs.umich.edu#include <fstream>
404997Sgblack@eecs.umich.edu#include <list>
414997Sgblack@eecs.umich.edu#include <queue>
424997Sgblack@eecs.umich.edu#include <string>
434997Sgblack@eecs.umich.edu#include <vector>
444997Sgblack@eecs.umich.edu
454997Sgblack@eecs.umich.edu#include "arch/generic/tlb.hh"
464997Sgblack@eecs.umich.edu#include "arch/x86/pagetable.hh"
474997Sgblack@eecs.umich.edu#include "arch/x86/pagetable_walker.hh"
484997Sgblack@eecs.umich.edu#include "arch/x86/regs/segment.hh"
494997Sgblack@eecs.umich.edu#include "base/callback.hh"
504997Sgblack@eecs.umich.edu#include "base/logging.hh"
514997Sgblack@eecs.umich.edu#include "base/statistics.hh"
524997Sgblack@eecs.umich.edu#include "gpu-compute/compute_unit.hh"
534997Sgblack@eecs.umich.edu#include "mem/mem_object.hh"
544997Sgblack@eecs.umich.edu#include "mem/port.hh"
554997Sgblack@eecs.umich.edu#include "mem/request.hh"
564997Sgblack@eecs.umich.edu#include "params/X86GPUTLB.hh"
574997Sgblack@eecs.umich.edu#include "sim/sim_object.hh"
584997Sgblack@eecs.umich.edu
594997Sgblack@eecs.umich.educlass BaseTLB;
605086Sgblack@eecs.umich.educlass Packet;
615086Sgblack@eecs.umich.educlass ThreadContext;
625124Sgblack@eecs.umich.edu
635086Sgblack@eecs.umich.edunamespace X86ISA
645149Sgblack@eecs.umich.edu{
655086Sgblack@eecs.umich.edu    class GpuTLB : public MemObject
665086Sgblack@eecs.umich.edu    {
675237Sgblack@eecs.umich.edu      protected:
685086Sgblack@eecs.umich.edu        friend class Walker;
695086Sgblack@eecs.umich.edu
705086Sgblack@eecs.umich.edu        typedef std::list<TlbEntry*> EntryList;
715086Sgblack@eecs.umich.edu
725245Sgblack@eecs.umich.edu        uint32_t configAddress;
735245Sgblack@eecs.umich.edu
745245Sgblack@eecs.umich.edu        // TLB clock: will inherit clock from shader's clock period in terms
755245Sgblack@eecs.umich.edu        // of nuber of ticks of curTime (aka global simulation clock)
765086Sgblack@eecs.umich.edu        // The assignment of TLB clock from shader clock is done in the python
775086Sgblack@eecs.umich.edu        // config files.
785086Sgblack@eecs.umich.edu        int clock;
795358Sgblack@eecs.umich.edu
805124Sgblack@eecs.umich.edu      public:
815124Sgblack@eecs.umich.edu        // clock related functions ; maps to-and-from Simulation ticks and
825124Sgblack@eecs.umich.edu        // object clocks.
835124Sgblack@eecs.umich.edu        Tick frequency() const { return SimClock::Frequency / clock; }
845124Sgblack@eecs.umich.edu
855124Sgblack@eecs.umich.edu        Tick
865124Sgblack@eecs.umich.edu        ticks(int numCycles) const
875237Sgblack@eecs.umich.edu        {
885245Sgblack@eecs.umich.edu            return (Tick)clock * numCycles;
895245Sgblack@eecs.umich.edu        }
905245Sgblack@eecs.umich.edu
915236Sgblack@eecs.umich.edu        Tick curCycle() const { return curTick() / clock; }
925236Sgblack@eecs.umich.edu        Tick tickToCycles(Tick val) const { return val / clock;}
935236Sgblack@eecs.umich.edu
945124Sgblack@eecs.umich.edu        typedef X86GPUTLBParams Params;
955124Sgblack@eecs.umich.edu        GpuTLB(const Params *p);
965124Sgblack@eecs.umich.edu        ~GpuTLB();
975124Sgblack@eecs.umich.edu
985124Sgblack@eecs.umich.edu        typedef enum BaseTLB::Mode Mode;
995124Sgblack@eecs.umich.edu
1005124Sgblack@eecs.umich.edu        class Translation
1015124Sgblack@eecs.umich.edu        {
1025124Sgblack@eecs.umich.edu          public:
1035124Sgblack@eecs.umich.edu            virtual ~Translation() { }
1045124Sgblack@eecs.umich.edu
1055124Sgblack@eecs.umich.edu            /**
1065124Sgblack@eecs.umich.edu             * Signal that the translation has been delayed due to a hw page
1075124Sgblack@eecs.umich.edu             * table walk.
1085124Sgblack@eecs.umich.edu             */
1095124Sgblack@eecs.umich.edu            virtual void markDelayed() = 0;
1105124Sgblack@eecs.umich.edu
1115360Sgblack@eecs.umich.edu            /**
1125360Sgblack@eecs.umich.edu             * The memory for this object may be dynamically allocated, and it
1135124Sgblack@eecs.umich.edu             * may be responsible for cleaning itslef up which will happen in
1145124Sgblack@eecs.umich.edu             * this function. Once it's called the object is no longer valid.
1155124Sgblack@eecs.umich.edu             */
1165124Sgblack@eecs.umich.edu            virtual void finish(Fault fault, RequestPtr req, ThreadContext *tc,
1175124Sgblack@eecs.umich.edu                    Mode mode) = 0;
1185124Sgblack@eecs.umich.edu        };
1195124Sgblack@eecs.umich.edu
1205124Sgblack@eecs.umich.edu        void dumpAll();
1215360Sgblack@eecs.umich.edu        TlbEntry *lookup(Addr va, bool update_lru=true);
1225124Sgblack@eecs.umich.edu        void setConfigAddress(uint32_t addr);
1235360Sgblack@eecs.umich.edu
1245124Sgblack@eecs.umich.edu      protected:
1255360Sgblack@eecs.umich.edu        EntryList::iterator lookupIt(Addr va, bool update_lru=true);
1265124Sgblack@eecs.umich.edu        Walker *walker;
1275124Sgblack@eecs.umich.edu
1285360Sgblack@eecs.umich.edu      public:
1295360Sgblack@eecs.umich.edu        Walker *getWalker();
1305360Sgblack@eecs.umich.edu        void invalidateAll();
1315360Sgblack@eecs.umich.edu        void invalidateNonGlobal();
1325360Sgblack@eecs.umich.edu        void demapPage(Addr va, uint64_t asn);
1335360Sgblack@eecs.umich.edu
1345360Sgblack@eecs.umich.edu      protected:
1355360Sgblack@eecs.umich.edu        int size;
1365360Sgblack@eecs.umich.edu        int assoc;
1375360Sgblack@eecs.umich.edu        int numSets;
1385360Sgblack@eecs.umich.edu
1395124Sgblack@eecs.umich.edu        /**
1405124Sgblack@eecs.umich.edu         *  true if this is a fully-associative TLB
1415245Sgblack@eecs.umich.edu         */
1425245Sgblack@eecs.umich.edu        bool FA;
1435245Sgblack@eecs.umich.edu        Addr setMask;
1445245Sgblack@eecs.umich.edu
1455245Sgblack@eecs.umich.edu        /**
1465245Sgblack@eecs.umich.edu         * Allocation Policy: true if we always allocate on a hit, false
1475245Sgblack@eecs.umich.edu         * otherwise. Default is true.
1485245Sgblack@eecs.umich.edu         */
1495124Sgblack@eecs.umich.edu        bool allocationPolicy;
1505124Sgblack@eecs.umich.edu
1515124Sgblack@eecs.umich.edu        /**
1525242Sgblack@eecs.umich.edu         * if true, then this is not the last level TLB
1535242Sgblack@eecs.umich.edu         */
1545242Sgblack@eecs.umich.edu        bool hasMemSidePort;
1555242Sgblack@eecs.umich.edu
1565242Sgblack@eecs.umich.edu        /**
1575242Sgblack@eecs.umich.edu         * Print out accessDistance stats. One stat file
1585124Sgblack@eecs.umich.edu         * per TLB.
1595124Sgblack@eecs.umich.edu         */
1605124Sgblack@eecs.umich.edu        bool accessDistance;
1615357Sgblack@eecs.umich.edu
1625357Sgblack@eecs.umich.edu        std::vector<TlbEntry> tlb;
1635357Sgblack@eecs.umich.edu
1645357Sgblack@eecs.umich.edu        /*
1655357Sgblack@eecs.umich.edu         * It's a per-set list. As long as we have not reached
1665357Sgblack@eecs.umich.edu         * the full capacity of the given set, grab an entry from
1675124Sgblack@eecs.umich.edu         * the freeList.
1685124Sgblack@eecs.umich.edu         */
1695242Sgblack@eecs.umich.edu        std::vector<EntryList> freeList;
1705242Sgblack@eecs.umich.edu
1715242Sgblack@eecs.umich.edu        /**
1725242Sgblack@eecs.umich.edu         * An entryList per set is the equivalent of an LRU stack;
1735242Sgblack@eecs.umich.edu         * it's used to guide replacement decisions. The head of the list
1745242Sgblack@eecs.umich.edu         * contains the MRU TLB entry of the given set. If the freeList
1755242Sgblack@eecs.umich.edu         * for this set is empty, the last element of the list
1765242Sgblack@eecs.umich.edu         * is evicted (i.e., dropped on the floor).
1775242Sgblack@eecs.umich.edu         */
1785242Sgblack@eecs.umich.edu        std::vector<EntryList> entryList;
1795124Sgblack@eecs.umich.edu
1805124Sgblack@eecs.umich.edu        Fault translateInt(RequestPtr req, ThreadContext *tc);
1815124Sgblack@eecs.umich.edu
1825358Sgblack@eecs.umich.edu        Fault translate(RequestPtr req, ThreadContext *tc,
1835086Sgblack@eecs.umich.edu                Translation *translation, Mode mode, bool &delayedResponse,
1845359Sgblack@eecs.umich.edu                bool timing, int &latency);
1855359Sgblack@eecs.umich.edu
1865359Sgblack@eecs.umich.edu      public:
1875359Sgblack@eecs.umich.edu        // latencies for a TLB hit, miss and page fault
1885359Sgblack@eecs.umich.edu        int hitLatency;
1895086Sgblack@eecs.umich.edu        int missLatency1;
1905086Sgblack@eecs.umich.edu        int missLatency2;
1915140Sgblack@eecs.umich.edu
1925086Sgblack@eecs.umich.edu        // local_stats are as seen from the TLB
1935140Sgblack@eecs.umich.edu        // without taking into account coalescing
1945086Sgblack@eecs.umich.edu        Stats::Scalar localNumTLBAccesses;
1955124Sgblack@eecs.umich.edu        Stats::Scalar localNumTLBHits;
1965140Sgblack@eecs.umich.edu        Stats::Scalar localNumTLBMisses;
1975124Sgblack@eecs.umich.edu        Stats::Formula localTLBMissRate;
1985124Sgblack@eecs.umich.edu
1995140Sgblack@eecs.umich.edu        // global_stats are as seen from the
2005294Sgblack@eecs.umich.edu        // CU's perspective taking into account
2015124Sgblack@eecs.umich.edu        // all coalesced requests.
2025124Sgblack@eecs.umich.edu        Stats::Scalar globalNumTLBAccesses;
2035149Sgblack@eecs.umich.edu        Stats::Scalar globalNumTLBHits;
2045149Sgblack@eecs.umich.edu        Stats::Scalar globalNumTLBMisses;
2055149Sgblack@eecs.umich.edu        Stats::Formula globalTLBMissRate;
2065149Sgblack@eecs.umich.edu
2075294Sgblack@eecs.umich.edu        // from the CU perspective (global)
2085243Sgblack@eecs.umich.edu        Stats::Scalar accessCycles;
2095418Sgblack@eecs.umich.edu        // from the CU perspective (global)
2105149Sgblack@eecs.umich.edu        Stats::Scalar pageTableCycles;
2115149Sgblack@eecs.umich.edu        Stats::Scalar numUniquePages;
2125149Sgblack@eecs.umich.edu        // from the perspective of this TLB
2135418Sgblack@eecs.umich.edu        Stats::Scalar localCycles;
2145149Sgblack@eecs.umich.edu        // from the perspective of this TLB
2155149Sgblack@eecs.umich.edu        Stats::Formula localLatency;
2165149Sgblack@eecs.umich.edu        // I take the avg. per page and then
2175149Sgblack@eecs.umich.edu        // the avg. over all pages.
2185149Sgblack@eecs.umich.edu        Stats::Scalar avgReuseDistance;
2195149Sgblack@eecs.umich.edu
2205360Sgblack@eecs.umich.edu        void regStats();
2215360Sgblack@eecs.umich.edu        void updatePageFootprint(Addr virt_page_addr);
2225360Sgblack@eecs.umich.edu        void printAccessPattern();
2235149Sgblack@eecs.umich.edu
2245149Sgblack@eecs.umich.edu
2255149Sgblack@eecs.umich.edu        Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode,
2265149Sgblack@eecs.umich.edu                              int &latency);
2275149Sgblack@eecs.umich.edu
2285149Sgblack@eecs.umich.edu        void translateTiming(RequestPtr req, ThreadContext *tc,
2295149Sgblack@eecs.umich.edu                             Translation *translation, Mode mode,
2305149Sgblack@eecs.umich.edu                             int &latency);
2315149Sgblack@eecs.umich.edu
2325149Sgblack@eecs.umich.edu        Tick doMmuRegRead(ThreadContext *tc, Packet *pkt);
2335149Sgblack@eecs.umich.edu        Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt);
2345149Sgblack@eecs.umich.edu
2355149Sgblack@eecs.umich.edu        TlbEntry *insert(Addr vpn, TlbEntry &entry);
2365149Sgblack@eecs.umich.edu
2375149Sgblack@eecs.umich.edu        // Checkpointing
2385149Sgblack@eecs.umich.edu        virtual void serialize(CheckpointOut& cp) const;
2395149Sgblack@eecs.umich.edu        virtual void unserialize(CheckpointIn& cp);
2405149Sgblack@eecs.umich.edu        void issueTranslation();
2415149Sgblack@eecs.umich.edu        enum tlbOutcome {TLB_HIT, TLB_MISS, PAGE_WALK, MISS_RETURN};
2425149Sgblack@eecs.umich.edu        bool tlbLookup(RequestPtr req, ThreadContext *tc, bool update_stats);
2435149Sgblack@eecs.umich.edu
2445149Sgblack@eecs.umich.edu        void handleTranslationReturn(Addr addr, tlbOutcome outcome,
2455149Sgblack@eecs.umich.edu                                     PacketPtr pkt);
2465149Sgblack@eecs.umich.edu
2475149Sgblack@eecs.umich.edu        void handleFuncTranslationReturn(PacketPtr pkt, tlbOutcome outcome);
2485149Sgblack@eecs.umich.edu
2495149Sgblack@eecs.umich.edu        void pagingProtectionChecks(ThreadContext *tc, PacketPtr pkt,
2505149Sgblack@eecs.umich.edu                                    TlbEntry *tlb_entry, Mode mode);
2515149Sgblack@eecs.umich.edu
2525149Sgblack@eecs.umich.edu        void updatePhysAddresses(Addr virt_page_addr, TlbEntry *tlb_entry,
2535149Sgblack@eecs.umich.edu                                 Addr phys_page_addr);
2545149Sgblack@eecs.umich.edu
2555149Sgblack@eecs.umich.edu        void issueTLBLookup(PacketPtr pkt);
2565149Sgblack@eecs.umich.edu
2575149Sgblack@eecs.umich.edu        // CpuSidePort is the TLB Port closer to the CPU/CU side
2585149Sgblack@eecs.umich.edu        class CpuSidePort : public SlavePort
2595149Sgblack@eecs.umich.edu        {
2605149Sgblack@eecs.umich.edu          public:
2615149Sgblack@eecs.umich.edu            CpuSidePort(const std::string &_name, GpuTLB * gpu_TLB,
2625149Sgblack@eecs.umich.edu                        PortID _index)
2635149Sgblack@eecs.umich.edu                : SlavePort(_name, gpu_TLB), tlb(gpu_TLB), index(_index) { }
2645149Sgblack@eecs.umich.edu
2655149Sgblack@eecs.umich.edu          protected:
2665149Sgblack@eecs.umich.edu            GpuTLB *tlb;
2675149Sgblack@eecs.umich.edu            int index;
2685149Sgblack@eecs.umich.edu
2695149Sgblack@eecs.umich.edu            virtual bool recvTimingReq(PacketPtr pkt);
2705149Sgblack@eecs.umich.edu            virtual Tick recvAtomic(PacketPtr pkt) { return 0; }
2715149Sgblack@eecs.umich.edu            virtual void recvFunctional(PacketPtr pkt);
2725149Sgblack@eecs.umich.edu            virtual void recvRangeChange() { }
2735149Sgblack@eecs.umich.edu            virtual void recvReqRetry();
2745149Sgblack@eecs.umich.edu            virtual void recvRespRetry() { assert(false); }
2755149Sgblack@eecs.umich.edu            virtual AddrRangeList getAddrRanges() const;
2765149Sgblack@eecs.umich.edu        };
2775149Sgblack@eecs.umich.edu
2785149Sgblack@eecs.umich.edu        /**
2795149Sgblack@eecs.umich.edu         * MemSidePort is the TLB Port closer to the memory side
2805149Sgblack@eecs.umich.edu         * If this is a last level TLB then this port will not be connected.
2815149Sgblack@eecs.umich.edu         *
2825149Sgblack@eecs.umich.edu         * Future action item: if we ever do real page walks, then this port
2835149Sgblack@eecs.umich.edu         * should be connected to a RubyPort.
2845149Sgblack@eecs.umich.edu         */
2855149Sgblack@eecs.umich.edu        class MemSidePort : public MasterPort
2865149Sgblack@eecs.umich.edu        {
2875149Sgblack@eecs.umich.edu          public:
2885149Sgblack@eecs.umich.edu            MemSidePort(const std::string &_name, GpuTLB * gpu_TLB,
2895149Sgblack@eecs.umich.edu                        PortID _index)
2905149Sgblack@eecs.umich.edu                : MasterPort(_name, gpu_TLB), tlb(gpu_TLB), index(_index) { }
2915149Sgblack@eecs.umich.edu
2925149Sgblack@eecs.umich.edu            std::deque<PacketPtr> retries;
2935149Sgblack@eecs.umich.edu
2945149Sgblack@eecs.umich.edu          protected:
2955149Sgblack@eecs.umich.edu            GpuTLB *tlb;
2965149Sgblack@eecs.umich.edu            int index;
2975149Sgblack@eecs.umich.edu
2985149Sgblack@eecs.umich.edu            virtual bool recvTimingResp(PacketPtr pkt);
2995149Sgblack@eecs.umich.edu            virtual Tick recvAtomic(PacketPtr pkt) { return 0; }
3005149Sgblack@eecs.umich.edu            virtual void recvFunctional(PacketPtr pkt) { }
3015149Sgblack@eecs.umich.edu            virtual void recvRangeChange() { }
3025149Sgblack@eecs.umich.edu            virtual void recvReqRetry();
3035149Sgblack@eecs.umich.edu        };
3045149Sgblack@eecs.umich.edu
3055149Sgblack@eecs.umich.edu        // TLB ports on the cpu Side
3065149Sgblack@eecs.umich.edu        std::vector<CpuSidePort*> cpuSidePort;
3075149Sgblack@eecs.umich.edu        // TLB ports on the memory side
3085149Sgblack@eecs.umich.edu        std::vector<MemSidePort*> memSidePort;
3095149Sgblack@eecs.umich.edu
3105149Sgblack@eecs.umich.edu        BaseMasterPort &getMasterPort(const std::string &if_name,
3115149Sgblack@eecs.umich.edu                                      PortID idx=InvalidPortID);
3125149Sgblack@eecs.umich.edu
3135149Sgblack@eecs.umich.edu        BaseSlavePort &getSlavePort(const std::string &if_name,
3145149Sgblack@eecs.umich.edu                                    PortID idx=InvalidPortID);
3155149Sgblack@eecs.umich.edu
3165149Sgblack@eecs.umich.edu        /**
3175149Sgblack@eecs.umich.edu         * TLB TranslationState: this currently is a somewhat bastardization of
3185149Sgblack@eecs.umich.edu         * the usage of SenderState, whereby the receiver of a packet is not
3195149Sgblack@eecs.umich.edu         * usually supposed to need to look at the contents of the senderState,
3205149Sgblack@eecs.umich.edu         * you're really only supposed to look at what you pushed on, pop it
3215149Sgblack@eecs.umich.edu         * off, and send it back.
3225149Sgblack@eecs.umich.edu         *
3235149Sgblack@eecs.umich.edu         * However, since there is state that we want to pass to the TLBs using
3245149Sgblack@eecs.umich.edu         * the send/recv Timing/Functional/etc. APIs, which don't allow for new
3255149Sgblack@eecs.umich.edu         * arguments, we need a common TLB senderState to pass between TLBs,
3265149Sgblack@eecs.umich.edu         * both "forwards" and "backwards."
3275149Sgblack@eecs.umich.edu         *
3285149Sgblack@eecs.umich.edu         * So, basically, the rule is that any packet received by a TLB port
3295149Sgblack@eecs.umich.edu         * (cpuside OR memside) must be safely castable to a TranslationState.
3305149Sgblack@eecs.umich.edu         */
3315149Sgblack@eecs.umich.edu
3325149Sgblack@eecs.umich.edu        struct TranslationState : public Packet::SenderState
3335149Sgblack@eecs.umich.edu        {
3345149Sgblack@eecs.umich.edu            // TLB mode, read or write
3355149Sgblack@eecs.umich.edu            Mode tlbMode;
3365149Sgblack@eecs.umich.edu            // Thread context associated with this req
3375149Sgblack@eecs.umich.edu            ThreadContext *tc;
3385149Sgblack@eecs.umich.edu
3395149Sgblack@eecs.umich.edu            /*
3405149Sgblack@eecs.umich.edu            * TLB entry to be populated and passed back and filled in
3415149Sgblack@eecs.umich.edu            * previous TLBs.  Equivalent to the data cache concept of
3425149Sgblack@eecs.umich.edu            * "data return."
3435149Sgblack@eecs.umich.edu            */
3445149Sgblack@eecs.umich.edu            TlbEntry *tlbEntry;
3455149Sgblack@eecs.umich.edu            // Is this a TLB prefetch request?
3465149Sgblack@eecs.umich.edu            bool prefetch;
3475149Sgblack@eecs.umich.edu            // When was the req for this translation issued
3485149Sgblack@eecs.umich.edu            uint64_t issueTime;
3495149Sgblack@eecs.umich.edu            // Remember where this came from
3505149Sgblack@eecs.umich.edu            std::vector<SlavePort*>ports;
3515149Sgblack@eecs.umich.edu
3525149Sgblack@eecs.umich.edu            // keep track of #uncoalesced reqs per packet per TLB level;
3535149Sgblack@eecs.umich.edu            // reqCnt per level >= reqCnt higher level
3545149Sgblack@eecs.umich.edu            std::vector<int> reqCnt;
3555149Sgblack@eecs.umich.edu            // TLB level this packet hit in; 0 if it hit in the page table
3565149Sgblack@eecs.umich.edu            int hitLevel;
3575149Sgblack@eecs.umich.edu            Packet::SenderState *saved;
3585149Sgblack@eecs.umich.edu
3595149Sgblack@eecs.umich.edu            TranslationState(Mode tlb_mode, ThreadContext *_tc,
3605149Sgblack@eecs.umich.edu                             bool _prefetch=false,
3615419Sgblack@eecs.umich.edu                             Packet::SenderState *_saved=nullptr)
3625419Sgblack@eecs.umich.edu                : tlbMode(tlb_mode), tc(_tc), tlbEntry(nullptr),
3635419Sgblack@eecs.umich.edu                  prefetch(_prefetch), issueTime(0),
3645419Sgblack@eecs.umich.edu                  hitLevel(0),saved(_saved) { }
3655419Sgblack@eecs.umich.edu        };
3665419Sgblack@eecs.umich.edu
3675419Sgblack@eecs.umich.edu        // maximum number of permitted coalesced requests per cycle
3685419Sgblack@eecs.umich.edu        int maxCoalescedReqs;
3695419Sgblack@eecs.umich.edu
3705149Sgblack@eecs.umich.edu        // Current number of outstandings coalesced requests.
3715149Sgblack@eecs.umich.edu        // Should be <= maxCoalescedReqs
3725149Sgblack@eecs.umich.edu        int outstandingReqs;
3735149Sgblack@eecs.umich.edu
3745149Sgblack@eecs.umich.edu        /**
3755149Sgblack@eecs.umich.edu         * A TLBEvent is scheduled after the TLB lookup and helps us take the
3765149Sgblack@eecs.umich.edu         * appropriate actions:
3775149Sgblack@eecs.umich.edu         *  (e.g., update TLB on a hit,
3785149Sgblack@eecs.umich.edu         *  send request to lower level TLB on a miss,
3795149Sgblack@eecs.umich.edu         *  or start a page walk if this was the last-level TLB).
3805149Sgblack@eecs.umich.edu         */
3815149Sgblack@eecs.umich.edu        void translationReturn(Addr virtPageAddr, tlbOutcome outcome,
3825149Sgblack@eecs.umich.edu                               PacketPtr pkt);
3835149Sgblack@eecs.umich.edu
3845149Sgblack@eecs.umich.edu        class TLBEvent : public Event
3855419Sgblack@eecs.umich.edu        {
3865419Sgblack@eecs.umich.edu            private:
3875419Sgblack@eecs.umich.edu                GpuTLB *tlb;
3885419Sgblack@eecs.umich.edu                Addr virtPageAddr;
3895419Sgblack@eecs.umich.edu                /**
3905419Sgblack@eecs.umich.edu                 * outcome can be TLB_HIT, TLB_MISS, or PAGE_WALK
3915419Sgblack@eecs.umich.edu                 */
3925419Sgblack@eecs.umich.edu                tlbOutcome outcome;
3935419Sgblack@eecs.umich.edu                PacketPtr pkt;
3945149Sgblack@eecs.umich.edu
3955149Sgblack@eecs.umich.edu            public:
3965149Sgblack@eecs.umich.edu                TLBEvent(GpuTLB *_tlb, Addr _addr, tlbOutcome outcome,
3975149Sgblack@eecs.umich.edu                        PacketPtr _pkt);
3985149Sgblack@eecs.umich.edu
3995149Sgblack@eecs.umich.edu                void process();
4005149Sgblack@eecs.umich.edu                const char *description() const;
4015149Sgblack@eecs.umich.edu
4025149Sgblack@eecs.umich.edu                // updateOutcome updates the tlbOutcome of a TLBEvent
4035149Sgblack@eecs.umich.edu                void updateOutcome(tlbOutcome _outcome);
4045149Sgblack@eecs.umich.edu                Addr getTLBEventVaddr();
4055149Sgblack@eecs.umich.edu        };
4065149Sgblack@eecs.umich.edu
4075149Sgblack@eecs.umich.edu        std::unordered_map<Addr, TLBEvent*> translationReturnEvent;
4085149Sgblack@eecs.umich.edu
4095419Sgblack@eecs.umich.edu        // this FIFO queue keeps track of the virt. page addresses
4105419Sgblack@eecs.umich.edu        // that are pending cleanup
4115419Sgblack@eecs.umich.edu        std::queue<Addr> cleanupQueue;
4125419Sgblack@eecs.umich.edu
4135419Sgblack@eecs.umich.edu        // the cleanupEvent is scheduled after a TLBEvent triggers in order to
4145419Sgblack@eecs.umich.edu        // free memory and do the required clean-up
4155419Sgblack@eecs.umich.edu        void cleanup();
4165419Sgblack@eecs.umich.edu
4175419Sgblack@eecs.umich.edu        EventFunctionWrapper cleanupEvent;
4185149Sgblack@eecs.umich.edu
4195149Sgblack@eecs.umich.edu        /**
4205149Sgblack@eecs.umich.edu         * This hash map will use the virtual page address as a key
4215149Sgblack@eecs.umich.edu         * and will keep track of total number of accesses per page
4225149Sgblack@eecs.umich.edu         */
4235149Sgblack@eecs.umich.edu
4245149Sgblack@eecs.umich.edu        struct AccessInfo
4255149Sgblack@eecs.umich.edu        {
4265149Sgblack@eecs.umich.edu            unsigned int lastTimeAccessed; // last access to this page
4275149Sgblack@eecs.umich.edu            unsigned int accessesPerPage;
4285149Sgblack@eecs.umich.edu            // need to divide it by accessesPerPage at the end
4295149Sgblack@eecs.umich.edu            unsigned int totalReuseDistance;
4305149Sgblack@eecs.umich.edu
4315149Sgblack@eecs.umich.edu            /**
4325149Sgblack@eecs.umich.edu             * The field below will help us compute the access distance,
4335419Sgblack@eecs.umich.edu             * that is the number of (coalesced) TLB accesses that
4345419Sgblack@eecs.umich.edu             * happened in between each access to this page
4355419Sgblack@eecs.umich.edu             *
4365419Sgblack@eecs.umich.edu             * localTLBAccesses[x] is the value of localTLBNumAccesses
4375419Sgblack@eecs.umich.edu             * when the page <Addr> was accessed for the <x>th time
4385419Sgblack@eecs.umich.edu             */
4395419Sgblack@eecs.umich.edu            std::vector<unsigned int> localTLBAccesses;
4405419Sgblack@eecs.umich.edu            unsigned int sumDistance;
4415419Sgblack@eecs.umich.edu            unsigned int meanDistance;
4425149Sgblack@eecs.umich.edu        };
4435149Sgblack@eecs.umich.edu
4445149Sgblack@eecs.umich.edu        typedef std::unordered_map<Addr, AccessInfo> AccessPatternTable;
4455149Sgblack@eecs.umich.edu        AccessPatternTable TLBFootprint;
4465149Sgblack@eecs.umich.edu
4475149Sgblack@eecs.umich.edu        // Called at the end of simulation to dump page access stats.
4485149Sgblack@eecs.umich.edu        void exitCallback();
4495149Sgblack@eecs.umich.edu
4505149Sgblack@eecs.umich.edu        EventFunctionWrapper exitEvent;
4515149Sgblack@eecs.umich.edu    };
4525149Sgblack@eecs.umich.edu}
4535149Sgblack@eecs.umich.edu
4545149Sgblack@eecs.umich.edu#endif // __GPU_TLB_HH__
4555149Sgblack@eecs.umich.edu