Go to the documentation of this file.
40 #include "debug/GPUPrefetch.hh"
41 #include "debug/GPUTLB.hh"
54 gpuDevice(
p.gpu_device), size(
p.size), stats(this),
59 assert(assoc <= size);
61 allocationPolicy =
p.allocationPolicy;
62 hasMemSidePort =
false;
64 tlb.assign(size, VegaTlbEntry());
66 freeList.resize(numSets);
67 entryList.resize(numSets);
70 for (
int way = 0; way < assoc; ++way) {
71 int x =
set * assoc + way;
72 freeList[
set].push_back(&
tlb.at(
x));
77 setMask = numSets - 1;
79 maxCoalescedReqs =
p.maxOutstandingReqs;
83 hitLatency =
p.hitLatency;
84 missLatency1 =
p.missLatency1;
85 missLatency2 =
p.missLatency2;
88 for (
size_t i = 0;
i <
p.port_cpu_side_ports_connection_count; ++
i) {
89 cpuSidePort.push_back(
new CpuSidePort(
csprintf(
"%s-port%d",
94 for (
size_t i = 0;
i <
p.port_mem_side_ports_connection_count; ++
i) {
95 memSidePort.push_back(
new MemSidePort(
csprintf(
"%s-port%d",
100 walker->setTLB(
this);
105 gpuDevice->getVM().registerTLB(
this);
116 if (if_name ==
"cpu_side_ports") {
118 panic(
"TLBCoalescer::getPort: unknown index %d\n", idx);
122 }
else if (if_name ==
"mem_side_ports") {
124 panic(
"TLBCoalescer::getPort: unknown index %d\n", idx);
131 panic(
"TLBCoalescer::getPort: unknown port %s\n", if_name);
138 DPRINTF(GPUTLB,
"GPUTLB: Raising page fault.\n");
146 return std::make_shared<PageFault>(
vaddr, code,
true,
mode,
true);
153 return (
vaddr & ~pageMask);
159 VegaTlbEntry *newEntry =
nullptr;
168 Addr real_vpn = vpn & ~(entry.size() - 1);
173 Addr real_ppn = entry.paddr & ~(entry.size() - 1);
177 DPRINTF(GPUTLB,
"Inserted %#lx -> %#lx of size %#lx into set %d\n",
178 real_vpn, real_ppn, entry.size(),
set);
189 newEntry->vaddr = real_vpn;
190 newEntry->paddr = real_ppn;
196 GpuTLB::EntryList::iterator
207 int page_size = (*entry)->size();
209 if ((*entry)->vaddr <=
va && (*entry)->vaddr + page_size >
va) {
210 DPRINTF(GPUTLB,
"Matched vaddr %#x to entry starting at %#x "
211 "with size %#x.\n",
va, (*entry)->vaddr, page_size);
242 DPRINTF(GPUTLB,
"Invalidating all entries.\n");
283 VegaTlbEntry *entry =
lookup(alignedVaddr,
true);
343 bool update_stats = !sender_state->
isPrefetch;
345 DPRINTF(GPUTLB,
"Translation req. for virt. page addr %#x\n",
348 int req_cnt = sender_state->
reqCnt.back();
360 auto entry =
tlbLookup(tmp_req, update_stats);
365 VegaTlbEntry *entry =
lookup(virt_page_addr,
false);
369 pkt->
req->setSystemReq(entry->pte.s);
373 new VegaTlbEntry(1 , virt_page_addr, alignedPaddr,
374 entry->logBytes, entry->pte);
397 new TLBEvent(
this, virt_page_addr, lookup_outcome, pkt);
400 panic(
"Virtual Page Address %#x already has a return event\n",
407 DPRINTF(GPUTLB,
"schedule translationReturnEvent @ curTick %d\n",
415 :
Event(CPU_Tick_Pri),
tlb(_tlb), virtPageAddr(_addr),
416 outcome(tlb_outcome), pkt(_pkt)
429 bool badWrite = (!tlb_entry->writable());
435 fatal(
"Page fault on addr %lx PTE=%#lx", pkt->
req->getVaddr(),
436 (uint64_t)tlb_entry->pte);
443 DPRINTF(GPUTLB,
"WalkerResponse for %#lx. Entry: (%#lx, %#lx, %#lx)\n",
444 pkt->
req->getVaddr(), entry.vaddr, entry.paddr, entry.size());
450 Addr paddr =
insertBits(page_addr, entry.logBytes - 1, 0, entry.vaddr);
451 pkt->
req->setPaddr(paddr);
452 pkt->
req->setSystemReq(entry.pte.s);
456 sender_state->
tlbEntry =
new VegaTlbEntry(entry);
478 VegaTlbEntry *local_entry, *new_entry;
480 int req_cnt = sender_state->
reqCnt.back();
481 bool update_stats = !sender_state->
isPrefetch;
489 DPRINTF(GPUTLB,
"Translation Done - TLB Hit for addr %#x\n",
491 local_entry = safe_cast<VegaTlbEntry *>(sender_state->
tlbEntry);
493 DPRINTF(GPUTLB,
"Translation Done - TLB Miss for addr %#x\n",
501 new_entry = safe_cast<VegaTlbEntry *>(sender_state->
tlbEntry);
503 local_entry = new_entry;
506 assert(new_entry->pte);
507 DPRINTF(GPUTLB,
"allocating entry w/ addr %#lx of size %#lx\n",
508 virt_page_addr, new_entry->size());
510 local_entry =
insert(virt_page_addr, *new_entry);
521 DPRINTF(GPUTLB,
"Entry found with vaddr %#x, doing protection checks "
522 "while paddr was %#x.\n", local_entry->vaddr,
526 int page_size = local_entry->size();
527 Addr paddr = local_entry->paddr | (
vaddr & (page_size - 1));
528 DPRINTF(GPUTLB,
"Translated %#x -> %#x.\n",
vaddr, paddr);
536 pkt->
req->setPaddr(paddr);
538 if (local_entry->uncacheable()) {
547 DPRINTF(GPUTLB,
"Scheduled %#lx for cleanup\n", virt_page_addr);
567 DPRINTF(GPUTLB,
"Triggered TLBEvent for addr %#x\n", virtPageAddr);
575 int req_cnt = tmp_sender_state->
reqCnt.back();
576 bool update_stats = !tmp_sender_state->
isPrefetch;
584 DPRINTF(GPUTLB,
"This is a TLB miss\n");
596 tmp_sender_state->
pasId = 0;
599 DPRINTF(GPUTLB,
"Failed sending translation request to "
600 "lower level TLB for addr %#x\n", virtPageAddr);
604 DPRINTF(GPUTLB,
"Sent translation request to lower level "
605 "TLB for addr %#x\n", virtPageAddr);
609 DPRINTF(GPUTLB,
"Last level TLB - start a page walk for "
610 "addr %#x\n", virtPageAddr);
626 DPRINTF(GPUTLB,
"Doing a page walk for address %#x\n",
641 panic(
"Unexpected TLB outcome %d", outcome);
648 tlb->translationReturn(virtPageAddr, outcome, pkt);
654 return "trigger translationDoneEvent";
682 if (
tlb->outstandingReqs <
tlb->maxCoalescedReqs) {
683 assert(!
tlb->translationReturnEvent.count(virt_page_addr));
684 tlb->issueTLBLookup(pkt);
686 tlb->outstandingReqs++;
689 DPRINTF(GPUTLB,
"Reached maxCoalescedReqs number %d\n",
690 tlb->outstandingReqs);
691 tlb->stats.maxDownstreamReached++;
696 if (
tlb->outstandingReqs >
tlb->stats.outstandingReqsMax.value())
697 tlb->stats.outstandingReqsMax =
tlb->outstandingReqs;
719 VegaTlbEntry *local_entry, *new_entry;
722 DPRINTF(GPUTLB,
"Functional Translation Done - TLB hit for addr "
725 local_entry = safe_cast<VegaTlbEntry *>(sender_state->
tlbEntry);
727 DPRINTF(GPUTLB,
"Functional Translation Done - TLB miss for addr "
735 new_entry = safe_cast<VegaTlbEntry *>(sender_state->
tlbEntry);
737 local_entry = new_entry;
742 DPRINTF(GPUTLB,
"allocating entry w/ addr %#lx\n",
745 local_entry =
insert(virt_page_addr, *new_entry);
751 DPRINTF(GPUTLB,
"Entry found with vaddr %#x, doing protection checks "
752 "while paddr was %#x.\n", local_entry->vaddr,
769 int page_size = local_entry->size();
770 Addr paddr = local_entry->paddr | (
vaddr & (page_size - 1));
771 DPRINTF(GPUTLB,
"Translated %#x -> %#x.\n",
vaddr, paddr);
773 pkt->
req->setPaddr(paddr);
775 if (local_entry->uncacheable())
787 bool update_stats = !sender_state->
isPrefetch;
793 bool success =
tlb->tlbLookup(pkt->
req, update_stats);
799 tlb->stats.globalNumTLBAccesses++;
803 tlb->stats.globalNumTLBHits++;
805 tlb->stats.globalNumTLBMisses++;
810 if (
tlb->hasMemSidePort) {
812 tlb->memSidePort[0]->sendFunctional(pkt);
818 DPRINTF(GPUTLB,
"Doing a page walk for address %#x\n",
822 [[maybe_unused]]
Addr alignedVaddr =
823 tlb->pageAlign(virt_page_addr);
824 assert(alignedVaddr == virt_page_addr);
830 Addr base =
tlb->gpuDevice->getVM().getPageTableBase(1);
831 tlb->walker->setDevRequestor(
tlb->gpuDevice->vramRequestorId());
836 BaseMMU::Mode::Read);
838 fatal(
"Translation fault in TLB at %d!", __LINE__);
846 Addr alignedPaddr =
tlb->pageAlign(paddr);
847 pkt->
req->setPaddr(paddr);
848 pkt->
req->setSystemReq(pte.s);
856 new VegaTlbEntry(1 , virt_page_addr,
857 alignedPaddr, logBytes, pte);
867 new VegaTlbEntry(1 , virt_page_addr,
868 alignedPaddr, logBytes, pte);
879 VegaTlbEntry *entry =
tlb->lookup(virt_page_addr, update_stats);
883 DPRINTF(GPUPrefetch,
"Functional Hit for vaddr %#x\n",
887 sender_state->
tlbEntry =
new VegaTlbEntry(1 , entry->vaddr,
888 entry->paddr, entry->logBytes,
896 tlb->handleFuncTranslationReturn(pkt, tlb_outcome);
904 panic(
"recvReqRetry called");
927 DPRINTF(GPUTLB,
"MemSidePort recvTiming for virt_page_addr %#x\n",
930 TLBEvent *tlb_event =
tlb->translationReturnEvent[virt_page_addr];
945 panic(
"recvReqRetry called");
955 DPRINTF(GPUTLB,
"Deleting return event for %#lx\n", cleanup_addr);
959 delete old_tlb_event;
975 : statistics::
Group(parent),
976 ADD_STAT(maxDownstreamReached,
"Number of refused translation requests"),
977 ADD_STAT(outstandingReqsMax,
"Maximum count in coalesced request queue"),
978 ADD_STAT(localNumTLBAccesses,
"Number of TLB accesses"),
979 ADD_STAT(localNumTLBHits,
"Number of TLB hits"),
980 ADD_STAT(localNumTLBMisses,
"Number of TLB misses"),
981 ADD_STAT(localTLBMissRate,
"TLB miss rate"),
982 ADD_STAT(globalNumTLBAccesses,
"Number of TLB accesses"),
983 ADD_STAT(globalNumTLBHits,
"Number of TLB hits"),
984 ADD_STAT(globalNumTLBMisses,
"Number of TLB misses"),
985 ADD_STAT(globalTLBMissRate,
"TLB miss rate"),
986 ADD_STAT(accessCycles,
"Cycles spent accessing this TLB level"),
987 ADD_STAT(pageTableCycles,
"Cycles spent accessing the page table"),
988 ADD_STAT(localCycles,
"Number of cycles spent in queue for all "
990 ADD_STAT(localLatency,
"Avg. latency over incoming coalesced reqs")
statistics::Scalar pageTableCycles
Tick curTick()
The universal simulation clock.
#define fatal(...)
This implements a cprintf based fatal() function.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
VegaTlbEntry * tlbLookup(const RequestPtr &req, bool update_stats)
TLB_lookup will only perform a TLB lookup returning the TLB entry on a TLB hit and nullptr on a TLB m...
constexpr decltype(nullptr) NoFault
std::vector< CpuSidePort * > cpuSidePort
Cycles curCycle() const
Determine the current cycle, corresponding to a tick aligned to a clock edge.
std::queue< Addr > cleanupQueue
GPU TranslationState: this currently is a somewhat bastardization of the usage of SenderState,...
std::vector< EntryList > freeList
void issueTLBLookup(PacketPtr pkt)
Do the TLB lookup for this coalesced request and schedule another event <TLB access latency> cycles l...
VegaTlbEntry * lookup(Addr va, bool update_lru=true)
RequestPtr req
A pointer to the original request.
Addr pageAlign(Addr vaddr)
bool FA
true if this is a fully-associative TLB
statistics::Scalar localCycles
GpuTLB(const VegaGPUTLBParams &p)
EntryList::iterator lookupIt(Addr va, bool update_lru=true)
VegaTlbEntry * insert(Addr vpn, VegaTlbEntry &entry)
virtual bool recvTimingReq(PacketPtr pkt)
recvTiming receives a coalesced timing request from a TLBCoalescer and it calls issueTLBLookup() It o...
statistics::Scalar localNumTLBHits
void startTiming(PacketPtr pkt, Addr base, Addr vaddr, BaseMMU::Mode mode)
void schedule(Event &event, Tick when)
statistics::Scalar globalNumTLBAccesses
void walkerResponse(VegaTlbEntry &entry, PacketPtr pkt)
std::string csprintf(const char *format, const Args &...args)
statistics::Scalar globalNumTLBHits
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
std::vector< EntryList > entryList
An entryList per set is the equivalent of an LRU stack; it's used to guide replacement decisions.
Cycles is a wrapper class for representing cycle counts, i.e.
void demapPage(Addr va, uint64_t asn)
const char * description() const
Return a C string describing the event.
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
bool allocationPolicy
Allocation Policy: true if we always allocate on a hit, false otherwise.
@ UNCACHEABLE
The request is to an uncacheable address.
void updateOutcome(tlbOutcome _outcome)
virtual void recvFunctional(PacketPtr pkt)
Receive a functional request packet from the peer.
bool hasMemSidePort
if true, then this is not the last level TLB
std::shared_ptr< FaultBase > Fault
std::unordered_map< Addr, TLBEvent * > translationReturnEvent
Tick cyclesToTicks(Cycles c) const
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
statistics::Formula globalTLBMissRate
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
statistics::Scalar accessCycles
virtual void recvReqRetry()
gem5::VegaISA::GpuTLB::VegaTLBStats stats
statistics::Scalar localNumTLBMisses
static const Priority Maximum_Pri
Maximum priority.
std::shared_ptr< Request > RequestPtr
statistics::Formula localLatency
TLBEvent(GpuTLB *_tlb, Addr _addr, tlbOutcome outcome, PacketPtr _pkt)
virtual bool recvTimingResp(PacketPtr pkt)
MemSidePort receives the packet back.
statistics::Scalar globalNumTLBMisses
constexpr T insertBits(T val, unsigned first, unsigned last, B bit_val)
Returns val with bits first to last set to the LSBs of bit_val.
static constexpr T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
std::vector< int > reqCnt
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
SenderState * senderState
This packet's sender state.
const std::string & name()
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
Addr getPageTableBase(uint16_t vmid)
void handleTranslationReturn(Addr addr, tlbOutcome outcome, PacketPtr pkt)
handleTranslationReturn is called on a TLB hit, when a TLB miss returns or when a page fault returns.
Fault createPagefault(Addr vaddr, Mode mode)
void makeTimingResponse()
Ports are used to interface objects to each other.
virtual AddrRangeList getAddrRanges() const
Get a list of the non-overlapping address ranges the owner is responsible for.
void pagingProtectionChecks(PacketPtr pkt, VegaTlbEntry *tlb_entry, Mode mode)
Do Paging protection checks.
void handleFuncTranslationReturn(PacketPtr pkt, tlbOutcome outcome)
handleFuncTranslationReturn is called on a TLB hit, when a TLB miss returns or when a page fault retu...
EventFunctionWrapper cleanupEvent
std::vector< MemSidePort * > memSidePort
std::vector< VegaTlbEntry > tlb
virtual void serialize(CheckpointOut &cp) const override
Serialize an object.
std::ostream CheckpointOut
virtual void unserialize(CheckpointIn &cp) override
Unserialize an object.
void translationReturn(Addr virtPageAddr, tlbOutcome outcome, PacketPtr pkt)
A TLBEvent is scheduled after the TLB lookup and helps us take the appropriate actions: (e....
void setDevRequestor(RequestorID mid)
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
virtual void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
statistics::Scalar localNumTLBAccesses
RequestorID vramRequestorId()
Methods related to translations and system/device memory.
VegaTLBStats(statistics::Group *parent)
bool scheduled() const
Determine if the current event is scheduled.
statistics::Formula localTLBMissRate
#define panic(...)
This implements a cprintf based panic() function.
Generated on Thu Jun 16 2022 10:41:09 for gem5 by doxygen 1.8.17