gem5  v22.1.0.0
table_walker.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2016, 2019, 2021-2022 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 
38 #ifndef __ARCH_ARM_TABLE_WALKER_HH__
39 #define __ARCH_ARM_TABLE_WALKER_HH__
40 
41 #include <list>
42 
43 #include "arch/arm/faults.hh"
44 #include "arch/arm/mmu.hh"
45 #include "arch/arm/regs/misc.hh"
46 #include "arch/arm/system.hh"
47 #include "arch/arm/tlb.hh"
48 #include "arch/arm/types.hh"
49 #include "arch/generic/mmu.hh"
50 #include "mem/packet_queue.hh"
51 #include "mem/qport.hh"
52 #include "mem/request.hh"
53 #include "params/ArmTableWalker.hh"
54 #include "sim/clocked_object.hh"
55 #include "sim/eventq.hh"
56 
57 namespace gem5
58 {
59 
60 class ThreadContext;
61 
62 namespace ArmISA {
63 class Translation;
64 class TLB;
65 
66 class TableWalker : public ClockedObject
67 {
68  using LookupLevel = enums::ArmLookupLevel;
69 
70  public:
71  class WalkerState;
72 
74  {
75  public:
77 
80 
81  virtual Addr pfn() const = 0;
82  virtual TlbEntry::DomainType domain() const = 0;
83  virtual bool xn() const = 0;
84  virtual uint8_t ap() const = 0;
85  virtual bool global(WalkerState *currState) const = 0;
86  virtual uint8_t offsetBits() const = 0;
87  virtual bool secure(bool have_security, WalkerState *currState) const = 0;
88  virtual std::string dbgHeader() const = 0;
89  virtual uint64_t getRawData() const = 0;
90  virtual uint8_t texcb() const
91  {
92  panic("texcb() not implemented for this class\n");
93  }
94  virtual bool shareable() const
95  {
96  panic("shareable() not implemented for this class\n");
97  }
98  };
99 
101  {
102  public:
105  {
109  Reserved
110  };
111 
113  uint32_t data;
114 
117  bool _dirty;
118 
120  L1Descriptor() : data(0), _dirty(false)
121  {
123  }
124 
125  uint64_t
126  getRawData() const override
127  {
128  return (data);
129  }
130 
131  std::string
132  dbgHeader() const override
133  {
134  return "Inserting Section Descriptor into TLB\n";
135  }
136 
137  uint8_t
138  offsetBits() const override
139  {
140  return 20;
141  }
142 
143  EntryType
144  type() const
145  {
146  return (EntryType)(data & 0x3);
147  }
148 
150  bool
151  supersection() const
152  {
153  return bits(data, 18);
154  }
155 
157  Addr
158  paddr() const
159  {
160  if (supersection())
161  panic("Super sections not implemented\n");
162  return mbits(data, 31, 20);
163  }
164 
166  Addr
167  paddr(Addr va) const
168  {
169  if (supersection())
170  panic("Super sections not implemented\n");
171  return mbits(data, 31, 20) | mbits(va, 19, 0);
172  }
173 
175  Addr
176  pfn() const override
177  {
178  if (supersection())
179  panic("Super sections not implemented\n");
180  return bits(data, 31, 20);
181  }
182 
184  bool
185  global(WalkerState *currState) const override
186  {
187  return !bits(data, 17);
188  }
189 
191  bool
192  xn() const override
193  {
194  return bits(data, 4);
195  }
196 
198  uint8_t
199  ap() const override
200  {
201  return (bits(data, 15) << 2) | bits(data, 11, 10);
202  }
203 
206  domain() const override
207  {
208  return static_cast<TlbEntry::DomainType>(bits(data, 8, 5));
209  }
210 
212  Addr
213  l2Addr() const
214  {
215  return mbits(data, 31, 10);
216  }
217 
223  uint8_t
224  texcb() const override
225  {
226  return bits(data, 2) | bits(data, 3) << 1 | bits(data, 14, 12) << 2;
227  }
228 
230  bool
231  shareable() const override
232  {
233  return bits(data, 16);
234  }
235 
239  void
241  {
242  data |= 1 << 10;
243  _dirty = true;
244  }
245 
247  bool
248  dirty() const
249  {
250  return _dirty;
251  }
252 
257  bool
258  secure(bool have_security, WalkerState *currState) const override
259  {
260  if (have_security && currState->secureLookup) {
261  if (type() == PageTable)
262  return !bits(data, 3);
263  else
264  return !bits(data, 19);
265  }
266  return false;
267  }
268  };
269 
272  {
273  public:
275  uint32_t data;
277 
280  bool _dirty;
281 
283  L2Descriptor() : data(0), l1Parent(nullptr), _dirty(false)
284  {
286  }
287 
288  L2Descriptor(L1Descriptor &parent) : data(0), l1Parent(&parent),
289  _dirty(false)
290  {
292  }
293 
294  uint64_t
295  getRawData() const override
296  {
297  return (data);
298  }
299 
300  std::string
301  dbgHeader() const override
302  {
303  return "Inserting L2 Descriptor into TLB\n";
304  }
305 
307  domain() const override
308  {
309  return l1Parent->domain();
310  }
311 
312  bool
313  secure(bool have_security, WalkerState *currState) const override
314  {
315  return l1Parent->secure(have_security, currState);
316  }
317 
318  uint8_t
319  offsetBits() const override
320  {
321  return large() ? 16 : 12;
322  }
323 
325  bool
326  invalid() const
327  {
328  return bits(data, 1, 0) == 0;
329  }
330 
332  bool
333  large() const
334  {
335  return bits(data, 1) == 0;
336  }
337 
339  bool
340  xn() const override
341  {
342  return large() ? bits(data, 15) : bits(data, 0);
343  }
344 
346  bool
347  global(WalkerState *currState) const override
348  {
349  return !bits(data, 11);
350  }
351 
353  uint8_t
354  ap() const override
355  {
356  return bits(data, 5, 4) | (bits(data, 9) << 2);
357  }
358 
360  uint8_t
361  texcb() const override
362  {
363  return large() ?
364  (bits(data, 2) | (bits(data, 3) << 1) | (bits(data, 14, 12) << 2)) :
365  (bits(data, 2) | (bits(data, 3) << 1) | (bits(data, 8, 6) << 2));
366  }
367 
369  Addr
370  pfn() const override
371  {
372  return large() ? bits(data, 31, 16) : bits(data, 31, 12);
373  }
374 
376  Addr
377  paddr(Addr va) const
378  {
379  if (large())
380  return mbits(data, 31, 16) | mbits(va, 15, 0);
381  else
382  return mbits(data, 31, 12) | mbits(va, 11, 0);
383  }
384 
386  bool
387  shareable() const override
388  {
389  return bits(data, 10);
390  }
391 
395  void
397  {
398  data |= 1 << 4;
399  _dirty = true;
400  }
401 
403  bool
404  dirty() const
405  {
406  return _dirty;
407  }
408 
409  };
410 
413  {
414  public:
417  {
421  Page
422  };
423 
425  : data(0), _dirty(false), aarch64(false), grainSize(Grain4KB),
426  physAddrRange(0)
427  {}
428 
430  uint64_t data;
431 
434  bool _dirty;
435 
437  bool aarch64;
438 
441 
442  uint8_t physAddrRange;
443 
444  uint64_t
445  getRawData() const override
446  {
447  return (data);
448  }
449 
450  std::string
451  dbgHeader() const override
452  {
453  switch (type()) {
455  assert(lookupLevel == LookupLevel::L3);
456  return "Inserting Page descriptor into TLB\n";
458  assert(lookupLevel < LookupLevel::L3);
459  return "Inserting Block descriptor into TLB\n";
461  return "Inserting Table descriptor into TLB\n";
462  default:
463  panic("Trying to insert and invalid descriptor\n");
464  }
465  }
466 
471  bool
472  secure(bool have_security, WalkerState *currState) const override
473  {
474  if (type() == Block || type() == Page) {
475  return have_security &&
476  (currState->secureLookup && !bits(data, 5));
477  } else {
478  return have_security && currState->secureLookup;
479  }
480  }
481 
483  EntryType
484  type() const
485  {
486  switch (bits(data, 1, 0)) {
487  case 0x1:
488  // In AArch64 blocks are not allowed at L0 for the
489  // 4 KiB granule and at L1 for 16/64 KiB granules
490  switch (grainSize) {
491  case Grain4KB:
492  if (lookupLevel == LookupLevel::L0 ||
494  return Invalid;
495  else
496  return Block;
497 
498  case Grain16KB:
500  return Block;
501  else
502  return Invalid;
503 
504  case Grain64KB:
505  // With Armv8.2-LPA (52bit PA) L1 Block descriptors
506  // are allowed for 64KiB granule
507  if ((lookupLevel == LookupLevel::L1 && physAddrRange == 52) ||
509  return Block;
510  else
511  return Invalid;
512 
513  default:
514  return Invalid;
515  }
516  case 0x3:
517  return lookupLevel == LookupLevel::L3 ? Page : Table;
518  default:
519  return Invalid;
520  }
521  }
522 
524  uint8_t
525  offsetBits() const override
526  {
527  if (type() == Block) {
528  switch (grainSize) {
529  case Grain4KB:
530  return lookupLevel == LookupLevel::L1 ?
531  30 /* 1 GiB */ : 21 /* 2 MiB */;
532  case Grain16KB:
533  return 25 /* 32 MiB */;
534  case Grain64KB:
535  return lookupLevel == LookupLevel::L1 ?
536  42 /* 4 TiB */ : 29 /* 512 MiB */;
537  default:
538  panic("Invalid AArch64 VM granule size\n");
539  }
540  } else if (type() == Page) {
541  switch (grainSize) {
542  case Grain4KB:
543  case Grain16KB:
544  case Grain64KB:
545  return grainSize; /* enum -> uint okay */
546  default:
547  panic("Invalid AArch64 VM granule size\n");
548  }
549  } else if (type() == Table) {
550  const auto* ptops = getPageTableOps(grainSize);
551  return ptops->walkBits(lookupLevel);
552  }
553  panic("AArch64 page table entry must be block or page\n");
554  }
555 
557  Addr
558  pfn() const override
559  {
560  return paddr() >> offsetBits();
561  }
562 
564  Addr
565  paddr() const
566  {
567  Addr addr = 0;
568  if (aarch64) {
569  addr = mbits(data, 47, offsetBits());
570  if (physAddrRange == 52 && grainSize == Grain64KB) {
571  addr |= bits(data, 15, 12) << 48;
572  }
573  } else {
574  addr = mbits(data, 39, offsetBits());
575  }
576  return addr;
577  }
578 
580  Addr
582  {
583  assert(type() == Table);
584  Addr table_address = 0;
585  if (aarch64) {
586  table_address = mbits(data, 47, grainSize);
587  // Using 52bit if Armv8.2-LPA is implemented
588  if (physAddrRange == 52 && grainSize == Grain64KB)
589  table_address |= bits(data, 15, 12) << 48;
590  } else {
591  table_address = mbits(data, 39, 12);
592  }
593 
594  return table_address;
595  }
596 
598  Addr
600  {
601  assert(type() == Table);
602  Addr pa = 0;
603  if (aarch64) {
604  int stride = grainSize - 3;
605  int va_lo = stride * (3 - (lookupLevel + 1)) + grainSize;
606  int va_hi = va_lo + stride - 1;
607  pa = nextTableAddr() | (bits(va, va_hi, va_lo) << 3);
608  } else {
610  pa = nextTableAddr() | (bits(va, 29, 21) << 3);
611  else // lookupLevel == L2
612  pa = nextTableAddr() | (bits(va, 20, 12) << 3);
613  }
614  return pa;
615  }
616 
618  bool
619  xn() const override
620  {
621  assert(type() == Block || type() == Page);
622  return bits(data, 54);
623  }
624 
626  bool
627  pxn() const
628  {
629  assert(type() == Block || type() == Page);
630  return bits(data, 53);
631  }
632 
634  bool
636  {
637  assert(type() == Block || type() == Page);
638  return bits(data, 52);
639  }
640 
642  bool
643  global(WalkerState *currState) const override
644  {
645  assert(currState && (type() == Block || type() == Page));
646  if (!currState->aarch64 && (currState->isSecure &&
647  !currState->secureLookup)) {
648  return false; // ARM ARM issue C B3.6.3
649  } else if (currState->aarch64) {
651  // By default translations are treated as global
652  // in AArch64 for regimes without an unpriviledged
653  // component
654  return true;
655  } else if (currState->isSecure && !currState->secureLookup) {
656  return false;
657  }
658  }
659  return !bits(data, 11);
660  }
661 
663  bool
664  af() const
665  {
666  assert(type() == Block || type() == Page);
667  return bits(data, 10);
668  }
669 
671  uint8_t
672  sh() const
673  {
674  assert(type() == Block || type() == Page);
675  return bits(data, 9, 8);
676  }
677 
679  uint8_t
680  ap() const override
681  {
682  assert(type() == Block || type() == Page);
683  // Long descriptors only support the AP[2:1] scheme
684  return bits(data, 7, 6);
685  }
686 
688  bool
689  rw() const
690  {
691  assert(type() == Block || type() == Page);
692  return !bits(data, 7);
693  }
694 
696  bool
697  user() const
698  {
699  assert(type() == Block || type() == Page);
700  return bits(data, 6);
701  }
702 
706  static uint8_t
707  ap(bool rw, bool user)
708  {
709  return ((!rw) << 2) | (user << 1);
710  }
711 
713  domain() const override
714  {
715  // Long-desc. format only supports Client domain
717  }
718 
720  uint8_t
721  attrIndx() const
722  {
723  assert(type() == Block || type() == Page);
724  return bits(data, 4, 2);
725  }
726 
728  uint8_t
729  memAttr() const
730  {
731  assert(type() == Block || type() == Page);
732  return bits(data, 5, 2);
733  }
734 
737  void
739  {
740  data |= 1 << 10;
741  _dirty = true;
742  }
743 
745  bool
746  dirty() const
747  {
748  return _dirty;
749  }
750 
752  bool
753  secureTable() const
754  {
755  assert(type() == Table);
756  return !bits(data, 63);
757  }
758 
760  uint8_t
761  apTable() const
762  {
763  assert(type() == Table);
764  return bits(data, 62, 61);
765  }
766 
768  uint8_t
769  rwTable() const
770  {
771  assert(type() == Table);
772  return !bits(data, 62);
773  }
774 
777  uint8_t
778  userTable() const
779  {
780  assert(type() == Table);
781  return !bits(data, 61);
782  }
783 
785  bool
786  xnTable() const
787  {
788  assert(type() == Table);
789  return bits(data, 60);
790  }
791 
793  bool
794  pxnTable() const
795  {
796  assert(type() == Table);
797  return bits(data, 59);
798  }
799  };
800 
802  {
803  public:
806 
808  bool aarch64;
809 
812 
815 
818 
821 
823  uint16_t asid;
825  bool isHyp;
826 
829 
832 
835 
838 
840  SCTLR sctlr;
841 
843  SCR scr;
844 
846  CPSR cpsr;
847 
849  union
850  {
851  TTBCR ttbcr; // AArch32 translations
852  TCR tcr; // AArch64 translations
853  };
854 
856  HTCR htcr;
857 
859  HCR hcr;
860 
862  VTCR_t vtcr;
863 
865  bool isWrite;
866 
868  bool isFetch;
869 
871  bool isSecure;
872 
875 
879  bool rwTable;
880  bool userTable;
881  bool xnTable;
882  bool pxnTable;
883 
885  bool hpd;
886 
888  bool stage2Req;
889 
892 
894  bool timing;
895 
898 
901 
904 
908 
911 
914  bool delayed;
915 
917 
920 
922  unsigned levels;
923 
926 
928 
929  WalkerState();
930 
931  std::string name() const { return tableWalker->name(); }
932  };
933 
935  {
936  public:
937  Tick delay = 0;
938  Event *event = nullptr;
939  };
940 
941  class Port : public QueuedRequestPort
942  {
943  public:
944  Port(TableWalker* _walker, RequestorID id);
945 
946  void sendFunctionalReq(Addr desc_addr, int size,
947  uint8_t *data, Request::Flags flag);
948  void sendAtomicReq(Addr desc_addr, int size,
949  uint8_t *data, Request::Flags flag, Tick delay);
950  void sendTimingReq(Addr desc_addr, int size,
951  uint8_t *data, Request::Flags flag, Tick delay,
952  Event *event);
953 
954  bool recvTimingResp(PacketPtr pkt) override;
955 
956  private:
957  void handleRespPacket(PacketPtr pkt, Tick delay=0);
959  Addr size, Tick delay=0);
960 
961  PacketPtr createPacket(Addr desc_addr, int size,
962  uint8_t *data, Request::Flags flag,
963  Tick delay, Event *event);
964 
965  private:
968 
971 
974  };
975 
979  {
980  private:
981  uint8_t *data;
982  int numBytes;
989 
990  public:
992 
993  Stage2Walk(TableWalker &_parent, uint8_t *_data, Event *_event,
995  MMU::ArmTranslationType tran_type);
996 
997  void markDelayed() {}
998 
999  void finish(const Fault &fault, const RequestPtr &req,
1001 
1002  void
1004  int requestorId)
1005  {
1006  numBytes = size;
1007  req->setVirt(vaddr, size, flags, requestorId, 0);
1008  }
1009 
1010  void translateTiming(ThreadContext *tc);
1011  };
1012 
1014  uint8_t *data, int num_bytes, Request::Flags flags,
1016  bool functional);
1017  void readDataTimed(ThreadContext *tc, Addr desc_addr,
1018  Stage2Walk *translation, int num_bytes,
1020 
1021  protected:
1022 
1024  std::list<WalkerState *> stateQueues[LookupLevel::Num_ArmLookupLevel];
1025 
1029 
1032 
1035 
1038 
1040  const bool isStage2;
1041 
1044 
1046  SCTLR sctlr;
1047 
1049 
1051  bool pending;
1052 
1055  unsigned numSquashable;
1056 
1061 
1064  {
1075  // Essentially "L" of queueing theory
1080 
1081  mutable unsigned pendingReqs;
1083 
1084  static const unsigned REQUESTED = 0;
1085  static const unsigned COMPLETED = 1;
1086 
1087  public:
1088  PARAMS(ArmTableWalker);
1089  TableWalker(const Params &p);
1090  virtual ~TableWalker();
1091 
1092  bool haveLargeAsid64() const { return _haveLargeAsid64; }
1093  uint8_t physAddrRange() const { return _physAddrRange; }
1095  void completeDrain();
1096  DrainState drain() override;
1097  void drainResume() override;
1098 
1099  gem5::Port &getPort(const std::string &if_name,
1100  PortID idx=InvalidPortID) override;
1101 
1103 
1104  Fault walk(const RequestPtr &req, ThreadContext *tc,
1105  uint16_t asid, vmid_t _vmid,
1106  bool hyp, BaseMMU::Mode mode, BaseMMU::Translation *_trans,
1107  bool timing, bool functional, bool secure,
1108  MMU::ArmTranslationType tran_type, bool stage2,
1109  const TlbEntry *walk_entry);
1110 
1111  void setMmu(MMU *_mmu);
1112  void setTlb(TLB *_tlb) { tlb = _tlb; }
1113  TLB* getTlb() { return tlb; }
1114  void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr,
1115  uint8_t texcb, bool s);
1117  LongDescriptor &lDescriptor);
1119  LongDescriptor &lDescriptor);
1120 
1121  static LookupLevel toLookupLevel(uint8_t lookup_level_as_int);
1122 
1123  private:
1124 
1125  void doL1Descriptor();
1126  void doL1DescriptorWrapper();
1128 
1129  void doL2Descriptor();
1130  void doL2DescriptorWrapper();
1132 
1133  void doLongDescriptor();
1134 
1143 
1144  void doLongDescriptorWrapper(LookupLevel curr_lookup_level);
1146 
1147  bool fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes,
1148  Request::Flags flags, int queueIndex, Event *event,
1149  void (TableWalker::*doDescriptor)());
1150 
1152 
1153  void insertTableEntry(DescriptorBase &descriptor, bool longDescriptor);
1154  void insertPartialTableEntry(LongDescriptor &descriptor);
1155 
1161  std::tuple<Addr, Addr, LookupLevel> walkAddresses(
1162  Addr ttbr, GrainSize tg, int tsz, int pa_range);
1163 
1164  Fault processWalk();
1166 
1167  bool checkVAddrSizeFaultAArch64(Addr addr, int top_bit,
1168  GrainSize granule, int tsz, bool low_range);
1169 
1172  bool checkAddrSizeFaultAArch64(Addr addr, int pa_range);
1173 
1175  void processWalkWrapper();
1177 
1178  void nextWalk(ThreadContext *tc);
1179 
1180  void pendingChange();
1181 
1182  static uint8_t pageSizeNtoStatBin(uint8_t N);
1183 
1185  LookupLevel lookup_level, bool stage2);
1186 };
1187 
1188 } // namespace ArmISA
1189 } // namespace gem5
1190 
1191 #endif //__ARCH_ARM_TABLE_WALKER_HH__
const char data[]
FaultSource
Generic fault source enums used to index into {short/long/aarch64}DescFaultSources[] to get the actua...
Definition: faults.hh:96
static bool hasUnprivRegime(ExceptionLevel el, bool e2h)
Definition: mmu.cc:702
virtual bool global(WalkerState *currState) const =0
virtual uint64_t getRawData() const =0
virtual std::string dbgHeader() const =0
virtual uint8_t offsetBits() const =0
LookupLevel lookupLevel
Current lookup level for this descriptor.
Definition: table_walker.hh:79
virtual TlbEntry::DomainType domain() const =0
virtual bool secure(bool have_security, WalkerState *currState) const =0
uint64_t getRawData() const override
EntryType
Type of page table entry ARM DDI 0406B: B3-8.
void setAp0()
Set access flag that this entry has been touched.
bool dirty() const
This entry needs to be written back to memory.
Addr paddr(Addr va) const
Return the physcal address of the entry, bits in position.
uint32_t data
The raw bits of the entry.
bool supersection() const
Is the page a Supersection (16 MiB)?
bool secure(bool have_security, WalkerState *currState) const override
Returns true if this entry targets the secure physical address map.
bool xn() const override
Is the translation not allow execution?
Addr l2Addr() const
Address of L2 descriptor if it exists.
bool global(WalkerState *currState) const override
Is the translation global (no asid used)?
Addr pfn() const override
Return the physical frame, bits shifted right.
bool shareable() const override
If the section is shareable.
uint8_t texcb() const override
Memory region attributes: ARM DDI 0406B: B3-32.
uint8_t ap() const override
Three bit access protection flags.
TlbEntry::DomainType domain() const override
Domain Client/Manager: ARM DDI 0406B: B3-31.
bool _dirty
This entry has been modified (access flag set) and needs to be written back to memory.
Addr paddr() const
Return the physcal address of the entry, bits in position.
std::string dbgHeader() const override
uint8_t offsetBits() const override
Level 2 page table descriptor.
bool xn() const override
Is execution allowed on this mapping?
uint64_t getRawData() const override
uint8_t ap() const override
Three bit access protection flags.
bool global(WalkerState *currState) const override
Is the translation global (no asid used)?
void setAp0()
Set access flag that this entry has been touched.
Addr pfn() const override
Return the physical frame, bits shifted right.
uint8_t offsetBits() const override
bool secure(bool have_security, WalkerState *currState) const override
std::string dbgHeader() const override
TlbEntry::DomainType domain() const override
bool _dirty
This entry has been modified (access flag set) and needs to be written back to memory.
uint32_t data
The raw bits of the entry.
bool shareable() const override
If the section is shareable.
bool invalid() const
Is the entry invalid.
bool large() const
What is the size of the mapping?
uint8_t texcb() const override
Memory region attributes: ARM DDI 0406B: B3-32.
Addr paddr(Addr va) const
Return complete physical address given a VA.
bool dirty() const
This entry needs to be written back to memory.
Long-descriptor format (LPAE)
uint8_t sh() const
2-bit shareability field
uint8_t memAttr() const
Memory attributes, only used by stage 2 translations.
uint8_t rwTable() const
R/W protection flag for subsequent levels of lookup.
void setAf()
Set access flag that this entry has been touched.
uint8_t offsetBits() const override
Return the bit width of the page/block offset.
bool contiguousHint() const
Contiguous hint bit.
bool pxn() const
Is privileged execution allowed on this mapping? (LPAE only)
bool af() const
Returns true if the access flag (AF) is set.
bool pxnTable() const
Is privileged execution allowed on subsequent lookup levels?
bool aarch64
True if the current lookup is performed in AArch64 state.
EntryType type() const
Return the descriptor type.
bool xn() const override
Is execution allowed on this mapping?
bool secure(bool have_security, WalkerState *currState) const override
Returns true if this entry targets the secure physical address map.
std::string dbgHeader() const override
bool rw() const
Read/write access protection flag.
Addr nextTableAddr() const
Return the address of the next page table.
bool global(WalkerState *currState) const override
Is the translation global (no asid used)?
GrainSize grainSize
Width of the granule size in bits.
uint8_t attrIndx() const
Attribute index.
uint8_t ap() const override
2-bit access protection flags
uint64_t data
The raw bits of the entry.
bool _dirty
This entry has been modified (access flag set) and needs to be written back to memory.
Addr pfn() const override
Return the physical frame, bits shifted right.
Addr nextDescAddr(Addr va) const
Return the address of the next descriptor.
uint8_t apTable() const
Two bit access protection flags for subsequent levels of lookup.
Addr paddr() const
Return the physical address of the entry.
bool user() const
User/privileged level access protection flag.
uint8_t userTable() const
User/privileged mode protection flag for subsequent levels of lookup.
bool secureTable() const
Whether the subsequent levels of lookup are secure.
TlbEntry::DomainType domain() const override
static uint8_t ap(bool rw, bool user)
Return the AP bits as compatible with the AP[2:0] format.
uint64_t getRawData() const override
bool xnTable() const
Is execution allowed on subsequent lookup levels?
bool dirty() const
This entry needs to be written back to memory.
void sendFunctionalReq(Addr desc_addr, int size, uint8_t *data, Request::Flags flag)
SnoopRespPacketQueue snoopRespQueue
Packet queue used to store outgoing snoop responses.
void sendTimingReq(Addr desc_addr, int size, uint8_t *data, Request::Flags flag, Tick delay, Event *event)
RequestorID requestorId
Cached requestorId of the table walker.
ReqPacketQueue reqQueue
Packet queue used to store outgoing requests.
PacketPtr createPacket(Addr desc_addr, int size, uint8_t *data, Request::Flags flag, Tick delay, Event *event)
void handleResp(TableWalkerState *state, Addr addr, Addr size, Tick delay=0)
void handleRespPacket(PacketPtr pkt, Tick delay=0)
void sendAtomicReq(Addr desc_addr, int size, uint8_t *data, Request::Flags flag, Tick delay)
Port(TableWalker *_walker, RequestorID id)
bool recvTimingResp(PacketPtr pkt) override
Receive a timing response from the peer.
This translation class is used to trigger the data fetch once a timing translation returns the transl...
void markDelayed()
Signal that the translation has been delayed due to a hw page table walk.
void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode)
void setVirt(Addr vaddr, int size, Request::Flags flags, int requestorId)
MMU::ArmTranslationType tranType
Stage2Walk(TableWalker &_parent, uint8_t *_data, Event *_event, Addr vaddr, BaseMMU::Mode mode, MMU::ArmTranslationType tran_type)
void translateTiming(ThreadContext *tc)
bool isWrite
If the access is a write.
CPSR cpsr
Cached copy of the cpsr as it existed when translation began.
Addr vaddr_tainted
The virtual address that is being translated.
RequestPtr req
Request that is currently being serviced.
VTCR_t vtcr
Cached copy of the vtcr as it existed when translation began.
HCR hcr
Cached copy of the htcr as it existed when translation began.
Addr vaddr
The virtual address that is being translated with tagging removed.
bool functional
If the atomic mode should be functional.
bool secureLookup
Helper variables used to implement hierarchical access permissions when the long-desc.
bool isUncacheable
True if table walks are uncacheable (for table descriptors)
ThreadContext * tc
Thread context that we're doing the walk for.
bool hpd
Hierarchical access permission disable.
BaseMMU::Translation * transState
Translation state for delayed requests.
unsigned levels
Page entries walked during service (for stats)
bool isSecure
If the access comes from the secure state.
BaseMMU::Mode mode
Save mode for use in delayed response.
HTCR htcr
Cached copy of the htcr as it existed when translation began.
SCR scr
Cached copy of the scr as it existed when translation began.
ExceptionLevel el
Current exception level.
MMU::ArmTranslationType tranType
The translation type that has been requested.
SCTLR sctlr
Cached copy of the sctlr as it existed when translation began.
Fault fault
The fault that we are going to return.
Tick startTime
Timestamp for calculating elapsed time in service (for stats)
bool isFetch
If the access is a fetch (for execution, and no-exec) must be checked?
bool stage2Req
Flag indicating if a second stage of lookup is required.
TlbEntry walkEntry
Initial walk entry allowing to skip lookup levels.
bool timing
If the mode is timing or atomic.
LongDescriptor longDesc
Long-format descriptor (LPAE and AArch64)
int physAddrRange
Current physical address range in bits.
bool delayed
Whether the response is delayed in timing mode due to additional lookups.
uint16_t asid
ASID that we're servicing the request under.
L1Descriptor l1Desc
Short-format descriptors.
bool aarch64
If the access is performed in AArch64 state.
BaseMMU::Translation * stage2Tran
A pointer to the stage 2 translation that's in progress.
static LookupLevel toLookupLevel(uint8_t lookup_level_as_int)
enums::ArmLookupLevel LookupLevel
Definition: table_walker.hh:68
Fault testWalk(Addr pa, Addr size, TlbEntry::DomainType domain, LookupLevel lookup_level, bool stage2)
void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr, uint8_t texcb, bool s)
EventFunctionWrapper doL0LongDescEvent
const ArmRelease * release
Cached copies of system-level properties.
Fault generateLongDescFault(ArmFault::FaultSource src)
EventFunctionWrapper doL1DescEvent
EventFunctionWrapper doProcessEvent
static const unsigned REQUESTED
static const unsigned COMPLETED
void memAttrsAArch64(ThreadContext *tc, TlbEntry &te, LongDescriptor &lDescriptor)
void insertPartialTableEntry(LongDescriptor &descriptor)
void drainResume() override
Resume execution after a successful drain.
void doLongDescriptorWrapper(LookupLevel curr_lookup_level)
bool pending
If a timing translation is currently in progress.
Port * port
Port shared by the two table walkers.
PARAMS(ArmTableWalker)
std::tuple< Addr, Addr, LookupLevel > walkAddresses(Addr ttbr, GrainSize tg, int tsz, int pa_range)
Returns a tuple made of: 1) The address of the first page table 2) The address of the first descripto...
Fault readDataUntimed(ThreadContext *tc, Addr vaddr, Addr desc_addr, uint8_t *data, int num_bytes, Request::Flags flags, BaseMMU::Mode mode, MMU::ArmTranslationType tran_type, bool functional)
TableWalker(const Params &p)
Definition: table_walker.cc:62
void nextWalk(ThreadContext *tc)
void readDataTimed(ThreadContext *tc, Addr desc_addr, Stage2Walk *translation, int num_bytes, Request::Flags flags)
EventFunctionWrapper doL2DescEvent
bool checkVAddrSizeFaultAArch64(Addr addr, int top_bit, GrainSize granule, int tsz, bool low_range)
gem5::Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
std::list< WalkerState * > pendingQueue
Queue of requests that have passed are waiting because the walker is currently busy.
Fault walk(const RequestPtr &req, ThreadContext *tc, uint16_t asid, vmid_t _vmid, bool hyp, BaseMMU::Mode mode, BaseMMU::Translation *_trans, bool timing, bool functional, bool secure, MMU::ArmTranslationType tran_type, bool stage2, const TlbEntry *walk_entry)
MMU * mmu
The MMU to forward second stage look upts to.
RequestorID requestorId
Requestor id assigned by the MMU.
bool fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes, Request::Flags flags, int queueIndex, Event *event, void(TableWalker::*doDescriptor)())
gem5::ArmISA::TableWalker::TableWalkerStats stats
const bool isStage2
Indicates whether this table walker is part of the stage 2 mmu.
EventFunctionWrapper doL1LongDescEvent
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 ...
static uint8_t pageSizeNtoStatBin(uint8_t N)
void completeDrain()
Checks if all state is cleared and if so, completes drain.
void insertTableEntry(DescriptorBase &descriptor, bool longDescriptor)
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
std::list< WalkerState * > stateQueues[LookupLevel::Num_ArmLookupLevel]
Queues of requests for all the different lookup levels.
unsigned numSquashable
The number of walks belonging to squashed instructions that can be removed from the pendingQueue per ...
TLB * tlb
TLB that is initiating these table walks.
void memAttrsLPAE(ThreadContext *tc, TlbEntry &te, LongDescriptor &lDescriptor)
EventFunctionWrapper doL2LongDescEvent
uint8_t physAddrRange() const
SCTLR sctlr
Cached copy of the sctlr as it existed when translation began.
EventFunctionWrapper doL3LongDescEvent
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
ClockedObjectParams Params
Parameters of ClockedObject.
virtual std::string name() const
Definition: named.hh:47
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:294
Ports are used to interface objects to each other.
Definition: port.hh:62
The QueuedRequestPort combines two queues, a request queue and a snoop response queue,...
Definition: qport.hh:110
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Statistics container.
Definition: group.hh:94
A simple histogram stat.
Definition: statistics.hh:2127
This is a simple scalar statistic, like a counter.
Definition: statistics.hh:1931
A 2-Dimensional vecto of scalar stats.
Definition: statistics.hh:2059
A vector of scalar stats.
Definition: statistics.hh:2007
STL list class.
Definition: stl.hh:51
ClockedObject declaration and implementation.
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:76
constexpr T mbits(T val, unsigned first, unsigned last)
Mask off the given bits in place like bits() but without shifting.
Definition: bitfield.hh:103
DrainState
Object drain/handover states.
Definition: drain.hh:75
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
atomic_var_t state
Definition: helpers.cc:188
uint8_t flags
Definition: helpers.cc:66
static const RegId & hyp(unsigned index)
Definition: int.hh:473
Bitfield< 30 > te
Definition: misc_types.hh:344
const PageTableOps * getPageTableOps(GrainSize trans_granule)
Definition: pagetable.cc:476
Bitfield< 4, 0 > mode
Definition: misc_types.hh:74
Bitfield< 4 > s
Definition: misc_types.hh:568
Bitfield< 7, 4 > domain
Definition: misc_types.hh:430
Bitfield< 21, 20 > stride
Definition: misc_types.hh:453
uint16_t vmid_t
Definition: types.hh:57
Bitfield< 39, 12 > pa
Definition: misc_types.hh:663
Bitfield< 8 > va
Definition: misc_types.hh:282
Bitfield< 10, 5 > event
constexpr RegId L2
Definition: int.hh:113
constexpr RegId L1
Definition: int.hh:112
constexpr RegId L0
Definition: int.hh:111
constexpr RegId L3
Definition: int.hh:114
Bitfield< 54 > p
Definition: pagetable.hh:70
Bitfield< 3 > addr
Definition: types.hh:84
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::shared_ptr< FaultBase > Fault
Definition: types.hh:248
std::shared_ptr< Request > RequestPtr
Definition: request.hh:92
const PortID InvalidPortID
Definition: types.hh:246
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:245
uint64_t Tick
Tick count type.
Definition: types.hh:58
uint16_t RequestorID
Definition: request.hh:95
Declaration of a simple PacketQueue that is associated with a port on which it attempts to send packe...
Declaration of the queued port.
Declaration of a request, the overall memory request consisting of the parts of the request that are ...
Definition: global.h:77
TableWalkerStats(statistics::Group *parent)
A virtual base opaque structure used to hold state associated with the packet (e.g....
Definition: packet.hh:468

Generated on Wed Dec 21 2022 10:22:27 for gem5 by doxygen 1.9.1