Ivan Pizarro has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/14575

Change subject: arch-arm: Reverting some changes in the headers for tlb and table_walker files to ease the review with the previous implementation and reverting miscregs_types.hh and utility files to include them in a separate commit
......................................................................

arch-arm: Reverting some changes in the headers for tlb and table_walker files to ease the review with the previous implementation and reverting miscregs_types.hh and utility files to include them in a separate commit

Change-Id: Ie6c4ae604f956ba93c2db535fc60f4e94b1379eb
---
A extras
M src/arch/arm/miscregs_types.hh
M src/arch/arm/table_walker.cc
M src/arch/arm/table_walker.hh
M src/arch/arm/tlb.cc
M src/arch/arm/tlb.hh
M src/arch/arm/utility.cc
M src/arch/arm/utility.hh
8 files changed, 1,118 insertions(+), 1,024 deletions(-)



diff --git a/extras b/extras
new file mode 120000
index 0000000..c6ac546
--- /dev/null
+++ b/extras
@@ -0,0 +1 @@
+../gem5-public-commit/extras
\ No newline at end of file
diff --git a/src/arch/arm/miscregs_types.hh b/src/arch/arm/miscregs_types.hh
index 940bf39..c3ee6ca 100644
--- a/src/arch/arm/miscregs_types.hh
+++ b/src/arch/arm/miscregs_types.hh
@@ -271,11 +271,6 @@
         Bitfield<0>      vm;
     EndBitUnion(HCR)

-    BitUnion32(HCR2)
-        Bitfield<1> id;
-        Bitfield<0> cd;
-    EndBitUnion(HCR2)
-
     BitUnion32(NSACR)
         Bitfield<20> nstrcdis;
         Bitfield<19> rfr;
@@ -324,7 +319,6 @@
                                 // DC CVAC and IC IVAU instructions
                                 // (AArch64 SCTLR_EL1 only)
         Bitfield<25>   ee;      // Exception Endianness
-        Bitfield<24>   ve;      // Interrupt Vectors Enable (ARMv7 only)
Bitfield<24> e0e; // Endianness of explicit data accesses at EL0
                                 // (AArch64 SCTLR_EL1 only)
Bitfield<23> xp; // Extended page table enable (dropped in ARMv7)
@@ -466,7 +460,6 @@
         Bitfield<5> pd1;
         // Long-descriptor translation table format
         Bitfield<2, 0> t0sz;
-        Bitfield<6> t2e;
         Bitfield<7> epd0;
         Bitfield<9, 8> irgn0;
         Bitfield<11, 10> orgn0;
@@ -488,8 +481,6 @@
         // TCR_EL2/3 (AArch64)
         Bitfield<18, 16> ps;
         Bitfield<20> tbi;
-        Bitfield<41> hpd0;
-        Bitfield<42> hpd1;
     EndBitUnion(TTBCR)

     // Fields of TCR_EL{1,2,3} (mostly overlapping)
@@ -514,10 +505,6 @@
         Bitfield<36> as; // EL1
         Bitfield<37> tbi0; // EL1
         Bitfield<38> tbi1; // EL1
-        Bitfield<39> ha;
-        Bitfield<40> hd;
-        Bitfield<41> hpd0;
-        Bitfield<42> hpd1;
     EndBitUnion(TCR)

     BitUnion32(HTCR)
@@ -525,7 +512,6 @@
         Bitfield<9, 8> irgn0;
         Bitfield<11, 10> orgn0;
         Bitfield<13, 12> sh0;
-        Bitfield<24> hpd;
     EndBitUnion(HTCR)

     BitUnion32(VTCR_t)
@@ -538,8 +524,6 @@
         Bitfield<13, 12> sh0;
         Bitfield<15, 14> tg0;
         Bitfield<18, 16> ps; // Only defined for VTCR_EL2
-        Bitfield<21> ha;     // Only defined for VTCR_EL2
-        Bitfield<22> hd;     // Only defined for VTCR_EL2
     EndBitUnion(VTCR_t)

     BitUnion32(PRRR)
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index fbaba87..fea208a 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -59,10 +59,10 @@
 using namespace ArmISA;

 TableWalker::TableWalker(const Params *p)
-    : MemObject(p), mmu(NULL), masterId(p->sys->getMasterId(this, name())),
+    : MemObject(p), mmu(NULL), currState(NULL), tlb(NULL), id(0),
+      currentId(-1), masterId(p->sys->getMasterId(this, name())),
       isStage2(p->is_stage2), numSquashable(p->num_squash_per_cycle),
       maxInflightWalks(p->max_inflight_walks), inflightWalks(0),
-      cpuSidePort(NULL), memSidePort(NULL),
       doL1ShortDescEvent([this]{ doL1ShortDescriptorWrapper(); }, name()),
       doL2ShortDescEvent([this]{ doL2ShortDescriptorWrapper(); }, name()),
       doL0LongDescEvent([this]{ doL0LongDescriptorWrapper(); }, name()),
@@ -71,8 +71,7 @@
       doL3LongDescEvent([this]{ doL3LongDescriptorWrapper(); }, name()),
       LongDescEventByLevel { &doL0LongDescEvent, &doL1LongDescEvent,
                             &doL2LongDescEvent, &doL3LongDescEvent },
-      doProcessEvent([this]{ processWalkWrapper(); }, name()),
-      tlb(NULL), currState(NULL)
+      doProcessEvent([this]{ processWalkWrapper(); }, name())
 {
     // Cache system-level properties
     if (FullSystem) {
@@ -96,6 +95,11 @@
     currentId = -1;
 }

+TableWalker::~TableWalker()
+{
+    ;
+}
+
 BaseSlavePort&
 TableWalker::getSlavePort(const std::string &if_name, PortID idx)
 {
@@ -2832,6 +2836,37 @@
     }
 }

+DrainState
+TableWalker::drain()
+{
+    bool state_queues_not_empty = false;
+
+    for (int i = 0; i < MAX_LOOKUP_LEVELS; ++i) {
+        if (!stateQueues[i].empty()) {
+            state_queues_not_empty = true;
+            break;
+        }
+    }
+
+    if (state_queues_not_empty || pendingQueue.size()) {
+        DPRINTF(Drain, "TableWalker not drained\n");
+        return DrainState::Draining;
+    } else {
+        DPRINTF(Drain, "TableWalker free, no need to drain\n");
+        return DrainState::Drained;
+    }
+}
+
+void
+TableWalker::drainResume()
+{
+    if (params()->sys->isTimingMode() && currState) {
+        delete currState;
+        currState = NULL;
+    }
+}
+
+
 void
 TableWalker::regStats()
 {
diff --git a/src/arch/arm/table_walker.hh b/src/arch/arm/table_walker.hh
index 462c346..2b84410 100644
--- a/src/arch/arm/table_walker.hh
+++ b/src/arch/arm/table_walker.hh
@@ -68,424 +68,431 @@

 class TableWalker : public MemObject
 {
-    private:
+  public:
+    class WalkerState : public Packet::SenderState
+    {
+      public:
+        /** ID identifying the walk */
+        const uint64_t id;
+        /** Thread context that we're doing the walk for */
+        ThreadContext *tc;
+        /** Pointer to the Table Walker performing the translation */
+        TableWalker *walker;
+        /** If the access is performed in AArch64 state */
+        bool aarch64;
+        /** Current exception level */
+        ExceptionLevel el;
+        /** Current lookup level */
+        int level;
+        /** First block where the translation started */
+        int firstblocklevel;
+        /** Address descriptor used during the table walk */
+        AddressDescriptorPtr addrdesc;
+        /** Request  that is currently being service */
+        RequestPtr req;
+        /** Cached copy of the sctlr when the translation started */
+        SCTLR sctlr;
+        /** Cached copy of the hcr when the translation started */
+        HCR hcr;
+        /** Cached copy of the mair when the translation started */
+        uint64_t mair;
+        /** Flag indicating if a we are a second stage walker */
+        bool isStage2;
+        /** Flag indicating if a second stage of lookup is required */
+        bool stage2Req;
+        /** If the mode is timing or atomic */
+        bool timing;
+        /** If the atomic mode should be functional */
+        bool functional;
+        /** Raw bits of the descriptor fetched */
+        uint64_t data;
+        /** Copy of the L1 short descriptor lookup */
+        uint32_t l1desc;
+        /** Address used to index in the inflight list */
+        Addr desc_addr;

-        MMU* mmu; // Associated MMU for this table walker
+        /** Input address size for the current translation */
+        uint8_t inputsize;
+        /** Output address size for the current translation */
+        uint8_t outputsize;
+        /** Flag to indicate if we are using 64KB granule */
+        bool largegrain;
+        /** Flag to indicate if we are using 16KB granule */
+        bool midgrain;
+        /** Grain size used during the translation */
+        uint8_t grainsize;
+        /** Number of strides needed to consume the address */
+        uint8_t stride;

-        /** Master id assigned by the MMU */
-        MasterID masterId;
+        /** Access flags values */
+        uint8_t ap_table, ns_table, xn_table, pxn_table;
+        /** Flags to indicate update in the descriptor */
+        bool update_AP, update_AF;
+        /** Flag to indicate if the desciptor is in big endian */
+        bool reversedescriptors;
+        /** Other access flags values */
+        bool lookupsecure, singlepriv, hierattrsdisabled;

- /** Indicates whether this table walker is part of the stage 2 MMU */
-        const bool isStage2;
-        const unsigned numSquashable;
-        const unsigned maxInflightWalks;
+        /** Access type of the translation */
+        AccType acctype;
+        /** Flag to indicate if it's a write */
+        bool iswrite;
+        /** Flag to indicate a stage 2 from stage 1 translation */
+        bool s2fs1walk;

-        /** Keep track of how many walks are inflight */
-        unsigned inflightWalks;
+        /** virtual address for this translation */
+        Addr address;
+        /** Base address register value for this translation */
+        Addr baseregister;
+        /** Next descriptor address bit selection */
+        uint8_t addrselecttop, addrselectbottom;

-        /** Cached copies of system-level properties */
-        bool haveSecurity;
-        bool _haveLPAE;
-        bool _haveVirtualization;
-        uint8_t physAddrRange;
-        bool _haveLargeAsid64;
+        /** Pointer to the translation structure being used */
+        TLB::TranslationStatePtr tran;

-        /** Statistics */
-        Stats::Scalar statWalks;
-        Stats::Scalar statWalksShortDescriptor;
-        Stats::Scalar statWalksLongDescriptor;
-        Stats::Vector statWalksShortTerminatedAtLevel;
-        Stats::Vector statWalksLongTerminatedAtLevel;
-        Stats::Scalar statSquashedBefore;
-        Stats::Scalar statSquashedAfter;
-        Stats::Histogram statWalkWaitTime;
-        Stats::Histogram statWalkServiceTime;
-        // Essentially "L" of queueing theory
-        Stats::Histogram statPendingWalks;
-        Stats::Vector statPageSizes;
-        Stats::Vector2d statRequestOrigin;
+        TLB::Translation* stage2Tran;
+        Event* next_event;
+        Tick startTime;
+        bool delayed;
+        bool partial_hit;
+        bool isInflight;

-        static const unsigned REQUESTED = 0;
-        static const unsigned COMPLETED = 1;
+        WalkerState(TableWalker*, uint64_t);
+        ~WalkerState();

-        enum {
-            SIZE_4GB = 0,
-            SIZE_64GB,
-            SIZE_1TB,
-            SIZE_4TB,
-            SIZE_16TB,
-            SIZE_256TB,
-            SIZE_4PB
-        };
-
-        enum class TG0 : std::uint8_t {
-            GRANULE_4KB = 0,
-            GRANULE_64KB = 1,
-            GRANULE_16KB = 2,
-            UNUSED = 3
-        };
-
-        enum class TG1 : long unsigned int {
-            UNUSED = 0,
-            GRANULE_16KB = 1,
-            GRANULE_4KB = 2,
-            GRANULE_64KB = 3
-        };
-
-    public:
-
-        class WalkerState : public Packet::SenderState
+        void
+        s1AttrDecode64(uint8_t sh, uint8_t memattr)
         {
-            public:
-
-                /** ID identifying the walk */
-                const uint64_t id;
-                /** Thread context that we're doing the walk for */
-                ThreadContext *tc;
- /** Pointer to the Table Walker performing the translation */
-                TableWalker *walker;
-                /** If the access is performed in AArch64 state */
-                bool aarch64;
-                /** Current exception level */
-                ExceptionLevel el;
-                /** Current lookup level */
-                int level;
-                /** First block where the translation started */
-                int firstblocklevel;
-                /** Address descriptor used during the table walk */
-                AddressDescriptorPtr addrdesc;
-                /** Request  that is currently being service */
-                RequestPtr req;
- /** Cached copy of the sctlr when the translation started */
-                SCTLR sctlr;
-                /** Cached copy of the hcr when the translation started */
-                HCR hcr;
-                /** Cached copy of the mair when the translation started */
-                uint64_t mair;
-                /** Flag indicating if a we are a second stage walker */
-                bool isStage2;
- /** Flag indicating if a second stage of lookup is required */
-                bool stage2Req;
-                /** If the mode is timing or atomic */
-                bool timing;
-                /** If the atomic mode should be functional */
-                bool functional;
-                /** Raw bits of the descriptor fetched */
-                uint64_t data;
-                /** Copy of the L1 short descriptor lookup */
-                uint32_t l1desc;
-                /** Address used to index in the inflight list */
-                Addr desc_addr;
-
-                /** Input address size for the current translation */
-                uint8_t inputsize;
-                /** Output address size for the current translation */
-                uint8_t outputsize;
-                /** Flag to indicate if we are using 64KB granule */
-                bool largegrain;
-                /** Flag to indicate if we are using 16KB granule */
-                bool midgrain;
-                /** Grain size used during the translation */
-                uint8_t grainsize;
-                /** Number of strides needed to consume the address */
-                uint8_t stride;
-
-                /** Access flags values */
-                uint8_t ap_table, ns_table, xn_table, pxn_table;
-                /** Flags to indicate update in the descriptor */
-                bool update_AP, update_AF;
-                /** Flag to indicate if the desciptor is in big endian */
-                bool reversedescriptors;
-                /** Other access flags values */
-                bool lookupsecure, singlepriv, hierattrsdisabled;
-
-                /** Access type of the translation */
-                AccType acctype;
-                /** Flag to indicate if it's a write */
-                bool iswrite;
-                /** Flag to indicate a stage 2 from stage 1 translation */
-                bool s2fs1walk;
-
-                /** virtual address for this translation */
-                Addr address;
-                /** Base address register value for this translation */
-                Addr baseregister;
-                /** Next descriptor address bit selection */
-                uint8_t addrselecttop, addrselectbottom;
-
-                /** Pointer to the translation structure being used */
-                TLB::TranslationStatePtr tran;
-
-                TLB::Translation* stage2Tran;
-                Event* next_event;
-                Tick startTime;
-                bool delayed;
-                bool partial_hit;
-                bool isInflight;
-
-                WalkerState(TableWalker*, uint64_t);
-                ~WalkerState();
-
-                void
-                s1AttrDecode64(uint8_t sh, uint8_t memattr)
-                {
-                    MemoryAttributes* memattrs = addrdesc->memattrs;
-                    uint8_t attr = bits(memattr, 2, 0);
-                    SCTLR sctlr = tran->sctlr;
-                    HCR hcr = tran->hcr;
-                    uint64_t mair = tran->mair;
- walker->s1AttrDecode64(tc, memattrs, sh, attr, acctype, el,
-                                            sctlr, hcr, mair);
-                }
-
-                void
-                s1AttrDecode32(uint8_t sh, uint8_t memattr)
-                {
-                    MemoryAttributes* memattrs = addrdesc->memattrs;
-                    uint8_t attr = bits(memattr, 2, 0);
- walker->s1AttrDecode32(tc, memattrs, sh, attr, acctype, el,
-                                            sctlr, hcr, mair);
-                }
-
-                void
-                s2AttrDecode(uint8_t sh, uint8_t memattr, AccType acctype)
-                {
-                    MemoryAttributes* memattrs = addrdesc->memattrs;
-                    walker->s2AttrDecode(memattrs, sh, memattr, acctype);
-                }
-
-                void maxtickReached();
-                EventFunctionWrapper* maxtickReachedEvent;
-        };
-
-        class CpuSidePort : public SlavePort
-        {
-            public:
-                CpuSidePort(const std::string &_name, TableWalker *_walker,
-                    PortID _index) : SlavePort(_name, _walker),
-                        walker(_walker), index(_index) {}
-
-            protected:
-                TableWalker *walker;
-                int index;
-
-                virtual bool recvTimingReq(PacketPtr pkt);
-                virtual Tick recvAtomic(PacketPtr pkt);
-                virtual void recvFunctional(PacketPtr pkt) { };
-                virtual void recvRangeChange() { };
-                virtual void recvReqRetry();
-                virtual void recvRespRetry();
-                virtual AddrRangeList getAddrRanges() const
-                {
-                    AddrRangeList range;
-                    return range;
-                }
-        };
-
-        class MemSidePort : public MasterPort
-        {
-            public:
-                MemSidePort(const std::string &_name, TableWalker *_walker,
-                    PortID _index) : MasterPort(_name, _walker),
-                        walker(_walker), index(_index) {}
-
-                std::deque<PacketPtr> retries;
-                std::multimap<Addr, PacketPtr> new_retries;
-
-            protected:
-                TableWalker *walker;
-                int index;
-
-                virtual bool recvTimingResp(PacketPtr pkt);
-                virtual Tick recvAtomic(PacketPtr pkt) { return 0; }
-                virtual void recvFunctional(PacketPtr pkt) { };
-                virtual void recvRangeChange() { };
-                virtual void recvReqRetry();
-        };
-
-        CpuSidePort* cpuSidePort;
-        MemSidePort* memSidePort;
-
-        BaseMasterPort&
-        getMasterPort(const std::string &if_name, PortID idx) override;
-        BaseSlavePort&
-        getSlavePort(const std::string &if_name, PortID idx) override;
-
-        void regStats() override;
-
-        void increaseInflightWalks() {
-            currState->isInflight = true;
-            inflightWalks++;
+            MemoryAttributes* memattrs = addrdesc->memattrs;
+            uint8_t attr = bits(memattr, 2, 0);
+            SCTLR sctlr = tran->sctlr;
+            HCR hcr = tran->hcr;
+            uint64_t mair = tran->mair;
+            walker->s1AttrDecode64(tc, memattrs, sh, attr, acctype, el,
+                                    sctlr, hcr, mair);
         }

-        void decreaseInflightWalks() {
-            if (currState->isInflight) {
-                assert(inflightWalks > 0);
-                inflightWalks--;
+        void
+        s1AttrDecode32(uint8_t sh, uint8_t memattr)
+        {
+            MemoryAttributes* memattrs = addrdesc->memattrs;
+            uint8_t attr = bits(memattr, 2, 0);
+            walker->s1AttrDecode32(tc, memattrs, sh, attr, acctype, el,
+                                    sctlr, hcr, mair);
+        }
+
+        void
+        s2AttrDecode(uint8_t sh, uint8_t memattr, AccType acctype)
+        {
+            MemoryAttributes* memattrs = addrdesc->memattrs;
+            walker->s2AttrDecode(memattrs, sh, memattr, acctype);
+        }
+
+        void maxtickReached();
+        EventFunctionWrapper* maxtickReachedEvent;
+    };
+
+  protected:
+
+    /** Queues of requests for all the different lookup levels */
+    std::map<uint64_t, WalkerState*> stateQueues[MAX_LOOKUP_LEVELS];
+
+ /** Queue of requests that have passed are waiting because the walker is
+     * currently busy. */
+    std::map<uint64_t, WalkerState*> pendingQueue;
+
+    /** The MMU to forward second stage look upts to */
+    MMU* mmu;
+
+    /** Queue of walks in flight */
+    typedef std::queue<WalkerState*> WalksQueue;
+    std::map<Addr, WalksQueue> inflightDescriptors;
+
+    WalkerState* currState;
+
+    /** TLB that initiated the table walk. Used for functional lookups */
+    TLB *tlb;
+
+    /** Global walk ID */
+    uint64_t id, currentId;
+
+    /** Master id assigned by the MMU */
+    MasterID masterId;
+
+    /** Indicates whether this table walker is part of the stage 2 MMU */
+    const bool isStage2;
+    const unsigned numSquashable;
+    const unsigned maxInflightWalks;
+
+    /** Keep track of how many walks are inflight */
+    unsigned inflightWalks;
+
+    /** Cached copies of system-level properties */
+    bool haveSecurity;
+    bool _haveLPAE;
+    bool _haveVirtualization;
+    uint8_t physAddrRange;
+    bool _haveLargeAsid64;
+
+    /** Statistics */
+    Stats::Scalar statWalks;
+    Stats::Scalar statWalksShortDescriptor;
+    Stats::Scalar statWalksLongDescriptor;
+    Stats::Vector statWalksShortTerminatedAtLevel;
+    Stats::Vector statWalksLongTerminatedAtLevel;
+    Stats::Scalar statSquashedBefore;
+    Stats::Scalar statSquashedAfter;
+    Stats::Histogram statWalkWaitTime;
+    Stats::Histogram statWalkServiceTime;
+    // Essentially "L" of queueing theory
+    Stats::Histogram statPendingWalks;
+    Stats::Vector statPageSizes;
+    Stats::Vector2d statRequestOrigin;
+
+    static const unsigned REQUESTED = 0;
+    static const unsigned COMPLETED = 1;
+
+    enum {
+        SIZE_4GB = 0,
+        SIZE_64GB,
+        SIZE_1TB,
+        SIZE_4TB,
+        SIZE_16TB,
+        SIZE_256TB,
+        SIZE_4PB
+    };
+
+    enum class TG0 : std::uint8_t {
+        GRANULE_4KB = 0,
+        GRANULE_64KB = 1,
+        GRANULE_16KB = 2,
+        UNUSED = 3
+    };
+
+    enum class TG1 : long unsigned int {
+        UNUSED = 0,
+        GRANULE_16KB = 1,
+        GRANULE_4KB = 2,
+        GRANULE_64KB = 3
+    };
+
+  public:
+   typedef ArmTableWalkerParams Params;
+    TableWalker(const Params *p);
+    virtual ~TableWalker();
+
+    const Params *
+    params() const
+    {
+        return dynamic_cast<const Params *>(_params);
+    }
+
+    bool haveLPAE() const { return _haveLPAE; }
+    bool haveVirtualization() const { return _haveVirtualization; }
+    bool haveLargeAsid64() const { return _haveLargeAsid64; }
+    /** Checks if all state is cleared and if so, completes drain */
+    void completeDrain();
+    DrainState drain() override;
+    void drainResume() override;
+
+    void regStats() override;
+
+    class CpuSidePort : public SlavePort
+    {
+        public:
+            CpuSidePort(const std::string &_name, TableWalker *_walker,
+                PortID _index) : SlavePort(_name, _walker),
+                    walker(_walker), index(_index) {}
+
+        protected:
+            TableWalker *walker;
+            int index;
+
+            virtual bool recvTimingReq(PacketPtr pkt);
+            virtual Tick recvAtomic(PacketPtr pkt);
+            virtual void recvFunctional(PacketPtr pkt) { };
+            virtual void recvRangeChange() { };
+            virtual void recvReqRetry();
+            virtual void recvRespRetry();
+            virtual AddrRangeList getAddrRanges() const
+            {
+                AddrRangeList range;
+                return range;
             }
+    };
+
+    class MemSidePort : public MasterPort
+    {
+        public:
+            MemSidePort(const std::string &_name, TableWalker *_walker,
+                PortID _index) : MasterPort(_name, _walker),
+                    walker(_walker), index(_index) {}
+
+            std::deque<PacketPtr> retries;
+
+        protected:
+            TableWalker *walker;
+            int index;
+
+            virtual bool recvTimingResp(PacketPtr pkt);
+            virtual Tick recvAtomic(PacketPtr pkt) { return 0; }
+            virtual void recvFunctional(PacketPtr pkt) { };
+            virtual void recvRangeChange() { };
+            virtual void recvReqRetry();
+    };
+
+    CpuSidePort* cpuSidePort;
+    MemSidePort* memSidePort;
+
+    BaseMasterPort&
+    getMasterPort(const std::string &if_name, PortID idx) override;
+    BaseSlavePort&
+    getSlavePort(const std::string &if_name, PortID idx) override;
+
+    void increaseInflightWalks() {
+        currState->isInflight = true;
+        inflightWalks++;
+    }
+
+    void decreaseInflightWalks() {
+        if (currState->isInflight) {
+            assert(inflightWalks > 0);
+            inflightWalks--;
         }
+    }

-    private:
+private:

- // Returns TRUE if the bits of the input (n) between the high bit (h)
-        // and the low bit (l) are ones
-        bool isOnes(uint64_t n, uint32_t h, uint32_t l);
+    // Returns TRUE if the bits of the input (n) between the high bit (h)
+    // and the low bit (l) are ones
+    bool isOnes(uint64_t n, uint32_t h, uint32_t l);

-        /** Short descriptor event functions */
-        void doL1ShortDescriptor();
-        void doL1ShortDescriptorWrapper();
-        EventFunctionWrapper doL1ShortDescEvent;
+    /** Short descriptor event functions */
+    void doL1ShortDescriptor();
+    void doL1ShortDescriptorWrapper();
+    EventFunctionWrapper doL1ShortDescEvent;

-        void doL2ShortDescriptor();
-        void doL2ShortDescriptorWrapper();
-        EventFunctionWrapper doL2ShortDescEvent;
+    void doL2ShortDescriptor();
+    void doL2ShortDescriptorWrapper();
+    EventFunctionWrapper doL2ShortDescEvent;

-        /** Long descriptor event functions for LPAE and AArch64*/
-        void doL0LongDescriptorWrapper();
-        EventFunctionWrapper doL0LongDescEvent;
-        void doL1LongDescriptorWrapper();
-        EventFunctionWrapper doL1LongDescEvent;
-        void doL2LongDescriptorWrapper();
-        EventFunctionWrapper doL2LongDescEvent;
-        void doL3LongDescriptorWrapper();
-        EventFunctionWrapper doL3LongDescEvent;
+    /** Long descriptor event functions for LPAE and AArch64*/
+    void doL0LongDescriptorWrapper();
+    EventFunctionWrapper doL0LongDescEvent;
+    void doL1LongDescriptorWrapper();
+    EventFunctionWrapper doL1LongDescEvent;
+    void doL2LongDescriptorWrapper();
+    EventFunctionWrapper doL2LongDescEvent;
+    void doL3LongDescriptorWrapper();
+    EventFunctionWrapper doL3LongDescEvent;

-        void doLongDescriptor();
-        void doLongDescriptorWrapper(int);
-        Event* LongDescEventByLevel[4];
+    void doLongDescriptor();
+    void doLongDescriptorWrapper(int);
+    Event* LongDescEventByLevel[4];

-        /** AArch64 descriptor event functions */
-        void doAArch64Descriptor();
-        void doAArch64DescriptorWrapper(int);
+    /** AArch64 descriptor event functions */
+    void doAArch64Descriptor();
+    void doAArch64DescriptorWrapper(int);

-        void processWalkWrapper();
-        EventFunctionWrapper doProcessEvent;
+    void processWalkWrapper();
+    EventFunctionWrapper doProcessEvent;

-        // Returns the descriptor at the physical address specified by the
-        // AddressDescriptor, checks access permissions and sets the fault
-        // field if needed
- bool fetchDescriptor(AddressDescriptorPtr, int, Request::Flags, int, - Event *event, void (TableWalker::*doDescriptor)());
+    // Returns the descriptor at the physical address specified by the
+    // AddressDescriptor, checks access permissions and sets the fault
+    // field if needed
+    bool fetchDescriptor(AddressDescriptorPtr, int, Request::Flags, int,
+                        Event *event, void (TableWalker::*doDescriptor)());

-        // Schedule the next table walk in the pending queue
-        void nextWalk();
+    // Schedule the next table walk in the pending queue
+    void nextWalk();

-        void completeDrain();
+    void sendTimingResponse();

-        void sendTimingResponse();
+    void insertPartialTranslation();

-        void insertPartialTranslation();
+    // Annotate the fault as it was produced during a stage 1 translation
+    // in a stage 2 page walk
+    void annotateStage2Fault();

- // Annotate the fault as it was produced during a stage 1 translation
-        // in a stage 2 page walk
-        void annotateStage2Fault();
+protected:

-    protected:
+    // Process the queue with pending descriptor requests and continue the
+    // walk for the ones with the matching address
+    bool processInflightDescriptors(Addr);

-        // TLB that initiated the table walk. Used for functional lookups
-        TLB *tlb;
+    void accessFlagFault(uint8_t, ArmFault::TranMethod);
+    void addressSizeFault(uint8_t, bool, ArmFault::TranMethod);
+    void translationFault(uint8_t, ArmFault::TranMethod);

-        // Global walk ID
-        uint64_t id, currentId;
-        // Queues of requests for all the the different lookup levels
-        std::map<uint64_t, WalkerState*> stateQueues[MAX_LOOKUP_LEVELS];
+    bool s1CacheDisabled(AccType);
+    bool s2CacheDisabled(AccType);

- // Queue of requests that have passed are waiting because the walker
-        // is currently busy
-        std::map<uint64_t, WalkerState*> pendingQueue;
-        std::queue<WalkerState*> newPendingQueue;
+    // Converts the Stage 1 attribute fields, using the uint64_t
+    // to orthogonal attributes and hints
+    void s1AttrDecode32(ThreadContext*, MemoryAttributes*, uint8_t,
+                uint8_t, AccType, ExceptionLevel, SCTLR, HCR, uint64_t);
+    void s1AttrDecode64(ThreadContext*, MemoryAttributes*, uint8_t,
+                uint8_t, AccType, ExceptionLevel, SCTLR, HCR, uint64_t);

-        WalkerState* currState;
+    // Converts the Stage 2 attribute fields into othogonal attributes and
+    // hints
+    void s2AttrDecode(MemoryAttributes*, uint8_t, uint8_t, AccType);

-        typedef std::queue<WalkerState*> WalksQueue;
-        std::map<Addr, WalksQueue> inflightDescriptors;
+    // Converts the short attribute fields for Normal memory as used in the
+    // TTBR and TEX fields to orthogonal attributes and hints
+    MemAttrHints shortConvertAttrsHints(uint8_t, AccType);

- // Process the queue with pending descriptor requests and continue the
-        // walk for the ones with the matching address
-        bool processInflightDescriptors(Addr);
+    // Converts the long attribute fields for Normal memory as used in the
+    // uint64_t fields to orthogonal attributes and hints
+    MemAttrHints longConvertAttrsHints(uint8_t, AccType, SCTLR, HCR);

-        void accessFlagFault(uint8_t, ArmFault::TranMethod);
-        void addressSizeFault(uint8_t, bool, ArmFault::TranMethod);
-        void translationFault(uint8_t, ArmFault::TranMethod);
+    // Converts the attribute fields for Normal memory as used in stage 2
+    // descriptors to orthogonal attributes and hints
+    MemAttrHints s2ConvertAttrsHints(uint8_t, AccType);

-        bool s1CacheDisabled(AccType);
-        bool s2CacheDisabled(AccType);
+    void walkAttrDecode(ThreadContext*, MemoryAttributes*, uint8_t,
+                        uint8_t, uint8_t, ExceptionLevel, SCTLR, HCR);

-        // Converts the Stage 1 attribute fields, using the uint64_t
-        // to orthogonal attributes and hints
-        void s1AttrDecode32(ThreadContext*, MemoryAttributes*, uint8_t,
- uint8_t, AccType, ExceptionLevel, SCTLR, HCR, uint64_t);
-        void s1AttrDecode64(ThreadContext*, MemoryAttributes*, uint8_t,
- uint8_t, AccType, ExceptionLevel, SCTLR, HCR, uint64_t);
+    void defaultTEXDecode(MemoryAttributes*, uint8_t, bool, bool, bool,
+                            AccType);

- // Converts the Stage 2 attribute fields into othogonal attributes and
-        // hints
-        void s2AttrDecode(MemoryAttributes*, uint8_t, uint8_t, AccType);
+    void remappedTEXDecode(MemoryAttributes*, uint8_t, bool, bool, bool,
+                            AccType);

- // Converts the short attribute fields for Normal memory as used in the
-        // TTBR and TEX fields to orthogonal attributes and hints
-        MemAttrHints shortConvertAttrsHints(uint8_t, AccType);
+    void setCurrentStateId(uint64_t currId) {
+        currentId = currId;
+    }

- // Converts the long attribute fields for Normal memory as used in the
-        // uint64_t fields to orthogonal attributes and hints
-        MemAttrHints longConvertAttrsHints(uint8_t, AccType, SCTLR, HCR);
+public:

- // Converts the attribute fields for Normal memory as used in stage 2
-        // descriptors to orthogonal attributes and hints
-        MemAttrHints s2ConvertAttrsHints(uint8_t, AccType);
+    // Clean up the currState and pending walk
+    void cleanup();

-        void walkAttrDecode(ThreadContext*, MemoryAttributes*, uint8_t,
-                            uint8_t, uint8_t, ExceptionLevel, SCTLR, HCR);
+    bool haveLPAE() {
+        return _haveLPAE;
+    }

-        void defaultTEXDecode(MemoryAttributes*, uint8_t, bool, bool, bool,
-                                AccType);
+    bool haveVirtualization() {
+        return _haveVirtualization;
+    }

- void remappedTEXDecode(MemoryAttributes*, uint8_t, bool, bool, bool,
-                                AccType);
+    bool haveLargeAsid64() {
+        return _haveLargeAsid64;
+    }

-        void setCurrentStateId(uint64_t currId) {
-            currentId = currId;
-        }
+    void walk(TLB::TranslationStatePtr);

-    public:
+    void setMMU(MMU*, TLB*);

-        // Clean up the currState and pending walk
-        void cleanup();
+    // Returns TRUE if the page walk is being delayed, FALSE otherwise
+    // The result of the page walk will be updated in the TranslationState
+    // structure
+    void translationTableWalkSD(TLB::TranslationStatePtr);
+    void translationTableWalkLD(TLB::TranslationStatePtr);
+    void translationTableWalk64(TLB::TranslationStatePtr);

-        bool haveLPAE() {
-            return _haveLPAE;
-        }
-
-        bool haveVirtualization() {
-            return _haveVirtualization;
-        }
-
-        bool haveLargeAsid64() {
-            return _haveLargeAsid64;
-        }
-
-        void walk(TLB::TranslationStatePtr);
-
-        typedef ArmTableWalkerParams Params;
-        TableWalker(const Params *p);
-
-        const Params *
-        params() const
-        {
-            return dynamic_cast<const Params *>(_params);
-        }
-
-        void setMMU(MMU*, TLB*);
-
-        // Returns TRUE if the page walk is being delayed, FALSE otherwise
- // The result of the page walk will be updated in the TranslationState
-        // structure
-        void translationTableWalkSD(TLB::TranslationStatePtr);
-        void translationTableWalkLD(TLB::TranslationStatePtr);
-        void translationTableWalk64(TLB::TranslationStatePtr);
-
-        Fault testWalk(Addr pa, Addr size, TlbEntry::DomainType domain,
-                       LookupLevel lookup_level);
+    Fault testWalk(Addr pa, Addr size, TlbEntry::DomainType domain,
+                   LookupLevel lookup_level);
 };

 } // namespace ArmISA
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index 228535b..7b5b631 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -62,15 +62,16 @@
 using namespace ArmISA;

 TLB::TLB(const Params *p)
-    : BaseTLB(p), size(p->size), assoc(p->assoc),
-      allowPartial(p->allow_partial_translations), table(size),
+    : BaseTLB(p), table(p->size), size(p->size), assoc(p->assoc),
+ isStage2(p->is_stage2), stage2Req(false), stage2DescReq(false), _attr(0),
+      directToStage2(false), level(p->level),
+      allowPartial(p->allow_partial_translations), access_latency(p->lat),
       indexingPolicy(p->indexing_policy),
-      replacementPolicy(p->replacement_policy), isStage2(p->is_stage2),
-      level(p->level), access_latency(p->lat), next_tlb(p->next_tlb),
-      stage2Tlb(p->stage2tlb), tableWalker(p->walker), mmu(NULL),
- test(nullptr), stage2Req(false), directToStage2(false), aarch64(false), - aarch64EL(EL0), isPriv(false), isSecure(false), isHyp(false), asid(0),
-      vmid(0), miscRegValid(false)
+      replacementPolicy(p->replacement_policy), tableWalker(p->walker),
+ stage2Tlb(NULL), next_tlb(NULL), mmu(NULL), test(nullptr), rangeMRU(1),
+      aarch64(false), aarch64EL(EL0), isPriv(false), isSecure(false),
+      isHyp(false), asid(0), vmid(0), dacr(0),
+      miscRegValid(false), miscRegContext(0), curTranType(NormalTran)
 {
     assert(assoc < size);

@@ -180,6 +181,22 @@
     return fault;
 }

+Fault
+TLB::finalizePhysical(const RequestPtr &req,
+                      ThreadContext *tc, Mode mode) const
+{
+    const Addr paddr = req->getPaddr();
+
+    if (m5opRange.contains(paddr)) {
+        req->setFlags(Request::MMAPPED_IPR | Request::GENERIC_IPR);
+        req->setPaddr(GenericISA::iprAddressPseudoInst(
+                          (paddr >> 8) & 0xFF,
+                          paddr & 0xFF));
+    }
+
+    return NoFault;
+}
+
 void
 TLB::translateTiming(const RequestPtr &req, ThreadContext *tc,
     Translation *translation, Mode mode, TLB::ArmTranslationType tranType)
@@ -338,6 +355,12 @@
     return delay ? NoFault : finalizeTranslation(tran);
 }

+void
+TLB::regProbePoints()
+{
+    ppRefills.reset(new ProbePoints::PMU(getProbeManager(), "Refills"));
+}
+
 Fault
 TLB::translateSe(const RequestPtr &req, ThreadContext *tc, Mode mode,
                     Translation *translation, bool &delay, bool timing)
@@ -381,13 +404,13 @@

 Fault
 TLB::translateAtomic(const RequestPtr &req, ThreadContext *tc, Mode mode,
-        ArmTranslationType tranType, TranslationStatePtr ts)
+        ArmTranslationType tranType)
 {
     updateMiscReg(tc, tranType);

     if (directToStage2) {
         assert(stage2Tlb);
-        return stage2Tlb->translateAtomic(req, tc, mode, tranType, ts);
+        return stage2Tlb->translateAtomic(req, tc, mode, tranType);
     }

     bool delay = false;
@@ -610,10 +633,6 @@
                  te->pfn, te->size, te->vpn, te->asid, te->vmid, te->N,
                  te->global, te->valid, xn, ap, te->ns, te->nstid,
                  te->isHyp);
-
-    // Sanity check
-    bool tlb_hit = lookup(tran, true, true, from_ptw);
-    assert(tlb_hit);
 }

 bool
@@ -640,7 +659,7 @@
         target_el = tran->aarch64 ? tran->aarch64EL : 1;
     } else {
         va = tran->ptw_desc_addr;
-        if (!functional) printTLB();
+        if (!functional) printTlb();
     }

     TlbEntryPtr _te = nullptr; // For debugging
@@ -1895,6 +1914,30 @@
 }

 void
+TLB::takeOverFrom(BaseTLB *_otlb)
+{
+    TLB *otlb = dynamic_cast<TLB*>(_otlb);
+    /* Make sure we actually have a valid type */
+    if (otlb) {
+        _attr = otlb->_attr;
+        haveLPAE = otlb->haveLPAE;
+        directToStage2 = otlb->directToStage2;
+        stage2Req = otlb->stage2Req;
+        stage2DescReq = otlb->stage2DescReq;
+
+        /* Sync the stage2 MMU if they exist in both
+         * the old CPU and the new
+         */
+        if (!isStage2 &&
+            stage2Tlb && otlb->stage2Tlb) {
+            stage2Tlb->takeOverFrom(otlb->stage2Tlb);
+        }
+    } else {
+        panic("Incompatible TLB type!");
+    }
+}
+
+void
 TLB::regStats()
 {
     BaseTLB::regStats();
@@ -2308,15 +2351,15 @@
 }

 void
-TLB::printTLB()
+TLB::printTlb() const
 {
-    DPRINTF(TLB, "Current TLB contents:\n");
-
-    for (unsigned int i = 0; i < size; i++) {
-        if (table[i].getData()) {
-            DPRINTF(TLB, " * [%u] %s\n", i, table[i].getData()->print());
-        }
-    }
+//    DPRINTF(TLB, "Current TLB contents:\n");
+//
+//    for (unsigned int i = 0; i < size; i++) {
+//        if (table[i].getData()) {
+//            DPRINTF(TLB, " * [%u] %s\n", i, table[i].getData()->print());
+//        }
+//    }
 }

 void
@@ -2332,7 +2375,8 @@
 }

 Fault
-TLB::testTranslation(RequestPtr req, Mode mode, TlbEntry::DomainType domain)
+TLB::testTranslation(const RequestPtr &req, Mode mode,
+        TlbEntry::DomainType domain)
 {
     if (!test || !req->hasSize() || req->getSize() == 0 ||
         req->isCacheMaintenance()) {
diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh
index 7702e8a..9cadc6c 100644
--- a/src/arch/arm/tlb.hh
+++ b/src/arch/arm/tlb.hh
@@ -109,661 +109,692 @@

 class TLB : public BaseTLB
 {
-    private:
+  public:
+    enum ArmFlags {
+        AlignmentMask = 0x7,

-        // Number of TLB entries
-        unsigned int size;
-        unsigned int assoc;
-        // Allow storing partial translations
-        const bool allowPartial;
+        AlignByte = 0x0,
+        AlignHalfWord = 0x1,
+        AlignWord = 0x2,
+        AlignDoubleWord = 0x3,
+        AlignQuadWord = 0x4,
+        AlignOctWord = 0x5,

-        std::vector<TlbEntryRepl> table;
+        AllowUnaligned = 0x8,
+        // Priv code operating as if it wasn't
+        UserMode = 0x10,
+ // Because zero otherwise looks like a valid setting and may be used
+        // accidentally, this bit must be non-zero to show it was used on
+        // purpose.
+        MustBeOne = 0x40
+    };

-        BaseIndexingPolicy    *indexingPolicy;
-        BaseReplacementPolicy *replacementPolicy;
+    enum ArmTranslationType {
+        NormalTran = 0,
+        S1CTran = 0x1,
+        HypMode = 0x2,
+        // Secure code operating as if it wasn't (required by some Address
+        // Translate operations)
+        S1S2NsTran = 0x4,
+ // Address translation instructions (eg AT S1E0R_Xt) need to be handled + // in special ways during translation because they could need to act
+        // like a different EL than the current EL. The following flags are
+        // for these instructions
+        S1E0Tran = 0x8,
+        S1E1Tran = 0x10,
+        S1E2Tran = 0x20,
+        S1E3Tran = 0x40,
+        S12E0Tran = 0x80,
+        S12E1Tran = 0x100
+    };

-        bool isStage2;  // The TLB is part of the Stage 2 MMU
-        uint8_t level;  // TLB level
+    /**
+     * Determine the EL to use for the purpose of a translation given
+     * a specific translation type. If the translation type doesn't
+     * specify an EL, we use the current EL.
+     */
+    static ExceptionLevel tranTypeEL(CPSR cpsr, ArmTranslationType type);

-        Cycles access_latency;
+  protected:
+    std::vector<TlbEntryRepl> table; // the Page Table
+    int size;            // TLB Size
+    unsigned int assoc;  // Associativity of the TLB
+ bool isStage2; // Indicates this TLB is part of the second stage MMU + bool stage2Req; // Indicates whether a stage 2 lookup is also required + // Indicates whether a stage 2 lookup of the table descriptors is required. + // Certain address translation instructions will intercept the IPA but the
+    // table descriptors still need to be translated by the stage2.
+    bool stage2DescReq;
+    uint64_t _attr;      // Memory attributes for last accessed TLB entry
+ bool directToStage2; // Indicates whether all translation requests should
+                         // be routed directly to the stage 2 TLB
+    const uint8_t level;     // TLB level
+    const bool allowPartial; // Allow storing partial translations

-        TLB *next_tlb;
-        TLB *stage2Tlb;
-        TableWalker *tableWalker;
-        MMU *mmu;
+    const Cycles access_latency;

-        TlbTestInterface *test;
+    BaseIndexingPolicy    *indexingPolicy;
+    BaseReplacementPolicy *replacementPolicy;

-        // Access Stats
-        mutable Stats::Scalar instHits;
-        mutable Stats::Scalar instMisses;
-        mutable Stats::Scalar readHits;
-        mutable Stats::Scalar readMisses;
-        mutable Stats::Scalar writeHits;
-        mutable Stats::Scalar writeMisses;
-        mutable Stats::Scalar partialHits;
-        mutable Stats::Scalar partialMisses;
-        mutable Stats::Scalar inserts;
-        mutable Stats::Scalar flushTlb;
-        mutable Stats::Scalar flushTlbMva;
-        mutable Stats::Scalar flushTlbMvaAsid;
-        mutable Stats::Scalar flushTlbAsid;
-        mutable Stats::Scalar flushedEntries;
-        mutable Stats::Scalar alignFaults;
-        mutable Stats::Scalar prefetchFaults;
-        mutable Stats::Scalar domainFaults;
-        mutable Stats::Scalar permsFaults;
+    TableWalker *tableWalker;
+    TLB *stage2Tlb;
+    TLB *next_tlb;
+    MMU *mmu;

-        Stats::Formula readAccesses;
-        Stats::Formula writeAccesses;
-        Stats::Formula instAccesses;
-        Stats::Formula hits;
-        Stats::Formula misses;
-        Stats::Formula accesses;
-        Stats::Formula partialAccesses;
+    TlbTestInterface *test;

-        uint64_t _attr; // Memory attributes for last accessed TLB entry
+    // Access Stats
+    mutable Stats::Scalar instHits;
+    mutable Stats::Scalar instMisses;
+    mutable Stats::Scalar readHits;
+    mutable Stats::Scalar readMisses;
+    mutable Stats::Scalar writeHits;
+    mutable Stats::Scalar writeMisses;
+    mutable Stats::Scalar inserts;
+    mutable Stats::Scalar flushTlb;
+    mutable Stats::Scalar flushTlbMva;
+    mutable Stats::Scalar flushTlbMvaAsid;
+    mutable Stats::Scalar flushTlbAsid;
+    mutable Stats::Scalar flushedEntries;
+    mutable Stats::Scalar alignFaults;
+    mutable Stats::Scalar prefetchFaults;
+    mutable Stats::Scalar domainFaults;
+    mutable Stats::Scalar permsFaults;
+    mutable Stats::Scalar partialHits;
+    mutable Stats::Scalar partialMisses;

-    public:
+    Stats::Formula readAccesses;
+    Stats::Formula writeAccesses;
+    Stats::Formula instAccesses;
+    Stats::Formula hits;
+    Stats::Formula misses;
+    Stats::Formula accesses;
+    Stats::Formula partialAccesses;

-        enum ArmFlags {
-            AlignmentMask = 0x7,
+    /** PMU probe for TLB refills */
+    ProbePoints::PMUUPtr ppRefills;

-            AlignByte = 0x0,
-            AlignHalfWord = 0x1,
-            AlignWord = 0x2,
-            AlignDoubleWord = 0x3,
-            AlignQuadWord = 0x4,
-            AlignOctWord = 0x5,
+ int rangeMRU; //On lookup, only move entries ahead when outside rangeMRU

-            AllowUnaligned = 0x8,
-            // Priv code operating as if it wasn't
-            UserMode = 0x10,
-            // Because zero otherwise looks like a valid setting
-            // and may be used accidentally, this bit must be
-            // non-zero to show it was used on purpose.
-            MustBeOne = 0x40
-        };
+  public:
+    TLB(const ArmTLBParams *p);
+    TLB(const Params *p, int _size, TableWalker *_walker);

-        enum ArmTranslationType {
-            NormalTran = 0,
-            S1CTran = 0x1,
-            HypMode = 0x2,
- // Secure code operating as if it wasn't (required by some Address
-            // Translate operations)
-            S1S2NsTran = 0x4,
-            // Address translation instructions (eg AT S1E0R_Xt) need to be
- // handled in special ways during translation because they could
-            // need to act like a different EL than the current EL.
-            // The following flags are for these instructions
-            S1E0Tran = 0x8,
-            S1E1Tran = 0x10,
-            S1E2Tran = 0x20,
-            S1E3Tran = 0x40,
-            S12E0Tran = 0x80,
-            S12E1Tran = 0x100
-        };
+    virtual ~TLB();

-        enum LookupStatus {
-            TLB_HIT,
-            TLB_MISS,
-            PAGE_WALK,
-            UNDEFINED
-        };
+    void takeOverFrom(BaseTLB *otlb) override;

-        bool is_stage2() {
-            return isStage2;
-        }
+    void setTestInterface(SimObject *ti);

-    private:
+    TableWalker *getTableWalker() { return tableWalker; }

-        // Cached registers
-        Addr  ttbr0_el1;
-        Addr  ttbr1_el1;
-        Addr  vttbr_el2;
+    void setMMU(MMU*, MasterID);

-        bool stage2Req;      // Whether a stage 2 lookup is also required
-        bool directToStage2; // Whether all translation requests should be
-                             // routed directly to the stage 2 TLB
+    int getsize() const { return size; }

-        CPSR cpsr;
-        bool aarch64;
-        ExceptionLevel aarch64EL;
-        SCTLR sctlr;
-        SCR scr;
-        bool isPriv;
-        bool isSecure;
-        bool isHyp;
-        TTBCR ttbcr;
-        HTCR htcr;
-        uint16_t asid;
-        uint8_t vmid;
-        PRRR prrr;
-        NMRR nmrr;
-        HCR hcr;
-        uint64_t mair;
-        uint64_t hcr_el2;
-        uint32_t dacr;
-        ContextID miscRegContext;
-        bool miscRegValid;
-        TLB::ArmTranslationType curTranType;
+    /** Reset the entire TLB
+     * @param secure_lookup if the operation affects the secure world
+     */
+    void flushAllSecurity(bool secure_lookup, uint8_t target_el,
+                          bool ignore_el = false);

-        // Cached copies of system-level properties
-        bool haveLPAE;
-        bool haveVirtualization;
-        bool haveLargeAsid64;
+ /** Remove all entries in the non secure world, depending on whether they
+     *  were allocated in hyp mode or not
+     * @param hyp if the opperation affects hyp mode
+     */
+    void flushAllNs(bool hyp, uint8_t target_el, bool ignore_el = false);

-    protected:

-        void updateMiscReg(ThreadContext *tc,
-                           ArmTranslationType tranType = NormalTran);
+    /** Reset the entire TLB. Used for CPU switching to prevent stale
+     * translations after multiple switches
+     */
+    void flushAll() override
+    {
+        flushAllSecurity(false, 0, true);
+        flushAllSecurity(true, 0, true);
+    }

-    public:
+    /** Remove any entries that match both a va and asn
+     * @param mva virtual address to flush
+     * @param asn contextid/asn to flush on match
+     * @param secure_lookup if the operation affects the secure world
+     */
+    void flushMvaAsid(Addr mva, uint64_t asn, bool secure_lookup,
+                      uint8_t target_el);

-        class CpuSidePort : public SlavePort
-        {
-            public:
- CpuSidePort(const std::string &_name, TLB *_tlb, PortID _index)
-                    : SlavePort(_name, _tlb), tlb(_tlb), index(_index){}
+    /** Remove any entries that match the asn
+     * @param asn contextid/asn to flush on match
+     * @param secure_lookup if the operation affects the secure world
+     */
+    void flushAsid(uint64_t asn, bool secure_lookup, uint8_t target_el);

-            protected:
-                TLB *tlb;
-                int index;
+    /** Remove all entries that match the va regardless of asn
+     * @param mva address to flush from cache
+     * @param secure_lookup if the operation affects the secure world
+     * @param hyp if the operation affects hyp mode
+     */
+ void flushMva(Addr mva, bool secure_lookup, bool hyp, uint8_t target_el);

-                virtual bool recvTimingReq(PacketPtr pkt);
-                virtual Tick recvAtomic(PacketPtr pkt);
-                virtual void recvFunctional(PacketPtr pkt) { };
-                virtual void recvRangeChange() { };
-                virtual void recvReqRetry();
-                virtual void recvRespRetry();
-                virtual AddrRangeList getAddrRanges() const
-                {
-                    AddrRangeList range;
-                    return range;
-                }
-        };
+    /**
+     * Invalidate all entries in the stage 2 TLB that match the given ipa
+     * and the current VMID
+     * @param ipa the address to invalidate
+     * @param secure_lookup if the operation affects the secure world
+     * @param hyp if the operation affects hyp mode
+     */
+    void flushIpaVmid(Addr ipa, bool secure_lookup, bool hyp,
+                      uint8_t target_el);

-        class MemSidePort : public MasterPort
-        {
-            public:
- MemSidePort(const std::string &_name, TLB *_tlb, PortID _index)
-                    : MasterPort(_name, _tlb), tlb(_tlb), index(_index){}
+    Fault trickBoxCheck(const RequestPtr &req, Mode mode,
+                        TlbEntry::DomainType domain);

-                std::deque<PacketPtr> retries;
-
-            protected:
-                TLB *tlb;
-                int index;
-
-                virtual bool recvTimingResp(PacketPtr pkt);
-                virtual Tick recvAtomic(PacketPtr pkt);
-                virtual void recvFunctional(PacketPtr pkt) { };
-                virtual void recvRangeChange() { };
-                virtual void recvReqRetry();
-        };
-
-        std::vector<CpuSidePort*> cpuSidePort;
-        MemSidePort* memSidePort;
-
-        class TLBEvent;
-
-        struct TranslationState
-        {
-            /** Pointer to the TLBRecord used in the stage 1 translation */
-            TLBRecordPtr s1;
-            /** Pointer to the TLBRecord used in the stage 2 translation */
-            TLBRecordPtr s2;
-
-            bool timing;
-            bool functional;
-
-            RequestPtr req;
-            ThreadContext *tc;
-            BaseTLB::Mode mode;
-            ArmTranslationType tranType;
-
-            Addr vaddress;
-            Addr ipaddress;
-            Addr s1_physaddr;
-            Addr s2_physaddr;
-            AccType acctype;
-            bool wasaligned;
-            bool hwupdatewalk;
-            bool s2fs1walk;
-            int size;
-            ExceptionLevel aarch64EL;
-
-            bool aarch64;
-            bool isHyp;
-            bool _isPriv;
-            bool isSecure;
-            bool stage2Req;
-            bool usingLongDescFormat;
-
-            uint16_t asid;
-            uint8_t  vmid;
-
-            bool delayed;
-            bool finished;
-            bool s1_enabled;
-            bool s2_enabled;
-            bool stage2lookup;
-            bool stage2lookupDone;
-
-            bool permissioncheck;
-            bool domaincheck;
-
-            TlbEntry::DomainType domain;
-
-            /** Cached system registers */
-            CPSR cpsr;
-            SCTLR sctlr;
-            SCR scr;
-            union {
-                TTBCR ttbcr;
-                TCR tcr;
-            };
-            HTCR htcr;
-            Addr ttbr0_el1;
-            Addr ttbr1_el1;
-            uint64_t mair;
-            uint32_t dacr;
-            HCR hcr;
-            PRRR prrr;
-            NMRR nmrr;
-
-            Fault fault;
-            ArmFault::TranMethod tranMethod;
-
-            /** Flag to indicate if we are returning from a page walk */
-            bool fromPTW;
-
-            /** Pointer to the TLB starting the translation */
-            TLB *tlb;
- /** Pointer to the Stage 2 TLB to be used for a stage 2 lookup */
-            TLB *stage2Tlb;
-
-            /** Remember the port this came from */
-            std::vector<SlavePort*>ports;
-
-            Translation *translation;
-
-            Cycles latency;
-
- /** Pointer to the TLB entry in a lower level to use in a fill */
-            TlbEntryPtr s1te;
-            TlbEntryPtr s2te;
-
-            Tick start;
-            Addr pc;
-
-            Addr ptw_desc_addr;
-            uint64_t ptw_desc_value;
-
-            /** Flag indicating if we are returning from a walk which was
-             *  squashed */
-            bool walkSquashed;
-
-            void tickLimitReached();
-            EventFunctionWrapper* tickLimitReachedEvent;
-
-            bool isFetch() {
-                return (mode == Execute);
-            }
-            bool isPrefetch() {
-                return req->isPrefetch();
-            }
-            bool isWrite() {
-                return (mode == Write);
-            }
-            bool accessIsPrivileged() {
- return (_isPriv && !(req->getFlags() & ArmFlags::UserMode));
-            }
-
-            // Return TRUE if the request is of the specified 'AccType'
-            // FALSE otherwise
-            bool hasAcctype(AccType);
-
-            bool isPartial;
-
-            TranslationState(TLB*);
-            ~TranslationState();
-        };
-
-        typedef std::shared_ptr<TranslationState> TranslationStatePtr;
-
-        // Wrapper struct to use with the send/recv functions. Only the
- // SenderState class can be used to transfer information so we need a
-        // struct that can be cast to its type
-        struct TranslationSender : public Packet::SenderState
-        {
-            TranslationStatePtr tran;
-
-            TranslationSender(TranslationStatePtr _tran) : tran(_tran) {
-            }
-        };
-
-        // This function will be called N cycles after the lookup depending
- // if it was hit or miss and take the aproppiate action. In a TLB miss
-        // the request will be sent to the next TLB level (if any) or issue
-        // a table walk if this is the last TLB level
-        void lookupReturn(TranslationStatePtr, LookupStatus);
-
-        // Finalize the translation setting the request physical address
-        Fault finalizeTranslation(TranslationStatePtr);
-
-        class TLBEvent : public Event
-        {
-            private:
-                TLB *tlb;
-                TranslationStatePtr tran;
-                LookupStatus status;
-
-            public:
-                TLBEvent(TLB*, TranslationStatePtr, LookupStatus);
-                void process();
-                void updateStatus(LookupStatus _status) {
-                    status = _status;
-                }
-                TLB* getTLB() {
-                    return tlb;
-                }
-                TranslationStatePtr getTranslation() {
-                    return tran;
-                }
-                Addr getPC() {
-                    return tran->req->getPC();
-                }
-        };
-
-        std::vector<TLBEvent*> translationReturnEvent;
-
-        // Schedule event for the specified address and lookup status
-        void scheduleEvent(TranslationStatePtr, LookupStatus);
-
-        void cleanupEvent(TLBEvent*);
-
-        void sendTimingResponse(TranslationStatePtr);
-
-        BaseMasterPort&
-        getMasterPort(const std::string &if_name, PortID idx) override;
-        BaseSlavePort&
-        getSlavePort(const std::string &if_name, PortID idx) override;
-
-        void setTestInterface(SimObject *ti);
-
-        void setMMU(MMU*, MasterID);
-
-        MMU* getMMU() { return mmu; }
-
-        inline void invalidateMiscReg() { miscRegValid = false; }
-
-        bool checkELMatch(uint8_t, uint8_t, bool);
-
-        /** Reset the entire TLB
-         * @param secure_lookup if the operation affects the secure world
-         */
-        void flushAllSecurity(bool, uint8_t, bool ignore_el = false);
-
- /** Remove all entries in the non secure world, depending on whether
-         *  they were allocated in hyp mode or not
-         * @param hyp if the opperation affects hyp mode
-         */
-        void flushAllNs(bool, uint8_t, bool ignore_el = false);
-
-        /** Reset the entire TLB. Used for CPU switching to prevent stale
-         * translations after multiple switches
-         */
-        void flushAll() override
-        {
-            flushAllSecurity(false, 0, true);
-            flushAllSecurity(true, 0, true);
-        }
-
-        /** Remove any entries that match both a va and asn
-         * @param mva virtual address to flush
-         * @param asn contextid/asn to flush on match
-         * @param secure_lookup if the operation affects the secure world
-         */
-        void flushMvaAsid(Addr, uint64_t, bool, uint8_t);
-
-        /** Remove any entries that match the asn
-         * @param asn contextid/asn to flush on match
-         * @param secure_lookup if the operation affects the secure world
-         */
- void flushAsid(uint64_t asn, bool secure_lookup, uint8_t target_el);
-
-        /** Remove all entries that match the va regardless of asn
-         * @param mva address to flush from cache
-         * @param secure_lookup if the operation affects the secure world
-         * @param hyp if the operation affects hyp mode
-         */
-        void flushMva(Addr mva, bool secure_lookup, bool hyp,
-                uint8_t target_el);
-
-        void _flushMva(Addr, uint64_t, bool, bool, bool, uint8_t);
+    Fault walkTrickBoxCheck(Addr pa, bool is_secure, Addr va, Addr sz,
+                            bool is_exec, bool is_write,
+                            TlbEntry::DomainType domain,
+                            LookupLevel lookup_level);

-        /**
- * Invalidate all entries in the stage 2 TLB that match the given ipa
-         * and the current VMID
-         * @param ipa the address to invalidate
-         * @param secure_lookup if the operation affects the secure world
-         * @param hyp if the operation affects hyp mode
-         */
-        void flushIpaVmid(Addr ipa, bool secure_lookup, bool hyp,
-                uint8_t target_el);
+    void printTlb() const;

-        void demapPage(Addr vaddr, uint64_t asn) override
-        {
-            // needed for x86 only
-            panic("%s: not implemented", __func__);
-        }
+    void demapPage(Addr vaddr, uint64_t asn) override
+    {
+        // needed for x86 only
+        panic("demapPage() is not implemented.\n");
+    }

-        /**
-         * Do a functional lookup on the TLB (for debugging)
-         * and don't modify any internal state
-         * @param tc thread context to get the context id from
-         * @param vaddr virtual address to translate
-         * @param pa returned physical address
-         * @return if the translation was successful
-         */
- bool translateFunctional(ThreadContext *tc, Addr vaddr, Addr &paddr);
+    /**
+     * Do a functional lookup on the TLB (for debugging)
+     * and don't modify any internal state
+     * @param tc thread context to get the context id from
+     * @param vaddr virtual address to translate
+     * @param pa returned physical address
+     * @return if the translation was successful
+     */
+    bool translateFunctional(ThreadContext *tc, Addr vaddr, Addr &paddr);

-        /**
-         * Do a functional lookup on the TLB (for checker cpu) that
- * behaves like a normal lookup without modifying any page table state.
-         */
-        Fault translateFunctional(const RequestPtr &req, ThreadContext *tc,
+    /**
+     * Do a functional lookup on the TLB (for checker cpu) that
+     * behaves like a normal lookup without modifying any page table state.
+     */
+    Fault translateFunctional(const RequestPtr &req, ThreadContext *tc,
             Mode mode, ArmTranslationType tranType);
-        Fault translateFunctional(
-            const RequestPtr &req, ThreadContext *tc, Mode mode) override
-        {
-            return translateFunctional(req, tc, mode, NormalTran);
-        }
+    Fault
+    translateFunctional(const RequestPtr &req,
+                        ThreadContext *tc, Mode mode) override
+    {
+        return translateFunctional(req, tc, mode, NormalTran);
+    }

- Fault translateFs(const RequestPtr &req, ThreadContext *tc, Mode mode,
-            Translation *translation, bool &delay, bool timing,
-            ArmTranslationType tranType, bool functional = false);
+ /** Accessor functions for memory attributes for last accessed TLB entry
+     */
+    void
+    setAttr(uint64_t attr)
+    {
+        _attr = attr;
+    }

- Fault translateSe(const RequestPtr &req, ThreadContext *tc, Mode mode,
+    uint64_t
+    getAttr() const
+    {
+        return _attr;
+    }
+
+    Fault translateFs(const RequestPtr &req, ThreadContext *tc, Mode mode,
+            Translation *translation, bool &delay,
+ bool timing, ArmTranslationType tranType, bool functional = false);
+    Fault translateSe(const RequestPtr &req, ThreadContext *tc, Mode mode,
             Translation *translation, bool &delay, bool timing);
-
-        Fault translateAtomic(const RequestPtr &req, ThreadContext *tc,
- Mode mode, ArmTranslationType tranType, TLB::TranslationStatePtr);
-
-        Fault translateAtomic(
-            const RequestPtr &req, ThreadContext *tc, Mode mode) override
-        {
-            return translateAtomic(req, tc, mode, NormalTran, NULL);
-        }
-
-        void translateTiming(const RequestPtr &req, ThreadContext *tc,
- Translation *translation, Mode mode, ArmTranslationType tranType);
-
-        void translateTiming(
- const RequestPtr &req, ThreadContext *tc, Translation *translation,
-            Mode mode) override
-        {
-            translateTiming(req, tc, translation, mode, NormalTran);
-        }
-
-        Fault translateComplete(const RequestPtr &req, ThreadContext *tc,
+ Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, Mode mode,
+            ArmTranslationType tranType);
+    Fault
+    translateAtomic(const RequestPtr &req,
+                    ThreadContext *tc, Mode mode) override
+    {
+        return translateAtomic(req, tc, mode, NormalTran);
+    }
+    void translateTiming(
+            const RequestPtr &req, ThreadContext *tc,
+            Translation *translation, Mode mode,
+            ArmTranslationType tranType);
+    void
+    translateTiming(const RequestPtr &req, ThreadContext *tc,
+                    Translation *translation, Mode mode) override
+    {
+        translateTiming(req, tc, translation, mode, NormalTran);
+    }
+    Fault translateComplete(const RequestPtr &req, ThreadContext *tc,
Translation *translation, Mode mode, ArmTranslationType tranType,
             bool callFromS2);
+    Fault finalizePhysical(
+            const RequestPtr &req,
+            ThreadContext *tc, Mode mode) const override;

-        Fault finalizePhysical(
- const RequestPtr &req, ThreadContext *tc, Mode mode) const override
-        {
-            panic("%s: not implemented", __func__);
-            return 0;
+    void drainResume() override;
+
+    void regStats() override;
+
+    void regProbePoints() override;
+
+    // Caching misc register values here.
+    // Writing to misc registers needs to invalidate them.
+    // translateFunctional/translateSe/translateFs checks if they are
+    // invalid and call updateMiscReg if necessary.
+protected:
+    CPSR cpsr;
+    bool aarch64;
+    ExceptionLevel aarch64EL;
+    SCTLR sctlr;
+    SCR scr;
+    bool isPriv;
+    bool isSecure;
+    bool isHyp;
+    TTBCR ttbcr;
+    uint16_t asid;
+    uint8_t vmid;
+    PRRR prrr;
+    NMRR nmrr;
+    HCR hcr;
+    uint32_t dacr;
+    bool miscRegValid;
+    ContextID miscRegContext;
+    ArmTranslationType curTranType;
+
+    // Cached copies of system-level properties
+    bool haveLPAE;
+    bool haveVirtualization;
+    bool haveLargeAsid64;
+
+    AddrRange m5opRange;
+
+    Addr  ttbr0_el1;
+    Addr  ttbr1_el1;
+    Addr  vttbr_el2;
+
+    HTCR htcr;
+    uint64_t mair;
+    uint64_t hcr_el2;
+
+    void updateMiscReg(ThreadContext *tc,
+                       ArmTranslationType tranType = NormalTran);
+
+public:
+    const Params *
+    params() const
+    {
+        return dynamic_cast<const Params *>(_params);
+    }
+    inline void invalidateMiscReg() { miscRegValid = false; }
+
+private:
+    /** Remove any entries that match both a va and asn
+     * @param mva virtual address to flush
+     * @param asn contextid/asn to flush on match
+     * @param secure_lookup if the operation affects the secure world
+     * @param hyp if the operation affects hyp mode
+     * @param ignore_asn if the flush should ignore the asn
+     */
+    void _flushMva(Addr mva, uint64_t asn, bool secure_lookup,
+                   bool hyp, bool ignore_asn, uint8_t target_el);
+
+ bool checkELMatch(uint8_t target_el, uint8_t tentry_el, bool ignore_el);
+
+  public: /* Testing */
+    Fault testTranslation(const RequestPtr &req, Mode mode,
+                          TlbEntry::DomainType domain);
+    Fault testWalk(Addr pa, Addr size, Addr va, bool is_secure, Mode mode,
+                   TlbEntry::DomainType domain,
+                   LookupLevel lookup_level);
+
+    enum LookupStatus {
+        TLB_HIT,
+        TLB_MISS,
+        PAGE_WALK,
+        UNDEFINED
+    };
+
+    bool is_stage2() {
+        return isStage2;
+    }
+
+    class CpuSidePort : public SlavePort
+    {
+        public:
+            CpuSidePort(const std::string &_name, TLB *_tlb, PortID _index)
+                : SlavePort(_name, _tlb), tlb(_tlb), index(_index){}
+
+        protected:
+            TLB *tlb;
+            int index;
+
+            virtual bool recvTimingReq(PacketPtr pkt);
+            virtual Tick recvAtomic(PacketPtr pkt);
+            virtual void recvFunctional(PacketPtr pkt) { };
+            virtual void recvRangeChange() { };
+            virtual void recvReqRetry();
+            virtual void recvRespRetry();
+            virtual AddrRangeList getAddrRanges() const
+            {
+                AddrRangeList range;
+                return range;
+            }
+    };
+
+    class MemSidePort : public MasterPort
+    {
+        public:
+            MemSidePort(const std::string &_name, TLB *_tlb, PortID _index)
+                : MasterPort(_name, _tlb), tlb(_tlb), index(_index){}
+
+            std::deque<PacketPtr> retries;
+
+        protected:
+            TLB *tlb;
+            int index;
+
+            virtual bool recvTimingResp(PacketPtr pkt);
+            virtual Tick recvAtomic(PacketPtr pkt);
+            virtual void recvFunctional(PacketPtr pkt) { };
+            virtual void recvRangeChange() { };
+            virtual void recvReqRetry();
+    };
+
+    std::vector<CpuSidePort*> cpuSidePort;
+    MemSidePort* memSidePort;
+
+    class TLBEvent;
+
+    struct TranslationState
+    {
+        /** Pointer to the TLBRecord used in the stage 1 translation */
+        TLBRecordPtr s1;
+        /** Pointer to the TLBRecord used in the stage 2 translation */
+        TLBRecordPtr s2;
+
+        bool timing;
+        bool functional;
+
+        RequestPtr req;
+        ThreadContext *tc;
+        BaseTLB::Mode mode;
+        ArmTranslationType tranType;
+
+        Addr vaddress;
+        Addr ipaddress;
+        Addr s1_physaddr;
+        Addr s2_physaddr;
+        AccType acctype;
+        bool wasaligned;
+        bool hwupdatewalk;
+        bool s2fs1walk;
+        int size;
+        ExceptionLevel aarch64EL;
+
+        bool aarch64;
+        bool isHyp;
+        bool _isPriv;
+        bool isSecure;
+        bool stage2Req;
+        bool usingLongDescFormat;
+
+        uint16_t asid;
+        uint8_t  vmid;
+
+        bool delayed;
+        bool finished;
+        bool s1_enabled;
+        bool s2_enabled;
+        bool stage2lookup;
+        bool stage2lookupDone;
+
+        bool permissioncheck;
+        bool domaincheck;
+
+        TlbEntry::DomainType domain;
+
+        /** Cached system registers */
+        CPSR cpsr;
+        SCTLR sctlr;
+        SCR scr;
+        union {
+            TTBCR ttbcr;
+            TCR tcr;
+        };
+        HTCR htcr;
+        Addr ttbr0_el1;
+        Addr ttbr1_el1;
+        uint64_t mair;
+        uint32_t dacr;
+        HCR hcr;
+        PRRR prrr;
+        NMRR nmrr;
+
+        Fault fault;
+        ArmFault::TranMethod tranMethod;
+
+        /** Flag to indicate if we are returning from a page walk */
+        bool fromPTW;
+
+        /** Pointer to the TLB starting the translation */
+        TLB *tlb;
+        /** Pointer to the Stage 2 TLB to be used for a stage 2 lookup */
+        TLB *stage2Tlb;
+
+        /** Remember the port this came from */
+        std::vector<SlavePort*>ports;
+
+        Translation *translation;
+
+        Cycles latency;
+
+        /** Pointer to the TLB entry in a lower level to use in a fill */
+        TlbEntryPtr s1te;
+        TlbEntryPtr s2te;
+
+        Tick start;
+        Addr pc;
+
+        Addr ptw_desc_addr;
+        uint64_t ptw_desc_value;
+
+        /** Flag indicating if we are returning from a walk which was
+         *  squashed */
+        bool walkSquashed;
+
+        void tickLimitReached();
+        EventFunctionWrapper* tickLimitReachedEvent;
+
+        bool isFetch() {
+            return (mode == Execute);
+        }
+        bool isPrefetch() {
+            return req->isPrefetch();
+        }
+        bool isWrite() {
+            return (mode == Write);
+        }
+        bool accessIsPrivileged() {
+            return (_isPriv && !(req->getFlags() & ArmFlags::UserMode));
         }

-        static ExceptionLevel tranTypeEL(CPSR, ArmTranslationType);
-
-        void drainResume() override;
-
-        void regStats() override;
-
-        /* Accessor functions for memory attributes for last accessed
-         * TLB entry
-         */
-        void
-        setAttr(uint64_t attr)
-        {
-            _attr = attr;
-        }
-
-        uint64_t
-        getAttr() const
-        {
-            return _attr;
-        }
-
-        void takeOverFrom(BaseTLB *otlb) override
-        {
-            panic("%s: not implemented", __func__);
-        }
-
-        typedef ArmTLBParams Params;
-        TLB(const Params *p);
-        virtual ~TLB();
-
-        // Update the misc registers in the TranslationState structure
-        void updateTranslationRegisters(TranslationStatePtr);
-
-    protected:
-
-        Fault permissionFault(TranslationStatePtr);
-
-        void stage2lookup(TranslationStatePtr);
-
-        // Creates a basic access descriptor
-        AccessDescriptor* createAccessDescriptor(AccType);
- AccessDescriptor* createAccessDescriptorPTW(AccType, bool, bool, int);
-
- // Perform a stage 1 translation. It will use the cached values in the
-        // TLB if a valid entry is found, issue a table walk if not
-        void firstStageTranslate32(TranslationStatePtr);
-        void firstStageTranslate64(TranslationStatePtr);
-
- // Perform a stage 2 translation. It will use the cached values in the
-        // TLB if a valid entry is found, issue a table walk if not
-        void secondStageTranslate(TranslationStatePtr);
-
- // Called for stage 1 translations when translation is enabled. Will
-        // launch a page walk if miss in all TLB levels
-        void translateAddressOn(TranslationStatePtr);
-
-        // Called for stage 1 translations when translation is disabled to
-        // supply a default translation
-        void translateAddressS1Off32(TranslationStatePtr);
-        void translateAddressS1Off64(TranslationStatePtr);
-
-        Fault checkPermissions64(TranslationStatePtr);
-        Fault checkPermissions(TranslationStatePtr);
-
-        // Permission checking from AArch64 stage 1 and 2 translations
-        Fault checkS1Permission32(TranslationStatePtr);
-        Fault checkS1Permission64(TranslationStatePtr);
-        Fault checkS2Permission32(TranslationStatePtr);
-        Fault checkS2Permission64(TranslationStatePtr);
-
-        // Domain checking for AArch32 stage 1 translations
-        Fault checkDomain(TranslationStatePtr);
-
-        // Combines the address descriptors from stage 1 and stage 2
-        AddressDescriptorPtr combineS1S2Desc(AddressDescriptorPtr,
-                                    AddressDescriptorPtr);
-        // Combines device types from stage 1 and stage 2
-        DeviceType combineS1S2Device(DeviceType, DeviceType);
-        MemAttrHints combineS1S2AttrHints(MemAttrHints, MemAttrHints);
-
-    public:
-
- // Return a TRUE if a valid entry for the translation is found in the
-        // TLB and update the record field in TranslationState structure.
+        // Return TRUE if the request is of the specified 'AccType'
         // FALSE otherwise
-        bool lookup(TranslationStatePtr, bool,
-            bool update_alloc=true, bool from_ptw=false);
+        bool hasAcctype(AccType);

-        // Insert an entry for the specified address
-        void insert(TranslationStatePtr, bool from_ptw=false);
+        bool isPartial;

- // Supply default values for memory attributes, including overriding
-        // the shareability attributes for Device and Non-cacheable memory
-        // types
-        static void memAttrDefaults(MemoryAttributes*);
+        TranslationState(TLB*);
+        ~TranslationState();
+    };

-        static
-        AddressDescriptorPtr initAddressDescriptor()
-        {
-            AddressDescriptorPtr d = std::make_shared<AddressDescriptor>();
-            d->fault = NoFault;
-            d->memattrs = new MemoryAttributes;
-            return d;
+    typedef std::shared_ptr<TranslationState> TranslationStatePtr;
+
+    // Wrapper struct to use with the send/recv functions. Only the
+    // SenderState class can be used to transfer information so we need a
+    // struct that can be cast to its type
+    struct TranslationSender : public Packet::SenderState
+    {
+        TranslationStatePtr tran;
+
+        TranslationSender(TranslationStatePtr _tran) : tran(_tran) {
         }
+    };

-        static
-        DescriptorUpdate* initDescriptorUpdate()
-        {
-            DescriptorUpdate *d = new DescriptorUpdate;
-            d->AF = false;
-            d->AP = false;
-            d->descaddr = initAddressDescriptor();
-            return d;
-        }
+    Fault checkPermissions(TranslationStatePtr);
+    Fault checkPermissions64(TranslationStatePtr);

-        static
-        TLBRecordPtr initTLBRecord()
-        {
-            TLBRecordPtr r = std::make_shared<TLBRecord>();
-            r->descupdate = initDescriptorUpdate();
-            r->addrdesc = initAddressDescriptor();
-            return r;
-        }
+    // This function will be called N cycles after the lookup depending
+    // if it was hit or miss and take the aproppiate action. In a TLB miss
+    // the request will be sent to the next TLB level (if any) or issue
+    // a table walk if this is the last TLB level
+    void lookupReturn(TranslationStatePtr, LookupStatus);

-        static
-        TLBRecordPtr initTLBRecord(AddressDescriptorPtr addrdesc)
-        {
-            TLBRecordPtr r = std::make_shared<TLBRecord>();
-            r->descupdate = initDescriptorUpdate();
-            r->addrdesc = addrdesc;
-            return r;
-        }
+    // Finalize the translation setting the request physical address
+    Fault finalizeTranslation(TranslationStatePtr);

-        TLB* getStage2TLB() {
-            return stage2Tlb;
-        }
+    class TLBEvent : public Event
+    {
+        private:
+            TLB *tlb;
+            TranslationStatePtr tran;
+            LookupStatus status;

-        void printTLB();
+        public:
+            TLBEvent(TLB*, TranslationStatePtr, LookupStatus);
+            void process();
+            void updateStatus(LookupStatus _status) {
+                status = _status;
+            }
+            TLB* getTLB() {
+                return tlb;
+            }
+            TranslationStatePtr getTranslation() {
+                return tran;
+            }
+            Addr getPC() {
+                return tran->req->getPC();
+            }
+    };

-      public: /* Testing */
+    std::vector<TLBEvent*> translationReturnEvent;

-        Fault testTranslation(RequestPtr req, Mode mode,
-                              TlbEntry::DomainType domain);
- Fault testWalk(Addr pa, Addr size, Addr va, bool is_secure, Mode mode,
-                       TlbEntry::DomainType domain,
-                       LookupLevel lookup_level);
+    // Schedule event for the specified address and lookup status
+    void scheduleEvent(TranslationStatePtr, LookupStatus);
+
+    void cleanupEvent(TLBEvent*);
+
+    void sendTimingResponse(TranslationStatePtr);
+
+    BaseMasterPort&
+    getMasterPort(const std::string &if_name, PortID idx) override;
+    BaseSlavePort&
+    getSlavePort(const std::string &if_name, PortID idx) override;
+
+    MMU* getMMU() { return mmu; }
+
+    typedef ArmTLBParams Params;
+
+    // Update the misc registers in the TranslationState structure
+    void updateTranslationRegisters(TranslationStatePtr);
+
+protected:
+
+    Fault permissionFault(TranslationStatePtr);
+
+    void stage2lookup(TranslationStatePtr);
+
+    // Creates a basic access descriptor
+    AccessDescriptor* createAccessDescriptor(AccType);
+    AccessDescriptor* createAccessDescriptorPTW(AccType, bool, bool, int);
+
+    // Perform a stage 1 translation. It will use the cached values in the
+    // TLB if a valid entry is found, issue a table walk if not
+    void firstStageTranslate32(TranslationStatePtr);
+    void firstStageTranslate64(TranslationStatePtr);
+
+    // Perform a stage 2 translation. It will use the cached values in the
+    // TLB if a valid entry is found, issue a table walk if not
+    void secondStageTranslate(TranslationStatePtr);
+
+    // Called for stage 1 translations when translation is enabled. Will
+    // launch a page walk if miss in all TLB levels
+    void translateAddressOn(TranslationStatePtr);
+
+    // Called for stage 1 translations when translation is disabled to
+    // supply a default translation
+    void translateAddressS1Off32(TranslationStatePtr);
+    void translateAddressS1Off64(TranslationStatePtr);
+
+    // Permission checking from AArch64 stage 1 and 2 translations
+    Fault checkS1Permission32(TranslationStatePtr);
+    Fault checkS1Permission64(TranslationStatePtr);
+    Fault checkS2Permission32(TranslationStatePtr);
+    Fault checkS2Permission64(TranslationStatePtr);
+
+    // Domain checking for AArch32 stage 1 translations
+    Fault checkDomain(TranslationStatePtr);
+
+    // Combines the address descriptors from stage 1 and stage 2
+    AddressDescriptorPtr combineS1S2Desc(AddressDescriptorPtr,
+                                AddressDescriptorPtr);
+    // Combines device types from stage 1 and stage 2
+    DeviceType combineS1S2Device(DeviceType, DeviceType);
+    MemAttrHints combineS1S2AttrHints(MemAttrHints, MemAttrHints);
+
+public:
+
+    // Return a TRUE if a valid entry for the translation is found in the
+    // TLB and update the record field in TranslationState structure.
+    // FALSE otherwise
+    bool lookup(TranslationStatePtr, bool,
+        bool update_alloc=true, bool from_ptw=false);
+
+    // Insert an entry for the specified address
+    void insert(TranslationStatePtr, bool from_ptw=false);
+
+    // Supply default values for memory attributes, including overriding
+    // the shareability attributes for Device and Non-cacheable memory
+    // types
+    static void memAttrDefaults(MemoryAttributes*);
+
+    static
+    AddressDescriptorPtr initAddressDescriptor()
+    {
+        AddressDescriptorPtr d = std::make_shared<AddressDescriptor>();
+        d->fault = NoFault;
+        d->memattrs = new MemoryAttributes;
+        return d;
+    }
+
+    static
+    DescriptorUpdate* initDescriptorUpdate()
+    {
+        DescriptorUpdate *d = new DescriptorUpdate;
+        d->AF = false;
+        d->AP = false;
+        d->descaddr = initAddressDescriptor();
+        return d;
+    }
+
+    static
+    TLBRecordPtr initTLBRecord()
+    {
+        TLBRecordPtr r = std::make_shared<TLBRecord>();
+        r->descupdate = initDescriptorUpdate();
+        r->addrdesc = initAddressDescriptor();
+        return r;
+    }
+
+    static
+    TLBRecordPtr initTLBRecord(AddressDescriptorPtr addrdesc)
+    {
+        TLBRecordPtr r = std::make_shared<TLBRecord>();
+        r->descupdate = initDescriptorUpdate();
+        r->addrdesc = addrdesc;
+        return r;
+    }
+
+    TLB* getStage2TLB() {
+        return stage2Tlb;
+    }
 };

 template<typename T>
diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc
index bf22c34..d30d54a 100644
--- a/src/arch/arm/utility.cc
+++ b/src/arch/arm/utility.cc
@@ -184,7 +184,7 @@
         scr, tc->readMiscReg(MISCREG_CPSR));
 }

-bool
+inline bool
 isSecureBelowEL3(ThreadContext *tc)
 {
     SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
@@ -250,12 +250,6 @@
     return aarch32;
 }

-bool
-ELUsingAArch32(ThreadContext *tc, ExceptionLevel el)
-{
-    return ELIs32(tc, el);
-}
-
 std::pair<bool, bool>
 ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el)
 {
diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh
index dca1a79..3369698 100644
--- a/src/arch/arm/utility.hh
+++ b/src/arch/arm/utility.hh
@@ -175,8 +175,6 @@
 std::pair<bool, bool>
 ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el);

-bool ELUsingAArch32(ThreadContext *tc, ExceptionLevel el);
-
 bool ELIs32(ThreadContext *tc, ExceptionLevel el);

 bool ELIs64(ThreadContext *tc, ExceptionLevel el);
@@ -248,7 +246,7 @@
  * Differs from inSecureState in that it ignores the current EL
  * or Mode in considering security state.
  */
-bool isSecureBelowEL3(ThreadContext *tc);
+inline bool isSecureBelowEL3(ThreadContext *tc);

 bool longDescFormatInUse(ThreadContext *tc);


--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/14575
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: Ie6c4ae604f956ba93c2db535fc60f4e94b1379eb
Gerrit-Change-Number: 14575
Gerrit-PatchSet: 1
Gerrit-Owner: Ivan Pizarro <ivan.piza...@metempsy.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to