gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
table_walker.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010-2016, 2019, 2021-2024 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 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 uint8_t* getRawPtr() = 0;
90 virtual uint64_t getRawData() const = 0;
91 virtual uint8_t texcb() const
92 {
93 panic("texcb() not implemented for this class\n");
94 }
95 virtual bool shareable() const
96 {
97 panic("shareable() not implemented for this class\n");
98 }
99 };
100
102 {
103 public:
112
114 uint32_t data;
115
118 bool _dirty;
119
121 L1Descriptor() : data(0), _dirty(false)
122 {
123 lookupLevel = LookupLevel::L1;
124 }
125
126 uint8_t*
127 getRawPtr() override
128 {
129 return reinterpret_cast<uint8_t*>(&data);
130 }
131
132 uint64_t
133 getRawData() const override
134 {
135 return (data);
136 }
137
138 std::string
139 dbgHeader() const override
140 {
141 return "Inserting Section Descriptor into TLB\n";
142 }
143
144 uint8_t
145 offsetBits() const override
146 {
147 return 20;
148 }
149
151 type() const
152 {
153 return (EntryType)(data & 0x3);
154 }
155
157 bool
159 {
160 return bits(data, 18);
161 }
162
164 Addr
165 paddr() const
166 {
167 if (supersection())
168 panic("Super sections not implemented\n");
169 return mbits(data, 31, 20);
170 }
171
173 Addr
174 paddr(Addr va) const
175 {
176 if (supersection())
177 panic("Super sections not implemented\n");
178 return mbits(data, 31, 20) | mbits(va, 19, 0);
179 }
180
182 Addr
183 pfn() const override
184 {
185 if (supersection())
186 panic("Super sections not implemented\n");
187 return bits(data, 31, 20);
188 }
189
191 bool
192 global(WalkerState *currState) const override
193 {
194 return !bits(data, 17);
195 }
196
198 bool
199 xn() const override
200 {
201 return bits(data, 4);
202 }
203
205 uint8_t
206 ap() const override
207 {
208 return (bits(data, 15) << 2) | bits(data, 11, 10);
209 }
210
213 domain() const override
214 {
215 return static_cast<DomainType>(bits(data, 8, 5));
216 }
217
219 Addr
220 l2Addr() const
221 {
222 return mbits(data, 31, 10);
223 }
224
230 uint8_t
231 texcb() const override
232 {
233 return bits(data, 2) | bits(data, 3) << 1 | bits(data, 14, 12) << 2;
234 }
235
237 bool
238 shareable() const override
239 {
240 return bits(data, 16);
241 }
242
246 void
248 {
249 data |= 1 << 10;
250 _dirty = true;
251 }
252
254 bool
255 dirty() const
256 {
257 return _dirty;
258 }
259
264 bool
265 secure(bool have_security, WalkerState *currState) const override
266 {
267 if (have_security && currState->secureLookup) {
268 if (type() == PageTable)
269 return !bits(data, 3);
270 else
271 return !bits(data, 19);
272 }
273 return false;
274 }
275 };
276
279 {
280 public:
282 uint32_t data;
284
287 bool _dirty;
288
290 L2Descriptor() : data(0), l1Parent(nullptr), _dirty(false)
291 {
292 lookupLevel = LookupLevel::L2;
293 }
294
295 L2Descriptor(L1Descriptor &parent) : data(0), l1Parent(&parent),
296 _dirty(false)
297 {
298 lookupLevel = LookupLevel::L2;
299 }
300
301 uint8_t*
302 getRawPtr() override
303 {
304 return reinterpret_cast<uint8_t*>(&data);
305 }
306
307 uint64_t
308 getRawData() const override
309 {
310 return (data);
311 }
312
313 std::string
314 dbgHeader() const override
315 {
316 return "Inserting L2 Descriptor into TLB\n";
317 }
318
320 domain() const override
321 {
322 return l1Parent->domain();
323 }
324
325 bool
326 secure(bool have_security, WalkerState *currState) const override
327 {
328 return l1Parent->secure(have_security, currState);
329 }
330
331 uint8_t
332 offsetBits() const override
333 {
334 return large() ? 16 : 12;
335 }
336
338 bool
339 invalid() const
340 {
341 return bits(data, 1, 0) == 0;
342 }
343
345 bool
346 large() const
347 {
348 return bits(data, 1) == 0;
349 }
350
352 bool
353 xn() const override
354 {
355 return large() ? bits(data, 15) : bits(data, 0);
356 }
357
359 bool
360 global(WalkerState *currState) const override
361 {
362 return !bits(data, 11);
363 }
364
366 uint8_t
367 ap() const override
368 {
369 return bits(data, 5, 4) | (bits(data, 9) << 2);
370 }
371
373 uint8_t
374 texcb() const override
375 {
376 return large() ?
377 (bits(data, 2) | (bits(data, 3) << 1) | (bits(data, 14, 12) << 2)) :
378 (bits(data, 2) | (bits(data, 3) << 1) | (bits(data, 8, 6) << 2));
379 }
380
382 Addr
383 pfn() const override
384 {
385 return large() ? bits(data, 31, 16) : bits(data, 31, 12);
386 }
387
389 Addr
390 paddr(Addr va) const
391 {
392 if (large())
393 return mbits(data, 31, 16) | mbits(va, 15, 0);
394 else
395 return mbits(data, 31, 12) | mbits(va, 11, 0);
396 }
397
399 bool
400 shareable() const override
401 {
402 return bits(data, 10);
403 }
404
408 void
410 {
411 data |= 1 << 4;
412 _dirty = true;
413 }
414
416 bool
417 dirty() const
418 {
419 return _dirty;
420 }
421
422 };
423
426 {
427 public:
436
438 : data(0), _dirty(false), aarch64(false), grainSize(Grain4KB),
439 physAddrRange(0), isStage2(false)
440 {}
441
443 uint64_t data;
444
447 bool _dirty;
448
451
454
456
458
459 uint8_t*
460 getRawPtr() override
461 {
462 return reinterpret_cast<uint8_t*>(&data);
463 }
464
465 uint64_t
466 getRawData() const override
467 {
468 return (data);
469 }
470
471 std::string
472 dbgHeader() const override
473 {
474 switch (type()) {
476 assert(lookupLevel == LookupLevel::L3);
477 return "Inserting Page descriptor into TLB\n";
479 assert(lookupLevel < LookupLevel::L3);
480 return "Inserting Block descriptor into TLB\n";
482 return "Inserting Table descriptor into TLB\n";
483 default:
484 panic("Trying to insert and invalid descriptor\n");
485 }
486 }
487
492 bool
493 secure(bool have_security, WalkerState *currState) const override
494 {
495 if (type() == Block || type() == Page) {
496 if (isStage2) {
497 return have_security && currState->secureLookup &&
498 !currState->vtcr.nsa;
499 } else {
500 return have_security &&
501 (currState->secureLookup && !bits(data, 5));
502 }
503 } else {
504 return have_security && currState->secureLookup;
505 }
506 }
507
510 type() const
511 {
512 switch (bits(data, 1, 0)) {
513 case 0x1:
514 // In AArch64 blocks are not allowed at L0 for the
515 // 4 KiB granule and at L1 for 16/64 KiB granules
516 switch (grainSize) {
517 case Grain4KB:
518 if (lookupLevel == LookupLevel::L0 ||
519 lookupLevel == LookupLevel::L3)
520 return Invalid;
521 else
522 return Block;
523
524 case Grain16KB:
525 if (lookupLevel == LookupLevel::L2)
526 return Block;
527 else
528 return Invalid;
529
530 case Grain64KB:
531 // With Armv8.2-LPA (52bit PA) L1 Block descriptors
532 // are allowed for 64KiB granule
533 if ((lookupLevel == LookupLevel::L1 && physAddrRange == 52) ||
534 lookupLevel == LookupLevel::L2)
535 return Block;
536 else
537 return Invalid;
538
539 default:
540 return Invalid;
541 }
542 case 0x3:
543 return lookupLevel == LookupLevel::L3 ? Page : Table;
544 default:
545 return Invalid;
546 }
547 }
548
550 uint8_t
551 offsetBits() const override
552 {
553 if (type() == Block) {
554 switch (grainSize) {
555 case Grain4KB:
556 return lookupLevel == LookupLevel::L1 ?
557 30 /* 1 GiB */ : 21 /* 2 MiB */;
558 case Grain16KB:
559 return 25 /* 32 MiB */;
560 case Grain64KB:
561 return lookupLevel == LookupLevel::L1 ?
562 42 /* 4 TiB */ : 29 /* 512 MiB */;
563 default:
564 panic("Invalid AArch64 VM granule size\n");
565 }
566 } else if (type() == Page) {
567 switch (grainSize) {
568 case Grain4KB:
569 case Grain16KB:
570 case Grain64KB:
571 return grainSize; /* enum -> uint okay */
572 default:
573 panic("Invalid AArch64 VM granule size\n");
574 }
575 } else if (type() == Table) {
576 const auto* ptops = getPageTableOps(grainSize);
577 return ptops->walkBits(lookupLevel);
578 }
579 panic("AArch64 page table entry must be block or page\n");
580 }
581
583 Addr
584 pfn() const override
585 {
586 return paddr() >> offsetBits();
587 }
588
590 Addr
591 paddr() const
592 {
593 Addr addr = 0;
594 if (aarch64) {
595 addr = mbits(data, 47, offsetBits());
596 if (physAddrRange == 52 && grainSize == Grain64KB) {
597 addr |= bits(data, 15, 12) << 48;
598 }
599 } else {
600 addr = mbits(data, 39, offsetBits());
601 }
602 return addr;
603 }
604
606 Addr
608 {
609 assert(type() == Table);
610 Addr table_address = 0;
611 if (aarch64) {
612 table_address = mbits(data, 47, grainSize);
613 // Using 52bit if Armv8.2-LPA is implemented
614 if (physAddrRange == 52 && grainSize == Grain64KB)
615 table_address |= bits(data, 15, 12) << 48;
616 } else {
617 table_address = mbits(data, 39, 12);
618 }
619
620 return table_address;
621 }
622
624 Addr
626 {
627 assert(type() == Table);
628 Addr pa = 0;
629 if (aarch64) {
630 int stride = grainSize - 3;
631 int va_lo = stride * (3 - (lookupLevel + 1)) + grainSize;
632 int va_hi = va_lo + stride - 1;
633 pa = nextTableAddr() | (bits(va, va_hi, va_lo) << 3);
634 } else {
635 if (lookupLevel == LookupLevel::L1)
636 pa = nextTableAddr() | (bits(va, 29, 21) << 3);
637 else // lookupLevel == L2
638 pa = nextTableAddr() | (bits(va, 20, 12) << 3);
639 }
640 return pa;
641 }
642
644 bool
645 xn() const override
646 {
647 assert(type() == Block || type() == Page);
648 return bits(data, 54);
649 }
650
652 bool
653 pxn() const
654 {
655 assert(type() == Block || type() == Page);
656 return bits(data, 53);
657 }
658
660 bool
662 {
663 assert(type() == Block || type() == Page);
664 return bits(data, 52);
665 }
666
668 bool
669 global(WalkerState *currState) const override
670 {
671 assert(currState && (type() == Block || type() == Page));
672 const bool secure_state = currState->ss == SecurityState::Secure;
673 if (!currState->aarch64 && secure_state &&
674 !currState->secureLookup) {
675 return false; // ARM ARM issue C B3.6.3
676 } else if (currState->aarch64) {
677 if (!MMU::hasUnprivRegime(currState->regime)) {
678 // By default translations are treated as global
679 // in AArch64 for regimes without an unpriviledged
680 // component
681 return true;
682 } else if (secure_state && !currState->secureLookup) {
683 return false;
684 }
685 }
686 return !bits(data, 11);
687 }
688
690 bool
691 fnxs() const
692 {
693 assert((type() == Block || type() == Page));
694 return bits(data, 11);
695 }
696
698 bool
699 af() const
700 {
701 assert(type() == Block || type() == Page);
702 return bits(data, 10);
703 }
704
706 uint8_t
707 sh() const
708 {
709 assert(type() == Block || type() == Page);
710 return bits(data, 9, 8);
711 }
712
714 uint8_t
715 ap() const override
716 {
717 assert(type() == Block || type() == Page);
718 // Long descriptors only support the AP[2:1] scheme
719 return bits(data, 7, 6);
720 }
721
723 uint8_t
724 piindex() const
725 {
726 assert(type() == Block || type() == Page);
727 return (bits(data, 54) << 3) +
728 (bits(data, 53) << 2) +
729 (bits(data, 51) << 1) +
730 bits(data, 6);
731 }
732
734 bool
735 rw() const
736 {
737 assert(type() == Block || type() == Page);
738 return !bits(data, 7);
739 }
740
742 bool
743 user() const
744 {
745 assert(type() == Block || type() == Page);
746 return bits(data, 6);
747 }
748
752 static uint8_t
753 ap(bool rw, bool user)
754 {
755 return ((!rw) << 2) | (user << 1);
756 }
757
759 domain() const override
760 {
761 // Long-desc. format only supports Client domain
762 return DomainType::Client;
763 }
764
766 uint8_t
767 attrIndx() const
768 {
769 assert(type() == Block || type() == Page);
770 return bits(data, 4, 2);
771 }
772
774 uint8_t
775 memAttr() const
776 {
777 assert(type() == Block || type() == Page);
778 return bits(data, 5, 2);
779 }
780
783 void
785 {
786 data |= 1 << 10;
787 _dirty = true;
788 }
789
791 bool
792 dirty() const
793 {
794 return _dirty;
795 }
796
798 bool
800 {
801 assert(type() == Table);
802 return !bits(data, 63);
803 }
804
806 uint8_t
807 apTable() const
808 {
809 assert(type() == Table);
810 return bits(data, 62, 61);
811 }
812
814 uint8_t
815 rwTable() const
816 {
817 assert(type() == Table);
818 return !bits(data, 62);
819 }
820
823 uint8_t
824 userTable() const
825 {
826 assert(type() == Table);
827 return !bits(data, 61);
828 }
829
831 bool
832 xnTable() const
833 {
834 assert(type() == Table);
835 return bits(data, 60);
836 }
837
839 bool
840 pxnTable() const
841 {
842 assert(type() == Table);
843 return bits(data, 59);
844 }
845 };
846
848 {
849 public:
852
855
858
861
864
867
870
872 uint16_t asid;
874
877
880
883
886
888 SCTLR sctlr;
889
891 SCR scr;
892
894 CPSR cpsr;
895
897 union
898 {
899 TTBCR ttbcr; // AArch32 translations
900 TCR tcr; // AArch64 translations
901 };
902
904 HTCR htcr;
905
907 HCR hcr;
908
910 VTCR_t vtcr;
911
914
917
923 bool secureLookup = false;
924
929
932
936 {
937 bool rwTable = false;
938 bool userTable = false;
939 bool xnTable = false;
940 bool pxnTable = false;
941 };
942 std::optional<LongDescData> longDescData;
943
945 bool hpd;
946
947 uint8_t sh;
948 uint8_t irgn;
949 uint8_t orgn;
950
953
956
958 bool timing;
959
962
965
968
972
975
979
981
984
986 unsigned levels;
987
990
992
993 WalkerState();
994
995 std::string name() const { return tableWalker->name(); }
996 };
997
999 {
1000 public:
1002 Event *event = nullptr;
1003 };
1004
1006 {
1007 public:
1008 Port(TableWalker& _walker);
1009
1010 void sendFunctionalReq(const RequestPtr &req, uint8_t *data);
1011 void sendAtomicReq(const RequestPtr &req, uint8_t *data, Tick delay);
1012 void sendTimingReq(const RequestPtr &req, uint8_t *data, Tick delay,
1013 Event *event);
1014
1015 bool recvTimingResp(PacketPtr pkt) override;
1016
1017 private:
1018 void handleRespPacket(PacketPtr pkt, Tick delay=0);
1019 void handleResp(TableWalkerState *state, Addr addr,
1020 Addr size, Tick delay=0);
1021
1022 PacketPtr createPacket(const RequestPtr &req, uint8_t *data,
1023 Tick delay, Event *event);
1024
1025 private:
1027
1030
1033 };
1034
1038 {
1039 private:
1040 uint8_t *data;
1048
1049 public:
1051
1052 Stage2Walk(TableWalker &_parent, uint8_t *_data, Event *_event,
1054 MMU::ArmTranslationType tran_type);
1055
1056 void markDelayed() {}
1057
1058 void finish(const Fault &fault, const RequestPtr &req,
1060
1061 void
1063 int requestorId)
1064 {
1065 numBytes = size;
1066 req->setVirt(vaddr, size, flags, requestorId, 0);
1067 }
1068
1070 };
1071
1073 uint8_t *data, int num_bytes, Request::Flags flags,
1075 bool functional);
1076 void readDataTimed(ThreadContext *tc, Addr desc_addr,
1077 Stage2Walk *translation, int num_bytes,
1078 Request::Flags flags);
1079
1080 protected:
1081
1083 std::list<WalkerState *> stateQueues[LookupLevel::Num_ArmLookupLevel];
1084
1088
1091
1094
1097
1099 const bool isStage2;
1100
1103
1105 SCTLR sctlr;
1106
1108
1111
1115
1120
1139
1140 mutable unsigned pendingReqs;
1142
1143 static const unsigned REQUESTED = 0;
1144 static const unsigned COMPLETED = 1;
1145
1146 public:
1147 PARAMS(ArmTableWalker);
1148 TableWalker(const Params &p);
1149 virtual ~TableWalker();
1150
1151 bool haveLargeAsid64() const { return _haveLargeAsid64; }
1152 uint8_t physAddrRange() const { return _physAddrRange; }
1154 void completeDrain();
1155 DrainState drain() override;
1156 void drainResume() override;
1157
1158 gem5::Port &getPort(const std::string &if_name,
1159 PortID idx=InvalidPortID) override;
1160
1162
1163 Fault walk(const RequestPtr &req, ThreadContext *tc,
1164 uint16_t asid, vmid_t _vmid,
1166 bool timing, bool functional, SecurityState ss,
1167 PASpace ipaspace,
1168 MMU::ArmTranslationType tran_type, bool stage2,
1169 const TlbEntry *walk_entry);
1170
1171 void setMmu(MMU *_mmu);
1172 void setTlb(TLB *_tlb) { tlb = _tlb; }
1173 TLB* getTlb() { return tlb; }
1174 void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr,
1175 uint8_t texcb, bool s);
1177 LongDescriptor &lDescriptor);
1179 LongDescriptor &lDescriptor);
1181 bool uncacheableFromAttrs(uint8_t attrs);
1182
1183 static LookupLevel toLookupLevel(uint8_t lookup_level_as_int);
1184
1185 private:
1186
1187 void doL1Descriptor();
1188 void doL1DescriptorWrapper();
1190
1191 void doL2Descriptor();
1192 void doL2DescriptorWrapper();
1194
1195 void doLongDescriptor();
1196
1205
1206 void doLongDescriptorWrapper(LookupLevel curr_lookup_level);
1208
1209 void fetchDescriptor(Addr desc_addr,
1210 DescriptorBase &descriptor, int num_bytes,
1211 Request::Flags flags, LookupLevel lookup_lvl, Event *event,
1212 void (TableWalker::*doDescriptor)());
1213
1215
1216 void insertTableEntry(DescriptorBase &descriptor, bool longDescriptor);
1217 void insertPartialTableEntry(LongDescriptor &descriptor);
1218
1224 std::tuple<Addr, Addr, LookupLevel> walkAddresses(
1225 Addr ttbr, GrainSize tg, int tsz, int pa_range);
1226
1229
1230 Addr maxTxSz(GrainSize tg) const;
1231 Addr s1MinTxSz(GrainSize tg) const;
1232 bool s1TxSzFault(GrainSize tg, int tsz) const;
1233 bool checkVAOutOfRange(Addr addr, int top_bit,
1234 int tsz, bool low_range);
1235
1238 bool checkAddrSizeFaultAArch64(Addr addr, int pa_range);
1239
1241 bool uncacheableWalk() const;
1242
1244 void processWalkWrapper();
1246
1247 void nextWalk(ThreadContext *tc);
1248
1249 void pendingChange();
1250
1252 void stashCurrState(int queue_idx);
1253
1254 static uint8_t pageSizeNtoStatBin(uint8_t N);
1255
1256 void mpamTagTableWalk(RequestPtr &req) const;
1257
1258 public: /* Testing */
1260
1262
1263 Fault testWalk(const RequestPtr &walk_req, DomainType domain,
1264 LookupLevel lookup_level);
1265};
1266
1267} // namespace ArmISA
1268} // namespace gem5
1269
1270#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(TranslationRegime regime)
Definition mmu.cc:989
virtual bool global(WalkerState *currState) const =0
virtual uint64_t getRawData() const =0
virtual DomainType domain() const =0
virtual std::string dbgHeader() const =0
virtual uint8_t offsetBits() const =0
LookupLevel lookupLevel
Current lookup level for this descriptor.
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)?
DomainType domain() const override
Domain Client/Manager: ARM DDI 0406B: B3-31.
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.
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
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.
DomainType domain() const override
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?
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?
uint8_t piindex() const
Stage 1 Indirect permissions.
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.
bool fnxs() const
FNXS for FEAT_XS only.
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.
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.
SnoopRespPacketQueue snoopRespQueue
Packet queue used to store outgoing snoop responses.
ReqPacketQueue reqQueue
Packet queue used to store outgoing requests.
void sendAtomicReq(const RequestPtr &req, uint8_t *data, Tick delay)
void handleResp(TableWalkerState *state, Addr addr, Addr size, Tick delay=0)
void sendFunctionalReq(const RequestPtr &req, uint8_t *data)
void handleRespPacket(PacketPtr pkt, Tick delay=0)
void sendTimingReq(const RequestPtr &req, uint8_t *data, Tick delay, Event *event)
PacketPtr createPacket(const RequestPtr &req, uint8_t *data, Tick delay, Event *event)
bool recvTimingResp(PacketPtr pkt) override
Receive a timing response from the peer.
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)
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
Whether lookups should be treated as using the secure state.
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.
SecurityState ss
Security State of the access.
std::optional< LongDescData > longDescData
unsigned levels
Page entries walked during service (for stats)
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.
TranslationRegime regime
Current translation regime.
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.
PASpace ipaSpace
IPA space (Secure vs NonSecure); stage2 only.
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
void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr, uint8_t texcb, bool s)
EventFunctionWrapper doL0LongDescEvent
const ArmRelease * release
Cached copies of system-level properties.
bool checkVAOutOfRange(Addr addr, int top_bit, int tsz, bool low_range)
Fault generateLongDescFault(ArmFault::FaultSource src)
EventFunctionWrapper doL1DescEvent
EventFunctionWrapper doProcessEvent
static const unsigned REQUESTED
static const unsigned COMPLETED
bool uncacheableWalk() const
Returns true if the table walk should be uncacheable.
void memAttrsAArch64(ThreadContext *tc, TlbEntry &te, LongDescriptor &lDescriptor)
void insertPartialTableEntry(LongDescriptor &descriptor)
void fetchDescriptor(Addr desc_addr, DescriptorBase &descriptor, int num_bytes, Request::Flags flags, LookupLevel lookup_lvl, Event *event, void(TableWalker::*doDescriptor)())
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.
Fault testWalk(const RequestPtr &walk_req, DomainType domain, LookupLevel lookup_level)
PARAMS(ArmTableWalker)
Addr s1MinTxSz(GrainSize tg) const
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)
void nextWalk(ThreadContext *tc)
TlbTestInterface * test
void readDataTimed(ThreadContext *tc, Addr desc_addr, Stage2Walk *translation, int num_bytes, Request::Flags flags)
EventFunctionWrapper doL2DescEvent
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.
bool s1TxSzFault(GrainSize tg, int tsz) const
MMU * mmu
The MMU to forward second stage look upts to.
RequestorID requestorId
Requestor id assigned by the MMU.
gem5::ArmISA::TableWalker::TableWalkerStats stats
Fault walk(const RequestPtr &req, ThreadContext *tc, uint16_t asid, vmid_t _vmid, BaseMMU::Mode mode, BaseMMU::Translation *_trans, bool timing, bool functional, SecurityState ss, PASpace ipaspace, MMU::ArmTranslationType tran_type, bool stage2, const TlbEntry *walk_entry)
const bool isStage2
Indicates whether this table walker is part of the stage 2 mmu.
EventFunctionWrapper doL1LongDescEvent
bool uncacheableFromAttrs(uint8_t attrs)
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 ...
void mpamTagTableWalk(RequestPtr &req) const
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)
void setTestInterface(TlbTestInterface *ti)
EventFunctionWrapper doL2LongDescEvent
uint8_t physAddrRange() const
void memAttrsWalkAArch64(TlbEntry &te)
Addr maxTxSz(GrainSize tg) const
SCTLR sctlr
Cached copy of the sctlr as it existed when translation began.
EventFunctionWrapper doL3LongDescEvent
void stashCurrState(int queue_idx)
Timing mode: saves the currState into the stateQueues.
ClockedObject(const ClockedObjectParams &p)
ClockedObjectParams Params
Parameters of ClockedObject.
Ports are used to interface objects to each other.
Definition port.hh:62
QueuedRequestPort(const std::string &name, ReqPacketQueue &req_queue, SnoopRespPacketQueue &snoop_resp_queue, PortID id=InvalidPortID)
Create a QueuedPort with a given name, and a supplied implementation of two packet queues.
Definition qport.hh:134
gem5::Flags< FlagsType > Flags
Definition request.hh:102
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:79
constexpr T mbits(T val, unsigned first, unsigned last)
Mask off the given bits in place like bits() but without shifting.
Definition bitfield.hh:106
DrainState
Object drain/handover states.
Definition drain.hh:75
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:220
Bitfield< 30 > te
const PageTableOps * getPageTableOps(GrainSize trans_granule)
Definition pagetable.cc:477
Bitfield< 4, 0 > mode
Definition misc_types.hh:74
Bitfield< 4 > s
Bitfield< 7, 4 > domain
SecurityState
Security State.
Definition types.hh:273
Bitfield< 21, 20 > stride
uint16_t vmid_t
Definition types.hh:57
PASpace
Physical Address Space.
Definition types.hh:280
Bitfield< 21 > ss
Definition misc_types.hh:60
Bitfield< 39, 12 > pa
Bitfield< 8 > va
Bitfield< 10, 5 > event
Bitfield< 0 > p
Bitfield< 30 > ti
Bitfield< 3 > addr
Definition types.hh:84
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
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
Packet * PacketPtr
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 ...
TableWalkerStats(statistics::Group *parent)
Helper variables used to implement hierarchical access permissions when the long-desc.
A virtual base opaque structure used to hold state associated with the packet (e.g....
Definition packet.hh:469

Generated on Mon May 26 2025 09:18:58 for gem5 by doxygen 1.13.2