gem5  v21.1.0.2
tlb.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2013, 2016-2021 Arm Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Copyright (c) 2001-2005 The Regents of The University of Michigan
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 #include "arch/arm/tlb.hh"
42 
43 #include <memory>
44 #include <string>
45 #include <vector>
46 
47 #include "arch/arm/faults.hh"
48 #include "arch/arm/isa.hh"
49 #include "arch/arm/pagetable.hh"
50 #include "arch/arm/reg_abi.hh"
51 #include "arch/arm/self_debug.hh"
53 #include "arch/arm/system.hh"
54 #include "arch/arm/table_walker.hh"
55 #include "arch/arm/tlbi_op.hh"
56 #include "arch/arm/utility.hh"
57 #include "base/compiler.hh"
58 #include "base/inifile.hh"
59 #include "base/str.hh"
60 #include "base/trace.hh"
61 #include "cpu/base.hh"
62 #include "cpu/thread_context.hh"
63 #include "debug/Checkpoint.hh"
64 #include "debug/TLB.hh"
65 #include "debug/TLBVerbose.hh"
66 #include "mem/packet_access.hh"
67 #include "mem/page_table.hh"
68 #include "mem/request.hh"
69 #include "params/ArmTLB.hh"
70 #include "sim/full_system.hh"
71 #include "sim/process.hh"
72 #include "sim/pseudo_inst.hh"
73 
74 namespace gem5
75 {
76 
77 using namespace ArmISA;
78 
79 TLB::TLB(const ArmTLBParams &p)
80  : BaseTLB(p), table(new TlbEntry[p.size]), size(p.size),
81  isStage2(p.is_stage2), stage2Req(false), stage2DescReq(false), _attr(0),
82  directToStage2(false), tableWalker(nullptr), stage2Tlb(nullptr),
83  test(nullptr), stats(this), rangeMRU(1),
84  aarch64(false), aarch64EL(EL0), isPriv(false), isSecure(false),
85  isHyp(false), asid(0), vmid(0), hcr(0), dacr(0),
86  miscRegValid(false), miscRegContext(0), curTranType(NormalTran)
87 {
88  // Cache system-level properties
89  if (FullSystem) {
90  ArmSystem *arm_sys = dynamic_cast<ArmSystem *>(p.sys);
91  assert(arm_sys);
92  haveLPAE = arm_sys->haveLPAE();
94  haveLargeAsid64 = arm_sys->haveLargeAsid64();
95  physAddrRange = arm_sys->physAddrRange();
96  } else {
97  haveLPAE = false;
98  haveVirtualization = false;
99  haveLargeAsid64 = false;
100  physAddrRange = 48;
101  }
102 
103  m5opRange = p.sys->m5opRange();
104 }
105 
107 {
108  delete[] table;
109 }
110 
111 void
113 {
114  tableWalker = table_walker;
115  tableWalker->setTlb(this);
116 }
117 
118 bool
120 {
121  updateMiscReg(tc);
122 
123  if (directToStage2) {
124  assert(stage2Tlb);
125  return stage2Tlb->translateFunctional(tc, va, pa);
126  }
127 
128  TlbEntry *e = lookup(va, asid, vmid, isHyp, isSecure, true, false,
129  aarch64 ? aarch64EL : EL1, false, BaseMMU::Read);
130  if (!e)
131  return false;
132  pa = e->pAddr(va);
133  return true;
134 }
135 
136 Fault
138  ThreadContext *tc, BaseMMU::Mode mode) const
139 {
140  const Addr paddr = req->getPaddr();
141 
142  if (m5opRange.contains(paddr)) {
143  uint8_t func;
145  req->setLocalAccessor(
146  [func, mode](ThreadContext *tc, PacketPtr pkt) -> Cycles
147  {
148  uint64_t ret;
149  if (inAArch64(tc))
150  pseudo_inst::pseudoInst<RegABI64>(tc, func, ret);
151  else
152  pseudo_inst::pseudoInst<RegABI32>(tc, func, ret);
153 
154  if (mode == BaseMMU::Read)
155  pkt->setLE(ret);
156 
157  return Cycles(1);
158  }
159  );
160  }
161 
162  return NoFault;
163 }
164 
165 TlbEntry*
166 TLB::lookup(Addr va, uint16_t asn, vmid_t vmid, bool hyp, bool secure,
167  bool functional, bool ignore_asn, ExceptionLevel target_el,
168  bool in_host, BaseMMU::Mode mode)
169 {
170 
171  TlbEntry *retval = NULL;
172 
173  // Maintaining LRU array
174  int x = 0;
175  while (retval == NULL && x < size) {
176  if ((!ignore_asn && table[x].match(va, asn, vmid, hyp, secure, false,
177  target_el, in_host)) ||
178  (ignore_asn && table[x].match(va, vmid, hyp, secure, target_el,
179  in_host))) {
180  // We only move the hit entry ahead when the position is higher
181  // than rangeMRU
182  if (x > rangeMRU && !functional) {
183  TlbEntry tmp_entry = table[x];
184  for (int i = x; i > 0; i--)
185  table[i] = table[i - 1];
186  table[0] = tmp_entry;
187  retval = &table[0];
188  } else {
189  retval = &table[x];
190  }
191  break;
192  }
193  ++x;
194  }
195 
196  DPRINTF(TLBVerbose, "Lookup %#x, asn %#x -> %s vmn 0x%x hyp %d secure %d "
197  "ppn %#x size: %#x pa: %#x ap:%d ns:%d nstid:%d g:%d asid: %d "
198  "el: %d\n",
199  va, asn, retval ? "hit" : "miss", vmid, hyp, secure,
200  retval ? retval->pfn : 0, retval ? retval->size : 0,
201  retval ? retval->pAddr(va) : 0, retval ? retval->ap : 0,
202  retval ? retval->ns : 0, retval ? retval->nstid : 0,
203  retval ? retval->global : 0, retval ? retval->asid : 0,
204  retval ? retval->el : 0);
205 
206  // Updating stats if this was not a functional lookup
207  if (!functional) {
208  if (!retval) {
209  if (mode == BaseMMU::Execute)
210  stats.instMisses++;
211  else if (mode == BaseMMU::Write)
212  stats.writeMisses++;
213  else
214  stats.readMisses++;
215  } else {
216  if (mode == BaseMMU::Execute)
217  stats.instHits++;
218  else if (mode == BaseMMU::Write)
219  stats.writeHits++;
220  else
221  stats.readHits++;
222  }
223  }
224 
225  return retval;
226 }
227 
228 // insert a new TLB entry
229 void
231 {
232  DPRINTF(TLB, "Inserting entry into TLB with pfn:%#x size:%#x vpn: %#x"
233  " asid:%d vmid:%d N:%d global:%d valid:%d nc:%d xn:%d"
234  " ap:%#x domain:%#x ns:%d nstid:%d isHyp:%d\n", entry.pfn,
235  entry.size, entry.vpn, entry.asid, entry.vmid, entry.N,
236  entry.global, entry.valid, entry.nonCacheable, entry.xn,
237  entry.ap, static_cast<uint8_t>(entry.domain), entry.ns, entry.nstid,
238  entry.isHyp);
239 
240  if (table[size - 1].valid)
241  DPRINTF(TLB, " - Replacing Valid entry %#x, asn %d vmn %d ppn %#x "
242  "size: %#x ap:%d ns:%d nstid:%d g:%d isHyp:%d el: %d\n",
243  table[size-1].vpn << table[size-1].N, table[size-1].asid,
244  table[size-1].vmid, table[size-1].pfn << table[size-1].N,
245  table[size-1].size, table[size-1].ap, table[size-1].ns,
246  table[size-1].nstid, table[size-1].global, table[size-1].isHyp,
247  table[size-1].el);
248 
249  //inserting to MRU position and evicting the LRU one
250 
251  for (int i = size - 1; i > 0; --i)
252  table[i] = table[i-1];
253  table[0] = entry;
254 
255  stats.inserts++;
256  ppRefills->notify(1);
257 }
258 
259 void
261 {
262  int x = 0;
263  TlbEntry *te;
264  DPRINTF(TLB, "Current TLB contents:\n");
265  while (x < size) {
266  te = &table[x];
267  if (te->valid)
268  DPRINTF(TLB, " * %s\n", te->print());
269  ++x;
270  }
271 }
272 
273 void
275 {
276  DPRINTF(TLB, "Flushing all TLB entries\n");
277  int x = 0;
278  TlbEntry *te;
279  while (x < size) {
280  te = &table[x];
281 
282  DPRINTF(TLB, " - %s\n", te->print());
283  te->valid = false;
285  ++x;
286  }
287 
288  stats.flushTlb++;
289 }
290 
291 void
292 TLB::flush(const TLBIALL& tlbi_op)
293 {
294  DPRINTF(TLB, "Flushing all TLB entries (%s lookup)\n",
295  (tlbi_op.secureLookup ? "secure" : "non-secure"));
296  int x = 0;
297  TlbEntry *te;
298  while (x < size) {
299  te = &table[x];
300  const bool el_match = te->checkELMatch(
301  tlbi_op.targetEL, tlbi_op.inHost);
302  if (te->valid && tlbi_op.secureLookup == !te->nstid &&
303  (te->vmid == vmid || tlbi_op.el2Enabled) && el_match) {
304 
305  DPRINTF(TLB, " - %s\n", te->print());
306  te->valid = false;
308  }
309  ++x;
310  }
311 
312  stats.flushTlb++;
313 }
314 
315 void
316 TLB::flush(const TLBIALLEL &tlbi_op)
317 {
318  DPRINTF(TLB, "Flushing all TLB entries (%s lookup)\n",
319  (tlbi_op.secureLookup ? "secure" : "non-secure"));
320  int x = 0;
321  TlbEntry *te;
322  while (x < size) {
323  te = &table[x];
324  const bool el_match = te->checkELMatch(
325  tlbi_op.targetEL, tlbi_op.inHost);
326  if (te->valid && tlbi_op.secureLookup == !te->nstid && el_match) {
327 
328  DPRINTF(TLB, " - %s\n", te->print());
329  te->valid = false;
331  }
332  ++x;
333  }
334 
335  stats.flushTlb++;
336 }
337 
338 void
339 TLB::flush(const TLBIVMALL &tlbi_op)
340 {
341  DPRINTF(TLB, "Flushing all TLB entries (%s lookup)\n",
342  (tlbi_op.secureLookup ? "secure" : "non-secure"));
343  int x = 0;
344  TlbEntry *te;
345  while (x < size) {
346  te = &table[x];
347  const bool el_match = te->checkELMatch(
348  tlbi_op.targetEL, tlbi_op.inHost);
349  if (te->valid && tlbi_op.secureLookup == !te->nstid &&
350  (te->vmid == vmid || !tlbi_op.el2Enabled) && el_match) {
351 
352  DPRINTF(TLB, " - %s\n", te->print());
353  te->valid = false;
355  }
356  ++x;
357  }
358 
359  stats.flushTlb++;
360 }
361 
362 void
363 TLB::flush(const TLBIALLN &tlbi_op)
364 {
365  bool hyp = tlbi_op.targetEL == EL2;
366 
367  DPRINTF(TLB, "Flushing all NS TLB entries (%s lookup)\n",
368  (hyp ? "hyp" : "non-hyp"));
369  int x = 0;
370  TlbEntry *te;
371  while (x < size) {
372  te = &table[x];
373  const bool el_match = te->checkELMatch(tlbi_op.targetEL, false);
374 
375  if (te->valid && te->nstid && te->isHyp == hyp && el_match) {
376 
377  DPRINTF(TLB, " - %s\n", te->print());
379  te->valid = false;
380  }
381  ++x;
382  }
383 
384  stats.flushTlb++;
385 }
386 
387 void
388 TLB::flush(const TLBIMVA &tlbi_op)
389 {
390  DPRINTF(TLB, "Flushing TLB entries with mva: %#x, asid: %#x "
391  "(%s lookup)\n", tlbi_op.addr, tlbi_op.asid,
392  (tlbi_op.secureLookup ? "secure" : "non-secure"));
393  _flushMva(tlbi_op.addr, tlbi_op.asid, tlbi_op.secureLookup, false,
394  tlbi_op.targetEL, tlbi_op.inHost);
396 }
397 
398 void
399 TLB::flush(const TLBIASID &tlbi_op)
400 {
401  DPRINTF(TLB, "Flushing TLB entries with asid: %#x (%s lookup)\n",
402  tlbi_op.asid, (tlbi_op.secureLookup ? "secure" : "non-secure"));
403 
404  int x = 0 ;
405  TlbEntry *te;
406 
407  while (x < size) {
408  te = &table[x];
409  if (te->valid && te->asid == tlbi_op.asid &&
410  tlbi_op.secureLookup == !te->nstid &&
411  (te->vmid == vmid || tlbi_op.el2Enabled) &&
412  te->checkELMatch(tlbi_op.targetEL, tlbi_op.inHost)) {
413 
414  te->valid = false;
415  DPRINTF(TLB, " - %s\n", te->print());
417  }
418  ++x;
419  }
421 }
422 
423 void
424 TLB::flush(const TLBIMVAA &tlbi_op) {
425 
426  DPRINTF(TLB, "Flushing TLB entries with mva: %#x (%s lookup)\n",
427  tlbi_op.addr,
428  (tlbi_op.secureLookup ? "secure" : "non-secure"));
429  _flushMva(tlbi_op.addr, 0xbeef, tlbi_op.secureLookup, true,
430  tlbi_op.targetEL, tlbi_op.inHost);
431  stats.flushTlbMva++;
432 }
433 
434 void
435 TLB::_flushMva(Addr mva, uint64_t asn, bool secure_lookup,
436  bool ignore_asn, ExceptionLevel target_el, bool in_host)
437 {
438  TlbEntry *te;
439  // D5.7.2: Sign-extend address to 64 bits
440  mva = sext<56>(mva);
441 
442  bool hyp = target_el == EL2;
443 
444  te = lookup(mva, asn, vmid, hyp, secure_lookup, true, ignore_asn,
445  target_el, in_host, BaseMMU::Read);
446  while (te != NULL) {
447  if (secure_lookup == !te->nstid) {
448  DPRINTF(TLB, " - %s\n", te->print());
449  te->valid = false;
451  }
452  te = lookup(mva, asn, vmid, hyp, secure_lookup, true, ignore_asn,
453  target_el, in_host, BaseMMU::Read);
454  }
455 }
456 
457 void
459 {
460  // We might have unserialized something or switched CPUs, so make
461  // sure to re-read the misc regs.
462  miscRegValid = false;
463 }
464 
465 void
467 {
468  TLB *otlb = dynamic_cast<TLB*>(_otlb);
469  /* Make sure we actually have a valid type */
470  if (otlb) {
471  _attr = otlb->_attr;
473  stage2Req = otlb->stage2Req;
475 
476  /* Sync the stage2 MMU if they exist in both
477  * the old CPU and the new
478  */
479  if (!isStage2 &&
480  stage2Tlb && otlb->stage2Tlb) {
482  }
483  } else {
484  panic("Incompatible TLB type!");
485  }
486 }
487 
489  : statistics::Group(parent),
490  ADD_STAT(instHits, statistics::units::Count::get(), "ITB inst hits"),
491  ADD_STAT(instMisses, statistics::units::Count::get(), "ITB inst misses"),
492  ADD_STAT(readHits, statistics::units::Count::get(), "DTB read hits"),
493  ADD_STAT(readMisses, statistics::units::Count::get(), "DTB read misses"),
494  ADD_STAT(writeHits, statistics::units::Count::get(), "DTB write hits"),
495  ADD_STAT(writeMisses, statistics::units::Count::get(), "DTB write misses"),
496  ADD_STAT(inserts, statistics::units::Count::get(),
497  "Number of times an entry is inserted into the TLB"),
498  ADD_STAT(flushTlb, statistics::units::Count::get(),
499  "Number of times complete TLB was flushed"),
500  ADD_STAT(flushTlbMva, statistics::units::Count::get(),
501  "Number of times TLB was flushed by MVA"),
502  ADD_STAT(flushTlbMvaAsid, statistics::units::Count::get(),
503  "Number of times TLB was flushed by MVA & ASID"),
504  ADD_STAT(flushTlbAsid, statistics::units::Count::get(),
505  "Number of times TLB was flushed by ASID"),
506  ADD_STAT(flushedEntries, statistics::units::Count::get(),
507  "Number of entries that have been flushed from TLB"),
508  ADD_STAT(alignFaults, statistics::units::Count::get(),
509  "Number of TLB faults due to alignment restrictions"),
510  ADD_STAT(prefetchFaults, statistics::units::Count::get(),
511  "Number of TLB faults due to prefetch"),
512  ADD_STAT(domainFaults, statistics::units::Count::get(),
513  "Number of TLB faults due to domain restrictions"),
514  ADD_STAT(permsFaults, statistics::units::Count::get(),
515  "Number of TLB faults due to permissions restrictions"),
516  ADD_STAT(readAccesses, statistics::units::Count::get(), "DTB read accesses",
517  readHits + readMisses),
518  ADD_STAT(writeAccesses, statistics::units::Count::get(), "DTB write accesses",
519  writeHits + writeMisses),
520  ADD_STAT(instAccesses, statistics::units::Count::get(), "ITB inst accesses",
521  instHits + instMisses),
522  ADD_STAT(hits, statistics::units::Count::get(),
523  "Total TLB (inst and data) hits",
524  readHits + writeHits + instHits),
525  ADD_STAT(misses, statistics::units::Count::get(),
526  "Total TLB (inst and data) misses",
527  readMisses + writeMisses + instMisses),
528  ADD_STAT(accesses, statistics::units::Count::get(),
529  "Total TLB (inst and data) accesses",
530  readAccesses + writeAccesses + instAccesses)
531 {
532 }
533 
534 void
536 {
537  ppRefills.reset(new probing::PMU(getProbeManager(), "Refills"));
538 }
539 
540 Fault
542  BaseMMU::Translation *translation, bool &delay, bool timing)
543 {
544  updateMiscReg(tc);
545  Addr vaddr_tainted = req->getVaddr();
546  Addr vaddr = 0;
547  if (aarch64)
548  vaddr = purifyTaggedAddr(vaddr_tainted, tc, aarch64EL, (TCR)ttbcr,
550  else
551  vaddr = vaddr_tainted;
552  Request::Flags flags = req->getFlags();
553 
554  bool is_fetch = (mode == BaseMMU::Execute);
555  bool is_write = (mode == BaseMMU::Write);
556 
557  if (!is_fetch) {
558  if (sctlr.a || !(flags & AllowUnaligned)) {
559  if (vaddr & mask(flags & AlignmentMask)) {
560  // LPAE is always disabled in SE mode
561  return std::make_shared<DataAbort>(
562  vaddr_tainted,
563  TlbEntry::DomainType::NoAccess, is_write,
564  ArmFault::AlignmentFault, isStage2,
566  }
567  }
568  }
569 
570  Addr paddr;
571  Process *p = tc->getProcessPtr();
572 
573  if (!p->pTable->translate(vaddr, paddr))
574  return std::make_shared<GenericPageTableFault>(vaddr_tainted);
575  req->setPaddr(paddr);
576 
577  return finalizePhysical(req, tc, mode);
578 }
579 
580 Fault
582 {
583  // a data cache maintenance instruction that operates by MVA does
584  // not generate a Data Abort exeception due to a Permission fault
585  if (req->isCacheMaintenance()) {
586  return NoFault;
587  }
588 
589  Addr vaddr = req->getVaddr(); // 32-bit don't have to purify
590  Request::Flags flags = req->getFlags();
591  bool is_fetch = (mode == BaseMMU::Execute);
592  bool is_write = (mode == BaseMMU::Write);
593  bool is_priv = isPriv && !(flags & UserMode);
594 
595  // Get the translation type from the actuall table entry
596  ArmFault::TranMethod tranMethod = te->longDescFormat ? ArmFault::LpaeTran
598 
599  // If this is the second stage of translation and the request is for a
600  // stage 1 page table walk then we need to check the HCR.PTW bit. This
601  // allows us to generate a fault if the request targets an area marked
602  // as a device or strongly ordered.
603  if (isStage2 && req->isPTWalk() && hcr.ptw &&
604  (te->mtype != TlbEntry::MemoryType::Normal)) {
605  return std::make_shared<DataAbort>(
606  vaddr, te->domain, is_write,
607  ArmFault::PermissionLL + te->lookupLevel,
608  isStage2, tranMethod);
609  }
610 
611  // Generate an alignment fault for unaligned data accesses to device or
612  // strongly ordered memory
613  if (!is_fetch) {
614  if (te->mtype != TlbEntry::MemoryType::Normal) {
615  if (vaddr & mask(flags & AlignmentMask)) {
616  stats.alignFaults++;
617  return std::make_shared<DataAbort>(
618  vaddr, TlbEntry::DomainType::NoAccess, is_write,
619  ArmFault::AlignmentFault, isStage2,
620  tranMethod);
621  }
622  }
623  }
624 
625  if (te->nonCacheable) {
626  // Prevent prefetching from I/O devices.
627  if (req->isPrefetch()) {
628  // Here we can safely use the fault status for the short
629  // desc. format in all cases
630  return std::make_shared<PrefetchAbort>(
632  isStage2, tranMethod);
633  }
634  }
635 
636  if (!te->longDescFormat) {
637  switch ((dacr >> (static_cast<uint8_t>(te->domain) * 2)) & 0x3) {
638  case 0:
639  stats.domainFaults++;
640  DPRINTF(TLB, "TLB Fault: Data abort on domain. DACR: %#x"
641  " domain: %#x write:%d\n", dacr,
642  static_cast<uint8_t>(te->domain), is_write);
643  if (is_fetch) {
644  // Use PC value instead of vaddr because vaddr might
645  // be aligned to cache line and should not be the
646  // address reported in FAR
647  return std::make_shared<PrefetchAbort>(
648  req->getPC(),
649  ArmFault::DomainLL + te->lookupLevel,
650  isStage2, tranMethod);
651  } else
652  return std::make_shared<DataAbort>(
653  vaddr, te->domain, is_write,
654  ArmFault::DomainLL + te->lookupLevel,
655  isStage2, tranMethod);
656  case 1:
657  // Continue with permissions check
658  break;
659  case 2:
660  panic("UNPRED domain\n");
661  case 3:
662  return NoFault;
663  }
664  }
665 
666  // The 'ap' variable is AP[2:0] or {AP[2,1],1b'0}, i.e. always three bits
667  uint8_t ap = te->longDescFormat ? te->ap << 1 : te->ap;
668  uint8_t hap = te->hap;
669 
670  if (sctlr.afe == 1 || te->longDescFormat)
671  ap |= 1;
672 
673  bool abt;
674  bool isWritable = true;
675  // If this is a stage 2 access (eg for reading stage 1 page table entries)
676  // then don't perform the AP permissions check, we stil do the HAP check
677  // below.
678  if (isStage2) {
679  abt = false;
680  } else {
681  switch (ap) {
682  case 0:
683  DPRINTF(TLB, "Access permissions 0, checking rs:%#x\n",
684  (int)sctlr.rs);
685  if (!sctlr.xp) {
686  switch ((int)sctlr.rs) {
687  case 2:
688  abt = is_write;
689  break;
690  case 1:
691  abt = is_write || !is_priv;
692  break;
693  case 0:
694  case 3:
695  default:
696  abt = true;
697  break;
698  }
699  } else {
700  abt = true;
701  }
702  break;
703  case 1:
704  abt = !is_priv;
705  break;
706  case 2:
707  abt = !is_priv && is_write;
708  isWritable = is_priv;
709  break;
710  case 3:
711  abt = false;
712  break;
713  case 4:
714  panic("UNPRED premissions\n");
715  case 5:
716  abt = !is_priv || is_write;
717  isWritable = false;
718  break;
719  case 6:
720  case 7:
721  abt = is_write;
722  isWritable = false;
723  break;
724  default:
725  panic("Unknown permissions %#x\n", ap);
726  }
727  }
728 
729  bool hapAbt = is_write ? !(hap & 2) : !(hap & 1);
730  bool xn = te->xn || (isWritable && sctlr.wxn) ||
731  (ap == 3 && sctlr.uwxn && is_priv);
732  if (is_fetch && (abt || xn ||
733  (te->longDescFormat && te->pxn && is_priv) ||
734  (isSecure && te->ns && scr.sif))) {
735  stats.permsFaults++;
736  DPRINTF(TLB, "TLB Fault: Prefetch abort on permission check. AP:%d "
737  "priv:%d write:%d ns:%d sif:%d sctlr.afe: %d \n",
738  ap, is_priv, is_write, te->ns, scr.sif,sctlr.afe);
739  // Use PC value instead of vaddr because vaddr might be aligned to
740  // cache line and should not be the address reported in FAR
741  return std::make_shared<PrefetchAbort>(
742  req->getPC(),
743  ArmFault::PermissionLL + te->lookupLevel,
744  isStage2, tranMethod);
745  } else if (abt | hapAbt) {
746  stats.permsFaults++;
747  DPRINTF(TLB, "TLB Fault: Data abort on permission check. AP:%d priv:%d"
748  " write:%d\n", ap, is_priv, is_write);
749  return std::make_shared<DataAbort>(
750  vaddr, te->domain, is_write,
751  ArmFault::PermissionLL + te->lookupLevel,
752  isStage2 | !abt, tranMethod);
753  }
754  return NoFault;
755 }
756 
757 
758 Fault
761 {
762  assert(aarch64);
763 
764  // A data cache maintenance instruction that operates by VA does
765  // not generate a Permission fault unless:
766  // * It is a data cache invalidate (dc ivac) which requires write
767  // permissions to the VA, or
768  // * It is executed from EL0
769  if (req->isCacheClean() && aarch64EL != EL0 && !isStage2) {
770  return NoFault;
771  }
772 
773  Addr vaddr_tainted = req->getVaddr();
774  Addr vaddr = purifyTaggedAddr(vaddr_tainted, tc, aarch64EL, (TCR)ttbcr,
776 
777  Request::Flags flags = req->getFlags();
778  bool is_fetch = (mode == BaseMMU::Execute);
779  // Cache clean operations require read permissions to the specified VA
780  bool is_write = !req->isCacheClean() && mode == BaseMMU::Write;
781  bool is_atomic = req->isAtomic();
782  GEM5_VAR_USED bool is_priv = isPriv && !(flags & UserMode);
783 
784  updateMiscReg(tc, curTranType);
785 
786  // If this is the second stage of translation and the request is for a
787  // stage 1 page table walk then we need to check the HCR.PTW bit. This
788  // allows us to generate a fault if the request targets an area marked
789  // as a device or strongly ordered.
790  if (isStage2 && req->isPTWalk() && hcr.ptw &&
791  (te->mtype != TlbEntry::MemoryType::Normal)) {
792  return std::make_shared<DataAbort>(
793  vaddr_tainted, te->domain, is_write,
794  ArmFault::PermissionLL + te->lookupLevel,
795  isStage2, ArmFault::LpaeTran);
796  }
797 
798  // Generate an alignment fault for unaligned accesses to device or
799  // strongly ordered memory
800  if (!is_fetch) {
801  if (te->mtype != TlbEntry::MemoryType::Normal) {
802  if (vaddr & mask(flags & AlignmentMask)) {
803  stats.alignFaults++;
804  return std::make_shared<DataAbort>(
805  vaddr_tainted,
806  TlbEntry::DomainType::NoAccess,
807  is_atomic ? false : is_write,
808  ArmFault::AlignmentFault, isStage2,
810  }
811  }
812  }
813 
814  if (te->nonCacheable) {
815  // Prevent prefetching from I/O devices.
816  if (req->isPrefetch()) {
817  // Here we can safely use the fault status for the short
818  // desc. format in all cases
819  return std::make_shared<PrefetchAbort>(
820  vaddr_tainted,
822  isStage2, ArmFault::LpaeTran);
823  }
824  }
825 
826  uint8_t ap = 0x3 & (te->ap); // 2-bit access protection field
827  bool grant = false;
828 
829  bool wxn = sctlr.wxn;
830  uint8_t xn = te->xn;
831  uint8_t pxn = te->pxn;
832  bool r = (!is_write && !is_fetch);
833  bool w = is_write;
834  bool x = is_fetch;
835 
836  if (ArmSystem::haveEL(tc, EL3) && isSecure && te->ns && scr.sif)
837  xn = true;
838 
839  // grant_read is used for faults from an atomic instruction that
840  // both reads and writes from a memory location. From a ISS point
841  // of view they count as read if a read to that address would have
842  // generated the fault; they count as writes otherwise
843  bool grant_read = true;
844  DPRINTF(TLBVerbose, "Checking permissions: ap:%d, xn:%d, pxn:%d, r:%d, "
845  "w:%d, x:%d, is_priv: %d, wxn: %d\n", ap, xn,
846  pxn, r, w, x, is_priv, wxn);
847 
848  if (isStage2) {
849  assert(ArmSystem::haveVirtualization(tc) && aarch64EL != EL2);
850  // In stage 2 we use the hypervisor access permission bits.
851  // The following permissions are described in ARM DDI 0487A.f
852  // D4-1802
853  uint8_t hap = 0x3 & te->hap;
854  grant_read = hap & 0x1;
855  if (is_fetch) {
856  // sctlr.wxn overrides the xn bit
857  grant = !wxn && !xn;
858  } else if (is_atomic) {
859  grant = hap;
860  } else if (is_write) {
861  grant = hap & 0x2;
862  } else { // is_read
863  grant = grant_read;
864  }
865  } else {
866  switch (aarch64EL) {
867  case EL0:
868  {
869  grant_read = ap & 0x1;
870  uint8_t perm = (ap << 2) | (xn << 1) | pxn;
871  switch (perm) {
872  case 0:
873  case 1:
874  case 8:
875  case 9:
876  grant = x;
877  break;
878  case 4:
879  case 5:
880  grant = r || w || (x && !wxn);
881  break;
882  case 6:
883  case 7:
884  grant = r || w;
885  break;
886  case 12:
887  case 13:
888  grant = r || x;
889  break;
890  case 14:
891  case 15:
892  grant = r;
893  break;
894  default:
895  grant = false;
896  }
897  }
898  break;
899  case EL1:
900  {
901  if (checkPAN(tc, ap, req, mode, is_priv)) {
902  grant = false;
903  grant_read = false;
904  break;
905  }
906 
907  uint8_t perm = (ap << 2) | (xn << 1) | pxn;
908  switch (perm) {
909  case 0:
910  case 2:
911  grant = r || w || (x && !wxn);
912  break;
913  case 1:
914  case 3:
915  case 4:
916  case 5:
917  case 6:
918  case 7:
919  // regions that are writeable at EL0 should not be
920  // executable at EL1
921  grant = r || w;
922  break;
923  case 8:
924  case 10:
925  case 12:
926  case 14:
927  grant = r || x;
928  break;
929  case 9:
930  case 11:
931  case 13:
932  case 15:
933  grant = r;
934  break;
935  default:
936  grant = false;
937  }
938  }
939  break;
940  case EL2:
941  if (hcr.e2h && checkPAN(tc, ap, req, mode, is_priv)) {
942  grant = false;
943  grant_read = false;
944  break;
945  }
947  case EL3:
948  {
949  uint8_t perm = (ap & 0x2) | xn;
950  switch (perm) {
951  case 0:
952  grant = r || w || (x && !wxn);
953  break;
954  case 1:
955  grant = r || w;
956  break;
957  case 2:
958  grant = r || x;
959  break;
960  case 3:
961  grant = r;
962  break;
963  default:
964  grant = false;
965  }
966  }
967  break;
968  }
969  }
970 
971  if (!grant) {
972  if (is_fetch) {
973  stats.permsFaults++;
974  DPRINTF(TLB, "TLB Fault: Prefetch abort on permission check. "
975  "AP:%d priv:%d write:%d ns:%d sif:%d "
976  "sctlr.afe: %d\n",
977  ap, is_priv, is_write, te->ns, scr.sif, sctlr.afe);
978  // Use PC value instead of vaddr because vaddr might be aligned to
979  // cache line and should not be the address reported in FAR
980  return std::make_shared<PrefetchAbort>(
981  req->getPC(),
982  ArmFault::PermissionLL + te->lookupLevel,
983  isStage2, ArmFault::LpaeTran);
984  } else {
985  stats.permsFaults++;
986  DPRINTF(TLB, "TLB Fault: Data abort on permission check. AP:%d "
987  "priv:%d write:%d\n", ap, is_priv, is_write);
988  return std::make_shared<DataAbort>(
989  vaddr_tainted, te->domain,
990  (is_atomic && !grant_read) ? false : is_write,
991  ArmFault::PermissionLL + te->lookupLevel,
992  isStage2, ArmFault::LpaeTran);
993  }
994  }
995 
996  return NoFault;
997 }
998 
999 bool
1000 TLB::checkPAN(ThreadContext *tc, uint8_t ap, const RequestPtr &req,
1001  BaseMMU::Mode mode, const bool is_priv)
1002 {
1003  // The PAN bit has no effect on:
1004  // 1) Instruction accesses.
1005  // 2) Data Cache instructions other than DC ZVA
1006  // 3) Address translation instructions, other than ATS1E1RP and
1007  // ATS1E1WP when ARMv8.2-ATS1E1 is implemented. (Unimplemented in
1008  // gem5)
1009  // 4) Instructions to be treated as unprivileged, unless
1010  // HCR_EL2.{E2H, TGE} == {1, 0}
1011  const AA64MMFR1 mmfr1 = tc->readMiscReg(MISCREG_ID_AA64MMFR1_EL1);
1012  if (mmfr1.pan && cpsr.pan && (ap & 0x1) && mode != BaseMMU::Execute) {
1013  if (req->isCacheMaintenance() &&
1014  !(req->getFlags() & Request::CACHE_BLOCK_ZERO)) {
1015  // Cache maintenance other than DC ZVA
1016  return false;
1017  } else if (!is_priv && !(hcr.e2h && !hcr.tge)) {
1018  // Treated as unprivileged unless HCR_EL2.{E2H, TGE} == {1, 0}
1019  return false;
1020  }
1021  return true;
1022  }
1023 
1024  return false;
1025 }
1026 
1027 Fault
1030  Addr vaddr, bool long_desc_format)
1031 {
1032  bool is_fetch = (mode == BaseMMU::Execute);
1033  bool is_atomic = req->isAtomic();
1034  req->setPaddr(vaddr);
1035  // When the MMU is off the security attribute corresponds to the
1036  // security state of the processor
1037  if (isSecure)
1038  req->setFlags(Request::SECURE);
1039 
1040  if (aarch64) {
1041  bool selbit = bits(vaddr, 55);
1042  TCR tcr1 = tc->readMiscReg(MISCREG_TCR_EL1);
1043  int topbit = computeAddrTop(tc, selbit, is_fetch, tcr1, currEL(tc));
1044  int addr_sz = bits(vaddr, topbit, physAddrRange);
1045  if (addr_sz != 0){
1046  Fault f;
1047  if (is_fetch)
1048  f = std::make_shared<PrefetchAbort>(vaddr,
1050  else
1051  f = std::make_shared<DataAbort>( vaddr,
1052  TlbEntry::DomainType::NoAccess,
1053  is_atomic ? false : mode==BaseMMU::Write,
1055  return f;
1056  }
1057  }
1058 
1059  // @todo: double check this (ARM ARM issue C B3.2.1)
1060  if (long_desc_format || sctlr.tre == 0 || nmrr.ir0 == 0 ||
1061  nmrr.or0 == 0 || prrr.tr0 != 0x2) {
1062  if (!req->isCacheMaintenance()) {
1063  req->setFlags(Request::UNCACHEABLE);
1064  }
1065  req->setFlags(Request::STRICT_ORDER);
1066  }
1067 
1068  // Set memory attributes
1069  TlbEntry temp_te;
1070  temp_te.ns = !isSecure;
1071  bool dc = (HaveVirtHostExt(tc)
1072  && hcr.e2h == 1 && hcr.tge == 1) ? 0: hcr.dc;
1073  bool i_cacheability = sctlr.i && !sctlr.m;
1074  if (isStage2 || !dc || isSecure ||
1075  (isHyp && !(tranType & S1CTran))) {
1076 
1077  temp_te.mtype = is_fetch ? TlbEntry::MemoryType::Normal
1078  : TlbEntry::MemoryType::StronglyOrdered;
1079  temp_te.innerAttrs = i_cacheability? 0x2: 0x0;
1080  temp_te.outerAttrs = i_cacheability? 0x2: 0x0;
1081  temp_te.shareable = true;
1082  temp_te.outerShareable = true;
1083  } else {
1084  temp_te.mtype = TlbEntry::MemoryType::Normal;
1085  temp_te.innerAttrs = 0x3;
1086  temp_te.outerAttrs = 0x3;
1087  temp_te.shareable = false;
1088  temp_te.outerShareable = false;
1089  }
1090  temp_te.setAttributes(long_desc_format);
1091  DPRINTF(TLBVerbose, "(No MMU) setting memory attributes: shareable: "
1092  "%d, innerAttrs: %d, outerAttrs: %d, isStage2: %d\n",
1093  temp_te.shareable, temp_te.innerAttrs, temp_te.outerAttrs,
1094  isStage2);
1095  setAttr(temp_te.attributes);
1096 
1097  return testTranslation(req, mode, TlbEntry::DomainType::NoAccess);
1098 }
1099 
1100 Fault
1102  BaseMMU::Mode mode, BaseMMU::Translation *translation,
1103  bool &delay, bool timing,
1104  bool functional, Addr vaddr,
1105  ArmFault::TranMethod tranMethod)
1106 {
1107  TlbEntry *te = NULL;
1108  bool is_fetch = (mode == BaseMMU::Execute);
1109  TlbEntry mergeTe;
1110 
1111  Request::Flags flags = req->getFlags();
1112  Addr vaddr_tainted = req->getVaddr();
1113 
1114  Fault fault = getResultTe(&te, req, tc, mode, translation, timing,
1115  functional, &mergeTe);
1116  // only proceed if we have a valid table entry
1117  if ((te == NULL) && (fault == NoFault)) delay = true;
1118 
1119  // If we have the table entry transfer some of the attributes to the
1120  // request that triggered the translation
1121  if (te != NULL) {
1122  // Set memory attributes
1123  DPRINTF(TLBVerbose,
1124  "Setting memory attributes: shareable: %d, innerAttrs: %d, "
1125  "outerAttrs: %d, mtype: %d, isStage2: %d\n",
1126  te->shareable, te->innerAttrs, te->outerAttrs,
1127  static_cast<uint8_t>(te->mtype), isStage2);
1128  setAttr(te->attributes);
1129 
1130  if (te->nonCacheable && !req->isCacheMaintenance())
1131  req->setFlags(Request::UNCACHEABLE);
1132 
1133  // Require requests to be ordered if the request goes to
1134  // strongly ordered or device memory (i.e., anything other
1135  // than normal memory requires strict order).
1136  if (te->mtype != TlbEntry::MemoryType::Normal)
1137  req->setFlags(Request::STRICT_ORDER);
1138 
1139  Addr pa = te->pAddr(vaddr);
1140  req->setPaddr(pa);
1141 
1142  if (isSecure && !te->ns) {
1143  req->setFlags(Request::SECURE);
1144  }
1145  if (!is_fetch && fault == NoFault &&
1146  (vaddr & mask(flags & AlignmentMask)) &&
1147  (te->mtype != TlbEntry::MemoryType::Normal)) {
1148  // Unaligned accesses to Device memory should always cause an
1149  // abort regardless of sctlr.a
1150  stats.alignFaults++;
1151  bool is_write = (mode == BaseMMU::Write);
1152  return std::make_shared<DataAbort>(
1153  vaddr_tainted,
1154  TlbEntry::DomainType::NoAccess, is_write,
1155  ArmFault::AlignmentFault, isStage2,
1156  tranMethod);
1157  }
1158 
1159  // Check for a trickbox generated address fault
1160  if (fault == NoFault)
1161  fault = testTranslation(req, mode, te->domain);
1162  }
1163 
1164  if (fault == NoFault) {
1165  // Don't try to finalize a physical address unless the
1166  // translation has completed (i.e., there is a table entry).
1167  return te ? finalizePhysical(req, tc, mode) : NoFault;
1168  } else {
1169  return fault;
1170  }
1171 }
1172 
1173 Fault
1175  BaseMMU::Translation *translation, bool &delay, bool timing,
1176  TLB::ArmTranslationType tranType, bool functional)
1177 {
1178  // No such thing as a functional timing access
1179  assert(!(timing && functional));
1180 
1181  updateMiscReg(tc, tranType);
1182 
1183  Addr vaddr_tainted = req->getVaddr();
1184  Addr vaddr = 0;
1185  if (aarch64)
1186  vaddr = purifyTaggedAddr(vaddr_tainted, tc, aarch64EL, (TCR)ttbcr,
1188  else
1189  vaddr = vaddr_tainted;
1190  Request::Flags flags = req->getFlags();
1191 
1192  bool is_fetch = (mode == BaseMMU::Execute);
1193  bool is_write = (mode == BaseMMU::Write);
1194  bool long_desc_format = aarch64 || longDescFormatInUse(tc);
1195  ArmFault::TranMethod tranMethod = long_desc_format ? ArmFault::LpaeTran
1197 
1198  DPRINTF(TLBVerbose,
1199  "CPSR is priv:%d UserMode:%d secure:%d S1S2NsTran:%d\n",
1200  isPriv, flags & UserMode, isSecure, tranType & S1S2NsTran);
1201 
1202  DPRINTF(TLB, "translateFs addr %#x, mode %d, st2 %d, scr %#x sctlr %#x "
1203  "flags %#lx tranType 0x%x\n", vaddr_tainted, mode, isStage2,
1204  scr, sctlr, flags, tranType);
1205 
1206  if ((req->isInstFetch() && (!sctlr.i)) ||
1207  ((!req->isInstFetch()) && (!sctlr.c))){
1208  if (!req->isCacheMaintenance()) {
1209  req->setFlags(Request::UNCACHEABLE);
1210  }
1211  req->setFlags(Request::STRICT_ORDER);
1212  }
1213  if (!is_fetch) {
1214  if (sctlr.a || !(flags & AllowUnaligned)) {
1215  if (vaddr & mask(flags & AlignmentMask)) {
1216  stats.alignFaults++;
1217  return std::make_shared<DataAbort>(
1218  vaddr_tainted,
1219  TlbEntry::DomainType::NoAccess, is_write,
1220  ArmFault::AlignmentFault, isStage2,
1221  tranMethod);
1222  }
1223  }
1224  }
1225 
1226  bool vm = hcr.vm;
1227  if (HaveVirtHostExt(tc) && hcr.e2h == 1 && hcr.tge ==1)
1228  vm = 0;
1229  else if (hcr.dc == 1)
1230  vm = 1;
1231 
1232  Fault fault = NoFault;
1233  // If guest MMU is off or hcr.vm=0 go straight to stage2
1234  if ((isStage2 && !vm) || (!isStage2 && !sctlr.m)) {
1235  fault = translateMmuOff(tc, req, mode, tranType, vaddr,
1236  long_desc_format);
1237  } else {
1238  DPRINTF(TLBVerbose, "Translating %s=%#x context=%d\n",
1239  isStage2 ? "IPA" : "VA", vaddr_tainted, asid);
1240  // Translation enabled
1241  fault = translateMmuOn(tc, req, mode, translation, delay, timing,
1242  functional, vaddr, tranMethod);
1243  }
1244 
1245  // Check for Debug Exceptions
1247 
1248  if (sd->enabled() && fault == NoFault) {
1249  fault = sd->testDebug(tc, req, mode);
1250  }
1251 
1252  return fault;
1253 }
1254 
1255 Fault
1258 {
1259  updateMiscReg(tc, tranType);
1260 
1261  if (directToStage2) {
1262  assert(stage2Tlb);
1263  return stage2Tlb->translateAtomic(req, tc, mode, tranType);
1264  }
1265 
1266  bool delay = false;
1267  Fault fault;
1268  if (FullSystem)
1269  fault = translateFs(req, tc, mode, NULL, delay, false, tranType);
1270  else
1271  fault = translateSe(req, tc, mode, NULL, delay, false);
1272  assert(!delay);
1273  return fault;
1274 }
1275 
1276 Fault
1279 {
1280  updateMiscReg(tc, tranType);
1281 
1282  if (directToStage2) {
1283  assert(stage2Tlb);
1284  return stage2Tlb->translateFunctional(req, tc, mode, tranType);
1285  }
1286 
1287  bool delay = false;
1288  Fault fault;
1289  if (FullSystem)
1290  fault = translateFs(req, tc, mode, NULL, delay, false, tranType, true);
1291  else
1292  fault = translateSe(req, tc, mode, NULL, delay, false);
1293  assert(!delay);
1294  return fault;
1295 }
1296 
1297 void
1299  BaseMMU::Translation *translation, BaseMMU::Mode mode,
1300  TLB::ArmTranslationType tranType)
1301 {
1302  updateMiscReg(tc, tranType);
1303 
1304  if (directToStage2) {
1305  assert(stage2Tlb);
1306  stage2Tlb->translateTiming(req, tc, translation, mode, tranType);
1307  return;
1308  }
1309 
1310  assert(translation);
1311 
1312  translateComplete(req, tc, translation, mode, tranType, isStage2);
1313 }
1314 
1315 Fault
1317  BaseMMU::Translation *translation, BaseMMU::Mode mode,
1318  TLB::ArmTranslationType tranType, bool callFromS2)
1319 {
1320  bool delay = false;
1321  Fault fault;
1322  if (FullSystem)
1323  fault = translateFs(req, tc, mode, translation, delay, true, tranType);
1324  else
1325  fault = translateSe(req, tc, mode, translation, delay, true);
1326  DPRINTF(TLBVerbose, "Translation returning delay=%d fault=%d\n", delay, fault !=
1327  NoFault);
1328  // If we have a translation, and we're not in the middle of doing a stage
1329  // 2 translation tell the translation that we've either finished or its
1330  // going to take a while. By not doing this when we're in the middle of a
1331  // stage 2 translation we prevent marking the translation as delayed twice,
1332  // one when the translation starts and again when the stage 1 translation
1333  // completes.
1334 
1335  if (translation && (callFromS2 || !stage2Req || req->hasPaddr() ||
1336  fault != NoFault)) {
1337  if (!delay)
1338  translation->finish(fault, req, tc, mode);
1339  else
1340  translation->markDelayed();
1341  }
1342  return fault;
1343 }
1344 
1345 Port *
1347 {
1348  return &tableWalker->getTableWalkerPort();
1349 }
1350 
1351 vmid_t
1353 {
1354  AA64MMFR1 mmfr1 = tc->readMiscReg(MISCREG_ID_AA64MMFR1_EL1);
1355  VTCR_t vtcr = tc->readMiscReg(MISCREG_VTCR_EL2);
1356  vmid_t vmid = 0;
1357 
1358  switch (mmfr1.vmidbits) {
1359  case 0b0000:
1360  // 8 bits
1361  vmid = bits(tc->readMiscReg(MISCREG_VTTBR_EL2), 55, 48);
1362  break;
1363  case 0b0010:
1364  if (vtcr.vs && ELIs64(tc, EL2)) {
1365  // 16 bits
1366  vmid = bits(tc->readMiscReg(MISCREG_VTTBR_EL2), 63, 48);
1367  } else {
1368  // 8 bits
1369  vmid = bits(tc->readMiscReg(MISCREG_VTTBR_EL2), 55, 48);
1370  }
1371  break;
1372  default:
1373  panic("Reserved ID_AA64MMFR1_EL1.VMIDBits value: %#x",
1374  mmfr1.vmidbits);
1375  }
1376 
1377  return vmid;
1378 }
1379 
1380 void
1382 {
1383  // check if the regs have changed, or the translation mode is different.
1384  // NOTE: the tran type doesn't affect stage 2 TLB's as they only handle
1385  // one type of translation anyway
1386  if (miscRegValid && miscRegContext == tc->contextId() &&
1387  ((tranType == curTranType) || isStage2)) {
1388  return;
1389  }
1390 
1391  DPRINTF(TLBVerbose, "TLB variables changed!\n");
1392  cpsr = tc->readMiscReg(MISCREG_CPSR);
1393 
1394  // Dependencies: SCR/SCR_EL3, CPSR
1395  isSecure = ArmISA::isSecure(tc) &&
1396  !(tranType & HypMode) && !(tranType & S1S2NsTran);
1397 
1398  aarch64EL = tranTypeEL(cpsr, tranType);
1399  aarch64 = isStage2 ?
1400  ELIs64(tc, EL2) :
1401  ELIs64(tc, aarch64EL == EL0 ? EL1 : aarch64EL);
1402 
1403  hcr = tc->readMiscReg(MISCREG_HCR_EL2);
1404  if (aarch64) { // AArch64
1405  // determine EL we need to translate in
1406  switch (aarch64EL) {
1407  case EL0:
1408  if (HaveVirtHostExt(tc) && hcr.tge == 1 && hcr.e2h == 1) {
1409  // VHE code for EL2&0 regime
1410  sctlr = tc->readMiscReg(MISCREG_SCTLR_EL2);
1411  ttbcr = tc->readMiscReg(MISCREG_TCR_EL2);
1412  uint64_t ttbr_asid = ttbcr.a1 ?
1415  asid = bits(ttbr_asid,
1416  (haveLargeAsid64 && ttbcr.as) ? 63 : 55, 48);
1417 
1418  } else {
1419  sctlr = tc->readMiscReg(MISCREG_SCTLR_EL1);
1420  ttbcr = tc->readMiscReg(MISCREG_TCR_EL1);
1421  uint64_t ttbr_asid = ttbcr.a1 ?
1424  asid = bits(ttbr_asid,
1425  (haveLargeAsid64 && ttbcr.as) ? 63 : 55, 48);
1426 
1427  }
1428  break;
1429  case EL1:
1430  {
1431  sctlr = tc->readMiscReg(MISCREG_SCTLR_EL1);
1432  ttbcr = tc->readMiscReg(MISCREG_TCR_EL1);
1433  uint64_t ttbr_asid = ttbcr.a1 ?
1436  asid = bits(ttbr_asid,
1437  (haveLargeAsid64 && ttbcr.as) ? 63 : 55, 48);
1438  }
1439  break;
1440  case EL2:
1441  sctlr = tc->readMiscReg(MISCREG_SCTLR_EL2);
1442  ttbcr = tc->readMiscReg(MISCREG_TCR_EL2);
1443  if (hcr.e2h == 1) {
1444  // VHE code for EL2&0 regime
1445  uint64_t ttbr_asid = ttbcr.a1 ?
1448  asid = bits(ttbr_asid,
1449  (haveLargeAsid64 && ttbcr.as) ? 63 : 55, 48);
1450  } else {
1451  asid = -1;
1452  }
1453  break;
1454  case EL3:
1455  sctlr = tc->readMiscReg(MISCREG_SCTLR_EL3);
1456  ttbcr = tc->readMiscReg(MISCREG_TCR_EL3);
1457  asid = -1;
1458  break;
1459  }
1460 
1461  scr = tc->readMiscReg(MISCREG_SCR_EL3);
1462  isPriv = aarch64EL != EL0;
1463  if (haveVirtualization) {
1464  vmid = getVMID(tc);
1465  isHyp = aarch64EL == EL2;
1466  isHyp |= tranType & HypMode;
1467  isHyp &= (tranType & S1S2NsTran) == 0;
1468  isHyp &= (tranType & S1CTran) == 0;
1469  bool vm = hcr.vm;
1470  if (HaveVirtHostExt(tc) && hcr.e2h == 1 && hcr.tge ==1) {
1471  vm = 0;
1472  }
1473 
1474  if (hcr.e2h == 1 && (aarch64EL == EL2
1475  || (hcr.tge ==1 && aarch64EL == EL0))) {
1476  isHyp = true;
1477  directToStage2 = false;
1478  stage2Req = false;
1479  stage2DescReq = false;
1480  } else {
1481  // Work out if we should skip the first stage of translation and go
1482  // directly to stage 2. This value is cached so we don't have to
1483  // compute it for every translation.
1484  bool sec = !isSecure || (isSecure && IsSecureEL2Enabled(tc));
1485  stage2Req = isStage2 ||
1486  (vm && !isHyp && sec &&
1487  !(tranType & S1CTran) && (aarch64EL < EL2) &&
1488  !(tranType & S1E1Tran)); // <--- FIX THIS HACK
1489  stage2DescReq = isStage2 || (vm && !isHyp && sec &&
1490  (aarch64EL < EL2));
1491  directToStage2 = !isStage2 && stage2Req && !sctlr.m;
1492  }
1493  } else {
1494  vmid = 0;
1495  isHyp = false;
1496  directToStage2 = false;
1497  stage2Req = false;
1498  stage2DescReq = false;
1499  }
1500  } else { // AArch32
1501  sctlr = tc->readMiscReg(snsBankedIndex(MISCREG_SCTLR, tc,
1502  !isSecure));
1503  ttbcr = tc->readMiscReg(snsBankedIndex(MISCREG_TTBCR, tc,
1504  !isSecure));
1505  scr = tc->readMiscReg(MISCREG_SCR);
1506  isPriv = cpsr.mode != MODE_USER;
1507  if (longDescFormatInUse(tc)) {
1508  uint64_t ttbr_asid = tc->readMiscReg(
1509  snsBankedIndex(ttbcr.a1 ? MISCREG_TTBR1 :
1510  MISCREG_TTBR0,
1511  tc, !isSecure));
1512  asid = bits(ttbr_asid, 55, 48);
1513  } else { // Short-descriptor translation table format in use
1514  CONTEXTIDR context_id = tc->readMiscReg(snsBankedIndex(
1516  asid = context_id.asid;
1517  }
1518  prrr = tc->readMiscReg(snsBankedIndex(MISCREG_PRRR, tc,
1519  !isSecure));
1520  nmrr = tc->readMiscReg(snsBankedIndex(MISCREG_NMRR, tc,
1521  !isSecure));
1522  dacr = tc->readMiscReg(snsBankedIndex(MISCREG_DACR, tc,
1523  !isSecure));
1524  hcr = tc->readMiscReg(MISCREG_HCR);
1525 
1526  if (haveVirtualization) {
1527  vmid = bits(tc->readMiscReg(MISCREG_VTTBR), 55, 48);
1528  isHyp = cpsr.mode == MODE_HYP;
1529  isHyp |= tranType & HypMode;
1530  isHyp &= (tranType & S1S2NsTran) == 0;
1531  isHyp &= (tranType & S1CTran) == 0;
1532  if (isHyp) {
1533  sctlr = tc->readMiscReg(MISCREG_HSCTLR);
1534  }
1535  // Work out if we should skip the first stage of translation and go
1536  // directly to stage 2. This value is cached so we don't have to
1537  // compute it for every translation.
1538  bool sec = !isSecure || (isSecure && IsSecureEL2Enabled(tc));
1539  stage2Req = hcr.vm && !isStage2 && !isHyp && sec &&
1540  !(tranType & S1CTran);
1541  stage2DescReq = hcr.vm && !isStage2 && !isHyp && sec;
1542  directToStage2 = stage2Req && !sctlr.m;
1543  } else {
1544  vmid = 0;
1545  stage2Req = false;
1546  isHyp = false;
1547  directToStage2 = false;
1548  stage2DescReq = false;
1549  }
1550  }
1551  miscRegValid = true;
1552  miscRegContext = tc->contextId();
1553  curTranType = tranType;
1554 }
1555 
1558 {
1559  switch (type) {
1560  case S1E0Tran:
1561  case S12E0Tran:
1562  return EL0;
1563 
1564  case S1E1Tran:
1565  case S12E1Tran:
1566  return EL1;
1567 
1568  case S1E2Tran:
1569  return EL2;
1570 
1571  case S1E3Tran:
1572  return EL3;
1573 
1574  case NormalTran:
1575  case S1CTran:
1576  case S1S2NsTran:
1577  case HypMode:
1578  return currEL(cpsr);
1579 
1580  default:
1581  panic("Unknown translation mode!\n");
1582  }
1583 }
1584 
1585 Fault
1587  BaseMMU::Mode mode, BaseMMU::Translation *translation, bool timing,
1588  bool functional, bool is_secure, TLB::ArmTranslationType tranType)
1589 {
1590  // In a 2-stage system, the IPA->PA translation can be started via this
1591  // call so make sure the miscRegs are correct.
1592  if (isStage2) {
1593  updateMiscReg(tc, tranType);
1594  }
1595 
1596  Addr vaddr_tainted = req->getVaddr();
1597  Addr vaddr = 0;
1598  ExceptionLevel target_el = aarch64 ? aarch64EL : EL1;
1599  if (aarch64) {
1600  vaddr = purifyTaggedAddr(vaddr_tainted, tc, target_el, (TCR)ttbcr,
1602  } else {
1603  vaddr = vaddr_tainted;
1604  }
1605  *te = lookup(vaddr, asid, vmid, isHyp, is_secure, false, false, target_el,
1606  false, mode);
1607  if (*te == NULL) {
1608  if (req->isPrefetch()) {
1609  // if the request is a prefetch don't attempt to fill the TLB or go
1610  // any further with the memory access (here we can safely use the
1611  // fault status for the short desc. format in all cases)
1612  stats.prefetchFaults++;
1613  return std::make_shared<PrefetchAbort>(
1614  vaddr_tainted, ArmFault::PrefetchTLBMiss, isStage2);
1615  }
1616 
1617  // start translation table walk, pass variables rather than
1618  // re-retreaving in table walker for speed
1619  DPRINTF(TLB, "TLB Miss: Starting hardware table walker for %#x(%d:%d)\n",
1620  vaddr_tainted, asid, vmid);
1621  Fault fault;
1622  fault = tableWalker->walk(req, tc, asid, vmid, isHyp, mode,
1623  translation, timing, functional, is_secure,
1624  tranType, stage2DescReq);
1625  // for timing mode, return and wait for table walk,
1626  if (timing || fault != NoFault) {
1627  return fault;
1628  }
1629 
1630  *te = lookup(vaddr, asid, vmid, isHyp, is_secure, true, false,
1631  target_el, false, mode);
1632  if (!*te)
1633  printTlb();
1634  assert(*te);
1635  }
1636  return NoFault;
1637 }
1638 
1639 Fault
1642  BaseMMU::Translation *translation, bool timing, bool functional,
1643  TlbEntry *mergeTe)
1644 {
1645  Fault fault;
1646 
1647  if (isStage2) {
1648  // We are already in the stage 2 TLB. Grab the table entry for stage
1649  // 2 only. We are here because stage 1 translation is disabled.
1650  TlbEntry *s2Te = NULL;
1651  // Get the stage 2 table entry
1652  fault = getTE(&s2Te, req, tc, mode, translation, timing, functional,
1653  isSecure, curTranType);
1654  // Check permissions of stage 2
1655  if ((s2Te != NULL) && (fault == NoFault)) {
1656  if (aarch64)
1657  fault = checkPermissions64(s2Te, req, mode, tc);
1658  else
1659  fault = checkPermissions(s2Te, req, mode);
1660  }
1661  *te = s2Te;
1662  return fault;
1663  }
1664 
1665  TlbEntry *s1Te = NULL;
1666 
1667  Addr vaddr_tainted = req->getVaddr();
1668 
1669  // Get the stage 1 table entry
1670  fault = getTE(&s1Te, req, tc, mode, translation, timing, functional,
1671  isSecure, curTranType);
1672  // only proceed if we have a valid table entry
1673  if ((s1Te != NULL) && (fault == NoFault)) {
1674  // Check stage 1 permissions before checking stage 2
1675  if (aarch64)
1676  fault = checkPermissions64(s1Te, req, mode, tc);
1677  else
1678  fault = checkPermissions(s1Te, req, mode);
1679  if (stage2Req & (fault == NoFault)) {
1680  Stage2LookUp *s2Lookup = new Stage2LookUp(this, stage2Tlb, *s1Te,
1681  req, translation, mode, timing, functional, isSecure,
1682  curTranType);
1683  fault = s2Lookup->getTe(tc, mergeTe);
1684  if (s2Lookup->isComplete()) {
1685  *te = mergeTe;
1686  // We've finished with the lookup so delete it
1687  delete s2Lookup;
1688  } else {
1689  // The lookup hasn't completed, so we can't delete it now. We
1690  // get round this by asking the object to self delete when the
1691  // translation is complete.
1692  s2Lookup->setSelfDelete();
1693  }
1694  } else {
1695  // This case deals with an S1 hit (or bypass), followed by
1696  // an S2 hit-but-perms issue
1697  if (isStage2) {
1698  DPRINTF(TLBVerbose, "s2TLB: reqVa %#x, reqPa %#x, fault %p\n",
1699  vaddr_tainted, req->hasPaddr() ? req->getPaddr() : ~0, fault);
1700  if (fault != NoFault) {
1701  ArmFault *armFault = reinterpret_cast<ArmFault *>(fault.get());
1702  armFault->annotate(ArmFault::S1PTW, false);
1703  armFault->annotate(ArmFault::OVA, vaddr_tainted);
1704  }
1705  }
1706  *te = s1Te;
1707  }
1708  }
1709  return fault;
1710 }
1711 
1712 void
1714 {
1715  if (!_ti) {
1716  test = nullptr;
1717  } else {
1718  TlbTestInterface *ti(dynamic_cast<TlbTestInterface *>(_ti));
1719  fatal_if(!ti, "%s is not a valid ARM TLB tester\n", _ti->name());
1720  test = ti;
1721  }
1722 }
1723 
1724 Fault
1727 {
1728  if (!test || !req->hasSize() || req->getSize() == 0 ||
1729  req->isCacheMaintenance()) {
1730  return NoFault;
1731  } else {
1732  return test->translationCheck(req, isPriv, mode, domain);
1733  }
1734 }
1735 
1736 Fault
1738  TlbEntry::DomainType domain, LookupLevel lookup_level)
1739 {
1740  if (!test) {
1741  return NoFault;
1742  } else {
1743  return test->walkCheck(pa, size, va, is_secure, isPriv, mode,
1744  domain, lookup_level);
1745  }
1746 }
1747 
1748 } // namespace gem5
gem5::X86ISA::mask
mask
Definition: misc.hh:802
gem5::ArmISA::MISCREG_CPSR
@ MISCREG_CPSR
Definition: misc.hh:61
gem5::ArmSystem::physAddrRange
uint8_t physAddrRange() const
Returns the supported physical address range in bits.
Definition: system.hh:255
gem5::ArmISA::TLB::tableWalker
TableWalker * tableWalker
Definition: tlb.hh:168
gem5::ArmISA::MISCREG_VTTBR
@ MISCREG_VTTBR
Definition: misc.hh:448
gem5::ArmISA::TLB::finalizePhysical
Fault finalizePhysical(const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode) const override
Do post-translation physical address finalization.
Definition: tlb.cc:137
gem5::ArmISA::TLB::aarch64EL
ExceptionLevel aarch64EL
Definition: tlb.hh:420
gem5::BaseMMU::Read
@ Read
Definition: mmu.hh:53
gem5::ArmISA::TLB::ppRefills
probing::PMUUPtr ppRefills
PMU probe for TLB refills.
Definition: tlb.hh:203
gem5::ArmISA::MISCREG_TTBR0_EL2
@ MISCREG_TTBR0_EL2
Definition: misc.hh:603
gem5::ThreadContext::readMiscReg
virtual RegVal readMiscReg(RegIndex misc_reg)=0
gem5::X86ISA::x
Bitfield< 1 > x
Definition: types.hh:108
gem5::NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:260
gem5::ArmISA::TLB::isStage2
bool isStage2
Definition: tlb.hh:158
gem5::ArmISA::TLBIALLEL
Implementaton of AArch64 TLBI ALLE(1,2,3)(IS) instructions.
Definition: tlbi_op.hh:162
gem5::ArmISA::ELIs64
bool ELIs64(ThreadContext *tc, ExceptionLevel el)
Definition: utility.cc:282
gem5::ArmISA::ArmFault::AddressSizeLL
@ AddressSizeLL
Definition: faults.hh:111
gem5::AddrRange::start
Addr start() const
Get the start address of the range.
Definition: addr_range.hh:317
gem5::ArmISA::TlbEntry::valid
bool valid
Definition: pagetable.hh:131
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::ArmISA::MISCREG_SCTLR_EL3
@ MISCREG_SCTLR_EL3
Definition: misc.hh:591
gem5::RiscvISA::perm
Bitfield< 3, 1 > perm
Definition: pagetable.hh:72
gem5::ArmISA::TLB::aarch64
bool aarch64
Definition: tlb.hh:419
gem5::ArmISA::TLB::stage2DescReq
bool stage2DescReq
Definition: tlb.hh:163
gem5::ArmISA::SelfDebug
Definition: self_debug.hh:277
gem5::ArmISA::MISCREG_TTBR0
@ MISCREG_TTBR0
Definition: misc.hh:254
gem5::ArmISA::TLBIASID
TLB Invalidate by ASID match.
Definition: tlbi_op.hh:216
gem5::ArmISA::TLBIALL
TLB Invalidate All.
Definition: tlbi_op.hh:106
gem5::ArmISA::TLB::translateSe
Fault translateSe(const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode, BaseMMU::Translation *translation, bool &delay, bool timing)
Definition: tlb.cc:541
gem5::ArmISA::TLB::isSecure
bool isSecure
Definition: tlb.hh:424
gem5::ArmISA::TLB::stage2Req
bool stage2Req
Definition: tlb.hh:159
gem5::ArmISA::el
Bitfield< 3, 2 > el
Definition: misc_types.hh:72
gem5::ArmISA::MISCREG_CONTEXTIDR
@ MISCREG_CONTEXTIDR
Definition: misc.hh:399
gem5::ArmISA::TlbEntry::ns
bool ns
Definition: pagetable.hh:134
gem5::ArmISA::TLB::table
TlbEntry * table
Definition: tlb.hh:156
gem5::ArmISA::TLBIMVA::asid
uint16_t asid
Definition: tlbi_op.hh:308
gem5::ArmISA::MISCREG_TCR_EL2
@ MISCREG_TCR_EL2
Definition: misc.hh:604
gem5::ArmSystem::haveLPAE
bool haveLPAE() const
Returns true if this system implements the Large Physical Address Extension.
Definition: system.hh:166
gem5::ArmISA::aarch64
Bitfield< 34 > aarch64
Definition: types.hh:81
gem5::ArmISA::TLB::size
int size
Definition: tlb.hh:157
gem5::ArmISA::TLB::translateFs
Fault translateFs(const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode, BaseMMU::Translation *translation, bool &delay, bool timing, ArmTranslationType tranType, bool functional=false)
Definition: tlb.cc:1174
test
Definition: test.h:38
gem5::X86ISA::TLB::translateTiming
void translateTiming(const RequestPtr &req, ThreadContext *tc, BaseMMU::Translation *translation, BaseMMU::Mode mode) override
Definition: tlb.cc:508
gem5::ArmISA::TLB::TlbStats::readHits
statistics::Scalar readHits
Definition: tlb.hh:179
pseudo_inst.hh
gem5::BaseMMU::Mode
Mode
Definition: mmu.hh:53
gem5::Request::UNCACHEABLE
@ UNCACHEABLE
The request is to an uncacheable address.
Definition: request.hh:125
gem5::ArmISA::ArmFault::PrefetchUncacheable
@ PrefetchUncacheable
Definition: faults.hh:117
gem5::ArmISA::asid
asid
Definition: misc_types.hh:617
gem5::BaseMMU::Write
@ Write
Definition: mmu.hh:53
gem5::ArmISA::MISCREG_SCR_EL3
@ MISCREG_SCR_EL3
Definition: misc.hh:593
gem5::ArmISA::domain
Bitfield< 7, 4 > domain
Definition: misc_types.hh:423
gem5::AddrRange::contains
bool contains(const Addr &a) const
Determine if the range contains an address.
Definition: addr_range.hh:438
gem5::ArmISA::TlbEntry::outerAttrs
uint8_t outerAttrs
Definition: pagetable.hh:119
gem5::ArmISA::TlbEntry::pfn
Addr pfn
Definition: pagetable.hh:105
gem5::ArmISA::f
Bitfield< 6 > f
Definition: misc_types.hh:67
pagetable.hh
gem5::ArmISA::TLB::TLB
TLB(const Params &p)
Definition: tlb.cc:79
gem5::ArmISA::ArmFault::LpaeTran
@ LpaeTran
Definition: faults.hh:152
gem5::Request::CACHE_BLOCK_ZERO
@ CACHE_BLOCK_ZERO
This is a write that is targeted and zeroing an entire cache block.
Definition: request.hh:143
gem5::ArmISA::ArmFault::PrefetchTLBMiss
@ PrefetchTLBMiss
Definition: faults.hh:116
gem5::X86ISA::TLB::translateAtomic
Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode) override
Definition: tlb.cc:465
gem5::ArmISA::MISCREG_TTBR1_EL1
@ MISCREG_TTBR1_EL1
Definition: misc.hh:599
gem5::ArmISA::MISCREG_TTBCR
@ MISCREG_TTBCR
Definition: misc.hh:260
gem5::ArmISA::vmid_t
uint16_t vmid_t
Definition: types.hh:57
gem5::BaseMMU::Translation::markDelayed
virtual void markDelayed()=0
Signal that the translation has been delayed due to a hw page table walk.
gem5::ArmISA::MISCREG_HSCTLR
@ MISCREG_HSCTLR
Definition: misc.hh:246
gem5::ArmISA::currEL
static ExceptionLevel currEL(const ThreadContext *tc)
Definition: utility.hh:119
gem5::ArmSystem::haveLargeAsid64
bool haveLargeAsid64() const
Returns true if ASID is 16 bits in AArch64 (ARMv8)
Definition: system.hh:224
GEM5_FALLTHROUGH
#define GEM5_FALLTHROUGH
Definition: compiler.hh:61
gem5::ArmISA::LookupLevel
LookupLevel
Definition: pagetable.hh:76
gem5::ArmISA::e
Bitfield< 9 > e
Definition: misc_types.hh:64
gem5::ArmISA::TlbEntry::isHyp
bool isHyp
Definition: pagetable.hh:129
gem5::ArmISA::TLB
Definition: tlb.hh:109
gem5::ArmISA::TLB::checkPermissions
Fault checkPermissions(TlbEntry *te, const RequestPtr &req, BaseMMU::Mode mode)
Definition: tlb.cc:581
gem5::ArmISA::MISCREG_TCR_EL3
@ MISCREG_TCR_EL3
Definition: misc.hh:610
gem5::ArmISA::ArmFault::DomainLL
@ DomainLL
Definition: faults.hh:103
gem5::ThreadContext::contextId
virtual ContextID contextId() const =0
gem5::ArmISA::ns
Bitfield< 0 > ns
Definition: misc_types.hh:331
gem5::ArmISA::EL1
@ EL1
Definition: types.hh:267
gem5::ArmISA::TlbEntry::setAttributes
void setAttributes(bool lpae)
Definition: pagetable.hh:291
tlb.hh
gem5::ArmISA::inAArch64
bool inAArch64(ThreadContext *tc)
Definition: utility.cc:120
system.hh
gem5::ArmISA::TLB::lookup
TlbEntry * lookup(Addr vpn, uint16_t asn, vmid_t vmid, bool hyp, bool secure, bool functional, bool ignore_asn, ExceptionLevel target_el, bool in_host, BaseMMU::Mode mode)
Lookup an entry in the TLB.
Definition: tlb.cc:166
gem5::ArmISA::MISCREG_SCTLR
@ MISCREG_SCTLR
Definition: misc.hh:235
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:66
table_walker.hh
gem5::ArmISA::TLBIALL::inHost
bool inHost
Definition: tlbi_op.hh:130
gem5::ArmISA::TlbTestInterface
Definition: tlb.hh:73
request.hh
gem5::ArmISA::TlbEntry
Definition: pagetable.hh:86
gem5::ArmISA::TLBIOp::secureLookup
bool secureLookup
Definition: tlbi_op.hh:101
gem5::ArmISA::ArmFault::PermissionLL
@ PermissionLL
Definition: faults.hh:104
gem5::ArmISA::TlbEntry::DomainType
DomainType
Definition: pagetable.hh:96
gem5::ArmISA::MISCREG_VTCR_EL2
@ MISCREG_VTCR_EL2
Definition: misc.hh:606
gem5::X86ISA::TLB::translateFunctional
Fault translateFunctional(const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode) override
Definition: tlb.cc:473
gem5::BaseMMU::Execute
@ Execute
Definition: mmu.hh:53
gem5::ArmISA::TlbEntry::size
Addr size
Definition: pagetable.hh:106
gem5::ArmISA::TLBIASID::asid
uint16_t asid
Definition: tlbi_op.hh:226
gem5::ArmISA::ArmFault::VmsaTran
@ VmsaTran
Definition: faults.hh:153
gem5::ArmISA::MISCREG_DACR
@ MISCREG_DACR
Definition: misc.hh:265
gem5::Cycles
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:78
str.hh
gem5::ArmISA::TLB::stage2Tlb
TLB * stage2Tlb
Definition: tlb.hh:169
gem5::ArmISA::purifyTaggedAddr
Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, TCR tcr, bool isInstr)
Removes the tag from tagged addresses if that mode is enabled.
Definition: utility.cc:463
gem5::X86ISA::TLB::finalizePhysical
Fault finalizePhysical(const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode) const override
Do post-translation physical address finalization.
Definition: tlb.cc:261
gem5::ArmISA::TLBIALLN
TLB Invalidate All, Non-Secure.
Definition: tlbi_op.hh:258
gem5::ArmISA::TLBIASID::el2Enabled
bool el2Enabled
Definition: tlbi_op.hh:228
gem5::ArmISA::pa
Bitfield< 39, 12 > pa
Definition: misc_types.hh:656
gem5::ArmISA::TLB::TlbStats::instHits
statistics::Scalar instHits
Definition: tlb.hh:177
gem5::ArmISA::TLB::printTlb
void printTlb() const
Definition: tlb.cc:260
gem5::Flags< FlagsType >
gem5::X86ISA::r
Bitfield< 41 > r
Definition: misc.hh:940
gem5::ArmISA::TLB::getResultTe
Fault getResultTe(TlbEntry **te, const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode, BaseMMU::Translation *translation, bool timing, bool functional, TlbEntry *mergeTe)
Definition: tlb.cc:1640
gem5::ArmISA::MISCREG_PRRR
@ MISCREG_PRRR
Definition: misc.hh:369
gem5::ArmISA::TLB::TlbStats::writeHits
statistics::Scalar writeHits
Definition: tlb.hh:181
gem5::ArmISA::TlbEntry::shareable
bool shareable
Definition: pagetable.hh:144
gem5::ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:93
gem5::Request::SECURE
@ SECURE
The request targets the secure memory space.
Definition: request.hh:184
gem5::ArmISA::MODE_HYP
@ MODE_HYP
Definition: types.hh:287
gem5::ArmISA::MISCREG_SCTLR_EL1
@ MISCREG_SCTLR_EL1
Definition: misc.hh:579
gem5::ArmISA::TLB::takeOverFrom
void takeOverFrom(BaseTLB *otlb) override
Take over from an old tlb context.
Definition: tlb.cc:466
gem5::Named::name
virtual std::string name() const
Definition: named.hh:47
gem5::ArmISA::TLB::translateFunctional
bool translateFunctional(ThreadContext *tc, Addr vaddr, Addr &paddr)
Do a functional lookup on the TLB (for debugging) and don't modify any internal state.
Definition: tlb.cc:119
gem5::Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:255
gem5::ArmISA::HaveVirtHostExt
bool HaveVirtHostExt(ThreadContext *tc)
Definition: utility.cc:224
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
gem5::Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:283
gem5::ArmISA::TLB::TlbStats::readMisses
statistics::Scalar readMisses
Definition: tlb.hh:180
gem5::ArmISA::TLB::stats
gem5::ArmISA::TLB::TlbStats stats
gem5::ArmISA::TlbEntry::mtype
MemoryType mtype
Definition: pagetable.hh:124
gem5::ArmISA::TlbEntry::domain
DomainType domain
Definition: pagetable.hh:122
gem5::ArmISA::EL2
@ EL2
Definition: types.hh:268
gem5::ArmISA::TLBIMVAA
TLB Invalidate by VA, All ASID.
Definition: tlbi_op.hh:281
gem5::ArmISA::MISCREG_SCTLR_EL2
@ MISCREG_SCTLR_EL2
Definition: misc.hh:584
gem5::MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
gem5::ArmISA::wxn
Bitfield< 19 > wxn
Definition: misc_types.hh:359
gem5::ArmISA::TLB::flush
void flush(const TLBIALL &tlbi_op)
Reset the entire TLB.
Definition: tlb.cc:292
isa.hh
gem5::ArmISA::TableWalker::setTlb
void setTlb(TLB *_tlb)
Definition: table_walker.hh:1039
gem5::ArmISA::computeAddrTop
int computeAddrTop(ThreadContext *tc, bool selbit, bool isInstr, TCR tcr, ExceptionLevel el)
Definition: utility.cc:418
gem5::ArmISA::TlbEntry::el
ExceptionLevel el
Definition: pagetable.hh:138
gem5::X86ISA::type
type
Definition: misc.hh:733
gem5::RequestPtr
std::shared_ptr< Request > RequestPtr
Definition: request.hh:92
gem5::MipsISA::pfn
Bitfield< 29, 6 > pfn
Definition: pra_constants.hh:58
gem5::ArmISA::TLB::physAddrRange
uint8_t physAddrRange
Definition: tlb.hh:441
process.hh
gem5::BaseTLB
Definition: tlb.hh:54
stage2_lookup.hh
gem5::ArmISA::TLB::miscRegValid
bool miscRegValid
Definition: tlb.hh:433
gem5::ArmISA::TlbEntry::N
uint8_t N
Definition: pagetable.hh:117
reg_abi.hh
gem5::ArmISA::TLB::testTranslation
Fault testTranslation(const RequestPtr &req, BaseMMU::Mode mode, TlbEntry::DomainType domain)
Definition: tlb.cc:1725
tlbi_op.hh
gem5::ArmISA::te
Bitfield< 30 > te
Definition: misc_types.hh:337
gem5::X86ISA::TLB::stats
gem5::X86ISA::TLB::TlbStats stats
gem5::ArmISA::TLBIALL::el2Enabled
bool el2Enabled
Definition: tlbi_op.hh:131
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
compiler.hh
gem5::ArmISA::TLBIASID::inHost
bool inHost
Definition: tlbi_op.hh:227
gem5::ArmISA::TLB::TlbStats::flushTlbMva
statistics::Scalar flushTlbMva
Definition: tlb.hh:185
gem5::ArmISA::EL3
@ EL3
Definition: types.hh:269
inifile.hh
gem5::SimObject
Abstract superclass for simulation objects.
Definition: sim_object.hh:146
gem5::X86ISA::ti
Bitfield< 2 > ti
Definition: misc.hh:867
gem5::ArmISA::MODE_USER
@ MODE_USER
Definition: types.hh:281
gem5::ArmISA::TLB::isHyp
bool isHyp
Definition: tlb.hh:425
faults.hh
gem5::pseudo_inst::decodeAddrOffset
static void decodeAddrOffset(Addr offset, uint8_t &func)
Definition: pseudo_inst.hh:63
gem5::ArmISA::MISCREG_ID_AA64MMFR1_EL1
@ MISCREG_ID_AA64MMFR1_EL1
Definition: misc.hh:570
gem5::ArmISA::Stage2LookUp
Definition: stage2_lookup.hh:59
gem5::ArmISA::TLBIVMALL::el2Enabled
bool el2Enabled
Definition: tlbi_op.hh:211
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::ArmISA::TLB::haveLargeAsid64
bool haveLargeAsid64
Definition: tlb.hh:440
gem5::X86ISA::w
Bitfield< 1 > w
Definition: pagetable.hh:150
gem5::ArmISA::TLB::flushAll
void flushAll() override
Reset the entire TLB.
Definition: tlb.cc:274
gem5::X86ISA::TLB::lookup
TlbEntry * lookup(Addr va, bool update_lru=true)
Definition: tlb.cc:124
gem5::ArmISA::TlbEntry::global
bool global
Definition: pagetable.hh:130
gem5::ArmISA::TlbEntry::vpn
Addr vpn
Definition: pagetable.hh:107
gem5::ArmISA::MISCREG_NMRR
@ MISCREG_NMRR
Definition: misc.hh:375
gem5::ArmISA::TLB::testWalk
Fault testWalk(Addr pa, Addr size, Addr va, bool is_secure, BaseMMU::Mode mode, TlbEntry::DomainType domain, LookupLevel lookup_level)
Definition: tlb.cc:1737
gem5::ArmISA::TLBIMVAA::inHost
bool inHost
Definition: tlbi_op.hh:292
gem5::ArmISA::TLB::tranTypeEL
static ExceptionLevel tranTypeEL(CPSR cpsr, ArmTranslationType type)
Determine the EL to use for the purpose of a translation given a specific translation type.
Definition: tlb.cc:1557
gem5::ArmISA::MISCREG_TTBR1
@ MISCREG_TTBR1
Definition: misc.hh:257
gem5::ArmISA::isSecure
bool isSecure(ThreadContext *tc)
Definition: utility.cc:72
gem5::ArmISA::TLB::TlbStats::flushTlb
statistics::Scalar flushTlb
Definition: tlb.hh:184
packet_access.hh
gem5::ArmISA::va
Bitfield< 8 > va
Definition: misc_types.hh:275
utility.hh
gem5::ArmISA::TLB::TlbStats::TlbStats
TlbStats(statistics::Group *parent)
full_system.hh
gem5::ArmISA::TLB::checkPermissions64
Fault checkPermissions64(TlbEntry *te, const RequestPtr &req, BaseMMU::Mode mode, ThreadContext *tc)
Definition: tlb.cc:759
gem5::ArmISA::TlbEntry::outerShareable
bool outerShareable
Definition: pagetable.hh:145
gem5::ArmISA::TLB::TlbStats::flushTlbAsid
statistics::Scalar flushTlbAsid
Definition: tlb.hh:187
gem5::ArmISA::ArmFault
Definition: faults.hh:64
gem5::ArmISA::TLB::TlbStats::writeMisses
statistics::Scalar writeMisses
Definition: tlb.hh:182
gem5::ProbePointArg
ProbePointArg generates a point for the class of Arg.
Definition: thermal_domain.hh:54
gem5::Process
Definition: process.hh:67
gem5::ArmISA::TLBIMVA::inHost
bool inHost
Definition: tlbi_op.hh:309
gem5::ThreadContext::getProcessPtr
virtual Process * getProcessPtr()=0
gem5::FullSystem
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:223
gem5::ArmISA::TLBIALLEL::inHost
bool inHost
Definition: tlbi_op.hh:184
gem5::ArmISA::TlbEntry::attributes
uint64_t attributes
Definition: pagetable.hh:108
gem5::ArmISA::TLBIMVA::addr
Addr addr
Definition: tlbi_op.hh:307
gem5::BaseMMU::Translation
Definition: mmu.hh:55
gem5::SimObject::getProbeManager
ProbeManager * getProbeManager()
Get the probe manager for this object.
Definition: sim_object.cc:120
gem5::ArmISA::IsSecureEL2Enabled
bool IsSecureEL2Enabled(ThreadContext *tc)
Definition: utility.cc:260
gem5::ArmISA::TlbEntry::vmid
vmid_t vmid
Definition: pagetable.hh:116
gem5::ArmISA::TLB::TlbStats::instMisses
statistics::Scalar instMisses
Definition: tlb.hh:178
gem5::ArmISA::EL0
@ EL0
Definition: types.hh:266
gem5::ArmISA::Stage2LookUp::getTe
Fault getTe(ThreadContext *tc, TlbEntry *destTe)
Definition: stage2_lookup.cc:57
gem5::ArmSystem
Definition: system.hh:62
gem5::ArmISA::TableWalker
Definition: table_walker.hh:66
gem5::ArmISA::ArmFault::TranMethod
TranMethod
Definition: faults.hh:150
gem5::ArmISA::MISCREG_HCR
@ MISCREG_HCR
Definition: misc.hh:248
gem5::RiscvISA::x
Bitfield< 3 > x
Definition: pagetable.hh:73
gem5::ArmISA::TlbEntry::asid
uint16_t asid
Definition: pagetable.hh:115
gem5::ArmISA::TLBIMVAA::addr
Addr addr
Definition: tlbi_op.hh:291
gem5::X86ISA::vm
Bitfield< 17 > vm
Definition: misc.hh:568
gem5::ArmISA::ArmFault::AlignmentFault
@ AlignmentFault
Definition: faults.hh:97
gem5::ArmISA::TLB::updateMiscReg
void updateMiscReg(ThreadContext *tc, ArmTranslationType tranType=NormalTran)
Definition: tlb.cc:1381
gem5::ArmISA::TLB::_attr
uint64_t _attr
Definition: tlb.hh:164
gem5::ArmISA::TLB::vmid
vmid_t vmid
Definition: tlb.hh:428
base.hh
gem5::Port
Ports are used to interface objects to each other.
Definition: port.hh:61
gem5::ArmISA::TlbEntry::xn
bool xn
Definition: pagetable.hh:148
gem5::ArmISA::MISCREG_VTTBR_EL2
@ MISCREG_VTTBR_EL2
Definition: misc.hh:605
gem5::ArmISA::TLB::haveLPAE
bool haveLPAE
Definition: tlb.hh:438
gem5::ArmISA::TLB::setTableWalker
void setTableWalker(TableWalker *table_walker)
Definition: tlb.cc:112
gem5::ArmISA::TLBIMVA
TLB Invalidate by VA.
Definition: tlbi_op.hh:296
gem5::ArmISA::Stage2LookUp::isComplete
bool isComplete() const
Definition: stage2_lookup.hh:98
gem5::ArmISA::TLBIOp::targetEL
ExceptionLevel targetEL
Definition: tlbi_op.hh:102
gem5::ArmISA::ISA::getSelfDebug
SelfDebug * getSelfDebug() const
Definition: isa.hh:524
gem5::ArmISA::TLBIVMALL
Implementaton of AArch64 TLBI VMALLE1(IS)/VMALLS112E1(IS) instructions.
Definition: tlbi_op.hh:188
gem5::ArmISA::MISCREG_SCR
@ MISCREG_SCR
Definition: misc.hh:243
gem5::ArmISA::TlbEntry::nstid
bool nstid
Definition: pagetable.hh:136
gem5::X86ISA::TLB::getTableWalkerPort
Port * getTableWalkerPort() override
Get the table walker port.
Definition: tlb.cc:578
gem5::ArmISA::longDescFormatInUse
bool longDescFormatInUse(ThreadContext *tc)
Definition: utility.cc:127
gem5::ArmISA::TLBIVMALL::inHost
bool inHost
Definition: tlbi_op.hh:210
gem5::ArmISA::ArmFault::annotate
virtual void annotate(AnnotationIDs id, uint64_t val)
Definition: faults.hh:237
gem5::ArmISA::TLB::haveVirtualization
bool haveVirtualization
Definition: tlb.hh:439
gem5::statistics::Group
Statistics container.
Definition: group.hh:93
gem5::ArmISA::TLB::insert
void insert(Addr vaddr, TlbEntry &pte)
Definition: tlb.cc:230
gem5::ArmISA::TLB::directToStage2
bool directToStage2
Definition: tlb.hh:165
gem5::X86ISA::p
Bitfield< 0 > p
Definition: pagetable.hh:151
gem5::ArmISA::TLB::ArmTranslationType
ArmTranslationType
Definition: tlb.hh:128
gem5::ArmISA::TLB::TlbStats::inserts
statistics::Scalar inserts
Definition: tlb.hh:183
gem5::ArmISA::ArmFault::S1PTW
@ S1PTW
Definition: faults.hh:134
gem5::ArmISA::sd
Bitfield< 4 > sd
Definition: misc_types.hh:774
gem5::ArmISA::snsBankedIndex
int snsBankedIndex(MiscRegIndex reg, ThreadContext *tc)
Definition: misc.cc:1313
gem5::ArmISA::TLB::TlbStats::flushedEntries
statistics::Scalar flushedEntries
Definition: tlb.hh:188
gem5::ArmISA::TLB::getVMID
vmid_t getVMID(ThreadContext *tc) const
Returns the current VMID (information stored in the VTTBR_EL2 register)
Definition: tlb.cc:1352
gem5::ArmISA::Stage2LookUp::setSelfDelete
void setSelfDelete()
Definition: stage2_lookup.hh:96
gem5::ArmISA::TLB::drainResume
void drainResume() override
Resume execution after a successful drain.
Definition: tlb.cc:458
trace.hh
gem5::Packet::setLE
void setLE(T v)
Set the value in the data pointer to v as little endian.
Definition: packet_access.hh:108
gem5::SimObject::regProbePoints
virtual void regProbePoints()
Register probe points for this object.
Definition: sim_object.cc:107
gem5::MipsISA::vaddr
vaddr
Definition: pra_constants.hh:278
gem5::ArmISA::TLB::m5opRange
AddrRange m5opRange
Definition: tlb.hh:443
self_debug.hh
gem5::ArmISA::TLB::~TLB
virtual ~TLB()
Definition: tlb.cc:106
gem5::ArmSystem::haveEL
static bool haveEL(ThreadContext *tc, ArmISA::ExceptionLevel el)
Return true if the system implements a specific exception level.
Definition: system.cc:138
gem5::ArmISA::MISCREG_HCR_EL2
@ MISCREG_HCR_EL2
Definition: misc.hh:586
gem5::ArmISA::MISCREG_TTBR0_EL1
@ MISCREG_TTBR0_EL1
Definition: misc.hh:597
gem5::ArmISA::TLB::translateMmuOff
Fault translateMmuOff(ThreadContext *tc, const RequestPtr &req, BaseMMU::Mode mode, TLB::ArmTranslationType tranType, Addr vaddr, bool long_desc_format)
Definition: tlb.cc:1028
gem5::ArmISA::TlbEntry::nonCacheable
bool nonCacheable
Definition: pagetable.hh:141
fatal_if
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:225
page_table.hh
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::ArmISA::TlbEntry::pAddr
Addr pAddr(Addr va) const
Definition: pagetable.hh:243
gem5::X86ISA::TLB::size
uint32_t size
Definition: tlb.hh:96
gem5::BaseMMU::Translation::finish
virtual void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode)=0
gem5::ArmISA::TLB::setTestInterface
void setTestInterface(SimObject *ti)
Definition: tlb.cc:1713
gem5::ArmISA::TLB::translateComplete
Fault translateComplete(const RequestPtr &req, ThreadContext *tc, BaseMMU::Translation *translation, BaseMMU::Mode mode, ArmTranslationType tranType, bool callFromS2)
Definition: tlb.cc:1316
gem5::ArmISA::TLB::asid
uint16_t asid
Definition: tlb.hh:427
thread_context.hh
gem5::ArmISA::TLB::rangeMRU
int rangeMRU
Definition: tlb.hh:205
gem5::ArmISA::ArmFault::OVA
@ OVA
Definition: faults.hh:135
gem5::ArmISA::TLB::TlbStats::flushTlbMvaAsid
statistics::Scalar flushTlbMvaAsid
Definition: tlb.hh:186
gem5::ArmISA::MISCREG_TTBR1_EL2
@ MISCREG_TTBR1_EL2
Definition: misc.hh:820
gem5::ArmISA::TLB::translateMmuOn
Fault translateMmuOn(ThreadContext *tc, const RequestPtr &req, BaseMMU::Mode mode, BaseMMU::Translation *translation, bool &delay, bool timing, bool functional, Addr vaddr, ArmFault::TranMethod tranMethod)
Definition: tlb.cc:1101
gem5::ArmSystem::haveVirtualization
bool haveVirtualization() const
Returns true if this system implements the virtualization Extensions.
Definition: system.hh:171
gem5::ArmISA::TLB::_flushMva
void _flushMva(Addr mva, uint64_t asn, bool secure_lookup, bool ignore_asn, ExceptionLevel target_el, bool in_host)
Remove any entries that match both a va and asn.
Definition: tlb.cc:435
gem5::ArmISA::TlbEntry::innerAttrs
uint8_t innerAttrs
Definition: pagetable.hh:118
gem5::ArmISA::TlbEntry::ap
uint8_t ap
Definition: pagetable.hh:120
gem5::ArmISA::dc
Bitfield< 12 > dc
Definition: misc_types.hh:272
gem5::ArmISA::TLB::checkPAN
bool checkPAN(ThreadContext *tc, uint8_t ap, const RequestPtr &req, BaseMMU::Mode mode, const bool is_priv)
Definition: tlb.cc:1000
gem5::ArmISA::MISCREG_TCR_EL1
@ MISCREG_TCR_EL1
Definition: misc.hh:601
gem5::ArmISA::ExceptionLevel
ExceptionLevel
Definition: types.hh:264
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:177
gem5::ArmISA::mode
Bitfield< 4, 0 > mode
Definition: misc_types.hh:73
gem5::X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:84
gem5::ArmISA::TLB::getTE
Fault getTE(TlbEntry **te, const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode, BaseMMU::Translation *translation, bool timing, bool functional, bool is_secure, ArmTranslationType tranType)
Definition: tlb.cc:1586

Generated on Tue Sep 21 2021 12:24:26 for gem5 by doxygen 1.8.17