gem5  v21.0.1.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 = 48;
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 GiB
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 GiB
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 bool
751  GrainSize tg, int tsz, bool low_range)
752 {
753  // The effective maximum input size is 48 if ARMv8.2-LVA is not
754  // supported or if the translation granule that is in use is 4KB or
755  // 16KB in size. When ARMv8.2-LVA is supported, for the 64KB
756  // translation granule size only, the effective minimum value of
757  // 52.
758  int in_max = (HaveLVA(currState->tc) && tg == Grain64KB) ? 52 : 48;
759  int in_min = 64 - (tg == Grain64KB ? 47 : 48);
760 
761  return tsz > in_max || tsz < in_min || (low_range ?
762  bits(currState->vaddr, top_bit, tsz) != 0x0 :
763  bits(currState->vaddr, top_bit, tsz) != mask(top_bit - tsz + 1));
764 }
765 
766 bool
768 {
769  return (pa_range != _physAddrRange &&
770  bits(addr, _physAddrRange - 1, pa_range));
771 }
772 
773 Fault
775 {
776  assert(currState->aarch64);
777 
778  DPRINTF(TLB, "Beginning table walk for address %#llx, TCR: %#llx\n",
780 
781  static const GrainSize GrainMap_tg0[] =
783  static const GrainSize GrainMap_tg1[] =
785 
787 
788  // Determine TTBR, table size, granule size and phys. address range
789  Addr ttbr = 0;
790  int tsz = 0, ps = 0;
791  GrainSize tg = Grain4KB; // grain size computed from tg* field
792  bool fault = false;
793 
794  int top_bit = computeAddrTop(currState->tc,
795  bits(currState->vaddr, 55),
797  currState->tcr,
798  currState->el);
799 
800  LookupLevel start_lookup_level = MAX_LOOKUP_LEVELS;
801  bool vaddr_fault = false;
802  switch (currState->el) {
803  case EL0:
804  {
805  Addr ttbr0;
806  Addr ttbr1;
807  if (HaveVirtHostExt(currState->tc) &&
808  currState->hcr.tge==1 && currState->hcr.e2h == 1) {
809  // VHE code for EL2&0 regime
812  } else {
815  }
816  switch (bits(currState->vaddr, 63,48)) {
817  case 0:
818  DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n");
819  ttbr = ttbr0;
820  tsz = 64 - currState->tcr.t0sz;
821  tg = GrainMap_tg0[currState->tcr.tg0];
822  currState->hpd = currState->tcr.hpd0;
823  currState->isUncacheable = currState->tcr.irgn0 == 0;
825  top_bit, tg, tsz, true);
826 
827  if (vaddr_fault || currState->tcr.epd0)
828  fault = true;
829  break;
830  case 0xffff:
831  DPRINTF(TLB, " - Selecting TTBR1 (AArch64)\n");
832  ttbr = ttbr1;
833  tsz = 64 - currState->tcr.t1sz;
834  tg = GrainMap_tg1[currState->tcr.tg1];
835  currState->hpd = currState->tcr.hpd1;
836  currState->isUncacheable = currState->tcr.irgn1 == 0;
838  top_bit, tg, tsz, false);
839 
840  if (vaddr_fault || currState->tcr.epd1)
841  fault = true;
842  break;
843  default:
844  // top two bytes must be all 0s or all 1s, else invalid addr
845  fault = true;
846  }
847  ps = currState->tcr.ips;
848  }
849  break;
850  case EL1:
851  if (isStage2) {
852  if (currState->secureLookup) {
853  DPRINTF(TLB, " - Selecting VSTTBR_EL2 (AArch64 stage 2)\n");
855  } else {
856  DPRINTF(TLB, " - Selecting VTTBR_EL2 (AArch64 stage 2)\n");
858  }
859  tsz = 64 - currState->vtcr.t0sz64;
860  tg = GrainMap_tg0[currState->vtcr.tg0];
861  // ARM DDI 0487A.f D7-2148
862  // The starting level of stage 2 translation depends on
863  // VTCR_EL2.SL0 and VTCR_EL2.TG0
864  LookupLevel __ = MAX_LOOKUP_LEVELS; // invalid level
865  uint8_t sl_tg = (currState->vtcr.sl0 << 2) | currState->vtcr.tg0;
866  static const LookupLevel SLL[] = {
867  L2, L3, L3, __, // sl0 == 0
868  L1, L2, L2, __, // sl0 == 1, etc.
869  L0, L1, L1, __,
870  __, __, __, __
871  };
872  start_lookup_level = SLL[sl_tg];
873  panic_if(start_lookup_level == MAX_LOOKUP_LEVELS,
874  "Cannot discern lookup level from vtcr.{sl0,tg0}");
875  ps = currState->vtcr.ps;
876  currState->isUncacheable = currState->vtcr.irgn0 == 0;
877  } else {
878  switch (bits(currState->vaddr, top_bit)) {
879  case 0:
880  DPRINTF(TLB, " - Selecting TTBR0_EL1 (AArch64)\n");
882  tsz = 64 - currState->tcr.t0sz;
883  tg = GrainMap_tg0[currState->tcr.tg0];
884  currState->hpd = currState->tcr.hpd0;
885  currState->isUncacheable = currState->tcr.irgn0 == 0;
887  top_bit, tg, tsz, true);
888 
889  if (vaddr_fault || currState->tcr.epd0)
890  fault = true;
891  break;
892  case 0x1:
893  DPRINTF(TLB, " - Selecting TTBR1_EL1 (AArch64)\n");
895  tsz = 64 - currState->tcr.t1sz;
896  tg = GrainMap_tg1[currState->tcr.tg1];
897  currState->hpd = currState->tcr.hpd1;
898  currState->isUncacheable = currState->tcr.irgn1 == 0;
900  top_bit, tg, tsz, false);
901 
902  if (vaddr_fault || currState->tcr.epd1)
903  fault = true;
904  break;
905  default:
906  // top two bytes must be all 0s or all 1s, else invalid addr
907  fault = true;
908  }
909  ps = currState->tcr.ips;
910  }
911  break;
912  case EL2:
913  switch(bits(currState->vaddr, top_bit)) {
914  case 0:
915  DPRINTF(TLB, " - Selecting TTBR0_EL2 (AArch64)\n");
917  tsz = 64 - currState->tcr.t0sz;
918  tg = GrainMap_tg0[currState->tcr.tg0];
919  currState->hpd = currState->hcr.e2h ?
920  currState->tcr.hpd0 : currState->tcr.hpd;
921  currState->isUncacheable = currState->tcr.irgn0 == 0;
923  top_bit, tg, tsz, true);
924 
925  if (vaddr_fault || (currState->hcr.e2h && currState->tcr.epd0))
926  fault = true;
927  break;
928 
929  case 0x1:
930  DPRINTF(TLB, " - Selecting TTBR1_EL2 (AArch64)\n");
932  tsz = 64 - currState->tcr.t1sz;
933  tg = GrainMap_tg1[currState->tcr.tg1];
934  currState->hpd = currState->tcr.hpd1;
935  currState->isUncacheable = currState->tcr.irgn1 == 0;
937  top_bit, tg, tsz, false);
938 
939  if (vaddr_fault || !currState->hcr.e2h || currState->tcr.epd1)
940  fault = true;
941  break;
942 
943  default:
944  // invalid addr if top two bytes are not all 0s
945  fault = true;
946  }
947  ps = currState->hcr.e2h ? currState->tcr.ips: currState->tcr.ps;
948  break;
949  case EL3:
950  switch(bits(currState->vaddr, top_bit)) {
951  case 0:
952  DPRINTF(TLB, " - Selecting TTBR0_EL3 (AArch64)\n");
954  tsz = 64 - currState->tcr.t0sz;
955  tg = GrainMap_tg0[currState->tcr.tg0];
956  currState->hpd = currState->tcr.hpd;
957  currState->isUncacheable = currState->tcr.irgn0 == 0;
959  top_bit, tg, tsz, true);
960 
961  if (vaddr_fault)
962  fault = true;
963  break;
964  default:
965  // invalid addr if top two bytes are not all 0s
966  fault = true;
967  }
968  ps = currState->tcr.ps;
969  break;
970  }
971 
972  const bool is_atomic = currState->req->isAtomic();
973 
974  if (fault) {
975  Fault f;
976  if (currState->isFetch)
977  f = std::make_shared<PrefetchAbort>(
981  else
982  f = std::make_shared<DataAbort>(
985  is_atomic ? false : currState->isWrite,
988 
989  if (currState->timing) {
990  pending = false;
992  currState = NULL;
993  } else {
994  currState->tc = NULL;
995  currState->req = NULL;
996  }
997  return f;
998 
999  }
1000 
1001  if (tg == ReservedGrain) {
1002  warn_once("Reserved granule size requested; gem5's IMPLEMENTATION "
1003  "DEFINED behavior takes this to mean 4KB granules\n");
1004  tg = Grain4KB;
1005  }
1006 
1007  // Determine starting lookup level
1008  // See aarch64/translation/walk in Appendix G: ARMv8 Pseudocode Library
1009  // in ARM DDI 0487A. These table values correspond to the cascading tests
1010  // to compute the lookup level and are of the form
1011  // (grain_size + N*stride), for N = {1, 2, 3}.
1012  // A value of 64 will never succeed and a value of 0 will always succeed.
1013  if (start_lookup_level == MAX_LOOKUP_LEVELS) {
1014  struct GrainMap {
1015  GrainSize grain_size;
1016  unsigned lookup_level_cutoff[MAX_LOOKUP_LEVELS];
1017  };
1018  static const GrainMap GM[] = {
1019  { Grain4KB, { 39, 30, 0, 0 } },
1020  { Grain16KB, { 47, 36, 25, 0 } },
1021  { Grain64KB, { 64, 42, 29, 0 } }
1022  };
1023 
1024  const unsigned *lookup = NULL; // points to a lookup_level_cutoff
1025 
1026  for (unsigned i = 0; i < 3; ++i) { // choose entry of GM[]
1027  if (tg == GM[i].grain_size) {
1028  lookup = GM[i].lookup_level_cutoff;
1029  break;
1030  }
1031  }
1032  assert(lookup);
1033 
1034  for (int L = L0; L != MAX_LOOKUP_LEVELS; ++L) {
1035  if (tsz > lookup[L]) {
1036  start_lookup_level = (LookupLevel) L;
1037  break;
1038  }
1039  }
1040  panic_if(start_lookup_level == MAX_LOOKUP_LEVELS,
1041  "Table walker couldn't find lookup level\n");
1042  }
1043 
1044  // Clamp to lower limit
1045  int pa_range = decodePhysAddrRange64(ps);
1046  if (pa_range > _physAddrRange) {
1048  } else {
1049  currState->physAddrRange = pa_range;
1050  }
1051 
1052  // Determine table base address
1053  int stride = tg - 3;
1054  int base_addr_lo = 3 + tsz - stride * (3 - start_lookup_level) - tg;
1055  Addr base_addr = 0;
1056 
1057  if (pa_range == 52) {
1058  int z = (base_addr_lo < 6) ? 6 : base_addr_lo;
1059  base_addr = mbits(ttbr, 47, z);
1060  base_addr |= (bits(ttbr, 5, 2) << 48);
1061  } else {
1062  base_addr = mbits(ttbr, 47, base_addr_lo);
1063  }
1064 
1065  // Determine physical address size and raise an Address Size Fault if
1066  // necessary
1068  DPRINTF(TLB, "Address size fault before any lookup\n");
1069  Fault f;
1070  if (currState->isFetch)
1071  f = std::make_shared<PrefetchAbort>(
1073  ArmFault::AddressSizeLL + start_lookup_level,
1074  isStage2,
1076  else
1077  f = std::make_shared<DataAbort>(
1080  is_atomic ? false : currState->isWrite,
1081  ArmFault::AddressSizeLL + start_lookup_level,
1082  isStage2,
1084 
1085 
1086  if (currState->timing) {
1087  pending = false;
1088  nextWalk(currState->tc);
1089  currState = NULL;
1090  } else {
1091  currState->tc = NULL;
1092  currState->req = NULL;
1093  }
1094  return f;
1095 
1096  }
1097 
1098  // Determine descriptor address
1099  Addr desc_addr = base_addr |
1100  (bits(currState->vaddr, tsz - 1,
1101  stride * (3 - start_lookup_level) + tg) << 3);
1102 
1103  // Trickbox address check
1104  Fault f = testWalk(desc_addr, sizeof(uint64_t),
1105  TlbEntry::DomainType::NoAccess, start_lookup_level);
1106  if (f) {
1107  DPRINTF(TLB, "Trickbox check caused fault on %#x\n", currState->vaddr_tainted);
1108  if (currState->timing) {
1109  pending = false;
1110  nextWalk(currState->tc);
1111  currState = NULL;
1112  } else {
1113  currState->tc = NULL;
1114  currState->req = NULL;
1115  }
1116  return f;
1117  }
1118 
1120  if (currState->sctlr.c == 0 || currState->isUncacheable) {
1121  flag.set(Request::UNCACHEABLE);
1122  }
1123 
1124  if (currState->isSecure) {
1125  flag.set(Request::SECURE);
1126  }
1127 
1128  currState->longDesc.lookupLevel = start_lookup_level;
1129  currState->longDesc.aarch64 = true;
1132 
1133  if (currState->timing) {
1134  fetchDescriptor(desc_addr, (uint8_t*) &currState->longDesc.data,
1135  sizeof(uint64_t), flag, start_lookup_level,
1136  LongDescEventByLevel[start_lookup_level], NULL);
1137  } else {
1138  fetchDescriptor(desc_addr, (uint8_t*)&currState->longDesc.data,
1139  sizeof(uint64_t), flag, -1, NULL,
1141  f = currState->fault;
1142  }
1143 
1144  return f;
1145 }
1146 
1147 void
1149  uint8_t texcb, bool s)
1150 {
1151  // Note: tc and sctlr local variables are hiding tc and sctrl class
1152  // variables
1153  DPRINTF(TLBVerbose, "memAttrs texcb:%d s:%d\n", texcb, s);
1154  te.shareable = false; // default value
1155  te.nonCacheable = false;
1156  te.outerShareable = false;
1157  if (sctlr.tre == 0 || ((sctlr.tre == 1) && (sctlr.m == 0))) {
1158  switch(texcb) {
1159  case 0: // Stongly-ordered
1160  te.nonCacheable = true;
1162  te.shareable = true;
1163  te.innerAttrs = 1;
1164  te.outerAttrs = 0;
1165  break;
1166  case 1: // Shareable Device
1167  te.nonCacheable = true;
1169  te.shareable = true;
1170  te.innerAttrs = 3;
1171  te.outerAttrs = 0;
1172  break;
1173  case 2: // Outer and Inner Write-Through, no Write-Allocate
1175  te.shareable = s;
1176  te.innerAttrs = 6;
1177  te.outerAttrs = bits(texcb, 1, 0);
1178  break;
1179  case 3: // Outer and Inner Write-Back, no Write-Allocate
1181  te.shareable = s;
1182  te.innerAttrs = 7;
1183  te.outerAttrs = bits(texcb, 1, 0);
1184  break;
1185  case 4: // Outer and Inner Non-cacheable
1186  te.nonCacheable = true;
1188  te.shareable = s;
1189  te.innerAttrs = 0;
1190  te.outerAttrs = bits(texcb, 1, 0);
1191  break;
1192  case 5: // Reserved
1193  panic("Reserved texcb value!\n");
1194  break;
1195  case 6: // Implementation Defined
1196  panic("Implementation-defined texcb value!\n");
1197  break;
1198  case 7: // Outer and Inner Write-Back, Write-Allocate
1200  te.shareable = s;
1201  te.innerAttrs = 5;
1202  te.outerAttrs = 1;
1203  break;
1204  case 8: // Non-shareable Device
1205  te.nonCacheable = true;
1207  te.shareable = false;
1208  te.innerAttrs = 3;
1209  te.outerAttrs = 0;
1210  break;
1211  case 9 ... 15: // Reserved
1212  panic("Reserved texcb value!\n");
1213  break;
1214  case 16 ... 31: // Cacheable Memory
1216  te.shareable = s;
1217  if (bits(texcb, 1,0) == 0 || bits(texcb, 3,2) == 0)
1218  te.nonCacheable = true;
1219  te.innerAttrs = bits(texcb, 1, 0);
1220  te.outerAttrs = bits(texcb, 3, 2);
1221  break;
1222  default:
1223  panic("More than 32 states for 5 bits?\n");
1224  }
1225  } else {
1226  assert(tc);
1227  PRRR prrr = tc->readMiscReg(snsBankedIndex(MISCREG_PRRR,
1229  NMRR nmrr = tc->readMiscReg(snsBankedIndex(MISCREG_NMRR,
1231  DPRINTF(TLBVerbose, "memAttrs PRRR:%08x NMRR:%08x\n", prrr, nmrr);
1232  uint8_t curr_tr = 0, curr_ir = 0, curr_or = 0;
1233  switch(bits(texcb, 2,0)) {
1234  case 0:
1235  curr_tr = prrr.tr0;
1236  curr_ir = nmrr.ir0;
1237  curr_or = nmrr.or0;
1238  te.outerShareable = (prrr.nos0 == 0);
1239  break;
1240  case 1:
1241  curr_tr = prrr.tr1;
1242  curr_ir = nmrr.ir1;
1243  curr_or = nmrr.or1;
1244  te.outerShareable = (prrr.nos1 == 0);
1245  break;
1246  case 2:
1247  curr_tr = prrr.tr2;
1248  curr_ir = nmrr.ir2;
1249  curr_or = nmrr.or2;
1250  te.outerShareable = (prrr.nos2 == 0);
1251  break;
1252  case 3:
1253  curr_tr = prrr.tr3;
1254  curr_ir = nmrr.ir3;
1255  curr_or = nmrr.or3;
1256  te.outerShareable = (prrr.nos3 == 0);
1257  break;
1258  case 4:
1259  curr_tr = prrr.tr4;
1260  curr_ir = nmrr.ir4;
1261  curr_or = nmrr.or4;
1262  te.outerShareable = (prrr.nos4 == 0);
1263  break;
1264  case 5:
1265  curr_tr = prrr.tr5;
1266  curr_ir = nmrr.ir5;
1267  curr_or = nmrr.or5;
1268  te.outerShareable = (prrr.nos5 == 0);
1269  break;
1270  case 6:
1271  panic("Imp defined type\n");
1272  case 7:
1273  curr_tr = prrr.tr7;
1274  curr_ir = nmrr.ir7;
1275  curr_or = nmrr.or7;
1276  te.outerShareable = (prrr.nos7 == 0);
1277  break;
1278  }
1279 
1280  switch(curr_tr) {
1281  case 0:
1282  DPRINTF(TLBVerbose, "StronglyOrdered\n");
1284  te.nonCacheable = true;
1285  te.innerAttrs = 1;
1286  te.outerAttrs = 0;
1287  te.shareable = true;
1288  break;
1289  case 1:
1290  DPRINTF(TLBVerbose, "Device ds1:%d ds0:%d s:%d\n",
1291  prrr.ds1, prrr.ds0, s);
1293  te.nonCacheable = true;
1294  te.innerAttrs = 3;
1295  te.outerAttrs = 0;
1296  if (prrr.ds1 && s)
1297  te.shareable = true;
1298  if (prrr.ds0 && !s)
1299  te.shareable = true;
1300  break;
1301  case 2:
1302  DPRINTF(TLBVerbose, "Normal ns1:%d ns0:%d s:%d\n",
1303  prrr.ns1, prrr.ns0, s);
1305  if (prrr.ns1 && s)
1306  te.shareable = true;
1307  if (prrr.ns0 && !s)
1308  te.shareable = true;
1309  break;
1310  case 3:
1311  panic("Reserved type");
1312  }
1313 
1314  if (te.mtype == TlbEntry::MemoryType::Normal){
1315  switch(curr_ir) {
1316  case 0:
1317  te.nonCacheable = true;
1318  te.innerAttrs = 0;
1319  break;
1320  case 1:
1321  te.innerAttrs = 5;
1322  break;
1323  case 2:
1324  te.innerAttrs = 6;
1325  break;
1326  case 3:
1327  te.innerAttrs = 7;
1328  break;
1329  }
1330 
1331  switch(curr_or) {
1332  case 0:
1333  te.nonCacheable = true;
1334  te.outerAttrs = 0;
1335  break;
1336  case 1:
1337  te.outerAttrs = 1;
1338  break;
1339  case 2:
1340  te.outerAttrs = 2;
1341  break;
1342  case 3:
1343  te.outerAttrs = 3;
1344  break;
1345  }
1346  }
1347  }
1348  DPRINTF(TLBVerbose, "memAttrs: shareable: %d, innerAttrs: %d, "
1349  "outerAttrs: %d\n",
1350  te.shareable, te.innerAttrs, te.outerAttrs);
1351  te.setAttributes(false);
1352 }
1353 
1354 void
1356  LongDescriptor &lDescriptor)
1357 {
1358  assert(_haveLPAE);
1359 
1360  uint8_t attr;
1361  uint8_t sh = lDescriptor.sh();
1362  // Different format and source of attributes if this is a stage 2
1363  // translation
1364  if (isStage2) {
1365  attr = lDescriptor.memAttr();
1366  uint8_t attr_3_2 = (attr >> 2) & 0x3;
1367  uint8_t attr_1_0 = attr & 0x3;
1368 
1369  DPRINTF(TLBVerbose, "memAttrsLPAE MemAttr:%#x sh:%#x\n", attr, sh);
1370 
1371  if (attr_3_2 == 0) {
1372  te.mtype = attr_1_0 == 0 ? TlbEntry::MemoryType::StronglyOrdered
1374  te.outerAttrs = 0;
1375  te.innerAttrs = attr_1_0 == 0 ? 1 : 3;
1376  te.nonCacheable = true;
1377  } else {
1379  te.outerAttrs = attr_3_2 == 1 ? 0 :
1380  attr_3_2 == 2 ? 2 : 1;
1381  te.innerAttrs = attr_1_0 == 1 ? 0 :
1382  attr_1_0 == 2 ? 6 : 5;
1383  te.nonCacheable = (attr_3_2 == 1) || (attr_1_0 == 1);
1384  }
1385  } else {
1386  uint8_t attrIndx = lDescriptor.attrIndx();
1387 
1388  // LPAE always uses remapping of memory attributes, irrespective of the
1389  // value of SCTLR.TRE
1390  MiscRegIndex reg = attrIndx & 0x4 ? MISCREG_MAIR1 : MISCREG_MAIR0;
1391  int reg_as_int = snsBankedIndex(reg, currState->tc,
1392  !currState->isSecure);
1393  uint32_t mair = currState->tc->readMiscReg(reg_as_int);
1394  attr = (mair >> (8 * (attrIndx % 4))) & 0xff;
1395  uint8_t attr_7_4 = bits(attr, 7, 4);
1396  uint8_t attr_3_0 = bits(attr, 3, 0);
1397  DPRINTF(TLBVerbose, "memAttrsLPAE AttrIndx:%#x sh:%#x, attr %#x\n", attrIndx, sh, attr);
1398 
1399  // Note: the memory subsystem only cares about the 'cacheable' memory
1400  // attribute. The other attributes are only used to fill the PAR register
1401  // accordingly to provide the illusion of full support
1402  te.nonCacheable = false;
1403 
1404  switch (attr_7_4) {
1405  case 0x0:
1406  // Strongly-ordered or Device memory
1407  if (attr_3_0 == 0x0)
1409  else if (attr_3_0 == 0x4)
1411  else
1412  panic("Unpredictable behavior\n");
1413  te.nonCacheable = true;
1414  te.outerAttrs = 0;
1415  break;
1416  case 0x4:
1417  // Normal memory, Outer Non-cacheable
1419  te.outerAttrs = 0;
1420  if (attr_3_0 == 0x4)
1421  // Inner Non-cacheable
1422  te.nonCacheable = true;
1423  else if (attr_3_0 < 0x8)
1424  panic("Unpredictable behavior\n");
1425  break;
1426  case 0x8:
1427  case 0x9:
1428  case 0xa:
1429  case 0xb:
1430  case 0xc:
1431  case 0xd:
1432  case 0xe:
1433  case 0xf:
1434  if (attr_7_4 & 0x4) {
1435  te.outerAttrs = (attr_7_4 & 1) ? 1 : 3;
1436  } else {
1437  te.outerAttrs = 0x2;
1438  }
1439  // Normal memory, Outer Cacheable
1441  if (attr_3_0 != 0x4 && attr_3_0 < 0x8)
1442  panic("Unpredictable behavior\n");
1443  break;
1444  default:
1445  panic("Unpredictable behavior\n");
1446  break;
1447  }
1448 
1449  switch (attr_3_0) {
1450  case 0x0:
1451  te.innerAttrs = 0x1;
1452  break;
1453  case 0x4:
1454  te.innerAttrs = attr_7_4 == 0 ? 0x3 : 0;
1455  break;
1456  case 0x8:
1457  case 0x9:
1458  case 0xA:
1459  case 0xB:
1460  te.innerAttrs = 6;
1461  break;
1462  case 0xC:
1463  case 0xD:
1464  case 0xE:
1465  case 0xF:
1466  te.innerAttrs = attr_3_0 & 1 ? 0x5 : 0x7;
1467  break;
1468  default:
1469  panic("Unpredictable behavior\n");
1470  break;
1471  }
1472  }
1473 
1474  te.outerShareable = sh == 2;
1475  te.shareable = (sh & 0x2) ? true : false;
1476  te.setAttributes(true);
1477  te.attributes |= (uint64_t) attr << 56;
1478 }
1479 
1480 void
1482  LongDescriptor &lDescriptor)
1483 {
1484  uint8_t attr;
1485  uint8_t attr_hi;
1486  uint8_t attr_lo;
1487  uint8_t sh = lDescriptor.sh();
1488 
1489  if (isStage2) {
1490  attr = lDescriptor.memAttr();
1491  uint8_t attr_hi = (attr >> 2) & 0x3;
1492  uint8_t attr_lo = attr & 0x3;
1493 
1494  DPRINTF(TLBVerbose, "memAttrsAArch64 MemAttr:%#x sh:%#x\n", attr, sh);
1495 
1496  if (attr_hi == 0) {
1497  te.mtype = attr_lo == 0 ? TlbEntry::MemoryType::StronglyOrdered
1499  te.outerAttrs = 0;
1500  te.innerAttrs = attr_lo == 0 ? 1 : 3;
1501  te.nonCacheable = true;
1502  } else {
1504  te.outerAttrs = attr_hi == 1 ? 0 :
1505  attr_hi == 2 ? 2 : 1;
1506  te.innerAttrs = attr_lo == 1 ? 0 :
1507  attr_lo == 2 ? 6 : 5;
1508  // Treat write-through memory as uncacheable, this is safe
1509  // but for performance reasons not optimal.
1510  te.nonCacheable = (attr_hi == 1) || (attr_hi == 2) ||
1511  (attr_lo == 1) || (attr_lo == 2);
1512  }
1513  } else {
1514  uint8_t attrIndx = lDescriptor.attrIndx();
1515 
1516  DPRINTF(TLBVerbose, "memAttrsAArch64 AttrIndx:%#x sh:%#x\n", attrIndx, sh);
1518 
1519  // Select MAIR
1520  uint64_t mair;
1521  switch (regime) {
1522  case EL0:
1523  case EL1:
1524  mair = tc->readMiscReg(MISCREG_MAIR_EL1);
1525  break;
1526  case EL2:
1527  mair = tc->readMiscReg(MISCREG_MAIR_EL2);
1528  break;
1529  case EL3:
1530  mair = tc->readMiscReg(MISCREG_MAIR_EL3);
1531  break;
1532  default:
1533  panic("Invalid exception level");
1534  break;
1535  }
1536 
1537  // Select attributes
1538  attr = bits(mair, 8 * attrIndx + 7, 8 * attrIndx);
1539  attr_lo = bits(attr, 3, 0);
1540  attr_hi = bits(attr, 7, 4);
1541 
1542  // Memory type
1544 
1545  // Cacheability
1546  te.nonCacheable = false;
1547  if (te.mtype == TlbEntry::MemoryType::Device) { // Device memory
1548  te.nonCacheable = true;
1549  }
1550  // Treat write-through memory as uncacheable, this is safe
1551  // but for performance reasons not optimal.
1552  switch (attr_hi) {
1553  case 0x1 ... 0x3: // Normal Memory, Outer Write-through transient
1554  case 0x4: // Normal memory, Outer Non-cacheable
1555  case 0x8 ... 0xb: // Normal Memory, Outer Write-through non-transient
1556  te.nonCacheable = true;
1557  }
1558  switch (attr_lo) {
1559  case 0x1 ... 0x3: // Normal Memory, Inner Write-through transient
1560  case 0x9 ... 0xb: // Normal Memory, Inner Write-through non-transient
1561  warn_if(!attr_hi, "Unpredictable behavior");
1563  case 0x4: // Device-nGnRE memory or
1564  // Normal memory, Inner Non-cacheable
1565  case 0x8: // Device-nGRE memory or
1566  // Normal memory, Inner Write-through non-transient
1567  te.nonCacheable = true;
1568  }
1569 
1570  te.shareable = sh == 2;
1571  te.outerShareable = (sh & 0x2) ? true : false;
1572  // Attributes formatted according to the 64-bit PAR
1573  te.attributes = ((uint64_t) attr << 56) |
1574  (1 << 11) | // LPAE bit
1575  (te.ns << 9) | // NS bit
1576  (sh << 7);
1577  }
1578 }
1579 
1580 void
1582 {
1583  if (currState->fault != NoFault) {
1584  return;
1585  }
1586 
1588  byteOrder(currState->tc));
1589 
1590  DPRINTF(TLB, "L1 descriptor for %#x is %#x\n",
1592  TlbEntry te;
1593 
1594  const bool is_atomic = currState->req->isAtomic();
1595 
1596  switch (currState->l1Desc.type()) {
1597  case L1Descriptor::Ignore:
1599  if (!currState->timing) {
1600  currState->tc = NULL;
1601  currState->req = NULL;
1602  }
1603  DPRINTF(TLB, "L1 Descriptor Reserved/Ignore, causing fault\n");
1604  if (currState->isFetch)
1605  currState->fault =
1606  std::make_shared<PrefetchAbort>(
1609  isStage2,
1611  else
1612  currState->fault =
1613  std::make_shared<DataAbort>(
1616  is_atomic ? false : currState->isWrite,
1619  return;
1620  case L1Descriptor::Section:
1621  if (currState->sctlr.afe && bits(currState->l1Desc.ap(), 0) == 0) {
1627  currState->fault = std::make_shared<DataAbort>(
1629  currState->l1Desc.domain(),
1630  is_atomic ? false : currState->isWrite,
1632  isStage2,
1634  }
1635  if (currState->l1Desc.supersection()) {
1636  panic("Haven't implemented supersections\n");
1637  }
1639  return;
1641  {
1642  Addr l2desc_addr;
1643  l2desc_addr = currState->l1Desc.l2Addr() |
1644  (bits(currState->vaddr, 19, 12) << 2);
1645  DPRINTF(TLB, "L1 descriptor points to page table at: %#x (%s)\n",
1646  l2desc_addr, currState->isSecure ? "s" : "ns");
1647 
1648  // Trickbox address check
1649  currState->fault = testWalk(l2desc_addr, sizeof(uint32_t),
1650  currState->l1Desc.domain(), L2);
1651 
1652  if (currState->fault) {
1653  if (!currState->timing) {
1654  currState->tc = NULL;
1655  currState->req = NULL;
1656  }
1657  return;
1658  }
1659 
1661 
1662  if (currState->sctlr.c == 0 || currState->isUncacheable) {
1663  flag.set(Request::UNCACHEABLE);
1664  }
1665 
1666  if (currState->isSecure)
1667  flag.set(Request::SECURE);
1668 
1669  bool delayed;
1670  delayed = fetchDescriptor(l2desc_addr,
1671  (uint8_t*)&currState->l2Desc.data,
1672  sizeof(uint32_t), flag, -1, &doL2DescEvent,
1674  if (delayed) {
1675  currState->delayed = true;
1676  }
1677 
1678  return;
1679  }
1680  default:
1681  panic("A new type in a 2 bit field?\n");
1682  }
1683 }
1684 
1685 Fault
1687 {
1688  if (currState->isFetch) {
1689  return std::make_shared<PrefetchAbort>(
1692  isStage2,
1694  } else {
1695  return std::make_shared<DataAbort>(
1698  currState->req->isAtomic() ? false : currState->isWrite,
1700  isStage2,
1702  }
1703 }
1704 
1705 void
1707 {
1708  if (currState->fault != NoFault) {
1709  return;
1710  }
1711 
1713  byteOrder(currState->tc));
1714 
1715  DPRINTF(TLB, "L%d descriptor for %#llx is %#llx (%s)\n",
1718  currState->aarch64 ? "AArch64" : "long-desc.");
1719 
1722  DPRINTF(TLBVerbose, "Analyzing L%d descriptor: %#llx, pxn: %d, "
1723  "xn: %d, ap: %d, af: %d, type: %d\n",
1726  currState->longDesc.pxn(),
1727  currState->longDesc.xn(),
1728  currState->longDesc.ap(),
1729  currState->longDesc.af(),
1730  currState->longDesc.type());
1731  } else {
1732  DPRINTF(TLBVerbose, "Analyzing L%d descriptor: %#llx, type: %d\n",
1735  currState->longDesc.type());
1736  }
1737 
1738  TlbEntry te;
1739 
1740  switch (currState->longDesc.type()) {
1742  DPRINTF(TLB, "L%d descriptor Invalid, causing fault type %d\n",
1745 
1747  if (!currState->timing) {
1748  currState->tc = NULL;
1749  currState->req = NULL;
1750  }
1751  return;
1752 
1753  case LongDescriptor::Block:
1754  case LongDescriptor::Page:
1755  {
1756  auto fault_source = ArmFault::FaultSourceInvalid;
1757  // Check for address size fault
1760 
1761  DPRINTF(TLB, "L%d descriptor causing Address Size Fault\n",
1763  fault_source = ArmFault::AddressSizeLL;
1764 
1765  // Check for access fault
1766  } else if (currState->longDesc.af() == 0) {
1767 
1768  DPRINTF(TLB, "L%d descriptor causing Access Fault\n",
1770  fault_source = ArmFault::AccessFlagLL;
1771  }
1772 
1773  if (fault_source != ArmFault::FaultSourceInvalid) {
1774  currState->fault = generateLongDescFault(fault_source);
1775  } else {
1777  }
1778  }
1779  return;
1780  case LongDescriptor::Table:
1781  {
1782  // Set hierarchical permission flags
1793 
1794  // Set up next level lookup
1795  Addr next_desc_addr = currState->longDesc.nextDescAddr(
1796  currState->vaddr);
1797 
1798  DPRINTF(TLB, "L%d descriptor points to L%d descriptor at: %#x (%s)\n",
1801  next_desc_addr,
1802  currState->secureLookup ? "s" : "ns");
1803 
1804  // Check for address size fault
1806  next_desc_addr, currState->physAddrRange)) {
1807  DPRINTF(TLB, "L%d descriptor causing Address Size Fault\n",
1809 
1812  return;
1813  }
1814 
1815  // Trickbox address check
1817  next_desc_addr, sizeof(uint64_t), TlbEntry::DomainType::Client,
1819 
1820  if (currState->fault) {
1821  if (!currState->timing) {
1822  currState->tc = NULL;
1823  currState->req = NULL;
1824  }
1825  return;
1826  }
1827 
1829  if (currState->secureLookup)
1830  flag.set(Request::SECURE);
1831 
1832  if (currState->sctlr.c == 0 || currState->isUncacheable) {
1833  flag.set(Request::UNCACHEABLE);
1834  }
1835 
1838  Event *event = NULL;
1839  switch (L) {
1840  case L1:
1841  assert(currState->aarch64);
1842  case L2:
1843  case L3:
1844  event = LongDescEventByLevel[L];
1845  break;
1846  default:
1847  panic("Wrong lookup level in table walk\n");
1848  break;
1849  }
1850 
1851  bool delayed;
1852  delayed = fetchDescriptor(next_desc_addr, (uint8_t*)&currState->longDesc.data,
1853  sizeof(uint64_t), flag, -1, event,
1855  if (delayed) {
1856  currState->delayed = true;
1857  }
1858  }
1859  return;
1860  default:
1861  panic("A new type in a 2 bit field?\n");
1862  }
1863 }
1864 
1865 void
1867 {
1868  if (currState->fault != NoFault) {
1869  return;
1870  }
1871 
1873  byteOrder(currState->tc));
1874 
1875  DPRINTF(TLB, "L2 descriptor for %#x is %#x\n",
1877  TlbEntry te;
1878 
1879  const bool is_atomic = currState->req->isAtomic();
1880 
1881  if (currState->l2Desc.invalid()) {
1882  DPRINTF(TLB, "L2 descriptor invalid, causing fault\n");
1883  if (!currState->timing) {
1884  currState->tc = NULL;
1885  currState->req = NULL;
1886  }
1887  if (currState->isFetch)
1888  currState->fault = std::make_shared<PrefetchAbort>(
1891  isStage2,
1893  else
1894  currState->fault = std::make_shared<DataAbort>(
1896  is_atomic ? false : currState->isWrite,
1898  isStage2,
1900  return;
1901  }
1902 
1903  if (currState->sctlr.afe && bits(currState->l2Desc.ap(), 0) == 0) {
1907  DPRINTF(TLB, "Generating access fault at L2, afe: %d, ap: %d\n",
1908  currState->sctlr.afe, currState->l2Desc.ap());
1909 
1910  currState->fault = std::make_shared<DataAbort>(
1913  is_atomic ? false : currState->isWrite,
1916  }
1917 
1919 }
1920 
1921 void
1923 {
1924  currState = stateQueues[L1].front();
1925  currState->delayed = false;
1926  // if there's a stage2 translation object we don't need it any more
1927  if (currState->stage2Tran) {
1928  delete currState->stage2Tran;
1929  currState->stage2Tran = NULL;
1930  }
1931 
1932 
1933  DPRINTF(TLBVerbose, "L1 Desc object host addr: %p\n",&currState->l1Desc.data);
1934  DPRINTF(TLBVerbose, "L1 Desc object data: %08x\n",currState->l1Desc.data);
1935 
1936  DPRINTF(TLBVerbose, "calling doL1Descriptor for vaddr:%#x\n", currState->vaddr_tainted);
1937  doL1Descriptor();
1938 
1939  stateQueues[L1].pop_front();
1940  // Check if fault was generated
1941  if (currState->fault != NoFault) {
1943  currState->tc, currState->mode);
1945 
1946  pending = false;
1947  nextWalk(currState->tc);
1948 
1949  currState->req = NULL;
1950  currState->tc = NULL;
1951  currState->delayed = false;
1952  delete currState;
1953  }
1954  else if (!currState->delayed) {
1955  // delay is not set so there is no L2 to do
1956  // Don't finish the translation if a stage 2 look up is underway
1958  DPRINTF(TLBVerbose, "calling translateTiming again\n");
1962 
1963  pending = false;
1964  nextWalk(currState->tc);
1965 
1966  currState->req = NULL;
1967  currState->tc = NULL;
1968  currState->delayed = false;
1969  delete currState;
1970  } else {
1971  // need to do L2 descriptor
1972  stateQueues[L2].push_back(currState);
1973  }
1974  currState = NULL;
1975 }
1976 
1977 void
1979 {
1980  currState = stateQueues[L2].front();
1981  assert(currState->delayed);
1982  // if there's a stage2 translation object we don't need it any more
1983  if (currState->stage2Tran) {
1984  delete currState->stage2Tran;
1985  currState->stage2Tran = NULL;
1986  }
1987 
1988  DPRINTF(TLBVerbose, "calling doL2Descriptor for vaddr:%#x\n",
1990  doL2Descriptor();
1991 
1992  // Check if fault was generated
1993  if (currState->fault != NoFault) {
1995  currState->tc, currState->mode);
1997  } else {
1999  DPRINTF(TLBVerbose, "calling translateTiming again\n");
2003  }
2004 
2005 
2006  stateQueues[L2].pop_front();
2007  pending = false;
2008  nextWalk(currState->tc);
2009 
2010  currState->req = NULL;
2011  currState->tc = NULL;
2012  currState->delayed = false;
2013 
2014  delete currState;
2015  currState = NULL;
2016 }
2017 
2018 void
2020 {
2022 }
2023 
2024 void
2026 {
2028 }
2029 
2030 void
2032 {
2034 }
2035 
2036 void
2038 {
2040 }
2041 
2042 void
2044 {
2045  currState = stateQueues[curr_lookup_level].front();
2046  assert(curr_lookup_level == currState->longDesc.lookupLevel);
2047  currState->delayed = false;
2048 
2049  // if there's a stage2 translation object we don't need it any more
2050  if (currState->stage2Tran) {
2051  delete currState->stage2Tran;
2052  currState->stage2Tran = NULL;
2053  }
2054 
2055  DPRINTF(TLBVerbose, "calling doLongDescriptor for vaddr:%#x\n",
2057  doLongDescriptor();
2058 
2059  stateQueues[curr_lookup_level].pop_front();
2060 
2061  if (currState->fault != NoFault) {
2062  // A fault was generated
2064  currState->tc, currState->mode);
2065 
2066  pending = false;
2067  nextWalk(currState->tc);
2068 
2069  currState->req = NULL;
2070  currState->tc = NULL;
2071  currState->delayed = false;
2072  delete currState;
2073  } else if (!currState->delayed) {
2074  // No additional lookups required
2075  DPRINTF(TLBVerbose, "calling translateTiming again\n");
2079  stats.walksLongTerminatedAtLevel[(unsigned) curr_lookup_level]++;
2080 
2081  pending = false;
2082  nextWalk(currState->tc);
2083 
2084  currState->req = NULL;
2085  currState->tc = NULL;
2086  currState->delayed = false;
2087  delete currState;
2088  } else {
2089  if (curr_lookup_level >= MAX_LOOKUP_LEVELS - 1)
2090  panic("Max. number of lookups already reached in table walk\n");
2091  // Need to perform additional lookups
2093  }
2094  currState = NULL;
2095 }
2096 
2097 
2098 void
2100 {
2101  if (pendingQueue.size())
2103  else
2104  completeDrain();
2105 }
2106 
2107 bool
2108 TableWalker::fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes,
2109  Request::Flags flags, int queueIndex, Event *event,
2110  void (TableWalker::*doDescriptor)())
2111 {
2112  bool isTiming = currState->timing;
2113 
2114  DPRINTF(TLBVerbose, "Fetching descriptor at address: 0x%x stage2Req: %d\n",
2115  descAddr, currState->stage2Req);
2116 
2117  // If this translation has a stage 2 then we know descAddr is an IPA and
2118  // needs to be translated before we can access the page table. Do that
2119  // check here.
2120  if (currState->stage2Req) {
2121  Fault fault;
2122 
2123  if (isTiming) {
2124  Stage2MMU::Stage2Translation *tran = new
2126  currState->vaddr);
2127  currState->stage2Tran = tran;
2128  stage2Mmu->readDataTimed(currState->tc, descAddr, tran, numBytes,
2129  flags);
2130  fault = tran->fault;
2131  } else {
2133  currState->vaddr, descAddr, data, numBytes, flags,
2135  }
2136 
2137  if (fault != NoFault) {
2138  currState->fault = fault;
2139  }
2140  if (isTiming) {
2141  if (queueIndex >= 0) {
2142  DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n",
2143  stateQueues[queueIndex].size());
2144  stateQueues[queueIndex].push_back(currState);
2145  currState = NULL;
2146  }
2147  } else {
2148  (this->*doDescriptor)();
2149  }
2150  } else {
2151  if (isTiming) {
2152  port->dmaAction(MemCmd::ReadReq, descAddr, numBytes, event, data,
2153  currState->tc->getCpuPtr()->clockPeriod(),flags);
2154  if (queueIndex >= 0) {
2155  DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n",
2156  stateQueues[queueIndex].size());
2157  stateQueues[queueIndex].push_back(currState);
2158  currState = NULL;
2159  }
2160  } else if (!currState->functional) {
2161  port->dmaAction(MemCmd::ReadReq, descAddr, numBytes, NULL, data,
2162  currState->tc->getCpuPtr()->clockPeriod(), flags);
2163  (this->*doDescriptor)();
2164  } else {
2165  RequestPtr req = std::make_shared<Request>(
2166  descAddr, numBytes, flags, requestorId);
2167 
2168  req->taskId(ContextSwitchTaskId::DMA);
2169  PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
2170  pkt->dataStatic(data);
2171  port->sendFunctional(pkt);
2172  (this->*doDescriptor)();
2173  delete pkt;
2174  }
2175  }
2176  return (isTiming);
2177 }
2178 
2179 void
2180 TableWalker::insertTableEntry(DescriptorBase &descriptor, bool longDescriptor)
2181 {
2182  TlbEntry te;
2183 
2184  // Create and fill a new page table entry
2185  te.valid = true;
2186  te.longDescFormat = longDescriptor;
2187  te.isHyp = currState->isHyp;
2188  te.asid = currState->asid;
2189  te.vmid = currState->vmid;
2190  te.N = descriptor.offsetBits();
2191  te.vpn = currState->vaddr >> te.N;
2192  te.size = (1<<te.N) - 1;
2193  te.pfn = descriptor.pfn();
2194  te.domain = descriptor.domain();
2195  te.lookupLevel = descriptor.lookupLevel;
2196  te.ns = !descriptor.secure(haveSecurity, currState) || isStage2;
2197  te.nstid = !currState->isSecure;
2198  te.xn = descriptor.xn();
2199  if (currState->aarch64)
2200  te.el = currState->el;
2201  else
2202  te.el = EL1;
2203 
2206 
2207  // ASID has no meaning for stage 2 TLB entries, so mark all stage 2 entries
2208  // as global
2209  te.global = descriptor.global(currState) || isStage2;
2210  if (longDescriptor) {
2211  LongDescriptor lDescriptor =
2212  dynamic_cast<LongDescriptor &>(descriptor);
2213 
2214  te.xn |= currState->xnTable;
2215  te.pxn = currState->pxnTable || lDescriptor.pxn();
2216  if (isStage2) {
2217  // this is actually the HAP field, but its stored in the same bit
2218  // possitions as the AP field in a stage 1 translation.
2219  te.hap = lDescriptor.ap();
2220  } else {
2221  te.ap = ((!currState->rwTable || descriptor.ap() >> 1) << 1) |
2222  (currState->userTable && (descriptor.ap() & 0x1));
2223  }
2224  if (currState->aarch64)
2225  memAttrsAArch64(currState->tc, te, lDescriptor);
2226  else
2227  memAttrsLPAE(currState->tc, te, lDescriptor);
2228  } else {
2229  te.ap = descriptor.ap();
2230  memAttrs(currState->tc, te, currState->sctlr, descriptor.texcb(),
2231  descriptor.shareable());
2232  }
2233 
2234  // Debug output
2235  DPRINTF(TLB, descriptor.dbgHeader().c_str());
2236  DPRINTF(TLB, " - N:%d pfn:%#x size:%#x global:%d valid:%d\n",
2237  te.N, te.pfn, te.size, te.global, te.valid);
2238  DPRINTF(TLB, " - vpn:%#x xn:%d pxn:%d ap:%d domain:%d asid:%d "
2239  "vmid:%d hyp:%d nc:%d ns:%d\n", te.vpn, te.xn, te.pxn,
2240  te.ap, static_cast<uint8_t>(te.domain), te.asid, te.vmid, te.isHyp,
2241  te.nonCacheable, te.ns);
2242  DPRINTF(TLB, " - domain from L%d desc:%d data:%#x\n",
2243  descriptor.lookupLevel, static_cast<uint8_t>(descriptor.domain()),
2244  descriptor.getRawData());
2245 
2246  // Insert the entry into the TLB
2247  tlb->insert(currState->vaddr, te);
2248  if (!currState->timing) {
2249  currState->tc = NULL;
2250  currState->req = NULL;
2251  }
2252 }
2253 
2255 TableWalker::toLookupLevel(uint8_t lookup_level_as_int)
2256 {
2257  switch (lookup_level_as_int) {
2258  case L1:
2259  return L1;
2260  case L2:
2261  return L2;
2262  case L3:
2263  return L3;
2264  default:
2265  panic("Invalid lookup level conversion");
2266  }
2267 }
2268 
2269 /* this method keeps track of the table walker queue's residency, so
2270  * needs to be called whenever requests start and complete. */
2271 void
2273 {
2274  unsigned n = pendingQueue.size();
2275  if ((currState != NULL) && (currState != pendingQueue.front())) {
2276  ++n;
2277  }
2278 
2279  if (n != pendingReqs) {
2280  Tick now = curTick();
2282  pendingReqs = n;
2283  pendingChangeTick = now;
2284  }
2285 }
2286 
2287 Fault
2289  LookupLevel lookup_level)
2290 {
2291  return tlb->testWalk(pa, size, currState->vaddr, currState->isSecure,
2292  currState->mode, domain, lookup_level);
2293 }
2294 
2295 
2296 uint8_t
2298 {
2299  /* for stats.pageSizes */
2300  switch(N) {
2301  case 12: return 0; // 4K
2302  case 14: return 1; // 16K (using 16K granule in v8-64)
2303  case 16: return 2; // 64K
2304  case 20: return 3; // 1M
2305  case 21: return 4; // 2M-LPAE
2306  case 24: return 5; // 16M
2307  case 25: return 6; // 32M (using 16K granule in v8-64)
2308  case 29: return 7; // 512M (using 64K granule in v8-64)
2309  case 30: return 8; // 1G-LPAE
2310  case 42: return 9; // 1G-LPAE
2311  default:
2312  panic("unknown page size");
2313  return 255;
2314  }
2315 }
2316 
2317 
2319  : Stats::Group(parent),
2320  ADD_STAT(walks, UNIT_COUNT, "Table walker walks requested"),
2321  ADD_STAT(walksShortDescriptor, UNIT_COUNT,
2322  "Table walker walks initiated with short descriptors"),
2323  ADD_STAT(walksLongDescriptor, UNIT_COUNT,
2324  "Table walker walks initiated with long descriptors"),
2325  ADD_STAT(walksShortTerminatedAtLevel, UNIT_COUNT,
2326  "Level at which table walker walks with short descriptors "
2327  "terminate"),
2328  ADD_STAT(walksLongTerminatedAtLevel, UNIT_COUNT,
2329  "Level at which table walker walks with long descriptors "
2330  "terminate"),
2331  ADD_STAT(squashedBefore, UNIT_COUNT,
2332  "Table walks squashed before starting"),
2333  ADD_STAT(squashedAfter, UNIT_COUNT,
2334  "Table walks squashed after completion"),
2335  ADD_STAT(walkWaitTime, UNIT_TICK,
2336  "Table walker wait (enqueue to first request) latency"),
2337  ADD_STAT(walkServiceTime, UNIT_TICK,
2338  "Table walker service (enqueue to completion) latency"),
2339  ADD_STAT(pendingWalks, UNIT_TICK,
2340  "Table walker pending requests distribution"),
2341  ADD_STAT(pageSizes, UNIT_COUNT,
2342  "Table walker page sizes translated"),
2343  ADD_STAT(requestOrigin, UNIT_COUNT,
2344  "Table walker requests started/completed, data/inst")
2345 {
2347  .flags(Stats::nozero);
2348 
2350  .flags(Stats::nozero);
2351 
2353  .init(2)
2354  .flags(Stats::nozero);
2355 
2356  walksShortTerminatedAtLevel.subname(0, "Level1");
2357  walksShortTerminatedAtLevel.subname(1, "Level2");
2358 
2360  .init(4)
2361  .flags(Stats::nozero);
2362  walksLongTerminatedAtLevel.subname(0, "Level0");
2363  walksLongTerminatedAtLevel.subname(1, "Level1");
2364  walksLongTerminatedAtLevel.subname(2, "Level2");
2365  walksLongTerminatedAtLevel.subname(3, "Level3");
2366 
2368  .flags(Stats::nozero);
2369 
2371  .flags(Stats::nozero);
2372 
2373  walkWaitTime
2374  .init(16)
2376 
2378  .init(16)
2380 
2381  pendingWalks
2382  .init(16)
2384 
2385  pageSizes // see DDI 0487A D4-1661
2386  .init(10)
2388  pageSizes.subname(0, "4KiB");
2389  pageSizes.subname(1, "16KiB");
2390  pageSizes.subname(2, "64KiB");
2391  pageSizes.subname(3, "1MiB");
2392  pageSizes.subname(4, "2MiB");
2393  pageSizes.subname(5, "16MiB");
2394  pageSizes.subname(6, "32MiB");
2395  pageSizes.subname(7, "512MiB");
2396  pageSizes.subname(8, "1GiB");
2397  pageSizes.subname(9, "4TiB");
2398 
2400  .init(2,2) // Instruction/Data, requests/completed
2401  .flags(Stats::total);
2402  requestOrigin.subname(0,"Requested");
2403  requestOrigin.subname(1,"Completed");
2404  requestOrigin.ysubname(0,"Data");
2405  requestOrigin.ysubname(1,"Inst");
2406 }
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:797
ArmISA::TableWalker::TableWalkerStats::walkWaitTime
Stats::Histogram walkWaitTime
Definition: table_walker.hh:902
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:803
ArmISA::TableWalker::WalkerState::mode
BaseTLB::Mode mode
Save mode for use in delayed response.
Definition: table_walker.hh:815
BaseTLB::Translation::finish
virtual void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, Mode mode)=0
ArmISA::TableWalker::checkAddrSizeFaultAArch64
bool checkAddrSizeFaultAArch64(Addr addr, int pa_range)
Returns true if the address exceeds the range permitted by the system-wide setting or by the TCR_ELx ...
Definition: table_walker.cc:767
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:598
ArmISA::TableWalker::WalkerState::el
ExceptionLevel el
Current exception level.
Definition: table_walker.hh:730
ArmISA::TableWalker::LongDescriptor::grainSize
GrainSize grainSize
Width of the granule size in bits.
Definition: table_walker.hh:401
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:812
ArmISA::LookupLevel
LookupLevel
Definition: pagetable.hh:72
ArmISA::TableWalker::TableWalkerStats::walksShortDescriptor
Stats::Scalar walksShortDescriptor
Definition: table_walker.hh:896
X86ISA::L
Bitfield< 7, 0 > L
Definition: int.hh:57
ArmISA::TableWalker::WalkerState::tcr
TCR tcr
Definition: table_walker.hh:767
ArmISA::computeAddrTop
int computeAddrTop(ThreadContext *tc, bool selbit, bool isInstr, TCR tcr, ExceptionLevel el)
Definition: utility.cc:458
ArmISA::TableWalker::memAttrsAArch64
void memAttrsAArch64(ThreadContext *tc, TlbEntry &te, LongDescriptor &lDescriptor)
Definition: table_walker.cc:1481
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 (16 MiB)?
Definition: table_walker.hh:136
ArmISA::TableWalker::doL2Descriptor
void doL2Descriptor()
Definition: table_walker.cc:1866
Request::SECURE
@ SECURE
The request targets the secure memory space.
Definition: request.hh:177
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:741
ArmISA::TableWalker::WalkerState::tranType
TLB::ArmTranslationType tranType
The translation type that has been requested.
Definition: table_walker.hh:818
ArmISA::TableWalker::WalkerState::asid
uint16_t asid
ASID that we're servicing the request under.
Definition: table_walker.hh:739
ArmISA::TableWalker::TableWalkerStats::TableWalkerStats
TableWalkerStats(Stats::Group *parent)
Definition: table_walker.cc:2318
system.hh
ArmISA::MISCREG_TTBR0
@ MISCREG_TTBR0
Definition: miscregs.hh:250
ArmISA::HaveVirtHostExt
bool HaveVirtHostExt(ThreadContext *tc)
Definition: utility.cc:264
ArmISA::TableWalker::DescriptorBase::global
virtual bool global(WalkerState *currState) const =0
ArmISA::HaveLVA
bool HaveLVA(ThreadContext *tc)
Definition: utility.cc:271
ArmISA::TableWalker::LongDescriptor::physAddrRange
uint8_t physAddrRange
Definition: table_walker.hh:403
data
const char data[]
Definition: circlebuf.test.cc:47
ArmISA::TableWalker::LongDescriptor::rwTable
uint8_t rwTable() const
R/W protection flag for subsequent levels of lookup.
Definition: table_walker.hh:691
ArmISA::ArmFault::VmsaTran
@ VmsaTran
Definition: faults.hh:149
ArmISA::TableWalker::doL0LongDescriptorWrapper
void doL0LongDescriptorWrapper()
Definition: table_walker.cc:2019
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:2288
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:166
ArmSystem::physAddrRange
uint8_t physAddrRange() const
Returns the supported physical address range in bits.
Definition: system.hh:252
ArmISA::byteOrder
ByteOrder byteOrder(const ThreadContext *tc)
Definition: utility.hh:430
ArmISA::TLB::ArmTranslationType
ArmTranslationType
Definition: tlb.hh:127
ArmISA::TableWalker::_haveLPAE
bool _haveLPAE
Definition: table_walker.hh:887
ArmISA::TableWalker::WalkerState::req
RequestPtr req
Request that is currently being serviced.
Definition: table_walker.hh:736
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:260
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:874
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:795
ArmISA::TableWalker::stage2Mmu
Stage2MMU * stage2Mmu
The MMU to forward second stage look upts to.
Definition: table_walker.hh:859
ArmISA::TableWalker::DescriptorBase::dbgHeader
virtual std::string dbgHeader() const =0
Flags< FlagsType >
ArmISA::snsBankedIndex
int snsBankedIndex(MiscRegIndex reg, ThreadContext *tc)
Definition: miscregs.cc:1310
ArmISA::TableWalker::isStage2
const bool isStage2
Indicates whether this table walker is part of the stage 2 mmu.
Definition: table_walker.hh:868
ArmISA::TableWalker::LongDescriptor::nextDescAddr
Addr nextDescAddr(Addr va) const
Return the address of the next descriptor.
Definition: table_walker.hh:540
ArmISA::TableWalker::doLongDescriptorWrapper
void doLongDescriptorWrapper(LookupLevel curr_lookup_level)
Definition: table_walker.cc:2043
ArmISA::MISCREG_TTBR0_EL1
@ MISCREG_TTBR0_EL1
Definition: miscregs.hh:593
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:883
ArmISA::TableWalker::WalkerState::physAddrRange
int physAddrRange
Current physical address range in bits.
Definition: table_walker.hh:733
ArmISA::ArmFault::FaultSourceInvalid
@ FaultSourceInvalid
Definition: faults.hh:116
ArmISA::MISCREG_VTTBR_EL2
@ MISCREG_VTTBR_EL2
Definition: miscregs.hh:601
ArmISA::TableWalker::WalkerState::tc
ThreadContext * tc
Thread context that we're doing the walk for.
Definition: table_walker.hh:724
ArmISA::te
Bitfield< 30 > te
Definition: miscregs_types.hh:334
BaseTLB::Mode
Mode
Definition: tlb.hh:57
ArmISA::TableWalker::DescriptorBase::xn
virtual bool xn() const =0
MemCmd::ReadReq
@ ReadReq
Definition: packet.hh:83
ArmISA::TableWalker::TableWalker
TableWalker(const Params &p)
Definition: table_walker.cc:56
UNIT_TICK
#define UNIT_TICK
Definition: units.hh:40
Stats::DataWrapVec2d::ysubname
Derived & ysubname(off_type index, const std::string &subname)
Definition: statistics.hh:471
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:59
ArmISA::TableWalker::WalkerState::vmid
uint8_t vmid
Definition: table_walker.hh:740
ArmISA::TableWalker::_haveVirtualization
bool _haveVirtualization
Definition: table_walker.hh:888
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:243
ArmISA::TableWalker::doProcessEvent
EventFunctionWrapper doProcessEvent
Definition: table_walker.hh:996
ArmISA::TableWalker::ReservedGrain
@ ReservedGrain
Definition: table_walker.hh:371
ArmISA::TableWalker::WalkerState
Definition: table_walker.hh:720
RequestPtr
std::shared_ptr< Request > RequestPtr
Definition: request.hh:86
ArmISA::TableWalker::WalkerState::startTime
Tick startTime
Timestamp for calculating elapsed time in service (for stats)
Definition: table_walker.hh:834
ArmISA::decodePhysAddrRange64
int decodePhysAddrRange64(uint8_t pa_enc)
Returns the n.
Definition: utility.cc:1328
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:774
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:1148
ArmISA::TableWalker::pageSizeNtoStatBin
static uint8_t pageSizeNtoStatBin(uint8_t N)
Definition: table_walker.cc:2297
ArmISA::TableWalker::TableWalkerStats::walksLongDescriptor
Stats::Scalar walksLongDescriptor
Definition: table_walker.hh:897
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:204
ArmISA::TableWalker::LongDescriptor::pxnTable
bool pxnTable() const
Is privileged execution allowed on subsequent lookup levels?
Definition: table_walker.hh:713
ArmISA::TableWalker::doL2DescriptorWrapper
void doL2DescriptorWrapper()
Definition: table_walker.cc:1978
ArmISA::MISCREG_TCR_EL2
@ MISCREG_TCR_EL2
Definition: miscregs.hh:600
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
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:433
ArmISA::TlbEntry::MemoryType::Device
@ Device
system.hh
ArmISA::TableWalker::REQUESTED
static const unsigned REQUESTED
Definition: table_walker.hh:912
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:699
ArmISA::TableWalker::pendingChangeTick
Tick pendingChangeTick
Definition: table_walker.hh:910
ArmISA::MISCREG_HTTBR
@ MISCREG_HTTBR
Definition: miscregs.hh:443
ArmISA::TableWalker::WalkerState::tableWalker
TableWalker * tableWalker
Definition: table_walker.hh:831
ArmISA::TableWalker::WalkerState::isWrite
bool isWrite
If the access is a write.
Definition: table_walker.hh:780
ArmISA
Definition: ccregs.hh:41
ArmISA::MISCREG_TCR_EL3
@ MISCREG_TCR_EL3
Definition: miscregs.hh:606
ContextSwitchTaskId::DMA
@ DMA
Definition: request.hh:78
X86ISA::reg
Bitfield< 5, 3 > reg
Definition: types.hh:88
ArmISA::TableWalker::LongDescriptor::ap
uint8_t ap() const
2-bit access protection flags
Definition: table_walker.hh:612
ArmSystem::haveVirtualization
bool haveVirtualization() const
Returns true if this system implements the virtualization Extensions.
Definition: system.hh:168
ArmISA::TableWalker::WalkerState::isSecure
bool isSecure
If the access comes from the secure state.
Definition: table_walker.hh:786
ArmISA::TableWalker::nextWalk
void nextWalk(ThreadContext *tc)
Definition: table_walker.cc:2099
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:821
ArmISA::TableWalker::L1Descriptor::data
uint32_t data
The raw bits of the entry.
Definition: table_walker.hh:103
Request::PT_WALK
@ PT_WALK
The request is a page table walk.
Definition: request.hh:179
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:809
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:905
ArmISA::TableWalker::WalkerState::longDesc
LongDescriptor longDesc
Long-format descriptor (LPAE and AArch64)
Definition: table_walker.hh:825
ArmISA::TableWalker::WalkerState::secureLookup
bool secureLookup
Helper variables used to implement hierarchical access permissions when the long-desc.
Definition: table_walker.hh:793
ArmISA::ELIs64
bool ELIs64(ThreadContext *tc, ExceptionLevel el)
Definition: utility.cc:322
Stats::DataWrap::flags
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:339
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:2255
ArmISA::TableWalker::WalkerState::stage2Tran
TLB::Translation * stage2Tran
A pointer to the stage 2 translation that's in progress.
Definition: table_walker.hh:806
ArmISA::TableWalker::L1Descriptor::Section
@ Section
Definition: table_walker.hh:98
ArmISA::TableWalker::processWalkAArch64
Fault processWalkAArch64()
Definition: table_walker.cc:774
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:89
ArmISA::TableWalker::requestorId
RequestorID requestorId
Requestor id assigned by the MMU.
Definition: table_walker.hh:865
ArmISA::TableWalker::doL3LongDescriptorWrapper
void doL3LongDescriptorWrapper()
Definition: table_walker.cc:2037
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:391
dma_device.hh
EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1016
ArmISA::TableWalker::WalkerState::aarch64
bool aarch64
If the access is performed in AArch64 state.
Definition: table_walker.hh:727
ArmISA::ArmFault::LpaeTran
@ LpaeTran
Definition: faults.hh:148
ArmISA::TableWalker::LongDescriptor::attrIndx
uint8_t attrIndx() const
Attribute index.
Definition: table_walker.hh:649
ArmSystem::haveSecurity
bool haveSecurity() const
Returns true if this system implements the Security Extensions.
Definition: system.hh:159
ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
ClockedObject::Params
ClockedObjectParams Params
Parameters of ClockedObject.
Definition: clocked_object.hh:237
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:2108
ArmSystem::haveLPAE
bool haveLPAE() const
Returns true if this system implements the Large Physical Address Extension.
Definition: system.hh:163
Event
Definition: eventq.hh:248
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:120
ArmISA::TableWalker::TableWalkerStats::walks
Stats::Scalar walks
Definition: table_walker.hh:895
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
ArmISA::MISCREG_HCR
@ MISCREG_HCR
Definition: miscregs.hh:244
ADD_STAT
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:71
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:246
MipsISA::vaddr
vaddr
Definition: pra_constants.hh:275
ArmISA::TableWalker::WalkerState::xnTable
bool xnTable
Definition: table_walker.hh:796
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:156
ArmISA::ArmFault::AddressSizeLL
@ AddressSizeLL
Definition: faults.hh:107
ArmISA::TableWalker::haveSecurity
bool haveSecurity
Cached copies of system-level properties.
Definition: table_walker.hh:886
ArmISA::z
Bitfield< 11 > z
Definition: miscregs_types.hh:370
ArmISA::TableWalker::stateQueues
std::list< WalkerState * > stateQueues[MAX_LOOKUP_LEVELS]
Queues of requests for all the different lookup levels.
Definition: table_walker.hh:852
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:677
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:597
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::WalkerState::rwTable
bool rwTable
Definition: table_walker.hh:794
ArmISA::el
Bitfield< 3, 2 > el
Definition: miscregs_types.hh:69
ArmISA::MISCREG_TTBCR
@ MISCREG_TTBCR
Definition: miscregs.hh:256
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:656
ArmISA::attr
attr
Definition: miscregs_types.hh:649
ArmISA::TableWalker::pendingChange
void pendingChange()
Definition: table_walker.cc:2272
Flags::set
void set(Type mask)
Set all flag's bits matching the given mask.
Definition: flags.hh:113
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:59
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:1533
ArmISA::MISCREG_TTBR0_EL2
@ MISCREG_TTBR0_EL2
Definition: miscregs.hh:599
ArmISA::TableWalker::WalkerState::vtcr
VTCR_t vtcr
Cached copy of the vtcr as it existed when translation began.
Definition: table_walker.hh:777
mbits
constexpr T mbits(T val, unsigned first, unsigned last)
Mask off the given bits in place like bits() but without shifting.
Definition: bitfield.hh:100
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:2031
ArmISA::TableWalker::LongDescriptor::aarch64
bool aarch64
True if the current lookup is performed in AArch64 state.
Definition: table_walker.hh:398
ArmISA::TableWalker::WalkerState::delayed
bool delayed
Whether the response is delayed in timing mode due to additional lookups.
Definition: table_walker.hh:829
ArmISA::s1TranslationRegime
ExceptionLevel s1TranslationRegime(ThreadContext *tc, ExceptionLevel el)
Definition: utility.cc:278
ArmISA::L2
@ L2
Definition: pagetable.hh:75
ArmISA::longDescFormatInUse
bool longDescFormatInUse(ThreadContext *tc)
Definition: utility.cc:167
ArmISA::TableWalker::port
DmaPort * port
Port shared by the two table walkers.
Definition: table_walker.hh:862
ArmISA::MISCREG_VSTTBR_EL2
@ MISCREG_VSTTBR_EL2
Definition: miscregs.hh:603
ArmISA::TableWalker::LongDescriptor::Page
@ Page
Definition: table_walker.hh:382
ArmISA::MISCREG_TTBR0_EL3
@ MISCREG_TTBR0_EL3
Definition: miscregs.hh:605
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:582
UNIT_COUNT
#define UNIT_COUNT
Definition: units.hh:49
NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:251
ArmISA::MISCREG_TTBR1_EL1
@ MISCREG_TTBR1_EL1
Definition: miscregs.hh:595
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:1729
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:974
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:148
ArmISA::ArmFault::AccessFlagLL
@ AccessFlagLL
Definition: faults.hh:98
ArmISA::TableWalker::TableWalkerStats::walkServiceTime
Stats::Histogram walkServiceTime
Definition: table_walker.hh:903
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:503
ArmISA::TableWalker::TableWalkerStats::walksLongTerminatedAtLevel
Stats::Vector walksLongTerminatedAtLevel
Definition: table_walker.hh:899
Stats::dist
const FlagsType dist
Print the distribution.
Definition: info.hh:56
name
const std::string & name()
Definition: trace.cc:48
Stats::VectorBase::init
Derived & init(size_type size)
Set this vector to have the given size.
Definition: statistics.hh:1028
Request
Definition: request.hh:91
ArmISA::TableWalker::WalkerState::isFetch
bool isFetch
If the access is a fetch (for execution, and no-exec) must be checked?
Definition: table_walker.hh:783
ArmISA::TableWalker::TableWalkerStats::walksShortTerminatedAtLevel
Stats::Vector walksShortTerminatedAtLevel
Definition: table_walker.hh:898
Clocked::clockPeriod
Tick clockPeriod() const
Definition: clocked_object.hh:214
ArmISA::TableWalker::generateLongDescFault
Fault generateLongDescFault(ArmFault::FaultSource src)
Definition: table_walker.cc:1686
ArmISA::TableWalker::memAttrsLPAE
void memAttrsLPAE(ThreadContext *tc, TlbEntry &te, LongDescriptor &lDescriptor)
Definition: table_walker.cc:1355
ArmISA::TableWalker::WalkerState::htcr
HTCR htcr
Cached copy of the htcr as it existed when translation began.
Definition: table_walker.hh:771
Stats::nozero
const FlagsType nozero
Don't print if this is zero.
Definition: info.hh:58
ArmISA::MISCREG_NMRR
@ MISCREG_NMRR
Definition: miscregs.hh:371
ArmISA::MISCREG_TTBR1
@ MISCREG_TTBR1
Definition: miscregs.hh:253
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:109
DmaPort::dmaAction
void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, uint8_t *data, Tick delay, Request::Flags flag=0)
Definition: dma_device.cc:193
X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:80
BaseTLB::Write
@ Write
Definition: tlb.hh:57
ArmISA::TableWalker::WalkerState::hpd
bool hpd
Hierarchical access permission disable.
Definition: table_walker.hh:800
ArmISA::MISCREG_PRRR
@ MISCREG_PRRR
Definition: miscregs.hh:365
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:753
ArmISA::TableWalker::WalkerState::vaddr
Addr vaddr
The virtual address that is being translated with tagging removed.
Definition: table_walker.hh:750
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:1922
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:374
ArmISA::TableWalker::pendingReqs
unsigned pendingReqs
Definition: table_walker.hh:909
ArmISA::MISCREG_CPSR
@ MISCREG_CPSR
Definition: miscregs.hh:57
ArmISA::TableWalker::tlb
TLB * tlb
TLB that is initiating these table walks.
Definition: table_walker.hh:871
ArmISA::TableWalker::LongDescriptor::sh
uint8_t sh() const
2-bit shareability field
Definition: table_walker.hh:605
ArmISA::TableWalker::LongDescriptor::paddr
Addr paddr() const
Return the physical address of the entry.
Definition: table_walker.hh:508
base.hh
ArmISA::TableWalker::TableWalkerStats::requestOrigin
Stats::Vector2d requestOrigin
Definition: table_walker.hh:906
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:789
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:1108
Stats::pdf
const FlagsType pdf
Print the percent of the total that this entry represents.
Definition: info.hh:52
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:856
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:726
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:258
Request::UNCACHEABLE
@ UNCACHEABLE
The request is to an uncacheable address.
Definition: request.hh:118
Stats::Group
Statistics container.
Definition: group.hh:87
ThreadContext::readMiscReg
virtual RegVal readMiscReg(RegIndex misc_reg)=0
ArmISA::TableWalker::checkVAddrSizeFaultAArch64
bool checkVAddrSizeFaultAArch64(Addr addr, int top_bit, GrainSize granule, int tsz, bool low_range)
Definition: table_walker.cc:750
ArmISA::MISCREG_VSTCR_EL2
@ MISCREG_VSTCR_EL2
Definition: miscregs.hh:604
ArmISA::TableWalker::DescriptorBase::domain
virtual TlbEntry::DomainType domain() const =0
ArmISA::MiscRegIndex
MiscRegIndex
Definition: miscregs.hh:56
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:559
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:259
Stats::Vector2dBase::init
Derived & init(size_type _x, size_type _y)
Definition: statistics.hh:1166
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:1323
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:79
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:756
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:383
bits
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:73
ArmISA::TableWalker::COMPLETED
static const unsigned COMPLETED
Definition: table_walker.hh:913
ArmISA::TableWalker
Definition: table_walker.hh:61
ArmISA::MISCREG_MAIR0
@ MISCREG_MAIR0
Definition: miscregs.hh:368
Stats
Definition: statistics.cc:53
ArmISA::MISCREG_MAIR_EL3
@ MISCREG_MAIR_EL3
Definition: miscregs.hh:728
ArmISA::TableWalker::doL1LongDescriptorWrapper
void doL1LongDescriptorWrapper()
Definition: table_walker.cc:2025
ArmISA::MISCREG_MAIR_EL1
@ MISCREG_MAIR_EL1
Definition: miscregs.hh:722
ArmISA::TableWalker::LongDescriptor::xnTable
bool xnTable() const
Is execution allowed on subsequent lookup levels?
Definition: table_walker.hh:706
ArmISA::TableWalker::doL1DescEvent
EventFunctionWrapper doL1DescEvent
Definition: table_walker.hh:956
curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:43
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:566
ArmISA::TlbEntry::MemoryType::Normal
@ Normal
ArmISA::MISCREG_VTCR_EL2
@ MISCREG_VTCR_EL2
Definition: miscregs.hh:602
ArmISA::MISCREG_TTBR1_EL2
@ MISCREG_TTBR1_EL2
Definition: miscregs.hh:816
ArmISA::TableWalker::doL2DescEvent
EventFunctionWrapper doL2DescEvent
Definition: table_walker.hh:960
ArmISA::MISCREG_SCTLR
@ MISCREG_SCTLR
Definition: miscregs.hh:231
Stats::Histogram::init
Histogram & init(size_type size)
Set the parameters of this histogram.
Definition: statistics.hh:2153
SimObject::params
const Params & params() const
Definition: sim_object.hh:168
ArmISA::pa
Bitfield< 39, 12 > pa
Definition: miscregs_types.hh:650
ArmISA::TableWalker::currState
WalkerState * currState
Definition: table_walker.hh:876
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:1706
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:744
ArmISA::MISCREG_SCTLR_EL3
@ MISCREG_SCTLR_EL3
Definition: miscregs.hh:587
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:50
ArmISA::TableWalker::WalkerState::fault
Fault fault
The fault that we are going to return.
Definition: table_walker.hh:747
BaseTLB::Execute
@ Execute
Definition: tlb.hh:57
ArmISA::TableWalker::WalkerState::ttbcr
TTBCR ttbcr
Definition: table_walker.hh:766
ArmISA::TableWalker::TableWalkerStats::squashedAfter
Stats::Scalar squashedAfter
Definition: table_walker.hh:901
ArmISA::TableWalker::WalkerState::l2Desc
L2Descriptor l2Desc
Definition: table_walker.hh:822
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:900
ArmISA::MISCREG_SCTLR_EL2
@ MISCREG_SCTLR_EL2
Definition: miscregs.hh:580
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:444
thread_context.hh
ArmISA::TLB::translateTiming
void translateTiming(const RequestPtr &req, ThreadContext *tc, Translation *translation, Mode mode, ArmTranslationType tranType)
Definition: tlb.cc:1304
ULL
#define ULL(N)
uint64_t constant
Definition: types.hh:46
Stats::nonan
const FlagsType nonan
Don't print if this is NAN.
Definition: info.hh:60
RegVal
uint64_t RegVal
Definition: types.hh:174
ArmISA::TableWalker::insertTableEntry
void insertTableEntry(DescriptorBase &descriptor, bool longDescriptor)
Definition: table_walker.cc:2180
ArmISA::TableWalker::_physAddrRange
uint8_t _physAddrRange
Definition: table_walker.hh:889
ArmISA::TableWalker::TableWalkerStats::pendingWalks
Stats::Histogram pendingWalks
Definition: table_walker.hh:904
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:575
ArmISA::L3
@ L3
Definition: pagetable.hh:76
ArmISA::isSecure
bool isSecure(ThreadContext *tc)
Definition: utility.cc:112
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:879
ArmISA::TableWalker::doL1Descriptor
void doL1Descriptor()
Definition: table_walker.cc:1581
ArmSystem::haveLargeAsid64
bool haveLargeAsid64() const
Returns true if ASID is 16 bits in AArch64 (ARMv8)
Definition: system.hh:221
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
ArmISA::TLB::insert
void insert(Addr vaddr, TlbEntry &pte)
Definition: tlb.cc:211
ArmISA::TableWalker::L1Descriptor::PageTable
@ PageTable
Definition: table_walker.hh:97

Generated on Tue Jun 22 2021 15:28:21 for gem5 by doxygen 1.8.17