2 * Copyright (c) 2010-2015 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 "dev/dma_device.hh"
50 #include "mem/request.hh"
51 #include "params/ArmTableWalker.hh"
52 #include "sim/eventq.hh"
61 class TableWalker : public MemObject
66 class DescriptorBase {
68 /** Current lookup level for this descriptor */
69 LookupLevel lookupLevel;
71 virtual Addr pfn() const = 0;
72 virtual TlbEntry::DomainType domain() const = 0;
73 virtual bool xn() const = 0;
74 virtual uint8_t ap() const = 0;
75 virtual bool global(WalkerState *currState) const = 0;
76 virtual uint8_t offsetBits() const = 0;
77 virtual bool secure(bool have_security, WalkerState *currState) const = 0;
78 virtual std::string dbgHeader() const = 0;
79 virtual uint64_t getRawData() const = 0;
80 virtual uint8_t texcb() const
82 panic("texcb() not implemented for this class\n");
84 virtual bool shareable() const
86 panic("shareable() not implemented for this class\n");
90 class L1Descriptor : public DescriptorBase {
92 /** Type of page table entry ARM DDI 0406B: B3-8*/
100 /** The raw bits of the entry */
103 /** This entry has been modified (access flag set) and needs to be
104 * written back to memory */
108 L1Descriptor() : data(0), _dirty(false)
113 virtual uint64_t getRawData() const
118 virtual std::string dbgHeader() const
120 return "Inserting Section Descriptor into TLB\n";
123 virtual uint8_t offsetBits() const
128 EntryType type() const
130 return (EntryType)(data & 0x3);
133 /** Is the page a Supersection (16MB)?*/
134 bool supersection() const
136 return bits(data, 18);
139 /** Return the physcal address of the entry, bits in position*/
143 panic("Super sections not implemented\n");
144 return mbits(data, 31, 20);
146 /** Return the physcal address of the entry, bits in position*/
147 Addr paddr(Addr va) const
150 panic("Super sections not implemented\n");
151 return mbits(data, 31, 20) | mbits(va, 19, 0);
155 /** Return the physical frame, bits shifted right */
159 panic("Super sections not implemented\n");
160 return bits(data, 31, 20);
163 /** Is the translation global (no asid used)? */
164 bool global(WalkerState *currState) const
166 return !bits(data, 17);
169 /** Is the translation not allow execution? */
172 return bits(data, 4);
175 /** Three bit access protection flags */
178 return (bits(data, 15) << 2) | bits(data, 11, 10);
181 /** Domain Client/Manager: ARM DDI 0406B: B3-31 */
182 TlbEntry::DomainType domain() const
184 return static_cast<TlbEntry::DomainType>(bits(data, 8, 5));
187 /** Address of L2 descriptor if it exists */
190 return mbits(data, 31, 10);
193 /** Memory region attributes: ARM DDI 0406B: B3-32.
194 * These bits are largly ignored by M5 and only used to
195 * provide the illusion that the memory system cares about
196 * anything but cachable vs. uncachable.
198 uint8_t texcb() const
200 return bits(data, 2) | bits(data, 3) << 1 | bits(data, 14, 12) << 2;
203 /** If the section is shareable. See texcb() comment. */
204 bool shareable() const
206 return bits(data, 16);
209 /** Set access flag that this entry has been touched. Mark
210 * the entry as requiring a writeback, in the future.
218 /** This entry needs to be written back to memory */
225 * Returns true if this entry targets the secure physical address
228 bool secure(bool have_security, WalkerState *currState) const
231 if (type() == PageTable)
232 return !bits(data, 3);
234 return !bits(data, 19);
240 /** Level 2 page table descriptor */
241 class L2Descriptor : public DescriptorBase {
243 /** The raw bits of the entry. */
245 L1Descriptor *l1Parent;
247 /** This entry has been modified (access flag set) and needs to be
248 * written back to memory */
252 L2Descriptor() : data(0), l1Parent(nullptr), _dirty(false)
257 L2Descriptor(L1Descriptor &parent) : data(0), l1Parent(&parent),
263 virtual uint64_t getRawData() const
268 virtual std::string dbgHeader() const
270 return "Inserting L2 Descriptor into TLB\n";
273 virtual TlbEntry::DomainType domain() const
275 return l1Parent->domain();
278 bool secure(bool have_security, WalkerState *currState) const
280 return l1Parent->secure(have_security, currState);
283 virtual uint8_t offsetBits() const
285 return large() ? 16 : 12;
288 /** Is the entry invalid */
291 return bits(data, 1, 0) == 0;
294 /** What is the size of the mapping? */
297 return bits(data, 1) == 0;
300 /** Is execution allowed on this mapping? */
303 return large() ? bits(data, 15) : bits(data, 0);
306 /** Is the translation global (no asid used)? */
307 bool global(WalkerState *currState) const
309 return !bits(data, 11);
312 /** Three bit access protection flags */
315 return bits(data, 5, 4) | (bits(data, 9) << 2);
318 /** Memory region attributes: ARM DDI 0406B: B3-32 */
319 uint8_t texcb() const
322 (bits(data, 2) | (bits(data, 3) << 1) | (bits(data, 14, 12) << 2)) :
323 (bits(data, 2) | (bits(data, 3) << 1) | (bits(data, 8, 6) << 2));
326 /** Return the physical frame, bits shifted right */
329 return large() ? bits(data, 31, 16) : bits(data, 31, 12);
332 /** Return complete physical address given a VA */
333 Addr paddr(Addr va) const
336 return mbits(data, 31, 16) | mbits(va, 15, 0);
338 return mbits(data, 31, 12) | mbits(va, 11, 0);
341 /** If the section is shareable. See texcb() comment. */
342 bool shareable() const
344 return bits(data, 10);
347 /** Set access flag that this entry has been touched. Mark
348 * the entry as requiring a writeback, in the future.
356 /** This entry needs to be written back to memory */
364 // Granule sizes for AArch64 long descriptors
372 /** Long-descriptor format (LPAE) */
373 class LongDescriptor : public DescriptorBase {
375 /** Descriptor type */
383 /** The raw bits of the entry */
386 /** This entry has been modified (access flag set) and needs to be
387 * written back to memory */
390 virtual uint64_t getRawData() const
395 virtual std::string dbgHeader() const
397 if (type() == LongDescriptor::Page) {
398 assert(lookupLevel == L3);
399 return "Inserting Page descriptor into TLB\n";
401 assert(lookupLevel < L3);
402 return "Inserting Block descriptor into TLB\n";
407 * Returns true if this entry targets the secure physical address
410 bool secure(bool have_security, WalkerState *currState) const
412 assert(type() == Block || type() == Page);
413 return have_security && (currState->secureLookup && !bits(data, 5));
416 /** True if the current lookup is performed in AArch64 state */
419 /** Width of the granule size in bits */
422 /** Return the descriptor type */
423 EntryType type() const
425 switch (bits(data, 1, 0)) {
427 // In AArch64 blocks are not allowed at L0 for the 4 KB granule
428 // and at L1 for 16/64 KB granules
429 if (grainSize > Grain4KB)
430 return lookupLevel == L2 ? Block : Invalid;
431 return lookupLevel == L0 || lookupLevel == L3 ? Invalid : Block;
433 return lookupLevel == L3 ? Page : Table;
439 /** Return the bit width of the page/block offset */
440 uint8_t offsetBits() const
442 if (type() == Block) {
445 return lookupLevel == L1 ? 30 /* 1 GB */
448 return 25 /* 32 MB */;
450 return 29 /* 512 MB */;
452 panic("Invalid AArch64 VM granule size\n");
454 } else if (type() == Page) {
459 return grainSize; /* enum -> uint okay */
461 panic("Invalid AArch64 VM granule size\n");
464 panic("AArch64 page table entry must be block or page\n");
468 /** Return the physical frame, bits shifted right */
472 return bits(data, 47, offsetBits());
473 return bits(data, 39, offsetBits());
476 /** Return the complete physical address given a VA */
477 Addr paddr(Addr va) const
479 int n = offsetBits();
481 return mbits(data, 47, n) | mbits(va, n - 1, 0);
482 return mbits(data, 39, n) | mbits(va, n - 1, 0);
485 /** Return the physical address of the entry */
489 return mbits(data, 47, offsetBits());
490 return mbits(data, 39, offsetBits());
493 /** Return the address of the next page table */
494 Addr nextTableAddr() const
496 assert(type() == Table);
498 return mbits(data, 47, grainSize);
500 return mbits(data, 39, 12);
503 /** Return the address of the next descriptor */
504 Addr nextDescAddr(Addr va) const
506 assert(type() == Table);
509 int stride = grainSize - 3;
510 int va_lo = stride * (3 - (lookupLevel + 1)) + grainSize;
511 int va_hi = va_lo + stride - 1;
512 pa = nextTableAddr() | (bits(va, va_hi, va_lo) << 3);
514 if (lookupLevel == L1)
515 pa = nextTableAddr() | (bits(va, 29, 21) << 3);
516 else // lookupLevel == L2
517 pa = nextTableAddr() | (bits(va, 20, 12) << 3);
522 /** Is execution allowed on this mapping? */
525 assert(type() == Block || type() == Page);
526 return bits(data, 54);
529 /** Is privileged execution allowed on this mapping? (LPAE only) */
532 assert(type() == Block || type() == Page);
533 return bits(data, 53);
536 /** Contiguous hint bit. */
537 bool contiguousHint() const
539 assert(type() == Block || type() == Page);
540 return bits(data, 52);
543 /** Is the translation global (no asid used)? */
544 bool global(WalkerState *currState) const
546 assert(currState && (type() == Block || type() == Page));
547 if (!currState->aarch64 && (currState->isSecure &&
548 !currState->secureLookup)) {
549 return false; // ARM ARM issue C B3.6.3
550 } else if (currState->aarch64) {
551 if (currState->el == EL2 || currState->el == EL3) {
552 return true; // By default translations are treated as global
553 // in AArch64 EL2 and EL3
554 } else if (currState->isSecure && !currState->secureLookup) {
558 return !bits(data, 11);
561 /** Returns true if the access flag (AF) is set. */
564 assert(type() == Block || type() == Page);
565 return bits(data, 10);
568 /** 2-bit shareability field */
571 assert(type() == Block || type() == Page);
572 return bits(data, 9, 8);
575 /** 2-bit access protection flags */
578 assert(type() == Block || type() == Page);
579 // Long descriptors only support the AP[2:1] scheme
580 return bits(data, 7, 6);
583 /** Read/write access protection flag */
586 assert(type() == Block || type() == Page);
587 return !bits(data, 7);
590 /** User/privileged level access protection flag */
593 assert(type() == Block || type() == Page);
594 return bits(data, 6);
597 /** Return the AP bits as compatible with the AP[2:0] format. Utility
598 * function used to simplify the code in the TLB for performing
599 * permission checks. */
600 static uint8_t ap(bool rw, bool user)
602 return ((!rw) << 2) | (user << 1);
605 TlbEntry::DomainType domain() const
607 // Long-desc. format only supports Client domain
608 assert(type() == Block || type() == Page);
609 return TlbEntry::DomainType::Client;
612 /** Attribute index */
613 uint8_t attrIndx() const
615 assert(type() == Block || type() == Page);
616 return bits(data, 4, 2);
619 /** Memory attributes, only used by stage 2 translations */
620 uint8_t memAttr() const
622 assert(type() == Block || type() == Page);
623 return bits(data, 5, 2);
626 /** Set access flag that this entry has been touched. Mark the entry as
627 * requiring a writeback, in the future. */
634 /** This entry needs to be written back to memory */
640 /** Whether the subsequent levels of lookup are secure */
641 bool secureTable() const
643 assert(type() == Table);
644 return !bits(data, 63);
647 /** Two bit access protection flags for subsequent levels of lookup */
648 uint8_t apTable() const
650 assert(type() == Table);
651 return bits(data, 62, 61);
654 /** R/W protection flag for subsequent levels of lookup */
655 uint8_t rwTable() const
657 assert(type() == Table);
658 return !bits(data, 62);
661 /** User/privileged mode protection flag for subsequent levels of
663 uint8_t userTable() const
665 assert(type() == Table);
666 return !bits(data, 61);
669 /** Is execution allowed on subsequent lookup levels? */
672 assert(type() == Table);
673 return bits(data, 60);
676 /** Is privileged execution allowed on subsequent lookup levels? */
677 bool pxnTable() const
679 assert(type() == Table);
680 return bits(data, 59);
687 /** Thread context that we're doing the walk for */
690 /** If the access is performed in AArch64 state */
693 /** Current exception level */
696 /** Current physical address range in bits */
699 /** Request that is currently being serviced */
702 /** ASID that we're servicing the request under */
707 /** Translation state for delayed requests */
708 TLB::Translation *transState;
710 /** The fault that we are going to return */
713 /** The virtual address that is being translated with tagging removed.*/
716 /** The virtual address that is being translated */
719 /** Cached copy of the sctlr as it existed when translation began */
722 /** Cached copy of the scr as it existed when translation began */
725 /** Cached copy of the cpsr as it existed when translation began */
728 /** Cached copy of ttbcr/tcr as it existed when translation began */
730 TTBCR ttbcr; // AArch32 translations
731 TCR tcr; // AArch64 translations
734 /** Cached copy of the htcr as it existed when translation began. */
737 /** Cached copy of the htcr as it existed when translation began. */
740 /** Cached copy of the vtcr as it existed when translation began. */
743 /** If the access is a write */
746 /** If the access is a fetch (for execution, and no-exec) must be checked?*/
749 /** If the access comes from the secure state. */
752 /** Helper variables used to implement hierarchical access permissions
753 * when the long-desc. format is used (LPAE only) */
760 /** Flag indicating if a second stage of lookup is required */
763 /** Indicates whether the translation has been passed onto the second
764 * stage mmu, and no more work is required from the first stage.
768 /** A pointer to the stage 2 translation that's in progress */
769 TLB::Translation *stage2Tran;
771 /** If the mode is timing or atomic */
774 /** If the atomic mode should be functional */
777 /** Save mode for use in delayed response */
780 /** The translation type that has been requested */
781 TLB::ArmTranslationType tranType;
783 /** Short-format descriptors */
787 /** Long-format descriptor (LPAE and AArch64) */
788 LongDescriptor longDesc;
790 /** Whether the response is delayed in timing mode due to additional
794 TableWalker *tableWalker;
796 /** Timestamp for calculating elapsed time in service (for stats) */
799 /** Page entries walked during service (for stats) */
802 void doL1Descriptor();
803 void doL2Descriptor();
805 void doLongDescriptor();
809 std::string name() const { return tableWalker->name(); }
814 /** Queues of requests for all the different lookup levels */
815 std::list<WalkerState *> stateQueues[MAX_LOOKUP_LEVELS];
817 /** Queue of requests that have passed are waiting because the walker is
819 std::list<WalkerState *> pendingQueue;
821 /** If we're draining keep the drain event around until we're drained */
822 DrainManager *drainManager;
824 /** The MMU to forward second stage look upts to */
825 Stage2MMU *stage2Mmu;
827 /** Port shared by the two table walkers. */
830 /** Master id assigned by the MMU. */
833 /** Indicates whether this table walker is part of the stage 2 mmu */
836 /** TLB that is initiating these table walks */
839 /** Cached copy of the sctlr as it existed when translation began */
842 WalkerState *currState;
844 /** If a timing translation is currently in progress */
847 /** The number of walks belonging to squashed instructions that can be
848 * removed from the pendingQueue per cycle. */
849 unsigned numSquashable;
851 /** Cached copies of system-level properties */
854 bool _haveVirtualization;
855 uint8_t physAddrRange;
856 bool _haveLargeAsid64;
859 Stats::Scalar statWalks;
860 Stats::Scalar statWalksShortDescriptor;
861 Stats::Scalar statWalksLongDescriptor;
862 Stats::Vector statWalksShortTerminatedAtLevel;
863 Stats::Vector statWalksLongTerminatedAtLevel;
864 Stats::Scalar statSquashedBefore;
865 Stats::Scalar statSquashedAfter;
866 Stats::Histogram statWalkWaitTime;
867 Stats::Histogram statWalkServiceTime;
868 Stats::Histogram statPendingWalks; // essentially "L" of queueing theory
869 Stats::Vector statPageSizes;
870 Stats::Vector2d statRequestOrigin;
872 mutable unsigned pendingReqs;
873 mutable Tick pendingChangeTick;
875 static const unsigned REQUESTED = 0;
876 static const unsigned COMPLETED = 1;
879 typedef ArmTableWalkerParams Params;
880 TableWalker(const Params *p);
881 virtual ~TableWalker();
886 return dynamic_cast<const Params *>(_params);
891 bool haveLPAE() const { return _haveLPAE; }
892 bool haveVirtualization() const { return _haveVirtualization; }
893 bool haveLargeAsid64() const { return _haveLargeAsid64; }
894 /** Checks if all state is cleared and if so, completes drain */
895 void completeDrain();
896 unsigned int drain(DrainManager *dm);
897 virtual void drainResume();
899 virtual BaseMasterPort& getMasterPort(const std::string &if_name,
900 PortID idx = InvalidPortID);
904 Fault walk(RequestPtr req, ThreadContext *tc, uint16_t asid, uint8_t _vmid,
905 bool _isHyp, TLB::Mode mode, TLB::Translation *_trans,
906 bool timing, bool functional, bool secure,
907 TLB::ArmTranslationType tranType);
909 void setTlb(TLB *_tlb) { tlb = _tlb; }
910 TLB* getTlb() { return tlb; }
911 void setMMU(Stage2MMU *m, MasterID master_id);
912 void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr,
913 uint8_t texcb, bool s);
914 void memAttrsLPAE(ThreadContext *tc, TlbEntry &te,
915 LongDescriptor &lDescriptor);
916 void memAttrsAArch64(ThreadContext *tc, TlbEntry &te, uint8_t attrIndx,
919 static LookupLevel toLookupLevel(uint8_t lookup_level_as_int);
923 void doL1Descriptor();
924 void doL1DescriptorWrapper();
925 EventWrapper<TableWalker,
926 &TableWalker::doL1DescriptorWrapper> doL1DescEvent;
928 void doL2Descriptor();
929 void doL2DescriptorWrapper();
930 EventWrapper<TableWalker,
931 &TableWalker::doL2DescriptorWrapper> doL2DescEvent;
933 void doLongDescriptor();
935 void doL0LongDescriptorWrapper();
936 EventWrapper<TableWalker,
937 &TableWalker::doL0LongDescriptorWrapper> doL0LongDescEvent;
938 void doL1LongDescriptorWrapper();
939 EventWrapper<TableWalker,
940 &TableWalker::doL1LongDescriptorWrapper> doL1LongDescEvent;
941 void doL2LongDescriptorWrapper();
942 EventWrapper<TableWalker,
943 &TableWalker::doL2LongDescriptorWrapper> doL2LongDescEvent;
944 void doL3LongDescriptorWrapper();
945 EventWrapper<TableWalker,
946 &TableWalker::doL3LongDescriptorWrapper> doL3LongDescEvent;
948 void doLongDescriptorWrapper(LookupLevel curr_lookup_level);
950 bool fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes,
951 Request::Flags flags, int queueIndex, Event *event,
952 void (TableWalker::*doDescriptor)());
954 void insertTableEntry(DescriptorBase &descriptor, bool longDescriptor);
957 Fault processWalkLPAE();
958 static unsigned adjustTableSizeAArch64(unsigned tsz);
959 /// Returns true if the address exceeds the range permitted by the
960 /// system-wide setting or by the TCR_ELx IPS/PS setting
961 static bool checkAddrSizeFaultAArch64(Addr addr, int currPhysAddrRange);
962 Fault processWalkAArch64();
963 void processWalkWrapper();
964 EventWrapper<TableWalker, &TableWalker::processWalkWrapper> doProcessEvent;
966 void nextWalk(ThreadContext *tc);
968 void pendingChange();
970 static uint8_t pageSizeNtoStatBin(uint8_t N);
973 } // namespace ArmISA
975 #endif //__ARCH_ARM_TABLE_WALKER_HH__