2 * Copyright (c) 2010-2016 ARM Limited
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.
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.
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.
41 #ifndef __ARCH_ARM_TABLE_WALKER_HH__
42 #define __ARCH_ARM_TABLE_WALKER_HH__
46 #include "arch/arm/miscregs.hh"
47 #include "arch/arm/system.hh"
48 #include "arch/arm/tlb.hh"
49 #include "mem/request.hh"
50 #include "params/ArmTableWalker.hh"
51 #include "sim/clocked_object.hh"
52 #include "sim/eventq.hh"
63 class TableWalker : public ClockedObject
68 class DescriptorBase {
70 DescriptorBase() : lookupLevel(L0) {}
72 /** Current lookup level for this descriptor */
73 LookupLevel lookupLevel;
75 virtual Addr pfn() const = 0;
76 virtual TlbEntry::DomainType domain() const = 0;
77 virtual bool xn() const = 0;
78 virtual uint8_t ap() const = 0;
79 virtual bool global(WalkerState *currState) const = 0;
80 virtual uint8_t offsetBits() const = 0;
81 virtual bool secure(bool have_security, WalkerState *currState) const = 0;
82 virtual std::string dbgHeader() const = 0;
83 virtual uint64_t getRawData() const = 0;
84 virtual uint8_t texcb() const
86 panic("texcb() not implemented for this class\n");
88 virtual bool shareable() const
90 panic("shareable() not implemented for this class\n");
94 class L1Descriptor : public DescriptorBase {
96 /** Type of page table entry ARM DDI 0406B: B3-8*/
104 /** The raw bits of the entry */
107 /** This entry has been modified (access flag set) and needs to be
108 * written back to memory */
112 L1Descriptor() : data(0), _dirty(false)
117 virtual uint64_t getRawData() const
122 virtual std::string dbgHeader() const
124 return "Inserting Section Descriptor into TLB\n";
127 virtual uint8_t offsetBits() const
132 EntryType type() const
134 return (EntryType)(data & 0x3);
137 /** Is the page a Supersection (16MB)?*/
138 bool supersection() const
140 return bits(data, 18);
143 /** Return the physcal address of the entry, bits in position*/
147 panic("Super sections not implemented\n");
148 return mbits(data, 31, 20);
150 /** Return the physcal address of the entry, bits in position*/
151 Addr paddr(Addr va) const
154 panic("Super sections not implemented\n");
155 return mbits(data, 31, 20) | mbits(va, 19, 0);
159 /** Return the physical frame, bits shifted right */
163 panic("Super sections not implemented\n");
164 return bits(data, 31, 20);
167 /** Is the translation global (no asid used)? */
168 bool global(WalkerState *currState) const
170 return !bits(data, 17);
173 /** Is the translation not allow execution? */
176 return bits(data, 4);
179 /** Three bit access protection flags */
182 return (bits(data, 15) << 2) | bits(data, 11, 10);
185 /** Domain Client/Manager: ARM DDI 0406B: B3-31 */
186 TlbEntry::DomainType domain() const
188 return static_cast<TlbEntry::DomainType>(bits(data, 8, 5));
191 /** Address of L2 descriptor if it exists */
194 return mbits(data, 31, 10);
197 /** Memory region attributes: ARM DDI 0406B: B3-32.
198 * These bits are largly ignored by M5 and only used to
199 * provide the illusion that the memory system cares about
200 * anything but cachable vs. uncachable.
202 uint8_t texcb() const
204 return bits(data, 2) | bits(data, 3) << 1 | bits(data, 14, 12) << 2;
207 /** If the section is shareable. See texcb() comment. */
208 bool shareable() const
210 return bits(data, 16);
213 /** Set access flag that this entry has been touched. Mark
214 * the entry as requiring a writeback, in the future.
222 /** This entry needs to be written back to memory */
229 * Returns true if this entry targets the secure physical address
232 bool secure(bool have_security, WalkerState *currState) const
235 if (type() == PageTable)
236 return !bits(data, 3);
238 return !bits(data, 19);
244 /** Level 2 page table descriptor */
245 class L2Descriptor : public DescriptorBase {
247 /** The raw bits of the entry. */
249 L1Descriptor *l1Parent;
251 /** This entry has been modified (access flag set) and needs to be
252 * written back to memory */
256 L2Descriptor() : data(0), l1Parent(nullptr), _dirty(false)
261 L2Descriptor(L1Descriptor &parent) : data(0), l1Parent(&parent),
267 virtual uint64_t getRawData() const
272 virtual std::string dbgHeader() const
274 return "Inserting L2 Descriptor into TLB\n";
277 virtual TlbEntry::DomainType domain() const
279 return l1Parent->domain();
282 bool secure(bool have_security, WalkerState *currState) const
284 return l1Parent->secure(have_security, currState);
287 virtual uint8_t offsetBits() const
289 return large() ? 16 : 12;
292 /** Is the entry invalid */
295 return bits(data, 1, 0) == 0;
298 /** What is the size of the mapping? */
301 return bits(data, 1) == 0;
304 /** Is execution allowed on this mapping? */
307 return large() ? bits(data, 15) : bits(data, 0);
310 /** Is the translation global (no asid used)? */
311 bool global(WalkerState *currState) const
313 return !bits(data, 11);
316 /** Three bit access protection flags */
319 return bits(data, 5, 4) | (bits(data, 9) << 2);
322 /** Memory region attributes: ARM DDI 0406B: B3-32 */
323 uint8_t texcb() const
326 (bits(data, 2) | (bits(data, 3) << 1) | (bits(data, 14, 12) << 2)) :
327 (bits(data, 2) | (bits(data, 3) << 1) | (bits(data, 8, 6) << 2));
330 /** Return the physical frame, bits shifted right */
333 return large() ? bits(data, 31, 16) : bits(data, 31, 12);
336 /** Return complete physical address given a VA */
337 Addr paddr(Addr va) const
340 return mbits(data, 31, 16) | mbits(va, 15, 0);
342 return mbits(data, 31, 12) | mbits(va, 11, 0);
345 /** If the section is shareable. See texcb() comment. */
346 bool shareable() const
348 return bits(data, 10);
351 /** Set access flag that this entry has been touched. Mark
352 * the entry as requiring a writeback, in the future.
360 /** This entry needs to be written back to memory */
368 // Granule sizes for AArch64 long descriptors
376 /** Long-descriptor format (LPAE) */
377 class LongDescriptor : public DescriptorBase {
379 /** Descriptor type */
387 LongDescriptor() : data(0), _dirty(false) {}
389 /** The raw bits of the entry */
392 /** This entry has been modified (access flag set) and needs to be
393 * written back to memory */
396 virtual uint64_t getRawData() const
401 virtual std::string dbgHeader() const
403 if (type() == LongDescriptor::Page) {
404 assert(lookupLevel == L3);
405 return "Inserting Page descriptor into TLB\n";
407 assert(lookupLevel < L3);
408 return "Inserting Block descriptor into TLB\n";
413 * Returns true if this entry targets the secure physical address
416 bool secure(bool have_security, WalkerState *currState) const
418 assert(type() == Block || type() == Page);
419 return have_security && (currState->secureLookup && !bits(data, 5));
422 /** True if the current lookup is performed in AArch64 state */
425 /** Width of the granule size in bits */
428 /** Return the descriptor type */
429 EntryType type() const
431 switch (bits(data, 1, 0)) {
433 // In AArch64 blocks are not allowed at L0 for the 4 KB granule
434 // and at L1 for 16/64 KB granules
435 if (grainSize > Grain4KB)
436 return lookupLevel == L2 ? Block : Invalid;
437 return lookupLevel == L0 || lookupLevel == L3 ? Invalid : Block;
439 return lookupLevel == L3 ? Page : Table;
445 /** Return the bit width of the page/block offset */
446 uint8_t offsetBits() const
448 if (type() == Block) {
451 return lookupLevel == L1 ? 30 /* 1 GB */
454 return 25 /* 32 MB */;
456 return 29 /* 512 MB */;
458 panic("Invalid AArch64 VM granule size\n");
460 } else if (type() == Page) {
465 return grainSize; /* enum -> uint okay */
467 panic("Invalid AArch64 VM granule size\n");
470 panic("AArch64 page table entry must be block or page\n");
474 /** Return the physical frame, bits shifted right */
478 return bits(data, 47, offsetBits());
479 return bits(data, 39, offsetBits());
482 /** Return the complete physical address given a VA */
483 Addr paddr(Addr va) const
485 int n = offsetBits();
487 return mbits(data, 47, n) | mbits(va, n - 1, 0);
488 return mbits(data, 39, n) | mbits(va, n - 1, 0);
491 /** Return the physical address of the entry */
495 return mbits(data, 47, offsetBits());
496 return mbits(data, 39, offsetBits());
499 /** Return the address of the next page table */
500 Addr nextTableAddr() const
502 assert(type() == Table);
504 return mbits(data, 47, grainSize);
506 return mbits(data, 39, 12);
509 /** Return the address of the next descriptor */
510 Addr nextDescAddr(Addr va) const
512 assert(type() == Table);
515 int stride = grainSize - 3;
516 int va_lo = stride * (3 - (lookupLevel + 1)) + grainSize;
517 int va_hi = va_lo + stride - 1;
518 pa = nextTableAddr() | (bits(va, va_hi, va_lo) << 3);
520 if (lookupLevel == L1)
521 pa = nextTableAddr() | (bits(va, 29, 21) << 3);
522 else // lookupLevel == L2
523 pa = nextTableAddr() | (bits(va, 20, 12) << 3);
528 /** Is execution allowed on this mapping? */
531 assert(type() == Block || type() == Page);
532 return bits(data, 54);
535 /** Is privileged execution allowed on this mapping? (LPAE only) */
538 assert(type() == Block || type() == Page);
539 return bits(data, 53);
542 /** Contiguous hint bit. */
543 bool contiguousHint() const
545 assert(type() == Block || type() == Page);
546 return bits(data, 52);
549 /** Is the translation global (no asid used)? */
550 bool global(WalkerState *currState) const
552 assert(currState && (type() == Block || type() == Page));
553 if (!currState->aarch64 && (currState->isSecure &&
554 !currState->secureLookup)) {
555 return false; // ARM ARM issue C B3.6.3
556 } else if (currState->aarch64) {
557 if (currState->el == EL2 || currState->el == EL3) {
558 return true; // By default translations are treated as global
559 // in AArch64 EL2 and EL3
560 } else if (currState->isSecure && !currState->secureLookup) {
564 return !bits(data, 11);
567 /** Returns true if the access flag (AF) is set. */
570 assert(type() == Block || type() == Page);
571 return bits(data, 10);
574 /** 2-bit shareability field */
577 assert(type() == Block || type() == Page);
578 return bits(data, 9, 8);
581 /** 2-bit access protection flags */
584 assert(type() == Block || type() == Page);
585 // Long descriptors only support the AP[2:1] scheme
586 return bits(data, 7, 6);
589 /** Read/write access protection flag */
592 assert(type() == Block || type() == Page);
593 return !bits(data, 7);
596 /** User/privileged level access protection flag */
599 assert(type() == Block || type() == Page);
600 return bits(data, 6);
603 /** Return the AP bits as compatible with the AP[2:0] format. Utility
604 * function used to simplify the code in the TLB for performing
605 * permission checks. */
606 static uint8_t ap(bool rw, bool user)
608 return ((!rw) << 2) | (user << 1);
611 TlbEntry::DomainType domain() const
613 // Long-desc. format only supports Client domain
614 assert(type() == Block || type() == Page);
615 return TlbEntry::DomainType::Client;
618 /** Attribute index */
619 uint8_t attrIndx() const
621 assert(type() == Block || type() == Page);
622 return bits(data, 4, 2);
625 /** Memory attributes, only used by stage 2 translations */
626 uint8_t memAttr() const
628 assert(type() == Block || type() == Page);
629 return bits(data, 5, 2);
632 /** Set access flag that this entry has been touched. Mark the entry as
633 * requiring a writeback, in the future. */
640 /** This entry needs to be written back to memory */
646 /** Whether the subsequent levels of lookup are secure */
647 bool secureTable() const
649 assert(type() == Table);
650 return !bits(data, 63);
653 /** Two bit access protection flags for subsequent levels of lookup */
654 uint8_t apTable() const
656 assert(type() == Table);
657 return bits(data, 62, 61);
660 /** R/W protection flag for subsequent levels of lookup */
661 uint8_t rwTable() const
663 assert(type() == Table);
664 return !bits(data, 62);
667 /** User/privileged mode protection flag for subsequent levels of
669 uint8_t userTable() const
671 assert(type() == Table);
672 return !bits(data, 61);
675 /** Is execution allowed on subsequent lookup levels? */
678 assert(type() == Table);
679 return bits(data, 60);
682 /** Is privileged execution allowed on subsequent lookup levels? */
683 bool pxnTable() const
685 assert(type() == Table);
686 return bits(data, 59);
693 /** Thread context that we're doing the walk for */
696 /** If the access is performed in AArch64 state */
699 /** Current exception level */
702 /** Current physical address range in bits */
705 /** Request that is currently being serviced */
708 /** ASID that we're servicing the request under */
713 /** Translation state for delayed requests */
714 TLB::Translation *transState;
716 /** The fault that we are going to return */
719 /** The virtual address that is being translated with tagging removed.*/
722 /** The virtual address that is being translated */
725 /** Cached copy of the sctlr as it existed when translation began */
728 /** Cached copy of the scr as it existed when translation began */
731 /** Cached copy of the cpsr as it existed when translation began */
734 /** Cached copy of ttbcr/tcr as it existed when translation began */
736 TTBCR ttbcr; // AArch32 translations
737 TCR tcr; // AArch64 translations
740 /** Cached copy of the htcr as it existed when translation began. */
743 /** Cached copy of the htcr as it existed when translation began. */
746 /** Cached copy of the vtcr as it existed when translation began. */
749 /** If the access is a write */
752 /** If the access is a fetch (for execution, and no-exec) must be checked?*/
755 /** If the access comes from the secure state. */
758 /** Helper variables used to implement hierarchical access permissions
759 * when the long-desc. format is used (LPAE only) */
766 /** Flag indicating if a second stage of lookup is required */
769 /** A pointer to the stage 2 translation that's in progress */
770 TLB::Translation *stage2Tran;
772 /** If the mode is timing or atomic */
775 /** If the atomic mode should be functional */
778 /** Save mode for use in delayed response */
781 /** The translation type that has been requested */
782 TLB::ArmTranslationType tranType;
784 /** Short-format descriptors */
788 /** Long-format descriptor (LPAE and AArch64) */
789 LongDescriptor longDesc;
791 /** Whether the response is delayed in timing mode due to additional
795 TableWalker *tableWalker;
797 /** Timestamp for calculating elapsed time in service (for stats) */
800 /** Page entries walked during service (for stats) */
803 void doL1Descriptor();
804 void doL2Descriptor();
806 void doLongDescriptor();
810 std::string name() const { return tableWalker->name(); }
815 /** Queues of requests for all the different lookup levels */
816 std::list<WalkerState *> stateQueues[MAX_LOOKUP_LEVELS];
818 /** Queue of requests that have passed are waiting because the walker is
820 std::list<WalkerState *> pendingQueue;
822 /** The MMU to forward second stage look upts to */
823 Stage2MMU *stage2Mmu;
825 /** Port shared by the two table walkers. */
828 /** Master id assigned by the MMU. */
831 /** Indicates whether this table walker is part of the stage 2 mmu */
834 /** TLB that is initiating these table walks */
837 /** Cached copy of the sctlr as it existed when translation began */
840 WalkerState *currState;
842 /** If a timing translation is currently in progress */
845 /** The number of walks belonging to squashed instructions that can be
846 * removed from the pendingQueue per cycle. */
847 unsigned numSquashable;
849 /** Cached copies of system-level properties */
852 bool _haveVirtualization;
853 uint8_t physAddrRange;
854 bool _haveLargeAsid64;
857 Stats::Scalar statWalks;
858 Stats::Scalar statWalksShortDescriptor;
859 Stats::Scalar statWalksLongDescriptor;
860 Stats::Vector statWalksShortTerminatedAtLevel;
861 Stats::Vector statWalksLongTerminatedAtLevel;
862 Stats::Scalar statSquashedBefore;
863 Stats::Scalar statSquashedAfter;
864 Stats::Histogram statWalkWaitTime;
865 Stats::Histogram statWalkServiceTime;
866 Stats::Histogram statPendingWalks; // essentially "L" of queueing theory
867 Stats::Vector statPageSizes;
868 Stats::Vector2d statRequestOrigin;
870 mutable unsigned pendingReqs;
871 mutable Tick pendingChangeTick;
873 static const unsigned REQUESTED = 0;
874 static const unsigned COMPLETED = 1;
877 typedef ArmTableWalkerParams Params;
878 TableWalker(const Params *p);
879 virtual ~TableWalker();
884 return dynamic_cast<const Params *>(_params);
887 void init() override;
889 bool haveLPAE() const { return _haveLPAE; }
890 bool haveVirtualization() const { return _haveVirtualization; }
891 bool haveLargeAsid64() const { return _haveLargeAsid64; }
892 /** Checks if all state is cleared and if so, completes drain */
893 void completeDrain();
894 DrainState drain() override;
895 void drainResume() override;
897 Port &getPort(const std::string &if_name,
898 PortID idx=InvalidPortID) override;
900 void regStats() override;
902 Fault walk(const RequestPtr &req, ThreadContext *tc,
903 uint16_t asid, uint8_t _vmid,
904 bool _isHyp, TLB::Mode mode, TLB::Translation *_trans,
905 bool timing, bool functional, bool secure,
906 TLB::ArmTranslationType tranType, bool _stage2Req);
908 void setTlb(TLB *_tlb) { tlb = _tlb; }
909 TLB* getTlb() { return tlb; }
910 void setMMU(Stage2MMU *m, MasterID master_id);
911 void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr,
912 uint8_t texcb, bool s);
913 void memAttrsLPAE(ThreadContext *tc, TlbEntry &te,
914 LongDescriptor &lDescriptor);
915 void memAttrsAArch64(ThreadContext *tc, TlbEntry &te,
916 LongDescriptor &lDescriptor);
918 static LookupLevel toLookupLevel(uint8_t lookup_level_as_int);
922 void doL1Descriptor();
923 void doL1DescriptorWrapper();
924 EventFunctionWrapper doL1DescEvent;
926 void doL2Descriptor();
927 void doL2DescriptorWrapper();
928 EventFunctionWrapper doL2DescEvent;
930 void doLongDescriptor();
932 void doL0LongDescriptorWrapper();
933 EventFunctionWrapper doL0LongDescEvent;
934 void doL1LongDescriptorWrapper();
935 EventFunctionWrapper doL1LongDescEvent;
936 void doL2LongDescriptorWrapper();
937 EventFunctionWrapper doL2LongDescEvent;
938 void doL3LongDescriptorWrapper();
939 EventFunctionWrapper doL3LongDescEvent;
941 void doLongDescriptorWrapper(LookupLevel curr_lookup_level);
942 Event* LongDescEventByLevel[4];
944 bool fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes,
945 Request::Flags flags, int queueIndex, Event *event,
946 void (TableWalker::*doDescriptor)());
948 void insertTableEntry(DescriptorBase &descriptor, bool longDescriptor);
951 Fault processWalkLPAE();
952 static unsigned adjustTableSizeAArch64(unsigned tsz);
953 /// Returns true if the address exceeds the range permitted by the
954 /// system-wide setting or by the TCR_ELx IPS/PS setting
955 static bool checkAddrSizeFaultAArch64(Addr addr, int currPhysAddrRange);
956 Fault processWalkAArch64();
957 void processWalkWrapper();
958 EventFunctionWrapper doProcessEvent;
960 void nextWalk(ThreadContext *tc);
962 void pendingChange();
964 static uint8_t pageSizeNtoStatBin(uint8_t N);
966 Fault testWalk(Addr pa, Addr size, TlbEntry::DomainType domain,
967 LookupLevel lookup_level);
970 } // namespace ArmISA
972 #endif //__ARCH_ARM_TABLE_WALKER_HH__