gem5 v24.1.0.1
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
tlb.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011-2021 Advanced Micro Devices, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 */
32
34
35#include <cmath>
36#include <cstring>
37
39#include "arch/x86/faults.hh"
41#include "arch/x86/page_size.hh"
42#include "arch/x86/pagetable.hh"
44#include "arch/x86/regs/misc.hh"
45#include "arch/x86/regs/msr.hh"
48#include "base/bitfield.hh"
49#include "base/logging.hh"
50#include "base/output.hh"
51#include "base/trace.hh"
52#include "cpu/base.hh"
53#include "cpu/thread_context.hh"
54#include "debug/GPUPrefetch.hh"
55#include "debug/GPUTLB.hh"
56#include "mem/packet_access.hh"
57#include "mem/page_table.hh"
58#include "mem/request.hh"
59#include "sim/process.hh"
60#include "sim/pseudo_inst.hh"
61
62namespace gem5
63{
64namespace X86ISA
65{
66
68 : ClockedObject(p), configAddress(0), size(p.size),
69 cleanupEvent([this]{ cleanup(); }, name(), false,
71 exitEvent([this]{ exitCallback(); }, name()), stats(this)
72 {
73 assoc = p.assoc;
74 assert(assoc <= size);
76 allocationPolicy = p.allocationPolicy;
77 hasMemSidePort = false;
78 accessDistance = p.accessDistance;
79
80 tlb.assign(size, TlbEntry());
81
82 freeList.resize(numSets);
83 entryList.resize(numSets);
84
85 for (int set = 0; set < numSets; ++set) {
86 for (int way = 0; way < assoc; ++way) {
87 int x = set * assoc + way;
88 freeList[set].push_back(&tlb.at(x));
89 }
90 }
91
92 FA = (size == assoc);
93
102 setMask = numSets - 1;
103
104 maxCoalescedReqs = p.maxOutstandingReqs;
105
106 // Do not allow maxCoalescedReqs to be more than the TLB associativity
107 if (maxCoalescedReqs > assoc) {
109 cprintf("Forcing maxCoalescedReqs to %d (TLB assoc.) \n", assoc);
110 }
111
112 outstandingReqs = 0;
113 hitLatency = p.hitLatency;
114 missLatency1 = p.missLatency1;
115 missLatency2 = p.missLatency2;
116
117 // create the response ports based on the number of connected ports
118 for (size_t i = 0; i < p.port_cpu_side_ports_connection_count; ++i) {
119 cpuSidePort.push_back(new CpuSidePort(csprintf("%s-port%d",
120 name(), i), this, i));
121 }
122
123 // create the request ports based on the number of connected ports
124 for (size_t i = 0; i < p.port_mem_side_ports_connection_count; ++i) {
125 memSidePort.push_back(new MemSidePort(csprintf("%s-port%d",
126 name(), i), this, i));
127 }
128 }
129
130 // fixme: this is never called?
132 {
133 // make sure all the hash-maps are empty
134 assert(translationReturnEvent.empty());
135 }
136
137 Port &
138 GpuTLB::getPort(const std::string &if_name, PortID idx)
139 {
140 if (if_name == "cpu_side_ports") {
141 if (idx >= static_cast<PortID>(cpuSidePort.size())) {
142 panic("TLBCoalescer::getPort: unknown index %d\n", idx);
143 }
144
145 return *cpuSidePort[idx];
146 } else if (if_name == "mem_side_ports") {
147 if (idx >= static_cast<PortID>(memSidePort.size())) {
148 panic("TLBCoalescer::getPort: unknown index %d\n", idx);
149 }
150
151 hasMemSidePort = true;
152
153 return *memSidePort[idx];
154 } else {
155 panic("TLBCoalescer::getPort: unknown port %s\n", if_name);
156 }
157 }
158
159 TlbEntry*
161 {
162 TlbEntry *newEntry = nullptr;
163
168 int set = (vpn >> PageShift) & setMask;
169
170 if (!freeList[set].empty()) {
171 newEntry = freeList[set].front();
172 freeList[set].pop_front();
173 } else {
174 newEntry = entryList[set].back();
175 entryList[set].pop_back();
176 }
177
178 *newEntry = entry;
179 newEntry->vaddr = vpn;
180 entryList[set].push_front(newEntry);
181
182 return newEntry;
183 }
184
185 GpuTLB::EntryList::iterator
186 GpuTLB::lookupIt(Addr va, bool update_lru)
187 {
188 int set = (va >> PageShift) & setMask;
189
190 if (FA) {
191 assert(!set);
192 }
193
194 auto entry = entryList[set].begin();
195 for (; entry != entryList[set].end(); ++entry) {
196 int page_size = (*entry)->size();
197
198 if ((*entry)->vaddr <= va && (*entry)->vaddr + page_size > va) {
199 DPRINTF(GPUTLB, "Matched vaddr %#x to entry starting at %#x "
200 "with size %#x.\n", va, (*entry)->vaddr, page_size);
201
202 if (update_lru) {
203 entryList[set].push_front(*entry);
204 entryList[set].erase(entry);
205 entry = entryList[set].begin();
206 }
207
208 break;
209 }
210 }
211
212 return entry;
213 }
214
215 TlbEntry*
216 GpuTLB::lookup(Addr va, bool update_lru)
217 {
218 int set = (va >> PageShift) & setMask;
219
220 auto entry = lookupIt(va, update_lru);
221
222 if (entry == entryList[set].end())
223 return nullptr;
224 else
225 return *entry;
226 }
227
228 void
230 {
231 DPRINTF(GPUTLB, "Invalidating all entries.\n");
232
233 for (int i = 0; i < numSets; ++i) {
234 while (!entryList[i].empty()) {
235 TlbEntry *entry = entryList[i].front();
236 entryList[i].pop_front();
237 freeList[i].push_back(entry);
238 }
239 }
240 }
241
242 void
244 {
246 }
247
248 void
250 {
251 DPRINTF(GPUTLB, "Invalidating all non global entries.\n");
252
253 for (int i = 0; i < numSets; ++i) {
254 for (auto entryIt = entryList[i].begin();
255 entryIt != entryList[i].end();) {
256 if (!(*entryIt)->global) {
257 freeList[i].push_back(*entryIt);
258 entryList[i].erase(entryIt++);
259 } else {
260 ++entryIt;
261 }
262 }
263 }
264 }
265
266 void
267 GpuTLB::demapPage(Addr va, uint64_t asn)
268 {
269
270 int set = (va >> PageShift) & setMask;
271 auto entry = lookupIt(va, false);
272
273 if (entry != entryList[set].end()) {
274 freeList[set].push_back(*entry);
275 entryList[set].erase(entry);
276 }
277 }
278
279
280
281 namespace
282 {
283
284 Cycles
285 localMiscRegAccess(bool read, RegIndex regNum,
286 ThreadContext *tc, PacketPtr pkt)
287 {
288 if (read) {
289 RegVal data = htole(tc->readMiscReg(regNum));
290 // Make sure we don't trot off the end of data.
291 pkt->setData((uint8_t *)&data);
292 } else {
293 RegVal data = htole(tc->readMiscRegNoEffect(regNum));
294 tc->setMiscReg(regNum, letoh(data));
295 }
296 return Cycles(1);
297 }
298
299 } // anonymous namespace
300
301 Fault
303 {
304 DPRINTF(GPUTLB, "Addresses references internal memory.\n");
305 Addr vaddr = req->getVaddr();
306 Addr prefix = (vaddr >> 3) & IntAddrPrefixMask;
307
308 if (prefix == IntAddrPrefixCPUID) {
309 panic("CPUID memory space not yet implemented!\n");
310 } else if (prefix == IntAddrPrefixMSR) {
311 vaddr = (vaddr >> 3) & ~IntAddrPrefixMask;
312
313 RegIndex regNum;
314 if (!msrAddrToIndex(regNum, vaddr))
315 return std::make_shared<GeneralProtection>(0);
316
317 req->setLocalAccessor(
318 [read, regNum](ThreadContext *tc, PacketPtr pkt)
319 {
320 return localMiscRegAccess(read, regNum, tc, pkt);
321 }
322 );
323
324 return NoFault;
325 } else if (prefix == IntAddrPrefixIO) {
326 // TODO If CPL > IOPL or in virtual mode, check the I/O permission
327 // bitmap in the TSS.
328
329 Addr IOPort = vaddr & ~IntAddrPrefixMask;
330 // Make sure the address fits in the expected 16 bit IO address
331 // space.
332 assert(!(IOPort & ~0xFFFF));
333 if (IOPort == 0xCF8 && req->getSize() == 4) {
334 req->setLocalAccessor(
335 [read](ThreadContext *tc, PacketPtr pkt)
336 {
337 return localMiscRegAccess(
338 read, misc_reg::PciConfigAddress, tc, pkt);
339 }
340 );
341 } else if ((IOPort & ~mask(2)) == 0xCFC) {
345 if (bits(configAddress, 31, 31)) {
346 req->setPaddr(PhysAddrPrefixPciConfig |
347 mbits(configAddress, 30, 2) |
348 (IOPort & mask(2)));
349 } else {
350 req->setPaddr(PhysAddrPrefixIO | IOPort);
351 }
352 } else {
354 req->setPaddr(PhysAddrPrefixIO | IOPort);
355 }
356 return NoFault;
357 } else {
358 panic("Access to unrecognized internal address space %#x.\n",
359 prefix);
360 }
361 }
362
370 bool
372 ThreadContext *tc, bool update_stats)
373 {
374 bool tlb_hit = false;
375 #ifndef NDEBUG
376 uint32_t flags = req->getFlags();
377 int seg = flags & SegmentFlagMask;
378 #endif
379
380 assert(seg != segment_idx::Ms);
381 Addr vaddr = req->getVaddr();
382 if (req->hasNoAddr()) {
383 return true;
384 } else {
385 DPRINTF(GPUTLB, "TLB Lookup for vaddr %#x.\n", vaddr);
386 }
387 HandyM5Reg m5Reg = tc->readMiscRegNoEffect(misc_reg::M5Reg);
388
389 if (m5Reg.prot) {
390 DPRINTF(GPUTLB, "In protected mode.\n");
391 // make sure we are in 64-bit mode
392 assert(m5Reg.mode == LongMode);
393
394 // If paging is enabled, do the translation.
395 if (m5Reg.paging) {
396 DPRINTF(GPUTLB, "Paging enabled.\n");
397 //update LRU stack on a hit
398 TlbEntry *entry = lookup(vaddr, true);
399
400 if (entry)
401 tlb_hit = true;
402
403 if (!update_stats) {
404 // functional tlb access for memory initialization
405 // i.e., memory seeding or instr. seeding -> don't update
406 // TLB and stats
407 return tlb_hit;
408 }
409
411
412 if (!entry) {
414 } else {
416 }
417 }
418 }
419
420 return tlb_hit;
421 }
422
423 Fault
425 Translation *translation, Mode mode,
426 bool &delayedResponse, bool timing, int &latency)
427 {
428 uint32_t flags = req->getFlags();
429 int seg = flags & SegmentFlagMask;
430 bool storeCheck = flags & Request::READ_MODIFY_WRITE;
431
432 // If this is true, we're dealing with a request
433 // to a non-memory address space.
434 if (seg == segment_idx::Ms) {
435 return translateInt(mode == Mode::Read, req, tc);
436 }
437
438 delayedResponse = false;
439 Addr vaddr = req->getVaddr();
440 DPRINTF(GPUTLB, "Translating vaddr %#x.\n", vaddr);
441
442 HandyM5Reg m5Reg = tc->readMiscRegNoEffect(misc_reg::M5Reg);
443
444 // If protected mode has been enabled...
445 if (m5Reg.prot) {
446 DPRINTF(GPUTLB, "In protected mode.\n");
447 // If we're not in 64-bit mode, do protection/limit checks
448 if (m5Reg.mode != LongMode) {
449 DPRINTF(GPUTLB, "Not in long mode. Checking segment "
450 "protection.\n");
451
452 // Check for a null segment selector.
453 if (!(seg == segment_idx::Tsg || seg == segment_idx::Idtr ||
456 return std::make_shared<GeneralProtection>(0);
457 }
458
459 bool expandDown = false;
461
462 if (seg >= segment_idx::Es && seg <= segment_idx::Hs) {
463 if (!attr.writable && (mode == BaseMMU::Write ||
464 storeCheck))
465 return std::make_shared<GeneralProtection>(0);
466
467 if (!attr.readable && mode == BaseMMU::Read)
468 return std::make_shared<GeneralProtection>(0);
469
470 expandDown = attr.expandDown;
471
472 }
473
477 int size = 8 << logSize;
478
479 Addr offset = (vaddr - base) & mask(size);
480 Addr endOffset = offset + req->getSize() - 1;
481
482 if (expandDown) {
483 DPRINTF(GPUTLB, "Checking an expand down segment.\n");
484 warn_once("Expand down segments are untested.\n");
485
486 if (offset <= limit || endOffset <= limit)
487 return std::make_shared<GeneralProtection>(0);
488 } else {
489 if (offset > limit || endOffset > limit)
490 return std::make_shared<GeneralProtection>(0);
491 }
492 }
493
494 // If paging is enabled, do the translation.
495 if (m5Reg.paging) {
496 DPRINTF(GPUTLB, "Paging enabled.\n");
497 // The vaddr already has the segment base applied.
498 TlbEntry *entry = lookup(vaddr);
500
501 if (!entry) {
503 if (timing) {
504 latency = missLatency1;
505 }
506
507 if (FullSystem) {
508 fatal("GpuTLB doesn't support full-system mode\n");
509 } else {
510 DPRINTF(GPUTLB, "Handling a TLB miss for address %#x "
511 "at pc %#x.\n", vaddr,
512 tc->pcState().instAddr());
513
514 Process *p = tc->getProcessPtr();
515 const EmulationPageTable::Entry *pte =
516 p->pTable->lookup(vaddr);
517
518 if (!pte && mode != BaseMMU::Execute) {
519 // penalize a "page fault" more
520 if (timing)
521 latency += missLatency2;
522
523 if (p->fixupFault(vaddr))
524 pte = p->pTable->lookup(vaddr);
525 }
526
527 if (!pte) {
528 return std::make_shared<PageFault>(vaddr, true,
529 mode, true,
530 false);
531 } else {
532 Addr alignedVaddr = p->pTable->pageAlign(vaddr);
533
534 DPRINTF(GPUTLB, "Mapping %#x to %#x\n",
535 alignedVaddr, pte->paddr);
536
537 TlbEntry gpuEntry(p->pid(), alignedVaddr,
538 pte->paddr, false, false);
539 entry = insert(alignedVaddr, gpuEntry);
540 }
541
542 DPRINTF(GPUTLB, "Miss was serviced.\n");
543 }
544 } else {
546
547 if (timing) {
548 latency = hitLatency;
549 }
550 }
551
552 // Do paging protection checks.
553 bool inUser = m5Reg.cpl == 3 && !(flags & CPL0FlagBit);
554
555 CR0 cr0 = tc->readMiscRegNoEffect(misc_reg::Cr0);
556 bool badWrite = (!entry->writable && (inUser || cr0.wp));
557
558 if ((inUser && !entry->user) || (mode == BaseMMU::Write &&
559 badWrite)) {
560 // The page must have been present to get into the TLB in
561 // the first place. We'll assume the reserved bits are
562 // fine even though we're not checking them.
563 return std::make_shared<PageFault>(vaddr, true, mode,
564 inUser, false);
565 }
566
567 if (storeCheck && badWrite) {
568 // This would fault if this were a write, so return a page
569 // fault that reflects that happening.
570 return std::make_shared<PageFault>(vaddr, true,
572 inUser, false);
573 }
574
575
576 DPRINTF(GPUTLB, "Entry found with paddr %#x, doing protection "
577 "checks.\n", entry->paddr);
578
579 int page_size = entry->size();
580 Addr paddr = entry->paddr | (vaddr & (page_size - 1));
581 DPRINTF(GPUTLB, "Translated %#x -> %#x.\n", vaddr, paddr);
582 req->setPaddr(paddr);
583
584 if (entry->uncacheable)
585 req->setFlags(Request::UNCACHEABLE);
586 } else {
587 //Use the address which already has segmentation applied.
588 DPRINTF(GPUTLB, "Paging disabled.\n");
589 DPRINTF(GPUTLB, "Translated %#x -> %#x.\n", vaddr, vaddr);
590 req->setPaddr(vaddr);
591 }
592 } else {
593 // Real mode
594 DPRINTF(GPUTLB, "In real mode.\n");
595 DPRINTF(GPUTLB, "Translated %#x -> %#x.\n", vaddr, vaddr);
596 req->setPaddr(vaddr);
597 }
598
599 // Check for an access to the local APIC
600 if (FullSystem) {
601 LocalApicBase localApicBase =
603
604 Addr baseAddr = localApicBase.base * PageBytes;
605 Addr paddr = req->getPaddr();
606
607 if (baseAddr <= paddr && baseAddr + PageBytes > paddr) {
608 // Force the access to be uncacheable.
609 req->setFlags(Request::UNCACHEABLE);
610 req->setPaddr(x86LocalAPICAddress(tc->contextId(),
611 paddr - baseAddr));
612 }
613 }
614
615 return NoFault;
616 };
617
618 Fault
620 Mode mode, int &latency)
621 {
622 bool delayedResponse;
623
624 return GpuTLB::translate(req, tc, nullptr, mode, delayedResponse,
625 false, latency);
626 }
627
628 void
630 Translation *translation, Mode mode, int &latency)
631 {
632 bool delayedResponse;
633 assert(translation);
634
635 Fault fault = GpuTLB::translate(req, tc, translation, mode,
636 delayedResponse, true, latency);
637
638 if (!delayedResponse)
639 translation->finish(fault, req, tc, mode);
640 }
641
642 Walker*
644 {
645 return walker;
646 }
647
648
649 void
651 {
652 }
653
654 void
658
664 void
666 {
667 assert(pkt);
668 assert(pkt->senderState);
669
670 Addr virt_page_addr = roundDown(pkt->req->getVaddr(),
672
673 GpuTranslationState *sender_state =
674 safe_cast<GpuTranslationState*>(pkt->senderState);
675
676 bool update_stats = !sender_state->isPrefetch;
677 ThreadContext * tmp_tc = sender_state->tc;
678
679 DPRINTF(GPUTLB, "Translation req. for virt. page addr %#x\n",
680 virt_page_addr);
681
682 int req_cnt = sender_state->reqCnt.back();
683
684 if (update_stats) {
685 stats.accessCycles -= (curTick() * req_cnt);
687 updatePageFootprint(virt_page_addr);
688 stats.globalNumTLBAccesses += req_cnt;
689 }
690
691 tlbOutcome lookup_outcome = TLB_MISS;
692 const RequestPtr &tmp_req = pkt->req;
693
694 // Access the TLB and figure out if it's a hit or a miss.
695 bool success = tlbLookup(tmp_req, tmp_tc, update_stats);
696
697 if (success) {
698 lookup_outcome = TLB_HIT;
699 // Put the entry in SenderState
700 auto p = sender_state->tc->getProcessPtr();
701 if (pkt->req->hasNoAddr()) {
702 sender_state->tlbEntry =
703 new TlbEntry(p->pid(), 0, 0,
704 false, false);
705 } else {
706 TlbEntry *entry = lookup(tmp_req->getVaddr(), false);
707 assert(entry);
708
709 sender_state->tlbEntry =
710 new TlbEntry(p->pid(), entry->vaddr, entry->paddr,
711 false, false);
712 }
713
714 if (update_stats) {
715 // the reqCnt has an entry per level, so its size tells us
716 // which level we are in
717 sender_state->hitLevel = sender_state->reqCnt.size();
718 stats.globalNumTLBHits += req_cnt;
719 }
720 } else {
721 if (update_stats)
722 stats.globalNumTLBMisses += req_cnt;
723 }
724
725 /*
726 * We now know the TLB lookup outcome (if it's a hit or a miss), as
727 * well as the TLB access latency.
728 *
729 * We create and schedule a new TLBEvent which will help us take the
730 * appropriate actions (e.g., update TLB on a hit, send request to
731 * lower level TLB on a miss, or start a page walk if this was the
732 * last-level TLB)
733 */
734 TLBEvent *tlb_event =
735 new TLBEvent(this, virt_page_addr, lookup_outcome, pkt);
736
737 if (translationReturnEvent.count(virt_page_addr)) {
738 panic("Virtual Page Address %#x already has a return event\n",
739 virt_page_addr);
740 }
741
742 translationReturnEvent[virt_page_addr] = tlb_event;
743 assert(tlb_event);
744
745 DPRINTF(GPUTLB, "schedule translationReturnEvent @ curTick %d\n",
747
749 }
750
752 tlbOutcome tlb_outcome, PacketPtr _pkt)
753 : Event(CPU_Tick_Pri), tlb(_tlb), virtPageAddr(_addr),
754 outcome(tlb_outcome), pkt(_pkt)
755 {
756 }
757
762 void
764 TlbEntry * tlb_entry, Mode mode)
765 {
766 HandyM5Reg m5Reg = tc->readMiscRegNoEffect(misc_reg::M5Reg);
767 uint32_t flags = pkt->req->getFlags();
768 bool storeCheck = flags & Request::READ_MODIFY_WRITE;
769
770 // Do paging protection checks.
771 bool inUser = m5Reg.cpl == 3 && !(flags & CPL0FlagBit);
772 CR0 cr0 = tc->readMiscRegNoEffect(misc_reg::Cr0);
773
774 bool badWrite = (!tlb_entry->writable && (inUser || cr0.wp));
775
776 if ((inUser && !tlb_entry->user) ||
777 (mode == BaseMMU::Write && badWrite)) {
778 // The page must have been present to get into the TLB in
779 // the first place. We'll assume the reserved bits are
780 // fine even though we're not checking them.
781 panic("Page fault detected");
782 }
783
784 if (storeCheck && badWrite) {
785 // This would fault if this were a write, so return a page
786 // fault that reflects that happening.
787 panic("Page fault detected");
788 }
789 }
790
796 void
798 tlbOutcome tlb_outcome, PacketPtr pkt)
799 {
800 assert(pkt);
801 Addr vaddr = pkt->req->getVaddr();
802
803 GpuTranslationState *sender_state =
804 safe_cast<GpuTranslationState*>(pkt->senderState);
805
806 ThreadContext *tc = sender_state->tc;
807 Mode mode = sender_state->tlbMode;
808
809 TlbEntry *local_entry, *new_entry;
810
811 if (tlb_outcome == TLB_HIT) {
812 DPRINTF(GPUTLB, "Translation Done - TLB Hit for addr %#x\n",
813 vaddr);
814 local_entry = safe_cast<TlbEntry *>(sender_state->tlbEntry);
815 } else {
816 DPRINTF(GPUTLB, "Translation Done - TLB Miss for addr %#x\n",
817 vaddr);
818
824 new_entry = safe_cast<TlbEntry *>(sender_state->tlbEntry);
825 assert(new_entry);
826 local_entry = new_entry;
827
828 if (allocationPolicy) {
829 DPRINTF(GPUTLB, "allocating entry w/ addr %#x\n",
830 virt_page_addr);
831
832 local_entry = insert(virt_page_addr, *new_entry);
833 }
834
835 assert(local_entry);
836 }
837
843 DPRINTF(GPUTLB, "Entry found with vaddr %#x, doing protection checks "
844 "while paddr was %#x.\n", local_entry->vaddr,
845 local_entry->paddr);
846
847 pagingProtectionChecks(tc, pkt, local_entry, mode);
848 int page_size = local_entry->size();
849 Addr paddr = local_entry->paddr | (vaddr & (page_size - 1));
850 DPRINTF(GPUTLB, "Translated %#x -> %#x.\n", vaddr, paddr);
851
852 // Since this packet will be sent through the cpu side port,
853 // it must be converted to a response pkt if it is not one already
854 if (pkt->isRequest()) {
855 pkt->makeTimingResponse();
856 }
857
858 pkt->req->setPaddr(paddr);
859
860 if (local_entry->uncacheable) {
861 pkt->req->setFlags(Request::UNCACHEABLE);
862 }
863
864 //send packet back to coalescer
865 cpuSidePort[0]->sendTimingResp(pkt);
866 //schedule cleanup event
867 cleanupQueue.push(virt_page_addr);
868
869 // schedule this only once per cycle.
870 // The check is required because we might have multiple translations
871 // returning the same cycle
872 // this is a maximum priority event and must be on the same cycle
873 // as the cleanup event in TLBCoalescer to avoid a race with
874 // IssueProbeEvent caused by TLBCoalescer::MemSidePort::recvReqRetry
875 if (!cleanupEvent.scheduled())
877 }
878
883 void
885 PacketPtr pkt)
886 {
887 DPRINTF(GPUTLB, "Triggered TLBEvent for addr %#x\n", virtPageAddr);
888
889 assert(translationReturnEvent[virtPageAddr]);
890 assert(pkt);
891
892 GpuTranslationState *tmp_sender_state =
893 safe_cast<GpuTranslationState*>(pkt->senderState);
894
895 int req_cnt = tmp_sender_state->reqCnt.back();
896 bool update_stats = !tmp_sender_state->isPrefetch;
897
898
899 if (outcome == TLB_HIT) {
900 handleTranslationReturn(virtPageAddr, TLB_HIT, pkt);
901
902 if (update_stats) {
903 stats.accessCycles += (req_cnt * curTick());
905 }
906
907 } else if (outcome == TLB_MISS) {
908
909 DPRINTF(GPUTLB, "This is a TLB miss\n");
910 if (update_stats) {
911 stats.accessCycles += (req_cnt*curTick());
913 }
914
915 if (hasMemSidePort) {
916 // the one cyle added here represent the delay from when we get
917 // the reply back till when we propagate it to the coalescer
918 // above.
919 if (update_stats) {
920 stats.accessCycles += (req_cnt * 1);
921 stats.localCycles += 1;
922 }
923
929 if (!memSidePort[0]->sendTimingReq(pkt)) {
930 DPRINTF(GPUTLB, "Failed sending translation request to "
931 "lower level TLB for addr %#x\n", virtPageAddr);
932
933 memSidePort[0]->retries.push_back(pkt);
934 } else {
935 DPRINTF(GPUTLB, "Sent translation request to lower level "
936 "TLB for addr %#x\n", virtPageAddr);
937 }
938 } else {
939 //this is the last level TLB. Start a page walk
940 DPRINTF(GPUTLB, "Last level TLB - start a page walk for "
941 "addr %#x\n", virtPageAddr);
942
943 if (update_stats)
944 stats.pageTableCycles -= (req_cnt*curTick());
945
946 TLBEvent *tlb_event = translationReturnEvent[virtPageAddr];
947 assert(tlb_event);
948 tlb_event->updateOutcome(PAGE_WALK);
949 schedule(tlb_event,
951 }
952 } else if (outcome == PAGE_WALK) {
953 if (update_stats)
954 stats.pageTableCycles += (req_cnt*curTick());
955
956 // Need to access the page table and update the TLB
957 DPRINTF(GPUTLB, "Doing a page walk for address %#x\n",
958 virtPageAddr);
959
960 GpuTranslationState *sender_state =
961 safe_cast<GpuTranslationState*>(pkt->senderState);
962
963 Process *p = sender_state->tc->getProcessPtr();
964 Addr vaddr = pkt->req->getVaddr();
965
966 Addr alignedVaddr = p->pTable->pageAlign(vaddr);
967 assert(alignedVaddr == virtPageAddr);
968
969 const EmulationPageTable::Entry *pte = p->pTable->lookup(vaddr);
970 if (!pte && sender_state->tlbMode != BaseMMU::Execute &&
971 p->fixupFault(vaddr)) {
972 pte = p->pTable->lookup(vaddr);
973 }
974
975 if (pte) {
976 DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr,
977 pte->paddr);
978
979 sender_state->tlbEntry =
980 new TlbEntry(p->pid(), virtPageAddr, pte->paddr, false,
981 false);
982 } else {
983 sender_state->tlbEntry = nullptr;
984 }
985
986 handleTranslationReturn(virtPageAddr, TLB_MISS, pkt);
987 } else if (outcome == MISS_RETURN) {
991 handleTranslationReturn(virtPageAddr, TLB_MISS, pkt);
992 } else {
993 panic("Unexpected TLB outcome %d", outcome);
994 }
995 }
996
997 void
999 {
1000 tlb->translationReturn(virtPageAddr, outcome, pkt);
1001 }
1002
1003 const char*
1005 {
1006 return "trigger translationDoneEvent";
1007 }
1008
1009 void
1011 {
1012 outcome = _outcome;
1013 }
1014
1015 Addr
1017 {
1018 return virtPageAddr;
1019 }
1020
1027 bool
1029 {
1030 if (tlb->outstandingReqs < tlb->maxCoalescedReqs) {
1031 tlb->issueTLBLookup(pkt);
1032 // update number of outstanding translation requests
1033 tlb->outstandingReqs++;
1034 return true;
1035 } else {
1036 DPRINTF(GPUTLB, "Reached maxCoalescedReqs number %d\n",
1037 tlb->outstandingReqs);
1038 return false;
1039 }
1040 }
1041
1050 void
1052 {
1053 GpuTranslationState *sender_state =
1054 safe_cast<GpuTranslationState*>(pkt->senderState);
1055
1056 ThreadContext *tc = sender_state->tc;
1057 Mode mode = sender_state->tlbMode;
1058 Addr vaddr = pkt->req->getVaddr();
1059
1060 TlbEntry *local_entry, *new_entry;
1061
1062 if (tlb_outcome == TLB_HIT) {
1063 DPRINTF(GPUTLB, "Functional Translation Done - TLB hit for addr "
1064 "%#x\n", vaddr);
1065
1066 local_entry = safe_cast<TlbEntry *>(sender_state->tlbEntry);
1067 } else {
1068 DPRINTF(GPUTLB, "Functional Translation Done - TLB miss for addr "
1069 "%#x\n", vaddr);
1070
1076 new_entry = safe_cast<TlbEntry *>(sender_state->tlbEntry);
1077 assert(new_entry);
1078 local_entry = new_entry;
1079
1080 if (allocationPolicy) {
1081 Addr virt_page_addr = roundDown(vaddr, X86ISA::PageBytes);
1082
1083 DPRINTF(GPUTLB, "allocating entry w/ addr %#x\n",
1084 virt_page_addr);
1085
1086 local_entry = insert(virt_page_addr, *new_entry);
1087 }
1088
1089 assert(local_entry);
1090 }
1091
1092 DPRINTF(GPUTLB, "Entry found with vaddr %#x, doing protection checks "
1093 "while paddr was %#x.\n", local_entry->vaddr,
1094 local_entry->paddr);
1095
1107 if (!sender_state->isPrefetch && sender_state->tlbEntry)
1108 pagingProtectionChecks(tc, pkt, local_entry, mode);
1109
1110 int page_size = local_entry->size();
1111 Addr paddr = local_entry->paddr | (vaddr & (page_size - 1));
1112 DPRINTF(GPUTLB, "Translated %#x -> %#x.\n", vaddr, paddr);
1113
1114 pkt->req->setPaddr(paddr);
1115
1116 if (local_entry->uncacheable)
1117 pkt->req->setFlags(Request::UNCACHEABLE);
1118 }
1119
1120 // This is used for atomic translations. Need to
1121 // make it all happen during the same cycle.
1122 void
1124 {
1125 GpuTranslationState *sender_state =
1126 safe_cast<GpuTranslationState*>(pkt->senderState);
1127
1128 ThreadContext *tc = sender_state->tc;
1129 bool update_stats = !sender_state->isPrefetch;
1130
1131 Addr virt_page_addr = roundDown(pkt->req->getVaddr(),
1133
1134 if (update_stats)
1135 tlb->updatePageFootprint(virt_page_addr);
1136
1137 // do the TLB lookup without updating the stats
1138 bool success = tlb->tlbLookup(pkt->req, tc, update_stats);
1139 tlbOutcome tlb_outcome = success ? TLB_HIT : TLB_MISS;
1140
1141 // functional mode means no coalescing
1142 // global metrics are the same as the local metrics
1143 if (update_stats) {
1144 tlb->stats.globalNumTLBAccesses++;
1145
1146 if (success) {
1147 sender_state->hitLevel = sender_state->reqCnt.size();
1148 tlb->stats.globalNumTLBHits++;
1149 }
1150 }
1151
1152 if (!success) {
1153 if (update_stats)
1154 tlb->stats.globalNumTLBMisses++;
1155 if (tlb->hasMemSidePort) {
1156 // there is a TLB below -> propagate down the TLB hierarchy
1157 tlb->memSidePort[0]->sendFunctional(pkt);
1158 // If no valid translation from a prefetch, then just return
1159 if (sender_state->isPrefetch && !pkt->req->hasPaddr())
1160 return;
1161 } else {
1162 // Need to access the page table and update the TLB
1163 DPRINTF(GPUTLB, "Doing a page walk for address %#x\n",
1164 virt_page_addr);
1165
1166 Process *p = tc->getProcessPtr();
1167
1168 Addr vaddr = pkt->req->getVaddr();
1169
1170 Addr alignedVaddr = p->pTable->pageAlign(vaddr);
1171 assert(alignedVaddr == virt_page_addr);
1172
1173 const EmulationPageTable::Entry *pte =
1174 p->pTable->lookup(vaddr);
1175 if (!pte && sender_state->tlbMode != BaseMMU::Execute &&
1176 p->fixupFault(vaddr)) {
1177 pte = p->pTable->lookup(vaddr);
1178 }
1179
1180 if (!sender_state->isPrefetch) {
1181 // no PageFaults are permitted after
1182 // the second page table lookup
1183 assert(pte);
1184
1185 DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr,
1186 pte->paddr);
1187
1188 sender_state->tlbEntry =
1189 new TlbEntry(p->pid(), virt_page_addr,
1190 pte->paddr, false, false);
1191 } else {
1192 // If this was a prefetch, then do the normal thing if it
1193 // was a successful translation. Otherwise, send an empty
1194 // TLB entry back so that it can be figured out as empty
1195 // and handled accordingly.
1196 if (pte) {
1197 DPRINTF(GPUTLB, "Mapping %#x to %#x\n", alignedVaddr,
1198 pte->paddr);
1199
1200 sender_state->tlbEntry =
1201 new TlbEntry(p->pid(), virt_page_addr,
1202 pte->paddr, false, false);
1203 } else {
1204 DPRINTF(GPUPrefetch, "Prefetch failed %#x\n",
1205 alignedVaddr);
1206
1207 sender_state->tlbEntry = nullptr;
1208
1209 return;
1210 }
1211 }
1212 }
1213 } else {
1214 DPRINTF(GPUPrefetch, "Functional Hit for vaddr %#x\n",
1215 tlb->lookup(pkt->req->getVaddr()));
1216
1217 TlbEntry *entry = tlb->lookup(pkt->req->getVaddr(),
1218 update_stats);
1219
1220 assert(entry);
1221
1222 auto p = sender_state->tc->getProcessPtr();
1223 sender_state->tlbEntry =
1224 new TlbEntry(p->pid(), entry->vaddr, entry->paddr,
1225 false, false);
1226 }
1227 // This is the function that would populate pkt->req with the paddr of
1228 // the translation. But if no translation happens (i.e Prefetch fails)
1229 // then the early returns in the above code wiill keep this function
1230 // from executing.
1231 tlb->handleFuncTranslationReturn(pkt, tlb_outcome);
1232 }
1233
1234 void
1236 {
1237 // The CPUSidePort never sends anything but replies. No retries
1238 // expected.
1239 panic("recvReqRetry called");
1240 }
1241
1244 {
1245 // currently not checked by the requestor
1246 AddrRangeList ranges;
1247
1248 return ranges;
1249 }
1250
1256 bool
1258 {
1259 Addr virt_page_addr = roundDown(pkt->req->getVaddr(),
1261
1262 DPRINTF(GPUTLB, "MemSidePort recvTiming for virt_page_addr %#x\n",
1263 virt_page_addr);
1264
1265 TLBEvent *tlb_event = tlb->translationReturnEvent[virt_page_addr];
1266 assert(tlb_event);
1267 assert(virt_page_addr == tlb_event->getTLBEventVaddr());
1268
1269 tlb_event->updateOutcome(MISS_RETURN);
1270 tlb->schedule(tlb_event, curTick()+tlb->clockPeriod());
1271
1272 return true;
1273 }
1274
1275 void
1277 {
1278 // No retries should reach the TLB. The retries
1279 // should only reach the TLBCoalescer.
1280 panic("recvReqRetry called");
1281 }
1282
1283 void
1285 {
1286 while (!cleanupQueue.empty()) {
1287 Addr cleanup_addr = cleanupQueue.front();
1288 cleanupQueue.pop();
1289
1290 // delete TLBEvent
1291 TLBEvent * old_tlb_event = translationReturnEvent[cleanup_addr];
1292 delete old_tlb_event;
1293 translationReturnEvent.erase(cleanup_addr);
1294
1295 // update number of outstanding requests
1297 }
1298
1302 for (int i = 0; i < cpuSidePort.size(); ++i) {
1303 cpuSidePort[i]->sendRetryReq();
1304 }
1305 }
1306
1307 void
1309 {
1310
1312
1313 AccessInfo tmp_access_info;
1314 tmp_access_info.lastTimeAccessed = 0;
1315 tmp_access_info.accessesPerPage = 0;
1316 tmp_access_info.totalReuseDistance = 0;
1317 tmp_access_info.sumDistance = 0;
1318 tmp_access_info.meanDistance = 0;
1319
1320 ret = TLBFootprint.insert(
1321 AccessPatternTable::value_type(virt_page_addr, tmp_access_info));
1322
1323 bool first_page_access = ret.second;
1324
1325 if (first_page_access) {
1327 } else {
1328 int accessed_before;
1329 accessed_before = curTick() - ret.first->second.lastTimeAccessed;
1330 ret.first->second.totalReuseDistance += accessed_before;
1331 }
1332
1333 ret.first->second.accessesPerPage++;
1334 ret.first->second.lastTimeAccessed = curTick();
1335
1336 if (accessDistance) {
1337 ret.first->second.localTLBAccesses
1338 .push_back(stats.localNumTLBAccesses.value());
1339 }
1340 }
1341
1342 void
1344 {
1345 std::ostream *page_stat_file = nullptr;
1346
1347 if (accessDistance) {
1348
1349 // print per page statistics to a separate file (.csv format)
1350 // simout is the gem5 output directory (default is m5out or the one
1351 // specified with -d
1352 page_stat_file = simout.create(name().c_str())->stream();
1353
1354 // print header
1355 *page_stat_file
1356 << "page,max_access_distance,mean_access_distance, "
1357 << "stddev_distance" << std::endl;
1358 }
1359
1360 // update avg. reuse distance footprint
1361 unsigned int sum_avg_reuse_distance_per_page = 0;
1362
1363 // iterate through all pages seen by this TLB
1364 for (auto &iter : TLBFootprint) {
1365 sum_avg_reuse_distance_per_page += iter.second.totalReuseDistance /
1366 iter.second.accessesPerPage;
1367
1368 if (accessDistance) {
1369 unsigned int tmp = iter.second.localTLBAccesses[0];
1370 unsigned int prev = tmp;
1371
1372 for (int i = 0; i < iter.second.localTLBAccesses.size(); ++i) {
1373 if (i) {
1374 tmp = prev + 1;
1375 }
1376
1377 prev = iter.second.localTLBAccesses[i];
1378 // update the localTLBAccesses value
1379 // with the actual differece
1380 iter.second.localTLBAccesses[i] -= tmp;
1381 // compute the sum of AccessDistance per page
1382 // used later for mean
1383 iter.second.sumDistance +=
1384 iter.second.localTLBAccesses[i];
1385 }
1386
1387 iter.second.meanDistance =
1388 iter.second.sumDistance / iter.second.accessesPerPage;
1389
1390 // compute std_dev and max (we need a second round because we
1391 // need to know the mean value
1392 unsigned int max_distance = 0;
1393 unsigned int stddev_distance = 0;
1394
1395 for (int i = 0; i < iter.second.localTLBAccesses.size(); ++i) {
1396 unsigned int tmp_access_distance =
1397 iter.second.localTLBAccesses[i];
1398
1399 if (tmp_access_distance > max_distance) {
1400 max_distance = tmp_access_distance;
1401 }
1402
1403 unsigned int diff =
1404 tmp_access_distance - iter.second.meanDistance;
1405 stddev_distance += pow(diff, 2);
1406
1407 }
1408
1409 stddev_distance =
1410 sqrt(stddev_distance/iter.second.accessesPerPage);
1411
1412 if (page_stat_file) {
1413 *page_stat_file << std::hex << iter.first << ",";
1414 *page_stat_file << std::dec << max_distance << ",";
1415 *page_stat_file << std::dec << iter.second.meanDistance
1416 << ",";
1417 *page_stat_file << std::dec << stddev_distance;
1418 *page_stat_file << std::endl;
1419 }
1420
1421 // erase the localTLBAccesses array
1422 iter.second.localTLBAccesses.clear();
1423 }
1424 }
1425
1426 if (!TLBFootprint.empty()) {
1428 sum_avg_reuse_distance_per_page / TLBFootprint.size();
1429 }
1430
1431 //clear the TLBFootprint map
1432 TLBFootprint.clear();
1433 }
1434
1436 : statistics::Group(parent),
1437 ADD_STAT(localNumTLBAccesses, "Number of TLB accesses"),
1438 ADD_STAT(localNumTLBHits, "Number of TLB hits"),
1439 ADD_STAT(localNumTLBMisses, "Number of TLB misses"),
1440 ADD_STAT(localTLBMissRate, "TLB miss rate"),
1441 ADD_STAT(globalNumTLBAccesses, "Number of TLB accesses"),
1442 ADD_STAT(globalNumTLBHits, "Number of TLB hits"),
1443 ADD_STAT(globalNumTLBMisses, "Number of TLB misses"),
1444 ADD_STAT(globalTLBMissRate, "TLB miss rate"),
1445 ADD_STAT(accessCycles, "Cycles spent accessing this TLB level"),
1446 ADD_STAT(pageTableCycles, "Cycles spent accessing the page table"),
1447 ADD_STAT(numUniquePages, "Number of unique pages touched"),
1448 ADD_STAT(localCycles, "Number of cycles spent in queue for all "
1449 "incoming reqs"),
1450 ADD_STAT(localLatency, "Avg. latency over incoming coalesced reqs"),
1451 ADD_STAT(avgReuseDistance, "avg. reuse distance over all pages (in "
1452 "ticks)")
1453 {
1455
1458 }
1459} // namespace X86ISA
1460} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:209
const char data[]
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
Tick cyclesToTicks(Cycles c) const
Cycles is a wrapper class for representing cycle counts, i.e.
Definition types.hh:79
virtual std::string name() const
Definition named.hh:47
OutputStream * create(const std::string &name, bool binary=false, bool no_gz=false)
Creates a file in this directory (optionally compressed).
Definition output.cc:210
std::ostream * stream() const
Get the output underlying output stream.
Definition output.hh:62
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
Definition pcstate.hh:108
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
void makeTimingResponse()
Definition packet.hh:1080
SenderState * senderState
This packet's sender state.
Definition packet.hh:545
void setData(const uint8_t *p)
Copy data into the packet from the provided pointer.
Definition packet.hh:1293
RequestPtr req
A pointer to the original request.
Definition packet.hh:377
bool isRequest() const
Definition packet.hh:597
Ports are used to interface objects to each other.
Definition port.hh:62
@ STRICT_ORDER
The request is required to be strictly ordered by CPU models and is non-speculative.
Definition request.hh:135
@ UNCACHEABLE
The request is to an uncacheable address.
Definition request.hh:125
@ READ_MODIFY_WRITE
This request is a read which will be followed by a write.
Definition request.hh:161
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal readMiscReg(RegIndex misc_reg)=0
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
virtual const PCStateBase & pcState() const =0
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
virtual Process * getProcessPtr()=0
virtual ContextID contextId() const =0
virtual void recvFunctional(PacketPtr pkt)
Receive a functional request packet from the peer.
Definition tlb.cc:1123
virtual bool recvTimingReq(PacketPtr pkt)
recvTiming receives a coalesced timing request from a TLBCoalescer and it calls issueTLBLookup() It o...
Definition tlb.cc:1028
virtual AddrRangeList getAddrRanges() const
Get a list of the non-overlapping address ranges the owner is responsible for.
Definition tlb.cc:1243
virtual void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
Definition tlb.cc:1276
virtual bool recvTimingResp(PacketPtr pkt)
MemSidePort receives the packet back.
Definition tlb.cc:1257
void updateOutcome(tlbOutcome _outcome)
Definition tlb.cc:1010
TLBEvent(GpuTLB *_tlb, Addr _addr, tlbOutcome outcome, PacketPtr _pkt)
Definition tlb.cc:751
const char * description() const
Return a C string describing the event.
Definition tlb.cc:1004
virtual void finish(Fault fault, const RequestPtr &req, ThreadContext *tc, Mode mode)=0
The memory for this object may be dynamically allocated, and it may be responsible for cleaning itsle...
void exitCallback()
Definition tlb.cc:1343
X86GPUTLBParams Params
Definition tlb.hh:75
void issueTLBLookup(PacketPtr pkt)
Do the TLB lookup for this coalesced request and schedule another event <TLB access latency> cycles l...
Definition tlb.cc:665
std::unordered_map< Addr, TLBEvent * > translationReturnEvent
Definition tlb.hh:308
void translationReturn(Addr virtPageAddr, tlbOutcome outcome, PacketPtr pkt)
A TLBEvent is scheduled after the TLB lookup and helps us take the appropriate actions: (e....
Definition tlb.cc:884
void invalidateNonGlobal()
Definition tlb.cc:249
enum BaseMMU::Mode Mode
Definition tlb.hh:79
EventFunctionWrapper cleanupEvent
Definition tlb.hh:318
EntryList::iterator lookupIt(Addr va, bool update_lru=true)
Definition tlb.cc:186
Fault translateInt(bool read, const RequestPtr &req, ThreadContext *tc)
Definition tlb.cc:302
GpuTLB(const Params &p)
Definition tlb.cc:67
Fault translate(const RequestPtr &req, ThreadContext *tc, Translation *translation, Mode mode, bool &delayedResponse, bool timing, int &latency)
Definition tlb.cc:424
AccessPatternTable TLBFootprint
Definition tlb.hh:346
void demapPage(Addr va, uint64_t asn)
Definition tlb.cc:267
uint32_t configAddress
Definition tlb.hh:72
virtual void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition tlb.cc:655
TlbEntry * lookup(Addr va, bool update_lru=true)
Definition tlb.cc:216
std::vector< TlbEntry > tlb
Definition tlb.hh:143
std::vector< MemSidePort * > memSidePort
Definition tlb.hh:262
bool accessDistance
Print out accessDistance stats.
Definition tlb.hh:141
void invalidateAll()
Definition tlb.cc:229
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Definition tlb.cc:138
Walker * walker
Definition tlb.hh:107
std::queue< Addr > cleanupQueue
Definition tlb.hh:312
bool FA
true if this is a fully-associative TLB
Definition tlb.hh:123
TlbEntry * insert(Addr vpn, TlbEntry &entry)
Definition tlb.cc:160
gem5::X86ISA::GpuTLB::GpuTLBStats stats
void translateTiming(const RequestPtr &req, ThreadContext *tc, Translation *translation, Mode mode, int &latency)
Definition tlb.cc:629
void handleFuncTranslationReturn(PacketPtr pkt, tlbOutcome outcome)
handleFuncTranslationReturn is called on a TLB hit, when a TLB miss returns or when a page fault retu...
Definition tlb.cc:1051
std::vector< EntryList > freeList
Definition tlb.hh:150
std::vector< EntryList > entryList
An entryList per set is the equivalent of an LRU stack; it's used to guide replacement decisions.
Definition tlb.hh:159
virtual void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition tlb.cc:650
void setConfigAddress(uint32_t addr)
Definition tlb.cc:243
bool hasMemSidePort
if true, then this is not the last level TLB
Definition tlb.hh:135
bool allocationPolicy
Allocation Policy: true if we always allocate on a hit, false otherwise.
Definition tlb.hh:130
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.
Definition tlb.cc:797
void updatePageFootprint(Addr virt_page_addr)
Definition tlb.cc:1308
bool tlbLookup(const RequestPtr &req, ThreadContext *tc, bool update_stats)
TLB_lookup will only perform a TLB lookup returning true on a TLB hit and false on a TLB miss.
Definition tlb.cc:371
Walker * getWalker()
Definition tlb.cc:643
std::vector< CpuSidePort * > cpuSidePort
Definition tlb.hh:260
Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, Mode mode, int &latency)
Definition tlb.cc:619
void pagingProtectionChecks(ThreadContext *tc, PacketPtr pkt, TlbEntry *tlb_entry, Mode mode)
Do Paging protection checks.
Definition tlb.cc:763
Statistics container.
Definition group.hh:93
size_type size() const
Return the number of elements, always 1 for a scalar.
Counter value() const
Return the current value of this stat as its base type.
STL pair class.
Definition stl.hh:58
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition group.hh:75
static constexpr T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
Definition intmath.hh:279
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition bitfield.hh:79
constexpr T mbits(T val, unsigned first, unsigned last)
Mask off the given bits in place like bits() but without shifting.
Definition bitfield.hh:106
static const Priority Maximum_Pri
Maximum priority.
Definition eventq.hh:244
bool scheduled() const
Determine if the current event is scheduled.
Definition eventq.hh:458
void schedule(Event &event, Tick when)
Definition eventq.hh:1012
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:200
uint8_t flags
Definition helpers.cc:87
#define warn_once(...)
Definition logging.hh:260
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 12, 11 > set
Bitfield< 8 > va
Bitfield< 59, 56 > tlb
static RegIndex segSel(int index)
Definition misc.hh:515
static RegIndex segAttr(int index)
Definition misc.hh:543
static RegIndex segBase(int index)
Definition misc.hh:522
static RegIndex segLimit(int index)
Definition misc.hh:536
constexpr auto AddrSizeFlagMask
Definition ldstflags.hh:58
const Addr PhysAddrPrefixPciConfig
Definition x86_traits.hh:69
Bitfield< 51, 12 > base
Definition pagetable.hh:141
Bitfield< 14 > expandDown
Definition misc.hh:1031
const Addr IntAddrPrefixIO
Definition x86_traits.hh:66
constexpr auto AddrSizeFlagShift
Definition ldstflags.hh:57
constexpr Request::FlagsType SegmentFlagMask
Definition ldstflags.hh:54
BitfieldType< SegDescriptorLimit > limit
Definition misc.hh:959
const Addr PageShift
Definition page_size.hh:48
Bitfield< 3 > addr
Definition types.hh:84
Bitfield< 2, 0 > seg
Definition types.hh:87
const Addr PhysAddrPrefixIO
Definition x86_traits.hh:68
constexpr auto CPL0FlagBit
Definition ldstflags.hh:56
Bitfield< 3 > mode
Definition types.hh:192
Bitfield< 0 > p
Definition pagetable.hh:151
const Addr IntAddrPrefixCPUID
Definition x86_traits.hh:64
const Addr IntAddrPrefixMSR
Definition x86_traits.hh:65
const Addr IntAddrPrefixMask
Definition x86_traits.hh:63
Bitfield< 1 > x
Definition types.hh:108
bool msrAddrToIndex(RegIndex &reg_num, Addr addr)
Find and return the misc reg corresponding to an MSR address.
Definition msr.cc:150
static Addr x86LocalAPICAddress(const uint8_t id, const uint16_t addr)
Definition x86_traits.hh:92
const Addr PageBytes
Definition page_size.hh:49
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
std::shared_ptr< FaultBase > Fault
Definition types.hh:249
T letoh(T value)
Definition byteswap.hh:173
std::shared_ptr< Request > RequestPtr
Definition request.hh:94
uint16_t RegIndex
Definition types.hh:176
void cprintf(const char *format, const Args &...args)
Definition cprintf.hh:155
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
std::ostream CheckpointOut
Definition serialize.hh:66
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition types.hh:245
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition root.cc:220
OutputDirectory simout
Definition output.cc:62
T htole(T value)
Definition byteswap.hh:172
uint64_t RegVal
Definition types.hh:173
std::string csprintf(const char *format, const Args &...args)
Definition cprintf.hh:161
constexpr decltype(nullptr) NoFault
Definition types.hh:253
Declarations of a non-full system Page Table.
Declaration of a request, the overall memory request consisting of the parts of the request that are ...
GPU TranslationState: this currently is a somewhat bastardization of the usage of SenderState,...
This hash map will use the virtual page address as a key and will keep track of total number of acces...
Definition tlb.hh:326
unsigned int totalReuseDistance
Definition tlb.hh:330
unsigned int lastTimeAccessed
Definition tlb.hh:327
GpuTLBStats(statistics::Group *parent)
Definition tlb.cc:1435
statistics::Formula localTLBMissRate
Definition tlb.hh:363
statistics::Scalar globalNumTLBMisses
Definition tlb.hh:370
statistics::Scalar localCycles
Definition tlb.hh:379
statistics::Formula globalTLBMissRate
Definition tlb.hh:371
statistics::Scalar localNumTLBHits
Definition tlb.hh:361
statistics::Scalar numUniquePages
Definition tlb.hh:377
statistics::Scalar avgReuseDistance
Definition tlb.hh:384
statistics::Scalar globalNumTLBHits
Definition tlb.hh:369
statistics::Formula localLatency
Definition tlb.hh:381
statistics::Scalar localNumTLBMisses
Definition tlb.hh:362
statistics::Scalar globalNumTLBAccesses
Definition tlb.hh:368
statistics::Scalar accessCycles
Definition tlb.hh:374
statistics::Scalar localNumTLBAccesses
Definition tlb.hh:360
statistics::Scalar pageTableCycles
Definition tlb.hh:376
const std::string & name()
Definition trace.cc:48

Generated on Mon Jan 13 2025 04:28:27 for gem5 by doxygen 1.9.8