/*
 * Copyright (c) 2010-2016, 2019, 2021 Arm Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __ARCH_ARM_TABLE_WALKER_HH__
#define __ARCH_ARM_TABLE_WALKER_HH__

#include <list>

#include "arch/arm/faults.hh"
#include "arch/arm/mmu.hh"
#include "arch/arm/regs/misc.hh"
#include "arch/arm/system.hh"
#include "arch/arm/tlb.hh"
#include "arch/arm/types.hh"
#include "arch/generic/mmu.hh"
#include "mem/packet_queue.hh"
#include "mem/qport.hh"
#include "mem/request.hh"
#include "params/ArmTableWalker.hh"
#include "sim/clocked_object.hh"
#include "sim/eventq.hh"

namespace gem5
{

class ThreadContext;

namespace ArmISA {
class Translation;
class TLB;

class TableWalker : public ClockedObject
{
    using LookupLevel = enums::ArmLookupLevel;

  public:
    class WalkerState;

    class DescriptorBase
    {
      public:
        DescriptorBase() : lookupLevel(LookupLevel::L0) {}

        /** Current lookup level for this descriptor */
        LookupLevel lookupLevel;

        virtual Addr pfn() const = 0;
        virtual TlbEntry::DomainType domain() const = 0;
        virtual bool xn() const = 0;
        virtual uint8_t ap() const = 0;
        virtual bool global(WalkerState *currState) const = 0;
        virtual uint8_t offsetBits() const = 0;
        virtual bool secure(bool have_security, WalkerState *currState) const = 0;
        virtual std::string dbgHeader() const = 0;
        virtual uint64_t getRawData() const = 0;
        virtual uint8_t texcb() const
        {
            panic("texcb() not implemented for this class\n");
        }
        virtual bool shareable() const
        {
            panic("shareable() not implemented for this class\n");
        }
    };

    class L1Descriptor : public DescriptorBase
    {
      public:
        /** Type of page table entry ARM DDI 0406B: B3-8*/
        enum EntryType
        {
            Ignore,
            PageTable,
            Section,
            Reserved
        };

        /** The raw bits of the entry */
        uint32_t data;

        /** This entry has been modified (access flag set) and needs to be
         * written back to memory */
        bool _dirty;

        /** Default ctor */
        L1Descriptor() : data(0), _dirty(false)
        {
            lookupLevel = LookupLevel::L1;
        }

        uint64_t
        getRawData() const override
        {
            return (data);
        }

        std::string
        dbgHeader() const override
        {
            return "Inserting Section Descriptor into TLB\n";
        }

        uint8_t
        offsetBits() const override
        {
            return 20;
        }

        EntryType
        type() const
        {
            return (EntryType)(data & 0x3);
        }

        /** Is the page a Supersection (16 MiB)?*/
        bool
        supersection() const
        {
            return bits(data, 18);
        }

        /** Return the physcal address of the entry, bits in position*/
        Addr
        paddr() const
        {
            if (supersection())
                panic("Super sections not implemented\n");
            return mbits(data, 31, 20);
        }

        /** Return the physcal address of the entry, bits in position*/
        Addr
        paddr(Addr va) const
        {
            if (supersection())
                panic("Super sections not implemented\n");
            return mbits(data, 31, 20) | mbits(va, 19, 0);
        }

        /** Return the physical frame, bits shifted right */
        Addr
        pfn() const override
        {
            if (supersection())
                panic("Super sections not implemented\n");
            return bits(data, 31, 20);
        }

        /** Is the translation global (no asid used)? */
        bool
        global(WalkerState *currState) const override
        {
            return !bits(data, 17);
        }

        /** Is the translation not allow execution? */
        bool
        xn() const override
        {
            return bits(data, 4);
        }

        /** Three bit access protection flags */
        uint8_t
        ap() const override
        {
            return (bits(data, 15) << 2) | bits(data, 11, 10);
        }

        /** Domain Client/Manager: ARM DDI 0406B: B3-31 */
        TlbEntry::DomainType
        domain() const override
        {
            return static_cast<TlbEntry::DomainType>(bits(data, 8, 5));
        }

        /** Address of L2 descriptor if it exists */
        Addr
        l2Addr() const
        {
            return mbits(data, 31, 10);
        }

        /** Memory region attributes: ARM DDI 0406B: B3-32.
         * These bits are largly ignored by M5 and only used to
         * provide the illusion that the memory system cares about
         * anything but cachable vs. uncachable.
         */
        uint8_t
        texcb() const override
        {
            return bits(data, 2) | bits(data, 3) << 1 | bits(data, 14, 12) << 2;
        }

        /** If the section is shareable. See texcb() comment. */
        bool
        shareable() const override
        {
            return bits(data, 16);
        }

        /** Set access flag that this entry has been touched. Mark
         * the entry as requiring a writeback, in the future.
         */
        void
        setAp0()
        {
            data |= 1 << 10;
            _dirty = true;
        }

        /** This entry needs to be written back to memory */
        bool
        dirty() const
        {
            return _dirty;
        }

        /**
         * Returns true if this entry targets the secure physical address
         * map.
         */
        bool
        secure(bool have_security, WalkerState *currState) const override
        {
            if (have_security && currState->secureLookup) {
                if (type() == PageTable)
                    return !bits(data, 3);
                else
                    return !bits(data, 19);
            }
            return false;
        }
    };

    /** Level 2 page table descriptor */
    class L2Descriptor : public DescriptorBase
    {
      public:
        /** The raw bits of the entry. */
        uint32_t     data;
        L1Descriptor *l1Parent;

        /** This entry has been modified (access flag set) and needs to be
         * written back to memory */
        bool _dirty;

        /** Default ctor */
        L2Descriptor() : data(0), l1Parent(nullptr), _dirty(false)
        {
            lookupLevel = LookupLevel::L2;
        }

        L2Descriptor(L1Descriptor &parent) : data(0), l1Parent(&parent),
                                             _dirty(false)
        {
            lookupLevel = LookupLevel::L2;
        }

        uint64_t
        getRawData() const override
        {
            return (data);
        }

        std::string
        dbgHeader() const override
        {
            return "Inserting L2 Descriptor into TLB\n";
        }

        TlbEntry::DomainType
        domain() const override
        {
            return l1Parent->domain();
        }

        bool
        secure(bool have_security, WalkerState *currState) const override
        {
            return l1Parent->secure(have_security, currState);
        }

        uint8_t
        offsetBits() const override
        {
            return large() ? 16 : 12;
        }

        /** Is the entry invalid */
        bool
        invalid() const
        {
            return bits(data, 1, 0) == 0;
        }

        /** What is the size of the mapping? */
        bool
        large() const
        {
            return bits(data, 1) == 0;
        }

        /** Is execution allowed on this mapping? */
        bool
        xn() const override
        {
            return large() ? bits(data, 15) : bits(data, 0);
        }

        /** Is the translation global (no asid used)? */
        bool
        global(WalkerState *currState) const override
        {
            return !bits(data, 11);
        }

        /** Three bit access protection flags */
        uint8_t
        ap() const override
        {
           return bits(data, 5, 4) | (bits(data, 9) << 2);
        }

        /** Memory region attributes: ARM DDI 0406B: B3-32 */
        uint8_t
        texcb() const override
        {
            return large() ?
                (bits(data, 2) | (bits(data, 3) << 1) | (bits(data, 14, 12) << 2)) :
                (bits(data, 2) | (bits(data, 3) << 1) | (bits(data, 8, 6) << 2));
        }

        /** Return the physical frame, bits shifted right */
        Addr
        pfn() const override
        {
            return large() ? bits(data, 31, 16) : bits(data, 31, 12);
        }

        /** Return complete physical address given a VA */
        Addr
        paddr(Addr va) const
        {
            if (large())
                return mbits(data, 31, 16) | mbits(va, 15, 0);
            else
                return mbits(data, 31, 12) | mbits(va, 11, 0);
        }

        /** If the section is shareable. See texcb() comment. */
        bool
        shareable() const override
        {
            return bits(data, 10);
        }

        /** Set access flag that this entry has been touched. Mark
         * the entry as requiring a writeback, in the future.
         */
        void
        setAp0()
        {
            data |= 1 << 4;
            _dirty = true;
        }

        /** This entry needs to be written back to memory */
        bool
        dirty() const
        {
            return _dirty;
        }

    };

    /** Long-descriptor format (LPAE) */
    class LongDescriptor : public DescriptorBase
    {
      public:
        /** Descriptor type */
        enum EntryType
        {
            Invalid,
            Table,
            Block,
            Page
        };

        LongDescriptor()
          : data(0), _dirty(false), aarch64(false), grainSize(Grain4KB),
            physAddrRange(0)
        {}

        /** The raw bits of the entry */
        uint64_t data;

        /** This entry has been modified (access flag set) and needs to be
         * written back to memory */
        bool _dirty;

        /** True if the current lookup is performed in AArch64 state */
        bool aarch64;

        /** Width of the granule size in bits */
        GrainSize grainSize;

        uint8_t physAddrRange;

        uint64_t
        getRawData() const override
        {
            return (data);
        }

        std::string
        dbgHeader() const override
        {
            if (type() == LongDescriptor::Page) {
                assert(lookupLevel == LookupLevel::L3);
                return "Inserting Page descriptor into TLB\n";
            } else {
                assert(lookupLevel < LookupLevel::L3);
                return "Inserting Block descriptor into TLB\n";
            }
        }

        /**
         * Returns true if this entry targets the secure physical address
         * map.
         */
        bool
        secure(bool have_security, WalkerState *currState) const override
        {
            assert(type() == Block || type() == Page);
            return have_security && (currState->secureLookup && !bits(data, 5));
        }

        /** Return the descriptor type */
        EntryType
        type() const
        {
            switch (bits(data, 1, 0)) {
              case 0x1:
                // In AArch64 blocks are not allowed at L0 for the
                // 4 KiB granule and at L1 for 16/64 KiB granules
                switch (grainSize) {
                  case Grain4KB:
                    if (lookupLevel == LookupLevel::L0 ||
                        lookupLevel == LookupLevel::L3)
                        return Invalid;
                    else
                        return Block;

                  case Grain16KB:
                    if (lookupLevel == LookupLevel::L2)
                        return Block;
                    else
                        return Invalid;

                  case Grain64KB:
                    // With Armv8.2-LPA (52bit PA) L1 Block descriptors
                    // are allowed for 64KiB granule
                    if ((lookupLevel == LookupLevel::L1 && physAddrRange == 52) ||
                        lookupLevel == LookupLevel::L2)
                        return Block;
                    else
                        return Invalid;

                  default:
                    return Invalid;
                }
              case 0x3:
                return lookupLevel == LookupLevel::L3 ? Page : Table;
              default:
                return Invalid;
            }
        }

        /** Return the bit width of the page/block offset */
        uint8_t
        offsetBits() const override
        {
            if (type() == Block) {
                switch (grainSize) {
                    case Grain4KB:
                        return lookupLevel == LookupLevel::L1 ?
                            30 /* 1 GiB */ : 21 /* 2 MiB */;
                    case Grain16KB:
                        return 25  /* 32 MiB */;
                    case Grain64KB:
                        return lookupLevel == LookupLevel::L1 ?
                            42 /* 4 TiB */ : 29 /* 512 MiB */;
                    default:
                        panic("Invalid AArch64 VM granule size\n");
                }
            } else if (type() == Page) {
                switch (grainSize) {
                    case Grain4KB:
                    case Grain16KB:
                    case Grain64KB:
                        return grainSize; /* enum -> uint okay */
                    default:
                        panic("Invalid AArch64 VM granule size\n");
                }
            } else {
                panic("AArch64 page table entry must be block or page\n");
            }
        }

        /** Return the physical frame, bits shifted right */
        Addr
        pfn() const override
        {
            return paddr() >> offsetBits();
        }

        /** Return the physical address of the entry */
        Addr
        paddr() const
        {
            Addr addr = 0;
            if (aarch64) {
                addr = mbits(data, 47, offsetBits());
                if (physAddrRange == 52 && grainSize == Grain64KB) {
                    addr |= bits(data, 15, 12) << 48;
                }
            } else {
                addr = mbits(data, 39, offsetBits());
            }
            return addr;
        }

        /** Return the address of the next page table */
        Addr
        nextTableAddr() const
        {
            assert(type() == Table);
            Addr table_address = 0;
            if (aarch64) {
                table_address = mbits(data, 47, grainSize);
                // Using 52bit if Armv8.2-LPA is implemented
                if (physAddrRange == 52 && grainSize == Grain64KB)
                    table_address |= bits(data, 15, 12) << 48;
            } else {
                table_address = mbits(data, 39, 12);
            }

            return table_address;
        }

        /** Return the address of the next descriptor */
        Addr
        nextDescAddr(Addr va) const
        {
            assert(type() == Table);
            Addr pa = 0;
            if (aarch64) {
                int stride = grainSize - 3;
                int va_lo = stride * (3 - (lookupLevel + 1)) + grainSize;
                int va_hi = va_lo + stride - 1;
                pa = nextTableAddr() | (bits(va, va_hi, va_lo) << 3);
            } else {
                if (lookupLevel == LookupLevel::L1)
                    pa = nextTableAddr() | (bits(va, 29, 21) << 3);
                else  // lookupLevel == L2
                    pa = nextTableAddr() | (bits(va, 20, 12) << 3);
            }
            return pa;
        }

        /** Is execution allowed on this mapping? */
        bool
        xn() const override
        {
            assert(type() == Block || type() == Page);
            return bits(data, 54);
        }

        /** Is privileged execution allowed on this mapping? (LPAE only) */
        bool
        pxn() const
        {
            assert(type() == Block || type() == Page);
            return bits(data, 53);
        }

        /** Contiguous hint bit. */
        bool
        contiguousHint() const
        {
            assert(type() == Block || type() == Page);
            return bits(data, 52);
        }

        /** Is the translation global (no asid used)? */
        bool
        global(WalkerState *currState) const override
        {
            assert(currState && (type() == Block || type() == Page));
            if (!currState->aarch64 && (currState->isSecure &&
                                        !currState->secureLookup)) {
                return false;  // ARM ARM issue C B3.6.3
            } else if (currState->aarch64) {
                if (currState->el == EL2 || currState->el == EL3) {
                    return true;  // By default translations are treated as global
                                  // in AArch64 EL2 and EL3
                } else if (currState->isSecure && !currState->secureLookup) {
                    return false;
                }
            }
            return !bits(data, 11);
        }

        /** Returns true if the access flag (AF) is set. */
        bool
        af() const
        {
            assert(type() == Block || type() == Page);
            return bits(data, 10);
        }

        /** 2-bit shareability field */
        uint8_t
        sh() const
        {
            assert(type() == Block || type() == Page);
            return bits(data, 9, 8);
        }

        /** 2-bit access protection flags */
        uint8_t
        ap() const override
        {
            assert(type() == Block || type() == Page);
            // Long descriptors only support the AP[2:1] scheme
            return bits(data, 7, 6);
        }

        /** Read/write access protection flag */
        bool
        rw() const
        {
            assert(type() == Block || type() == Page);
            return !bits(data, 7);
        }

        /** User/privileged level access protection flag */
        bool
        user() const
        {
            assert(type() == Block || type() == Page);
            return bits(data, 6);
        }

        /** Return the AP bits as compatible with the AP[2:0] format.  Utility
         * function used to simplify the code in the TLB for performing
         * permission checks. */
        static uint8_t
        ap(bool rw, bool user)
        {
            return ((!rw) << 2) | (user << 1);
        }

        TlbEntry::DomainType
        domain() const override
        {
            // Long-desc. format only supports Client domain
            assert(type() == Block || type() == Page);
            return TlbEntry::DomainType::Client;
        }

        /** Attribute index */
        uint8_t
        attrIndx() const
        {
            assert(type() == Block || type() == Page);
            return bits(data, 4, 2);
        }

        /** Memory attributes, only used by stage 2 translations */
        uint8_t
        memAttr() const
        {
            assert(type() == Block || type() == Page);
            return bits(data, 5, 2);
        }

        /** Set access flag that this entry has been touched.  Mark the entry as
         * requiring a writeback, in the future. */
        void
        setAf()
        {
            data |= 1 << 10;
            _dirty = true;
        }

        /** This entry needs to be written back to memory */
        bool
        dirty() const
        {
            return _dirty;
        }

        /** Whether the subsequent levels of lookup are secure */
        bool
        secureTable() const
        {
            assert(type() == Table);
            return !bits(data, 63);
        }

        /** Two bit access protection flags for subsequent levels of lookup */
        uint8_t
        apTable() const
        {
            assert(type() == Table);
            return bits(data, 62, 61);
        }

        /** R/W protection flag for subsequent levels of lookup */
        uint8_t
        rwTable() const
        {
            assert(type() == Table);
            return !bits(data, 62);
        }

        /** User/privileged mode protection flag for subsequent levels of
         * lookup */
        uint8_t
        userTable() const
        {
            assert(type() == Table);
            return !bits(data, 61);
        }

        /** Is execution allowed on subsequent lookup levels? */
        bool
        xnTable() const
        {
            assert(type() == Table);
            return bits(data, 60);
        }

        /** Is privileged execution allowed on subsequent lookup levels? */
        bool
        pxnTable() const
        {
            assert(type() == Table);
            return bits(data, 59);
        }
    };

    class WalkerState
    {
      public:
        /** Thread context that we're doing the walk for */
        ThreadContext *tc;

        /** If the access is performed in AArch64 state */
        bool aarch64;

        /** Current exception level */
        ExceptionLevel el;

        /** Current physical address range in bits */
        int physAddrRange;

        /** Request that is currently being serviced */
        RequestPtr req;

        /** ASID that we're servicing the request under */
        uint16_t asid;
        vmid_t vmid;
        bool    isHyp;

        /** Translation state for delayed requests */
        BaseMMU::Translation *transState;

        /** The fault that we are going to return */
        Fault fault;

        /** The virtual address that is being translated with tagging removed.*/
        Addr vaddr;

        /** The virtual address that is being translated */
        Addr vaddr_tainted;

        /** Cached copy of the sctlr as it existed when translation began */
        SCTLR sctlr;

        /** Cached copy of the scr as it existed when translation began */
        SCR scr;

        /** Cached copy of the cpsr as it existed when translation began */
        CPSR cpsr;

        /** Cached copy of ttbcr/tcr as it existed when translation began */
        union
        {
            TTBCR ttbcr; // AArch32 translations
            TCR tcr;     // AArch64 translations
        };

        /** Cached copy of the htcr as it existed when translation began. */
        HTCR htcr;

        /** Cached copy of the htcr as it existed when translation began. */
        HCR  hcr;

        /** Cached copy of the vtcr as it existed when translation began. */
        VTCR_t vtcr;

        /** If the access is a write */
        bool isWrite;

        /** If the access is a fetch (for execution, and no-exec) must be checked?*/
        bool isFetch;

        /** If the access comes from the secure state. */
        bool isSecure;

        /** True if table walks are uncacheable (for table descriptors) */
        bool isUncacheable;

        /** Helper variables used to implement hierarchical access permissions
         * when the long-desc. format is used (LPAE only) */
        bool secureLookup;
        bool rwTable;
        bool userTable;
        bool xnTable;
        bool pxnTable;

        /** Hierarchical access permission disable */
        bool hpd;

        /** Flag indicating if a second stage of lookup is required */
        bool stage2Req;

        /** A pointer to the stage 2 translation that's in progress */
        BaseMMU::Translation *stage2Tran;

        /** If the mode is timing or atomic */
        bool timing;

        /** If the atomic mode should be functional */
        bool functional;

        /** Save mode for use in delayed response */
        BaseMMU::Mode mode;

        /** The translation type that has been requested */
        MMU::ArmTranslationType tranType;

        /** Short-format descriptors */
        L1Descriptor l1Desc;
        L2Descriptor l2Desc;

        /** Long-format descriptor (LPAE and AArch64) */
        LongDescriptor longDesc;

        /** Whether the response is delayed in timing mode due to additional
         * lookups */
        bool delayed;

        TableWalker *tableWalker;

        /** Timestamp for calculating elapsed time in service (for stats) */
        Tick startTime;

        /** Page entries walked during service (for stats) */
        unsigned levels;

        void doL1Descriptor();
        void doL2Descriptor();

        void doLongDescriptor();

        WalkerState();

        std::string name() const { return tableWalker->name(); }
    };

    class TableWalkerState : public Packet::SenderState
    {
      public:
        Tick delay = 0;
        Event *event = nullptr;
    };

    class Port : public QueuedRequestPort
    {
      public:
        Port(TableWalker* _walker, RequestorID id);

        void sendFunctionalReq(Addr desc_addr, int size,
            uint8_t *data, Request::Flags flag);
        void sendAtomicReq(Addr desc_addr, int size,
            uint8_t *data, Request::Flags flag, Tick delay);
        void sendTimingReq(Addr desc_addr, int size,
            uint8_t *data, Request::Flags flag, Tick delay,
            Event *event);

        bool recvTimingResp(PacketPtr pkt) override;

      private:
        void handleRespPacket(PacketPtr pkt, Tick delay=0);
        void handleResp(TableWalkerState *state, Addr addr,
                        Addr size, Tick delay=0);

        PacketPtr createPacket(Addr desc_addr, int size,
                               uint8_t *data, Request::Flags flag,
                               Tick delay, Event *event);

      private:
        /** Packet queue used to store outgoing requests. */
        ReqPacketQueue reqQueue;

        /** Packet queue used to store outgoing snoop responses. */
        SnoopRespPacketQueue snoopRespQueue;

        /** Cached requestorId of the table walker */
        RequestorID requestorId;
    };

    /** This translation class is used to trigger the data fetch once a timing
        translation returns the translated physical address */
    class Stage2Walk : public BaseMMU::Translation
    {
      private:
        uint8_t      *data;
        int          numBytes;
        RequestPtr   req;
        Event        *event;
        TableWalker  &parent;
        Addr         oVAddr;
        BaseMMU::Mode mode;
        MMU::ArmTranslationType tranType;

      public:
        Fault fault;

        Stage2Walk(TableWalker &_parent, uint8_t *_data, Event *_event,
                   Addr vaddr, BaseMMU::Mode mode,
                   MMU::ArmTranslationType tran_type);

        void markDelayed() {}

        void finish(const Fault &fault, const RequestPtr &req,
            ThreadContext *tc, BaseMMU::Mode mode);

        void
        setVirt(Addr vaddr, int size, Request::Flags flags,
                int requestorId)
        {
            numBytes = size;
            req->setVirt(vaddr, size, flags, requestorId, 0);
        }

        void translateTiming(ThreadContext *tc);
    };

    Fault readDataUntimed(ThreadContext *tc, Addr vaddr, Addr desc_addr,
                          uint8_t *data, int num_bytes, Request::Flags flags,
                          BaseMMU::Mode mode, MMU::ArmTranslationType tran_type,
                          bool functional);
    void readDataTimed(ThreadContext *tc, Addr desc_addr,
                       Stage2Walk *translation, int num_bytes,
                       Request::Flags flags);

  protected:

    /** Queues of requests for all the different lookup levels */
    std::list<WalkerState *> stateQueues[LookupLevel::Num_ArmLookupLevel];

    /** Queue of requests that have passed are waiting because the walker is
     * currently busy. */
    std::list<WalkerState *> pendingQueue;

    /** The MMU to forward second stage look upts to */
    MMU *mmu;

    /** Requestor id assigned by the MMU. */
    RequestorID requestorId;

    /** Port shared by the two table walkers. */
    Port* port;

    /** Indicates whether this table walker is part of the stage 2 mmu */
    const bool isStage2;

    /** TLB that is initiating these table walks */
    TLB *tlb;

    /** Cached copy of the sctlr as it existed when translation began */
    SCTLR sctlr;

    WalkerState *currState;

    /** If a timing translation is currently in progress */
    bool pending;

    /** The number of walks belonging to squashed instructions that can be
     * removed from the pendingQueue per cycle. */
    unsigned numSquashable;

    /** Cached copies of system-level properties */
    const ArmRelease *release;
    uint8_t _physAddrRange;
    bool _haveLargeAsid64;

    /** Statistics */
    struct TableWalkerStats : public statistics::Group
    {
        TableWalkerStats(statistics::Group *parent);
        statistics::Scalar walks;
        statistics::Scalar walksShortDescriptor;
        statistics::Scalar walksLongDescriptor;
        statistics::Vector walksShortTerminatedAtLevel;
        statistics::Vector walksLongTerminatedAtLevel;
        statistics::Scalar squashedBefore;
        statistics::Scalar squashedAfter;
        statistics::Histogram walkWaitTime;
        statistics::Histogram walkServiceTime;
        // Essentially "L" of queueing theory
        statistics::Histogram pendingWalks;
        statistics::Vector pageSizes;
        statistics::Vector2d requestOrigin;
    } stats;

    mutable unsigned pendingReqs;
    mutable Tick pendingChangeTick;

    static const unsigned REQUESTED = 0;
    static const unsigned COMPLETED = 1;

  public:
    PARAMS(ArmTableWalker);
    TableWalker(const Params &p);
    virtual ~TableWalker();

    bool haveLargeAsid64() const { return _haveLargeAsid64; }
    uint8_t physAddrRange() const { return _physAddrRange; }
    /** Checks if all state is cleared and if so, completes drain */
    void completeDrain();
    DrainState drain() override;
    void drainResume() override;

    gem5::Port &getPort(const std::string &if_name,
                    PortID idx=InvalidPortID) override;

    Port &getTableWalkerPort();

    Fault walk(const RequestPtr &req, ThreadContext *tc,
               uint16_t asid, vmid_t _vmid,
               bool _isHyp, BaseMMU::Mode mode, BaseMMU::Translation *_trans,
               bool timing, bool functional, bool secure,
               MMU::ArmTranslationType tranType, bool _stage2Req);

    void setMmu(MMU *_mmu);
    void setTlb(TLB *_tlb) { tlb = _tlb; }
    TLB* getTlb() { return tlb; }
    void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr,
                  uint8_t texcb, bool s);
    void memAttrsLPAE(ThreadContext *tc, TlbEntry &te,
                      LongDescriptor &lDescriptor);
    void memAttrsAArch64(ThreadContext *tc, TlbEntry &te,
                         LongDescriptor &lDescriptor);

    static LookupLevel toLookupLevel(uint8_t lookup_level_as_int);

  private:

    void doL1Descriptor();
    void doL1DescriptorWrapper();
    EventFunctionWrapper doL1DescEvent;

    void doL2Descriptor();
    void doL2DescriptorWrapper();
    EventFunctionWrapper doL2DescEvent;

    void doLongDescriptor();

    void doL0LongDescriptorWrapper();
    EventFunctionWrapper doL0LongDescEvent;
    void doL1LongDescriptorWrapper();
    EventFunctionWrapper doL1LongDescEvent;
    void doL2LongDescriptorWrapper();
    EventFunctionWrapper doL2LongDescEvent;
    void doL3LongDescriptorWrapper();
    EventFunctionWrapper doL3LongDescEvent;

    void doLongDescriptorWrapper(LookupLevel curr_lookup_level);
    Event* LongDescEventByLevel[4];

    bool fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes,
        Request::Flags flags, int queueIndex, Event *event,
        void (TableWalker::*doDescriptor)());

    Fault generateLongDescFault(ArmFault::FaultSource src);

    void insertTableEntry(DescriptorBase &descriptor, bool longDescriptor);

    Fault processWalk();
    Fault processWalkLPAE();

    bool checkVAddrSizeFaultAArch64(Addr addr, int top_bit,
        GrainSize granule, int tsz, bool low_range);

    /// Returns true if the address exceeds the range permitted by the
    /// system-wide setting or by the TCR_ELx IPS/PS setting
    bool checkAddrSizeFaultAArch64(Addr addr, int pa_range);

    Fault processWalkAArch64();
    void processWalkWrapper();
    EventFunctionWrapper doProcessEvent;

    void nextWalk(ThreadContext *tc);

    void pendingChange();

    static uint8_t pageSizeNtoStatBin(uint8_t N);

    Fault testWalk(Addr pa, Addr size, TlbEntry::DomainType domain,
                   LookupLevel lookup_level, bool stage2);
};

} // namespace ArmISA
} // namespace gem5

#endif //__ARCH_ARM_TABLE_WALKER_HH__
