gem5 v24.0.0.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 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 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<TlbEntry::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),
440 {}
441
443 uint64_t data;
444
447 bool _dirty;
448
451
454
456
457 uint8_t*
458 getRawPtr() override
459 {
460 return reinterpret_cast<uint8_t*>(&data);
461 }
462
463 uint64_t
464 getRawData() const override
465 {
466 return (data);
467 }
468
469 std::string
470 dbgHeader() const override
471 {
472 switch (type()) {
474 assert(lookupLevel == LookupLevel::L3);
475 return "Inserting Page descriptor into TLB\n";
477 assert(lookupLevel < LookupLevel::L3);
478 return "Inserting Block descriptor into TLB\n";
480 return "Inserting Table descriptor into TLB\n";
481 default:
482 panic("Trying to insert and invalid descriptor\n");
483 }
484 }
485
490 bool
491 secure(bool have_security, WalkerState *currState) const override
492 {
493 if (type() == Block || type() == Page) {
494 return have_security &&
495 (currState->secureLookup && !bits(data, 5));
496 } else {
497 return have_security && currState->secureLookup;
498 }
499 }
500
503 type() const
504 {
505 switch (bits(data, 1, 0)) {
506 case 0x1:
507 // In AArch64 blocks are not allowed at L0 for the
508 // 4 KiB granule and at L1 for 16/64 KiB granules
509 switch (grainSize) {
510 case Grain4KB:
511 if (lookupLevel == LookupLevel::L0 ||
512 lookupLevel == LookupLevel::L3)
513 return Invalid;
514 else
515 return Block;
516
517 case Grain16KB:
518 if (lookupLevel == LookupLevel::L2)
519 return Block;
520 else
521 return Invalid;
522
523 case Grain64KB:
524 // With Armv8.2-LPA (52bit PA) L1 Block descriptors
525 // are allowed for 64KiB granule
526 if ((lookupLevel == LookupLevel::L1 && physAddrRange == 52) ||
527 lookupLevel == LookupLevel::L2)
528 return Block;
529 else
530 return Invalid;
531
532 default:
533 return Invalid;
534 }
535 case 0x3:
536 return lookupLevel == LookupLevel::L3 ? Page : Table;
537 default:
538 return Invalid;
539 }
540 }
541
543 uint8_t
544 offsetBits() const override
545 {
546 if (type() == Block) {
547 switch (grainSize) {
548 case Grain4KB:
549 return lookupLevel == LookupLevel::L1 ?
550 30 /* 1 GiB */ : 21 /* 2 MiB */;
551 case Grain16KB:
552 return 25 /* 32 MiB */;
553 case Grain64KB:
554 return lookupLevel == LookupLevel::L1 ?
555 42 /* 4 TiB */ : 29 /* 512 MiB */;
556 default:
557 panic("Invalid AArch64 VM granule size\n");
558 }
559 } else if (type() == Page) {
560 switch (grainSize) {
561 case Grain4KB:
562 case Grain16KB:
563 case Grain64KB:
564 return grainSize; /* enum -> uint okay */
565 default:
566 panic("Invalid AArch64 VM granule size\n");
567 }
568 } else if (type() == Table) {
569 const auto* ptops = getPageTableOps(grainSize);
570 return ptops->walkBits(lookupLevel);
571 }
572 panic("AArch64 page table entry must be block or page\n");
573 }
574
576 Addr
577 pfn() const override
578 {
579 return paddr() >> offsetBits();
580 }
581
583 Addr
584 paddr() const
585 {
586 Addr addr = 0;
587 if (aarch64) {
588 addr = mbits(data, 47, offsetBits());
589 if (physAddrRange == 52 && grainSize == Grain64KB) {
590 addr |= bits(data, 15, 12) << 48;
591 }
592 } else {
593 addr = mbits(data, 39, offsetBits());
594 }
595 return addr;
596 }
597
599 Addr
601 {
602 assert(type() == Table);
603 Addr table_address = 0;
604 if (aarch64) {
605 table_address = mbits(data, 47, grainSize);
606 // Using 52bit if Armv8.2-LPA is implemented
607 if (physAddrRange == 52 && grainSize == Grain64KB)
608 table_address |= bits(data, 15, 12) << 48;
609 } else {
610 table_address = mbits(data, 39, 12);
611 }
612
613 return table_address;
614 }
615
617 Addr
619 {
620 assert(type() == Table);
621 Addr pa = 0;
622 if (aarch64) {
623 int stride = grainSize - 3;
624 int va_lo = stride * (3 - (lookupLevel + 1)) + grainSize;
625 int va_hi = va_lo + stride - 1;
626 pa = nextTableAddr() | (bits(va, va_hi, va_lo) << 3);
627 } else {
628 if (lookupLevel == LookupLevel::L1)
629 pa = nextTableAddr() | (bits(va, 29, 21) << 3);
630 else // lookupLevel == L2
631 pa = nextTableAddr() | (bits(va, 20, 12) << 3);
632 }
633 return pa;
634 }
635
637 bool
638 xn() const override
639 {
640 assert(type() == Block || type() == Page);
641 return bits(data, 54);
642 }
643
645 bool
646 pxn() const
647 {
648 assert(type() == Block || type() == Page);
649 return bits(data, 53);
650 }
651
653 bool
655 {
656 assert(type() == Block || type() == Page);
657 return bits(data, 52);
658 }
659
661 bool
662 global(WalkerState *currState) const override
663 {
664 assert(currState && (type() == Block || type() == Page));
665 if (!currState->aarch64 && (currState->isSecure &&
667 return false; // ARM ARM issue C B3.6.3
668 } else if (currState->aarch64) {
670 // By default translations are treated as global
671 // in AArch64 for regimes without an unpriviledged
672 // component
673 return true;
674 } else if (currState->isSecure && !currState->secureLookup) {
675 return false;
676 }
677 }
678 return !bits(data, 11);
679 }
680
682 bool
683 af() const
684 {
685 assert(type() == Block || type() == Page);
686 return bits(data, 10);
687 }
688
690 uint8_t
691 sh() const
692 {
693 assert(type() == Block || type() == Page);
694 return bits(data, 9, 8);
695 }
696
698 uint8_t
699 ap() const override
700 {
701 assert(type() == Block || type() == Page);
702 // Long descriptors only support the AP[2:1] scheme
703 return bits(data, 7, 6);
704 }
705
707 bool
708 rw() const
709 {
710 assert(type() == Block || type() == Page);
711 return !bits(data, 7);
712 }
713
715 bool
716 user() const
717 {
718 assert(type() == Block || type() == Page);
719 return bits(data, 6);
720 }
721
725 static uint8_t
726 ap(bool rw, bool user)
727 {
728 return ((!rw) << 2) | (user << 1);
729 }
730
732 domain() const override
733 {
734 // Long-desc. format only supports Client domain
736 }
737
739 uint8_t
740 attrIndx() const
741 {
742 assert(type() == Block || type() == Page);
743 return bits(data, 4, 2);
744 }
745
747 uint8_t
748 memAttr() const
749 {
750 assert(type() == Block || type() == Page);
751 return bits(data, 5, 2);
752 }
753
756 void
758 {
759 data |= 1 << 10;
760 _dirty = true;
761 }
762
764 bool
765 dirty() const
766 {
767 return _dirty;
768 }
769
771 bool
773 {
774 assert(type() == Table);
775 return !bits(data, 63);
776 }
777
779 uint8_t
780 apTable() const
781 {
782 assert(type() == Table);
783 return bits(data, 62, 61);
784 }
785
787 uint8_t
788 rwTable() const
789 {
790 assert(type() == Table);
791 return !bits(data, 62);
792 }
793
796 uint8_t
797 userTable() const
798 {
799 assert(type() == Table);
800 return !bits(data, 61);
801 }
802
804 bool
805 xnTable() const
806 {
807 assert(type() == Table);
808 return bits(data, 60);
809 }
810
812 bool
813 pxnTable() const
814 {
815 assert(type() == Table);
816 return bits(data, 59);
817 }
818 };
819
821 {
822 public:
825
828
831
834
837
840
843
845 uint16_t asid;
847
850
853
856
859
861 SCTLR sctlr;
862
864 SCR scr;
865
867 CPSR cpsr;
868
870 union
871 {
872 TTBCR ttbcr; // AArch32 translations
873 TCR tcr; // AArch64 translations
874 };
875
877 HTCR htcr;
878
880 HCR hcr;
881
883 VTCR_t vtcr;
884
887
890
896 bool secureLookup = false;
897
900
904 {
905 bool rwTable = false;
906 bool userTable = false;
907 bool xnTable = false;
908 bool pxnTable = false;
909 };
910 std::optional<LongDescData> longDescData;
911
913 bool hpd;
914
915 uint8_t sh;
916 uint8_t irgn;
917 uint8_t orgn;
918
921
924
926 bool timing;
927
930
933
936
940
943
947
949
952
954 unsigned levels;
955
958
960
961 WalkerState();
962
963 std::string name() const { return tableWalker->name(); }
964 };
965
967 {
968 public:
970 Event *event = nullptr;
971 };
972
973 class Port : public QueuedRequestPort
974 {
975 public:
976 Port(TableWalker& _walker);
977
978 void sendFunctionalReq(const RequestPtr &req, uint8_t *data);
979 void sendAtomicReq(const RequestPtr &req, uint8_t *data, Tick delay);
980 void sendTimingReq(const RequestPtr &req, uint8_t *data, Tick delay,
981 Event *event);
982
983 bool recvTimingResp(PacketPtr pkt) override;
984
985 private:
986 void handleRespPacket(PacketPtr pkt, Tick delay=0);
988 Addr size, Tick delay=0);
989
990 PacketPtr createPacket(const RequestPtr &req, uint8_t *data,
991 Tick delay, Event *event);
992
993 private:
995
998
1001 };
1002
1006 {
1007 private:
1008 uint8_t *data;
1016
1017 public:
1019
1020 Stage2Walk(TableWalker &_parent, uint8_t *_data, Event *_event,
1022 MMU::ArmTranslationType tran_type);
1023
1024 void markDelayed() {}
1025
1026 void finish(const Fault &fault, const RequestPtr &req,
1028
1029 void
1031 int requestorId)
1032 {
1033 numBytes = size;
1034 req->setVirt(vaddr, size, flags, requestorId, 0);
1035 }
1036
1038 };
1039
1041 uint8_t *data, int num_bytes, Request::Flags flags,
1043 bool functional);
1044 void readDataTimed(ThreadContext *tc, Addr desc_addr,
1045 Stage2Walk *translation, int num_bytes,
1047
1048 protected:
1049
1051 std::list<WalkerState *> stateQueues[LookupLevel::Num_ArmLookupLevel];
1052
1056
1059
1062
1065
1067 const bool isStage2;
1068
1071
1073 SCTLR sctlr;
1074
1076
1079
1083
1088
1107
1108 mutable unsigned pendingReqs;
1110
1111 static const unsigned REQUESTED = 0;
1112 static const unsigned COMPLETED = 1;
1113
1114 public:
1115 PARAMS(ArmTableWalker);
1116 TableWalker(const Params &p);
1117 virtual ~TableWalker();
1118
1119 bool haveLargeAsid64() const { return _haveLargeAsid64; }
1120 uint8_t physAddrRange() const { return _physAddrRange; }
1122 void completeDrain();
1123 DrainState drain() override;
1124 void drainResume() override;
1125
1126 gem5::Port &getPort(const std::string &if_name,
1127 PortID idx=InvalidPortID) override;
1128
1130
1131 Fault walk(const RequestPtr &req, ThreadContext *tc,
1132 uint16_t asid, vmid_t _vmid,
1134 bool timing, bool functional, bool secure,
1135 MMU::ArmTranslationType tran_type, bool stage2,
1136 const TlbEntry *walk_entry);
1137
1138 void setMmu(MMU *_mmu);
1139 void setTlb(TLB *_tlb) { tlb = _tlb; }
1140 TLB* getTlb() { return tlb; }
1141 void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr,
1142 uint8_t texcb, bool s);
1144 LongDescriptor &lDescriptor);
1146 LongDescriptor &lDescriptor);
1148
1149 static LookupLevel toLookupLevel(uint8_t lookup_level_as_int);
1150
1151 private:
1152
1153 void doL1Descriptor();
1156
1157 void doL2Descriptor();
1158 void doL2DescriptorWrapper();
1160
1161 void doLongDescriptor();
1162
1171
1172 void doLongDescriptorWrapper(LookupLevel curr_lookup_level);
1174
1175 void fetchDescriptor(Addr desc_addr,
1176 DescriptorBase &descriptor, int num_bytes,
1178 void (TableWalker::*doDescriptor)());
1179
1181
1182 void insertTableEntry(DescriptorBase &descriptor, bool longDescriptor);
1183 void insertPartialTableEntry(LongDescriptor &descriptor);
1184
1190 std::tuple<Addr, Addr, LookupLevel> walkAddresses(
1191 Addr ttbr, GrainSize tg, int tsz, int pa_range);
1192
1195
1196 bool checkVAddrSizeFaultAArch64(Addr addr, int top_bit,
1197 GrainSize granule, int tsz, bool low_range);
1198
1201 bool checkAddrSizeFaultAArch64(Addr addr, int pa_range);
1202
1204 bool uncacheableWalk() const;
1205
1209
1210 void nextWalk(ThreadContext *tc);
1211
1212 void pendingChange();
1213
1215 void stashCurrState(int queue_idx);
1216
1217 static uint8_t pageSizeNtoStatBin(uint8_t N);
1218
1219 void mpamTagTableWalk(RequestPtr &req) const;
1220
1221 public: /* Testing */
1223
1225
1227 LookupLevel lookup_level);
1228};
1229
1230} // namespace ArmISA
1231} // namespace gem5
1232
1233#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:726
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.
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)
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.
std::optional< LongDescData > longDescData
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.
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.
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.
Fault walk(const RequestPtr &req, ThreadContext *tc, uint16_t asid, vmid_t _vmid, BaseMMU::Mode mode, BaseMMU::Translation *_trans, bool timing, bool functional, bool secure, MMU::ArmTranslationType tran_type, bool stage2, const TlbEntry *walk_entry)
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.
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.
PARAMS(ArmTableWalker)
Fault testWalk(const RequestPtr &walk_req, TlbEntry::DomainType domain, LookupLevel lookup_level)
Fault generateLongDescFault(ArmFault::FaultSource src)
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
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.
MMU * mmu
The MMU to forward second stage look upts to.
RequestorID requestorId
Requestor id assigned by the MMU.
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 ...
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)
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: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< 30 > ti
Bitfield< 3 > addr
Definition types.hh:84
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria 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
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 Tue Jun 18 2024 16:23:57 for gem5 by doxygen 1.11.0