gpu_tlb.hh revision 14292
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 * 1712697Santhony.gutierrez@amd.com * 3. Neither the name of the copyright holder nor the names of its 1812697Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from this 1912697Santhony.gutierrez@amd.com * software 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 * 3312697Santhony.gutierrez@amd.com * Authors: 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" 5012334Sgabeblack@google.com#include "base/logging.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/port.hh" 5411308Santhony.gutierrez@amd.com#include "mem/request.hh" 5511308Santhony.gutierrez@amd.com#include "params/X86GPUTLB.hh" 5613892Sgabeblack@google.com#include "sim/clocked_object.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{ 6513892Sgabeblack@google.com class GpuTLB : public ClockedObject 6611308Santhony.gutierrez@amd.com { 6711308Santhony.gutierrez@amd.com protected: 6811308Santhony.gutierrez@amd.com friend class Walker; 6911308Santhony.gutierrez@amd.com 7012717Sbrandon.potter@amd.com typedef std::list<TlbEntry*> EntryList; 7111308Santhony.gutierrez@amd.com 7211308Santhony.gutierrez@amd.com uint32_t configAddress; 7311308Santhony.gutierrez@amd.com 7411308Santhony.gutierrez@amd.com // TLB clock: will inherit clock from shader's clock period in terms 7511308Santhony.gutierrez@amd.com // of nuber of ticks of curTime (aka global simulation clock) 7611308Santhony.gutierrez@amd.com // The assignment of TLB clock from shader clock is done in the python 7711308Santhony.gutierrez@amd.com // config files. 7811308Santhony.gutierrez@amd.com int clock; 7911308Santhony.gutierrez@amd.com 8011308Santhony.gutierrez@amd.com public: 8111308Santhony.gutierrez@amd.com // clock related functions ; maps to-and-from Simulation ticks and 8211308Santhony.gutierrez@amd.com // object clocks. 8311308Santhony.gutierrez@amd.com Tick frequency() const { return SimClock::Frequency / clock; } 8411308Santhony.gutierrez@amd.com 8511308Santhony.gutierrez@amd.com Tick 8611308Santhony.gutierrez@amd.com ticks(int numCycles) const 8711308Santhony.gutierrez@amd.com { 8811308Santhony.gutierrez@amd.com return (Tick)clock * numCycles; 8911308Santhony.gutierrez@amd.com } 9011308Santhony.gutierrez@amd.com 9111308Santhony.gutierrez@amd.com Tick curCycle() const { return curTick() / clock; } 9211308Santhony.gutierrez@amd.com Tick tickToCycles(Tick val) const { return val / clock;} 9311308Santhony.gutierrez@amd.com 9411308Santhony.gutierrez@amd.com typedef X86GPUTLBParams Params; 9511308Santhony.gutierrez@amd.com GpuTLB(const Params *p); 9611308Santhony.gutierrez@amd.com ~GpuTLB(); 9711308Santhony.gutierrez@amd.com 9811308Santhony.gutierrez@amd.com typedef enum BaseTLB::Mode Mode; 9911308Santhony.gutierrez@amd.com 10011308Santhony.gutierrez@amd.com class Translation 10111308Santhony.gutierrez@amd.com { 10211308Santhony.gutierrez@amd.com public: 10311308Santhony.gutierrez@amd.com virtual ~Translation() { } 10411308Santhony.gutierrez@amd.com 10511308Santhony.gutierrez@amd.com /** 10611308Santhony.gutierrez@amd.com * Signal that the translation has been delayed due to a hw page 10711308Santhony.gutierrez@amd.com * table walk. 10811308Santhony.gutierrez@amd.com */ 10911308Santhony.gutierrez@amd.com virtual void markDelayed() = 0; 11011308Santhony.gutierrez@amd.com 11111308Santhony.gutierrez@amd.com /** 11211308Santhony.gutierrez@amd.com * The memory for this object may be dynamically allocated, and it 11311308Santhony.gutierrez@amd.com * may be responsible for cleaning itslef up which will happen in 11411308Santhony.gutierrez@amd.com * this function. Once it's called the object is no longer valid. 11511308Santhony.gutierrez@amd.com */ 11612749Sgiacomo.travaglini@arm.com virtual void finish(Fault fault, const RequestPtr &req, 11712749Sgiacomo.travaglini@arm.com ThreadContext *tc, Mode mode) = 0; 11811308Santhony.gutierrez@amd.com }; 11911308Santhony.gutierrez@amd.com 12011308Santhony.gutierrez@amd.com void dumpAll(); 12112717Sbrandon.potter@amd.com TlbEntry *lookup(Addr va, bool update_lru=true); 12211308Santhony.gutierrez@amd.com void setConfigAddress(uint32_t addr); 12311308Santhony.gutierrez@amd.com 12411308Santhony.gutierrez@amd.com protected: 12511308Santhony.gutierrez@amd.com EntryList::iterator lookupIt(Addr va, bool update_lru=true); 12611308Santhony.gutierrez@amd.com Walker *walker; 12711308Santhony.gutierrez@amd.com 12811308Santhony.gutierrez@amd.com public: 12911308Santhony.gutierrez@amd.com Walker *getWalker(); 13011308Santhony.gutierrez@amd.com void invalidateAll(); 13111308Santhony.gutierrez@amd.com void invalidateNonGlobal(); 13211308Santhony.gutierrez@amd.com void demapPage(Addr va, uint64_t asn); 13311308Santhony.gutierrez@amd.com 13411308Santhony.gutierrez@amd.com protected: 13511308Santhony.gutierrez@amd.com int size; 13611308Santhony.gutierrez@amd.com int assoc; 13711308Santhony.gutierrez@amd.com int numSets; 13811308Santhony.gutierrez@amd.com 13911308Santhony.gutierrez@amd.com /** 14011308Santhony.gutierrez@amd.com * true if this is a fully-associative TLB 14111308Santhony.gutierrez@amd.com */ 14211308Santhony.gutierrez@amd.com bool FA; 14311308Santhony.gutierrez@amd.com Addr setMask; 14411308Santhony.gutierrez@amd.com 14511308Santhony.gutierrez@amd.com /** 14611308Santhony.gutierrez@amd.com * Allocation Policy: true if we always allocate on a hit, false 14711308Santhony.gutierrez@amd.com * otherwise. Default is true. 14811308Santhony.gutierrez@amd.com */ 14911308Santhony.gutierrez@amd.com bool allocationPolicy; 15011308Santhony.gutierrez@amd.com 15111308Santhony.gutierrez@amd.com /** 15211308Santhony.gutierrez@amd.com * if true, then this is not the last level TLB 15311308Santhony.gutierrez@amd.com */ 15411308Santhony.gutierrez@amd.com bool hasMemSidePort; 15511308Santhony.gutierrez@amd.com 15611308Santhony.gutierrez@amd.com /** 15711308Santhony.gutierrez@amd.com * Print out accessDistance stats. One stat file 15811308Santhony.gutierrez@amd.com * per TLB. 15911308Santhony.gutierrez@amd.com */ 16011308Santhony.gutierrez@amd.com bool accessDistance; 16111308Santhony.gutierrez@amd.com 16212717Sbrandon.potter@amd.com std::vector<TlbEntry> tlb; 16311308Santhony.gutierrez@amd.com 16411308Santhony.gutierrez@amd.com /* 16511308Santhony.gutierrez@amd.com * It's a per-set list. As long as we have not reached 16611308Santhony.gutierrez@amd.com * the full capacity of the given set, grab an entry from 16711308Santhony.gutierrez@amd.com * the freeList. 16811308Santhony.gutierrez@amd.com */ 16911308Santhony.gutierrez@amd.com std::vector<EntryList> freeList; 17011308Santhony.gutierrez@amd.com 17111308Santhony.gutierrez@amd.com /** 17211308Santhony.gutierrez@amd.com * An entryList per set is the equivalent of an LRU stack; 17311308Santhony.gutierrez@amd.com * it's used to guide replacement decisions. The head of the list 17411308Santhony.gutierrez@amd.com * contains the MRU TLB entry of the given set. If the freeList 17511308Santhony.gutierrez@amd.com * for this set is empty, the last element of the list 17611308Santhony.gutierrez@amd.com * is evicted (i.e., dropped on the floor). 17711308Santhony.gutierrez@amd.com */ 17811308Santhony.gutierrez@amd.com std::vector<EntryList> entryList; 17911308Santhony.gutierrez@amd.com 18012749Sgiacomo.travaglini@arm.com Fault translateInt(const RequestPtr &req, ThreadContext *tc); 18111308Santhony.gutierrez@amd.com 18212749Sgiacomo.travaglini@arm.com Fault translate(const RequestPtr &req, ThreadContext *tc, 18311308Santhony.gutierrez@amd.com Translation *translation, Mode mode, bool &delayedResponse, 18411308Santhony.gutierrez@amd.com bool timing, int &latency); 18511308Santhony.gutierrez@amd.com 18611308Santhony.gutierrez@amd.com public: 18711308Santhony.gutierrez@amd.com // latencies for a TLB hit, miss and page fault 18811308Santhony.gutierrez@amd.com int hitLatency; 18911308Santhony.gutierrez@amd.com int missLatency1; 19011308Santhony.gutierrez@amd.com int missLatency2; 19111308Santhony.gutierrez@amd.com 19211308Santhony.gutierrez@amd.com // local_stats are as seen from the TLB 19311308Santhony.gutierrez@amd.com // without taking into account coalescing 19411308Santhony.gutierrez@amd.com Stats::Scalar localNumTLBAccesses; 19511308Santhony.gutierrez@amd.com Stats::Scalar localNumTLBHits; 19611308Santhony.gutierrez@amd.com Stats::Scalar localNumTLBMisses; 19711308Santhony.gutierrez@amd.com Stats::Formula localTLBMissRate; 19811308Santhony.gutierrez@amd.com 19911308Santhony.gutierrez@amd.com // global_stats are as seen from the 20011308Santhony.gutierrez@amd.com // CU's perspective taking into account 20111308Santhony.gutierrez@amd.com // all coalesced requests. 20211308Santhony.gutierrez@amd.com Stats::Scalar globalNumTLBAccesses; 20311308Santhony.gutierrez@amd.com Stats::Scalar globalNumTLBHits; 20411308Santhony.gutierrez@amd.com Stats::Scalar globalNumTLBMisses; 20511308Santhony.gutierrez@amd.com Stats::Formula globalTLBMissRate; 20611308Santhony.gutierrez@amd.com 20711308Santhony.gutierrez@amd.com // from the CU perspective (global) 20811308Santhony.gutierrez@amd.com Stats::Scalar accessCycles; 20911308Santhony.gutierrez@amd.com // from the CU perspective (global) 21011308Santhony.gutierrez@amd.com Stats::Scalar pageTableCycles; 21111308Santhony.gutierrez@amd.com Stats::Scalar numUniquePages; 21211308Santhony.gutierrez@amd.com // from the perspective of this TLB 21311308Santhony.gutierrez@amd.com Stats::Scalar localCycles; 21411308Santhony.gutierrez@amd.com // from the perspective of this TLB 21511308Santhony.gutierrez@amd.com Stats::Formula localLatency; 21611308Santhony.gutierrez@amd.com // I take the avg. per page and then 21711308Santhony.gutierrez@amd.com // the avg. over all pages. 21811308Santhony.gutierrez@amd.com Stats::Scalar avgReuseDistance; 21911308Santhony.gutierrez@amd.com 22014292Sjqu32@wisc.edu void regStats() override; 22111308Santhony.gutierrez@amd.com void updatePageFootprint(Addr virt_page_addr); 22211308Santhony.gutierrez@amd.com void printAccessPattern(); 22311308Santhony.gutierrez@amd.com 22411308Santhony.gutierrez@amd.com 22512749Sgiacomo.travaglini@arm.com Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, 22612749Sgiacomo.travaglini@arm.com Mode mode, int &latency); 22711308Santhony.gutierrez@amd.com 22812749Sgiacomo.travaglini@arm.com void translateTiming(const RequestPtr &req, ThreadContext *tc, 22911308Santhony.gutierrez@amd.com Translation *translation, Mode mode, 23011308Santhony.gutierrez@amd.com int &latency); 23111308Santhony.gutierrez@amd.com 23211308Santhony.gutierrez@amd.com Tick doMmuRegRead(ThreadContext *tc, Packet *pkt); 23311308Santhony.gutierrez@amd.com Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt); 23411308Santhony.gutierrez@amd.com 23512717Sbrandon.potter@amd.com TlbEntry *insert(Addr vpn, TlbEntry &entry); 23611308Santhony.gutierrez@amd.com 23711308Santhony.gutierrez@amd.com // Checkpointing 23814292Sjqu32@wisc.edu virtual void serialize(CheckpointOut& cp) const override; 23914292Sjqu32@wisc.edu virtual void unserialize(CheckpointIn& cp) override; 24011308Santhony.gutierrez@amd.com void issueTranslation(); 24111308Santhony.gutierrez@amd.com enum tlbOutcome {TLB_HIT, TLB_MISS, PAGE_WALK, MISS_RETURN}; 24212749Sgiacomo.travaglini@arm.com bool tlbLookup(const RequestPtr &req, 24312749Sgiacomo.travaglini@arm.com ThreadContext *tc, bool update_stats); 24411308Santhony.gutierrez@amd.com 24511308Santhony.gutierrez@amd.com void handleTranslationReturn(Addr addr, tlbOutcome outcome, 24611308Santhony.gutierrez@amd.com PacketPtr pkt); 24711308Santhony.gutierrez@amd.com 24811308Santhony.gutierrez@amd.com void handleFuncTranslationReturn(PacketPtr pkt, tlbOutcome outcome); 24911308Santhony.gutierrez@amd.com 25011308Santhony.gutierrez@amd.com void pagingProtectionChecks(ThreadContext *tc, PacketPtr pkt, 25112717Sbrandon.potter@amd.com TlbEntry *tlb_entry, Mode mode); 25211308Santhony.gutierrez@amd.com 25312717Sbrandon.potter@amd.com void updatePhysAddresses(Addr virt_page_addr, TlbEntry *tlb_entry, 25411308Santhony.gutierrez@amd.com Addr phys_page_addr); 25511308Santhony.gutierrez@amd.com 25611308Santhony.gutierrez@amd.com void issueTLBLookup(PacketPtr pkt); 25711308Santhony.gutierrez@amd.com 25811308Santhony.gutierrez@amd.com // CpuSidePort is the TLB Port closer to the CPU/CU side 25911308Santhony.gutierrez@amd.com class CpuSidePort : public SlavePort 26011308Santhony.gutierrez@amd.com { 26111308Santhony.gutierrez@amd.com public: 26211308Santhony.gutierrez@amd.com CpuSidePort(const std::string &_name, GpuTLB * gpu_TLB, 26311308Santhony.gutierrez@amd.com PortID _index) 26411308Santhony.gutierrez@amd.com : SlavePort(_name, gpu_TLB), tlb(gpu_TLB), index(_index) { } 26511308Santhony.gutierrez@amd.com 26611308Santhony.gutierrez@amd.com protected: 26711308Santhony.gutierrez@amd.com GpuTLB *tlb; 26811308Santhony.gutierrez@amd.com int index; 26911308Santhony.gutierrez@amd.com 27011308Santhony.gutierrez@amd.com virtual bool recvTimingReq(PacketPtr pkt); 27111308Santhony.gutierrez@amd.com virtual Tick recvAtomic(PacketPtr pkt) { return 0; } 27211308Santhony.gutierrez@amd.com virtual void recvFunctional(PacketPtr pkt); 27311308Santhony.gutierrez@amd.com virtual void recvRangeChange() { } 27411308Santhony.gutierrez@amd.com virtual void recvReqRetry(); 27513449Sgabeblack@google.com virtual void recvRespRetry() { panic("recvRespRetry called"); } 27611308Santhony.gutierrez@amd.com virtual AddrRangeList getAddrRanges() const; 27711308Santhony.gutierrez@amd.com }; 27811308Santhony.gutierrez@amd.com 27911308Santhony.gutierrez@amd.com /** 28011308Santhony.gutierrez@amd.com * MemSidePort is the TLB Port closer to the memory side 28111308Santhony.gutierrez@amd.com * If this is a last level TLB then this port will not be connected. 28211308Santhony.gutierrez@amd.com * 28311308Santhony.gutierrez@amd.com * Future action item: if we ever do real page walks, then this port 28411308Santhony.gutierrez@amd.com * should be connected to a RubyPort. 28511308Santhony.gutierrez@amd.com */ 28611308Santhony.gutierrez@amd.com class MemSidePort : public MasterPort 28711308Santhony.gutierrez@amd.com { 28811308Santhony.gutierrez@amd.com public: 28911308Santhony.gutierrez@amd.com MemSidePort(const std::string &_name, GpuTLB * gpu_TLB, 29011308Santhony.gutierrez@amd.com PortID _index) 29111308Santhony.gutierrez@amd.com : MasterPort(_name, gpu_TLB), tlb(gpu_TLB), index(_index) { } 29211308Santhony.gutierrez@amd.com 29311308Santhony.gutierrez@amd.com std::deque<PacketPtr> retries; 29411308Santhony.gutierrez@amd.com 29511308Santhony.gutierrez@amd.com protected: 29611308Santhony.gutierrez@amd.com GpuTLB *tlb; 29711308Santhony.gutierrez@amd.com int index; 29811308Santhony.gutierrez@amd.com 29911308Santhony.gutierrez@amd.com virtual bool recvTimingResp(PacketPtr pkt); 30011308Santhony.gutierrez@amd.com virtual Tick recvAtomic(PacketPtr pkt) { return 0; } 30111308Santhony.gutierrez@amd.com virtual void recvFunctional(PacketPtr pkt) { } 30211308Santhony.gutierrez@amd.com virtual void recvRangeChange() { } 30311308Santhony.gutierrez@amd.com virtual void recvReqRetry(); 30411308Santhony.gutierrez@amd.com }; 30511308Santhony.gutierrez@amd.com 30611308Santhony.gutierrez@amd.com // TLB ports on the cpu Side 30711308Santhony.gutierrez@amd.com std::vector<CpuSidePort*> cpuSidePort; 30811308Santhony.gutierrez@amd.com // TLB ports on the memory side 30911308Santhony.gutierrez@amd.com std::vector<MemSidePort*> memSidePort; 31011308Santhony.gutierrez@amd.com 31113784Sgabeblack@google.com Port &getPort(const std::string &if_name, 31213784Sgabeblack@google.com PortID idx=InvalidPortID) override; 31311308Santhony.gutierrez@amd.com 31411308Santhony.gutierrez@amd.com /** 31511308Santhony.gutierrez@amd.com * TLB TranslationState: this currently is a somewhat bastardization of 31611308Santhony.gutierrez@amd.com * the usage of SenderState, whereby the receiver of a packet is not 31711308Santhony.gutierrez@amd.com * usually supposed to need to look at the contents of the senderState, 31811308Santhony.gutierrez@amd.com * you're really only supposed to look at what you pushed on, pop it 31911308Santhony.gutierrez@amd.com * off, and send it back. 32011308Santhony.gutierrez@amd.com * 32111308Santhony.gutierrez@amd.com * However, since there is state that we want to pass to the TLBs using 32211308Santhony.gutierrez@amd.com * the send/recv Timing/Functional/etc. APIs, which don't allow for new 32311308Santhony.gutierrez@amd.com * arguments, we need a common TLB senderState to pass between TLBs, 32411308Santhony.gutierrez@amd.com * both "forwards" and "backwards." 32511308Santhony.gutierrez@amd.com * 32611308Santhony.gutierrez@amd.com * So, basically, the rule is that any packet received by a TLB port 32711308Santhony.gutierrez@amd.com * (cpuside OR memside) must be safely castable to a TranslationState. 32811308Santhony.gutierrez@amd.com */ 32911308Santhony.gutierrez@amd.com 33011308Santhony.gutierrez@amd.com struct TranslationState : public Packet::SenderState 33111308Santhony.gutierrez@amd.com { 33211308Santhony.gutierrez@amd.com // TLB mode, read or write 33311308Santhony.gutierrez@amd.com Mode tlbMode; 33411308Santhony.gutierrez@amd.com // Thread context associated with this req 33511308Santhony.gutierrez@amd.com ThreadContext *tc; 33611308Santhony.gutierrez@amd.com 33711308Santhony.gutierrez@amd.com /* 33811308Santhony.gutierrez@amd.com * TLB entry to be populated and passed back and filled in 33911308Santhony.gutierrez@amd.com * previous TLBs. Equivalent to the data cache concept of 34011308Santhony.gutierrez@amd.com * "data return." 34111308Santhony.gutierrez@amd.com */ 34212717Sbrandon.potter@amd.com TlbEntry *tlbEntry; 34311308Santhony.gutierrez@amd.com // Is this a TLB prefetch request? 34411308Santhony.gutierrez@amd.com bool prefetch; 34511308Santhony.gutierrez@amd.com // When was the req for this translation issued 34611308Santhony.gutierrez@amd.com uint64_t issueTime; 34711308Santhony.gutierrez@amd.com // Remember where this came from 34811308Santhony.gutierrez@amd.com std::vector<SlavePort*>ports; 34911308Santhony.gutierrez@amd.com 35011308Santhony.gutierrez@amd.com // keep track of #uncoalesced reqs per packet per TLB level; 35111308Santhony.gutierrez@amd.com // reqCnt per level >= reqCnt higher level 35211308Santhony.gutierrez@amd.com std::vector<int> reqCnt; 35311308Santhony.gutierrez@amd.com // TLB level this packet hit in; 0 if it hit in the page table 35411308Santhony.gutierrez@amd.com int hitLevel; 35511308Santhony.gutierrez@amd.com Packet::SenderState *saved; 35611308Santhony.gutierrez@amd.com 35711308Santhony.gutierrez@amd.com TranslationState(Mode tlb_mode, ThreadContext *_tc, 35811308Santhony.gutierrez@amd.com bool _prefetch=false, 35911308Santhony.gutierrez@amd.com Packet::SenderState *_saved=nullptr) 36011308Santhony.gutierrez@amd.com : tlbMode(tlb_mode), tc(_tc), tlbEntry(nullptr), 36111308Santhony.gutierrez@amd.com prefetch(_prefetch), issueTime(0), 36211308Santhony.gutierrez@amd.com hitLevel(0),saved(_saved) { } 36311308Santhony.gutierrez@amd.com }; 36411308Santhony.gutierrez@amd.com 36511308Santhony.gutierrez@amd.com // maximum number of permitted coalesced requests per cycle 36611308Santhony.gutierrez@amd.com int maxCoalescedReqs; 36711308Santhony.gutierrez@amd.com 36811308Santhony.gutierrez@amd.com // Current number of outstandings coalesced requests. 36911308Santhony.gutierrez@amd.com // Should be <= maxCoalescedReqs 37011308Santhony.gutierrez@amd.com int outstandingReqs; 37111308Santhony.gutierrez@amd.com 37211308Santhony.gutierrez@amd.com /** 37311308Santhony.gutierrez@amd.com * A TLBEvent is scheduled after the TLB lookup and helps us take the 37411308Santhony.gutierrez@amd.com * appropriate actions: 37511308Santhony.gutierrez@amd.com * (e.g., update TLB on a hit, 37611308Santhony.gutierrez@amd.com * send request to lower level TLB on a miss, 37711308Santhony.gutierrez@amd.com * or start a page walk if this was the last-level TLB). 37811308Santhony.gutierrez@amd.com */ 37911308Santhony.gutierrez@amd.com void translationReturn(Addr virtPageAddr, tlbOutcome outcome, 38011308Santhony.gutierrez@amd.com PacketPtr pkt); 38111308Santhony.gutierrez@amd.com 38211308Santhony.gutierrez@amd.com class TLBEvent : public Event 38311308Santhony.gutierrez@amd.com { 38411308Santhony.gutierrez@amd.com private: 38511308Santhony.gutierrez@amd.com GpuTLB *tlb; 38611308Santhony.gutierrez@amd.com Addr virtPageAddr; 38711308Santhony.gutierrez@amd.com /** 38811308Santhony.gutierrez@amd.com * outcome can be TLB_HIT, TLB_MISS, or PAGE_WALK 38911308Santhony.gutierrez@amd.com */ 39011308Santhony.gutierrez@amd.com tlbOutcome outcome; 39111308Santhony.gutierrez@amd.com PacketPtr pkt; 39211308Santhony.gutierrez@amd.com 39311308Santhony.gutierrez@amd.com public: 39411308Santhony.gutierrez@amd.com TLBEvent(GpuTLB *_tlb, Addr _addr, tlbOutcome outcome, 39511308Santhony.gutierrez@amd.com PacketPtr _pkt); 39611308Santhony.gutierrez@amd.com 39711308Santhony.gutierrez@amd.com void process(); 39811308Santhony.gutierrez@amd.com const char *description() const; 39911308Santhony.gutierrez@amd.com 40011308Santhony.gutierrez@amd.com // updateOutcome updates the tlbOutcome of a TLBEvent 40111308Santhony.gutierrez@amd.com void updateOutcome(tlbOutcome _outcome); 40211308Santhony.gutierrez@amd.com Addr getTLBEventVaddr(); 40311308Santhony.gutierrez@amd.com }; 40411308Santhony.gutierrez@amd.com 40511308Santhony.gutierrez@amd.com std::unordered_map<Addr, TLBEvent*> translationReturnEvent; 40611308Santhony.gutierrez@amd.com 40711308Santhony.gutierrez@amd.com // this FIFO queue keeps track of the virt. page addresses 40811308Santhony.gutierrez@amd.com // that are pending cleanup 40911308Santhony.gutierrez@amd.com std::queue<Addr> cleanupQueue; 41011308Santhony.gutierrez@amd.com 41111308Santhony.gutierrez@amd.com // the cleanupEvent is scheduled after a TLBEvent triggers in order to 41211308Santhony.gutierrez@amd.com // free memory and do the required clean-up 41311308Santhony.gutierrez@amd.com void cleanup(); 41411308Santhony.gutierrez@amd.com 41512085Sspwilson2@wisc.edu EventFunctionWrapper cleanupEvent; 41611308Santhony.gutierrez@amd.com 41711308Santhony.gutierrez@amd.com /** 41811308Santhony.gutierrez@amd.com * This hash map will use the virtual page address as a key 41911308Santhony.gutierrez@amd.com * and will keep track of total number of accesses per page 42011308Santhony.gutierrez@amd.com */ 42111308Santhony.gutierrez@amd.com 42211308Santhony.gutierrez@amd.com struct AccessInfo 42311308Santhony.gutierrez@amd.com { 42411308Santhony.gutierrez@amd.com unsigned int lastTimeAccessed; // last access to this page 42511308Santhony.gutierrez@amd.com unsigned int accessesPerPage; 42611308Santhony.gutierrez@amd.com // need to divide it by accessesPerPage at the end 42711308Santhony.gutierrez@amd.com unsigned int totalReuseDistance; 42811308Santhony.gutierrez@amd.com 42911308Santhony.gutierrez@amd.com /** 43011308Santhony.gutierrez@amd.com * The field below will help us compute the access distance, 43111308Santhony.gutierrez@amd.com * that is the number of (coalesced) TLB accesses that 43211308Santhony.gutierrez@amd.com * happened in between each access to this page 43311308Santhony.gutierrez@amd.com * 43411308Santhony.gutierrez@amd.com * localTLBAccesses[x] is the value of localTLBNumAccesses 43511308Santhony.gutierrez@amd.com * when the page <Addr> was accessed for the <x>th time 43611308Santhony.gutierrez@amd.com */ 43711308Santhony.gutierrez@amd.com std::vector<unsigned int> localTLBAccesses; 43811308Santhony.gutierrez@amd.com unsigned int sumDistance; 43911308Santhony.gutierrez@amd.com unsigned int meanDistance; 44011308Santhony.gutierrez@amd.com }; 44111308Santhony.gutierrez@amd.com 44211308Santhony.gutierrez@amd.com typedef std::unordered_map<Addr, AccessInfo> AccessPatternTable; 44311308Santhony.gutierrez@amd.com AccessPatternTable TLBFootprint; 44411308Santhony.gutierrez@amd.com 44511308Santhony.gutierrez@amd.com // Called at the end of simulation to dump page access stats. 44611308Santhony.gutierrez@amd.com void exitCallback(); 44711308Santhony.gutierrez@amd.com 44812085Sspwilson2@wisc.edu EventFunctionWrapper exitEvent; 44911308Santhony.gutierrez@amd.com }; 45011308Santhony.gutierrez@amd.com} 45111308Santhony.gutierrez@amd.com 45211308Santhony.gutierrez@amd.com#endif // __GPU_TLB_HH__ 453