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