40 #include "debug/GPUTLB.hh"
48 TLBProbesPerCycle(
p.probesPerCycle),
49 coalescingWindow(
p.coalescingWindow),
50 disableCoalescing(
p.disableCoalescing),
52 "Probe the TLB below",
54 cleanupEvent([
this]{ processCleanupEvent(); },
55 "Cleanup issuedTranslationsTable hashmap",
60 for (
size_t i = 0;
i <
p.port_cpu_side_ports_connection_count; ++
i) {
66 for (
size_t i = 0;
i <
p.port_mem_side_ports_connection_count; ++
i) {
75 if (if_name ==
"cpu_side_ports") {
77 panic(
"TLBCoalescer::getPort: unknown index %d\n", idx);
81 }
else if (if_name ==
"mem_side_ports") {
83 panic(
"TLBCoalescer::getPort: unknown index %d\n", idx);
88 panic(
"TLBCoalescer::getPort: unknown port %s\n", if_name);
104 TheISA::GpuTLB::TranslationState *incoming_state =
105 safe_cast<TheISA::GpuTLB::TranslationState*>(incoming_pkt->
senderState);
107 TheISA::GpuTLB::TranslationState *coalesced_state =
108 safe_cast<TheISA::GpuTLB::TranslationState*>(coalesced_pkt->
senderState);
118 if (incoming_virt_page_addr != coalesced_virt_page_addr)
127 if (incoming_mode != coalesced_mode)
133 if (!incoming_state->isPrefetch)
134 coalesced_state->reqCnt.back() += incoming_state->reqCnt.back();
148 DPRINTF(GPUTLB,
"Update phys. addr. for %d coalesced reqs for page %#x\n",
151 TheISA::GpuTLB::TranslationState *sender_state =
152 safe_cast<TheISA::GpuTLB::TranslationState*>(pkt->
senderState);
154 TheISA::TlbEntry *tlb_entry = sender_state->tlbEntry;
156 Addr first_entry_vaddr = tlb_entry->vaddr;
157 Addr first_entry_paddr = tlb_entry->paddr;
158 int page_size = tlb_entry->size();
159 bool uncacheable = tlb_entry->uncacheable;
160 int first_hit_level = sender_state->hitLevel;
165 Addr phys_page_paddr = pkt->
req->getPaddr();
166 phys_page_paddr &= ~(page_size - 1);
170 TheISA::GpuTLB::TranslationState *sender_state =
171 safe_cast<TheISA::GpuTLB::TranslationState*>(
176 if (!sender_state->isPrefetch)
177 sender_state->reqCnt.pop_back();
186 Addr paddr = phys_page_paddr;
187 paddr |= (local_pkt->
req->getVaddr() & (page_size - 1));
188 local_pkt->
req->setPaddr(paddr);
195 auto p = sender_state->tc->getProcessPtr();
196 sender_state->tlbEntry =
197 new TheISA::TlbEntry(
p->pid(), first_entry_vaddr,
198 first_entry_paddr,
false,
false);
203 sender_state->hitLevel = first_hit_level;
207 sender_state->ports.pop_back();
237 bool didCoalesce =
false;
239 int coalescedReq_cnt = 0;
241 TheISA::GpuTLB::TranslationState *sender_state =
242 safe_cast<TheISA::GpuTLB::TranslationState*>(pkt->
senderState);
245 sender_state->ports.push_back(
this);
247 bool update_stats = !sender_state->isPrefetch;
257 if (!sender_state->reqCnt.empty())
258 req_cnt = sender_state->reqCnt.back();
260 sender_state->reqCnt.push_back(req_cnt);
264 req_cnt = sender_state->reqCnt.back();
265 DPRINTF(GPUTLB,
"receiving pkt w/ req_cnt %d\n", req_cnt);
275 if (!sender_state->issueTime)
276 sender_state->issueTime =
curTick();
289 for (
int i = 0;
i < coalescedReq_cnt; ++
i) {
295 DPRINTF(GPUTLB,
"Coalesced req %i w/ tick_index %d has %d reqs\n",
307 if (!coalescedReq_cnt || !didCoalesce) {
312 new_array.push_back(pkt);
315 DPRINTF(GPUTLB,
"coalescerFIFO[%d] now has %d coalesced reqs after "
316 "push\n", tick_index,
333 panic(
"recvReqRetry called");
340 TheISA::GpuTLB::TranslationState *sender_state =
341 safe_cast<TheISA::GpuTLB::TranslationState*>(pkt->
senderState);
343 bool update_stats = !sender_state->isPrefetch;
346 coalescer->stats.uncoalescedAccesses++;
353 int map_count = coalescer->issuedTranslationsTable.count(virt_page_addr);
356 DPRINTF(GPUTLB,
"Warning! Functional access to addr %#x sees timing "
357 "req. pending\n", virt_page_addr);
360 coalescer->memSidePort[0]->sendFunctional(pkt);
376 coalescer->updatePhysAddresses(pkt);
385 if (!coalescer->probeTLBEvent.scheduled())
386 coalescer->schedule(coalescer->probeTLBEvent,
387 curTick() + coalescer->clockPeriod());
393 fatal(
"Memory side recvFunctional() not implemented in TLB coalescer.\n");
414 bool rejected =
false;
420 DPRINTF(GPUTLB,
"triggered TLBCoalescer %s\n", __func__);
424 int coalescedReq_cnt = iter->second.size();
426 int vector_index = 0;
428 DPRINTF(GPUTLB,
"coalescedReq_cnt is %d for tick_index %d\n",
429 coalescedReq_cnt, iter->first);
431 while (
i < coalescedReq_cnt) {
433 PacketPtr first_packet = iter->second[vector_index][0];
444 DPRINTF(GPUTLB,
"Cannot issue - There are pending reqs for "
445 "page %#x\n", virt_page_addr);
454 if (!
memSidePort[0]->sendTimingReq(first_packet)) {
455 DPRINTF(GPUTLB,
"Failed to send TLB request for page %#x\n",
463 TheISA::GpuTLB::TranslationState *tmp_sender_state =
464 safe_cast<TheISA::GpuTLB::TranslationState*>
467 bool update_stats = !tmp_sender_state->isPrefetch;
473 int req_cnt = tmp_sender_state->reqCnt.back();
476 DPRINTF(GPUTLB,
"%s sending pkt w/ req_cnt %d\n",
481 int pkt_cnt = iter->second[vector_index].size();
485 DPRINTF(GPUTLB,
"Successfully sent TLB request for page %#x",
490 = iter->second[vector_index];
493 iter->second.erase(iter->second.begin() + vector_index);
495 if (iter->second.empty())
496 assert(
i == coalescedReq_cnt);
506 if (iter->second.empty()) {
522 DPRINTF(GPUTLB,
"Cleanup - Delete coalescer entry with key %#x\n",
528 : statistics::
Group(parent),
529 ADD_STAT(uncoalescedAccesses,
"Number of uncoalesced TLB accesses"),
530 ADD_STAT(coalescedAccesses,
"Number of coalesced TLB accesses"),
531 ADD_STAT(queuingCycles,
"Number of cycles spent in queue"),
533 "Number of cycles spent in queue for all incoming reqs"),
534 ADD_STAT(localLatency,
"Avg. latency over all incoming pkts")