gpu_tlb.hh revision 12334
112855Sgabeblack@google.com/*
212855Sgabeblack@google.com * Copyright (c) 2011-2015 Advanced Micro Devices, Inc.
312855Sgabeblack@google.com * All rights reserved.
412855Sgabeblack@google.com *
512855Sgabeblack@google.com * For use for simulation and test purposes only
612855Sgabeblack@google.com *
712855Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
812855Sgabeblack@google.com * modification, are permitted provided that the following conditions are met:
912855Sgabeblack@google.com *
1012855Sgabeblack@google.com * 1. Redistributions of source code must retain the above copyright notice,
1112855Sgabeblack@google.com * this list of conditions and the following disclaimer.
1212855Sgabeblack@google.com *
1312855Sgabeblack@google.com * 2. Redistributions in binary form must reproduce the above copyright notice,
1412855Sgabeblack@google.com * this list of conditions and the following disclaimer in the documentation
1512855Sgabeblack@google.com * and/or other materials provided with the distribution.
1612855Sgabeblack@google.com *
1712855Sgabeblack@google.com * 3. Neither the name of the copyright holder nor the names of its contributors
1812855Sgabeblack@google.com * may be used to endorse or promote products derived from this software
1912855Sgabeblack@google.com * without specific prior written permission.
2012855Sgabeblack@google.com *
2112855Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2212855Sgabeblack@google.com * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2312855Sgabeblack@google.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2412855Sgabeblack@google.com * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
2512855Sgabeblack@google.com * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2612855Sgabeblack@google.com * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2712855Sgabeblack@google.com * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2812855Sgabeblack@google.com * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2912855Sgabeblack@google.com * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3012855Sgabeblack@google.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3112855Sgabeblack@google.com * POSSIBILITY OF SUCH DAMAGE.
3212855Sgabeblack@google.com *
3312855Sgabeblack@google.com * Author: Lisa Hsu
3412855Sgabeblack@google.com */
3512855Sgabeblack@google.com
3612855Sgabeblack@google.com#ifndef __GPU_TLB_HH__
3712855Sgabeblack@google.com#define __GPU_TLB_HH__
3812855Sgabeblack@google.com
3912855Sgabeblack@google.com#include <fstream>
4012855Sgabeblack@google.com#include <list>
4112855Sgabeblack@google.com#include <queue>
4212855Sgabeblack@google.com#include <string>
4312855Sgabeblack@google.com#include <vector>
4412855Sgabeblack@google.com
4512855Sgabeblack@google.com#include "arch/generic/tlb.hh"
4612855Sgabeblack@google.com#include "arch/x86/pagetable.hh"
4712855Sgabeblack@google.com#include "arch/x86/pagetable_walker.hh"
4812855Sgabeblack@google.com#include "arch/x86/regs/segment.hh"
4912855Sgabeblack@google.com#include "base/callback.hh"
5012855Sgabeblack@google.com#include "base/logging.hh"
5112855Sgabeblack@google.com#include "base/statistics.hh"
5212855Sgabeblack@google.com#include "gpu-compute/compute_unit.hh"
5312855Sgabeblack@google.com#include "mem/mem_object.hh"
5412855Sgabeblack@google.com#include "mem/port.hh"
5512855Sgabeblack@google.com#include "mem/request.hh"
5612855Sgabeblack@google.com#include "params/X86GPUTLB.hh"
5712855Sgabeblack@google.com#include "sim/sim_object.hh"
5812855Sgabeblack@google.com
5912855Sgabeblack@google.comclass BaseTLB;
6012855Sgabeblack@google.comclass Packet;
6112855Sgabeblack@google.comclass ThreadContext;
6212855Sgabeblack@google.com
6312855Sgabeblack@google.comnamespace X86ISA
6412855Sgabeblack@google.com{
6512855Sgabeblack@google.com    class GpuTlbEntry : public TlbEntry
6612855Sgabeblack@google.com    {
6712855Sgabeblack@google.com      public:
6812855Sgabeblack@google.com        GpuTlbEntry(Addr asn, Addr _vaddr, Addr _paddr, bool _valid)
6912855Sgabeblack@google.com          : TlbEntry(asn, _vaddr, _paddr, false, false), valid(_valid) { }
7012855Sgabeblack@google.com
7112855Sgabeblack@google.com        GpuTlbEntry() : TlbEntry(), valid(false) { }
7212855Sgabeblack@google.com
7312855Sgabeblack@google.com        bool valid;
7412855Sgabeblack@google.com    };
7512855Sgabeblack@google.com
7612855Sgabeblack@google.com    class GpuTLB : public MemObject
7712855Sgabeblack@google.com    {
7812855Sgabeblack@google.com      protected:
7912855Sgabeblack@google.com        friend class Walker;
8012855Sgabeblack@google.com
8112855Sgabeblack@google.com        typedef std::list<GpuTlbEntry*> EntryList;
8212855Sgabeblack@google.com
8312855Sgabeblack@google.com        uint32_t configAddress;
8412855Sgabeblack@google.com
8512855Sgabeblack@google.com        // TLB clock: will inherit clock from shader's clock period in terms
8612855Sgabeblack@google.com        // of nuber of ticks of curTime (aka global simulation clock)
8712855Sgabeblack@google.com        // The assignment of TLB clock from shader clock is done in the python
8812855Sgabeblack@google.com        // config files.
8912855Sgabeblack@google.com        int clock;
9012855Sgabeblack@google.com
9112855Sgabeblack@google.com      public:
9212855Sgabeblack@google.com        // clock related functions ; maps to-and-from Simulation ticks and
9312855Sgabeblack@google.com        // object clocks.
9412855Sgabeblack@google.com        Tick frequency() const { return SimClock::Frequency / clock; }
9512855Sgabeblack@google.com
9612855Sgabeblack@google.com        Tick
9712855Sgabeblack@google.com        ticks(int numCycles) const
9812855Sgabeblack@google.com        {
9912855Sgabeblack@google.com            return (Tick)clock * numCycles;
10012855Sgabeblack@google.com        }
10112855Sgabeblack@google.com
10212855Sgabeblack@google.com        Tick curCycle() const { return curTick() / clock; }
10312855Sgabeblack@google.com        Tick tickToCycles(Tick val) const { return val / clock;}
10412855Sgabeblack@google.com
10512855Sgabeblack@google.com        typedef X86GPUTLBParams Params;
10612855Sgabeblack@google.com        GpuTLB(const Params *p);
10712855Sgabeblack@google.com        ~GpuTLB();
10812855Sgabeblack@google.com
10912855Sgabeblack@google.com        typedef enum BaseTLB::Mode Mode;
11012855Sgabeblack@google.com
11112855Sgabeblack@google.com        class Translation
11212855Sgabeblack@google.com        {
11312855Sgabeblack@google.com          public:
11412855Sgabeblack@google.com            virtual ~Translation() { }
11512855Sgabeblack@google.com
11612855Sgabeblack@google.com            /**
11712855Sgabeblack@google.com             * Signal that the translation has been delayed due to a hw page
11812855Sgabeblack@google.com             * table walk.
11912855Sgabeblack@google.com             */
12012855Sgabeblack@google.com            virtual void markDelayed() = 0;
12112855Sgabeblack@google.com
12212855Sgabeblack@google.com            /**
12312855Sgabeblack@google.com             * The memory for this object may be dynamically allocated, and it
12412855Sgabeblack@google.com             * may be responsible for cleaning itslef up which will happen in
12512855Sgabeblack@google.com             * this function. Once it's called the object is no longer valid.
12612855Sgabeblack@google.com             */
12712855Sgabeblack@google.com            virtual void finish(Fault fault, RequestPtr req, ThreadContext *tc,
12812855Sgabeblack@google.com                    Mode mode) = 0;
12912855Sgabeblack@google.com        };
13012855Sgabeblack@google.com
13112855Sgabeblack@google.com        void dumpAll();
13212855Sgabeblack@google.com        GpuTlbEntry *lookup(Addr va, bool update_lru=true);
13312855Sgabeblack@google.com        void setConfigAddress(uint32_t addr);
13412855Sgabeblack@google.com
13512855Sgabeblack@google.com      protected:
13612855Sgabeblack@google.com        EntryList::iterator lookupIt(Addr va, bool update_lru=true);
13712855Sgabeblack@google.com        Walker *walker;
13812855Sgabeblack@google.com
13912855Sgabeblack@google.com      public:
14012855Sgabeblack@google.com        Walker *getWalker();
14112855Sgabeblack@google.com        void invalidateAll();
14212855Sgabeblack@google.com        void invalidateNonGlobal();
14312855Sgabeblack@google.com        void demapPage(Addr va, uint64_t asn);
14412855Sgabeblack@google.com
14512855Sgabeblack@google.com      protected:
14612855Sgabeblack@google.com        int size;
14712855Sgabeblack@google.com        int assoc;
14812855Sgabeblack@google.com        int numSets;
14912855Sgabeblack@google.com
15012855Sgabeblack@google.com        /**
15112855Sgabeblack@google.com         *  true if this is a fully-associative TLB
15212855Sgabeblack@google.com         */
15312855Sgabeblack@google.com        bool FA;
15412855Sgabeblack@google.com        Addr setMask;
15512855Sgabeblack@google.com
15612855Sgabeblack@google.com        /**
15712855Sgabeblack@google.com         * Allocation Policy: true if we always allocate on a hit, false
15812855Sgabeblack@google.com         * otherwise. Default is true.
15912855Sgabeblack@google.com         */
16012855Sgabeblack@google.com        bool allocationPolicy;
16112855Sgabeblack@google.com
16212855Sgabeblack@google.com        /**
16312855Sgabeblack@google.com         * if true, then this is not the last level TLB
16412855Sgabeblack@google.com         */
16512855Sgabeblack@google.com        bool hasMemSidePort;
16612855Sgabeblack@google.com
16712855Sgabeblack@google.com        /**
16812855Sgabeblack@google.com         * Print out accessDistance stats. One stat file
16912855Sgabeblack@google.com         * per TLB.
17012855Sgabeblack@google.com         */
17112855Sgabeblack@google.com        bool accessDistance;
17212855Sgabeblack@google.com
17312855Sgabeblack@google.com        std::vector<GpuTlbEntry> tlb;
17412855Sgabeblack@google.com
17512855Sgabeblack@google.com        /*
17612855Sgabeblack@google.com         * It's a per-set list. As long as we have not reached
17712855Sgabeblack@google.com         * the full capacity of the given set, grab an entry from
17812855Sgabeblack@google.com         * the freeList.
17912855Sgabeblack@google.com         */
18012855Sgabeblack@google.com        std::vector<EntryList> freeList;
18112855Sgabeblack@google.com
18212855Sgabeblack@google.com        /**
18312855Sgabeblack@google.com         * An entryList per set is the equivalent of an LRU stack;
18412855Sgabeblack@google.com         * it's used to guide replacement decisions. The head of the list
18512855Sgabeblack@google.com         * contains the MRU TLB entry of the given set. If the freeList
18612855Sgabeblack@google.com         * for this set is empty, the last element of the list
18712855Sgabeblack@google.com         * is evicted (i.e., dropped on the floor).
18812855Sgabeblack@google.com         */
18912855Sgabeblack@google.com        std::vector<EntryList> entryList;
19012855Sgabeblack@google.com
19112855Sgabeblack@google.com        Fault translateInt(RequestPtr req, ThreadContext *tc);
19212855Sgabeblack@google.com
19312855Sgabeblack@google.com        Fault translate(RequestPtr req, ThreadContext *tc,
19412855Sgabeblack@google.com                Translation *translation, Mode mode, bool &delayedResponse,
19512855Sgabeblack@google.com                bool timing, int &latency);
19612855Sgabeblack@google.com
19712855Sgabeblack@google.com      public:
19812855Sgabeblack@google.com        // latencies for a TLB hit, miss and page fault
19912855Sgabeblack@google.com        int hitLatency;
20012855Sgabeblack@google.com        int missLatency1;
20112855Sgabeblack@google.com        int missLatency2;
20212855Sgabeblack@google.com
20312855Sgabeblack@google.com        // local_stats are as seen from the TLB
20412855Sgabeblack@google.com        // without taking into account coalescing
20512855Sgabeblack@google.com        Stats::Scalar localNumTLBAccesses;
20612855Sgabeblack@google.com        Stats::Scalar localNumTLBHits;
20712855Sgabeblack@google.com        Stats::Scalar localNumTLBMisses;
20812855Sgabeblack@google.com        Stats::Formula localTLBMissRate;
20912855Sgabeblack@google.com
21012855Sgabeblack@google.com        // global_stats are as seen from the
21112855Sgabeblack@google.com        // CU's perspective taking into account
21212855Sgabeblack@google.com        // all coalesced requests.
21312855Sgabeblack@google.com        Stats::Scalar globalNumTLBAccesses;
21412855Sgabeblack@google.com        Stats::Scalar globalNumTLBHits;
21512855Sgabeblack@google.com        Stats::Scalar globalNumTLBMisses;
21612855Sgabeblack@google.com        Stats::Formula globalTLBMissRate;
21712855Sgabeblack@google.com
21812855Sgabeblack@google.com        // from the CU perspective (global)
21912855Sgabeblack@google.com        Stats::Scalar accessCycles;
22012855Sgabeblack@google.com        // from the CU perspective (global)
22112855Sgabeblack@google.com        Stats::Scalar pageTableCycles;
22212855Sgabeblack@google.com        Stats::Scalar numUniquePages;
22312855Sgabeblack@google.com        // from the perspective of this TLB
22412855Sgabeblack@google.com        Stats::Scalar localCycles;
22512855Sgabeblack@google.com        // from the perspective of this TLB
22612855Sgabeblack@google.com        Stats::Formula localLatency;
22712855Sgabeblack@google.com        // I take the avg. per page and then
22812855Sgabeblack@google.com        // the avg. over all pages.
22912855Sgabeblack@google.com        Stats::Scalar avgReuseDistance;
23012855Sgabeblack@google.com
23112855Sgabeblack@google.com        void regStats();
23212855Sgabeblack@google.com        void updatePageFootprint(Addr virt_page_addr);
23312855Sgabeblack@google.com        void printAccessPattern();
23412855Sgabeblack@google.com
23512855Sgabeblack@google.com
23612855Sgabeblack@google.com        Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode,
23712855Sgabeblack@google.com                              int &latency);
23812855Sgabeblack@google.com
23912855Sgabeblack@google.com        void translateTiming(RequestPtr req, ThreadContext *tc,
24012855Sgabeblack@google.com                             Translation *translation, Mode mode,
24112855Sgabeblack@google.com                             int &latency);
24212855Sgabeblack@google.com
24312855Sgabeblack@google.com        Tick doMmuRegRead(ThreadContext *tc, Packet *pkt);
24412855Sgabeblack@google.com        Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt);
24512855Sgabeblack@google.com
24612855Sgabeblack@google.com        GpuTlbEntry *insert(Addr vpn, GpuTlbEntry &entry);
24712855Sgabeblack@google.com
24812855Sgabeblack@google.com        // Checkpointing
24912855Sgabeblack@google.com        virtual void serialize(CheckpointOut& cp) const;
25012855Sgabeblack@google.com        virtual void unserialize(CheckpointIn& cp);
25112855Sgabeblack@google.com        void issueTranslation();
25212855Sgabeblack@google.com        enum tlbOutcome {TLB_HIT, TLB_MISS, PAGE_WALK, MISS_RETURN};
25312855Sgabeblack@google.com        bool tlbLookup(RequestPtr req, ThreadContext *tc, bool update_stats);
25412855Sgabeblack@google.com
25512855Sgabeblack@google.com        void handleTranslationReturn(Addr addr, tlbOutcome outcome,
25612855Sgabeblack@google.com                                     PacketPtr pkt);
25712855Sgabeblack@google.com
25812855Sgabeblack@google.com        void handleFuncTranslationReturn(PacketPtr pkt, tlbOutcome outcome);
25912855Sgabeblack@google.com
26012855Sgabeblack@google.com        void pagingProtectionChecks(ThreadContext *tc, PacketPtr pkt,
26112855Sgabeblack@google.com                                    GpuTlbEntry *tlb_entry, Mode mode);
26212855Sgabeblack@google.com
26312855Sgabeblack@google.com        void updatePhysAddresses(Addr virt_page_addr, GpuTlbEntry *tlb_entry,
26412855Sgabeblack@google.com                                 Addr phys_page_addr);
26512855Sgabeblack@google.com
26612855Sgabeblack@google.com        void issueTLBLookup(PacketPtr pkt);
26712855Sgabeblack@google.com
26812855Sgabeblack@google.com        // CpuSidePort is the TLB Port closer to the CPU/CU side
26912855Sgabeblack@google.com        class CpuSidePort : public SlavePort
27012855Sgabeblack@google.com        {
27112855Sgabeblack@google.com          public:
27212855Sgabeblack@google.com            CpuSidePort(const std::string &_name, GpuTLB * gpu_TLB,
27312855Sgabeblack@google.com                        PortID _index)
27412855Sgabeblack@google.com                : SlavePort(_name, gpu_TLB), tlb(gpu_TLB), index(_index) { }
27512855Sgabeblack@google.com
27612855Sgabeblack@google.com          protected:
27712855Sgabeblack@google.com            GpuTLB *tlb;
27812855Sgabeblack@google.com            int index;
27912855Sgabeblack@google.com
28012855Sgabeblack@google.com            virtual bool recvTimingReq(PacketPtr pkt);
28112855Sgabeblack@google.com            virtual Tick recvAtomic(PacketPtr pkt) { return 0; }
28212855Sgabeblack@google.com            virtual void recvFunctional(PacketPtr pkt);
28312855Sgabeblack@google.com            virtual void recvRangeChange() { }
28412855Sgabeblack@google.com            virtual void recvReqRetry();
28512855Sgabeblack@google.com            virtual void recvRespRetry() { assert(false); }
28612855Sgabeblack@google.com            virtual AddrRangeList getAddrRanges() const;
28712855Sgabeblack@google.com        };
28812855Sgabeblack@google.com
28912855Sgabeblack@google.com        /**
29012855Sgabeblack@google.com         * MemSidePort is the TLB Port closer to the memory side
29112855Sgabeblack@google.com         * If this is a last level TLB then this port will not be connected.
29212855Sgabeblack@google.com         *
29312855Sgabeblack@google.com         * Future action item: if we ever do real page walks, then this port
29412855Sgabeblack@google.com         * should be connected to a RubyPort.
29512855Sgabeblack@google.com         */
29612855Sgabeblack@google.com        class MemSidePort : public MasterPort
29712855Sgabeblack@google.com        {
29812855Sgabeblack@google.com          public:
29912855Sgabeblack@google.com            MemSidePort(const std::string &_name, GpuTLB * gpu_TLB,
30012855Sgabeblack@google.com                        PortID _index)
30112855Sgabeblack@google.com                : MasterPort(_name, gpu_TLB), tlb(gpu_TLB), index(_index) { }
30212855Sgabeblack@google.com
30312855Sgabeblack@google.com            std::deque<PacketPtr> retries;
30412855Sgabeblack@google.com
30512855Sgabeblack@google.com          protected:
30612855Sgabeblack@google.com            GpuTLB *tlb;
30712855Sgabeblack@google.com            int index;
30812855Sgabeblack@google.com
30912855Sgabeblack@google.com            virtual bool recvTimingResp(PacketPtr pkt);
31012855Sgabeblack@google.com            virtual Tick recvAtomic(PacketPtr pkt) { return 0; }
31112855Sgabeblack@google.com            virtual void recvFunctional(PacketPtr pkt) { }
31212855Sgabeblack@google.com            virtual void recvRangeChange() { }
31312855Sgabeblack@google.com            virtual void recvReqRetry();
31412855Sgabeblack@google.com        };
31512855Sgabeblack@google.com
31612855Sgabeblack@google.com        // TLB ports on the cpu Side
31712855Sgabeblack@google.com        std::vector<CpuSidePort*> cpuSidePort;
31812855Sgabeblack@google.com        // TLB ports on the memory side
31912855Sgabeblack@google.com        std::vector<MemSidePort*> memSidePort;
32012855Sgabeblack@google.com
32112855Sgabeblack@google.com        BaseMasterPort &getMasterPort(const std::string &if_name,
32212855Sgabeblack@google.com                                      PortID idx=InvalidPortID);
32312855Sgabeblack@google.com
32412855Sgabeblack@google.com        BaseSlavePort &getSlavePort(const std::string &if_name,
32512855Sgabeblack@google.com                                    PortID idx=InvalidPortID);
32612855Sgabeblack@google.com
32712855Sgabeblack@google.com        /**
32812855Sgabeblack@google.com         * TLB TranslationState: this currently is a somewhat bastardization of
32912855Sgabeblack@google.com         * the usage of SenderState, whereby the receiver of a packet is not
33012855Sgabeblack@google.com         * usually supposed to need to look at the contents of the senderState,
33112855Sgabeblack@google.com         * you're really only supposed to look at what you pushed on, pop it
33212855Sgabeblack@google.com         * off, and send it back.
33312855Sgabeblack@google.com         *
33412855Sgabeblack@google.com         * However, since there is state that we want to pass to the TLBs using
33512855Sgabeblack@google.com         * the send/recv Timing/Functional/etc. APIs, which don't allow for new
33612855Sgabeblack@google.com         * arguments, we need a common TLB senderState to pass between TLBs,
33712855Sgabeblack@google.com         * both "forwards" and "backwards."
33812855Sgabeblack@google.com         *
33912855Sgabeblack@google.com         * So, basically, the rule is that any packet received by a TLB port
34012855Sgabeblack@google.com         * (cpuside OR memside) must be safely castable to a TranslationState.
34112855Sgabeblack@google.com         */
34212855Sgabeblack@google.com
34312855Sgabeblack@google.com        struct TranslationState : public Packet::SenderState
34412855Sgabeblack@google.com        {
34512855Sgabeblack@google.com            // TLB mode, read or write
34612855Sgabeblack@google.com            Mode tlbMode;
34712855Sgabeblack@google.com            // Thread context associated with this req
34812855Sgabeblack@google.com            ThreadContext *tc;
34912855Sgabeblack@google.com
35012855Sgabeblack@google.com            /*
35112855Sgabeblack@google.com            * TLB entry to be populated and passed back and filled in
35212855Sgabeblack@google.com            * previous TLBs.  Equivalent to the data cache concept of
35312855Sgabeblack@google.com            * "data return."
35412855Sgabeblack@google.com            */
35512855Sgabeblack@google.com            GpuTlbEntry *tlbEntry;
35612855Sgabeblack@google.com            // Is this a TLB prefetch request?
35712855Sgabeblack@google.com            bool prefetch;
35812855Sgabeblack@google.com            // When was the req for this translation issued
35912855Sgabeblack@google.com            uint64_t issueTime;
36012855Sgabeblack@google.com            // Remember where this came from
36112855Sgabeblack@google.com            std::vector<SlavePort*>ports;
36212855Sgabeblack@google.com
36312855Sgabeblack@google.com            // keep track of #uncoalesced reqs per packet per TLB level;
36412855Sgabeblack@google.com            // reqCnt per level >= reqCnt higher level
36512855Sgabeblack@google.com            std::vector<int> reqCnt;
36612855Sgabeblack@google.com            // TLB level this packet hit in; 0 if it hit in the page table
36712855Sgabeblack@google.com            int hitLevel;
36812855Sgabeblack@google.com            Packet::SenderState *saved;
36912855Sgabeblack@google.com
37012855Sgabeblack@google.com            TranslationState(Mode tlb_mode, ThreadContext *_tc,
37112855Sgabeblack@google.com                             bool _prefetch=false,
37212855Sgabeblack@google.com                             Packet::SenderState *_saved=nullptr)
37312855Sgabeblack@google.com                : tlbMode(tlb_mode), tc(_tc), tlbEntry(nullptr),
37412855Sgabeblack@google.com                  prefetch(_prefetch), issueTime(0),
37512855Sgabeblack@google.com                  hitLevel(0),saved(_saved) { }
37612855Sgabeblack@google.com        };
37712855Sgabeblack@google.com
37812855Sgabeblack@google.com        // maximum number of permitted coalesced requests per cycle
37912855Sgabeblack@google.com        int maxCoalescedReqs;
38012855Sgabeblack@google.com
38112855Sgabeblack@google.com        // Current number of outstandings coalesced requests.
38212855Sgabeblack@google.com        // Should be <= maxCoalescedReqs
38312855Sgabeblack@google.com        int outstandingReqs;
38412855Sgabeblack@google.com
38512855Sgabeblack@google.com        /**
38612855Sgabeblack@google.com         * A TLBEvent is scheduled after the TLB lookup and helps us take the
38712855Sgabeblack@google.com         * appropriate actions:
38812855Sgabeblack@google.com         *  (e.g., update TLB on a hit,
38912855Sgabeblack@google.com         *  send request to lower level TLB on a miss,
39012855Sgabeblack@google.com         *  or start a page walk if this was the last-level TLB).
39112855Sgabeblack@google.com         */
39212855Sgabeblack@google.com        void translationReturn(Addr virtPageAddr, tlbOutcome outcome,
39312855Sgabeblack@google.com                               PacketPtr pkt);
39412855Sgabeblack@google.com
39512855Sgabeblack@google.com        class TLBEvent : public Event
39612855Sgabeblack@google.com        {
39712855Sgabeblack@google.com            private:
39812855Sgabeblack@google.com                GpuTLB *tlb;
39912855Sgabeblack@google.com                Addr virtPageAddr;
40012855Sgabeblack@google.com                /**
40112855Sgabeblack@google.com                 * outcome can be TLB_HIT, TLB_MISS, or PAGE_WALK
40212855Sgabeblack@google.com                 */
40312855Sgabeblack@google.com                tlbOutcome outcome;
40412855Sgabeblack@google.com                PacketPtr pkt;
40512855Sgabeblack@google.com
40612855Sgabeblack@google.com            public:
40712855Sgabeblack@google.com                TLBEvent(GpuTLB *_tlb, Addr _addr, tlbOutcome outcome,
40812855Sgabeblack@google.com                        PacketPtr _pkt);
40912855Sgabeblack@google.com
41012855Sgabeblack@google.com                void process();
41112855Sgabeblack@google.com                const char *description() const;
41212855Sgabeblack@google.com
41312855Sgabeblack@google.com                // updateOutcome updates the tlbOutcome of a TLBEvent
41412855Sgabeblack@google.com                void updateOutcome(tlbOutcome _outcome);
41512855Sgabeblack@google.com                Addr getTLBEventVaddr();
41612855Sgabeblack@google.com        };
41712855Sgabeblack@google.com
41812855Sgabeblack@google.com        std::unordered_map<Addr, TLBEvent*> translationReturnEvent;
41912855Sgabeblack@google.com
42012855Sgabeblack@google.com        // this FIFO queue keeps track of the virt. page addresses
42112855Sgabeblack@google.com        // that are pending cleanup
42212855Sgabeblack@google.com        std::queue<Addr> cleanupQueue;
42312855Sgabeblack@google.com
42412855Sgabeblack@google.com        // the cleanupEvent is scheduled after a TLBEvent triggers in order to
42512855Sgabeblack@google.com        // free memory and do the required clean-up
42612855Sgabeblack@google.com        void cleanup();
42712855Sgabeblack@google.com
42812855Sgabeblack@google.com        EventFunctionWrapper cleanupEvent;
42912855Sgabeblack@google.com
43012855Sgabeblack@google.com        /**
43112855Sgabeblack@google.com         * This hash map will use the virtual page address as a key
43212855Sgabeblack@google.com         * and will keep track of total number of accesses per page
43312855Sgabeblack@google.com         */
43412855Sgabeblack@google.com
43512855Sgabeblack@google.com        struct AccessInfo
43612855Sgabeblack@google.com        {
43712855Sgabeblack@google.com            unsigned int lastTimeAccessed; // last access to this page
43812855Sgabeblack@google.com            unsigned int accessesPerPage;
43912855Sgabeblack@google.com            // need to divide it by accessesPerPage at the end
44012855Sgabeblack@google.com            unsigned int totalReuseDistance;
44112855Sgabeblack@google.com
44212855Sgabeblack@google.com            /**
44312855Sgabeblack@google.com             * The field below will help us compute the access distance,
44412855Sgabeblack@google.com             * that is the number of (coalesced) TLB accesses that
44512855Sgabeblack@google.com             * happened in between each access to this page
44612855Sgabeblack@google.com             *
44712855Sgabeblack@google.com             * localTLBAccesses[x] is the value of localTLBNumAccesses
44812855Sgabeblack@google.com             * when the page <Addr> was accessed for the <x>th time
44912855Sgabeblack@google.com             */
45012855Sgabeblack@google.com            std::vector<unsigned int> localTLBAccesses;
45112855Sgabeblack@google.com            unsigned int sumDistance;
45212855Sgabeblack@google.com            unsigned int meanDistance;
45312855Sgabeblack@google.com        };
45412855Sgabeblack@google.com
45512855Sgabeblack@google.com        typedef std::unordered_map<Addr, AccessInfo> AccessPatternTable;
45612855Sgabeblack@google.com        AccessPatternTable TLBFootprint;
45712855Sgabeblack@google.com
45812855Sgabeblack@google.com        // Called at the end of simulation to dump page access stats.
45912855Sgabeblack@google.com        void exitCallback();
46012855Sgabeblack@google.com
46112855Sgabeblack@google.com        EventFunctionWrapper exitEvent;
46212855Sgabeblack@google.com    };
46312855Sgabeblack@google.com}
46412855Sgabeblack@google.com
46512855Sgabeblack@google.com#endif // __GPU_TLB_HH__
46612855Sgabeblack@google.com