gem5 v23.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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
57namespace gem5
58{
59
60class ThreadContext;
61
62namespace ArmISA {
63class Translation;
64class TLB;
65
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 {
110 };
111
113 uint32_t data;
114
117 bool _dirty;
118
120 L1Descriptor() : data(0), _dirty(false)
121 {
122 lookupLevel = LookupLevel::L1;
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
144 type() const
145 {
146 return (EntryType)(data & 0x3);
147 }
148
150 bool
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 {
285 lookupLevel = LookupLevel::L2;
286 }
287
288 L2Descriptor(L1Descriptor &parent) : data(0), l1Parent(&parent),
289 _dirty(false)
290 {
291 lookupLevel = LookupLevel::L2;
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),
427 {}
428
430 uint64_t data;
431
434 bool _dirty;
435
438
441
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
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 ||
493 lookupLevel == LookupLevel::L3)
494 return Invalid;
495 else
496 return Block;
497
498 case Grain16KB:
499 if (lookupLevel == LookupLevel::L2)
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) ||
508 lookupLevel == LookupLevel::L2)
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 {
609 if (lookupLevel == LookupLevel::L1)
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 &&
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
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
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
866
869
872
875
883
885 bool hpd;
886
889
892
894 bool timing;
895
898
901
904
908
911
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:
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:
967
970
973
976 };
977
981 {
982 private:
983 uint8_t *data;
991
992 public:
994
995 Stage2Walk(TableWalker &_parent, uint8_t *_data, Event *_event,
997 MMU::ArmTranslationType tran_type);
998
999 void markDelayed() {}
1000
1001 void finish(const Fault &fault, const RequestPtr &req,
1003
1004 void
1006 int requestorId)
1007 {
1008 numBytes = size;
1009 req->setVirt(vaddr, size, flags, requestorId, 0);
1010 }
1011
1013 };
1014
1016 uint8_t *data, int num_bytes, Request::Flags flags,
1018 bool functional);
1019 void readDataTimed(ThreadContext *tc, Addr desc_addr,
1020 Stage2Walk *translation, int num_bytes,
1022
1023 protected:
1024
1026 std::list<WalkerState *> stateQueues[LookupLevel::Num_ArmLookupLevel];
1027
1031
1034
1037
1040
1042 const bool isStage2;
1043
1046
1048 SCTLR sctlr;
1049
1051
1054
1058
1063
1066 {
1077 // Essentially "L" of queueing theory
1082
1083 mutable unsigned pendingReqs;
1085
1086 static const unsigned REQUESTED = 0;
1087 static const unsigned COMPLETED = 1;
1088
1089 public:
1090 PARAMS(ArmTableWalker);
1091 TableWalker(const Params &p);
1092 virtual ~TableWalker();
1093
1094 bool haveLargeAsid64() const { return _haveLargeAsid64; }
1095 uint8_t physAddrRange() const { return _physAddrRange; }
1097 void completeDrain();
1098 DrainState drain() override;
1099 void drainResume() override;
1100
1101 gem5::Port &getPort(const std::string &if_name,
1102 PortID idx=InvalidPortID) override;
1103
1105
1106 Fault walk(const RequestPtr &req, ThreadContext *tc,
1107 uint16_t asid, vmid_t _vmid,
1108 bool hyp, BaseMMU::Mode mode, BaseMMU::Translation *_trans,
1109 bool timing, bool functional, bool secure,
1110 MMU::ArmTranslationType tran_type, bool stage2,
1111 const TlbEntry *walk_entry);
1112
1113 void setMmu(MMU *_mmu);
1114 void setTlb(TLB *_tlb) { tlb = _tlb; }
1115 TLB* getTlb() { return tlb; }
1116 void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr,
1117 uint8_t texcb, bool s);
1119 LongDescriptor &lDescriptor);
1121 LongDescriptor &lDescriptor);
1122
1123 static LookupLevel toLookupLevel(uint8_t lookup_level_as_int);
1124
1125 private:
1126
1127 void doL1Descriptor();
1128 void doL1DescriptorWrapper();
1130
1131 void doL2Descriptor();
1132 void doL2DescriptorWrapper();
1134
1135 void doLongDescriptor();
1136
1145
1146 void doLongDescriptorWrapper(LookupLevel curr_lookup_level);
1148
1149 bool fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes,
1150 Request::Flags flags, int queueIndex, Event *event,
1151 void (TableWalker::*doDescriptor)());
1152
1154
1155 void insertTableEntry(DescriptorBase &descriptor, bool longDescriptor);
1156 void insertPartialTableEntry(LongDescriptor &descriptor);
1157
1163 std::tuple<Addr, Addr, LookupLevel> walkAddresses(
1164 Addr ttbr, GrainSize tg, int tsz, int pa_range);
1165
1168
1169 bool checkVAddrSizeFaultAArch64(Addr addr, int top_bit,
1170 GrainSize granule, int tsz, bool low_range);
1171
1174 bool checkAddrSizeFaultAArch64(Addr addr, int pa_range);
1175
1177 void processWalkWrapper();
1179
1180 void nextWalk(ThreadContext *tc);
1181
1182 void pendingChange();
1183
1184 static uint8_t pageSizeNtoStatBin(uint8_t N);
1185
1187 LookupLevel lookup_level, bool stage2);
1188};
1189
1190} // namespace ArmISA
1191} // namespace gem5
1192
1193#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.
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
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.
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.
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)
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)
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
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)
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
Provide a default implementation of the drain interface for objects that don't need draining.
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:295
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:111
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Statistics container.
Definition group.hh:93
A simple histogram stat.
This is a simple scalar statistic, like a counter.
A 2-Dimensional vecto of scalar stats.
A vector of scalar stats.
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:188
atomic_var_t state
Definition helpers.cc:188
uint8_t flags
Definition helpers.cc:66
Bitfield< 30 > te
const PageTableOps * getPageTableOps(GrainSize trans_granule)
Definition pagetable.cc:476
Bitfield< 4, 0 > mode
Definition misc_types.hh:74
Bitfield< 4 > s
Bitfield< 7, 4 > domain
Bitfield< 21, 20 > stride
uint16_t vmid_t
Definition types.hh:57
Bitfield< 39, 12 > pa
Bitfield< 8 > va
Bitfield< 10, 5 > event
Bitfield< 0 > p
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:249
std::shared_ptr< Request > RequestPtr
Definition request.hh:94
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
A virtual base opaque structure used to hold state associated with the packet (e.g....
Definition packet.hh:469

Generated on Mon Jul 10 2023 14:24:25 for gem5 by doxygen 1.9.7