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

Generated on Tue Dec 21 2021 11:34:05 for gem5 by doxygen 1.8.17