gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
table_walker.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, 2012-2017 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  * Authors: Ali Saidi
38  * Giacomo Gabrielli
39  */
40 #include "arch/arm/table_walker.hh"
41 
42 #include <memory>
43 
44 #include "arch/arm/faults.hh"
45 #include "arch/arm/stage2_mmu.hh"
46 #include "arch/arm/system.hh"
47 #include "arch/arm/tlb.hh"
48 #include "cpu/base.hh"
49 #include "cpu/thread_context.hh"
50 #include "debug/Checkpoint.hh"
51 #include "debug/Drain.hh"
52 #include "debug/TLB.hh"
53 #include "debug/TLBVerbose.hh"
54 #include "dev/dma_device.hh"
55 #include "sim/system.hh"
56 
57 using namespace ArmISA;
58 
60  : MemObject(p),
61  stage2Mmu(NULL), port(NULL), masterId(Request::invldMasterId),
62  isStage2(p->is_stage2), tlb(NULL),
63  currState(NULL), pending(false),
64  numSquashable(p->num_squash_per_cycle),
65  pendingReqs(0),
66  pendingChangeTick(curTick()),
67  doL1DescEvent(this), doL2DescEvent(this),
68  doL0LongDescEvent(this), doL1LongDescEvent(this),
69  doL2LongDescEvent(this), doL3LongDescEvent(this),
70  LongDescEventByLevel { &doL0LongDescEvent, &doL1LongDescEvent,
72  doProcessEvent(this)
73 {
74  sctlr = 0;
75 
76  // Cache system-level properties
77  if (FullSystem) {
78  ArmSystem *armSys = dynamic_cast<ArmSystem *>(p->sys);
79  assert(armSys);
80  haveSecurity = armSys->haveSecurity();
81  _haveLPAE = armSys->haveLPAE();
82  _haveVirtualization = armSys->haveVirtualization();
83  physAddrRange = armSys->physAddrRange();
84  _haveLargeAsid64 = armSys->haveLargeAsid64();
85  } else {
86  haveSecurity = _haveLPAE = _haveVirtualization = false;
87  _haveLargeAsid64 = false;
88  physAddrRange = 32;
89  }
90 
91 }
92 
94 {
95  ;
96 }
97 
98 void
100 {
101  stage2Mmu = m;
102  port = &m->getPort();
103  masterId = master_id;
104 }
105 
106 void
108 {
109  fatal_if(!stage2Mmu, "Table walker must have a valid stage-2 MMU\n");
110  fatal_if(!port, "Table walker must have a valid port\n");
111  fatal_if(!tlb, "Table walker must have a valid TLB\n");
112 }
113 
115 TableWalker::getMasterPort(const std::string &if_name, PortID idx)
116 {
117  if (if_name == "port") {
118  if (!isStage2) {
119  return *port;
120  } else {
121  fatal("Cannot access table walker port through stage-two walker\n");
122  }
123  }
124  return MemObject::getMasterPort(if_name, idx);
125 }
126 
128  tc(nullptr), aarch64(false), el(EL0), physAddrRange(0), req(nullptr),
129  asid(0), vmid(0), isHyp(false), transState(nullptr),
130  vaddr(0), vaddr_tainted(0), isWrite(false), isFetch(false), isSecure(false),
131  secureLookup(false), rwTable(false), userTable(false), xnTable(false),
132  pxnTable(false), stage2Req(false), doingStage2(false),
133  stage2Tran(nullptr), timing(false), functional(false),
134  mode(BaseTLB::Read), tranType(TLB::NormalTran), l2Desc(l1Desc),
135  delayed(false), tableWalker(nullptr)
136 {
137 }
138 
139 void
141 {
142  if (drainState() == DrainState::Draining &&
143  stateQueues[L0].empty() && stateQueues[L1].empty() &&
144  stateQueues[L2].empty() && stateQueues[L3].empty() &&
145  pendingQueue.empty()) {
146 
147  DPRINTF(Drain, "TableWalker done draining, processing drain event\n");
148  signalDrainDone();
149  }
150 }
151 
154 {
155  bool state_queues_not_empty = false;
156 
157  for (int i = 0; i < MAX_LOOKUP_LEVELS; ++i) {
158  if (!stateQueues[i].empty()) {
159  state_queues_not_empty = true;
160  break;
161  }
162  }
163 
164  if (state_queues_not_empty || pendingQueue.size()) {
165  DPRINTF(Drain, "TableWalker not drained\n");
166  return DrainState::Draining;
167  } else {
168  DPRINTF(Drain, "TableWalker free, no need to drain\n");
169  return DrainState::Drained;
170  }
171 }
172 
173 void
175 {
176  if (params()->sys->isTimingMode() && currState) {
177  delete currState;
178  currState = NULL;
179  pendingChange();
180  }
181 }
182 
183 Fault
184 TableWalker::walk(RequestPtr _req, ThreadContext *_tc, uint16_t _asid,
185  uint8_t _vmid, bool _isHyp, TLB::Mode _mode,
186  TLB::Translation *_trans, bool _timing, bool _functional,
187  bool secure, TLB::ArmTranslationType tranType,
188  bool _stage2Req)
189 {
190  assert(!(_functional && _timing));
191  ++statWalks;
192 
193  WalkerState *savedCurrState = NULL;
194 
195  if (!currState && !_functional) {
196  // For atomic mode, a new WalkerState instance should be only created
197  // once per TLB. For timing mode, a new instance is generated for every
198  // TLB miss.
199  DPRINTF(TLBVerbose, "creating new instance of WalkerState\n");
200 
201  currState = new WalkerState();
202  currState->tableWalker = this;
203  } else if (_functional) {
204  // If we are mixing functional mode with timing (or even
205  // atomic), we need to to be careful and clean up after
206  // ourselves to not risk getting into an inconsistent state.
207  DPRINTF(TLBVerbose, "creating functional instance of WalkerState\n");
208  savedCurrState = currState;
209  currState = new WalkerState();
210  currState->tableWalker = this;
211  } else if (_timing) {
212  // This is a translation that was completed and then faulted again
213  // because some underlying parameters that affect the translation
214  // changed out from under us (e.g. asid). It will either be a
215  // misprediction, in which case nothing will happen or we'll use
216  // this fault to re-execute the faulting instruction which should clean
217  // up everything.
218  if (currState->vaddr_tainted == _req->getVaddr()) {
220  return std::make_shared<ReExec>();
221  }
222  }
223  pendingChange();
224 
226  currState->tc = _tc;
227  // ARM DDI 0487A.f (ARMv8 ARM) pg J8-5672
228  // aarch32/translation/translation/AArch32.TranslateAddress dictates
229  // even AArch32 EL0 will use AArch64 translation if EL1 is in AArch64.
230  currState->aarch64 = isStage2 || opModeIs64(currOpMode(_tc)) ||
231  ((currEL(_tc) == EL0) && ELIs64(_tc, EL1));
232  currState->el = currEL(_tc);
233  currState->transState = _trans;
234  currState->req = _req;
236  currState->asid = _asid;
237  currState->vmid = _vmid;
238  currState->isHyp = _isHyp;
239  currState->timing = _timing;
240  currState->functional = _functional;
241  currState->mode = _mode;
242  currState->tranType = tranType;
243  currState->isSecure = secure;
245 
249  if (currState->aarch64)
251  currState->tc, currState->el);
252  else
254 
255  if (currState->aarch64) {
256  if (isStage2) {
259  } else switch (currState->el) {
260  case EL0:
261  case EL1:
264  break;
265  case EL2:
266  assert(_haveVirtualization);
269  break;
270  case EL3:
271  assert(haveSecurity);
274  break;
275  default:
276  panic("Invalid exception level");
277  break;
278  }
280  } else {
288  }
289  sctlr = currState->sctlr;
290 
293 
295 
296  // We only do a second stage of translation if we're not secure, or in
297  // hyp mode, the second stage MMU is enabled, and this table walker
298  // instance is the first stage.
299  // TODO: fix setting of doingStage2 for timing mode
300  currState->doingStage2 = false;
301  currState->stage2Req = _stage2Req && !isStage2;
302 
303  bool long_desc_format = currState->aarch64 || _isHyp || isStage2 ||
305 
306  if (long_desc_format) {
307  // Helper variables used for hierarchical permissions
309  currState->rwTable = true;
310  currState->userTable = true;
311  currState->xnTable = false;
312  currState->pxnTable = false;
313 
315  } else {
317  }
318 
319  if (!currState->timing) {
320  Fault fault = NoFault;
321  if (currState->aarch64)
322  fault = processWalkAArch64();
323  else if (long_desc_format)
324  fault = processWalkLPAE();
325  else
326  fault = processWalk();
327 
328  // If this was a functional non-timing access restore state to
329  // how we found it.
330  if (currState->functional) {
331  delete currState;
332  currState = savedCurrState;
333  }
334  return fault;
335  }
336 
337  if (pending || pendingQueue.size()) {
338  pendingQueue.push_back(currState);
339  currState = NULL;
340  pendingChange();
341  } else {
342  pending = true;
343  pendingChange();
344  if (currState->aarch64)
345  return processWalkAArch64();
346  else if (long_desc_format)
347  return processWalkLPAE();
348  else
349  return processWalk();
350  }
351 
352  return NoFault;
353 }
354 
355 void
357 {
358  assert(!currState);
359  assert(pendingQueue.size());
360  pendingChange();
361  currState = pendingQueue.front();
362 
363  ExceptionLevel target_el = EL0;
364  if (currState->aarch64)
365  target_el = currEL(currState->tc);
366  else
367  target_el = EL1;
368 
369  // Check if a previous walk filled this request already
370  // @TODO Should this always be the TLB or should we look in the stage2 TLB?
372  currState->vmid, currState->isHyp, currState->isSecure, true, false,
373  target_el);
374 
375  // Check if we still need to have a walk for this request. If the requesting
376  // instruction has been squashed, or a previous walk has filled the TLB with
377  // a match, we just want to get rid of the walk. The latter could happen
378  // when there are multiple outstanding misses to a single page and a
379  // previous request has been successfully translated.
380  if (!currState->transState->squashed() && !te) {
381  // We've got a valid request, lets process it
382  pending = true;
383  pendingQueue.pop_front();
384  // Keep currState in case one of the processWalk... calls NULLs it
385  WalkerState *curr_state_copy = currState;
386  Fault f;
387  if (currState->aarch64)
388  f = processWalkAArch64();
389  else if (longDescFormatInUse(currState->tc) ||
391  f = processWalkLPAE();
392  else
393  f = processWalk();
394 
395  if (f != NoFault) {
396  curr_state_copy->transState->finish(f, curr_state_copy->req,
397  curr_state_copy->tc, curr_state_copy->mode);
398 
399  delete curr_state_copy;
400  }
401  return;
402  }
403 
404 
405  // If the instruction that we were translating for has been
406  // squashed we shouldn't bother.
407  unsigned num_squashed = 0;
408  ThreadContext *tc = currState->tc;
409  while ((num_squashed < numSquashable) && currState &&
410  (currState->transState->squashed() || te)) {
411  pendingQueue.pop_front();
412  num_squashed++;
414 
415  DPRINTF(TLB, "Squashing table walk for address %#x\n",
417 
418  if (currState->transState->squashed()) {
419  // finish the translation which will delete the translation object
421  std::make_shared<UnimpFault>("Squashed Inst"),
423  } else {
424  // translate the request now that we know it will work
428 
429  }
430 
431  // delete the current request
432  delete currState;
433 
434  // peak at the next one
435  if (pendingQueue.size()) {
436  currState = pendingQueue.front();
439  false, target_el);
440  } else {
441  // Terminate the loop, nothing more to do
442  currState = NULL;
443  }
444  }
445  pendingChange();
446 
447  // if we still have pending translations, schedule more work
448  nextWalk(tc);
449  currState = NULL;
450 }
451 
452 Fault
454 {
455  Addr ttbr = 0;
456 
457  // If translation isn't enabled, we shouldn't be here
458  assert(currState->sctlr.m || isStage2);
459 
460  DPRINTF(TLB, "Beginning table walk for address %#x, TTBCR: %#x, bits:%#x\n",
462  32 - currState->ttbcr.n));
463 
465 
466  if (currState->ttbcr.n == 0 || !mbits(currState->vaddr, 31,
467  32 - currState->ttbcr.n)) {
468  DPRINTF(TLB, " - Selecting TTBR0\n");
469  // Check if table walk is allowed when Security Extensions are enabled
470  if (haveSecurity && currState->ttbcr.pd0) {
471  if (currState->isFetch)
472  return std::make_shared<PrefetchAbort>(
475  isStage2,
477  else
478  return std::make_shared<DataAbort>(
483  }
486  } else {
487  DPRINTF(TLB, " - Selecting TTBR1\n");
488  // Check if table walk is allowed when Security Extensions are enabled
489  if (haveSecurity && currState->ttbcr.pd1) {
490  if (currState->isFetch)
491  return std::make_shared<PrefetchAbort>(
494  isStage2,
496  else
497  return std::make_shared<DataAbort>(
502  }
505  currState->ttbcr.n = 0;
506  }
507 
508  Addr l1desc_addr = mbits(ttbr, 31, 14 - currState->ttbcr.n) |
509  (bits(currState->vaddr, 31 - currState->ttbcr.n, 20) << 2);
510  DPRINTF(TLB, " - Descriptor at address %#x (%s)\n", l1desc_addr,
511  currState->isSecure ? "s" : "ns");
512 
513  // Trickbox address check
514  Fault f;
515  f = testWalk(l1desc_addr, sizeof(uint32_t),
517  if (f) {
518  DPRINTF(TLB, "Trickbox check caused fault on %#x\n", currState->vaddr_tainted);
519  if (currState->timing) {
520  pending = false;
522  currState = NULL;
523  } else {
524  currState->tc = NULL;
525  currState->req = NULL;
526  }
527  return f;
528  }
529 
531  if (currState->sctlr.c == 0) {
533  }
534 
535  if (currState->isSecure) {
536  flag.set(Request::SECURE);
537  }
538 
539  bool delayed;
540  delayed = fetchDescriptor(l1desc_addr, (uint8_t*)&currState->l1Desc.data,
541  sizeof(uint32_t), flag, L1, &doL1DescEvent,
543  if (!delayed) {
544  f = currState->fault;
545  }
546 
547  return f;
548 }
549 
550 Fault
552 {
553  Addr ttbr, ttbr0_max, ttbr1_min, desc_addr;
554  int tsz, n;
555  LookupLevel start_lookup_level = L1;
556 
557  DPRINTF(TLB, "Beginning table walk for address %#x, TTBCR: %#x\n",
559 
561 
563  if (currState->isSecure)
564  flag.set(Request::SECURE);
565 
566  // work out which base address register to use, if in hyp mode we always
567  // use HTTBR
568  if (isStage2) {
569  DPRINTF(TLB, " - Selecting VTTBR (long-desc.)\n");
571  tsz = sext<4>(currState->vtcr.t0sz);
572  start_lookup_level = currState->vtcr.sl0 ? L1 : L2;
573  } else if (currState->isHyp) {
574  DPRINTF(TLB, " - Selecting HTTBR (long-desc.)\n");
576  tsz = currState->htcr.t0sz;
577  } else {
578  assert(longDescFormatInUse(currState->tc));
579 
580  // Determine boundaries of TTBR0/1 regions
581  if (currState->ttbcr.t0sz)
582  ttbr0_max = (1ULL << (32 - currState->ttbcr.t0sz)) - 1;
583  else if (currState->ttbcr.t1sz)
584  ttbr0_max = (1ULL << 32) -
585  (1ULL << (32 - currState->ttbcr.t1sz)) - 1;
586  else
587  ttbr0_max = (1ULL << 32) - 1;
588  if (currState->ttbcr.t1sz)
589  ttbr1_min = (1ULL << 32) - (1ULL << (32 - currState->ttbcr.t1sz));
590  else
591  ttbr1_min = (1ULL << (32 - currState->ttbcr.t0sz));
592 
593  // The following code snippet selects the appropriate translation table base
594  // address (TTBR0 or TTBR1) and the appropriate starting lookup level
595  // depending on the address range supported by the translation table (ARM
596  // ARM issue C B3.6.4)
597  if (currState->vaddr <= ttbr0_max) {
598  DPRINTF(TLB, " - Selecting TTBR0 (long-desc.)\n");
599  // Check if table walk is allowed
600  if (currState->ttbcr.epd0) {
601  if (currState->isFetch)
602  return std::make_shared<PrefetchAbort>(
605  isStage2,
607  else
608  return std::make_shared<DataAbort>(
613  isStage2,
615  }
618  tsz = currState->ttbcr.t0sz;
619  if (ttbr0_max < (1ULL << 30)) // Upper limit < 1 GB
620  start_lookup_level = L2;
621  } else if (currState->vaddr >= ttbr1_min) {
622  DPRINTF(TLB, " - Selecting TTBR1 (long-desc.)\n");
623  // Check if table walk is allowed
624  if (currState->ttbcr.epd1) {
625  if (currState->isFetch)
626  return std::make_shared<PrefetchAbort>(
629  isStage2,
631  else
632  return std::make_shared<DataAbort>(
637  isStage2,
639  }
642  tsz = currState->ttbcr.t1sz;
643  if (ttbr1_min >= (1ULL << 31) + (1ULL << 30)) // Lower limit >= 3 GB
644  start_lookup_level = L2;
645  } else {
646  // Out of boundaries -> translation fault
647  if (currState->isFetch)
648  return std::make_shared<PrefetchAbort>(
651  isStage2,
653  else
654  return std::make_shared<DataAbort>(
659  }
660 
661  }
662 
663  // Perform lookup (ARM ARM issue C B3.6.6)
664  if (start_lookup_level == L1) {
665  n = 5 - tsz;
666  desc_addr = mbits(ttbr, 39, n) |
667  (bits(currState->vaddr, n + 26, 30) << 3);
668  DPRINTF(TLB, " - Descriptor at address %#x (%s) (long-desc.)\n",
669  desc_addr, currState->isSecure ? "s" : "ns");
670  } else {
671  // Skip first-level lookup
672  n = (tsz >= 2 ? 14 - tsz : 12);
673  desc_addr = mbits(ttbr, 39, n) |
674  (bits(currState->vaddr, n + 17, 21) << 3);
675  DPRINTF(TLB, " - Descriptor at address %#x (%s) (long-desc.)\n",
676  desc_addr, currState->isSecure ? "s" : "ns");
677  }
678 
679  // Trickbox address check
680  Fault f = testWalk(desc_addr, sizeof(uint64_t),
681  TlbEntry::DomainType::NoAccess, start_lookup_level);
682  if (f) {
683  DPRINTF(TLB, "Trickbox check caused fault on %#x\n", currState->vaddr_tainted);
684  if (currState->timing) {
685  pending = false;
687  currState = NULL;
688  } else {
689  currState->tc = NULL;
690  currState->req = NULL;
691  }
692  return f;
693  }
694 
695  if (currState->sctlr.c == 0) {
697  }
698 
699  currState->longDesc.lookupLevel = start_lookup_level;
700  currState->longDesc.aarch64 = false;
702 
703  bool delayed = fetchDescriptor(desc_addr, (uint8_t*)&currState->longDesc.data,
704  sizeof(uint64_t), flag, start_lookup_level,
705  LongDescEventByLevel[start_lookup_level],
707  if (!delayed) {
708  f = currState->fault;
709  }
710 
711  return f;
712 }
713 
714 unsigned
716 {
717  if (tsz < 25)
718  return 25;
719  if (tsz > 48)
720  return 48;
721  return tsz;
722 }
723 
724 bool
726 {
727  return (currPhysAddrRange != MaxPhysAddrRange &&
728  bits(addr, MaxPhysAddrRange - 1, currPhysAddrRange));
729 }
730 
731 Fault
733 {
734  assert(currState->aarch64);
735 
736  DPRINTF(TLB, "Beginning table walk for address %#llx, TCR: %#llx\n",
738 
739  static const GrainSize GrainMapDefault[] =
741  static const GrainSize GrainMap_EL1_tg1[] =
743 
745 
746  // Determine TTBR, table size, granule size and phys. address range
747  Addr ttbr = 0;
748  int tsz = 0, ps = 0;
749  GrainSize tg = Grain4KB; // grain size computed from tg* field
750  bool fault = false;
751 
752  LookupLevel start_lookup_level = MAX_LOOKUP_LEVELS;
753 
754  switch (currState->el) {
755  case EL0:
756  case EL1:
757  if (isStage2) {
758  DPRINTF(TLB, " - Selecting VTTBR0 (AArch64 stage 2)\n");
760  tsz = 64 - currState->vtcr.t0sz64;
761  tg = GrainMapDefault[currState->vtcr.tg0];
762  // ARM DDI 0487A.f D7-2148
763  // The starting level of stage 2 translation depends on
764  // VTCR_EL2.SL0 and VTCR_EL2.TG0
765  LookupLevel __ = MAX_LOOKUP_LEVELS; // invalid level
766  uint8_t sl_tg = (currState->vtcr.sl0 << 2) | currState->vtcr.tg0;
767  static const LookupLevel SLL[] = {
768  L2, L3, L3, __, // sl0 == 0
769  L1, L2, L2, __, // sl0 == 1, etc.
770  L0, L1, L1, __,
771  __, __, __, __
772  };
773  start_lookup_level = SLL[sl_tg];
774  panic_if(start_lookup_level == MAX_LOOKUP_LEVELS,
775  "Cannot discern lookup level from vtcr.{sl0,tg0}");
776  } else switch (bits(currState->vaddr, 63,48)) {
777  case 0:
778  DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n");
780  tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz);
781  tg = GrainMapDefault[currState->tcr.tg0];
782  if (bits(currState->vaddr, 63, tsz) != 0x0 ||
783  currState->tcr.epd0)
784  fault = true;
785  break;
786  case 0xffff:
787  DPRINTF(TLB, " - Selecting TTBR1 (AArch64)\n");
789  tsz = adjustTableSizeAArch64(64 - currState->tcr.t1sz);
790  tg = GrainMap_EL1_tg1[currState->tcr.tg1];
791  if (bits(currState->vaddr, 63, tsz) != mask(64-tsz) ||
792  currState->tcr.epd1)
793  fault = true;
794  break;
795  default:
796  // top two bytes must be all 0s or all 1s, else invalid addr
797  fault = true;
798  }
799  ps = currState->tcr.ips;
800  break;
801  case EL2:
802  case EL3:
803  switch(bits(currState->vaddr, 63,48)) {
804  case 0:
805  DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n");
806  if (currState->el == EL2)
808  else
810  tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz);
811  tg = GrainMapDefault[currState->tcr.tg0];
812  break;
813  default:
814  // invalid addr if top two bytes are not all 0s
815  fault = true;
816  }
817  ps = currState->tcr.ips;
818  break;
819  }
820 
821  if (fault) {
822  Fault f;
823  if (currState->isFetch)
824  f = std::make_shared<PrefetchAbort>(
828  else
829  f = std::make_shared<DataAbort>(
835 
836  if (currState->timing) {
837  pending = false;
839  currState = NULL;
840  } else {
841  currState->tc = NULL;
842  currState->req = NULL;
843  }
844  return f;
845 
846  }
847 
848  if (tg == ReservedGrain) {
849  warn_once("Reserved granule size requested; gem5's IMPLEMENTATION "
850  "DEFINED behavior takes this to mean 4KB granules\n");
851  tg = Grain4KB;
852  }
853 
854  // Determine starting lookup level
855  // See aarch64/translation/walk in Appendix G: ARMv8 Pseudocode Library
856  // in ARM DDI 0487A. These table values correspond to the cascading tests
857  // to compute the lookup level and are of the form
858  // (grain_size + N*stride), for N = {1, 2, 3}.
859  // A value of 64 will never succeed and a value of 0 will always succeed.
860  if (start_lookup_level == MAX_LOOKUP_LEVELS) {
861  struct GrainMap {
862  GrainSize grain_size;
863  unsigned lookup_level_cutoff[MAX_LOOKUP_LEVELS];
864  };
865  static const GrainMap GM[] = {
866  { Grain4KB, { 39, 30, 0, 0 } },
867  { Grain16KB, { 47, 36, 25, 0 } },
868  { Grain64KB, { 64, 42, 29, 0 } }
869  };
870 
871  const unsigned *lookup = NULL; // points to a lookup_level_cutoff
872 
873  for (unsigned i = 0; i < 3; ++i) { // choose entry of GM[]
874  if (tg == GM[i].grain_size) {
875  lookup = GM[i].lookup_level_cutoff;
876  break;
877  }
878  }
879  assert(lookup);
880 
881  for (int L = L0; L != MAX_LOOKUP_LEVELS; ++L) {
882  if (tsz > lookup[L]) {
883  start_lookup_level = (LookupLevel) L;
884  break;
885  }
886  }
887  panic_if(start_lookup_level == MAX_LOOKUP_LEVELS,
888  "Table walker couldn't find lookup level\n");
889  }
890 
891  int stride = tg - 3;
892 
893  // Determine table base address
894  int base_addr_lo = 3 + tsz - stride * (3 - start_lookup_level) - tg;
895  Addr base_addr = mbits(ttbr, 47, base_addr_lo);
896 
897  // Determine physical address size and raise an Address Size Fault if
898  // necessary
899  int pa_range = decodePhysAddrRange64(ps);
900  // Clamp to lower limit
901  if (pa_range > physAddrRange)
903  else
904  currState->physAddrRange = pa_range;
906  DPRINTF(TLB, "Address size fault before any lookup\n");
907  Fault f;
908  if (currState->isFetch)
909  f = std::make_shared<PrefetchAbort>(
911  ArmFault::AddressSizeLL + start_lookup_level,
912  isStage2,
914  else
915  f = std::make_shared<DataAbort>(
919  ArmFault::AddressSizeLL + start_lookup_level,
920  isStage2,
922 
923 
924  if (currState->timing) {
925  pending = false;
927  currState = NULL;
928  } else {
929  currState->tc = NULL;
930  currState->req = NULL;
931  }
932  return f;
933 
934  }
935 
936  // Determine descriptor address
937  Addr desc_addr = base_addr |
938  (bits(currState->vaddr, tsz - 1,
939  stride * (3 - start_lookup_level) + tg) << 3);
940 
941  // Trickbox address check
942  Fault f = testWalk(desc_addr, sizeof(uint64_t),
943  TlbEntry::DomainType::NoAccess, start_lookup_level);
944  if (f) {
945  DPRINTF(TLB, "Trickbox check caused fault on %#x\n", currState->vaddr_tainted);
946  if (currState->timing) {
947  pending = false;
949  currState = NULL;
950  } else {
951  currState->tc = NULL;
952  currState->req = NULL;
953  }
954  return f;
955  }
956 
958  if (currState->sctlr.c == 0) {
959  flag.set(Request::UNCACHEABLE);
960  }
961 
962  if (currState->isSecure) {
963  flag.set(Request::SECURE);
964  }
965 
966  currState->longDesc.lookupLevel = start_lookup_level;
967  currState->longDesc.aarch64 = true;
969 
970  if (currState->timing) {
971  fetchDescriptor(desc_addr, (uint8_t*) &currState->longDesc.data,
972  sizeof(uint64_t), flag, start_lookup_level,
973  LongDescEventByLevel[start_lookup_level], NULL);
974  } else {
975  fetchDescriptor(desc_addr, (uint8_t*)&currState->longDesc.data,
976  sizeof(uint64_t), flag, -1, NULL,
978  f = currState->fault;
979  }
980 
981  return f;
982 }
983 
984 void
986  uint8_t texcb, bool s)
987 {
988  // Note: tc and sctlr local variables are hiding tc and sctrl class
989  // variables
990  DPRINTF(TLBVerbose, "memAttrs texcb:%d s:%d\n", texcb, s);
991  te.shareable = false; // default value
992  te.nonCacheable = false;
993  te.outerShareable = false;
994  if (sctlr.tre == 0 || ((sctlr.tre == 1) && (sctlr.m == 0))) {
995  switch(texcb) {
996  case 0: // Stongly-ordered
997  te.nonCacheable = true;
999  te.shareable = true;
1000  te.innerAttrs = 1;
1001  te.outerAttrs = 0;
1002  break;
1003  case 1: // Shareable Device
1004  te.nonCacheable = true;
1006  te.shareable = true;
1007  te.innerAttrs = 3;
1008  te.outerAttrs = 0;
1009  break;
1010  case 2: // Outer and Inner Write-Through, no Write-Allocate
1012  te.shareable = s;
1013  te.innerAttrs = 6;
1014  te.outerAttrs = bits(texcb, 1, 0);
1015  break;
1016  case 3: // Outer and Inner Write-Back, no Write-Allocate
1018  te.shareable = s;
1019  te.innerAttrs = 7;
1020  te.outerAttrs = bits(texcb, 1, 0);
1021  break;
1022  case 4: // Outer and Inner Non-cacheable
1023  te.nonCacheable = true;
1025  te.shareable = s;
1026  te.innerAttrs = 0;
1027  te.outerAttrs = bits(texcb, 1, 0);
1028  break;
1029  case 5: // Reserved
1030  panic("Reserved texcb value!\n");
1031  break;
1032  case 6: // Implementation Defined
1033  panic("Implementation-defined texcb value!\n");
1034  break;
1035  case 7: // Outer and Inner Write-Back, Write-Allocate
1037  te.shareable = s;
1038  te.innerAttrs = 5;
1039  te.outerAttrs = 1;
1040  break;
1041  case 8: // Non-shareable Device
1042  te.nonCacheable = true;
1044  te.shareable = false;
1045  te.innerAttrs = 3;
1046  te.outerAttrs = 0;
1047  break;
1048  case 9 ... 15: // Reserved
1049  panic("Reserved texcb value!\n");
1050  break;
1051  case 16 ... 31: // Cacheable Memory
1053  te.shareable = s;
1054  if (bits(texcb, 1,0) == 0 || bits(texcb, 3,2) == 0)
1055  te.nonCacheable = true;
1056  te.innerAttrs = bits(texcb, 1, 0);
1057  te.outerAttrs = bits(texcb, 3, 2);
1058  break;
1059  default:
1060  panic("More than 32 states for 5 bits?\n");
1061  }
1062  } else {
1063  assert(tc);
1068  DPRINTF(TLBVerbose, "memAttrs PRRR:%08x NMRR:%08x\n", prrr, nmrr);
1069  uint8_t curr_tr = 0, curr_ir = 0, curr_or = 0;
1070  switch(bits(texcb, 2,0)) {
1071  case 0:
1072  curr_tr = prrr.tr0;
1073  curr_ir = nmrr.ir0;
1074  curr_or = nmrr.or0;
1075  te.outerShareable = (prrr.nos0 == 0);
1076  break;
1077  case 1:
1078  curr_tr = prrr.tr1;
1079  curr_ir = nmrr.ir1;
1080  curr_or = nmrr.or1;
1081  te.outerShareable = (prrr.nos1 == 0);
1082  break;
1083  case 2:
1084  curr_tr = prrr.tr2;
1085  curr_ir = nmrr.ir2;
1086  curr_or = nmrr.or2;
1087  te.outerShareable = (prrr.nos2 == 0);
1088  break;
1089  case 3:
1090  curr_tr = prrr.tr3;
1091  curr_ir = nmrr.ir3;
1092  curr_or = nmrr.or3;
1093  te.outerShareable = (prrr.nos3 == 0);
1094  break;
1095  case 4:
1096  curr_tr = prrr.tr4;
1097  curr_ir = nmrr.ir4;
1098  curr_or = nmrr.or4;
1099  te.outerShareable = (prrr.nos4 == 0);
1100  break;
1101  case 5:
1102  curr_tr = prrr.tr5;
1103  curr_ir = nmrr.ir5;
1104  curr_or = nmrr.or5;
1105  te.outerShareable = (prrr.nos5 == 0);
1106  break;
1107  case 6:
1108  panic("Imp defined type\n");
1109  case 7:
1110  curr_tr = prrr.tr7;
1111  curr_ir = nmrr.ir7;
1112  curr_or = nmrr.or7;
1113  te.outerShareable = (prrr.nos7 == 0);
1114  break;
1115  }
1116 
1117  switch(curr_tr) {
1118  case 0:
1119  DPRINTF(TLBVerbose, "StronglyOrdered\n");
1121  te.nonCacheable = true;
1122  te.innerAttrs = 1;
1123  te.outerAttrs = 0;
1124  te.shareable = true;
1125  break;
1126  case 1:
1127  DPRINTF(TLBVerbose, "Device ds1:%d ds0:%d s:%d\n",
1128  prrr.ds1, prrr.ds0, s);
1130  te.nonCacheable = true;
1131  te.innerAttrs = 3;
1132  te.outerAttrs = 0;
1133  if (prrr.ds1 && s)
1134  te.shareable = true;
1135  if (prrr.ds0 && !s)
1136  te.shareable = true;
1137  break;
1138  case 2:
1139  DPRINTF(TLBVerbose, "Normal ns1:%d ns0:%d s:%d\n",
1140  prrr.ns1, prrr.ns0, s);
1142  if (prrr.ns1 && s)
1143  te.shareable = true;
1144  if (prrr.ns0 && !s)
1145  te.shareable = true;
1146  break;
1147  case 3:
1148  panic("Reserved type");
1149  }
1150 
1152  switch(curr_ir) {
1153  case 0:
1154  te.nonCacheable = true;
1155  te.innerAttrs = 0;
1156  break;
1157  case 1:
1158  te.innerAttrs = 5;
1159  break;
1160  case 2:
1161  te.innerAttrs = 6;
1162  break;
1163  case 3:
1164  te.innerAttrs = 7;
1165  break;
1166  }
1167 
1168  switch(curr_or) {
1169  case 0:
1170  te.nonCacheable = true;
1171  te.outerAttrs = 0;
1172  break;
1173  case 1:
1174  te.outerAttrs = 1;
1175  break;
1176  case 2:
1177  te.outerAttrs = 2;
1178  break;
1179  case 3:
1180  te.outerAttrs = 3;
1181  break;
1182  }
1183  }
1184  }
1185  DPRINTF(TLBVerbose, "memAttrs: shareable: %d, innerAttrs: %d, "
1186  "outerAttrs: %d\n",
1187  te.shareable, te.innerAttrs, te.outerAttrs);
1188  te.setAttributes(false);
1189 }
1190 
1191 void
1193  LongDescriptor &lDescriptor)
1194 {
1195  assert(_haveLPAE);
1196 
1197  uint8_t attr;
1198  uint8_t sh = lDescriptor.sh();
1199  // Different format and source of attributes if this is a stage 2
1200  // translation
1201  if (isStage2) {
1202  attr = lDescriptor.memAttr();
1203  uint8_t attr_3_2 = (attr >> 2) & 0x3;
1204  uint8_t attr_1_0 = attr & 0x3;
1205 
1206  DPRINTF(TLBVerbose, "memAttrsLPAE MemAttr:%#x sh:%#x\n", attr, sh);
1207 
1208  if (attr_3_2 == 0) {
1209  te.mtype = attr_1_0 == 0 ? TlbEntry::MemoryType::StronglyOrdered
1211  te.outerAttrs = 0;
1212  te.innerAttrs = attr_1_0 == 0 ? 1 : 3;
1213  te.nonCacheable = true;
1214  } else {
1216  te.outerAttrs = attr_3_2 == 1 ? 0 :
1217  attr_3_2 == 2 ? 2 : 1;
1218  te.innerAttrs = attr_1_0 == 1 ? 0 :
1219  attr_1_0 == 2 ? 6 : 5;
1220  te.nonCacheable = (attr_3_2 == 1) || (attr_1_0 == 1);
1221  }
1222  } else {
1223  uint8_t attrIndx = lDescriptor.attrIndx();
1224 
1225  // LPAE always uses remapping of memory attributes, irrespective of the
1226  // value of SCTLR.TRE
1227  MiscRegIndex reg = attrIndx & 0x4 ? MISCREG_MAIR1 : MISCREG_MAIR0;
1228  int reg_as_int = flattenMiscRegNsBanked(reg, currState->tc,
1229  !currState->isSecure);
1230  uint32_t mair = currState->tc->readMiscReg(reg_as_int);
1231  attr = (mair >> (8 * (attrIndx % 4))) & 0xff;
1232  uint8_t attr_7_4 = bits(attr, 7, 4);
1233  uint8_t attr_3_0 = bits(attr, 3, 0);
1234  DPRINTF(TLBVerbose, "memAttrsLPAE AttrIndx:%#x sh:%#x, attr %#x\n", attrIndx, sh, attr);
1235 
1236  // Note: the memory subsystem only cares about the 'cacheable' memory
1237  // attribute. The other attributes are only used to fill the PAR register
1238  // accordingly to provide the illusion of full support
1239  te.nonCacheable = false;
1240 
1241  switch (attr_7_4) {
1242  case 0x0:
1243  // Strongly-ordered or Device memory
1244  if (attr_3_0 == 0x0)
1246  else if (attr_3_0 == 0x4)
1248  else
1249  panic("Unpredictable behavior\n");
1250  te.nonCacheable = true;
1251  te.outerAttrs = 0;
1252  break;
1253  case 0x4:
1254  // Normal memory, Outer Non-cacheable
1256  te.outerAttrs = 0;
1257  if (attr_3_0 == 0x4)
1258  // Inner Non-cacheable
1259  te.nonCacheable = true;
1260  else if (attr_3_0 < 0x8)
1261  panic("Unpredictable behavior\n");
1262  break;
1263  case 0x8:
1264  case 0x9:
1265  case 0xa:
1266  case 0xb:
1267  case 0xc:
1268  case 0xd:
1269  case 0xe:
1270  case 0xf:
1271  if (attr_7_4 & 0x4) {
1272  te.outerAttrs = (attr_7_4 & 1) ? 1 : 3;
1273  } else {
1274  te.outerAttrs = 0x2;
1275  }
1276  // Normal memory, Outer Cacheable
1278  if (attr_3_0 != 0x4 && attr_3_0 < 0x8)
1279  panic("Unpredictable behavior\n");
1280  break;
1281  default:
1282  panic("Unpredictable behavior\n");
1283  break;
1284  }
1285 
1286  switch (attr_3_0) {
1287  case 0x0:
1288  te.innerAttrs = 0x1;
1289  break;
1290  case 0x4:
1291  te.innerAttrs = attr_7_4 == 0 ? 0x3 : 0;
1292  break;
1293  case 0x8:
1294  case 0x9:
1295  case 0xA:
1296  case 0xB:
1297  te.innerAttrs = 6;
1298  break;
1299  case 0xC:
1300  case 0xD:
1301  case 0xE:
1302  case 0xF:
1303  te.innerAttrs = attr_3_0 & 1 ? 0x5 : 0x7;
1304  break;
1305  default:
1306  panic("Unpredictable behavior\n");
1307  break;
1308  }
1309  }
1310 
1311  te.outerShareable = sh == 2;
1312  te.shareable = (sh & 0x2) ? true : false;
1313  te.setAttributes(true);
1314  te.attributes |= (uint64_t) attr << 56;
1315 }
1316 
1317 void
1319  LongDescriptor &lDescriptor)
1320 {
1321  uint8_t attr;
1322  uint8_t attr_hi;
1323  uint8_t attr_lo;
1324  uint8_t sh = lDescriptor.sh();
1325 
1326  if (isStage2) {
1327  attr = lDescriptor.memAttr();
1328  uint8_t attr_hi = (attr >> 2) & 0x3;
1329  uint8_t attr_lo = attr & 0x3;
1330 
1331  DPRINTF(TLBVerbose, "memAttrsAArch64 MemAttr:%#x sh:%#x\n", attr, sh);
1332 
1333  if (attr_hi == 0) {
1334  te.mtype = attr_lo == 0 ? TlbEntry::MemoryType::StronglyOrdered
1336  te.outerAttrs = 0;
1337  te.innerAttrs = attr_lo == 0 ? 1 : 3;
1338  te.nonCacheable = true;
1339  } else {
1341  te.outerAttrs = attr_hi == 1 ? 0 :
1342  attr_hi == 2 ? 2 : 1;
1343  te.innerAttrs = attr_lo == 1 ? 0 :
1344  attr_lo == 2 ? 6 : 5;
1345  // Treat write-through memory as uncacheable, this is safe
1346  // but for performance reasons not optimal.
1347  te.nonCacheable = (attr_hi == 1) || (attr_hi == 2) ||
1348  (attr_lo == 1) || (attr_lo == 2);
1349  }
1350  } else {
1351  uint8_t attrIndx = lDescriptor.attrIndx();
1352 
1353  DPRINTF(TLBVerbose, "memAttrsAArch64 AttrIndx:%#x sh:%#x\n", attrIndx, sh);
1354 
1355  // Select MAIR
1356  uint64_t mair;
1357  switch (currState->el) {
1358  case EL0:
1359  case EL1:
1360  mair = tc->readMiscReg(MISCREG_MAIR_EL1);
1361  break;
1362  case EL2:
1363  mair = tc->readMiscReg(MISCREG_MAIR_EL2);
1364  break;
1365  case EL3:
1366  mair = tc->readMiscReg(MISCREG_MAIR_EL3);
1367  break;
1368  default:
1369  panic("Invalid exception level");
1370  break;
1371  }
1372 
1373  // Select attributes
1374  attr = bits(mair, 8 * attrIndx + 7, 8 * attrIndx);
1375  attr_lo = bits(attr, 3, 0);
1376  attr_hi = bits(attr, 7, 4);
1377 
1378  // Memory type
1380 
1381  // Cacheability
1382  te.nonCacheable = false;
1383  if (te.mtype == TlbEntry::MemoryType::Device) { // Device memory
1384  te.nonCacheable = true;
1385  }
1386  // Treat write-through memory as uncacheable, this is safe
1387  // but for performance reasons not optimal.
1388  switch (attr_hi) {
1389  case 0x1 ... 0x3: // Normal Memory, Outer Write-through transient
1390  case 0x4: // Normal memory, Outer Non-cacheable
1391  case 0x8 ... 0xb: // Normal Memory, Outer Write-through non-transient
1392  te.nonCacheable = true;
1393  }
1394  switch (attr_lo) {
1395  case 0x1 ... 0x3: // Normal Memory, Inner Write-through transient
1396  case 0x9 ... 0xb: // Normal Memory, Inner Write-through non-transient
1397  warn_if(!attr_hi, "Unpredictable behavior");
1398  case 0x4: // Device-nGnRE memory or
1399  // Normal memory, Inner Non-cacheable
1400  case 0x8: // Device-nGRE memory or
1401  // Normal memory, Inner Write-through non-transient
1402  te.nonCacheable = true;
1403  }
1404 
1405  te.shareable = sh == 2;
1406  te.outerShareable = (sh & 0x2) ? true : false;
1407  // Attributes formatted according to the 64-bit PAR
1408  te.attributes = ((uint64_t) attr << 56) |
1409  (1 << 11) | // LPAE bit
1410  (te.ns << 9) | // NS bit
1411  (sh << 7);
1412  }
1413 }
1414 
1415 void
1417 {
1418  if (currState->fault != NoFault) {
1419  return;
1420  }
1421 
1422  DPRINTF(TLB, "L1 descriptor for %#x is %#x\n",
1424  TlbEntry te;
1425 
1426  switch (currState->l1Desc.type()) {
1427  case L1Descriptor::Ignore:
1429  if (!currState->timing) {
1430  currState->tc = NULL;
1431  currState->req = NULL;
1432  }
1433  DPRINTF(TLB, "L1 Descriptor Reserved/Ignore, causing fault\n");
1434  if (currState->isFetch)
1435  currState->fault =
1436  std::make_shared<PrefetchAbort>(
1439  isStage2,
1441  else
1442  currState->fault =
1443  std::make_shared<DataAbort>(
1446  currState->isWrite,
1449  return;
1450  case L1Descriptor::Section:
1451  if (currState->sctlr.afe && bits(currState->l1Desc.ap(), 0) == 0) {
1457  currState->fault = std::make_shared<DataAbort>(
1459  currState->l1Desc.domain(),
1460  currState->isWrite,
1462  isStage2,
1464  }
1465  if (currState->l1Desc.supersection()) {
1466  panic("Haven't implemented supersections\n");
1467  }
1469  return;
1471  {
1472  Addr l2desc_addr;
1473  l2desc_addr = currState->l1Desc.l2Addr() |
1474  (bits(currState->vaddr, 19, 12) << 2);
1475  DPRINTF(TLB, "L1 descriptor points to page table at: %#x (%s)\n",
1476  l2desc_addr, currState->isSecure ? "s" : "ns");
1477 
1478  // Trickbox address check
1479  currState->fault = testWalk(l2desc_addr, sizeof(uint32_t),
1480  currState->l1Desc.domain(), L2);
1481 
1482  if (currState->fault) {
1483  if (!currState->timing) {
1484  currState->tc = NULL;
1485  currState->req = NULL;
1486  }
1487  return;
1488  }
1489 
1491  if (currState->isSecure)
1492  flag.set(Request::SECURE);
1493 
1494  bool delayed;
1495  delayed = fetchDescriptor(l2desc_addr,
1496  (uint8_t*)&currState->l2Desc.data,
1497  sizeof(uint32_t), flag, -1, &doL2DescEvent,
1499  if (delayed) {
1500  currState->delayed = true;
1501  }
1502 
1503  return;
1504  }
1505  default:
1506  panic("A new type in a 2 bit field?\n");
1507  }
1508 }
1509 
1510 void
1512 {
1513  if (currState->fault != NoFault) {
1514  return;
1515  }
1516 
1517  DPRINTF(TLB, "L%d descriptor for %#llx is %#llx (%s)\n",
1520  currState->aarch64 ? "AArch64" : "long-desc.");
1521 
1524  DPRINTF(TLBVerbose, "Analyzing L%d descriptor: %#llx, pxn: %d, "
1525  "xn: %d, ap: %d, af: %d, type: %d\n",
1528  currState->longDesc.pxn(),
1529  currState->longDesc.xn(),
1530  currState->longDesc.ap(),
1531  currState->longDesc.af(),
1532  currState->longDesc.type());
1533  } else {
1534  DPRINTF(TLBVerbose, "Analyzing L%d descriptor: %#llx, type: %d\n",
1537  currState->longDesc.type());
1538  }
1539 
1540  TlbEntry te;
1541 
1542  switch (currState->longDesc.type()) {
1544  if (!currState->timing) {
1545  currState->tc = NULL;
1546  currState->req = NULL;
1547  }
1548 
1549  DPRINTF(TLB, "L%d descriptor Invalid, causing fault type %d\n",
1552  if (currState->isFetch)
1553  currState->fault = std::make_shared<PrefetchAbort>(
1556  isStage2,
1558  else
1559  currState->fault = std::make_shared<DataAbort>(
1562  currState->isWrite,
1564  isStage2,
1566  return;
1567  case LongDescriptor::Block:
1568  case LongDescriptor::Page:
1569  {
1570  bool fault = false;
1571  bool aff = false;
1572  // Check for address size fault
1577  fault = true;
1578  DPRINTF(TLB, "L%d descriptor causing Address Size Fault\n",
1580  // Check for access fault
1581  } else if (currState->longDesc.af() == 0) {
1582  fault = true;
1583  DPRINTF(TLB, "L%d descriptor causing Access Fault\n",
1585  aff = true;
1586  }
1587  if (fault) {
1588  if (currState->isFetch)
1589  currState->fault = std::make_shared<PrefetchAbort>(
1593  isStage2,
1595  else
1596  currState->fault = std::make_shared<DataAbort>(
1601  isStage2,
1603  } else {
1605  }
1606  }
1607  return;
1608  case LongDescriptor::Table:
1609  {
1610  // Set hierarchical permission flags
1621 
1622  // Set up next level lookup
1623  Addr next_desc_addr = currState->longDesc.nextDescAddr(
1624  currState->vaddr);
1625 
1626  DPRINTF(TLB, "L%d descriptor points to L%d descriptor at: %#x (%s)\n",
1629  next_desc_addr,
1630  currState->secureLookup ? "s" : "ns");
1631 
1632  // Check for address size fault
1634  next_desc_addr, currState->physAddrRange)) {
1635  DPRINTF(TLB, "L%d descriptor causing Address Size Fault\n",
1637  if (currState->isFetch)
1638  currState->fault = std::make_shared<PrefetchAbort>(
1642  isStage2,
1644  else
1645  currState->fault = std::make_shared<DataAbort>(
1650  isStage2,
1652  return;
1653  }
1654 
1655  // Trickbox address check
1657  next_desc_addr, sizeof(uint64_t), TlbEntry::DomainType::Client,
1659 
1660  if (currState->fault) {
1661  if (!currState->timing) {
1662  currState->tc = NULL;
1663  currState->req = NULL;
1664  }
1665  return;
1666  }
1667 
1669  if (currState->secureLookup)
1670  flag.set(Request::SECURE);
1671 
1674  Event *event = NULL;
1675  switch (L) {
1676  case L1:
1677  assert(currState->aarch64);
1678  case L2:
1679  case L3:
1680  event = LongDescEventByLevel[L];
1681  break;
1682  default:
1683  panic("Wrong lookup level in table walk\n");
1684  break;
1685  }
1686 
1687  bool delayed;
1688  delayed = fetchDescriptor(next_desc_addr, (uint8_t*)&currState->longDesc.data,
1689  sizeof(uint64_t), flag, -1, event,
1691  if (delayed) {
1692  currState->delayed = true;
1693  }
1694  }
1695  return;
1696  default:
1697  panic("A new type in a 2 bit field?\n");
1698  }
1699 }
1700 
1701 void
1703 {
1704  if (currState->fault != NoFault) {
1705  return;
1706  }
1707 
1708  DPRINTF(TLB, "L2 descriptor for %#x is %#x\n",
1710  TlbEntry te;
1711 
1712  if (currState->l2Desc.invalid()) {
1713  DPRINTF(TLB, "L2 descriptor invalid, causing fault\n");
1714  if (!currState->timing) {
1715  currState->tc = NULL;
1716  currState->req = NULL;
1717  }
1718  if (currState->isFetch)
1719  currState->fault = std::make_shared<PrefetchAbort>(
1722  isStage2,
1724  else
1725  currState->fault = std::make_shared<DataAbort>(
1728  isStage2,
1730  return;
1731  }
1732 
1733  if (currState->sctlr.afe && bits(currState->l2Desc.ap(), 0) == 0) {
1737  DPRINTF(TLB, "Generating access fault at L2, afe: %d, ap: %d\n",
1738  currState->sctlr.afe, currState->l2Desc.ap());
1739 
1740  currState->fault = std::make_shared<DataAbort>(
1745  }
1746 
1748 }
1749 
1750 void
1752 {
1753  currState = stateQueues[L1].front();
1754  currState->delayed = false;
1755  // if there's a stage2 translation object we don't need it any more
1756  if (currState->stage2Tran) {
1757  delete currState->stage2Tran;
1758  currState->stage2Tran = NULL;
1759  }
1760 
1761 
1762  DPRINTF(TLBVerbose, "L1 Desc object host addr: %p\n",&currState->l1Desc.data);
1763  DPRINTF(TLBVerbose, "L1 Desc object data: %08x\n",currState->l1Desc.data);
1764 
1765  DPRINTF(TLBVerbose, "calling doL1Descriptor for vaddr:%#x\n", currState->vaddr_tainted);
1766  doL1Descriptor();
1767 
1768  stateQueues[L1].pop_front();
1769  // Check if fault was generated
1770  if (currState->fault != NoFault) {
1772  currState->tc, currState->mode);
1774 
1775  pending = false;
1776  nextWalk(currState->tc);
1777 
1778  currState->req = NULL;
1779  currState->tc = NULL;
1780  currState->delayed = false;
1781  delete currState;
1782  }
1783  else if (!currState->delayed) {
1784  // delay is not set so there is no L2 to do
1785  // Don't finish the translation if a stage 2 look up is underway
1786  if (!currState->doingStage2) {
1788  DPRINTF(TLBVerbose, "calling translateTiming again\n");
1792  }
1793 
1794  pending = false;
1795  nextWalk(currState->tc);
1796 
1797  currState->req = NULL;
1798  currState->tc = NULL;
1799  currState->delayed = false;
1800  delete currState;
1801  } else {
1802  // need to do L2 descriptor
1803  stateQueues[L2].push_back(currState);
1804  }
1805  currState = NULL;
1806 }
1807 
1808 void
1810 {
1811  currState = stateQueues[L2].front();
1812  assert(currState->delayed);
1813  // if there's a stage2 translation object we don't need it any more
1814  if (currState->stage2Tran) {
1815  delete currState->stage2Tran;
1816  currState->stage2Tran = NULL;
1817  }
1818 
1819  DPRINTF(TLBVerbose, "calling doL2Descriptor for vaddr:%#x\n",
1821  doL2Descriptor();
1822 
1823  // Check if fault was generated
1824  if (currState->fault != NoFault) {
1826  currState->tc, currState->mode);
1828  }
1829  else {
1830  // Don't finish the translation if a stage 2 look up is underway
1831  if (!currState->doingStage2) {
1833  DPRINTF(TLBVerbose, "calling translateTiming again\n");
1837  }
1838  }
1839 
1840 
1841  stateQueues[L2].pop_front();
1842  pending = false;
1843  nextWalk(currState->tc);
1844 
1845  currState->req = NULL;
1846  currState->tc = NULL;
1847  currState->delayed = false;
1848 
1849  delete currState;
1850  currState = NULL;
1851 }
1852 
1853 void
1855 {
1857 }
1858 
1859 void
1861 {
1863 }
1864 
1865 void
1867 {
1869 }
1870 
1871 void
1873 {
1875 }
1876 
1877 void
1879 {
1880  currState = stateQueues[curr_lookup_level].front();
1881  assert(curr_lookup_level == currState->longDesc.lookupLevel);
1882  currState->delayed = false;
1883 
1884  // if there's a stage2 translation object we don't need it any more
1885  if (currState->stage2Tran) {
1886  delete currState->stage2Tran;
1887  currState->stage2Tran = NULL;
1888  }
1889 
1890  DPRINTF(TLBVerbose, "calling doLongDescriptor for vaddr:%#x\n",
1892  doLongDescriptor();
1893 
1894  stateQueues[curr_lookup_level].pop_front();
1895 
1896  if (currState->fault != NoFault) {
1897  // A fault was generated
1899  currState->tc, currState->mode);
1900 
1901  pending = false;
1902  nextWalk(currState->tc);
1903 
1904  currState->req = NULL;
1905  currState->tc = NULL;
1906  currState->delayed = false;
1907  delete currState;
1908  } else if (!currState->delayed) {
1909  // No additional lookups required
1910  // Don't finish the translation if a stage 2 look up is underway
1911  if (!currState->doingStage2) {
1912  DPRINTF(TLBVerbose, "calling translateTiming again\n");
1916  currState->mode);
1917  statWalksLongTerminatedAtLevel[(unsigned) curr_lookup_level]++;
1918  }
1919 
1920  pending = false;
1921  nextWalk(currState->tc);
1922 
1923  currState->req = NULL;
1924  currState->tc = NULL;
1925  currState->delayed = false;
1926  delete currState;
1927  } else {
1928  if (curr_lookup_level >= MAX_LOOKUP_LEVELS - 1)
1929  panic("Max. number of lookups already reached in table walk\n");
1930  // Need to perform additional lookups
1932  }
1933  currState = NULL;
1934 }
1935 
1936 
1937 void
1939 {
1940  if (pendingQueue.size())
1942  else
1943  completeDrain();
1944 }
1945 
1946 bool
1947 TableWalker::fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes,
1948  Request::Flags flags, int queueIndex, Event *event,
1949  void (TableWalker::*doDescriptor)())
1950 {
1951  bool isTiming = currState->timing;
1952 
1953  DPRINTF(TLBVerbose, "Fetching descriptor at address: 0x%x stage2Req: %d\n",
1954  descAddr, currState->stage2Req);
1955 
1956  // If this translation has a stage 2 then we know descAddr is an IPA and
1957  // needs to be translated before we can access the page table. Do that
1958  // check here.
1959  if (currState->stage2Req) {
1960  Fault fault;
1961  flags = flags | TLB::MustBeOne;
1962 
1963  if (isTiming) {
1964  Stage2MMU::Stage2Translation *tran = new
1966  currState->vaddr);
1967  currState->stage2Tran = tran;
1968  stage2Mmu->readDataTimed(currState->tc, descAddr, tran, numBytes,
1969  flags);
1970  fault = tran->fault;
1971  } else {
1973  currState->vaddr, descAddr, data, numBytes, flags,
1975  }
1976 
1977  if (fault != NoFault) {
1978  currState->fault = fault;
1979  }
1980  if (isTiming) {
1981  if (queueIndex >= 0) {
1982  DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n",
1983  stateQueues[queueIndex].size());
1984  stateQueues[queueIndex].push_back(currState);
1985  currState = NULL;
1986  }
1987  } else {
1988  (this->*doDescriptor)();
1989  }
1990  } else {
1991  if (isTiming) {
1992  port->dmaAction(MemCmd::ReadReq, descAddr, numBytes, event, data,
1993  currState->tc->getCpuPtr()->clockPeriod(),flags);
1994  if (queueIndex >= 0) {
1995  DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n",
1996  stateQueues[queueIndex].size());
1997  stateQueues[queueIndex].push_back(currState);
1998  currState = NULL;
1999  }
2000  } else if (!currState->functional) {
2001  port->dmaAction(MemCmd::ReadReq, descAddr, numBytes, NULL, data,
2002  currState->tc->getCpuPtr()->clockPeriod(), flags);
2003  (this->*doDescriptor)();
2004  } else {
2005  RequestPtr req = new Request(descAddr, numBytes, flags, masterId);
2007  PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
2008  pkt->dataStatic(data);
2009  port->sendFunctional(pkt);
2010  (this->*doDescriptor)();
2011  delete req;
2012  delete pkt;
2013  }
2014  }
2015  return (isTiming);
2016 }
2017 
2018 void
2019 TableWalker::insertTableEntry(DescriptorBase &descriptor, bool longDescriptor)
2020 {
2021  TlbEntry te;
2022 
2023  // Create and fill a new page table entry
2024  te.valid = true;
2025  te.longDescFormat = longDescriptor;
2026  te.isHyp = currState->isHyp;
2027  te.asid = currState->asid;
2028  te.vmid = currState->vmid;
2029  te.N = descriptor.offsetBits();
2030  te.vpn = currState->vaddr >> te.N;
2031  te.size = (1<<te.N) - 1;
2032  te.pfn = descriptor.pfn();
2033  te.domain = descriptor.domain();
2034  te.lookupLevel = descriptor.lookupLevel;
2035  te.ns = !descriptor.secure(haveSecurity, currState) || isStage2;
2036  te.nstid = !currState->isSecure;
2037  te.xn = descriptor.xn();
2038  if (currState->aarch64)
2039  te.el = currState->el;
2040  else
2041  te.el = 1;
2042 
2045 
2046  // ASID has no meaning for stage 2 TLB entries, so mark all stage 2 entries
2047  // as global
2048  te.global = descriptor.global(currState) || isStage2;
2049  if (longDescriptor) {
2050  LongDescriptor lDescriptor =
2051  dynamic_cast<LongDescriptor &>(descriptor);
2052 
2053  te.xn |= currState->xnTable;
2054  te.pxn = currState->pxnTable || lDescriptor.pxn();
2055  if (isStage2) {
2056  // this is actually the HAP field, but its stored in the same bit
2057  // possitions as the AP field in a stage 1 translation.
2058  te.hap = lDescriptor.ap();
2059  } else {
2060  te.ap = ((!currState->rwTable || descriptor.ap() >> 1) << 1) |
2061  (currState->userTable && (descriptor.ap() & 0x1));
2062  }
2063  if (currState->aarch64)
2064  memAttrsAArch64(currState->tc, te, lDescriptor);
2065  else
2066  memAttrsLPAE(currState->tc, te, lDescriptor);
2067  } else {
2068  te.ap = descriptor.ap();
2069  memAttrs(currState->tc, te, currState->sctlr, descriptor.texcb(),
2070  descriptor.shareable());
2071  }
2072 
2073  // Debug output
2074  DPRINTF(TLB, descriptor.dbgHeader().c_str());
2075  DPRINTF(TLB, " - N:%d pfn:%#x size:%#x global:%d valid:%d\n",
2076  te.N, te.pfn, te.size, te.global, te.valid);
2077  DPRINTF(TLB, " - vpn:%#x xn:%d pxn:%d ap:%d domain:%d asid:%d "
2078  "vmid:%d hyp:%d nc:%d ns:%d\n", te.vpn, te.xn, te.pxn,
2079  te.ap, static_cast<uint8_t>(te.domain), te.asid, te.vmid, te.isHyp,
2080  te.nonCacheable, te.ns);
2081  DPRINTF(TLB, " - domain from L%d desc:%d data:%#x\n",
2082  descriptor.lookupLevel, static_cast<uint8_t>(descriptor.domain()),
2083  descriptor.getRawData());
2084 
2085  // Insert the entry into the TLB
2086  tlb->insert(currState->vaddr, te);
2087  if (!currState->timing) {
2088  currState->tc = NULL;
2089  currState->req = NULL;
2090  }
2091 }
2092 
2094 ArmTableWalkerParams::create()
2095 {
2096  return new ArmISA::TableWalker(this);
2097 }
2098 
2100 TableWalker::toLookupLevel(uint8_t lookup_level_as_int)
2101 {
2102  switch (lookup_level_as_int) {
2103  case L1:
2104  return L1;
2105  case L2:
2106  return L2;
2107  case L3:
2108  return L3;
2109  default:
2110  panic("Invalid lookup level conversion");
2111  }
2112 }
2113 
2114 /* this method keeps track of the table walker queue's residency, so
2115  * needs to be called whenever requests start and complete. */
2116 void
2118 {
2119  unsigned n = pendingQueue.size();
2120  if ((currState != NULL) && (currState != pendingQueue.front())) {
2121  ++n;
2122  }
2123 
2124  if (n != pendingReqs) {
2125  Tick now = curTick();
2127  pendingReqs = n;
2128  pendingChangeTick = now;
2129  }
2130 }
2131 
2132 Fault
2134  LookupLevel lookup_level)
2135 {
2136  return tlb->testWalk(pa, size, currState->vaddr, currState->isSecure,
2137  currState->mode, domain, lookup_level);
2138 }
2139 
2140 
2141 uint8_t
2143 {
2144  /* for statPageSizes */
2145  switch(N) {
2146  case 12: return 0; // 4K
2147  case 14: return 1; // 16K (using 16K granule in v8-64)
2148  case 16: return 2; // 64K
2149  case 20: return 3; // 1M
2150  case 21: return 4; // 2M-LPAE
2151  case 24: return 5; // 16M
2152  case 25: return 6; // 32M (using 16K granule in v8-64)
2153  case 29: return 7; // 512M (using 64K granule in v8-64)
2154  case 30: return 8; // 1G-LPAE
2155  default:
2156  panic("unknown page size");
2157  return 255;
2158  }
2159 }
2160 
2161 void
2163 {
2165 
2166  statWalks
2167  .name(name() + ".walks")
2168  .desc("Table walker walks requested")
2169  ;
2170 
2172  .name(name() + ".walksShort")
2173  .desc("Table walker walks initiated with short descriptors")
2175  ;
2176 
2178  .name(name() + ".walksLong")
2179  .desc("Table walker walks initiated with long descriptors")
2181  ;
2182 
2184  .init(2)
2185  .name(name() + ".walksShortTerminationLevel")
2186  .desc("Level at which table walker walks "
2187  "with short descriptors terminate")
2189  ;
2192 
2194  .init(4)
2195  .name(name() + ".walksLongTerminationLevel")
2196  .desc("Level at which table walker walks "
2197  "with long descriptors terminate")
2199  ;
2204 
2206  .name(name() + ".walksSquashedBefore")
2207  .desc("Table walks squashed before starting")
2209  ;
2210 
2212  .name(name() + ".walksSquashedAfter")
2213  .desc("Table walks squashed after completion")
2215  ;
2216 
2218  .init(16)
2219  .name(name() + ".walkWaitTime")
2220  .desc("Table walker wait (enqueue to first request) latency")
2222  ;
2223 
2225  .init(16)
2226  .name(name() + ".walkCompletionTime")
2227  .desc("Table walker service (enqueue to completion) latency")
2229  ;
2230 
2232  .init(16)
2233  .name(name() + ".walksPending")
2234  .desc("Table walker pending requests distribution")
2236  ;
2237 
2238  statPageSizes // see DDI 0487A D4-1661
2239  .init(9)
2240  .name(name() + ".walkPageSizes")
2241  .desc("Table walker page sizes translated")
2243  ;
2244  statPageSizes.subname(0, "4K");
2245  statPageSizes.subname(1, "16K");
2246  statPageSizes.subname(2, "64K");
2247  statPageSizes.subname(3, "1M");
2248  statPageSizes.subname(4, "2M");
2249  statPageSizes.subname(5, "16M");
2250  statPageSizes.subname(6, "32M");
2251  statPageSizes.subname(7, "512M");
2252  statPageSizes.subname(8, "1G");
2253 
2255  .init(2,2) // Instruction/Data, requests/completed
2256  .name(name() + ".walkRequestOrigin")
2257  .desc("Table walker requests started/completed, data/inst")
2259  ;
2260  statRequestOrigin.subname(0,"Requested");
2261  statRequestOrigin.subname(1,"Completed");
2262  statRequestOrigin.ysubname(0,"Data");
2263  statRequestOrigin.ysubname(1,"Inst");
2264 }
uint8_t innerAttrs
Definition: pagetable.hh:116
uint8_t ap() const
Three bit access protection flags.
#define DPRINTF(x,...)
Definition: trace.hh:212
void regStats() override
Register statistics for this object.
EventWrapper< TableWalker,&TableWalker::doL2LongDescriptorWrapper > doL2LongDescEvent
const FlagsType pdf
Print the percent of the total that this entry represents.
Definition: info.hh:51
void memAttrsLPAE(ThreadContext *tc, TlbEntry &te, LongDescriptor &lDescriptor)
Bitfield< 15 > te
Definition: mt_constants.hh:62
MiscRegIndex
Definition: miscregs.hh:57
EntryType type() const
Return the descriptor type.
Bitfield< 5, 3 > reg
Definition: types.hh:89
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Derived & init(size_type _x, size_type _y)
Definition: statistics.hh:1253
decltype(nullptr) constexpr NoFault
Definition: types.hh:189
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:358
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:83
uint8_t attrIndx() const
Attribute index.
static ExceptionLevel currEL(ThreadContext *tc)
Definition: utility.hh:154
bool isFetch
If the access is a fetch (for execution, and no-exec) must be checked?
LookupLevel lookupLevel
Current lookup level for this descriptor.
Definition: table_walker.hh:70
Bitfield< 7, 0 > L
Definition: int.hh:59
bool doingStage2
Indicates whether the translation has been passed onto the second stage mmu, and no more work is requ...
virtual TlbEntry::DomainType domain() const =0
EventWrapper< TableWalker,&TableWalker::processWalkWrapper > doProcessEvent
uint32_t data
The raw bits of the entry.
virtual Addr pfn() const =0
Bitfield< 7 > i
Definition: miscregs.hh:1378
DrainState
Object drain/handover states.
Definition: drain.hh:71
Bitfield< 0 > m
Definition: miscregs.hh:1577
void doL3LongDescriptorWrapper()
#define panic(...)
Definition: misc.hh:153
unsigned numSquashable
The number of walks belonging to squashed instructions that can be removed from the pendingQueue per ...
Running normally.
Addr l2Addr() const
Address of L2 descriptor if it exists.
std::list< WalkerState * > stateQueues[MAX_LOOKUP_LEVELS]
Queues of requests for all the different lookup levels.
const FlagsType nonan
Don't print if this is NAN.
Definition: info.hh:59
GrainSize grainSize
Width of the granule size in bits.
bool pending
If a timing translation is currently in progress.
Bitfield< 21, 20 > stride
Definition: miscregs.hh:1627
static uint8_t pageSizeNtoStatBin(uint8_t N)
Bitfield< 8, 7 > sh
Definition: miscregs.hh:1832
Stats::Vector statWalksShortTerminatedAtLevel
ip6_addr_t addr
Definition: inet.hh:335
Fault testWalk(Addr pa, Addr size, TlbEntry::DomainType domain, LookupLevel lookup_level)
bool isWrite
If the access is a write.
TableWalker(const Params *p)
Definition: table_walker.cc:59
panic_if(!root,"Invalid expression\n")
Stats::Histogram statPendingWalks
DrainState drain() override
Notify an object that it needs to drain its state.
DmaPort & getPort()
Get the port that ultimately belongs to the stage-two MMU, but is used by the two table walkers...
Definition: stage2_mmu.hh:113
bool haveSecurity
Cached copies of system-level properties.
bool af() const
Returns true if the access flag (AF) is set.
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:146
Stats::Scalar statWalksShortDescriptor
bool timing
If the mode is timing or atomic.
#define warn_once(...)
Definition: misc.hh:226
Stats::Scalar statSquashedBefore
Histogram & init(size_type size)
Set the parameters of this histogram.
Definition: statistics.hh:2560
virtual BaseCPU * getCpuPtr()=0
uint8_t offsetBits() const
Return the bit width of the page/block offset.
uint8_t physAddrRange() const
Returns the supported physical address range in bits.
Definition: system.hh:210
MemoryType mtype
Definition: pagetable.hh:122
bool stage2Req
Flag indicating if a second stage of lookup is required.
Bitfield< 4, 0 > mode
Definition: miscregs.hh:1385
TLB::Translation * transState
Translation state for delayed requests.
HTCR htcr
Cached copy of the htcr as it existed when translation began.
void doL2LongDescriptorWrapper()
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Definition: statistics.hh:311
ThreadContext is the external interface to all thread state for anything outside of the CPU...
Addr vaddr
The virtual address that is being translated with tagging removed.
virtual bool secure(bool have_security, WalkerState *currState) const =0
Derived & init(size_type size)
Set this vector to have the given size.
Definition: statistics.hh:1118
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
Definition: packet.hh:909
DmaPort * port
Port shared by the two table walkers.
ExceptionLevel
Definition: types.hh:562
uint8_t memAttr() const
Memory attributes, only used by stage 2 translations.
Bitfield< 31 > n
Definition: miscregs.hh:1636
const char data[]
Definition: circlebuf.cc:43
Fault testWalk(Addr pa, Addr size, Addr va, bool is_secure, Mode mode, TlbEntry::DomainType domain, LookupLevel lookup_level)
Definition: tlb.cc:1534
void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr, uint8_t texcb, bool s)
Bitfield< 6 > f
Definition: miscregs.hh:1379
WalkerState * currState
bool xnTable() const
Is execution allowed on subsequent lookup levels?
int decodePhysAddrRange64(uint8_t pa_enc)
Returns the n.
Definition: utility.cc:893
bool xn() const
Is execution allowed on this mapping?
virtual uint8_t offsetBits() const =0
uint8_t ap() const
Three bit access protection flags.
bool ELIs64(ThreadContext *tc, ExceptionLevel el)
Definition: utility.cc:228
EventWrapper< TableWalker,&TableWalker::doL1DescriptorWrapper > doL1DescEvent
Definition: tlb.hh:53
haveSecurity
Definition: isa.cc:238
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...
HCR hcr
Cached copy of the htcr as it existed when translation began.
static OperatingMode currOpMode(ThreadContext *tc)
Definition: utility.hh:147
MasterID masterId
Master id assigned by the MMU.
Tick curTick()
The current simulated tick.
Definition: core.hh:47
Bitfield< 3, 2 > el
Definition: miscregs.hh:1384
Stats::Vector statWalksLongTerminatedAtLevel
virtual ~TableWalker()
Definition: table_walker.cc:93
bool haveLPAE() const
Returns true if this system implements the Large Physical Address Extension.
Definition: system.hh:168
void insertTableEntry(DescriptorBase &descriptor, bool longDescriptor)
int physAddrRange
Current physical address range in bits.
Bitfield< 4 > s
Definition: miscregs.hh:1738
Fault fault
The fault that we are going to return.
bool invalid() const
Is the entry invalid.
The request is a page table walk.
Definition: request.hh:183
static LookupLevel toLookupLevel(uint8_t lookup_level_as_int)
virtual bool xn() const =0
bool supersection() const
Is the page a Supersection (16MB)?
uint64_t Tick
Tick count type.
Definition: types.hh:63
Fault translateTiming(RequestPtr req, ThreadContext *tc, Translation *translation, Mode mode, ArmTranslationType tranType=NormalTran)
Definition: tlb.cc:1183
bool pxn() const
Is privileged execution allowed on this mapping? (LPAE only)
void setMMU(Stage2MMU *m, MasterID master_id)
Definition: table_walker.cc:99
The request is to an uncacheable address.
Definition: request.hh:114
ExceptionLevel el
Current exception level.
Fault readDataTimed(ThreadContext *tc, Addr descAddr, Stage2Translation *translation, int numBytes, Request::Flags flags)
Definition: stage2_mmu.cc:101
void doL1LongDescriptorWrapper()
bool isSecure
If the access comes from the secure state.
Bitfield< 39, 12 > pa
Definition: miscregs.hh:1829
#define fatal(...)
Definition: misc.hh:163
virtual uint8_t texcb() const
Definition: table_walker.hh:81
bool fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes, Request::Flags flags, int queueIndex, Event *event, void(TableWalker::*doDescriptor)())
void doLongDescriptorWrapper(LookupLevel curr_lookup_level)
Event * LongDescEventByLevel[4]
Fault readDataUntimed(ThreadContext *tc, Addr oVAddr, Addr descAddr, uint8_t *data, int numBytes, Request::Flags flags, bool isFunctional)
Definition: stage2_mmu.cc:64
Stats::Histogram statWalkServiceTime
TLB::ArmTranslationType tranType
The translation type that has been requested.
bool functional
If the atomic mode should be functional.
SCTLR sctlr
Cached copy of the sctlr as it existed when translation began.
TlbEntry * lookup(Addr vpn, uint16_t asn, uint8_t vmid, bool hyp, bool secure, bool functional, bool ignore_asn, uint8_t target_el)
Lookup an entry in the TLB.
Definition: tlb.cc:151
void doL0LongDescriptorWrapper()
virtual bool global(WalkerState *currState) const =0
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
Definition: misc.hh:241
uint64_t attributes
Definition: pagetable.hh:106
Addr nextDescAddr(Addr va) const
Return the address of the next descriptor.
bool haveSecurity() const
Returns true if this system implements the Security Extensions.
Definition: system.hh:164
static unsigned adjustTableSizeAArch64(unsigned tsz)
uint8_t sh() const
2-bit shareability field
ArmTranslationType
Definition: tlb.hh:124
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
uint8_t userTable() const
User/privileged mode protection flag for subsequent levels of lookup.
uint8_t outerAttrs
Definition: pagetable.hh:117
uint16_t MasterID
Definition: request.hh:85
Draining buffers pending serialization/handover.
TlbEntry::DomainType domain() const
Domain Client/Manager: ARM DDI 0406B: B3-31.
#define ULL(N)
uint64_t constant
Definition: types.hh:50
uint8_t rwTable() const
R/W protection flag for subsequent levels of lookup.
bool pxnTable() const
Is privileged execution allowed on subsequent lookup levels?
void completeDrain()
Checks if all state is cleared and if so, completes drain.
SCTLR sctlr
Cached copy of the sctlr as it existed when translation began.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:245
Bitfield< 10, 5 > event
Bitfield< 34 > aarch64
Definition: types.hh:86
Stats::Histogram statWalkWaitTime
const Params * params() const
Stats::Scalar statSquashedAfter
static const unsigned REQUESTED
const FlagsType total
Print the total.
Definition: info.hh:49
TLB * tlb
TLB that is initiating these table walks.
RequestPtr dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, uint8_t *data, Tick delay, Request::Flags flag=0)
Definition: dma_device.cc:149
This translation class is used to trigger the data fetch once a timing translation returns the transl...
Definition: stage2_mmu.hh:70
virtual MiscReg readMiscReg(int misc_reg)=0
void drainResume() override
Resume execution after a successful drain.
Mode
Definition: tlb.hh:61
virtual uint8_t ap() const =0
EventWrapper< TableWalker,&TableWalker::doL3LongDescriptorWrapper > doL3LongDescEvent
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
Definition: statistics.hh:254
std::list< WalkerState * > pendingQueue
Queue of requests that have passed are waiting because the walker is currently busy.
Tick startTime
Timestamp for calculating elapsed time in service (for stats)
int size()
Definition: pagetable.hh:146
Stats::Scalar statWalks
Statistics.
virtual const std::string name() const
Definition: sim_object.hh:117
uint64_t data
The raw bits of the entry.
ThreadContext * tc
Thread context that we're doing the walk for.
bool longDescFormatInUse(ThreadContext *tc)
Definition: utility.cc:192
bool haveVirtualization() const
Returns true if this system implements the virtualization Extensions.
Definition: system.hh:173
Bitfield< 7, 4 > domain
Definition: miscregs.hh:1605
const unsigned MaxPhysAddrRange
Definition: isa_traits.hh:97
void insert(Addr vaddr, TlbEntry &pte)
Definition: tlb.cc:194
static const unsigned COMPLETED
virtual uint64_t getRawData() const =0
Definition: eventq.hh:185
Fault walk(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)
EventWrapper< TableWalker,&TableWalker::doL0LongDescriptorWrapper > doL0LongDescEvent
Derived & ysubname(off_type index, const std::string &subname)
Definition: statistics.hh:440
The MemObject class extends the ClockedObject with accessor functions to get its master and slave por...
Definition: mem_object.hh:60
Addr getVaddr() const
Definition: request.hh:616
LongDescriptor longDesc
Long-format descriptor (LPAE and AArch64)
A BaseMasterPort is a protocol-agnostic master port, responsible only for the structural connection t...
Definition: port.hh:115
void signalDrainDone() const
Signal that an object is drained.
Definition: drain.hh:267
DomainType domain
Definition: pagetable.hh:120
BaseTLB::Mode mode
Save mode for use in delayed response.
void schedule(Event &event, Tick when)
Definition: eventq.hh:728
uint16_t asid
ASID that we're servicing the request under.
Stats::Scalar statWalksLongDescriptor
VTCR_t vtcr
Cached copy of the vtcr as it existed when translation began.
Stats::Vector2d statRequestOrigin
DrainState drainState() const
Return the current drain state of an object.
Definition: drain.hh:282
EventWrapper< TableWalker,&TableWalker::doL1LongDescriptorWrapper > doL1LongDescEvent
The request targets the secure memory space.
Definition: request.hh:181
virtual bool shareable() const
Definition: table_walker.hh:85
L1Descriptor l1Desc
Short-format descriptors.
void nextWalk(ThreadContext *tc)
uint32_t data
The raw bits of the entry.
virtual std::string dbgHeader() const =0
bool secureTable() const
Whether the subsequent levels of lookup are secure.
Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, TTBCR tcr)
Removes the tag from tagged addresses if that mode is enabled.
Definition: utility.cc:279
Bitfield< 3, 0 > mask
Definition: types.hh:64
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
Definition: statistics.hh:287
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:181
EventWrapper< TableWalker,&TableWalker::doL2DescriptorWrapper > doL2DescEvent
bool secureLookup
Helper variables used to implement hierarchical access permissions when the long-desc.
Stage2MMU * stage2Mmu
The MMU to forward second stage look upts to.
bool aarch64
True if the current lookup is performed in AArch64 state.
int flattenMiscRegNsBanked(MiscRegIndex reg, ThreadContext *tc)
Definition: miscregs.cc:2045
fatal_if(p->js_features.size() > 16,"Too many job slot feature registers specified (%i)\n", p->js_features.size())
T mbits(T val, int first, int last)
Mask off the given bits in place like bits() but without shifting.
Definition: bitfield.hh:91
bool aarch64
If the access is performed in AArch64 state.
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
Definition: bitfield.hh:67
ArmTableWalkerParams Params
const bool isStage2
Indicates whether this table walker is part of the stage 2 mmu.
Bitfield< 18, 16 > ps
Definition: miscregs.hh:1701
static bool checkAddrSizeFaultAArch64(Addr addr, int currPhysAddrRange)
Returns true if the address exceeds the range permitted by the system-wide setting or by the TCR_ELx ...
LookupLevel lookupLevel
Definition: pagetable.hh:108
const FlagsType nozero
Don't print if this is zero.
Definition: info.hh:57
Bitfield< 0 > p
LookupLevel
Definition: pagetable.hh:77
const FlagsType dist
Print the distribution.
Definition: info.hh:55
bool haveLargeAsid64() const
Returns true if ASID is 16 bits in AArch64 (ARMv8)
Definition: system.hh:203
virtual void finish(const Fault &fault, RequestPtr req, ThreadContext *tc, Mode mode)=0
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:114
std::shared_ptr< FaultBase > Fault
Definition: types.hh:184
void set(Type flags)
Definition: flags.hh:70
Long-descriptor format (LPAE)
void regStats() override
Register statistics for this object.
virtual BaseMasterPort & getMasterPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a master port with a given name and index.
Definition: mem_object.cc:52
uint8_t ap() const
2-bit access protection flags
uint32_t taskId() const
Definition: request.hh:630
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
Definition: statistics.hh:1869
void memAttrsAArch64(ThreadContext *tc, TlbEntry &te, LongDescriptor &lDescriptor)
BaseMasterPort & getMasterPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a master port with a given name and index.
Addr vaddr_tainted
The virtual address that is being translated.
RequestPtr req
Request that is currently being serviced.
bool delayed
Whether the response is delayed in timing mode due to additional lookups.
void setAttributes(bool lpae)
Definition: pagetable.hh:272
void sendFunctional(PacketPtr pkt)
Send a functional request packet, where the data is instantly updated everywhere in the memory system...
Definition: port.cc:173
ProbePointArg< PacketInfo > Packet
Packet probe point.
Definition: mem.hh:102
TLB::Translation * stage2Tran
A pointer to the stage 2 translation that's in progress.
Stats::Vector statPageSizes

Generated on Fri Jun 9 2017 13:03:39 for gem5 by doxygen 1.8.6