gem5 v24.1.0.1
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 &&
675 return false; // ARM ARM issue C B3.6.3
676 } else if (currState->aarch64) {
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 bool
724 rw() const
725 {
726 assert(type() == Block || type() == Page);
727 return !bits(data, 7);
728 }
729
731 bool
732 user() const
733 {
734 assert(type() == Block || type() == Page);
735 return bits(data, 6);
736 }
737
741 static uint8_t
742 ap(bool rw, bool user)
743 {
744 return ((!rw) << 2) | (user << 1);
745 }
746
748 domain() const override
749 {
750 // Long-desc. format only supports Client domain
751 return DomainType::Client;
752 }
753
755 uint8_t
756 attrIndx() const
757 {
758 assert(type() == Block || type() == Page);
759 return bits(data, 4, 2);
760 }
761
763 uint8_t
764 memAttr() const
765 {
766 assert(type() == Block || type() == Page);
767 return bits(data, 5, 2);
768 }
769
772 void
774 {
775 data |= 1 << 10;
776 _dirty = true;
777 }
778
780 bool
781 dirty() const
782 {
783 return _dirty;
784 }
785
787 bool
789 {
790 assert(type() == Table);
791 return !bits(data, 63);
792 }
793
795 uint8_t
796 apTable() const
797 {
798 assert(type() == Table);
799 return bits(data, 62, 61);
800 }
801
803 uint8_t
804 rwTable() const
805 {
806 assert(type() == Table);
807 return !bits(data, 62);
808 }
809
812 uint8_t
813 userTable() const
814 {
815 assert(type() == Table);
816 return !bits(data, 61);
817 }
818
820 bool
821 xnTable() const
822 {
823 assert(type() == Table);
824 return bits(data, 60);
825 }
826
828 bool
829 pxnTable() const
830 {
831 assert(type() == Table);
832 return bits(data, 59);
833 }
834 };
835
837 {
838 public:
841
844
847
850
853
856
859
861 uint16_t asid;
863
866
869
872
875
877 SCTLR sctlr;
878
880 SCR scr;
881
883 CPSR cpsr;
884
886 union
887 {
888 TTBCR ttbcr; // AArch32 translations
889 TCR tcr; // AArch64 translations
890 };
891
893 HTCR htcr;
894
896 HCR hcr;
897
899 VTCR_t vtcr;
900
903
906
912 bool secureLookup = false;
913
918
921
925 {
926 bool rwTable = false;
927 bool userTable = false;
928 bool xnTable = false;
929 bool pxnTable = false;
930 };
931 std::optional<LongDescData> longDescData;
932
934 bool hpd;
935
936 uint8_t sh;
937 uint8_t irgn;
938 uint8_t orgn;
939
942
945
947 bool timing;
948
951
954
957
961
964
968
970
973
975 unsigned levels;
976
979
981
982 WalkerState();
983
984 std::string name() const { return tableWalker->name(); }
985 };
986
988 {
989 public:
991 Event *event = nullptr;
992 };
993
994 class Port : public QueuedRequestPort
995 {
996 public:
997 Port(TableWalker& _walker);
998
999 void sendFunctionalReq(const RequestPtr &req, uint8_t *data);
1000 void sendAtomicReq(const RequestPtr &req, uint8_t *data, Tick delay);
1001 void sendTimingReq(const RequestPtr &req, uint8_t *data, Tick delay,
1002 Event *event);
1003
1004 bool recvTimingResp(PacketPtr pkt) override;
1005
1006 private:
1007 void handleRespPacket(PacketPtr pkt, Tick delay=0);
1009 Addr size, Tick delay=0);
1010
1011 PacketPtr createPacket(const RequestPtr &req, uint8_t *data,
1012 Tick delay, Event *event);
1013
1014 private:
1016
1019
1022 };
1023
1027 {
1028 private:
1029 uint8_t *data;
1037
1038 public:
1040
1041 Stage2Walk(TableWalker &_parent, uint8_t *_data, Event *_event,
1043 MMU::ArmTranslationType tran_type);
1044
1045 void markDelayed() {}
1046
1047 void finish(const Fault &fault, const RequestPtr &req,
1049
1050 void
1052 int requestorId)
1053 {
1054 numBytes = size;
1055 req->setVirt(vaddr, size, flags, requestorId, 0);
1056 }
1057
1059 };
1060
1062 uint8_t *data, int num_bytes, Request::Flags flags,
1064 bool functional);
1065 void readDataTimed(ThreadContext *tc, Addr desc_addr,
1066 Stage2Walk *translation, int num_bytes,
1068
1069 protected:
1070
1072 std::list<WalkerState *> stateQueues[LookupLevel::Num_ArmLookupLevel];
1073
1077
1080
1083
1086
1088 const bool isStage2;
1089
1092
1094 SCTLR sctlr;
1095
1097
1100
1104
1109
1128
1129 mutable unsigned pendingReqs;
1131
1132 static const unsigned REQUESTED = 0;
1133 static const unsigned COMPLETED = 1;
1134
1135 public:
1136 PARAMS(ArmTableWalker);
1137 TableWalker(const Params &p);
1138 virtual ~TableWalker();
1139
1140 bool haveLargeAsid64() const { return _haveLargeAsid64; }
1141 uint8_t physAddrRange() const { return _physAddrRange; }
1143 void completeDrain();
1144 DrainState drain() override;
1145 void drainResume() override;
1146
1147 gem5::Port &getPort(const std::string &if_name,
1148 PortID idx=InvalidPortID) override;
1149
1151
1152 Fault walk(const RequestPtr &req, ThreadContext *tc,
1153 uint16_t asid, vmid_t _vmid,
1155 bool timing, bool functional, SecurityState ss,
1156 PASpace ipaspace,
1157 MMU::ArmTranslationType tran_type, bool stage2,
1158 const TlbEntry *walk_entry);
1159
1160 void setMmu(MMU *_mmu);
1161 void setTlb(TLB *_tlb) { tlb = _tlb; }
1162 TLB* getTlb() { return tlb; }
1163 void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr,
1164 uint8_t texcb, bool s);
1166 LongDescriptor &lDescriptor);
1168 LongDescriptor &lDescriptor);
1170 bool uncacheableFromAttrs(uint8_t attrs);
1171
1172 static LookupLevel toLookupLevel(uint8_t lookup_level_as_int);
1173
1174 private:
1175
1176 void doL1Descriptor();
1177 void doL1DescriptorWrapper();
1179
1180 void doL2Descriptor();
1181 void doL2DescriptorWrapper();
1183
1184 void doLongDescriptor();
1185
1194
1195 void doLongDescriptorWrapper(LookupLevel curr_lookup_level);
1197
1198 void fetchDescriptor(Addr desc_addr,
1199 DescriptorBase &descriptor, int num_bytes,
1201 void (TableWalker::*doDescriptor)());
1202
1204
1205 void insertTableEntry(DescriptorBase &descriptor, bool longDescriptor);
1206 void insertPartialTableEntry(LongDescriptor &descriptor);
1207
1213 std::tuple<Addr, Addr, LookupLevel> walkAddresses(
1214 Addr ttbr, GrainSize tg, int tsz, int pa_range);
1215
1218
1219 Addr maxTxSz(GrainSize tg) const;
1220 Addr s1MinTxSz(GrainSize tg) const;
1221 bool s1TxSzFault(GrainSize tg, int tsz) const;
1222 bool checkVAOutOfRange(Addr addr, int top_bit,
1223 int tsz, bool low_range);
1224
1227 bool checkAddrSizeFaultAArch64(Addr addr, int pa_range);
1228
1230 bool uncacheableWalk() const;
1231
1233 void processWalkWrapper();
1235
1236 void nextWalk(ThreadContext *tc);
1237
1238 void pendingChange();
1239
1241 void stashCurrState(int queue_idx);
1242
1243 static uint8_t pageSizeNtoStatBin(uint8_t N);
1244
1245 void mpamTagTableWalk(RequestPtr &req) const;
1246
1247 public: /* Testing */
1249
1251
1252 Fault testWalk(const RequestPtr &walk_req, DomainType domain,
1253 LookupLevel lookup_level);
1254};
1255
1256} // namespace ArmISA
1257} // namespace gem5
1258
1259#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:816
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? (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.
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.
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
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)
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.
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: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:188
atomic_var_t state
Definition helpers.cc:211
uint8_t flags
Definition helpers.cc:87
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
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
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 Jan 13 2025 04:28:20 for gem5 by doxygen 1.9.8