gpu_tlb.hh revision 11713
111308Santhony.gutierrez@amd.com/* 211308Santhony.gutierrez@amd.com * Copyright (c) 2011-2015 Advanced Micro Devices, Inc. 311308Santhony.gutierrez@amd.com * All rights reserved. 411308Santhony.gutierrez@amd.com * 511308Santhony.gutierrez@amd.com * For use for simulation and test purposes only 611308Santhony.gutierrez@amd.com * 711308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without 811308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are met: 911308Santhony.gutierrez@amd.com * 1011308Santhony.gutierrez@amd.com * 1. Redistributions of source code must retain the above copyright notice, 1111308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer. 1211308Santhony.gutierrez@amd.com * 1311308Santhony.gutierrez@amd.com * 2. Redistributions in binary form must reproduce the above copyright notice, 1411308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer in the documentation 1511308Santhony.gutierrez@amd.com * and/or other materials provided with the distribution. 1611308Santhony.gutierrez@amd.com * 1711308Santhony.gutierrez@amd.com * 3. Neither the name of the copyright holder nor the names of its contributors 1811308Santhony.gutierrez@amd.com * may be used to endorse or promote products derived from this software 1911308Santhony.gutierrez@amd.com * without specific prior written permission. 2011308Santhony.gutierrez@amd.com * 2111308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2211308Santhony.gutierrez@amd.com * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2311308Santhony.gutierrez@amd.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2411308Santhony.gutierrez@amd.com * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2511308Santhony.gutierrez@amd.com * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2611308Santhony.gutierrez@amd.com * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2711308Santhony.gutierrez@amd.com * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2811308Santhony.gutierrez@amd.com * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2911308Santhony.gutierrez@amd.com * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3011308Santhony.gutierrez@amd.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3111308Santhony.gutierrez@amd.com * POSSIBILITY OF SUCH DAMAGE. 3211308Santhony.gutierrez@amd.com * 3311308Santhony.gutierrez@amd.com * Author: Lisa Hsu 3411308Santhony.gutierrez@amd.com */ 3511308Santhony.gutierrez@amd.com 3611308Santhony.gutierrez@amd.com#ifndef __GPU_TLB_HH__ 3711308Santhony.gutierrez@amd.com#define __GPU_TLB_HH__ 3811308Santhony.gutierrez@amd.com 3911308Santhony.gutierrez@amd.com#include <fstream> 4011308Santhony.gutierrez@amd.com#include <list> 4111308Santhony.gutierrez@amd.com#include <queue> 4211308Santhony.gutierrez@amd.com#include <string> 4311308Santhony.gutierrez@amd.com#include <vector> 4411308Santhony.gutierrez@amd.com 4511308Santhony.gutierrez@amd.com#include "arch/generic/tlb.hh" 4611308Santhony.gutierrez@amd.com#include "arch/x86/pagetable.hh" 4711308Santhony.gutierrez@amd.com#include "arch/x86/pagetable_walker.hh" 4811308Santhony.gutierrez@amd.com#include "arch/x86/regs/segment.hh" 4911308Santhony.gutierrez@amd.com#include "base/callback.hh" 5011308Santhony.gutierrez@amd.com#include "base/misc.hh" 5111308Santhony.gutierrez@amd.com#include "base/statistics.hh" 5211308Santhony.gutierrez@amd.com#include "gpu-compute/compute_unit.hh" 5311308Santhony.gutierrez@amd.com#include "mem/mem_object.hh" 5411308Santhony.gutierrez@amd.com#include "mem/port.hh" 5511308Santhony.gutierrez@amd.com#include "mem/request.hh" 5611308Santhony.gutierrez@amd.com#include "params/X86GPUTLB.hh" 5711308Santhony.gutierrez@amd.com#include "sim/sim_object.hh" 5811308Santhony.gutierrez@amd.com 5911308Santhony.gutierrez@amd.comclass BaseTLB; 6011308Santhony.gutierrez@amd.comclass Packet; 6111308Santhony.gutierrez@amd.comclass ThreadContext; 6211308Santhony.gutierrez@amd.com 6311308Santhony.gutierrez@amd.comnamespace X86ISA 6411308Santhony.gutierrez@amd.com{ 6511308Santhony.gutierrez@amd.com class GpuTlbEntry : public TlbEntry 6611308Santhony.gutierrez@amd.com { 6711308Santhony.gutierrez@amd.com public: 6811308Santhony.gutierrez@amd.com GpuTlbEntry(Addr asn, Addr _vaddr, Addr _paddr, bool _valid) 6911308Santhony.gutierrez@amd.com : TlbEntry(asn, _vaddr, _paddr, false, false), valid(_valid) { } 7011308Santhony.gutierrez@amd.com 7111713Santhony.gutierrez@amd.com GpuTlbEntry() : TlbEntry(), valid(false) { } 7211308Santhony.gutierrez@amd.com 7311308Santhony.gutierrez@amd.com bool valid; 7411308Santhony.gutierrez@amd.com }; 7511308Santhony.gutierrez@amd.com 7611308Santhony.gutierrez@amd.com class GpuTLB : public MemObject 7711308Santhony.gutierrez@amd.com { 7811308Santhony.gutierrez@amd.com protected: 7911308Santhony.gutierrez@amd.com friend class Walker; 8011308Santhony.gutierrez@amd.com 8111308Santhony.gutierrez@amd.com typedef std::list<GpuTlbEntry*> EntryList; 8211308Santhony.gutierrez@amd.com 8311308Santhony.gutierrez@amd.com uint32_t configAddress; 8411308Santhony.gutierrez@amd.com 8511308Santhony.gutierrez@amd.com // TLB clock: will inherit clock from shader's clock period in terms 8611308Santhony.gutierrez@amd.com // of nuber of ticks of curTime (aka global simulation clock) 8711308Santhony.gutierrez@amd.com // The assignment of TLB clock from shader clock is done in the python 8811308Santhony.gutierrez@amd.com // config files. 8911308Santhony.gutierrez@amd.com int clock; 9011308Santhony.gutierrez@amd.com 9111308Santhony.gutierrez@amd.com public: 9211308Santhony.gutierrez@amd.com // clock related functions ; maps to-and-from Simulation ticks and 9311308Santhony.gutierrez@amd.com // object clocks. 9411308Santhony.gutierrez@amd.com Tick frequency() const { return SimClock::Frequency / clock; } 9511308Santhony.gutierrez@amd.com 9611308Santhony.gutierrez@amd.com Tick 9711308Santhony.gutierrez@amd.com ticks(int numCycles) const 9811308Santhony.gutierrez@amd.com { 9911308Santhony.gutierrez@amd.com return (Tick)clock * numCycles; 10011308Santhony.gutierrez@amd.com } 10111308Santhony.gutierrez@amd.com 10211308Santhony.gutierrez@amd.com Tick curCycle() const { return curTick() / clock; } 10311308Santhony.gutierrez@amd.com Tick tickToCycles(Tick val) const { return val / clock;} 10411308Santhony.gutierrez@amd.com 10511308Santhony.gutierrez@amd.com typedef X86GPUTLBParams Params; 10611308Santhony.gutierrez@amd.com GpuTLB(const Params *p); 10711308Santhony.gutierrez@amd.com ~GpuTLB(); 10811308Santhony.gutierrez@amd.com 10911308Santhony.gutierrez@amd.com typedef enum BaseTLB::Mode Mode; 11011308Santhony.gutierrez@amd.com 11111308Santhony.gutierrez@amd.com class Translation 11211308Santhony.gutierrez@amd.com { 11311308Santhony.gutierrez@amd.com public: 11411308Santhony.gutierrez@amd.com virtual ~Translation() { } 11511308Santhony.gutierrez@amd.com 11611308Santhony.gutierrez@amd.com /** 11711308Santhony.gutierrez@amd.com * Signal that the translation has been delayed due to a hw page 11811308Santhony.gutierrez@amd.com * table walk. 11911308Santhony.gutierrez@amd.com */ 12011308Santhony.gutierrez@amd.com virtual void markDelayed() = 0; 12111308Santhony.gutierrez@amd.com 12211308Santhony.gutierrez@amd.com /** 12311308Santhony.gutierrez@amd.com * The memory for this object may be dynamically allocated, and it 12411308Santhony.gutierrez@amd.com * may be responsible for cleaning itslef up which will happen in 12511308Santhony.gutierrez@amd.com * this function. Once it's called the object is no longer valid. 12611308Santhony.gutierrez@amd.com */ 12711308Santhony.gutierrez@amd.com virtual void finish(Fault fault, RequestPtr req, ThreadContext *tc, 12811308Santhony.gutierrez@amd.com Mode mode) = 0; 12911308Santhony.gutierrez@amd.com }; 13011308Santhony.gutierrez@amd.com 13111308Santhony.gutierrez@amd.com void dumpAll(); 13211308Santhony.gutierrez@amd.com GpuTlbEntry *lookup(Addr va, bool update_lru=true); 13311308Santhony.gutierrez@amd.com void setConfigAddress(uint32_t addr); 13411308Santhony.gutierrez@amd.com 13511308Santhony.gutierrez@amd.com protected: 13611308Santhony.gutierrez@amd.com EntryList::iterator lookupIt(Addr va, bool update_lru=true); 13711308Santhony.gutierrez@amd.com Walker *walker; 13811308Santhony.gutierrez@amd.com 13911308Santhony.gutierrez@amd.com public: 14011308Santhony.gutierrez@amd.com Walker *getWalker(); 14111308Santhony.gutierrez@amd.com void invalidateAll(); 14211308Santhony.gutierrez@amd.com void invalidateNonGlobal(); 14311308Santhony.gutierrez@amd.com void demapPage(Addr va, uint64_t asn); 14411308Santhony.gutierrez@amd.com 14511308Santhony.gutierrez@amd.com protected: 14611308Santhony.gutierrez@amd.com int size; 14711308Santhony.gutierrez@amd.com int assoc; 14811308Santhony.gutierrez@amd.com int numSets; 14911308Santhony.gutierrez@amd.com 15011308Santhony.gutierrez@amd.com /** 15111308Santhony.gutierrez@amd.com * true if this is a fully-associative TLB 15211308Santhony.gutierrez@amd.com */ 15311308Santhony.gutierrez@amd.com bool FA; 15411308Santhony.gutierrez@amd.com Addr setMask; 15511308Santhony.gutierrez@amd.com 15611308Santhony.gutierrez@amd.com /** 15711308Santhony.gutierrez@amd.com * Allocation Policy: true if we always allocate on a hit, false 15811308Santhony.gutierrez@amd.com * otherwise. Default is true. 15911308Santhony.gutierrez@amd.com */ 16011308Santhony.gutierrez@amd.com bool allocationPolicy; 16111308Santhony.gutierrez@amd.com 16211308Santhony.gutierrez@amd.com /** 16311308Santhony.gutierrez@amd.com * if true, then this is not the last level TLB 16411308Santhony.gutierrez@amd.com */ 16511308Santhony.gutierrez@amd.com bool hasMemSidePort; 16611308Santhony.gutierrez@amd.com 16711308Santhony.gutierrez@amd.com /** 16811308Santhony.gutierrez@amd.com * Print out accessDistance stats. One stat file 16911308Santhony.gutierrez@amd.com * per TLB. 17011308Santhony.gutierrez@amd.com */ 17111308Santhony.gutierrez@amd.com bool accessDistance; 17211308Santhony.gutierrez@amd.com 17311704Santhony.gutierrez@amd.com std::vector<GpuTlbEntry> tlb; 17411308Santhony.gutierrez@amd.com 17511308Santhony.gutierrez@amd.com /* 17611308Santhony.gutierrez@amd.com * It's a per-set list. As long as we have not reached 17711308Santhony.gutierrez@amd.com * the full capacity of the given set, grab an entry from 17811308Santhony.gutierrez@amd.com * the freeList. 17911308Santhony.gutierrez@amd.com */ 18011308Santhony.gutierrez@amd.com std::vector<EntryList> freeList; 18111308Santhony.gutierrez@amd.com 18211308Santhony.gutierrez@amd.com /** 18311308Santhony.gutierrez@amd.com * An entryList per set is the equivalent of an LRU stack; 18411308Santhony.gutierrez@amd.com * it's used to guide replacement decisions. The head of the list 18511308Santhony.gutierrez@amd.com * contains the MRU TLB entry of the given set. If the freeList 18611308Santhony.gutierrez@amd.com * for this set is empty, the last element of the list 18711308Santhony.gutierrez@amd.com * is evicted (i.e., dropped on the floor). 18811308Santhony.gutierrez@amd.com */ 18911308Santhony.gutierrez@amd.com std::vector<EntryList> entryList; 19011308Santhony.gutierrez@amd.com 19111308Santhony.gutierrez@amd.com Fault translateInt(RequestPtr req, ThreadContext *tc); 19211308Santhony.gutierrez@amd.com 19311308Santhony.gutierrez@amd.com Fault translate(RequestPtr req, ThreadContext *tc, 19411308Santhony.gutierrez@amd.com Translation *translation, Mode mode, bool &delayedResponse, 19511308Santhony.gutierrez@amd.com bool timing, int &latency); 19611308Santhony.gutierrez@amd.com 19711308Santhony.gutierrez@amd.com public: 19811308Santhony.gutierrez@amd.com // latencies for a TLB hit, miss and page fault 19911308Santhony.gutierrez@amd.com int hitLatency; 20011308Santhony.gutierrez@amd.com int missLatency1; 20111308Santhony.gutierrez@amd.com int missLatency2; 20211308Santhony.gutierrez@amd.com 20311308Santhony.gutierrez@amd.com // local_stats are as seen from the TLB 20411308Santhony.gutierrez@amd.com // without taking into account coalescing 20511308Santhony.gutierrez@amd.com Stats::Scalar localNumTLBAccesses; 20611308Santhony.gutierrez@amd.com Stats::Scalar localNumTLBHits; 20711308Santhony.gutierrez@amd.com Stats::Scalar localNumTLBMisses; 20811308Santhony.gutierrez@amd.com Stats::Formula localTLBMissRate; 20911308Santhony.gutierrez@amd.com 21011308Santhony.gutierrez@amd.com // global_stats are as seen from the 21111308Santhony.gutierrez@amd.com // CU's perspective taking into account 21211308Santhony.gutierrez@amd.com // all coalesced requests. 21311308Santhony.gutierrez@amd.com Stats::Scalar globalNumTLBAccesses; 21411308Santhony.gutierrez@amd.com Stats::Scalar globalNumTLBHits; 21511308Santhony.gutierrez@amd.com Stats::Scalar globalNumTLBMisses; 21611308Santhony.gutierrez@amd.com Stats::Formula globalTLBMissRate; 21711308Santhony.gutierrez@amd.com 21811308Santhony.gutierrez@amd.com // from the CU perspective (global) 21911308Santhony.gutierrez@amd.com Stats::Scalar accessCycles; 22011308Santhony.gutierrez@amd.com // from the CU perspective (global) 22111308Santhony.gutierrez@amd.com Stats::Scalar pageTableCycles; 22211308Santhony.gutierrez@amd.com Stats::Scalar numUniquePages; 22311308Santhony.gutierrez@amd.com // from the perspective of this TLB 22411308Santhony.gutierrez@amd.com Stats::Scalar localCycles; 22511308Santhony.gutierrez@amd.com // from the perspective of this TLB 22611308Santhony.gutierrez@amd.com Stats::Formula localLatency; 22711308Santhony.gutierrez@amd.com // I take the avg. per page and then 22811308Santhony.gutierrez@amd.com // the avg. over all pages. 22911308Santhony.gutierrez@amd.com Stats::Scalar avgReuseDistance; 23011308Santhony.gutierrez@amd.com 23111308Santhony.gutierrez@amd.com void regStats(); 23211308Santhony.gutierrez@amd.com void updatePageFootprint(Addr virt_page_addr); 23311308Santhony.gutierrez@amd.com void printAccessPattern(); 23411308Santhony.gutierrez@amd.com 23511308Santhony.gutierrez@amd.com 23611308Santhony.gutierrez@amd.com Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode, 23711308Santhony.gutierrez@amd.com int &latency); 23811308Santhony.gutierrez@amd.com 23911308Santhony.gutierrez@amd.com void translateTiming(RequestPtr req, ThreadContext *tc, 24011308Santhony.gutierrez@amd.com Translation *translation, Mode mode, 24111308Santhony.gutierrez@amd.com int &latency); 24211308Santhony.gutierrez@amd.com 24311308Santhony.gutierrez@amd.com Tick doMmuRegRead(ThreadContext *tc, Packet *pkt); 24411308Santhony.gutierrez@amd.com Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt); 24511308Santhony.gutierrez@amd.com 24611308Santhony.gutierrez@amd.com GpuTlbEntry *insert(Addr vpn, GpuTlbEntry &entry); 24711308Santhony.gutierrez@amd.com 24811308Santhony.gutierrez@amd.com // Checkpointing 24911308Santhony.gutierrez@amd.com virtual void serialize(CheckpointOut& cp) const; 25011308Santhony.gutierrez@amd.com virtual void unserialize(CheckpointIn& cp); 25111308Santhony.gutierrez@amd.com void issueTranslation(); 25211308Santhony.gutierrez@amd.com enum tlbOutcome {TLB_HIT, TLB_MISS, PAGE_WALK, MISS_RETURN}; 25311308Santhony.gutierrez@amd.com bool tlbLookup(RequestPtr req, ThreadContext *tc, bool update_stats); 25411308Santhony.gutierrez@amd.com 25511308Santhony.gutierrez@amd.com void handleTranslationReturn(Addr addr, tlbOutcome outcome, 25611308Santhony.gutierrez@amd.com PacketPtr pkt); 25711308Santhony.gutierrez@amd.com 25811308Santhony.gutierrez@amd.com void handleFuncTranslationReturn(PacketPtr pkt, tlbOutcome outcome); 25911308Santhony.gutierrez@amd.com 26011308Santhony.gutierrez@amd.com void pagingProtectionChecks(ThreadContext *tc, PacketPtr pkt, 26111308Santhony.gutierrez@amd.com GpuTlbEntry *tlb_entry, Mode mode); 26211308Santhony.gutierrez@amd.com 26311308Santhony.gutierrez@amd.com void updatePhysAddresses(Addr virt_page_addr, GpuTlbEntry *tlb_entry, 26411308Santhony.gutierrez@amd.com Addr phys_page_addr); 26511308Santhony.gutierrez@amd.com 26611308Santhony.gutierrez@amd.com void issueTLBLookup(PacketPtr pkt); 26711308Santhony.gutierrez@amd.com 26811308Santhony.gutierrez@amd.com // CpuSidePort is the TLB Port closer to the CPU/CU side 26911308Santhony.gutierrez@amd.com class CpuSidePort : public SlavePort 27011308Santhony.gutierrez@amd.com { 27111308Santhony.gutierrez@amd.com public: 27211308Santhony.gutierrez@amd.com CpuSidePort(const std::string &_name, GpuTLB * gpu_TLB, 27311308Santhony.gutierrez@amd.com PortID _index) 27411308Santhony.gutierrez@amd.com : SlavePort(_name, gpu_TLB), tlb(gpu_TLB), index(_index) { } 27511308Santhony.gutierrez@amd.com 27611308Santhony.gutierrez@amd.com protected: 27711308Santhony.gutierrez@amd.com GpuTLB *tlb; 27811308Santhony.gutierrez@amd.com int index; 27911308Santhony.gutierrez@amd.com 28011308Santhony.gutierrez@amd.com virtual bool recvTimingReq(PacketPtr pkt); 28111308Santhony.gutierrez@amd.com virtual Tick recvAtomic(PacketPtr pkt) { return 0; } 28211308Santhony.gutierrez@amd.com virtual void recvFunctional(PacketPtr pkt); 28311308Santhony.gutierrez@amd.com virtual void recvRangeChange() { } 28411308Santhony.gutierrez@amd.com virtual void recvReqRetry(); 28511308Santhony.gutierrez@amd.com virtual void recvRespRetry() { assert(false); } 28611308Santhony.gutierrez@amd.com virtual AddrRangeList getAddrRanges() const; 28711308Santhony.gutierrez@amd.com }; 28811308Santhony.gutierrez@amd.com 28911308Santhony.gutierrez@amd.com /** 29011308Santhony.gutierrez@amd.com * MemSidePort is the TLB Port closer to the memory side 29111308Santhony.gutierrez@amd.com * If this is a last level TLB then this port will not be connected. 29211308Santhony.gutierrez@amd.com * 29311308Santhony.gutierrez@amd.com * Future action item: if we ever do real page walks, then this port 29411308Santhony.gutierrez@amd.com * should be connected to a RubyPort. 29511308Santhony.gutierrez@amd.com */ 29611308Santhony.gutierrez@amd.com class MemSidePort : public MasterPort 29711308Santhony.gutierrez@amd.com { 29811308Santhony.gutierrez@amd.com public: 29911308Santhony.gutierrez@amd.com MemSidePort(const std::string &_name, GpuTLB * gpu_TLB, 30011308Santhony.gutierrez@amd.com PortID _index) 30111308Santhony.gutierrez@amd.com : MasterPort(_name, gpu_TLB), tlb(gpu_TLB), index(_index) { } 30211308Santhony.gutierrez@amd.com 30311308Santhony.gutierrez@amd.com std::deque<PacketPtr> retries; 30411308Santhony.gutierrez@amd.com 30511308Santhony.gutierrez@amd.com protected: 30611308Santhony.gutierrez@amd.com GpuTLB *tlb; 30711308Santhony.gutierrez@amd.com int index; 30811308Santhony.gutierrez@amd.com 30911308Santhony.gutierrez@amd.com virtual bool recvTimingResp(PacketPtr pkt); 31011308Santhony.gutierrez@amd.com virtual Tick recvAtomic(PacketPtr pkt) { return 0; } 31111308Santhony.gutierrez@amd.com virtual void recvFunctional(PacketPtr pkt) { } 31211308Santhony.gutierrez@amd.com virtual void recvRangeChange() { } 31311308Santhony.gutierrez@amd.com virtual void recvReqRetry(); 31411308Santhony.gutierrez@amd.com }; 31511308Santhony.gutierrez@amd.com 31611308Santhony.gutierrez@amd.com // TLB ports on the cpu Side 31711308Santhony.gutierrez@amd.com std::vector<CpuSidePort*> cpuSidePort; 31811308Santhony.gutierrez@amd.com // TLB ports on the memory side 31911308Santhony.gutierrez@amd.com std::vector<MemSidePort*> memSidePort; 32011308Santhony.gutierrez@amd.com 32111308Santhony.gutierrez@amd.com BaseMasterPort &getMasterPort(const std::string &if_name, 32211308Santhony.gutierrez@amd.com PortID idx=InvalidPortID); 32311308Santhony.gutierrez@amd.com 32411308Santhony.gutierrez@amd.com BaseSlavePort &getSlavePort(const std::string &if_name, 32511308Santhony.gutierrez@amd.com PortID idx=InvalidPortID); 32611308Santhony.gutierrez@amd.com 32711308Santhony.gutierrez@amd.com /** 32811308Santhony.gutierrez@amd.com * TLB TranslationState: this currently is a somewhat bastardization of 32911308Santhony.gutierrez@amd.com * the usage of SenderState, whereby the receiver of a packet is not 33011308Santhony.gutierrez@amd.com * usually supposed to need to look at the contents of the senderState, 33111308Santhony.gutierrez@amd.com * you're really only supposed to look at what you pushed on, pop it 33211308Santhony.gutierrez@amd.com * off, and send it back. 33311308Santhony.gutierrez@amd.com * 33411308Santhony.gutierrez@amd.com * However, since there is state that we want to pass to the TLBs using 33511308Santhony.gutierrez@amd.com * the send/recv Timing/Functional/etc. APIs, which don't allow for new 33611308Santhony.gutierrez@amd.com * arguments, we need a common TLB senderState to pass between TLBs, 33711308Santhony.gutierrez@amd.com * both "forwards" and "backwards." 33811308Santhony.gutierrez@amd.com * 33911308Santhony.gutierrez@amd.com * So, basically, the rule is that any packet received by a TLB port 34011308Santhony.gutierrez@amd.com * (cpuside OR memside) must be safely castable to a TranslationState. 34111308Santhony.gutierrez@amd.com */ 34211308Santhony.gutierrez@amd.com 34311308Santhony.gutierrez@amd.com struct TranslationState : public Packet::SenderState 34411308Santhony.gutierrez@amd.com { 34511308Santhony.gutierrez@amd.com // TLB mode, read or write 34611308Santhony.gutierrez@amd.com Mode tlbMode; 34711308Santhony.gutierrez@amd.com // Thread context associated with this req 34811308Santhony.gutierrez@amd.com ThreadContext *tc; 34911308Santhony.gutierrez@amd.com 35011308Santhony.gutierrez@amd.com /* 35111308Santhony.gutierrez@amd.com * TLB entry to be populated and passed back and filled in 35211308Santhony.gutierrez@amd.com * previous TLBs. Equivalent to the data cache concept of 35311308Santhony.gutierrez@amd.com * "data return." 35411308Santhony.gutierrez@amd.com */ 35511308Santhony.gutierrez@amd.com GpuTlbEntry *tlbEntry; 35611308Santhony.gutierrez@amd.com // Is this a TLB prefetch request? 35711308Santhony.gutierrez@amd.com bool prefetch; 35811308Santhony.gutierrez@amd.com // When was the req for this translation issued 35911308Santhony.gutierrez@amd.com uint64_t issueTime; 36011308Santhony.gutierrez@amd.com // Remember where this came from 36111308Santhony.gutierrez@amd.com std::vector<SlavePort*>ports; 36211308Santhony.gutierrez@amd.com 36311308Santhony.gutierrez@amd.com // keep track of #uncoalesced reqs per packet per TLB level; 36411308Santhony.gutierrez@amd.com // reqCnt per level >= reqCnt higher level 36511308Santhony.gutierrez@amd.com std::vector<int> reqCnt; 36611308Santhony.gutierrez@amd.com // TLB level this packet hit in; 0 if it hit in the page table 36711308Santhony.gutierrez@amd.com int hitLevel; 36811308Santhony.gutierrez@amd.com Packet::SenderState *saved; 36911308Santhony.gutierrez@amd.com 37011308Santhony.gutierrez@amd.com TranslationState(Mode tlb_mode, ThreadContext *_tc, 37111308Santhony.gutierrez@amd.com bool _prefetch=false, 37211308Santhony.gutierrez@amd.com Packet::SenderState *_saved=nullptr) 37311308Santhony.gutierrez@amd.com : tlbMode(tlb_mode), tc(_tc), tlbEntry(nullptr), 37411308Santhony.gutierrez@amd.com prefetch(_prefetch), issueTime(0), 37511308Santhony.gutierrez@amd.com hitLevel(0),saved(_saved) { } 37611308Santhony.gutierrez@amd.com }; 37711308Santhony.gutierrez@amd.com 37811308Santhony.gutierrez@amd.com // maximum number of permitted coalesced requests per cycle 37911308Santhony.gutierrez@amd.com int maxCoalescedReqs; 38011308Santhony.gutierrez@amd.com 38111308Santhony.gutierrez@amd.com // Current number of outstandings coalesced requests. 38211308Santhony.gutierrez@amd.com // Should be <= maxCoalescedReqs 38311308Santhony.gutierrez@amd.com int outstandingReqs; 38411308Santhony.gutierrez@amd.com 38511308Santhony.gutierrez@amd.com /** 38611308Santhony.gutierrez@amd.com * A TLBEvent is scheduled after the TLB lookup and helps us take the 38711308Santhony.gutierrez@amd.com * appropriate actions: 38811308Santhony.gutierrez@amd.com * (e.g., update TLB on a hit, 38911308Santhony.gutierrez@amd.com * send request to lower level TLB on a miss, 39011308Santhony.gutierrez@amd.com * or start a page walk if this was the last-level TLB). 39111308Santhony.gutierrez@amd.com */ 39211308Santhony.gutierrez@amd.com void translationReturn(Addr virtPageAddr, tlbOutcome outcome, 39311308Santhony.gutierrez@amd.com PacketPtr pkt); 39411308Santhony.gutierrez@amd.com 39511308Santhony.gutierrez@amd.com class TLBEvent : public Event 39611308Santhony.gutierrez@amd.com { 39711308Santhony.gutierrez@amd.com private: 39811308Santhony.gutierrez@amd.com GpuTLB *tlb; 39911308Santhony.gutierrez@amd.com Addr virtPageAddr; 40011308Santhony.gutierrez@amd.com /** 40111308Santhony.gutierrez@amd.com * outcome can be TLB_HIT, TLB_MISS, or PAGE_WALK 40211308Santhony.gutierrez@amd.com */ 40311308Santhony.gutierrez@amd.com tlbOutcome outcome; 40411308Santhony.gutierrez@amd.com PacketPtr pkt; 40511308Santhony.gutierrez@amd.com 40611308Santhony.gutierrez@amd.com public: 40711308Santhony.gutierrez@amd.com TLBEvent(GpuTLB *_tlb, Addr _addr, tlbOutcome outcome, 40811308Santhony.gutierrez@amd.com PacketPtr _pkt); 40911308Santhony.gutierrez@amd.com 41011308Santhony.gutierrez@amd.com void process(); 41111308Santhony.gutierrez@amd.com const char *description() const; 41211308Santhony.gutierrez@amd.com 41311308Santhony.gutierrez@amd.com // updateOutcome updates the tlbOutcome of a TLBEvent 41411308Santhony.gutierrez@amd.com void updateOutcome(tlbOutcome _outcome); 41511308Santhony.gutierrez@amd.com Addr getTLBEventVaddr(); 41611308Santhony.gutierrez@amd.com }; 41711308Santhony.gutierrez@amd.com 41811308Santhony.gutierrez@amd.com std::unordered_map<Addr, TLBEvent*> translationReturnEvent; 41911308Santhony.gutierrez@amd.com 42011308Santhony.gutierrez@amd.com // this FIFO queue keeps track of the virt. page addresses 42111308Santhony.gutierrez@amd.com // that are pending cleanup 42211308Santhony.gutierrez@amd.com std::queue<Addr> cleanupQueue; 42311308Santhony.gutierrez@amd.com 42411308Santhony.gutierrez@amd.com // the cleanupEvent is scheduled after a TLBEvent triggers in order to 42511308Santhony.gutierrez@amd.com // free memory and do the required clean-up 42611308Santhony.gutierrez@amd.com void cleanup(); 42711308Santhony.gutierrez@amd.com 42811308Santhony.gutierrez@amd.com EventWrapper<GpuTLB, &GpuTLB::cleanup> cleanupEvent; 42911308Santhony.gutierrez@amd.com 43011308Santhony.gutierrez@amd.com /** 43111308Santhony.gutierrez@amd.com * This hash map will use the virtual page address as a key 43211308Santhony.gutierrez@amd.com * and will keep track of total number of accesses per page 43311308Santhony.gutierrez@amd.com */ 43411308Santhony.gutierrez@amd.com 43511308Santhony.gutierrez@amd.com struct AccessInfo 43611308Santhony.gutierrez@amd.com { 43711308Santhony.gutierrez@amd.com unsigned int lastTimeAccessed; // last access to this page 43811308Santhony.gutierrez@amd.com unsigned int accessesPerPage; 43911308Santhony.gutierrez@amd.com // need to divide it by accessesPerPage at the end 44011308Santhony.gutierrez@amd.com unsigned int totalReuseDistance; 44111308Santhony.gutierrez@amd.com 44211308Santhony.gutierrez@amd.com /** 44311308Santhony.gutierrez@amd.com * The field below will help us compute the access distance, 44411308Santhony.gutierrez@amd.com * that is the number of (coalesced) TLB accesses that 44511308Santhony.gutierrez@amd.com * happened in between each access to this page 44611308Santhony.gutierrez@amd.com * 44711308Santhony.gutierrez@amd.com * localTLBAccesses[x] is the value of localTLBNumAccesses 44811308Santhony.gutierrez@amd.com * when the page <Addr> was accessed for the <x>th time 44911308Santhony.gutierrez@amd.com */ 45011308Santhony.gutierrez@amd.com std::vector<unsigned int> localTLBAccesses; 45111308Santhony.gutierrez@amd.com unsigned int sumDistance; 45211308Santhony.gutierrez@amd.com unsigned int meanDistance; 45311308Santhony.gutierrez@amd.com }; 45411308Santhony.gutierrez@amd.com 45511308Santhony.gutierrez@amd.com typedef std::unordered_map<Addr, AccessInfo> AccessPatternTable; 45611308Santhony.gutierrez@amd.com AccessPatternTable TLBFootprint; 45711308Santhony.gutierrez@amd.com 45811308Santhony.gutierrez@amd.com // Called at the end of simulation to dump page access stats. 45911308Santhony.gutierrez@amd.com void exitCallback(); 46011308Santhony.gutierrez@amd.com 46111308Santhony.gutierrez@amd.com EventWrapper<GpuTLB, &GpuTLB::exitCallback> exitEvent; 46211308Santhony.gutierrez@amd.com }; 46311308Santhony.gutierrez@amd.com} 46411308Santhony.gutierrez@amd.com 46511308Santhony.gutierrez@amd.com#endif // __GPU_TLB_HH__ 466