gem5  v20.1.0.0
table_walker.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, 2012-2019 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  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 #include "arch/arm/table_walker.hh"
38 
39 #include <memory>
40 
41 #include "arch/arm/faults.hh"
42 #include "arch/arm/stage2_mmu.hh"
43 #include "arch/arm/system.hh"
44 #include "arch/arm/tlb.hh"
45 #include "cpu/base.hh"
46 #include "cpu/thread_context.hh"
47 #include "debug/Checkpoint.hh"
48 #include "debug/Drain.hh"
49 #include "debug/TLB.hh"
50 #include "debug/TLBVerbose.hh"
51 #include "dev/dma_device.hh"
52 #include "sim/system.hh"
53 
54 using namespace ArmISA;
55 
57  : ClockedObject(p),
58  stage2Mmu(NULL), port(NULL), requestorId(Request::invldRequestorId),
59  isStage2(p->is_stage2), tlb(NULL),
60  currState(NULL), pending(false),
61  numSquashable(p->num_squash_per_cycle),
62  stats(this),
63  pendingReqs(0),
64  pendingChangeTick(curTick()),
65  doL1DescEvent([this]{ doL1DescriptorWrapper(); }, name()),
66  doL2DescEvent([this]{ doL2DescriptorWrapper(); }, name()),
67  doL0LongDescEvent([this]{ doL0LongDescriptorWrapper(); }, name()),
68  doL1LongDescEvent([this]{ doL1LongDescriptorWrapper(); }, name()),
69  doL2LongDescEvent([this]{ doL2LongDescriptorWrapper(); }, name()),
70  doL3LongDescEvent([this]{ doL3LongDescriptorWrapper(); }, name()),
71  LongDescEventByLevel { &doL0LongDescEvent, &doL1LongDescEvent,
72  &doL2LongDescEvent, &doL3LongDescEvent },
73  doProcessEvent([this]{ processWalkWrapper(); }, name())
74 {
75  sctlr = 0;
76 
77  // Cache system-level properties
78  if (FullSystem) {
79  ArmSystem *armSys = dynamic_cast<ArmSystem *>(p->sys);
80  assert(armSys);
81  haveSecurity = armSys->haveSecurity();
82  _haveLPAE = armSys->haveLPAE();
83  _haveVirtualization = armSys->haveVirtualization();
84  physAddrRange = armSys->physAddrRange();
85  _haveLargeAsid64 = armSys->haveLargeAsid64();
86  } else {
87  haveSecurity = _haveLPAE = _haveVirtualization = false;
88  _haveLargeAsid64 = false;
89  physAddrRange = 32;
90  }
91 
92 }
93 
95 {
96  ;
97 }
98 
99 void
101 {
102  stage2Mmu = m;
103  port = &m->getDMAPort();
104  requestorId = requestor_id;
105 }
106 
107 void
109 {
110  fatal_if(!stage2Mmu, "Table walker must have a valid stage-2 MMU\n");
111  fatal_if(!port, "Table walker must have a valid port\n");
112  fatal_if(!tlb, "Table walker must have a valid TLB\n");
113 }
114 
115 Port &
116 TableWalker::getPort(const std::string &if_name, PortID idx)
117 {
118  if (if_name == "port") {
119  if (!isStage2) {
120  return *port;
121  } else {
122  fatal("Cannot access table walker port through stage-two walker\n");
123  }
124  }
125  return ClockedObject::getPort(if_name, idx);
126 }
127 
129  tc(nullptr), aarch64(false), el(EL0), physAddrRange(0), req(nullptr),
130  asid(0), vmid(0), isHyp(false), transState(nullptr),
131  vaddr(0), vaddr_tainted(0),
132  sctlr(0), scr(0), cpsr(0), tcr(0),
133  htcr(0), hcr(0), vtcr(0),
134  isWrite(false), isFetch(false), isSecure(false),
135  isUncacheable(false),
136  secureLookup(false), rwTable(false), userTable(false), xnTable(false),
137  pxnTable(false), hpd(false), stage2Req(false),
138  stage2Tran(nullptr), timing(false), functional(false),
139  mode(BaseTLB::Read), tranType(TLB::NormalTran), l2Desc(l1Desc),
140  delayed(false), tableWalker(nullptr)
141 {
142 }
143 
144 void
146 {
147  if (drainState() == DrainState::Draining &&
148  stateQueues[L0].empty() && stateQueues[L1].empty() &&
149  stateQueues[L2].empty() && stateQueues[L3].empty() &&
150  pendingQueue.empty()) {
151 
152  DPRINTF(Drain, "TableWalker done draining, processing drain event\n");
153  signalDrainDone();
154  }
155 }
156 
159 {
160  bool state_queues_not_empty = false;
161 
162  for (int i = 0; i < MAX_LOOKUP_LEVELS; ++i) {
163  if (!stateQueues[i].empty()) {
164  state_queues_not_empty = true;
165  break;
166  }
167  }
168 
169  if (state_queues_not_empty || pendingQueue.size()) {
170  DPRINTF(Drain, "TableWalker not drained\n");
171  return DrainState::Draining;
172  } else {
173  DPRINTF(Drain, "TableWalker free, no need to drain\n");
174  return DrainState::Drained;
175  }
176 }
177 
178 void
180 {
181  if (params()->sys->isTimingMode() && currState) {
182  delete currState;
183  currState = NULL;
184  pendingChange();
185  }
186 }
187 
188 Fault
189 TableWalker::walk(const RequestPtr &_req, ThreadContext *_tc, uint16_t _asid,
190  uint8_t _vmid, bool _isHyp, TLB::Mode _mode,
191  TLB::Translation *_trans, bool _timing, bool _functional,
192  bool secure, TLB::ArmTranslationType tranType,
193  bool _stage2Req)
194 {
195  assert(!(_functional && _timing));
196  ++stats.walks;
197 
198  WalkerState *savedCurrState = NULL;
199 
200  if (!currState && !_functional) {
201  // For atomic mode, a new WalkerState instance should be only created
202  // once per TLB. For timing mode, a new instance is generated for every
203  // TLB miss.
204  DPRINTF(TLBVerbose, "creating new instance of WalkerState\n");
205 
206  currState = new WalkerState();
207  currState->tableWalker = this;
208  } else if (_functional) {
209  // If we are mixing functional mode with timing (or even
210  // atomic), we need to to be careful and clean up after
211  // ourselves to not risk getting into an inconsistent state.
212  DPRINTF(TLBVerbose, "creating functional instance of WalkerState\n");
213  savedCurrState = currState;
214  currState = new WalkerState();
215  currState->tableWalker = this;
216  } else if (_timing) {
217  // This is a translation that was completed and then faulted again
218  // because some underlying parameters that affect the translation
219  // changed out from under us (e.g. asid). It will either be a
220  // misprediction, in which case nothing will happen or we'll use
221  // this fault to re-execute the faulting instruction which should clean
222  // up everything.
223  if (currState->vaddr_tainted == _req->getVaddr()) {
225  return std::make_shared<ReExec>();
226  }
227  }
228  pendingChange();
229 
231  currState->tc = _tc;
232  // ARM DDI 0487A.f (ARMv8 ARM) pg J8-5672
233  // aarch32/translation/translation/AArch32.TranslateAddress dictates
234  // even AArch32 EL0 will use AArch64 translation if EL1 is in AArch64.
235  if (isStage2) {
236  currState->el = EL1;
237  currState->aarch64 = ELIs64(_tc, EL2);
238  } else {
239  currState->el =
240  TLB::tranTypeEL(_tc->readMiscReg(MISCREG_CPSR), tranType);
241  currState->aarch64 =
242  ELIs64(_tc, currState->el == EL0 ? EL1 : currState->el);
243  }
244  currState->transState = _trans;
245  currState->req = _req;
247  currState->asid = _asid;
248  currState->vmid = _vmid;
249  currState->isHyp = _isHyp;
250  currState->timing = _timing;
251  currState->functional = _functional;
252  currState->mode = _mode;
253  currState->tranType = tranType;
254  currState->isSecure = secure;
256 
259  currState->vaddr_tainted = currState->req->getVaddr();
260  if (currState->aarch64)
264  else
266 
267  if (currState->aarch64) {
269  if (isStage2) {
271  if (currState->secureLookup) {
272  currState->vtcr =
274  } else {
275  currState->vtcr =
277  }
278  } else switch (currState->el) {
279  case EL0:
280  if (HaveVirtHostExt(currState->tc) &&
281  currState->hcr.tge == 1 && currState->hcr.e2h ==1) {
284  } else {
287  }
288  break;
289  case EL1:
292  break;
293  case EL2:
294  assert(_haveVirtualization);
297  break;
298  case EL3:
299  assert(haveSecurity);
302  break;
303  default:
304  panic("Invalid exception level");
305  break;
306  }
307  } else {
315  }
316  sctlr = currState->sctlr;
317 
320 
322 
323  currState->stage2Req = _stage2Req && !isStage2;
324 
325  bool long_desc_format = currState->aarch64 || _isHyp || isStage2 ||
327 
328  if (long_desc_format) {
329  // Helper variables used for hierarchical permissions
331  currState->rwTable = true;
332  currState->userTable = true;
333  currState->xnTable = false;
334  currState->pxnTable = false;
335 
337  } else {
339  }
340 
341  if (!currState->timing) {
342  Fault fault = NoFault;
343  if (currState->aarch64)
344  fault = processWalkAArch64();
345  else if (long_desc_format)
346  fault = processWalkLPAE();
347  else
348  fault = processWalk();
349 
350  // If this was a functional non-timing access restore state to
351  // how we found it.
352  if (currState->functional) {
353  delete currState;
354  currState = savedCurrState;
355  }
356  return fault;
357  }
358 
359  if (pending || pendingQueue.size()) {
360  pendingQueue.push_back(currState);
361  currState = NULL;
362  pendingChange();
363  } else {
364  pending = true;
365  pendingChange();
366  if (currState->aarch64)
367  return processWalkAArch64();
368  else if (long_desc_format)
369  return processWalkLPAE();
370  else
371  return processWalk();
372  }
373 
374  return NoFault;
375 }
376 
377 void
379 {
380  assert(!currState);
381  assert(pendingQueue.size());
382  pendingChange();
383  currState = pendingQueue.front();
384 
385  // Check if a previous walk filled this request already
386  // @TODO Should this always be the TLB or should we look in the stage2 TLB?
388  currState->vmid, currState->isHyp, currState->isSecure, true, false,
389  currState->el, false);
390 
391  // Check if we still need to have a walk for this request. If the requesting
392  // instruction has been squashed, or a previous walk has filled the TLB with
393  // a match, we just want to get rid of the walk. The latter could happen
394  // when there are multiple outstanding misses to a single page and a
395  // previous request has been successfully translated.
396  if (!currState->transState->squashed() && !te) {
397  // We've got a valid request, lets process it
398  pending = true;
399  pendingQueue.pop_front();
400  // Keep currState in case one of the processWalk... calls NULLs it
401  WalkerState *curr_state_copy = currState;
402  Fault f;
403  if (currState->aarch64)
404  f = processWalkAArch64();
405  else if (longDescFormatInUse(currState->tc) ||
407  f = processWalkLPAE();
408  else
409  f = processWalk();
410 
411  if (f != NoFault) {
412  curr_state_copy->transState->finish(f, curr_state_copy->req,
413  curr_state_copy->tc, curr_state_copy->mode);
414 
415  delete curr_state_copy;
416  }
417  return;
418  }
419 
420 
421  // If the instruction that we were translating for has been
422  // squashed we shouldn't bother.
423  unsigned num_squashed = 0;
424  ThreadContext *tc = currState->tc;
425  while ((num_squashed < numSquashable) && currState &&
426  (currState->transState->squashed() || te)) {
427  pendingQueue.pop_front();
428  num_squashed++;
430 
431  DPRINTF(TLB, "Squashing table walk for address %#x\n",
433 
434  if (currState->transState->squashed()) {
435  // finish the translation which will delete the translation object
437  std::make_shared<UnimpFault>("Squashed Inst"),
439  } else {
440  // translate the request now that we know it will work
444 
445  }
446 
447  // delete the current request
448  delete currState;
449 
450  // peak at the next one
451  if (pendingQueue.size()) {
452  currState = pendingQueue.front();
455  false, currState->el, false);
456  } else {
457  // Terminate the loop, nothing more to do
458  currState = NULL;
459  }
460  }
461  pendingChange();
462 
463  // if we still have pending translations, schedule more work
464  nextWalk(tc);
465  currState = NULL;
466 }
467 
468 Fault
470 {
471  Addr ttbr = 0;
472 
473  // For short descriptors, translation configs are held in
474  // TTBR1.
477 
478  const auto irgn0_mask = 0x1;
479  const auto irgn1_mask = 0x40;
480  currState->isUncacheable = (ttbr1 & (irgn0_mask | irgn1_mask)) == 0;
481 
482  // If translation isn't enabled, we shouldn't be here
483  assert(currState->sctlr.m || isStage2);
484  const bool is_atomic = currState->req->isAtomic();
485 
486  DPRINTF(TLB, "Beginning table walk for address %#x, TTBCR: %#x, bits:%#x\n",
488  32 - currState->ttbcr.n));
489 
491 
492  if (currState->ttbcr.n == 0 || !mbits(currState->vaddr, 31,
493  32 - currState->ttbcr.n)) {
494  DPRINTF(TLB, " - Selecting TTBR0\n");
495  // Check if table walk is allowed when Security Extensions are enabled
496  if (haveSecurity && currState->ttbcr.pd0) {
497  if (currState->isFetch)
498  return std::make_shared<PrefetchAbort>(
501  isStage2,
503  else
504  return std::make_shared<DataAbort>(
507  is_atomic ? false : currState->isWrite,
510  }
513  } else {
514  DPRINTF(TLB, " - Selecting TTBR1\n");
515  // Check if table walk is allowed when Security Extensions are enabled
516  if (haveSecurity && currState->ttbcr.pd1) {
517  if (currState->isFetch)
518  return std::make_shared<PrefetchAbort>(
521  isStage2,
523  else
524  return std::make_shared<DataAbort>(
527  is_atomic ? false : currState->isWrite,
530  }
531  ttbr = ttbr1;
532  currState->ttbcr.n = 0;
533  }
534 
535  Addr l1desc_addr = mbits(ttbr, 31, 14 - currState->ttbcr.n) |
536  (bits(currState->vaddr, 31 - currState->ttbcr.n, 20) << 2);
537  DPRINTF(TLB, " - Descriptor at address %#x (%s)\n", l1desc_addr,
538  currState->isSecure ? "s" : "ns");
539 
540  // Trickbox address check
541  Fault f;
542  f = testWalk(l1desc_addr, sizeof(uint32_t),
544  if (f) {
545  DPRINTF(TLB, "Trickbox check caused fault on %#x\n", currState->vaddr_tainted);
546  if (currState->timing) {
547  pending = false;
549  currState = NULL;
550  } else {
551  currState->tc = NULL;
552  currState->req = NULL;
553  }
554  return f;
555  }
556 
558  if (currState->sctlr.c == 0 || currState->isUncacheable) {
560  }
561 
562  if (currState->isSecure) {
563  flag.set(Request::SECURE);
564  }
565 
566  bool delayed;
567  delayed = fetchDescriptor(l1desc_addr, (uint8_t*)&currState->l1Desc.data,
568  sizeof(uint32_t), flag, L1, &doL1DescEvent,
570  if (!delayed) {
571  f = currState->fault;
572  }
573 
574  return f;
575 }
576 
577 Fault
579 {
580  Addr ttbr, ttbr0_max, ttbr1_min, desc_addr;
581  int tsz, n;
582  LookupLevel start_lookup_level = L1;
583 
584  DPRINTF(TLB, "Beginning table walk for address %#x, TTBCR: %#x\n",
586 
588 
590  if (currState->isSecure)
591  flag.set(Request::SECURE);
592 
593  // work out which base address register to use, if in hyp mode we always
594  // use HTTBR
595  if (isStage2) {
596  DPRINTF(TLB, " - Selecting VTTBR (long-desc.)\n");
598  tsz = sext<4>(currState->vtcr.t0sz);
599  start_lookup_level = currState->vtcr.sl0 ? L1 : L2;
600  currState->isUncacheable = currState->vtcr.irgn0 == 0;
601  } else if (currState->isHyp) {
602  DPRINTF(TLB, " - Selecting HTTBR (long-desc.)\n");
604  tsz = currState->htcr.t0sz;
605  currState->isUncacheable = currState->htcr.irgn0 == 0;
606  } else {
607  assert(longDescFormatInUse(currState->tc));
608 
609  // Determine boundaries of TTBR0/1 regions
610  if (currState->ttbcr.t0sz)
611  ttbr0_max = (1ULL << (32 - currState->ttbcr.t0sz)) - 1;
612  else if (currState->ttbcr.t1sz)
613  ttbr0_max = (1ULL << 32) -
614  (1ULL << (32 - currState->ttbcr.t1sz)) - 1;
615  else
616  ttbr0_max = (1ULL << 32) - 1;
617  if (currState->ttbcr.t1sz)
618  ttbr1_min = (1ULL << 32) - (1ULL << (32 - currState->ttbcr.t1sz));
619  else
620  ttbr1_min = (1ULL << (32 - currState->ttbcr.t0sz));
621 
622  const bool is_atomic = currState->req->isAtomic();
623 
624  // The following code snippet selects the appropriate translation table base
625  // address (TTBR0 or TTBR1) and the appropriate starting lookup level
626  // depending on the address range supported by the translation table (ARM
627  // ARM issue C B3.6.4)
628  if (currState->vaddr <= ttbr0_max) {
629  DPRINTF(TLB, " - Selecting TTBR0 (long-desc.)\n");
630  // Check if table walk is allowed
631  if (currState->ttbcr.epd0) {
632  if (currState->isFetch)
633  return std::make_shared<PrefetchAbort>(
636  isStage2,
638  else
639  return std::make_shared<DataAbort>(
642  is_atomic ? false : currState->isWrite,
644  isStage2,
646  }
649  tsz = currState->ttbcr.t0sz;
650  currState->isUncacheable = currState->ttbcr.irgn0 == 0;
651  if (ttbr0_max < (1ULL << 30)) // Upper limit < 1 GB
652  start_lookup_level = L2;
653  } else if (currState->vaddr >= ttbr1_min) {
654  DPRINTF(TLB, " - Selecting TTBR1 (long-desc.)\n");
655  // Check if table walk is allowed
656  if (currState->ttbcr.epd1) {
657  if (currState->isFetch)
658  return std::make_shared<PrefetchAbort>(
661  isStage2,
663  else
664  return std::make_shared<DataAbort>(
667  is_atomic ? false : currState->isWrite,
669  isStage2,
671  }
674  tsz = currState->ttbcr.t1sz;
675  currState->isUncacheable = currState->ttbcr.irgn1 == 0;
676  // Lower limit >= 3 GB
677  if (ttbr1_min >= (1ULL << 31) + (1ULL << 30))
678  start_lookup_level = L2;
679  } else {
680  // Out of boundaries -> translation fault
681  if (currState->isFetch)
682  return std::make_shared<PrefetchAbort>(
685  isStage2,
687  else
688  return std::make_shared<DataAbort>(
691  is_atomic ? false : currState->isWrite,
694  }
695 
696  }
697 
698  // Perform lookup (ARM ARM issue C B3.6.6)
699  if (start_lookup_level == L1) {
700  n = 5 - tsz;
701  desc_addr = mbits(ttbr, 39, n) |
702  (bits(currState->vaddr, n + 26, 30) << 3);
703  DPRINTF(TLB, " - Descriptor at address %#x (%s) (long-desc.)\n",
704  desc_addr, currState->isSecure ? "s" : "ns");
705  } else {
706  // Skip first-level lookup
707  n = (tsz >= 2 ? 14 - tsz : 12);
708  desc_addr = mbits(ttbr, 39, n) |
709  (bits(currState->vaddr, n + 17, 21) << 3);
710  DPRINTF(TLB, " - Descriptor at address %#x (%s) (long-desc.)\n",
711  desc_addr, currState->isSecure ? "s" : "ns");
712  }
713 
714  // Trickbox address check
715  Fault f = testWalk(desc_addr, sizeof(uint64_t),
716  TlbEntry::DomainType::NoAccess, start_lookup_level);
717  if (f) {
718  DPRINTF(TLB, "Trickbox check caused fault on %#x\n", currState->vaddr_tainted);
719  if (currState->timing) {
720  pending = false;
722  currState = NULL;
723  } else {
724  currState->tc = NULL;
725  currState->req = NULL;
726  }
727  return f;
728  }
729 
730  if (currState->sctlr.c == 0 || currState->isUncacheable) {
732  }
733 
734  currState->longDesc.lookupLevel = start_lookup_level;
735  currState->longDesc.aarch64 = false;
737 
738  bool delayed = fetchDescriptor(desc_addr, (uint8_t*)&currState->longDesc.data,
739  sizeof(uint64_t), flag, start_lookup_level,
740  LongDescEventByLevel[start_lookup_level],
742  if (!delayed) {
743  f = currState->fault;
744  }
745 
746  return f;
747 }
748 
749 unsigned
751 {
752  if (tsz < 25)
753  return 25;
754  if (tsz > 48)
755  return 48;
756  return tsz;
757 }
758 
759 bool
761 {
762  return (currPhysAddrRange != MaxPhysAddrRange &&
763  bits(addr, MaxPhysAddrRange - 1, currPhysAddrRange));
764 }
765 
766 Fault
768 {
769  assert(currState->aarch64);
770 
771  DPRINTF(TLB, "Beginning table walk for address %#llx, TCR: %#llx\n",
773 
774  static const GrainSize GrainMap_tg0[] =
776  static const GrainSize GrainMap_tg1[] =
778 
780 
781  // Determine TTBR, table size, granule size and phys. address range
782  Addr ttbr = 0;
783  int tsz = 0, ps = 0;
784  GrainSize tg = Grain4KB; // grain size computed from tg* field
785  bool fault = false;
786 
787  LookupLevel start_lookup_level = MAX_LOOKUP_LEVELS;
788 
789  switch (currState->el) {
790  case EL0:
791  {
792  Addr ttbr0;
793  Addr ttbr1;
794  if (HaveVirtHostExt(currState->tc) &&
795  currState->hcr.tge==1 && currState->hcr.e2h == 1) {
796  // VHE code for EL2&0 regime
799  } else {
802  }
803  switch (bits(currState->vaddr, 63,48)) {
804  case 0:
805  DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n");
806  ttbr = ttbr0;
807  tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz);
808  tg = GrainMap_tg0[currState->tcr.tg0];
809  currState->hpd = currState->tcr.hpd0;
810  currState->isUncacheable = currState->tcr.irgn0 == 0;
811  if (bits(currState->vaddr, 63, tsz) != 0x0 ||
812  currState->tcr.epd0)
813  fault = true;
814  break;
815  case 0xffff:
816  DPRINTF(TLB, " - Selecting TTBR1 (AArch64)\n");
817  ttbr = ttbr1;
818  tsz = adjustTableSizeAArch64(64 - currState->tcr.t1sz);
819  tg = GrainMap_tg1[currState->tcr.tg1];
820  currState->hpd = currState->tcr.hpd1;
821  currState->isUncacheable = currState->tcr.irgn1 == 0;
822  if (bits(currState->vaddr, 63, tsz) != mask(64-tsz) ||
823  currState->tcr.epd1)
824  fault = true;
825  break;
826  default:
827  // top two bytes must be all 0s or all 1s, else invalid addr
828  fault = true;
829  }
830  ps = currState->tcr.ips;
831  }
832  break;
833  case EL1:
834  if (isStage2) {
835  if (currState->secureLookup) {
836  DPRINTF(TLB, " - Selecting VSTTBR_EL2 (AArch64 stage 2)\n");
838  } else {
839  DPRINTF(TLB, " - Selecting VTTBR_EL2 (AArch64 stage 2)\n");
841  }
842  tsz = 64 - currState->vtcr.t0sz64;
843  tg = GrainMap_tg0[currState->vtcr.tg0];
844  // ARM DDI 0487A.f D7-2148
845  // The starting level of stage 2 translation depends on
846  // VTCR_EL2.SL0 and VTCR_EL2.TG0
847  LookupLevel __ = MAX_LOOKUP_LEVELS; // invalid level
848  uint8_t sl_tg = (currState->vtcr.sl0 << 2) | currState->vtcr.tg0;
849  static const LookupLevel SLL[] = {
850  L2, L3, L3, __, // sl0 == 0
851  L1, L2, L2, __, // sl0 == 1, etc.
852  L0, L1, L1, __,
853  __, __, __, __
854  };
855  start_lookup_level = SLL[sl_tg];
856  panic_if(start_lookup_level == MAX_LOOKUP_LEVELS,
857  "Cannot discern lookup level from vtcr.{sl0,tg0}");
858  ps = currState->vtcr.ps;
859  currState->isUncacheable = currState->vtcr.irgn0 == 0;
860  } else {
861  switch (bits(currState->vaddr, 63,48)) {
862  case 0:
863  DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n");
865  tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz);
866  tg = GrainMap_tg0[currState->tcr.tg0];
867  currState->hpd = currState->tcr.hpd0;
868  currState->isUncacheable = currState->tcr.irgn0 == 0;
869  if (bits(currState->vaddr, 63, tsz) != 0x0 ||
870  currState->tcr.epd0)
871  fault = true;
872  break;
873  case 0xffff:
874  DPRINTF(TLB, " - Selecting TTBR1 (AArch64)\n");
876  tsz = adjustTableSizeAArch64(64 - currState->tcr.t1sz);
877  tg = GrainMap_tg1[currState->tcr.tg1];
878  currState->hpd = currState->tcr.hpd1;
879  currState->isUncacheable = currState->tcr.irgn1 == 0;
880  if (bits(currState->vaddr, 63, tsz) != mask(64-tsz) ||
881  currState->tcr.epd1)
882  fault = true;
883  break;
884  default:
885  // top two bytes must be all 0s or all 1s, else invalid addr
886  fault = true;
887  }
888  ps = currState->tcr.ips;
889  }
890  break;
891  case EL2:
892  switch(bits(currState->vaddr, 63,48)) {
893  case 0:
894  DPRINTF(TLB, " - Selecting TTBR0_EL2 (AArch64)\n");
896  tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz);
897  tg = GrainMap_tg0[currState->tcr.tg0];
898  currState->hpd = currState->hcr.e2h ?
899  currState->tcr.hpd0 : currState->tcr.hpd;
900  currState->isUncacheable = currState->tcr.irgn0 == 0;
901  break;
902 
903  case 0xffff:
904  DPRINTF(TLB, " - Selecting TTBR1_EL2 (AArch64)\n");
906  tsz = adjustTableSizeAArch64(64 - currState->tcr.t1sz);
907  tg = GrainMap_tg1[currState->tcr.tg1];
908  currState->hpd = currState->tcr.hpd1;
909  currState->isUncacheable = currState->tcr.irgn1 == 0;
910  if (bits(currState->vaddr, 63, tsz) != mask(64-tsz) ||
911  currState->tcr.epd1 || !currState->hcr.e2h)
912  fault = true;
913  break;
914 
915  default:
916  // invalid addr if top two bytes are not all 0s
917  fault = true;
918  }
919  ps = currState->hcr.e2h ? currState->tcr.ips: currState->tcr.ps;
920  break;
921  case EL3:
922  switch(bits(currState->vaddr, 63,48)) {
923  case 0:
924  DPRINTF(TLB, " - Selecting TTBR0_EL3 (AArch64)\n");
926  tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz);
927  tg = GrainMap_tg0[currState->tcr.tg0];
928  currState->hpd = currState->tcr.hpd;
929  currState->isUncacheable = currState->tcr.irgn0 == 0;
930  break;
931  default:
932  // invalid addr if top two bytes are not all 0s
933  fault = true;
934  }
935  ps = currState->tcr.ps;
936  break;
937  }
938 
939  const bool is_atomic = currState->req->isAtomic();
940 
941  if (fault) {
942  Fault f;
943  if (currState->isFetch)
944  f = std::make_shared<PrefetchAbort>(
948  else
949  f = std::make_shared<DataAbort>(
952  is_atomic ? false : currState->isWrite,
955 
956  if (currState->timing) {
957  pending = false;
959  currState = NULL;
960  } else {
961  currState->tc = NULL;
962  currState->req = NULL;
963  }
964  return f;
965 
966  }
967 
968  if (tg == ReservedGrain) {
969  warn_once("Reserved granule size requested; gem5's IMPLEMENTATION "
970  "DEFINED behavior takes this to mean 4KB granules\n");
971  tg = Grain4KB;
972  }
973 
974  // Determine starting lookup level
975  // See aarch64/translation/walk in Appendix G: ARMv8 Pseudocode Library
976  // in ARM DDI 0487A. These table values correspond to the cascading tests
977  // to compute the lookup level and are of the form
978  // (grain_size + N*stride), for N = {1, 2, 3}.
979  // A value of 64 will never succeed and a value of 0 will always succeed.
980  if (start_lookup_level == MAX_LOOKUP_LEVELS) {
981  struct GrainMap {
982  GrainSize grain_size;
983  unsigned lookup_level_cutoff[MAX_LOOKUP_LEVELS];
984  };
985  static const GrainMap GM[] = {
986  { Grain4KB, { 39, 30, 0, 0 } },
987  { Grain16KB, { 47, 36, 25, 0 } },
988  { Grain64KB, { 64, 42, 29, 0 } }
989  };
990 
991  const unsigned *lookup = NULL; // points to a lookup_level_cutoff
992 
993  for (unsigned i = 0; i < 3; ++i) { // choose entry of GM[]
994  if (tg == GM[i].grain_size) {
995  lookup = GM[i].lookup_level_cutoff;
996  break;
997  }
998  }
999  assert(lookup);
1000 
1001  for (int L = L0; L != MAX_LOOKUP_LEVELS; ++L) {
1002  if (tsz > lookup[L]) {
1003  start_lookup_level = (LookupLevel) L;
1004  break;
1005  }
1006  }
1007  panic_if(start_lookup_level == MAX_LOOKUP_LEVELS,
1008  "Table walker couldn't find lookup level\n");
1009  }
1010 
1011  int stride = tg - 3;
1012 
1013  // Determine table base address
1014  int base_addr_lo = 3 + tsz - stride * (3 - start_lookup_level) - tg;
1015  Addr base_addr = mbits(ttbr, 47, base_addr_lo);
1016 
1017  // Determine physical address size and raise an Address Size Fault if
1018  // necessary
1019  int pa_range = decodePhysAddrRange64(ps);
1020  // Clamp to lower limit
1021  if (pa_range > physAddrRange)
1023  else
1024  currState->physAddrRange = pa_range;
1026  DPRINTF(TLB, "Address size fault before any lookup\n");
1027  Fault f;
1028  if (currState->isFetch)
1029  f = std::make_shared<PrefetchAbort>(
1031  ArmFault::AddressSizeLL + start_lookup_level,
1032  isStage2,
1034  else
1035  f = std::make_shared<DataAbort>(
1038  is_atomic ? false : currState->isWrite,
1039  ArmFault::AddressSizeLL + start_lookup_level,
1040  isStage2,
1042 
1043 
1044  if (currState->timing) {
1045  pending = false;
1046  nextWalk(currState->tc);
1047  currState = NULL;
1048  } else {
1049  currState->tc = NULL;
1050  currState->req = NULL;
1051  }
1052  return f;
1053 
1054  }
1055 
1056  // Determine descriptor address
1057  Addr desc_addr = base_addr |
1058  (bits(currState->vaddr, tsz - 1,
1059  stride * (3 - start_lookup_level) + tg) << 3);
1060 
1061  // Trickbox address check
1062  Fault f = testWalk(desc_addr, sizeof(uint64_t),
1063  TlbEntry::DomainType::NoAccess, start_lookup_level);
1064  if (f) {
1065  DPRINTF(TLB, "Trickbox check caused fault on %#x\n", currState->vaddr_tainted);
1066  if (currState->timing) {
1067  pending = false;
1068  nextWalk(currState->tc);
1069  currState = NULL;
1070  } else {
1071  currState->tc = NULL;
1072  currState->req = NULL;
1073  }
1074  return f;
1075  }
1076 
1078  if (currState->sctlr.c == 0 || currState->isUncacheable) {
1079  flag.set(Request::UNCACHEABLE);
1080  }
1081 
1082  if (currState->isSecure) {
1083  flag.set(Request::SECURE);
1084  }
1085 
1086  currState->longDesc.lookupLevel = start_lookup_level;
1087  currState->longDesc.aarch64 = true;
1089 
1090  if (currState->timing) {
1091  fetchDescriptor(desc_addr, (uint8_t*) &currState->longDesc.data,
1092  sizeof(uint64_t), flag, start_lookup_level,
1093  LongDescEventByLevel[start_lookup_level], NULL);
1094  } else {
1095  fetchDescriptor(desc_addr, (uint8_t*)&currState->longDesc.data,
1096  sizeof(uint64_t), flag, -1, NULL,
1098  f = currState->fault;
1099  }
1100 
1101  return f;
1102 }
1103 
1104 void
1106  uint8_t texcb, bool s)
1107 {
1108  // Note: tc and sctlr local variables are hiding tc and sctrl class
1109  // variables
1110  DPRINTF(TLBVerbose, "memAttrs texcb:%d s:%d\n", texcb, s);
1111  te.shareable = false; // default value
1112  te.nonCacheable = false;
1113  te.outerShareable = false;
1114  if (sctlr.tre == 0 || ((sctlr.tre == 1) && (sctlr.m == 0))) {
1115  switch(texcb) {
1116  case 0: // Stongly-ordered
1117  te.nonCacheable = true;
1119  te.shareable = true;
1120  te.innerAttrs = 1;
1121  te.outerAttrs = 0;
1122  break;
1123  case 1: // Shareable Device
1124  te.nonCacheable = true;
1126  te.shareable = true;
1127  te.innerAttrs = 3;
1128  te.outerAttrs = 0;
1129  break;
1130  case 2: // Outer and Inner Write-Through, no Write-Allocate
1132  te.shareable = s;
1133  te.innerAttrs = 6;
1134  te.outerAttrs = bits(texcb, 1, 0);
1135  break;
1136  case 3: // Outer and Inner Write-Back, no Write-Allocate
1138  te.shareable = s;
1139  te.innerAttrs = 7;
1140  te.outerAttrs = bits(texcb, 1, 0);
1141  break;
1142  case 4: // Outer and Inner Non-cacheable
1143  te.nonCacheable = true;
1145  te.shareable = s;
1146  te.innerAttrs = 0;
1147  te.outerAttrs = bits(texcb, 1, 0);
1148  break;
1149  case 5: // Reserved
1150  panic("Reserved texcb value!\n");
1151  break;
1152  case 6: // Implementation Defined
1153  panic("Implementation-defined texcb value!\n");
1154  break;
1155  case 7: // Outer and Inner Write-Back, Write-Allocate
1157  te.shareable = s;
1158  te.innerAttrs = 5;
1159  te.outerAttrs = 1;
1160  break;
1161  case 8: // Non-shareable Device
1162  te.nonCacheable = true;
1164  te.shareable = false;
1165  te.innerAttrs = 3;
1166  te.outerAttrs = 0;
1167  break;
1168  case 9 ... 15: // Reserved
1169  panic("Reserved texcb value!\n");
1170  break;
1171  case 16 ... 31: // Cacheable Memory
1173  te.shareable = s;
1174  if (bits(texcb, 1,0) == 0 || bits(texcb, 3,2) == 0)
1175  te.nonCacheable = true;
1176  te.innerAttrs = bits(texcb, 1, 0);
1177  te.outerAttrs = bits(texcb, 3, 2);
1178  break;
1179  default:
1180  panic("More than 32 states for 5 bits?\n");
1181  }
1182  } else {
1183  assert(tc);
1184  PRRR prrr = tc->readMiscReg(snsBankedIndex(MISCREG_PRRR,
1186  NMRR nmrr = tc->readMiscReg(snsBankedIndex(MISCREG_NMRR,
1188  DPRINTF(TLBVerbose, "memAttrs PRRR:%08x NMRR:%08x\n", prrr, nmrr);
1189  uint8_t curr_tr = 0, curr_ir = 0, curr_or = 0;
1190  switch(bits(texcb, 2,0)) {
1191  case 0:
1192  curr_tr = prrr.tr0;
1193  curr_ir = nmrr.ir0;
1194  curr_or = nmrr.or0;
1195  te.outerShareable = (prrr.nos0 == 0);
1196  break;
1197  case 1:
1198  curr_tr = prrr.tr1;
1199  curr_ir = nmrr.ir1;
1200  curr_or = nmrr.or1;
1201  te.outerShareable = (prrr.nos1 == 0);
1202  break;
1203  case 2:
1204  curr_tr = prrr.tr2;
1205  curr_ir = nmrr.ir2;
1206  curr_or = nmrr.or2;
1207  te.outerShareable = (prrr.nos2 == 0);
1208  break;
1209  case 3:
1210  curr_tr = prrr.tr3;
1211  curr_ir = nmrr.ir3;
1212  curr_or = nmrr.or3;
1213  te.outerShareable = (prrr.nos3 == 0);
1214  break;
1215  case 4:
1216  curr_tr = prrr.tr4;
1217  curr_ir = nmrr.ir4;
1218  curr_or = nmrr.or4;
1219  te.outerShareable = (prrr.nos4 == 0);
1220  break;
1221  case 5:
1222  curr_tr = prrr.tr5;
1223  curr_ir = nmrr.ir5;
1224  curr_or = nmrr.or5;
1225  te.outerShareable = (prrr.nos5 == 0);
1226  break;
1227  case 6:
1228  panic("Imp defined type\n");
1229  case 7:
1230  curr_tr = prrr.tr7;
1231  curr_ir = nmrr.ir7;
1232  curr_or = nmrr.or7;
1233  te.outerShareable = (prrr.nos7 == 0);
1234  break;
1235  }
1236 
1237  switch(curr_tr) {
1238  case 0:
1239  DPRINTF(TLBVerbose, "StronglyOrdered\n");
1241  te.nonCacheable = true;
1242  te.innerAttrs = 1;
1243  te.outerAttrs = 0;
1244  te.shareable = true;
1245  break;
1246  case 1:
1247  DPRINTF(TLBVerbose, "Device ds1:%d ds0:%d s:%d\n",
1248  prrr.ds1, prrr.ds0, s);
1250  te.nonCacheable = true;
1251  te.innerAttrs = 3;
1252  te.outerAttrs = 0;
1253  if (prrr.ds1 && s)
1254  te.shareable = true;
1255  if (prrr.ds0 && !s)
1256  te.shareable = true;
1257  break;
1258  case 2:
1259  DPRINTF(TLBVerbose, "Normal ns1:%d ns0:%d s:%d\n",
1260  prrr.ns1, prrr.ns0, s);
1262  if (prrr.ns1 && s)
1263  te.shareable = true;
1264  if (prrr.ns0 && !s)
1265  te.shareable = true;
1266  break;
1267  case 3:
1268  panic("Reserved type");
1269  }
1270 
1271  if (te.mtype == TlbEntry::MemoryType::Normal){
1272  switch(curr_ir) {
1273  case 0:
1274  te.nonCacheable = true;
1275  te.innerAttrs = 0;
1276  break;
1277  case 1:
1278  te.innerAttrs = 5;
1279  break;
1280  case 2:
1281  te.innerAttrs = 6;
1282  break;
1283  case 3:
1284  te.innerAttrs = 7;
1285  break;
1286  }
1287 
1288  switch(curr_or) {
1289  case 0:
1290  te.nonCacheable = true;
1291  te.outerAttrs = 0;
1292  break;
1293  case 1:
1294  te.outerAttrs = 1;
1295  break;
1296  case 2:
1297  te.outerAttrs = 2;
1298  break;
1299  case 3:
1300  te.outerAttrs = 3;
1301  break;
1302  }
1303  }
1304  }
1305  DPRINTF(TLBVerbose, "memAttrs: shareable: %d, innerAttrs: %d, "
1306  "outerAttrs: %d\n",
1307  te.shareable, te.innerAttrs, te.outerAttrs);
1308  te.setAttributes(false);
1309 }
1310 
1311 void
1313  LongDescriptor &lDescriptor)
1314 {
1315  assert(_haveLPAE);
1316 
1317  uint8_t attr;
1318  uint8_t sh = lDescriptor.sh();
1319  // Different format and source of attributes if this is a stage 2
1320  // translation
1321  if (isStage2) {
1322  attr = lDescriptor.memAttr();
1323  uint8_t attr_3_2 = (attr >> 2) & 0x3;
1324  uint8_t attr_1_0 = attr & 0x3;
1325 
1326  DPRINTF(TLBVerbose, "memAttrsLPAE MemAttr:%#x sh:%#x\n", attr, sh);
1327 
1328  if (attr_3_2 == 0) {
1329  te.mtype = attr_1_0 == 0 ? TlbEntry::MemoryType::StronglyOrdered
1331  te.outerAttrs = 0;
1332  te.innerAttrs = attr_1_0 == 0 ? 1 : 3;
1333  te.nonCacheable = true;
1334  } else {
1336  te.outerAttrs = attr_3_2 == 1 ? 0 :
1337  attr_3_2 == 2 ? 2 : 1;
1338  te.innerAttrs = attr_1_0 == 1 ? 0 :
1339  attr_1_0 == 2 ? 6 : 5;
1340  te.nonCacheable = (attr_3_2 == 1) || (attr_1_0 == 1);
1341  }
1342  } else {
1343  uint8_t attrIndx = lDescriptor.attrIndx();
1344 
1345  // LPAE always uses remapping of memory attributes, irrespective of the
1346  // value of SCTLR.TRE
1347  MiscRegIndex reg = attrIndx & 0x4 ? MISCREG_MAIR1 : MISCREG_MAIR0;
1348  int reg_as_int = snsBankedIndex(reg, currState->tc,
1349  !currState->isSecure);
1350  uint32_t mair = currState->tc->readMiscReg(reg_as_int);
1351  attr = (mair >> (8 * (attrIndx % 4))) & 0xff;
1352  uint8_t attr_7_4 = bits(attr, 7, 4);
1353  uint8_t attr_3_0 = bits(attr, 3, 0);
1354  DPRINTF(TLBVerbose, "memAttrsLPAE AttrIndx:%#x sh:%#x, attr %#x\n", attrIndx, sh, attr);
1355 
1356  // Note: the memory subsystem only cares about the 'cacheable' memory
1357  // attribute. The other attributes are only used to fill the PAR register
1358  // accordingly to provide the illusion of full support
1359  te.nonCacheable = false;
1360 
1361  switch (attr_7_4) {
1362  case 0x0:
1363  // Strongly-ordered or Device memory
1364  if (attr_3_0 == 0x0)
1366  else if (attr_3_0 == 0x4)
1368  else
1369  panic("Unpredictable behavior\n");
1370  te.nonCacheable = true;
1371  te.outerAttrs = 0;
1372  break;
1373  case 0x4:
1374  // Normal memory, Outer Non-cacheable
1376  te.outerAttrs = 0;
1377  if (attr_3_0 == 0x4)
1378  // Inner Non-cacheable
1379  te.nonCacheable = true;
1380  else if (attr_3_0 < 0x8)
1381  panic("Unpredictable behavior\n");
1382  break;
1383  case 0x8:
1384  case 0x9:
1385  case 0xa:
1386  case 0xb:
1387  case 0xc:
1388  case 0xd:
1389  case 0xe:
1390  case 0xf:
1391  if (attr_7_4 & 0x4) {
1392  te.outerAttrs = (attr_7_4 & 1) ? 1 : 3;
1393  } else {
1394  te.outerAttrs = 0x2;
1395  }
1396  // Normal memory, Outer Cacheable
1398  if (attr_3_0 != 0x4 && attr_3_0 < 0x8)
1399  panic("Unpredictable behavior\n");
1400  break;
1401  default:
1402  panic("Unpredictable behavior\n");
1403  break;
1404  }
1405 
1406  switch (attr_3_0) {
1407  case 0x0:
1408  te.innerAttrs = 0x1;
1409  break;
1410  case 0x4:
1411  te.innerAttrs = attr_7_4 == 0 ? 0x3 : 0;
1412  break;
1413  case 0x8:
1414  case 0x9:
1415  case 0xA:
1416  case 0xB:
1417  te.innerAttrs = 6;
1418  break;
1419  case 0xC:
1420  case 0xD:
1421  case 0xE:
1422  case 0xF:
1423  te.innerAttrs = attr_3_0 & 1 ? 0x5 : 0x7;
1424  break;
1425  default:
1426  panic("Unpredictable behavior\n");
1427  break;
1428  }
1429  }
1430 
1431  te.outerShareable = sh == 2;
1432  te.shareable = (sh & 0x2) ? true : false;
1433  te.setAttributes(true);
1434  te.attributes |= (uint64_t) attr << 56;
1435 }
1436 
1437 void
1439  LongDescriptor &lDescriptor)
1440 {
1441  uint8_t attr;
1442  uint8_t attr_hi;
1443  uint8_t attr_lo;
1444  uint8_t sh = lDescriptor.sh();
1445 
1446  if (isStage2) {
1447  attr = lDescriptor.memAttr();
1448  uint8_t attr_hi = (attr >> 2) & 0x3;
1449  uint8_t attr_lo = attr & 0x3;
1450 
1451  DPRINTF(TLBVerbose, "memAttrsAArch64 MemAttr:%#x sh:%#x\n", attr, sh);
1452 
1453  if (attr_hi == 0) {
1454  te.mtype = attr_lo == 0 ? TlbEntry::MemoryType::StronglyOrdered
1456  te.outerAttrs = 0;
1457  te.innerAttrs = attr_lo == 0 ? 1 : 3;
1458  te.nonCacheable = true;
1459  } else {
1461  te.outerAttrs = attr_hi == 1 ? 0 :
1462  attr_hi == 2 ? 2 : 1;
1463  te.innerAttrs = attr_lo == 1 ? 0 :
1464  attr_lo == 2 ? 6 : 5;
1465  // Treat write-through memory as uncacheable, this is safe
1466  // but for performance reasons not optimal.
1467  te.nonCacheable = (attr_hi == 1) || (attr_hi == 2) ||
1468  (attr_lo == 1) || (attr_lo == 2);
1469  }
1470  } else {
1471  uint8_t attrIndx = lDescriptor.attrIndx();
1472 
1473  DPRINTF(TLBVerbose, "memAttrsAArch64 AttrIndx:%#x sh:%#x\n", attrIndx, sh);
1475 
1476  // Select MAIR
1477  uint64_t mair;
1478  switch (regime) {
1479  case EL0:
1480  case EL1:
1481  mair = tc->readMiscReg(MISCREG_MAIR_EL1);
1482  break;
1483  case EL2:
1484  mair = tc->readMiscReg(MISCREG_MAIR_EL2);
1485  break;
1486  case EL3:
1487  mair = tc->readMiscReg(MISCREG_MAIR_EL3);
1488  break;
1489  default:
1490  panic("Invalid exception level");
1491  break;
1492  }
1493 
1494  // Select attributes
1495  attr = bits(mair, 8 * attrIndx + 7, 8 * attrIndx);
1496  attr_lo = bits(attr, 3, 0);
1497  attr_hi = bits(attr, 7, 4);
1498 
1499  // Memory type
1501 
1502  // Cacheability
1503  te.nonCacheable = false;
1504  if (te.mtype == TlbEntry::MemoryType::Device) { // Device memory
1505  te.nonCacheable = true;
1506  }
1507  // Treat write-through memory as uncacheable, this is safe
1508  // but for performance reasons not optimal.
1509  switch (attr_hi) {
1510  case 0x1 ... 0x3: // Normal Memory, Outer Write-through transient
1511  case 0x4: // Normal memory, Outer Non-cacheable
1512  case 0x8 ... 0xb: // Normal Memory, Outer Write-through non-transient
1513  te.nonCacheable = true;
1514  }
1515  switch (attr_lo) {
1516  case 0x1 ... 0x3: // Normal Memory, Inner Write-through transient
1517  case 0x9 ... 0xb: // Normal Memory, Inner Write-through non-transient
1518  warn_if(!attr_hi, "Unpredictable behavior");
1520  case 0x4: // Device-nGnRE memory or
1521  // Normal memory, Inner Non-cacheable
1522  case 0x8: // Device-nGRE memory or
1523  // Normal memory, Inner Write-through non-transient
1524  te.nonCacheable = true;
1525  }
1526 
1527  te.shareable = sh == 2;
1528  te.outerShareable = (sh & 0x2) ? true : false;
1529  // Attributes formatted according to the 64-bit PAR
1530  te.attributes = ((uint64_t) attr << 56) |
1531  (1 << 11) | // LPAE bit
1532  (te.ns << 9) | // NS bit
1533  (sh << 7);
1534  }
1535 }
1536 
1537 void
1539 {
1540  if (currState->fault != NoFault) {
1541  return;
1542  }
1543 
1545  byteOrder(currState->tc));
1546 
1547  DPRINTF(TLB, "L1 descriptor for %#x is %#x\n",
1549  TlbEntry te;
1550 
1551  const bool is_atomic = currState->req->isAtomic();
1552 
1553  switch (currState->l1Desc.type()) {
1554  case L1Descriptor::Ignore:
1556  if (!currState->timing) {
1557  currState->tc = NULL;
1558  currState->req = NULL;
1559  }
1560  DPRINTF(TLB, "L1 Descriptor Reserved/Ignore, causing fault\n");
1561  if (currState->isFetch)
1562  currState->fault =
1563  std::make_shared<PrefetchAbort>(
1566  isStage2,
1568  else
1569  currState->fault =
1570  std::make_shared<DataAbort>(
1573  is_atomic ? false : currState->isWrite,
1576  return;
1577  case L1Descriptor::Section:
1578  if (currState->sctlr.afe && bits(currState->l1Desc.ap(), 0) == 0) {
1584  currState->fault = std::make_shared<DataAbort>(
1586  currState->l1Desc.domain(),
1587  is_atomic ? false : currState->isWrite,
1589  isStage2,
1591  }
1592  if (currState->l1Desc.supersection()) {
1593  panic("Haven't implemented supersections\n");
1594  }
1596  return;
1598  {
1599  Addr l2desc_addr;
1600  l2desc_addr = currState->l1Desc.l2Addr() |
1601  (bits(currState->vaddr, 19, 12) << 2);
1602  DPRINTF(TLB, "L1 descriptor points to page table at: %#x (%s)\n",
1603  l2desc_addr, currState->isSecure ? "s" : "ns");
1604 
1605  // Trickbox address check
1606  currState->fault = testWalk(l2desc_addr, sizeof(uint32_t),
1607  currState->l1Desc.domain(), L2);
1608 
1609  if (currState->fault) {
1610  if (!currState->timing) {
1611  currState->tc = NULL;
1612  currState->req = NULL;
1613  }
1614  return;
1615  }
1616 
1618 
1619  if (currState->sctlr.c == 0 || currState->isUncacheable) {
1620  flag.set(Request::UNCACHEABLE);
1621  }
1622 
1623  if (currState->isSecure)
1624  flag.set(Request::SECURE);
1625 
1626  bool delayed;
1627  delayed = fetchDescriptor(l2desc_addr,
1628  (uint8_t*)&currState->l2Desc.data,
1629  sizeof(uint32_t), flag, -1, &doL2DescEvent,
1631  if (delayed) {
1632  currState->delayed = true;
1633  }
1634 
1635  return;
1636  }
1637  default:
1638  panic("A new type in a 2 bit field?\n");
1639  }
1640 }
1641 
1642 Fault
1644 {
1645  if (currState->isFetch) {
1646  return std::make_shared<PrefetchAbort>(
1649  isStage2,
1651  } else {
1652  return std::make_shared<DataAbort>(
1655  currState->req->isAtomic() ? false : currState->isWrite,
1657  isStage2,
1659  }
1660 }
1661 
1662 void
1664 {
1665  if (currState->fault != NoFault) {
1666  return;
1667  }
1668 
1670  byteOrder(currState->tc));
1671 
1672  DPRINTF(TLB, "L%d descriptor for %#llx is %#llx (%s)\n",
1675  currState->aarch64 ? "AArch64" : "long-desc.");
1676 
1679  DPRINTF(TLBVerbose, "Analyzing L%d descriptor: %#llx, pxn: %d, "
1680  "xn: %d, ap: %d, af: %d, type: %d\n",
1683  currState->longDesc.pxn(),
1684  currState->longDesc.xn(),
1685  currState->longDesc.ap(),
1686  currState->longDesc.af(),
1687  currState->longDesc.type());
1688  } else {
1689  DPRINTF(TLBVerbose, "Analyzing L%d descriptor: %#llx, type: %d\n",
1692  currState->longDesc.type());
1693  }
1694 
1695  TlbEntry te;
1696 
1697  switch (currState->longDesc.type()) {
1699  DPRINTF(TLB, "L%d descriptor Invalid, causing fault type %d\n",
1702 
1704  if (!currState->timing) {
1705  currState->tc = NULL;
1706  currState->req = NULL;
1707  }
1708  return;
1709 
1710  case LongDescriptor::Block:
1711  case LongDescriptor::Page:
1712  {
1713  auto fault_source = ArmFault::FaultSourceInvalid;
1714  // Check for address size fault
1719 
1720  DPRINTF(TLB, "L%d descriptor causing Address Size Fault\n",
1722  fault_source = ArmFault::AddressSizeLL;
1723 
1724  // Check for access fault
1725  } else if (currState->longDesc.af() == 0) {
1726 
1727  DPRINTF(TLB, "L%d descriptor causing Access Fault\n",
1729  fault_source = ArmFault::AccessFlagLL;
1730  }
1731 
1732  if (fault_source != ArmFault::FaultSourceInvalid) {
1733  currState->fault = generateLongDescFault(fault_source);
1734  } else {
1736  }
1737  }
1738  return;
1739  case LongDescriptor::Table:
1740  {
1741  // Set hierarchical permission flags
1752 
1753  // Set up next level lookup
1754  Addr next_desc_addr = currState->longDesc.nextDescAddr(
1755  currState->vaddr);
1756 
1757  DPRINTF(TLB, "L%d descriptor points to L%d descriptor at: %#x (%s)\n",
1760  next_desc_addr,
1761  currState->secureLookup ? "s" : "ns");
1762 
1763  // Check for address size fault
1765  next_desc_addr, currState->physAddrRange)) {
1766  DPRINTF(TLB, "L%d descriptor causing Address Size Fault\n",
1768 
1771  return;
1772  }
1773 
1774  // Trickbox address check
1776  next_desc_addr, sizeof(uint64_t), TlbEntry::DomainType::Client,
1778 
1779  if (currState->fault) {
1780  if (!currState->timing) {
1781  currState->tc = NULL;
1782  currState->req = NULL;
1783  }
1784  return;
1785  }
1786 
1788  if (currState->secureLookup)
1789  flag.set(Request::SECURE);
1790 
1791  if (currState->sctlr.c == 0 || currState->isUncacheable) {
1792  flag.set(Request::UNCACHEABLE);
1793  }
1794 
1797  Event *event = NULL;
1798  switch (L) {
1799  case L1:
1800  assert(currState->aarch64);
1801  case L2:
1802  case L3:
1803  event = LongDescEventByLevel[L];
1804  break;
1805  default:
1806  panic("Wrong lookup level in table walk\n");
1807  break;
1808  }
1809 
1810  bool delayed;
1811  delayed = fetchDescriptor(next_desc_addr, (uint8_t*)&currState->longDesc.data,
1812  sizeof(uint64_t), flag, -1, event,
1814  if (delayed) {
1815  currState->delayed = true;
1816  }
1817  }
1818  return;
1819  default:
1820  panic("A new type in a 2 bit field?\n");
1821  }
1822 }
1823 
1824 void
1826 {
1827  if (currState->fault != NoFault) {
1828  return;
1829  }
1830 
1832  byteOrder(currState->tc));
1833 
1834  DPRINTF(TLB, "L2 descriptor for %#x is %#x\n",
1836  TlbEntry te;
1837 
1838  const bool is_atomic = currState->req->isAtomic();
1839 
1840  if (currState->l2Desc.invalid()) {
1841  DPRINTF(TLB, "L2 descriptor invalid, causing fault\n");
1842  if (!currState->timing) {
1843  currState->tc = NULL;
1844  currState->req = NULL;
1845  }
1846  if (currState->isFetch)
1847  currState->fault = std::make_shared<PrefetchAbort>(
1850  isStage2,
1852  else
1853  currState->fault = std::make_shared<DataAbort>(
1855  is_atomic ? false : currState->isWrite,
1857  isStage2,
1859  return;
1860  }
1861 
1862  if (currState->sctlr.afe && bits(currState->l2Desc.ap(), 0) == 0) {
1866  DPRINTF(TLB, "Generating access fault at L2, afe: %d, ap: %d\n",
1867  currState->sctlr.afe, currState->l2Desc.ap());
1868 
1869  currState->fault = std::make_shared<DataAbort>(
1872  is_atomic ? false : currState->isWrite,
1875  }
1876 
1878 }
1879 
1880 void
1882 {
1883  currState = stateQueues[L1].front();
1884  currState->delayed = false;
1885  // if there's a stage2 translation object we don't need it any more
1886  if (currState->stage2Tran) {
1887  delete currState->stage2Tran;
1888  currState->stage2Tran = NULL;
1889  }
1890 
1891 
1892  DPRINTF(TLBVerbose, "L1 Desc object host addr: %p\n",&currState->l1Desc.data);
1893  DPRINTF(TLBVerbose, "L1 Desc object data: %08x\n",currState->l1Desc.data);
1894 
1895  DPRINTF(TLBVerbose, "calling doL1Descriptor for vaddr:%#x\n", currState->vaddr_tainted);
1896  doL1Descriptor();
1897 
1898  stateQueues[L1].pop_front();
1899  // Check if fault was generated
1900  if (currState->fault != NoFault) {
1902  currState->tc, currState->mode);
1904 
1905  pending = false;
1906  nextWalk(currState->tc);
1907 
1908  currState->req = NULL;
1909  currState->tc = NULL;
1910  currState->delayed = false;
1911  delete currState;
1912  }
1913  else if (!currState->delayed) {
1914  // delay is not set so there is no L2 to do
1915  // Don't finish the translation if a stage 2 look up is underway
1917  DPRINTF(TLBVerbose, "calling translateTiming again\n");
1921 
1922  pending = false;
1923  nextWalk(currState->tc);
1924 
1925  currState->req = NULL;
1926  currState->tc = NULL;
1927  currState->delayed = false;
1928  delete currState;
1929  } else {
1930  // need to do L2 descriptor
1931  stateQueues[L2].push_back(currState);
1932  }
1933  currState = NULL;
1934 }
1935 
1936 void
1938 {
1939  currState = stateQueues[L2].front();
1940  assert(currState->delayed);
1941  // if there's a stage2 translation object we don't need it any more
1942  if (currState->stage2Tran) {
1943  delete currState->stage2Tran;
1944  currState->stage2Tran = NULL;
1945  }
1946 
1947  DPRINTF(TLBVerbose, "calling doL2Descriptor for vaddr:%#x\n",
1949  doL2Descriptor();
1950 
1951  // Check if fault was generated
1952  if (currState->fault != NoFault) {
1954  currState->tc, currState->mode);
1956  } else {
1958  DPRINTF(TLBVerbose, "calling translateTiming again\n");
1962  }
1963 
1964 
1965  stateQueues[L2].pop_front();
1966  pending = false;
1967  nextWalk(currState->tc);
1968 
1969  currState->req = NULL;
1970  currState->tc = NULL;
1971  currState->delayed = false;
1972 
1973  delete currState;
1974  currState = NULL;
1975 }
1976 
1977 void
1979 {
1981 }
1982 
1983 void
1985 {
1987 }
1988 
1989 void
1991 {
1993 }
1994 
1995 void
1997 {
1999 }
2000 
2001 void
2003 {
2004  currState = stateQueues[curr_lookup_level].front();
2005  assert(curr_lookup_level == currState->longDesc.lookupLevel);
2006  currState->delayed = false;
2007 
2008  // if there's a stage2 translation object we don't need it any more
2009  if (currState->stage2Tran) {
2010  delete currState->stage2Tran;
2011  currState->stage2Tran = NULL;
2012  }
2013 
2014  DPRINTF(TLBVerbose, "calling doLongDescriptor for vaddr:%#x\n",
2016  doLongDescriptor();
2017 
2018  stateQueues[curr_lookup_level].pop_front();
2019 
2020  if (currState->fault != NoFault) {
2021  // A fault was generated
2023  currState->tc, currState->mode);
2024 
2025  pending = false;
2026  nextWalk(currState->tc);
2027 
2028  currState->req = NULL;
2029  currState->tc = NULL;
2030  currState->delayed = false;
2031  delete currState;
2032  } else if (!currState->delayed) {
2033  // No additional lookups required
2034  DPRINTF(TLBVerbose, "calling translateTiming again\n");
2038  stats.walksLongTerminatedAtLevel[(unsigned) curr_lookup_level]++;
2039 
2040  pending = false;
2041  nextWalk(currState->tc);
2042 
2043  currState->req = NULL;
2044  currState->tc = NULL;
2045  currState->delayed = false;
2046  delete currState;
2047  } else {
2048  if (curr_lookup_level >= MAX_LOOKUP_LEVELS - 1)
2049  panic("Max. number of lookups already reached in table walk\n");
2050  // Need to perform additional lookups
2052  }
2053  currState = NULL;
2054 }
2055 
2056 
2057 void
2059 {
2060  if (pendingQueue.size())
2062  else
2063  completeDrain();
2064 }
2065 
2066 bool
2067 TableWalker::fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes,
2068  Request::Flags flags, int queueIndex, Event *event,
2069  void (TableWalker::*doDescriptor)())
2070 {
2071  bool isTiming = currState->timing;
2072 
2073  DPRINTF(TLBVerbose, "Fetching descriptor at address: 0x%x stage2Req: %d\n",
2074  descAddr, currState->stage2Req);
2075 
2076  // If this translation has a stage 2 then we know descAddr is an IPA and
2077  // needs to be translated before we can access the page table. Do that
2078  // check here.
2079  if (currState->stage2Req) {
2080  Fault fault;
2081 
2082  if (isTiming) {
2083  Stage2MMU::Stage2Translation *tran = new
2085  currState->vaddr);
2086  currState->stage2Tran = tran;
2087  stage2Mmu->readDataTimed(currState->tc, descAddr, tran, numBytes,
2088  flags);
2089  fault = tran->fault;
2090  } else {
2092  currState->vaddr, descAddr, data, numBytes, flags,
2094  }
2095 
2096  if (fault != NoFault) {
2097  currState->fault = fault;
2098  }
2099  if (isTiming) {
2100  if (queueIndex >= 0) {
2101  DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n",
2102  stateQueues[queueIndex].size());
2103  stateQueues[queueIndex].push_back(currState);
2104  currState = NULL;
2105  }
2106  } else {
2107  (this->*doDescriptor)();
2108  }
2109  } else {
2110  if (isTiming) {
2111  port->dmaAction(MemCmd::ReadReq, descAddr, numBytes, event, data,
2112  currState->tc->getCpuPtr()->clockPeriod(),flags);
2113  if (queueIndex >= 0) {
2114  DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n",
2115  stateQueues[queueIndex].size());
2116  stateQueues[queueIndex].push_back(currState);
2117  currState = NULL;
2118  }
2119  } else if (!currState->functional) {
2120  port->dmaAction(MemCmd::ReadReq, descAddr, numBytes, NULL, data,
2121  currState->tc->getCpuPtr()->clockPeriod(), flags);
2122  (this->*doDescriptor)();
2123  } else {
2124  RequestPtr req = std::make_shared<Request>(
2125  descAddr, numBytes, flags, requestorId);
2126 
2127  req->taskId(ContextSwitchTaskId::DMA);
2128  PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
2129  pkt->dataStatic(data);
2130  port->sendFunctional(pkt);
2131  (this->*doDescriptor)();
2132  delete pkt;
2133  }
2134  }
2135  return (isTiming);
2136 }
2137 
2138 void
2139 TableWalker::insertTableEntry(DescriptorBase &descriptor, bool longDescriptor)
2140 {
2141  TlbEntry te;
2142 
2143  // Create and fill a new page table entry
2144  te.valid = true;
2145  te.longDescFormat = longDescriptor;
2146  te.isHyp = currState->isHyp;
2147  te.asid = currState->asid;
2148  te.vmid = currState->vmid;
2149  te.N = descriptor.offsetBits();
2150  te.vpn = currState->vaddr >> te.N;
2151  te.size = (1<<te.N) - 1;
2152  te.pfn = descriptor.pfn();
2153  te.domain = descriptor.domain();
2154  te.lookupLevel = descriptor.lookupLevel;
2155  te.ns = !descriptor.secure(haveSecurity, currState) || isStage2;
2156  te.nstid = !currState->isSecure;
2157  te.xn = descriptor.xn();
2158  if (currState->aarch64)
2159  te.el = currState->el;
2160  else
2161  te.el = EL1;
2162 
2165 
2166  // ASID has no meaning for stage 2 TLB entries, so mark all stage 2 entries
2167  // as global
2168  te.global = descriptor.global(currState) || isStage2;
2169  if (longDescriptor) {
2170  LongDescriptor lDescriptor =
2171  dynamic_cast<LongDescriptor &>(descriptor);
2172 
2173  te.xn |= currState->xnTable;
2174  te.pxn = currState->pxnTable || lDescriptor.pxn();
2175  if (isStage2) {
2176  // this is actually the HAP field, but its stored in the same bit
2177  // possitions as the AP field in a stage 1 translation.
2178  te.hap = lDescriptor.ap();
2179  } else {
2180  te.ap = ((!currState->rwTable || descriptor.ap() >> 1) << 1) |
2181  (currState->userTable && (descriptor.ap() & 0x1));
2182  }
2183  if (currState->aarch64)
2184  memAttrsAArch64(currState->tc, te, lDescriptor);
2185  else
2186  memAttrsLPAE(currState->tc, te, lDescriptor);
2187  } else {
2188  te.ap = descriptor.ap();
2189  memAttrs(currState->tc, te, currState->sctlr, descriptor.texcb(),
2190  descriptor.shareable());
2191  }
2192 
2193  // Debug output
2194  DPRINTF(TLB, descriptor.dbgHeader().c_str());
2195  DPRINTF(TLB, " - N:%d pfn:%#x size:%#x global:%d valid:%d\n",
2196  te.N, te.pfn, te.size, te.global, te.valid);
2197  DPRINTF(TLB, " - vpn:%#x xn:%d pxn:%d ap:%d domain:%d asid:%d "
2198  "vmid:%d hyp:%d nc:%d ns:%d\n", te.vpn, te.xn, te.pxn,
2199  te.ap, static_cast<uint8_t>(te.domain), te.asid, te.vmid, te.isHyp,
2200  te.nonCacheable, te.ns);
2201  DPRINTF(TLB, " - domain from L%d desc:%d data:%#x\n",
2202  descriptor.lookupLevel, static_cast<uint8_t>(descriptor.domain()),
2203  descriptor.getRawData());
2204 
2205  // Insert the entry into the TLB
2206  tlb->insert(currState->vaddr, te);
2207  if (!currState->timing) {
2208  currState->tc = NULL;
2209  currState->req = NULL;
2210  }
2211 }
2212 
2214 ArmTableWalkerParams::create()
2215 {
2216  return new ArmISA::TableWalker(this);
2217 }
2218 
2220 TableWalker::toLookupLevel(uint8_t lookup_level_as_int)
2221 {
2222  switch (lookup_level_as_int) {
2223  case L1:
2224  return L1;
2225  case L2:
2226  return L2;
2227  case L3:
2228  return L3;
2229  default:
2230  panic("Invalid lookup level conversion");
2231  }
2232 }
2233 
2234 /* this method keeps track of the table walker queue's residency, so
2235  * needs to be called whenever requests start and complete. */
2236 void
2238 {
2239  unsigned n = pendingQueue.size();
2240  if ((currState != NULL) && (currState != pendingQueue.front())) {
2241  ++n;
2242  }
2243 
2244  if (n != pendingReqs) {
2245  Tick now = curTick();
2247  pendingReqs = n;
2248  pendingChangeTick = now;
2249  }
2250 }
2251 
2252 Fault
2254  LookupLevel lookup_level)
2255 {
2256  return tlb->testWalk(pa, size, currState->vaddr, currState->isSecure,
2257  currState->mode, domain, lookup_level);
2258 }
2259 
2260 
2261 uint8_t
2263 {
2264  /* for stats.pageSizes */
2265  switch(N) {
2266  case 12: return 0; // 4K
2267  case 14: return 1; // 16K (using 16K granule in v8-64)
2268  case 16: return 2; // 64K
2269  case 20: return 3; // 1M
2270  case 21: return 4; // 2M-LPAE
2271  case 24: return 5; // 16M
2272  case 25: return 6; // 32M (using 16K granule in v8-64)
2273  case 29: return 7; // 512M (using 64K granule in v8-64)
2274  case 30: return 8; // 1G-LPAE
2275  default:
2276  panic("unknown page size");
2277  return 255;
2278  }
2279 }
2280 
2281 
2283  : Stats::Group(parent),
2284  ADD_STAT(walks, "Table walker walks requested"),
2285  ADD_STAT(walksShortDescriptor, "Table walker walks initiated with"
2286  " short descriptors"),
2287  ADD_STAT(walksLongDescriptor, "Table walker walks initiated with"
2288  " long descriptors"),
2289  ADD_STAT(walksShortTerminatedAtLevel, "Level at which table walker"
2290  " walks with short descriptors terminate"),
2291  ADD_STAT(walksLongTerminatedAtLevel, "Level at which table walker"
2292  " walks with long descriptors terminate"),
2293  ADD_STAT(squashedBefore, "Table walks squashed before starting"),
2294  ADD_STAT(squashedAfter, "Table walks squashed after completion"),
2295  ADD_STAT(walkWaitTime, "Table walker wait (enqueue to first request)"
2296  " latency"),
2297  ADD_STAT(walkServiceTime, "Table walker service (enqueue to completion)"
2298  " latency"),
2299  ADD_STAT(pendingWalks, "Table walker pending requests distribution"),
2300  ADD_STAT(pageSizes, "Table walker page sizes translated"),
2301  ADD_STAT(requestOrigin, "Table walker requests started/completed,"
2302  " data/inst")
2303 {
2305  .flags(Stats::nozero);
2306 
2308  .flags(Stats::nozero);
2309 
2311  .init(2)
2312  .flags(Stats::nozero);
2313 
2314  walksShortTerminatedAtLevel.subname(0, "Level1");
2315  walksShortTerminatedAtLevel.subname(1, "Level2");
2316 
2318  .init(4)
2319  .flags(Stats::nozero);
2320  walksLongTerminatedAtLevel.subname(0, "Level0");
2321  walksLongTerminatedAtLevel.subname(1, "Level1");
2322  walksLongTerminatedAtLevel.subname(2, "Level2");
2323  walksLongTerminatedAtLevel.subname(3, "Level3");
2324 
2326  .flags(Stats::nozero);
2327 
2329  .flags(Stats::nozero);
2330 
2331  walkWaitTime
2332  .init(16)
2334 
2336  .init(16)
2338 
2339  pendingWalks
2340  .init(16)
2342 
2343  pageSizes // see DDI 0487A D4-1661
2344  .init(9)
2346  pageSizes.subname(0, "4K");
2347  pageSizes.subname(1, "16K");
2348  pageSizes.subname(2, "64K");
2349  pageSizes.subname(3, "1M");
2350  pageSizes.subname(4, "2M");
2351  pageSizes.subname(5, "16M");
2352  pageSizes.subname(6, "32M");
2353  pageSizes.subname(7, "512M");
2354  pageSizes.subname(8, "1G");
2355 
2357  .init(2,2) // Instruction/Data, requests/completed
2358  .flags(Stats::total);
2359  requestOrigin.subname(0,"Requested");
2360  requestOrigin.subname(1,"Completed");
2361  requestOrigin.ysubname(0,"Data");
2362  requestOrigin.ysubname(1,"Inst");
2363 }
ArmISA::TableWalker::L1Descriptor::l2Addr
Addr l2Addr() const
Address of L2 descriptor if it exists.
Definition: table_walker.hh:190
ArmISA::TableWalker::WalkerState::pxnTable
bool pxnTable
Definition: table_walker.hh:765
ArmISA::TableWalker::TableWalkerStats::walkWaitTime
Stats::Histogram walkWaitTime
Definition: table_walker.hh:870
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:183
ArmISA::TableWalker::WalkerState::stage2Req
bool stage2Req
Flag indicating if a second stage of lookup is required.
Definition: table_walker.hh:771
ArmISA::TableWalker::WalkerState::mode
BaseTLB::Mode mode
Save mode for use in delayed response.
Definition: table_walker.hh:783
BaseTLB::Translation::finish
virtual void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, Mode mode)=0
BaseTLB::Translation::squashed
virtual bool squashed() const
This function is used by the page table walker to determine if it should translate the a pending requ...
Definition: tlb.hh:84
ArmISA::TableWalker::LongDescriptor::af
bool af() const
Returns true if the access flag (AF) is set.
Definition: table_walker.hh:566
ArmISA::TableWalker::WalkerState::el
ExceptionLevel el
Current exception level.
Definition: table_walker.hh:698
ArmISA::TableWalker::LongDescriptor::grainSize
GrainSize grainSize
Width of the granule size in bits.
Definition: table_walker.hh:424
ArmISA::TableWalker::walk
Fault walk(const RequestPtr &req, ThreadContext *tc, uint16_t asid, uint8_t _vmid, bool _isHyp, TLB::Mode mode, TLB::Translation *_trans, bool timing, bool functional, bool secure, TLB::ArmTranslationType tranType, bool _stage2Req)
Definition: table_walker.cc:189
ArmISA::TableWalker::drainResume
void drainResume() override
Resume execution after a successful drain.
Definition: table_walker.cc:179
ArmISA::TableWalker::WalkerState::functional
bool functional
If the atomic mode should be functional.
Definition: table_walker.hh:780
ArmISA::LookupLevel
LookupLevel
Definition: pagetable.hh:72
ArmISA::TableWalker::TableWalkerStats::walksShortDescriptor
Stats::Scalar walksShortDescriptor
Definition: table_walker.hh:864
X86ISA::L
Bitfield< 7, 0 > L
Definition: int.hh:57
ArmISA::TableWalker::WalkerState::tcr
TCR tcr
Definition: table_walker.hh:735
ArmISA::TableWalker::memAttrsAArch64
void memAttrsAArch64(ThreadContext *tc, TlbEntry &te, LongDescriptor &lDescriptor)
Definition: table_walker.cc:1438
ArmISA::TableWalker::DescriptorBase::secure
virtual bool secure(bool have_security, WalkerState *currState) const =0
ArmISA::TableWalker::L1Descriptor::supersection
bool supersection() const
Is the page a Supersection (16MB)?
Definition: table_walker.hh:136
ArmISA::TableWalker::doL2Descriptor
void doL2Descriptor()
Definition: table_walker.cc:1825
ArmISA::sh
Bitfield< 8, 7 > sh
Definition: miscregs_types.hh:654
ArmISA::EL2
@ EL2
Definition: types.hh:624
ArmISA::TableWalker::WalkerState::isHyp
bool isHyp
Definition: table_walker.hh:709
ArmISA::TableWalker::WalkerState::tranType
TLB::ArmTranslationType tranType
The translation type that has been requested.
Definition: table_walker.hh:786
ArmISA::TableWalker::WalkerState::asid
uint16_t asid
ASID that we're servicing the request under.
Definition: table_walker.hh:707
ArmISA::TableWalker::TableWalkerStats::TableWalkerStats
TableWalkerStats(Stats::Group *parent)
Definition: table_walker.cc:2282
system.hh
ArmISA::MISCREG_TTBR0
@ MISCREG_TTBR0
Definition: miscregs.hh:248
ArmISA::HaveVirtHostExt
bool HaveVirtHostExt(ThreadContext *tc)
Definition: utility.cc:326
ArmISA::TableWalker::DescriptorBase::global
virtual bool global(WalkerState *currState) const =0
data
const char data[]
Definition: circlebuf.test.cc:42
ArmISA::TableWalker::LongDescriptor::rwTable
uint8_t rwTable() const
R/W protection flag for subsequent levels of lookup.
Definition: table_walker.hh:659
ArmISA::ArmFault::VmsaTran
@ VmsaTran
Definition: faults.hh:149
ArmISA::TableWalker::doL0LongDescriptorWrapper
void doL0LongDescriptorWrapper()
Definition: table_walker.cc:1978
ArmISA::TableWalker::DescriptorBase::shareable
virtual bool shareable() const
Definition: table_walker.hh:86
ArmISA::TableWalker::testWalk
Fault testWalk(Addr pa, Addr size, TlbEntry::DomainType domain, LookupLevel lookup_level)
Definition: table_walker.cc:2253
ArmISA::TableWalker::processWalkLPAE
Fault processWalkLPAE()
Definition: table_walker.cc:578
ArmISA::TLB::lookup
TlbEntry * lookup(Addr vpn, uint16_t asn, uint8_t vmid, bool hyp, bool secure, bool functional, bool ignore_asn, ExceptionLevel target_el, bool in_host)
Lookup an entry in the TLB.
Definition: tlb.cc:159
ArmSystem::physAddrRange
uint8_t physAddrRange() const
Returns the supported physical address range in bits.
Definition: system.hh:251
ArmISA::byteOrder
ByteOrder byteOrder(const ThreadContext *tc)
Definition: utility.hh:449
ArmISA::TLB::ArmTranslationType
ArmTranslationType
Definition: tlb.hh:118
ArmISA::TableWalker::_haveLPAE
bool _haveLPAE
Definition: table_walker.hh:855
ArmISA::TableWalker::WalkerState::req
RequestPtr req
Request that is currently being serviced.
Definition: table_walker.hh:704
warn_once
#define warn_once(...)
Definition: logging.hh:243
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
ArmISA::MISCREG_VTCR
@ MISCREG_VTCR
Definition: miscregs.hh:258
ArmISA::EL0
@ EL0
Definition: types.hh:622
ArmISA::TableWalker::sctlr
SCTLR sctlr
Cached copy of the sctlr as it existed when translation began.
Definition: table_walker.hh:842
ArmISA::TableWalker::DescriptorBase::lookupLevel
LookupLevel lookupLevel
Current lookup level for this descriptor.
Definition: table_walker.hh:71
ArmISA::TableWalker::WalkerState::userTable
bool userTable
Definition: table_walker.hh:763
ArmISA::TableWalker::stage2Mmu
Stage2MMU * stage2Mmu
The MMU to forward second stage look upts to.
Definition: table_walker.hh:827
ArmISA::TableWalker::DescriptorBase::dbgHeader
virtual std::string dbgHeader() const =0
Flags< FlagsType >
ArmISA::snsBankedIndex
int snsBankedIndex(MiscRegIndex reg, ThreadContext *tc)
Definition: miscregs.cc:1311
ArmISA::TableWalker::isStage2
const bool isStage2
Indicates whether this table walker is part of the stage 2 mmu.
Definition: table_walker.hh:836
ArmISA::TableWalker::LongDescriptor::nextDescAddr
Addr nextDescAddr(Addr va) const
Return the address of the next descriptor.
Definition: table_walker.hh:508
ArmISA::TableWalker::doLongDescriptorWrapper
void doLongDescriptorWrapper(LookupLevel curr_lookup_level)
Definition: table_walker.cc:2002
ArmISA::MISCREG_TTBR0_EL1
@ MISCREG_TTBR0_EL1
Definition: miscregs.hh:589
ArmISA::TableWalker::numSquashable
unsigned numSquashable
The number of walks belonging to squashed instructions that can be removed from the pendingQueue per ...
Definition: table_walker.hh:851
ArmISA::TableWalker::WalkerState::physAddrRange
int physAddrRange
Current physical address range in bits.
Definition: table_walker.hh:701
ArmISA::ArmFault::FaultSourceInvalid
@ FaultSourceInvalid
Definition: faults.hh:116
ArmISA::MISCREG_VTTBR_EL2
@ MISCREG_VTTBR_EL2
Definition: miscregs.hh:597
ArmISA::TableWalker::WalkerState::tc
ThreadContext * tc
Thread context that we're doing the walk for.
Definition: table_walker.hh:692
ArmISA::te
Bitfield< 30 > te
Definition: miscregs_types.hh:334
ArmISA::TableWalker::params
const Params * params() const
Definition: table_walker.hh:889
BaseTLB::Mode
Mode
Definition: tlb.hh:57
ArmISA::TableWalker::DescriptorBase::xn
virtual bool xn() const =0
MemCmd::ReadReq
@ ReadReq
Definition: packet.hh:82
Stats::DataWrapVec2d::ysubname
Derived & ysubname(off_type index, const std::string &subname)
Definition: statistics.hh:461
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:63
ArmISA::TableWalker::WalkerState::vmid
uint8_t vmid
Definition: table_walker.hh:708
ArmISA::TableWalker::_haveVirtualization
bool _haveVirtualization
Definition: table_walker.hh:856
ArmISA::TableWalker::processWalk
Fault processWalk()
Definition: table_walker.cc:469
PortID
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:237
ArmISA::TableWalker::doProcessEvent
EventFunctionWrapper doProcessEvent
Definition: table_walker.hh:965
ArmISA::TableWalker::ReservedGrain
@ ReservedGrain
Definition: table_walker.hh:371
ArmISA::TableWalker::WalkerState
Definition: table_walker.hh:688
RequestPtr
std::shared_ptr< Request > RequestPtr
Definition: request.hh:82
ArmISA::TableWalker::WalkerState::startTime
Tick startTime
Timestamp for calculating elapsed time in service (for stats)
Definition: table_walker.hh:802
ArmISA::decodePhysAddrRange64
int decodePhysAddrRange64(uint8_t pa_enc)
Returns the n.
Definition: utility.cc:1381
ArmISA::TableWalker::LongDescriptor::Table
@ Table
Definition: table_walker.hh:380
ArmISA::TableWalker::WalkerState::hcr
HCR hcr
Cached copy of the htcr as it existed when translation began.
Definition: table_walker.hh:742
ArmISA::Stage2MMU::Stage2Translation::fault
Fault fault
Definition: stage2_mmu.hh:79
ArmISA::TableWalker::memAttrs
void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr, uint8_t texcb, bool s)
Definition: table_walker.cc:1105
ArmISA::TableWalker::pageSizeNtoStatBin
static uint8_t pageSizeNtoStatBin(uint8_t N)
Definition: table_walker.cc:2262
ArmISA::TableWalker::TableWalkerStats::walksLongDescriptor
Stats::Scalar walksLongDescriptor
Definition: table_walker.hh:865
tlb.hh
ArmISA::EL3
@ EL3
Definition: types.hh:625
ArmISA::TableWalker::L1Descriptor::type
EntryType type() const
Definition: table_walker.hh:130
FullSystem
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:132
ArmISA::TableWalker::LongDescriptor::pxnTable
bool pxnTable() const
Is privileged execution allowed on subsequent lookup levels?
Definition: table_walker.hh:681
ArmISA::TableWalker::doL2DescriptorWrapper
void doL2DescriptorWrapper()
Definition: table_walker.cc:1937
ArmISA::MISCREG_TCR_EL2
@ MISCREG_TCR_EL2
Definition: miscregs.hh:596
RequestPort::sendFunctional
void sendFunctional(PacketPtr pkt) const
Send a functional request packet, where the data is instantly updated everywhere in the memory system...
Definition: port.hh:482
ArmISA::TableWalker::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: table_walker.cc:108
ArmISA::TableWalker::L1Descriptor::domain
TlbEntry::DomainType domain() const
Domain Client/Manager: ARM DDI 0406B: B3-31.
Definition: table_walker.hh:184
mbits
T mbits(T val, int first, int last)
Mask off the given bits in place like bits() but without shifting.
Definition: bitfield.hh:104
ArmISA::Stage2MMU::Stage2Translation
This translation class is used to trigger the data fetch once a timing translation returns the transl...
Definition: stage2_mmu.hh:68
stage2_mmu.hh
ArmISA::TableWalker::LongDescriptor::type
EntryType type() const
Return the descriptor type.
Definition: table_walker.hh:427
ArmISA::TlbEntry::MemoryType::Device
@ Device
system.hh
ArmISA::TableWalker::REQUESTED
static const unsigned REQUESTED
Definition: table_walker.hh:880
ArmISA::ArmFault::FaultSource
FaultSource
Generic fault source enums used to index into {short/long/aarch64}DescFaultSources[] to get the actua...
Definition: faults.hh:91
ArmISA::Stage2MMU
Definition: stage2_mmu.hh:50
ArmISA::TableWalker::L1Descriptor::ap
uint8_t ap() const
Three bit access protection flags.
Definition: table_walker.hh:178
table_walker.hh
ArmISA::TableWalker::DescriptorBase::offsetBits
virtual uint8_t offsetBits() const =0
ArmISA::TableWalker::LongDescriptor::userTable
uint8_t userTable() const
User/privileged mode protection flag for subsequent levels of lookup.
Definition: table_walker.hh:667
ArmISA::TableWalker::pendingChangeTick
Tick pendingChangeTick
Definition: table_walker.hh:878
ArmISA::MISCREG_HTTBR
@ MISCREG_HTTBR
Definition: miscregs.hh:441
ArmISA::TableWalker::WalkerState::tableWalker
TableWalker * tableWalker
Definition: table_walker.hh:799
ArmISA::TableWalker::WalkerState::isWrite
bool isWrite
If the access is a write.
Definition: table_walker.hh:748
ArmISA
Definition: ccregs.hh:41
ArmISA::MISCREG_TCR_EL3
@ MISCREG_TCR_EL3
Definition: miscregs.hh:602
ContextSwitchTaskId::DMA
@ DMA
Definition: request.hh:74
X86ISA::reg
Bitfield< 5, 3 > reg
Definition: types.hh:87
ArmISA::TableWalker::LongDescriptor::ap
uint8_t ap() const
2-bit access protection flags
Definition: table_walker.hh:580
ArmSystem::haveVirtualization
bool haveVirtualization() const
Returns true if this system implements the virtualization Extensions.
Definition: system.hh:170
ArmISA::TableWalker::WalkerState::isSecure
bool isSecure
If the access comes from the secure state.
Definition: table_walker.hh:754
ArmISA::TableWalker::nextWalk
void nextWalk(ThreadContext *tc)
Definition: table_walker.cc:2058
ArmISA::TableWalker::L2Descriptor::invalid
bool invalid() const
Is the entry invalid.
Definition: table_walker.hh:291
BaseTLB
Definition: tlb.hh:50
ArmISA::TableWalker::WalkerState::l1Desc
L1Descriptor l1Desc
Short-format descriptors.
Definition: table_walker.hh:789
ArmISA::TableWalker::L1Descriptor::data
uint32_t data
The raw bits of the entry.
Definition: table_walker.hh:103
ArmISA::TlbEntry::DomainType::Client
@ Client
ArmISA::L0
@ L0
Definition: pagetable.hh:73
ArmISA::TableWalker::WalkerState::timing
bool timing
If the mode is timing or atomic.
Definition: table_walker.hh:777
ClockedObject
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
Definition: clocked_object.hh:231
ArmISA::TableWalker::TableWalkerStats::pageSizes
Stats::Vector pageSizes
Definition: table_walker.hh:873
ArmISA::TableWalker::WalkerState::longDesc
LongDescriptor longDesc
Long-format descriptor (LPAE and AArch64)
Definition: table_walker.hh:793
ArmISA::TableWalker::WalkerState::secureLookup
bool secureLookup
Helper variables used to implement hierarchical access permissions when the long-desc.
Definition: table_walker.hh:761
ArmISA::ELIs64
bool ELIs64(ThreadContext *tc, ExceptionLevel el)
Definition: utility.cc:377
Stats::DataWrap::flags
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:331
DrainState::Drained
@ Drained
Buffers drained, ready for serialization/handover.
ArmISA::aarch64
Bitfield< 34 > aarch64
Definition: types.hh:90
ArmISA::TableWalker::DescriptorBase::pfn
virtual Addr pfn() const =0
ArmISA::TableWalker::toLookupLevel
static LookupLevel toLookupLevel(uint8_t lookup_level_as_int)
Definition: table_walker.cc:2220
ArmISA::TableWalker::WalkerState::stage2Tran
TLB::Translation * stage2Tran
A pointer to the stage 2 translation that's in progress.
Definition: table_walker.hh:774
ArmISA::TableWalker::L1Descriptor::Section
@ Section
Definition: table_walker.hh:98
ArmISA::TableWalker::processWalkAArch64
Fault processWalkAArch64()
Definition: table_walker.cc:767
ArmISA::TableWalker::LongDescriptor::Block
@ Block
Definition: table_walker.hh:381
DrainState
DrainState
Object drain/handover states.
Definition: drain.hh:71
ArmISA::n
Bitfield< 31 > n
Definition: miscregs_types.hh:450
RequestorID
uint16_t RequestorID
Definition: request.hh:85
ArmISA::TableWalker::requestorId
RequestorID requestorId
Requestor id assigned by the MMU.
Definition: table_walker.hh:833
ArmISA::TableWalker::doL3LongDescriptorWrapper
void doL3LongDescriptorWrapper()
Definition: table_walker.cc:1996
ArmISA::TableWalker::L2Descriptor::ap
uint8_t ap() const
Three bit access protection flags.
Definition: table_walker.hh:315
ArmISA::TableWalker::LongDescriptor::data
uint64_t data
The raw bits of the entry.
Definition: table_walker.hh:388
dma_device.hh
EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1005
ArmISA::TableWalker::WalkerState::aarch64
bool aarch64
If the access is performed in AArch64 state.
Definition: table_walker.hh:695
ArmISA::ArmFault::LpaeTran
@ LpaeTran
Definition: faults.hh:148
ArmISA::TableWalker::LongDescriptor::attrIndx
uint8_t attrIndx() const
Attribute index.
Definition: table_walker.hh:617
Request::SECURE
@ SECURE
The request targets the secure memory space.
Definition: request.hh:173
ArmSystem::haveSecurity
bool haveSecurity() const
Returns true if this system implements the Security Extensions.
Definition: system.hh:161
ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
ArmISA::TableWalker::fetchDescriptor
bool fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes, Request::Flags flags, int queueIndex, Event *event, void(TableWalker::*doDescriptor)())
Definition: table_walker.cc:2067
ArmSystem::haveLPAE
bool haveLPAE() const
Returns true if this system implements the Large Physical Address Extension.
Definition: system.hh:165
Event
Definition: eventq.hh:246
ArmISA::TableWalker::DescriptorBase::getRawData
virtual uint64_t getRawData() const =0
SimObject::getPort
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Definition: sim_object.cc:123
ArmISA::TableWalker::TableWalkerStats::walks
Stats::Scalar walks
Definition: table_walker.hh:863
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
ArmISA::MISCREG_HCR
@ MISCREG_HCR
Definition: miscregs.hh:242
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:67
ArmISA::ArmFault::TranslationLL
@ TranslationLL
Definition: faults.hh:97
ArmISA::L1
@ L1
Definition: pagetable.hh:74
ArmISA::TlbEntry::MemoryType::StronglyOrdered
@ StronglyOrdered
ArmISA::ExceptionLevel
ExceptionLevel
Definition: types.hh:621
ArmISA::TableWalker::L1Descriptor::Reserved
@ Reserved
Definition: table_walker.hh:99
Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:240
MipsISA::vaddr
vaddr
Definition: pra_constants.hh:275
ArmISA::TableWalker::WalkerState::xnTable
bool xnTable
Definition: table_walker.hh:764
MipsISA::event
Bitfield< 10, 5 > event
Definition: pra_constants.hh:297
ArmISA::TableWalker::stats
ArmISA::TableWalker::TableWalkerStats stats
htog
T htog(T value, ByteOrder guest_byte_order)
Definition: byteswap.hh:155
ArmISA::ArmFault::AddressSizeLL
@ AddressSizeLL
Definition: faults.hh:107
ArmISA::MaxPhysAddrRange
const unsigned MaxPhysAddrRange
Definition: pagetable.hh:54
ArmISA::TableWalker::haveSecurity
bool haveSecurity
Cached copies of system-level properties.
Definition: table_walker.hh:854
ArmISA::TableWalker::stateQueues
std::list< WalkerState * > stateQueues[MAX_LOOKUP_LEVELS]
Queues of requests for all the different lookup levels.
Definition: table_walker.hh:820
Port
Ports are used to interface objects to each other.
Definition: port.hh:56
ArmISA::TableWalker::LongDescriptor::secureTable
bool secureTable() const
Whether the subsequent levels of lookup are secure.
Definition: table_walker.hh:645
ArmISA::TableWalker::Grain64KB
@ Grain64KB
Definition: table_walker.hh:370
ArmISA::TableWalker::L1Descriptor::Ignore
@ Ignore
Definition: table_walker.hh:96
ArmISA::TableWalker::Grain16KB
@ Grain16KB
Definition: table_walker.hh:369
ArmISA::MISCREG_TCR_EL1
@ MISCREG_TCR_EL1
Definition: miscregs.hh:593
Clocked::clockEdge
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Definition: clocked_object.hh:174
ArmISA::mode
Bitfield< 4, 0 > mode
Definition: miscregs_types.hh:70
ArmISA::TableWalker::physAddrRange
uint8_t physAddrRange
Definition: table_walker.hh:857
ArmISA::TableWalker::WalkerState::rwTable
bool rwTable
Definition: table_walker.hh:762
ArmISA::el
Bitfield< 3, 2 > el
Definition: miscregs_types.hh:69
ArmISA::MISCREG_TTBCR
@ MISCREG_TTBCR
Definition: miscregs.hh:254
ArmISA::TableWalker::DescriptorBase
Definition: table_walker.hh:66
ArmISA::TableWalker::LongDescriptor::memAttr
uint8_t memAttr() const
Memory attributes, only used by stage 2 translations.
Definition: table_walker.hh:624
ArmISA::attr
attr
Definition: miscregs_types.hh:649
ArmISA::TableWalker::pendingChange
void pendingChange()
Definition: table_walker.cc:2237
ArmISA::TableWalker::Params
ArmTableWalkerParams Params
Definition: table_walker.hh:884
BaseTLB::Translation
Definition: tlb.hh:59
Drainable::signalDrainDone
void signalDrainDone() const
Signal that an object is drained.
Definition: drain.hh:301
M5_FALLTHROUGH
#define M5_FALLTHROUGH
Definition: compiler.hh:84
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:1434
Flags::set
void set(Type flags)
Definition: flags.hh:87
ArmISA::TableWalker::TableWalker
TableWalker(const Params *p)
Definition: table_walker.cc:56
ArmISA::MISCREG_TTBR0_EL2
@ MISCREG_TTBR0_EL2
Definition: miscregs.hh:595
ArmISA::TableWalker::WalkerState::vtcr
VTCR_t vtcr
Cached copy of the vtcr as it existed when translation began.
Definition: table_walker.hh:745
ArmISA::TableWalker::checkAddrSizeFaultAArch64
static bool checkAddrSizeFaultAArch64(Addr addr, int currPhysAddrRange)
Returns true if the address exceeds the range permitted by the system-wide setting or by the TCR_ELx ...
Definition: table_walker.cc:760
ArmISA::TableWalker::getPort
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Definition: table_walker.cc:116
ArmISA::TableWalker::doL2LongDescriptorWrapper
void doL2LongDescriptorWrapper()
Definition: table_walker.cc:1990
Request::UNCACHEABLE
@ UNCACHEABLE
The request is to an uncacheable address.
Definition: request.hh:114
ArmISA::TableWalker::LongDescriptor::aarch64
bool aarch64
True if the current lookup is performed in AArch64 state.
Definition: table_walker.hh:421
ArmISA::TableWalker::WalkerState::delayed
bool delayed
Whether the response is delayed in timing mode due to additional lookups.
Definition: table_walker.hh:797
ArmISA::s1TranslationRegime
ExceptionLevel s1TranslationRegime(ThreadContext *tc, ExceptionLevel el)
Definition: utility.cc:333
ArmISA::L2
@ L2
Definition: pagetable.hh:75
ArmISA::longDescFormatInUse
bool longDescFormatInUse(ThreadContext *tc)
Definition: utility.cc:229
ArmISA::TableWalker::port
DmaPort * port
Port shared by the two table walkers.
Definition: table_walker.hh:830
ArmISA::MISCREG_VSTTBR_EL2
@ MISCREG_VSTTBR_EL2
Definition: miscregs.hh:599
ArmISA::TableWalker::LongDescriptor::Page
@ Page
Definition: table_walker.hh:382
ArmISA::MISCREG_TTBR0_EL3
@ MISCREG_TTBR0_EL3
Definition: miscregs.hh:601
ArmISA::TableWalker::L2Descriptor::data
uint32_t data
The raw bits of the entry.
Definition: table_walker.hh:246
faults.hh
ArmISA::MISCREG_HCR_EL2
@ MISCREG_HCR_EL2
Definition: miscregs.hh:578
NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:245
ArmISA::MISCREG_TTBR1_EL1
@ MISCREG_TTBR1_EL1
Definition: miscregs.hh:591
ArmISA::TableWalker::DescriptorBase::ap
virtual uint8_t ap() const =0
ArmISA::TLB::testWalk
Fault testWalk(Addr pa, Addr size, Addr va, bool is_secure, Mode mode, TlbEntry::DomainType domain, LookupLevel lookup_level)
Definition: tlb.cc:1630
ArmISA::EL1
@ EL1
Definition: types.hh:623
ProbePoints::Packet
ProbePointArg< PacketInfo > Packet
Packet probe point.
Definition: mem.hh:103
ArmISA::TableWalker::LongDescEventByLevel
Event * LongDescEventByLevel[4]
Definition: table_walker.hh:947
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
ArmISA::ArmFault::AccessFlagLL
@ AccessFlagLL
Definition: faults.hh:98
ArmISA::TableWalker::TableWalkerStats::walkServiceTime
Stats::Histogram walkServiceTime
Definition: table_walker.hh:871
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:558
ArmISA::TableWalker::TableWalkerStats::walksLongTerminatedAtLevel
Stats::Vector walksLongTerminatedAtLevel
Definition: table_walker.hh:867
Stats::dist
const FlagsType dist
Print the distribution.
Definition: info.hh:55
name
const std::string & name()
Definition: trace.cc:50
Stats::VectorBase::init
Derived & init(size_type size)
Set this vector to have the given size.
Definition: statistics.hh:1177
Request
Definition: request.hh:87
ArmISA::TableWalker::WalkerState::isFetch
bool isFetch
If the access is a fetch (for execution, and no-exec) must be checked?
Definition: table_walker.hh:751
DmaPort::dmaAction
RequestPtr dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, uint8_t *data, Tick delay, Request::Flags flag=0)
Definition: dma_device.cc:197
ArmISA::TableWalker::TableWalkerStats::walksShortTerminatedAtLevel
Stats::Vector walksShortTerminatedAtLevel
Definition: table_walker.hh:866
ArmISA::TableWalker::generateLongDescFault
Fault generateLongDescFault(ArmFault::FaultSource src)
Definition: table_walker.cc:1643
ArmISA::TableWalker::LongDescriptor::offsetBits
uint8_t offsetBits() const
Return the bit width of the page/block offset.
Definition: table_walker.hh:444
ArmISA::TableWalker::memAttrsLPAE
void memAttrsLPAE(ThreadContext *tc, TlbEntry &te, LongDescriptor &lDescriptor)
Definition: table_walker.cc:1312
ArmISA::TableWalker::WalkerState::htcr
HTCR htcr
Cached copy of the htcr as it existed when translation began.
Definition: table_walker.hh:739
Stats::nozero
const FlagsType nozero
Don't print if this is zero.
Definition: info.hh:57
ArmISA::MISCREG_NMRR
@ MISCREG_NMRR
Definition: miscregs.hh:369
ArmISA::MISCREG_TTBR1
@ MISCREG_TTBR1
Definition: miscregs.hh:251
Drainable::drainState
DrainState drainState() const
Return the current drain state of an object.
Definition: drain.hh:320
ArmISA::asid
asid
Definition: miscregs_types.hh:611
ArmISA::TableWalker::completeDrain
void completeDrain()
Checks if all state is cleared and if so, completes drain.
Definition: table_walker.cc:145
ArmISA::TLB
Definition: tlb.hh:100
BaseTLB::Write
@ Write
Definition: tlb.hh:57
ArmISA::TableWalker::WalkerState::hpd
bool hpd
Hierarchical access permission disable.
Definition: table_walker.hh:768
ArmISA::MISCREG_PRRR
@ MISCREG_PRRR
Definition: miscregs.hh:363
ArmISA::TableWalker::drain
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
Definition: table_walker.cc:158
ArmSystem
Definition: system.hh:59
ArmISA::TableWalker::WalkerState::vaddr_tainted
Addr vaddr_tainted
The virtual address that is being translated.
Definition: table_walker.hh:721
ArmISA::TableWalker::WalkerState::vaddr
Addr vaddr
The virtual address that is being translated with tagging removed.
Definition: table_walker.hh:718
ArmISA::TableWalker::setMMU
void setMMU(Stage2MMU *m, RequestorID requestor_id)
Definition: table_walker.cc:100
warn_if
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
Definition: logging.hh:263
ArmISA::TableWalker::doL1DescriptorWrapper
void doL1DescriptorWrapper()
Definition: table_walker.cc:1881
panic_if
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:197
ArmISA::TlbEntry::DomainType
DomainType
Definition: pagetable.hh:90
ArmISA::TlbEntry
Definition: pagetable.hh:81
ArmISA::MISCREG_MAIR1
@ MISCREG_MAIR1
Definition: miscregs.hh:372
ArmISA::TableWalker::pendingReqs
unsigned pendingReqs
Definition: table_walker.hh:877
ArmISA::MISCREG_CPSR
@ MISCREG_CPSR
Definition: miscregs.hh:57
Request::PT_WALK
@ PT_WALK
The request is a page table walk.
Definition: request.hh:175
ArmISA::TableWalker::tlb
TLB * tlb
TLB that is initiating these table walks.
Definition: table_walker.hh:839
ArmISA::TableWalker::LongDescriptor::sh
uint8_t sh() const
2-bit shareability field
Definition: table_walker.hh:573
base.hh
ArmISA::TableWalker::TableWalkerStats::requestOrigin
Stats::Vector2d requestOrigin
Definition: table_walker.hh:874
ArmISA::TableWalker::Grain4KB
@ Grain4KB
Definition: table_walker.hh:368
ArmISA::TableWalker::WalkerState::isUncacheable
bool isUncacheable
True if table walks are uncacheable (for table descriptors)
Definition: table_walker.hh:757
ArmISA::domain
Bitfield< 7, 4 > domain
Definition: miscregs_types.hh:418
Packet::dataStatic
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
Definition: packet.hh:1107
Stats::pdf
const FlagsType pdf
Print the percent of the total that this entry represents.
Definition: info.hh:51
ArmISA::TableWalker::pendingQueue
std::list< WalkerState * > pendingQueue
Queue of requests that have passed are waiting because the walker is currently busy.
Definition: table_walker.hh:824
ArmISA::Stage2MMU::readDataTimed
void readDataTimed(ThreadContext *tc, Addr descAddr, Stage2Translation *translation, int numBytes, Request::Flags flags)
Definition: stage2_mmu.cc:100
ArmISA::MISCREG_MAIR_EL2
@ MISCREG_MAIR_EL2
Definition: miscregs.hh:722
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:257
Stats::Group
Statistics container.
Definition: group.hh:83
ThreadContext::readMiscReg
virtual RegVal readMiscReg(RegIndex misc_reg)=0
ArmISA::MISCREG_VSTCR_EL2
@ MISCREG_VSTCR_EL2
Definition: miscregs.hh:600
ArmISA::TableWalker::DescriptorBase::domain
virtual TlbEntry::DomainType domain() const =0
ArmISA::MiscRegIndex
MiscRegIndex
Definition: miscregs.hh:56
addr
ip6_addr_t addr
Definition: inet.hh:423
ArmISA::TableWalker::LongDescriptor::Invalid
@ Invalid
Definition: table_walker.hh:379
ArmISA::TableWalker::LongDescriptor::xn
bool xn() const
Is execution allowed on this mapping?
Definition: table_walker.hh:527
ArmISA::Stage2MMU::readDataUntimed
Fault readDataUntimed(ThreadContext *tc, Addr oVAddr, Addr descAddr, uint8_t *data, int numBytes, Request::Flags flags, bool isFunctional)
Definition: stage2_mmu.cc:62
ArmISA::MISCREG_HTCR
@ MISCREG_HTCR
Definition: miscregs.hh:257
ArmISA::TableWalker::adjustTableSizeAArch64
static unsigned adjustTableSizeAArch64(unsigned tsz)
Definition: table_walker.cc:750
Stats::Vector2dBase::init
Derived & init(size_type _x, size_type _y)
Definition: statistics.hh:1313
ArmISA::stride
Bitfield< 21, 20 > stride
Definition: miscregs_types.hh:441
Stats::DistBase::sample
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
Definition: statistics.hh:1924
ArmISA::MAX_LOOKUP_LEVELS
@ MAX_LOOKUP_LEVELS
Definition: pagetable.hh:77
Cycles
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:83
ArmISA::hpd
Bitfield< 24 > hpd
Definition: miscregs_types.hh:528
ArmISA::TableWalker::WalkerState::sctlr
SCTLR sctlr
Cached copy of the sctlr as it existed when translation began.
Definition: table_walker.hh:724
Stats::DataWrapVec::subname
Derived & subname(off_type index, const std::string &name)
Set the subfield name for the given index, and marks this stat to print at the end of simulation.
Definition: statistics.hh:374
ArmISA::TableWalker::COMPLETED
static const unsigned COMPLETED
Definition: table_walker.hh:881
ArmISA::TableWalker
Definition: table_walker.hh:61
ArmISA::MISCREG_MAIR0
@ MISCREG_MAIR0
Definition: miscregs.hh:366
Stats
Definition: statistics.cc:61
ArmISA::MISCREG_MAIR_EL3
@ MISCREG_MAIR_EL3
Definition: miscregs.hh:724
ArmISA::TableWalker::doL1LongDescriptorWrapper
void doL1LongDescriptorWrapper()
Definition: table_walker.cc:1984
ArmISA::MISCREG_MAIR_EL1
@ MISCREG_MAIR_EL1
Definition: miscregs.hh:718
ArmISA::TableWalker::LongDescriptor::xnTable
bool xnTable() const
Is execution allowed on subsequent lookup levels?
Definition: table_walker.hh:674
ArmISA::TableWalker::doL1DescEvent
EventFunctionWrapper doL1DescEvent
Definition: table_walker.hh:929
ArmISA::TableWalker::WalkerState::WalkerState
WalkerState()
Definition: table_walker.cc:128
ArmISA::TableWalker::LongDescriptor::pxn
bool pxn() const
Is privileged execution allowed on this mapping? (LPAE only)
Definition: table_walker.hh:534
ArmISA::TlbEntry::MemoryType::Normal
@ Normal
ArmISA::MISCREG_VTCR_EL2
@ MISCREG_VTCR_EL2
Definition: miscregs.hh:598
ArmISA::MISCREG_TTBR1_EL2
@ MISCREG_TTBR1_EL2
Definition: miscregs.hh:812
ArmISA::TableWalker::doL2DescEvent
EventFunctionWrapper doL2DescEvent
Definition: table_walker.hh:933
ArmISA::MISCREG_SCTLR
@ MISCREG_SCTLR
Definition: miscregs.hh:229
Stats::Histogram::init
Histogram & init(size_type size)
Set the parameters of this histogram.
Definition: statistics.hh:2669
ArmISA::pa
Bitfield< 39, 12 > pa
Definition: miscregs_types.hh:650
ArmISA::TableWalker::currState
WalkerState * currState
Definition: table_walker.hh:844
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
ArmISA::TableWalker::~TableWalker
virtual ~TableWalker()
Definition: table_walker.cc:94
ArmISA::TableWalker::doLongDescriptor
void doLongDescriptor()
Definition: table_walker.cc:1663
ArmISA::TableWalker::processWalkWrapper
void processWalkWrapper()
Definition: table_walker.cc:378
ArmISA::ps
Bitfield< 18, 16 > ps
Definition: miscregs_types.hh:508
ArmISA::TableWalker::LongDescriptor
Long-descriptor format (LPAE)
Definition: table_walker.hh:375
ArmISA::s
Bitfield< 4 > s
Definition: miscregs_types.hh:556
ArmISA::TableWalker::WalkerState::transState
TLB::Translation * transState
Translation state for delayed requests.
Definition: table_walker.hh:712
ArmISA::MISCREG_SCTLR_EL3
@ MISCREG_SCTLR_EL3
Definition: miscregs.hh:583
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:219
Stats::total
const FlagsType total
Print the total.
Definition: info.hh:49
ArmISA::TableWalker::WalkerState::fault
Fault fault
The fault that we are going to return.
Definition: table_walker.hh:715
BaseTLB::Execute
@ Execute
Definition: tlb.hh:57
ArmISA::TableWalker::WalkerState::ttbcr
TTBCR ttbcr
Definition: table_walker.hh:734
ArmISA::TableWalker::TableWalkerStats::squashedAfter
Stats::Scalar squashedAfter
Definition: table_walker.hh:869
ArmISA::TableWalker::WalkerState::l2Desc
L2Descriptor l2Desc
Definition: table_walker.hh:790
ThreadContext::getCpuPtr
virtual BaseCPU * getCpuPtr()=0
ArmISA::tlb
Bitfield< 59, 56 > tlb
Definition: miscregs_types.hh:88
ArmISA::TableWalker::TableWalkerStats::squashedBefore
Stats::Scalar squashedBefore
Definition: table_walker.hh:868
ArmISA::MISCREG_SCTLR_EL2
@ MISCREG_SCTLR_EL2
Definition: miscregs.hh:576
ArmISA::TableWalker::DescriptorBase::texcb
virtual uint8_t texcb() const
Definition: table_walker.hh:82
ArmISA::TlbEntry::DomainType::NoAccess
@ NoAccess
ArmISA::MISCREG_VTTBR
@ MISCREG_VTTBR
Definition: miscregs.hh:442
thread_context.hh
ArmISA::TLB::translateTiming
void translateTiming(const RequestPtr &req, ThreadContext *tc, Translation *translation, Mode mode, ArmTranslationType tranType)
Definition: tlb.cc:1205
ULL
#define ULL(N)
uint64_t constant
Definition: types.hh:50
Stats::nonan
const FlagsType nonan
Don't print if this is NAN.
Definition: info.hh:59
RegVal
uint64_t RegVal
Definition: types.hh:168
ArmISA::TableWalker::insertTableEntry
void insertTableEntry(DescriptorBase &descriptor, bool longDescriptor)
Definition: table_walker.cc:2139
ArmISA::TableWalker::TableWalkerStats::pendingWalks
Stats::Histogram pendingWalks
Definition: table_walker.hh:872
DrainState::Draining
@ Draining
Draining buffers pending serialization/handover.
ArmISA::mask
Bitfield< 28, 24 > mask
Definition: miscregs_types.hh:711
ArmISA::MISCREG_SCTLR_EL1
@ MISCREG_SCTLR_EL1
Definition: miscregs.hh:571
ArmISA::L3
@ L3
Definition: pagetable.hh:76
ArmISA::isSecure
bool isSecure(ThreadContext *tc)
Definition: utility.cc:174
ArmISA::m
Bitfield< 0 > m
Definition: miscregs_types.hh:389
ArmISA::TableWalker::pending
bool pending
If a timing translation is currently in progress.
Definition: table_walker.hh:847
ArmISA::TableWalker::doL1Descriptor
void doL1Descriptor()
Definition: table_walker.cc:1538
ArmSystem::haveLargeAsid64
bool haveLargeAsid64() const
Returns true if ASID is 16 bits in AArch64 (ARMv8)
Definition: system.hh:223
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
ArmISA::f
Bitfield< 6 > f
Definition: miscregs_types.hh:64
ArmISA::TableWalker::GrainSize
GrainSize
Definition: table_walker.hh:367
curTick
Tick curTick()
The current simulated tick.
Definition: core.hh:45
bits
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:75
ArmISA::TLB::insert
void insert(Addr vaddr, TlbEntry &pte)
Definition: tlb.cc:204
ArmISA::TableWalker::L1Descriptor::PageTable
@ PageTable
Definition: table_walker.hh:97

Generated on Wed Sep 30 2020 14:02:01 for gem5 by doxygen 1.8.17