/*
 * Copyright (c) 2010, 2012-2014 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.
 *
 * Authors: Ali Saidi
 *          Giacomo Gabrielli
 */

#include "arch/arm/faults.hh"
#include "arch/arm/stage2_mmu.hh"
#include "arch/arm/system.hh"
#include "arch/arm/table_walker.hh"
#include "arch/arm/tlb.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "debug/Checkpoint.hh"
#include "debug/Drain.hh"
#include "debug/TLB.hh"
#include "debug/TLBVerbose.hh"
#include "sim/system.hh"

using namespace ArmISA;

TableWalker::TableWalker(const Params *p)
    : MemObject(p), port(this, p->sys), drainManager(NULL),
      stage2Mmu(NULL), isStage2(p->is_stage2), tlb(NULL),
      currState(NULL), pending(false), masterId(p->sys->getMasterId(name())),
      numSquashable(p->num_squash_per_cycle),
      doL1DescEvent(this), doL2DescEvent(this),
      doL0LongDescEvent(this), doL1LongDescEvent(this), doL2LongDescEvent(this),
      doL3LongDescEvent(this),
      doProcessEvent(this)
{
    sctlr = 0;

    // Cache system-level properties
    if (FullSystem) {
        armSys = dynamic_cast<ArmSystem *>(p->sys);
        assert(armSys);
        haveSecurity = armSys->haveSecurity();
        _haveLPAE = armSys->haveLPAE();
        _haveVirtualization = armSys->haveVirtualization();
        physAddrRange = armSys->physAddrRange();
        _haveLargeAsid64 = armSys->haveLargeAsid64();
    } else {
        armSys = NULL;
        haveSecurity = _haveLPAE = _haveVirtualization = false;
        _haveLargeAsid64 = false;
        physAddrRange = 32;
    }

}

TableWalker::~TableWalker()
{
    ;
}

TableWalker::WalkerState::WalkerState() : stage2Tran(NULL), l2Desc(l1Desc)
{
}

void
TableWalker::completeDrain()
{
    if (drainManager && stateQueues[L1].empty() && stateQueues[L2].empty() &&
        pendingQueue.empty()) {
        setDrainState(Drainable::Drained);
        DPRINTF(Drain, "TableWalker done draining, processing drain event\n");
        drainManager->signalDrainDone();
        drainManager = NULL;
    }
}

unsigned int
TableWalker::drain(DrainManager *dm)
{
    unsigned int count = port.drain(dm);

    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()) {
        drainManager = dm;
        setDrainState(Drainable::Draining);
        DPRINTF(Drain, "TableWalker not drained\n");

        // return port drain count plus the table walker itself needs to drain
        return count + 1;
    } else {
        setDrainState(Drainable::Drained);
        DPRINTF(Drain, "TableWalker free, no need to drain\n");

        // table walker is drained, but its ports may still need to be drained
        return count;
    }
}

void
TableWalker::drainResume()
{
    Drainable::drainResume();
    if (params()->sys->isTimingMode() && currState) {
        delete currState;
        currState = NULL;
    }
}

BaseMasterPort&
TableWalker::getMasterPort(const std::string &if_name, PortID idx)
{
    if (if_name == "port") {
        return port;
    }
    return MemObject::getMasterPort(if_name, idx);
}

Fault
TableWalker::walk(RequestPtr _req, ThreadContext *_tc, uint16_t _asid,
                  uint8_t _vmid, bool _isHyp, TLB::Mode _mode,
                  TLB::Translation *_trans, bool _timing, bool _functional,
                  bool secure, TLB::ArmTranslationType tranType)
{
    assert(!(_functional && _timing));
    WalkerState *savedCurrState = NULL;

    if (!currState && !_functional) {
        // For atomic mode, a new WalkerState instance should be only created
        // once per TLB. For timing mode, a new instance is generated for every
        // TLB miss.
        DPRINTF(TLBVerbose, "creating new instance of WalkerState\n");

        currState = new WalkerState();
        currState->tableWalker = this;
    } else if (_functional) {
        // If we are mixing functional mode with timing (or even
        // atomic), we need to to be careful and clean up after
        // ourselves to not risk getting into an inconsistent state.
        DPRINTF(TLBVerbose, "creating functional instance of WalkerState\n");
        savedCurrState = currState;
        currState = new WalkerState();
        currState->tableWalker = this;
    } else if (_timing) {
        // This is a translation that was completed and then faulted again
        // because some underlying parameters that affect the translation
        // changed out from under us (e.g. asid). It will either be a
        // misprediction, in which case nothing will happen or we'll use
        // this fault to re-execute the faulting instruction which should clean
        // up everything.
        if (currState->vaddr_tainted == _req->getVaddr()) {
            return new ReExec;
        }
    }

    currState->tc = _tc;
    currState->aarch64 = opModeIs64(currOpMode(_tc));
    currState->el = currEL(_tc);
    currState->transState = _trans;
    currState->req = _req;
    currState->fault = NoFault;
    currState->asid = _asid;
    currState->vmid = _vmid;
    currState->isHyp = _isHyp;
    currState->timing = _timing;
    currState->functional = _functional;
    currState->mode = _mode;
    currState->tranType = tranType;
    currState->isSecure = secure;
    currState->physAddrRange = physAddrRange;

    /** @todo These should be cached or grabbed from cached copies in
     the TLB, all these miscreg reads are expensive */
    currState->vaddr_tainted = currState->req->getVaddr();
    if (currState->aarch64)
        currState->vaddr = purifyTaggedAddr(currState->vaddr_tainted,
                                            currState->tc, currState->el);
    else
        currState->vaddr = currState->vaddr_tainted;

    if (currState->aarch64) {
        switch (currState->el) {
          case EL0:
          case EL1:
            currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL1);
            currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL1);
            break;
          // @todo: uncomment this to enable Virtualization
          // case EL2:
          //   assert(haveVirtualization);
          //   currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL2);
          //   currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL2);
          //   break;
          case EL3:
            assert(haveSecurity);
            currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL3);
            currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL3);
            break;
          default:
            panic("Invalid exception level");
            break;
        }
    } else {
        currState->sctlr = currState->tc->readMiscReg(flattenMiscRegNsBanked(
            MISCREG_SCTLR, currState->tc, !currState->isSecure));
        currState->ttbcr = currState->tc->readMiscReg(flattenMiscRegNsBanked(
            MISCREG_TTBCR, currState->tc, !currState->isSecure));
        currState->htcr  = currState->tc->readMiscReg(MISCREG_HTCR);
        currState->hcr   = currState->tc->readMiscReg(MISCREG_HCR);
        currState->vtcr  = currState->tc->readMiscReg(MISCREG_VTCR);
    }
    sctlr = currState->sctlr;

    currState->isFetch = (currState->mode == TLB::Execute);
    currState->isWrite = (currState->mode == TLB::Write);

    // We only do a second stage of translation if we're not secure, or in
    // hyp mode, the second stage MMU is enabled, and this table walker
    // instance is the first stage.
    currState->doingStage2 = false;
    // @todo: for now disable this in AArch64 (HCR is not set)
    currState->stage2Req = !currState->aarch64 && currState->hcr.vm &&
                           !isStage2 && !currState->isSecure && !currState->isHyp;

    bool long_desc_format = currState->aarch64 ||
                            (_haveLPAE && currState->ttbcr.eae) ||
                            _isHyp || isStage2;

    if (long_desc_format) {
        // Helper variables used for hierarchical permissions
        currState->secureLookup = currState->isSecure;
        currState->rwTable = true;
        currState->userTable = true;
        currState->xnTable = false;
        currState->pxnTable = false;
    }

    if (!currState->timing) {
        Fault fault = NoFault;
        if (currState->aarch64)
            fault = processWalkAArch64();
        else if (long_desc_format)
            fault = processWalkLPAE();
        else
            fault = processWalk();

        // If this was a functional non-timing access restore state to
        // how we found it.
        if (currState->functional) {
            delete currState;
            currState = savedCurrState;
        }
        return fault;
    }

    if (pending || pendingQueue.size()) {
        pendingQueue.push_back(currState);
        currState = NULL;
    } else {
        pending = true;
        if (currState->aarch64)
            return processWalkAArch64();
        else if (long_desc_format)
            return processWalkLPAE();
        else
            return processWalk();
    }

    return NoFault;
}

void
TableWalker::processWalkWrapper()
{
    assert(!currState);
    assert(pendingQueue.size());
    currState = pendingQueue.front();

    ExceptionLevel target_el = EL0;
    if (currState->aarch64)
        target_el = currEL(currState->tc);
    else
        target_el = EL1;

    // Check if a previous walk filled this request already
    // @TODO Should this always be the TLB or should we look in the stage2 TLB?
    TlbEntry* te = tlb->lookup(currState->vaddr, currState->asid,
            currState->vmid, currState->isHyp, currState->isSecure, true, false,
            target_el);

    // Check if we still need to have a walk for this request. If the requesting
    // instruction has been squashed, or a previous walk has filled the TLB with
    // a match, we just want to get rid of the walk. The latter could happen
    // when there are multiple outstanding misses to a single page and a
    // previous request has been successfully translated.
    if (!currState->transState->squashed() && !te) {
        // We've got a valid request, lets process it
        pending = true;
        pendingQueue.pop_front();
        if (currState->aarch64)
            processWalkAArch64();
        else if ((_haveLPAE && currState->ttbcr.eae) || currState->isHyp || isStage2)
            processWalkLPAE();
        else
            processWalk();
        return;
    }


    // If the instruction that we were translating for has been
    // squashed we shouldn't bother.
    unsigned num_squashed = 0;
    ThreadContext *tc = currState->tc;
    while ((num_squashed < numSquashable) && currState &&
           (currState->transState->squashed() || te)) {
        pendingQueue.pop_front();
        num_squashed++;

        DPRINTF(TLB, "Squashing table walk for address %#x\n",
                      currState->vaddr_tainted);

        if (currState->transState->squashed()) {
            // finish the translation which will delete the translation object
            currState->transState->finish(new UnimpFault("Squashed Inst"),
                    currState->req, currState->tc, currState->mode);
        } else {
            // translate the request now that we know it will work
            tlb->translateTiming(currState->req, currState->tc,
                        currState->transState, currState->mode);

        }

        // delete the current request
        delete currState;

        // peak at the next one
        if (pendingQueue.size()) {
            currState = pendingQueue.front();
            te = tlb->lookup(currState->vaddr, currState->asid,
                currState->vmid, currState->isHyp, currState->isSecure, true,
                false, target_el);
        } else {
            // Terminate the loop, nothing more to do
            currState = NULL;
        }
    }

    // if we've still got pending translations schedule more work
    nextWalk(tc);
    currState = NULL;
    completeDrain();
}

Fault
TableWalker::processWalk()
{
    Addr ttbr = 0;

    // If translation isn't enabled, we shouldn't be here
    assert(currState->sctlr.m || isStage2);

    DPRINTF(TLB, "Beginning table walk for address %#x, TTBCR: %#x, bits:%#x\n",
            currState->vaddr_tainted, currState->ttbcr, mbits(currState->vaddr, 31,
                                                      32 - currState->ttbcr.n));

    if (currState->ttbcr.n == 0 || !mbits(currState->vaddr, 31,
                                          32 - currState->ttbcr.n)) {
        DPRINTF(TLB, " - Selecting TTBR0\n");
        // Check if table walk is allowed when Security Extensions are enabled
        if (haveSecurity && currState->ttbcr.pd0) {
            if (currState->isFetch)
                return new PrefetchAbort(currState->vaddr_tainted,
                                         ArmFault::TranslationLL + L1,
                                         isStage2,
                                         ArmFault::VmsaTran);
            else
                return new DataAbort(currState->vaddr_tainted,
                        TlbEntry::DomainType::NoAccess, currState->isWrite,
                                     ArmFault::TranslationLL + L1, isStage2,
                                     ArmFault::VmsaTran);
        }
        ttbr = currState->tc->readMiscReg(flattenMiscRegNsBanked(
            MISCREG_TTBR0, currState->tc, !currState->isSecure));
    } else {
        DPRINTF(TLB, " - Selecting TTBR1\n");
        // Check if table walk is allowed when Security Extensions are enabled
        if (haveSecurity && currState->ttbcr.pd1) {
            if (currState->isFetch)
                return new PrefetchAbort(currState->vaddr_tainted,
                                         ArmFault::TranslationLL + L1,
                                         isStage2,
                                         ArmFault::VmsaTran);
            else
                return new DataAbort(currState->vaddr_tainted,
                        TlbEntry::DomainType::NoAccess, currState->isWrite,
                                     ArmFault::TranslationLL + L1, isStage2,
                                     ArmFault::VmsaTran);
        }
        ttbr = currState->tc->readMiscReg(flattenMiscRegNsBanked(
            MISCREG_TTBR1, currState->tc, !currState->isSecure));
        currState->ttbcr.n = 0;
    }

    Addr l1desc_addr = mbits(ttbr, 31, 14 - currState->ttbcr.n) |
        (bits(currState->vaddr, 31 - currState->ttbcr.n, 20) << 2);
    DPRINTF(TLB, " - Descriptor at address %#x (%s)\n", l1desc_addr,
            currState->isSecure ? "s" : "ns");

    // Trickbox address check
    Fault f;
    f = tlb->walkTrickBoxCheck(l1desc_addr, currState->isSecure,
            currState->vaddr, sizeof(uint32_t), currState->isFetch,
            currState->isWrite, TlbEntry::DomainType::NoAccess, L1);
    if (f) {
        DPRINTF(TLB, "Trickbox check caused fault on %#x\n", currState->vaddr_tainted);
        if (currState->timing) {
            pending = false;
            nextWalk(currState->tc);
            currState = NULL;
        } else {
            currState->tc = NULL;
            currState->req = NULL;
        }
        return f;
    }

    Request::Flags flag = 0;
    if (currState->sctlr.c == 0) {
        flag = Request::UNCACHEABLE;
    }

    bool delayed;
    delayed = fetchDescriptor(l1desc_addr, (uint8_t*)&currState->l1Desc.data,
                              sizeof(uint32_t), flag, L1, &doL1DescEvent,
                              &TableWalker::doL1Descriptor);
    if (!delayed) {
       f = currState->fault;
    }

    return f;
}

Fault
TableWalker::processWalkLPAE()
{
    Addr ttbr, ttbr0_max, ttbr1_min, desc_addr;
    int tsz, n;
    LookupLevel start_lookup_level = L1;

    DPRINTF(TLB, "Beginning table walk for address %#x, TTBCR: %#x\n",
            currState->vaddr_tainted, currState->ttbcr);

    Request::Flags flag = 0;
    if (currState->isSecure)
        flag.set(Request::SECURE);

    // work out which base address register to use, if in hyp mode we always
    // use HTTBR
    if (isStage2) {
        DPRINTF(TLB, " - Selecting VTTBR (long-desc.)\n");
        ttbr = currState->tc->readMiscReg(MISCREG_VTTBR);
        tsz  = sext<4>(currState->vtcr.t0sz);
        start_lookup_level = currState->vtcr.sl0 ? L1 : L2;
    } else if (currState->isHyp) {
        DPRINTF(TLB, " - Selecting HTTBR (long-desc.)\n");
        ttbr = currState->tc->readMiscReg(MISCREG_HTTBR);
        tsz  = currState->htcr.t0sz;
    } else {
        assert(_haveLPAE && currState->ttbcr.eae);

        // Determine boundaries of TTBR0/1 regions
        if (currState->ttbcr.t0sz)
            ttbr0_max = (1ULL << (32 - currState->ttbcr.t0sz)) - 1;
        else if (currState->ttbcr.t1sz)
            ttbr0_max = (1ULL << 32) -
                (1ULL << (32 - currState->ttbcr.t1sz)) - 1;
        else
            ttbr0_max = (1ULL << 32) - 1;
        if (currState->ttbcr.t1sz)
            ttbr1_min = (1ULL << 32) - (1ULL << (32 - currState->ttbcr.t1sz));
        else
            ttbr1_min = (1ULL << (32 - currState->ttbcr.t0sz));

        // The following code snippet selects the appropriate translation table base
        // address (TTBR0 or TTBR1) and the appropriate starting lookup level
        // depending on the address range supported by the translation table (ARM
        // ARM issue C B3.6.4)
        if (currState->vaddr <= ttbr0_max) {
            DPRINTF(TLB, " - Selecting TTBR0 (long-desc.)\n");
            // Check if table walk is allowed
            if (currState->ttbcr.epd0) {
                if (currState->isFetch)
                    return new PrefetchAbort(currState->vaddr_tainted,
                                             ArmFault::TranslationLL + L1,
                                             isStage2,
                                             ArmFault::LpaeTran);
                else
                    return new DataAbort(currState->vaddr_tainted,
                                         TlbEntry::DomainType::NoAccess,
                                         currState->isWrite,
                                         ArmFault::TranslationLL + L1,
                                         isStage2,
                                         ArmFault::LpaeTran);
            }
            ttbr = currState->tc->readMiscReg(flattenMiscRegNsBanked(
                MISCREG_TTBR0, currState->tc, !currState->isSecure));
            tsz = currState->ttbcr.t0sz;
            if (ttbr0_max < (1ULL << 30))  // Upper limit < 1 GB
                start_lookup_level = L2;
        } else if (currState->vaddr >= ttbr1_min) {
            DPRINTF(TLB, " - Selecting TTBR1 (long-desc.)\n");
            // Check if table walk is allowed
            if (currState->ttbcr.epd1) {
                if (currState->isFetch)
                    return new PrefetchAbort(currState->vaddr_tainted,
                                             ArmFault::TranslationLL + L1,
                                             isStage2,
                                             ArmFault::LpaeTran);
                else
                    return new DataAbort(currState->vaddr_tainted,
                                         TlbEntry::DomainType::NoAccess,
                                         currState->isWrite,
                                         ArmFault::TranslationLL + L1,
                                         isStage2,
                                         ArmFault::LpaeTran);
            }
            ttbr = currState->tc->readMiscReg(flattenMiscRegNsBanked(
                MISCREG_TTBR1, currState->tc, !currState->isSecure));
            tsz = currState->ttbcr.t1sz;
            if (ttbr1_min >= (1ULL << 31) + (1ULL << 30))  // Lower limit >= 3 GB
                start_lookup_level = L2;
        } else {
            // Out of boundaries -> translation fault
            if (currState->isFetch)
                return new PrefetchAbort(currState->vaddr_tainted,
                                         ArmFault::TranslationLL + L1,
                                         isStage2,
                                         ArmFault::LpaeTran);
            else
                return new DataAbort(currState->vaddr_tainted,
                                     TlbEntry::DomainType::NoAccess,
                                     currState->isWrite, ArmFault::TranslationLL + L1,
                                     isStage2, ArmFault::LpaeTran);
        }

    }

    // Perform lookup (ARM ARM issue C B3.6.6)
    if (start_lookup_level == L1) {
        n = 5 - tsz;
        desc_addr = mbits(ttbr, 39, n) |
            (bits(currState->vaddr, n + 26, 30) << 3);
        DPRINTF(TLB, " - Descriptor at address %#x (%s) (long-desc.)\n",
                desc_addr, currState->isSecure ? "s" : "ns");
    } else {
        // Skip first-level lookup
        n = (tsz >= 2 ? 14 - tsz : 12);
        desc_addr = mbits(ttbr, 39, n) |
            (bits(currState->vaddr, n + 17, 21) << 3);
        DPRINTF(TLB, " - Descriptor at address %#x (%s) (long-desc.)\n",
                desc_addr, currState->isSecure ? "s" : "ns");
    }

    // Trickbox address check
    Fault f = tlb->walkTrickBoxCheck(desc_addr, currState->isSecure,
                        currState->vaddr, sizeof(uint64_t), currState->isFetch,
                        currState->isWrite, TlbEntry::DomainType::NoAccess,
                        start_lookup_level);
    if (f) {
        DPRINTF(TLB, "Trickbox check caused fault on %#x\n", currState->vaddr_tainted);
        if (currState->timing) {
            pending = false;
            nextWalk(currState->tc);
            currState = NULL;
        } else {
            currState->tc = NULL;
            currState->req = NULL;
        }
        return f;
    }

    if (currState->sctlr.c == 0) {
        flag = Request::UNCACHEABLE;
    }

    if (currState->isSecure)
        flag.set(Request::SECURE);

    currState->longDesc.lookupLevel = start_lookup_level;
    currState->longDesc.aarch64 = false;
    currState->longDesc.grainSize = Grain4KB;

    Event *event = start_lookup_level == L1 ? (Event *) &doL1LongDescEvent
                                            : (Event *) &doL2LongDescEvent;

    bool delayed = fetchDescriptor(desc_addr, (uint8_t*)&currState->longDesc.data,
                                   sizeof(uint64_t), flag, start_lookup_level,
                                   event, &TableWalker::doLongDescriptor);
    if (!delayed) {
        f = currState->fault;
    }

    return f;
}

unsigned
TableWalker::adjustTableSizeAArch64(unsigned tsz)
{
    if (tsz < 25)
        return 25;
    if (tsz > 48)
        return 48;
    return tsz;
}

bool
TableWalker::checkAddrSizeFaultAArch64(Addr addr, int currPhysAddrRange)
{
    return (currPhysAddrRange != MaxPhysAddrRange &&
            bits(addr, MaxPhysAddrRange - 1, currPhysAddrRange));
}

Fault
TableWalker::processWalkAArch64()
{
    assert(currState->aarch64);

    DPRINTF(TLB, "Beginning table walk for address %#llx, TCR: %#llx\n",
            currState->vaddr_tainted, currState->tcr);

    static const GrainSize GrainMapDefault[] =
      { Grain4KB, Grain64KB, Grain16KB, ReservedGrain };
    static const GrainSize GrainMap_EL1_tg1[] =
      { ReservedGrain, Grain16KB, Grain4KB, Grain64KB };

    // Determine TTBR, table size, granule size and phys. address range
    Addr ttbr = 0;
    int tsz = 0, ps = 0;
    GrainSize tg = Grain4KB; // grain size computed from tg* field
    bool fault = false;
    switch (currState->el) {
      case EL0:
      case EL1:
        switch (bits(currState->vaddr, 63,48)) {
          case 0:
            DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n");
            ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL1);
            tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz);
            tg = GrainMapDefault[currState->tcr.tg0];
            if (bits(currState->vaddr, 63, tsz) != 0x0 ||
                currState->tcr.epd0)
              fault = true;
            break;
          case 0xffff:
            DPRINTF(TLB, " - Selecting TTBR1 (AArch64)\n");
            ttbr = currState->tc->readMiscReg(MISCREG_TTBR1_EL1);
            tsz = adjustTableSizeAArch64(64 - currState->tcr.t1sz);
            tg = GrainMap_EL1_tg1[currState->tcr.tg1];
            if (bits(currState->vaddr, 63, tsz) != mask(64-tsz) ||
                currState->tcr.epd1)
              fault = true;
            break;
          default:
            // top two bytes must be all 0s or all 1s, else invalid addr
            fault = true;
        }
        ps = currState->tcr.ips;
        break;
      case EL2:
      case EL3:
        switch(bits(currState->vaddr, 63,48)) {
            case 0:
                DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n");
                if (currState->el == EL2)
                    ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL2);
                else
                    ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL3);
                tsz = adjustTableSizeAArch64(64 - currState->tcr.t0sz);
                tg = GrainMapDefault[currState->tcr.tg0];
                break;
            default:
                // invalid addr if top two bytes are not all 0s
                fault = true;
        }
        ps = currState->tcr.ips;
        break;
    }

    if (fault) {
        Fault f;
        if (currState->isFetch)
            f =  new PrefetchAbort(currState->vaddr_tainted,
                                     ArmFault::TranslationLL + L0, isStage2,
                                     ArmFault::LpaeTran);
        else
            f = new DataAbort(currState->vaddr_tainted,
                                 TlbEntry::DomainType::NoAccess,
                                 currState->isWrite,
                                 ArmFault::TranslationLL + L0,
                                 isStage2, ArmFault::LpaeTran);

        if (currState->timing) {
            pending = false;
            nextWalk(currState->tc);
            currState = NULL;
        } else {
            currState->tc = NULL;
            currState->req = NULL;
        }
        return f;

    }

    if (tg == ReservedGrain) {
        warn_once("Reserved granule size requested; gem5's IMPLEMENTATION "
                  "DEFINED behavior takes this to mean 4KB granules\n");
        tg = Grain4KB;
    }

    int stride = tg - 3;
    LookupLevel start_lookup_level = MAX_LOOKUP_LEVELS;

    // Determine starting lookup level
    // See aarch64/translation/walk in Appendix G: ARMv8 Pseudocode Library
    // in ARM DDI 0487A.  These table values correspond to the cascading tests
    // to compute the lookup level and are of the form
    // (grain_size + N*stride), for N = {1, 2, 3}.
    // A value of 64 will never succeed and a value of 0 will always succeed.
    {
        struct GrainMap {
            GrainSize grain_size;
            unsigned lookup_level_cutoff[MAX_LOOKUP_LEVELS];
        };
        static const GrainMap GM[] = {
            { Grain4KB,  { 39, 30,  0, 0 } },
            { Grain16KB, { 47, 36, 25, 0 } },
            { Grain64KB, { 64, 42, 29, 0 } }
        };

        const unsigned *lookup = NULL; // points to a lookup_level_cutoff

        for (unsigned i = 0; i < 3; ++i) { // choose entry of GM[]
            if (tg == GM[i].grain_size) {
                lookup = GM[i].lookup_level_cutoff;
                break;
            }
        }
        assert(lookup);

        for (int L = L0; L != MAX_LOOKUP_LEVELS; ++L) {
            if (tsz > lookup[L]) {
                start_lookup_level = (LookupLevel) L;
                break;
            }
        }
        panic_if(start_lookup_level == MAX_LOOKUP_LEVELS,
                 "Table walker couldn't find lookup level\n");
    }

    // Determine table base address
    int base_addr_lo = 3 + tsz - stride * (3 - start_lookup_level) - tg;
    Addr base_addr = mbits(ttbr, 47, base_addr_lo);

    // Determine physical address size and raise an Address Size Fault if
    // necessary
    int pa_range = decodePhysAddrRange64(ps);
    // Clamp to lower limit
    if (pa_range > physAddrRange)
        currState->physAddrRange = physAddrRange;
    else
        currState->physAddrRange = pa_range;
    if (checkAddrSizeFaultAArch64(base_addr, currState->physAddrRange)) {
        DPRINTF(TLB, "Address size fault before any lookup\n");
        Fault f;
        if (currState->isFetch)
            f = new PrefetchAbort(currState->vaddr_tainted,
                                     ArmFault::AddressSizeLL + start_lookup_level,
                                     isStage2,
                                     ArmFault::LpaeTran);
        else
            f = new DataAbort(currState->vaddr_tainted,
                                 TlbEntry::DomainType::NoAccess,
                                 currState->isWrite,
                                 ArmFault::AddressSizeLL + start_lookup_level,
                                 isStage2,
                                 ArmFault::LpaeTran);


        if (currState->timing) {
            pending = false;
            nextWalk(currState->tc);
            currState = NULL;
        } else {
            currState->tc = NULL;
            currState->req = NULL;
        }
        return f;

   }

    // Determine descriptor address
    Addr desc_addr = base_addr |
        (bits(currState->vaddr, tsz - 1,
              stride * (3 - start_lookup_level) + tg) << 3);

    // Trickbox address check
    Fault f = tlb->walkTrickBoxCheck(desc_addr, currState->isSecure,
                        currState->vaddr, sizeof(uint64_t), currState->isFetch,
                        currState->isWrite, TlbEntry::DomainType::NoAccess,
                        start_lookup_level);
    if (f) {
        DPRINTF(TLB, "Trickbox check caused fault on %#x\n", currState->vaddr_tainted);
        if (currState->timing) {
            pending = false;
            nextWalk(currState->tc);
            currState = NULL;
        } else {
            currState->tc = NULL;
            currState->req = NULL;
        }
        return f;
    }

    Request::Flags flag = 0;
    if (currState->sctlr.c == 0) {
        flag = Request::UNCACHEABLE;
    }

    currState->longDesc.lookupLevel = start_lookup_level;
    currState->longDesc.aarch64 = true;
    currState->longDesc.grainSize = tg;

    if (currState->timing) {
        Event *event;
        switch (start_lookup_level) {
          case L0:
            event = (Event *) &doL0LongDescEvent;
            break;
          case L1:
            event = (Event *) &doL1LongDescEvent;
            break;
          case L2:
            event = (Event *) &doL2LongDescEvent;
            break;
          case L3:
            event = (Event *) &doL3LongDescEvent;
            break;
          default:
            panic("Invalid table lookup level");
            break;
        }
        port.dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t), event,
                       (uint8_t*) &currState->longDesc.data,
                       currState->tc->getCpuPtr()->clockPeriod(), flag);
        DPRINTF(TLBVerbose,
                "Adding to walker fifo: queue size before adding: %d\n",
                stateQueues[start_lookup_level].size());
        stateQueues[start_lookup_level].push_back(currState);
        currState = NULL;
    } else if (!currState->functional) {
        port.dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t),
                       NULL, (uint8_t*) &currState->longDesc.data,
                       currState->tc->getCpuPtr()->clockPeriod(), flag);
        doLongDescriptor();
        f = currState->fault;
    } else {
        RequestPtr req = new Request(desc_addr, sizeof(uint64_t), flag,
                                     masterId);
        PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
        pkt->dataStatic((uint8_t*) &currState->longDesc.data);
        port.sendFunctional(pkt);
        doLongDescriptor();
        delete req;
        delete pkt;
        f = currState->fault;
    }

    return f;
}

void
TableWalker::memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr,
                      uint8_t texcb, bool s)
{
    // Note: tc and sctlr local variables are hiding tc and sctrl class
    // variables
    DPRINTF(TLBVerbose, "memAttrs texcb:%d s:%d\n", texcb, s);
    te.shareable = false; // default value
    te.nonCacheable = false;
    te.outerShareable = false;
    if (sctlr.tre == 0 || ((sctlr.tre == 1) && (sctlr.m == 0))) {
        switch(texcb) {
          case 0: // Stongly-ordered
            te.nonCacheable = true;
            te.mtype = TlbEntry::MemoryType::StronglyOrdered;
            te.shareable = true;
            te.innerAttrs = 1;
            te.outerAttrs = 0;
            break;
          case 1: // Shareable Device
            te.nonCacheable = true;
            te.mtype = TlbEntry::MemoryType::Device;
            te.shareable = true;
            te.innerAttrs = 3;
            te.outerAttrs = 0;
            break;
          case 2: // Outer and Inner Write-Through, no Write-Allocate
            te.mtype = TlbEntry::MemoryType::Normal;
            te.shareable = s;
            te.innerAttrs = 6;
            te.outerAttrs = bits(texcb, 1, 0);
            break;
          case 3: // Outer and Inner Write-Back, no Write-Allocate
            te.mtype = TlbEntry::MemoryType::Normal;
            te.shareable = s;
            te.innerAttrs = 7;
            te.outerAttrs = bits(texcb, 1, 0);
            break;
          case 4: // Outer and Inner Non-cacheable
            te.nonCacheable = true;
            te.mtype = TlbEntry::MemoryType::Normal;
            te.shareable = s;
            te.innerAttrs = 0;
            te.outerAttrs = bits(texcb, 1, 0);
            break;
          case 5: // Reserved
            panic("Reserved texcb value!\n");
            break;
          case 6: // Implementation Defined
            panic("Implementation-defined texcb value!\n");
            break;
          case 7: // Outer and Inner Write-Back, Write-Allocate
            te.mtype = TlbEntry::MemoryType::Normal;
            te.shareable = s;
            te.innerAttrs = 5;
            te.outerAttrs = 1;
            break;
          case 8: // Non-shareable Device
            te.nonCacheable = true;
            te.mtype = TlbEntry::MemoryType::Device;
            te.shareable = false;
            te.innerAttrs = 3;
            te.outerAttrs = 0;
            break;
          case 9 ... 15:  // Reserved
            panic("Reserved texcb value!\n");
            break;
          case 16 ... 31: // Cacheable Memory
            te.mtype = TlbEntry::MemoryType::Normal;
            te.shareable = s;
            if (bits(texcb, 1,0) == 0 || bits(texcb, 3,2) == 0)
                te.nonCacheable = true;
            te.innerAttrs = bits(texcb, 1, 0);
            te.outerAttrs = bits(texcb, 3, 2);
            break;
          default:
            panic("More than 32 states for 5 bits?\n");
        }
    } else {
        assert(tc);
        PRRR prrr = tc->readMiscReg(flattenMiscRegNsBanked(MISCREG_PRRR,
                                    currState->tc, !currState->isSecure));
        NMRR nmrr = tc->readMiscReg(flattenMiscRegNsBanked(MISCREG_NMRR,
                                    currState->tc, !currState->isSecure));
        DPRINTF(TLBVerbose, "memAttrs PRRR:%08x NMRR:%08x\n", prrr, nmrr);
        uint8_t curr_tr = 0, curr_ir = 0, curr_or = 0;
        switch(bits(texcb, 2,0)) {
          case 0:
            curr_tr = prrr.tr0;
            curr_ir = nmrr.ir0;
            curr_or = nmrr.or0;
            te.outerShareable = (prrr.nos0 == 0);
            break;
          case 1:
            curr_tr = prrr.tr1;
            curr_ir = nmrr.ir1;
            curr_or = nmrr.or1;
            te.outerShareable = (prrr.nos1 == 0);
            break;
          case 2:
            curr_tr = prrr.tr2;
            curr_ir = nmrr.ir2;
            curr_or = nmrr.or2;
            te.outerShareable = (prrr.nos2 == 0);
            break;
          case 3:
            curr_tr = prrr.tr3;
            curr_ir = nmrr.ir3;
            curr_or = nmrr.or3;
            te.outerShareable = (prrr.nos3 == 0);
            break;
          case 4:
            curr_tr = prrr.tr4;
            curr_ir = nmrr.ir4;
            curr_or = nmrr.or4;
            te.outerShareable = (prrr.nos4 == 0);
            break;
          case 5:
            curr_tr = prrr.tr5;
            curr_ir = nmrr.ir5;
            curr_or = nmrr.or5;
            te.outerShareable = (prrr.nos5 == 0);
            break;
          case 6:
            panic("Imp defined type\n");
          case 7:
            curr_tr = prrr.tr7;
            curr_ir = nmrr.ir7;
            curr_or = nmrr.or7;
            te.outerShareable = (prrr.nos7 == 0);
            break;
        }

        switch(curr_tr) {
          case 0:
            DPRINTF(TLBVerbose, "StronglyOrdered\n");
            te.mtype = TlbEntry::MemoryType::StronglyOrdered;
            te.nonCacheable = true;
            te.innerAttrs = 1;
            te.outerAttrs = 0;
            te.shareable = true;
            break;
          case 1:
            DPRINTF(TLBVerbose, "Device ds1:%d ds0:%d s:%d\n",
                    prrr.ds1, prrr.ds0, s);
            te.mtype = TlbEntry::MemoryType::Device;
            te.nonCacheable = true;
            te.innerAttrs = 3;
            te.outerAttrs = 0;
            if (prrr.ds1 && s)
                te.shareable = true;
            if (prrr.ds0 && !s)
                te.shareable = true;
            break;
          case 2:
            DPRINTF(TLBVerbose, "Normal ns1:%d ns0:%d s:%d\n",
                    prrr.ns1, prrr.ns0, s);
            te.mtype = TlbEntry::MemoryType::Normal;
            if (prrr.ns1 && s)
                te.shareable = true;
            if (prrr.ns0 && !s)
                te.shareable = true;
            break;
          case 3:
            panic("Reserved type");
        }

        if (te.mtype == TlbEntry::MemoryType::Normal){
            switch(curr_ir) {
              case 0:
                te.nonCacheable = true;
                te.innerAttrs = 0;
                break;
              case 1:
                te.innerAttrs = 5;
                break;
              case 2:
                te.innerAttrs = 6;
                break;
              case 3:
                te.innerAttrs = 7;
                break;
            }

            switch(curr_or) {
              case 0:
                te.nonCacheable = true;
                te.outerAttrs = 0;
                break;
              case 1:
                te.outerAttrs = 1;
                break;
              case 2:
                te.outerAttrs = 2;
                break;
              case 3:
                te.outerAttrs = 3;
                break;
            }
        }
    }
    DPRINTF(TLBVerbose, "memAttrs: shareable: %d, innerAttrs: %d, "
            "outerAttrs: %d\n",
            te.shareable, te.innerAttrs, te.outerAttrs);
    te.setAttributes(false);
}

void
TableWalker::memAttrsLPAE(ThreadContext *tc, TlbEntry &te,
    LongDescriptor &lDescriptor)
{
    assert(_haveLPAE);

    uint8_t attr;
    uint8_t sh = lDescriptor.sh();
    // Different format and source of attributes if this is a stage 2
    // translation
    if (isStage2) {
        attr = lDescriptor.memAttr();
        uint8_t attr_3_2 = (attr >> 2) & 0x3;
        uint8_t attr_1_0 =  attr       & 0x3;

        DPRINTF(TLBVerbose, "memAttrsLPAE MemAttr:%#x sh:%#x\n", attr, sh);

        if (attr_3_2 == 0) {
            te.mtype        = attr_1_0 == 0 ? TlbEntry::MemoryType::StronglyOrdered
                                            : TlbEntry::MemoryType::Device;
            te.outerAttrs   = 0;
            te.innerAttrs   = attr_1_0 == 0 ? 1 : 3;
            te.nonCacheable = true;
        } else {
            te.mtype        = TlbEntry::MemoryType::Normal;
            te.outerAttrs   = attr_3_2 == 1 ? 0 :
                              attr_3_2 == 2 ? 2 : 1;
            te.innerAttrs   = attr_1_0 == 1 ? 0 :
                              attr_1_0 == 2 ? 6 : 5;
            te.nonCacheable = (attr_3_2 == 1) || (attr_1_0 == 1);
        }
    } else {
        uint8_t attrIndx = lDescriptor.attrIndx();

        // LPAE always uses remapping of memory attributes, irrespective of the
        // value of SCTLR.TRE
        MiscRegIndex reg = attrIndx & 0x4 ? MISCREG_MAIR1 : MISCREG_MAIR0;
        int reg_as_int = flattenMiscRegNsBanked(reg, currState->tc,
                                                !currState->isSecure);
        uint32_t mair = currState->tc->readMiscReg(reg_as_int);
        attr = (mair >> (8 * (attrIndx % 4))) & 0xff;
        uint8_t attr_7_4 = bits(attr, 7, 4);
        uint8_t attr_3_0 = bits(attr, 3, 0);
        DPRINTF(TLBVerbose, "memAttrsLPAE AttrIndx:%#x sh:%#x, attr %#x\n", attrIndx, sh, attr);

        // Note: the memory subsystem only cares about the 'cacheable' memory
        // attribute. The other attributes are only used to fill the PAR register
        // accordingly to provide the illusion of full support
        te.nonCacheable = false;

        switch (attr_7_4) {
          case 0x0:
            // Strongly-ordered or Device memory
            if (attr_3_0 == 0x0)
                te.mtype = TlbEntry::MemoryType::StronglyOrdered;
            else if (attr_3_0 == 0x4)
                te.mtype = TlbEntry::MemoryType::Device;
            else
                panic("Unpredictable behavior\n");
            te.nonCacheable = true;
            te.outerAttrs   = 0;
            break;
          case 0x4:
            // Normal memory, Outer Non-cacheable
            te.mtype = TlbEntry::MemoryType::Normal;
            te.outerAttrs = 0;
            if (attr_3_0 == 0x4)
                // Inner Non-cacheable
                te.nonCacheable = true;
            else if (attr_3_0 < 0x8)
                panic("Unpredictable behavior\n");
            break;
          case 0x8:
          case 0x9:
          case 0xa:
          case 0xb:
          case 0xc:
          case 0xd:
          case 0xe:
          case 0xf:
            if (attr_7_4 & 0x4) {
                te.outerAttrs = (attr_7_4 & 1) ? 1 : 3;
            } else {
                te.outerAttrs = 0x2;
            }
            // Normal memory, Outer Cacheable
            te.mtype = TlbEntry::MemoryType::Normal;
            if (attr_3_0 != 0x4 && attr_3_0 < 0x8)
                panic("Unpredictable behavior\n");
            break;
          default:
            panic("Unpredictable behavior\n");
            break;
        }

        switch (attr_3_0) {
          case 0x0:
            te.innerAttrs = 0x1;
            break;
          case 0x4:
            te.innerAttrs = attr_7_4 == 0 ? 0x3 : 0;
            break;
          case 0x8:
          case 0x9:
          case 0xA:
          case 0xB:
            te.innerAttrs = 6;
            break;
          case 0xC:
          case 0xD:
          case 0xE:
          case 0xF:
            te.innerAttrs = attr_3_0 & 1 ? 0x5 : 0x7;
            break;
          default:
            panic("Unpredictable behavior\n");
            break;
        }
    }

    te.outerShareable = sh == 2;
    te.shareable       = (sh & 0x2) ? true : false;
    te.setAttributes(true);
    te.attributes |= (uint64_t) attr << 56;
}

void
TableWalker::memAttrsAArch64(ThreadContext *tc, TlbEntry &te, uint8_t attrIndx,
                             uint8_t sh)
{
    DPRINTF(TLBVerbose, "memAttrsAArch64 AttrIndx:%#x sh:%#x\n", attrIndx, sh);

    // Select MAIR
    uint64_t mair;
    switch (currState->el) {
      case EL0:
      case EL1:
        mair = tc->readMiscReg(MISCREG_MAIR_EL1);
        break;
      case EL2:
        mair = tc->readMiscReg(MISCREG_MAIR_EL2);
        break;
      case EL3:
        mair = tc->readMiscReg(MISCREG_MAIR_EL3);
        break;
      default:
        panic("Invalid exception level");
        break;
    }

    // Select attributes
    uint8_t attr = bits(mair, 8 * attrIndx + 7, 8 * attrIndx);
    uint8_t attr_lo = bits(attr, 3, 0);
    uint8_t attr_hi = bits(attr, 7, 4);

    // Memory type
    te.mtype = attr_hi == 0 ? TlbEntry::MemoryType::Device : TlbEntry::MemoryType::Normal;

    // Cacheability
    te.nonCacheable = false;
    if (te.mtype == TlbEntry::MemoryType::Device ||  // Device memory
        attr_hi == 0x8 ||  // Normal memory, Outer Non-cacheable
        attr_lo == 0x8) {  // Normal memory, Inner Non-cacheable
        te.nonCacheable = true;
    }

    te.shareable       = sh == 2;
    te.outerShareable = (sh & 0x2) ? true : false;
    // Attributes formatted according to the 64-bit PAR
    te.attributes = ((uint64_t) attr << 56) |
        (1 << 11) |     // LPAE bit
        (te.ns << 9) |  // NS bit
        (sh << 7);
}

void
TableWalker::doL1Descriptor()
{
    if (currState->fault != NoFault) {
        return;
    }

    DPRINTF(TLB, "L1 descriptor for %#x is %#x\n",
            currState->vaddr_tainted, currState->l1Desc.data);
    TlbEntry te;

    switch (currState->l1Desc.type()) {
      case L1Descriptor::Ignore:
      case L1Descriptor::Reserved:
        if (!currState->timing) {
            currState->tc = NULL;
            currState->req = NULL;
        }
        DPRINTF(TLB, "L1 Descriptor Reserved/Ignore, causing fault\n");
        if (currState->isFetch)
            currState->fault =
                new PrefetchAbort(currState->vaddr_tainted,
                                  ArmFault::TranslationLL + L1,
                                  isStage2,
                                  ArmFault::VmsaTran);
        else
            currState->fault =
                new DataAbort(currState->vaddr_tainted,
                              TlbEntry::DomainType::NoAccess,
                              currState->isWrite,
                              ArmFault::TranslationLL + L1, isStage2,
                              ArmFault::VmsaTran);
        return;
      case L1Descriptor::Section:
        if (currState->sctlr.afe && bits(currState->l1Desc.ap(), 0) == 0) {
            /** @todo: check sctlr.ha (bit[17]) if Hardware Access Flag is
              * enabled if set, do l1.Desc.setAp0() instead of generating
              * AccessFlag0
              */

            currState->fault = new DataAbort(currState->vaddr_tainted,
                                             currState->l1Desc.domain(),
                                             currState->isWrite,
                                             ArmFault::AccessFlagLL + L1,
                                             isStage2,
                                             ArmFault::VmsaTran);
        }
        if (currState->l1Desc.supersection()) {
            panic("Haven't implemented supersections\n");
        }
        insertTableEntry(currState->l1Desc, false);
        return;
      case L1Descriptor::PageTable:
        {
            Addr l2desc_addr;
            l2desc_addr = currState->l1Desc.l2Addr() |
                (bits(currState->vaddr, 19, 12) << 2);
            DPRINTF(TLB, "L1 descriptor points to page table at: %#x (%s)\n",
                    l2desc_addr, currState->isSecure ? "s" : "ns");

            // Trickbox address check
            currState->fault = tlb->walkTrickBoxCheck(
                l2desc_addr, currState->isSecure, currState->vaddr,
                sizeof(uint32_t), currState->isFetch, currState->isWrite,
                currState->l1Desc.domain(), L2);

            if (currState->fault) {
                if (!currState->timing) {
                    currState->tc = NULL;
                    currState->req = NULL;
                }
                return;
            }

            Request::Flags flag = 0;
            if (currState->isSecure)
                flag.set(Request::SECURE);

            bool delayed;
            delayed = fetchDescriptor(l2desc_addr,
                                      (uint8_t*)&currState->l2Desc.data,
                                      sizeof(uint32_t), flag, -1, &doL2DescEvent,
                                      &TableWalker::doL2Descriptor);
            if (delayed) {
                currState->delayed = true;
            }

            return;
        }
      default:
        panic("A new type in a 2 bit field?\n");
    }
}

void
TableWalker::doLongDescriptor()
{
    if (currState->fault != NoFault) {
        return;
    }

    DPRINTF(TLB, "L%d descriptor for %#llx is %#llx (%s)\n",
            currState->longDesc.lookupLevel, currState->vaddr_tainted,
            currState->longDesc.data,
            currState->aarch64 ? "AArch64" : "long-desc.");

    if ((currState->longDesc.type() == LongDescriptor::Block) ||
        (currState->longDesc.type() == LongDescriptor::Page)) {
        DPRINTF(TLBVerbose, "Analyzing L%d descriptor: %#llx, pxn: %d, "
                "xn: %d, ap: %d, af: %d, type: %d\n",
                currState->longDesc.lookupLevel,
                currState->longDesc.data,
                currState->longDesc.pxn(),
                currState->longDesc.xn(),
                currState->longDesc.ap(),
                currState->longDesc.af(),
                currState->longDesc.type());
    } else {
        DPRINTF(TLBVerbose, "Analyzing L%d descriptor: %#llx, type: %d\n",
                currState->longDesc.lookupLevel,
                currState->longDesc.data,
                currState->longDesc.type());
    }

    TlbEntry te;

    switch (currState->longDesc.type()) {
      case LongDescriptor::Invalid:
        if (!currState->timing) {
            currState->tc = NULL;
            currState->req = NULL;
        }

        DPRINTF(TLB, "L%d descriptor Invalid, causing fault type %d\n",
                currState->longDesc.lookupLevel,
                ArmFault::TranslationLL + currState->longDesc.lookupLevel);
        if (currState->isFetch)
            currState->fault = new PrefetchAbort(
                currState->vaddr_tainted,
                ArmFault::TranslationLL + currState->longDesc.lookupLevel,
                isStage2,
                ArmFault::LpaeTran);
        else
            currState->fault = new DataAbort(
                currState->vaddr_tainted,
                TlbEntry::DomainType::NoAccess,
                currState->isWrite,
                ArmFault::TranslationLL + currState->longDesc.lookupLevel,
                isStage2,
                ArmFault::LpaeTran);
        return;
      case LongDescriptor::Block:
      case LongDescriptor::Page:
        {
            bool fault = false;
            bool aff = false;
            // Check for address size fault
            if (checkAddrSizeFaultAArch64(
                    mbits(currState->longDesc.data, MaxPhysAddrRange - 1,
                          currState->longDesc.offsetBits()),
                    currState->physAddrRange)) {
                fault = true;
                DPRINTF(TLB, "L%d descriptor causing Address Size Fault\n",
                        currState->longDesc.lookupLevel);
            // Check for access fault
            } else if (currState->longDesc.af() == 0) {
                fault = true;
                DPRINTF(TLB, "L%d descriptor causing Access Fault\n",
                        currState->longDesc.lookupLevel);
                aff = true;
            }
            if (fault) {
                if (currState->isFetch)
                    currState->fault = new PrefetchAbort(
                        currState->vaddr_tainted,
                        (aff ? ArmFault::AccessFlagLL : ArmFault::AddressSizeLL) +
                        currState->longDesc.lookupLevel,
                        isStage2,
                        ArmFault::LpaeTran);
                else
                    currState->fault = new DataAbort(
                        currState->vaddr_tainted,
                        TlbEntry::DomainType::NoAccess, currState->isWrite,
                        (aff ? ArmFault::AccessFlagLL : ArmFault::AddressSizeLL) +
                        currState->longDesc.lookupLevel,
                        isStage2,
                        ArmFault::LpaeTran);
            } else {
                insertTableEntry(currState->longDesc, true);
            }
        }
        return;
      case LongDescriptor::Table:
        {
            // Set hierarchical permission flags
            currState->secureLookup = currState->secureLookup &&
                currState->longDesc.secureTable();
            currState->rwTable = currState->rwTable &&
                currState->longDesc.rwTable();
            currState->userTable = currState->userTable &&
                currState->longDesc.userTable();
            currState->xnTable = currState->xnTable ||
                currState->longDesc.xnTable();
            currState->pxnTable = currState->pxnTable ||
                currState->longDesc.pxnTable();

            // Set up next level lookup
            Addr next_desc_addr = currState->longDesc.nextDescAddr(
                currState->vaddr);

            DPRINTF(TLB, "L%d descriptor points to L%d descriptor at: %#x (%s)\n",
                    currState->longDesc.lookupLevel,
                    currState->longDesc.lookupLevel + 1,
                    next_desc_addr,
                    currState->secureLookup ? "s" : "ns");

            // Check for address size fault
            if (currState->aarch64 && checkAddrSizeFaultAArch64(
                    next_desc_addr, currState->physAddrRange)) {
                DPRINTF(TLB, "L%d descriptor causing Address Size Fault\n",
                        currState->longDesc.lookupLevel);
                if (currState->isFetch)
                    currState->fault = new PrefetchAbort(
                        currState->vaddr_tainted,
                        ArmFault::AddressSizeLL
                        + currState->longDesc.lookupLevel,
                        isStage2,
                        ArmFault::LpaeTran);
                else
                    currState->fault = new DataAbort(
                        currState->vaddr_tainted,
                        TlbEntry::DomainType::NoAccess, currState->isWrite,
                        ArmFault::AddressSizeLL
                        + currState->longDesc.lookupLevel,
                        isStage2,
                        ArmFault::LpaeTran);
                return;
            }

            // Trickbox address check
            currState->fault = tlb->walkTrickBoxCheck(
                            next_desc_addr, currState->vaddr,
                            currState->vaddr, sizeof(uint64_t),
                            currState->isFetch, currState->isWrite,
                            TlbEntry::DomainType::Client,
                            toLookupLevel(currState->longDesc.lookupLevel +1));

            if (currState->fault) {
                if (!currState->timing) {
                    currState->tc = NULL;
                    currState->req = NULL;
                }
                return;
            }

            Request::Flags flag = 0;
            if (currState->secureLookup)
                flag.set(Request::SECURE);

            currState->longDesc.lookupLevel =
                (LookupLevel) (currState->longDesc.lookupLevel + 1);
            Event *event = NULL;
            switch (currState->longDesc.lookupLevel) {
              case L1:
                assert(currState->aarch64);
                event = &doL1LongDescEvent;
                break;
              case L2:
                event = &doL2LongDescEvent;
                break;
              case L3:
                event = &doL3LongDescEvent;
                break;
              default:
                panic("Wrong lookup level in table walk\n");
                break;
            }

            bool delayed;
            delayed = fetchDescriptor(next_desc_addr, (uint8_t*)&currState->longDesc.data,
                                      sizeof(uint64_t), flag, -1, event,
                                      &TableWalker::doLongDescriptor);
            if (delayed) {
                 currState->delayed = true;
            }
        }
        return;
      default:
        panic("A new type in a 2 bit field?\n");
    }
}

void
TableWalker::doL2Descriptor()
{
    if (currState->fault != NoFault) {
        return;
    }

    DPRINTF(TLB, "L2 descriptor for %#x is %#x\n",
            currState->vaddr_tainted, currState->l2Desc.data);
    TlbEntry te;

    if (currState->l2Desc.invalid()) {
        DPRINTF(TLB, "L2 descriptor invalid, causing fault\n");
        if (!currState->timing) {
            currState->tc = NULL;
            currState->req = NULL;
        }
        if (currState->isFetch)
            currState->fault =
                new PrefetchAbort(currState->vaddr_tainted,
                                  ArmFault::TranslationLL + L2,
                                  isStage2,
                                  ArmFault::VmsaTran);
        else
            currState->fault =
                new DataAbort(currState->vaddr_tainted, currState->l1Desc.domain(),
                              currState->isWrite, ArmFault::TranslationLL + L2,
                              isStage2,
                              ArmFault::VmsaTran);
        return;
    }

    if (currState->sctlr.afe && bits(currState->l2Desc.ap(), 0) == 0) {
        /** @todo: check sctlr.ha (bit[17]) if Hardware Access Flag is enabled
          * if set, do l2.Desc.setAp0() instead of generating AccessFlag0
          */
         DPRINTF(TLB, "Generating access fault at L2, afe: %d, ap: %d\n",
                 currState->sctlr.afe, currState->l2Desc.ap());

        currState->fault =
            new DataAbort(currState->vaddr_tainted,
                          TlbEntry::DomainType::NoAccess, currState->isWrite,
                          ArmFault::AccessFlagLL + L2, isStage2,
                          ArmFault::VmsaTran);
    }

    insertTableEntry(currState->l2Desc, false);
}

void
TableWalker::doL1DescriptorWrapper()
{
    currState = stateQueues[L1].front();
    currState->delayed = false;
    // if there's a stage2 translation object we don't need it any more
    if (currState->stage2Tran) {
        delete currState->stage2Tran;
        currState->stage2Tran = NULL;
    }


    DPRINTF(TLBVerbose, "L1 Desc object host addr: %p\n",&currState->l1Desc.data);
    DPRINTF(TLBVerbose, "L1 Desc object      data: %08x\n",currState->l1Desc.data);

    DPRINTF(TLBVerbose, "calling doL1Descriptor for vaddr:%#x\n", currState->vaddr_tainted);
    doL1Descriptor();

    stateQueues[L1].pop_front();
    completeDrain();
    // Check if fault was generated
    if (currState->fault != NoFault) {
        currState->transState->finish(currState->fault, currState->req,
                                      currState->tc, currState->mode);

        pending = false;
        nextWalk(currState->tc);

        currState->req = NULL;
        currState->tc = NULL;
        currState->delayed = false;
        delete currState;
    }
    else if (!currState->delayed) {
        // delay is not set so there is no L2 to do
        // Don't finish the translation if a stage 2 look up is underway
        if (!currState->doingStage2) {
            DPRINTF(TLBVerbose, "calling translateTiming again\n");
            currState->fault = tlb->translateTiming(currState->req, currState->tc,
                currState->transState, currState->mode);
        }

        pending = false;
        nextWalk(currState->tc);

        currState->req = NULL;
        currState->tc = NULL;
        currState->delayed = false;
        delete currState;
    } else {
        // need to do L2 descriptor
        stateQueues[L2].push_back(currState);
    }
    currState = NULL;
}

void
TableWalker::doL2DescriptorWrapper()
{
    currState = stateQueues[L2].front();
    assert(currState->delayed);
    // if there's a stage2 translation object we don't need it any more
    if (currState->stage2Tran) {
        delete currState->stage2Tran;
        currState->stage2Tran = NULL;
    }

    DPRINTF(TLBVerbose, "calling doL2Descriptor for vaddr:%#x\n",
            currState->vaddr_tainted);
    doL2Descriptor();

    // Check if fault was generated
    if (currState->fault != NoFault) {
        currState->transState->finish(currState->fault, currState->req,
                                      currState->tc, currState->mode);
    }
    else {
        // Don't finish the translation if a stage 2 look up is underway
        if (!currState->doingStage2) {
            DPRINTF(TLBVerbose, "calling translateTiming again\n");
            currState->fault = tlb->translateTiming(currState->req,
                currState->tc, currState->transState, currState->mode);
        }
    }


    stateQueues[L2].pop_front();
    completeDrain();
    pending = false;
    nextWalk(currState->tc);

    currState->req = NULL;
    currState->tc = NULL;
    currState->delayed = false;

    delete currState;
    currState = NULL;
}

void
TableWalker::doL0LongDescriptorWrapper()
{
    doLongDescriptorWrapper(L0);
}

void
TableWalker::doL1LongDescriptorWrapper()
{
    doLongDescriptorWrapper(L1);
}

void
TableWalker::doL2LongDescriptorWrapper()
{
    doLongDescriptorWrapper(L2);
}

void
TableWalker::doL3LongDescriptorWrapper()
{
    doLongDescriptorWrapper(L3);
}

void
TableWalker::doLongDescriptorWrapper(LookupLevel curr_lookup_level)
{
    currState = stateQueues[curr_lookup_level].front();
    assert(curr_lookup_level == currState->longDesc.lookupLevel);
    currState->delayed = false;

    // if there's a stage2 translation object we don't need it any more
    if (currState->stage2Tran) {
        delete currState->stage2Tran;
        currState->stage2Tran = NULL;
    }

    DPRINTF(TLBVerbose, "calling doLongDescriptor for vaddr:%#x\n",
            currState->vaddr_tainted);
    doLongDescriptor();

    stateQueues[curr_lookup_level].pop_front();

    if (currState->fault != NoFault) {
        // A fault was generated
        currState->transState->finish(currState->fault, currState->req,
                                      currState->tc, currState->mode);

        pending = false;
        nextWalk(currState->tc);

        currState->req = NULL;
        currState->tc = NULL;
        currState->delayed = false;
        delete currState;
    } else if (!currState->delayed) {
        // No additional lookups required
        // Don't finish the translation if a stage 2 look up is underway
        if (!currState->doingStage2) {
            DPRINTF(TLBVerbose, "calling translateTiming again\n");
            currState->fault = tlb->translateTiming(currState->req, currState->tc,
                                                    currState->transState,
                                                    currState->mode);
        }

        pending = false;
        nextWalk(currState->tc);

        currState->req = NULL;
        currState->tc = NULL;
        currState->delayed = false;
        delete currState;
    } else {
        if (curr_lookup_level >= MAX_LOOKUP_LEVELS - 1)
            panic("Max. number of lookups already reached in table walk\n");
        // Need to perform additional lookups
        stateQueues[currState->longDesc.lookupLevel].push_back(currState);
    }
    currState = NULL;
}


void
TableWalker::nextWalk(ThreadContext *tc)
{
    if (pendingQueue.size())
        schedule(doProcessEvent, clockEdge(Cycles(1)));
}

bool
TableWalker::fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes,
    Request::Flags flags, int queueIndex, Event *event,
    void (TableWalker::*doDescriptor)())
{
    bool isTiming = currState->timing;

    // do the requests for the page table descriptors have to go through the
    // second stage MMU
    if (currState->stage2Req) {
        Fault fault;
        flags = flags | TLB::MustBeOne;

        if (isTiming) {
            Stage2MMU::Stage2Translation *tran = new
                Stage2MMU::Stage2Translation(*stage2Mmu, data, event,
                                             currState->vaddr);
            currState->stage2Tran = tran;
            stage2Mmu->readDataTimed(currState->tc, descAddr, tran, numBytes,
                                     flags, masterId);
            fault = tran->fault;
        } else {
            fault = stage2Mmu->readDataUntimed(currState->tc,
                currState->vaddr, descAddr, data, numBytes, flags, masterId,
                currState->functional);
        }

        if (fault != NoFault) {
            currState->fault = fault;
        }
        if (isTiming) {
            if (queueIndex >= 0) {
                DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n",
                        stateQueues[queueIndex].size());
                stateQueues[queueIndex].push_back(currState);
                currState = NULL;
            }
        } else {
            (this->*doDescriptor)();
        }
    } else {
        if (isTiming) {
            port.dmaAction(MemCmd::ReadReq, descAddr, numBytes, event, data,
                           currState->tc->getCpuPtr()->clockPeriod(), flags);
            if (queueIndex >= 0) {
                DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n",
                        stateQueues[queueIndex].size());
                stateQueues[queueIndex].push_back(currState);
                currState = NULL;
            }
        } else if (!currState->functional) {
            port.dmaAction(MemCmd::ReadReq, descAddr, numBytes, NULL, data,
                           currState->tc->getCpuPtr()->clockPeriod(), flags);
            (this->*doDescriptor)();
        } else {
            RequestPtr req = new Request(descAddr, numBytes, flags, masterId);
            req->taskId(ContextSwitchTaskId::DMA);
            PacketPtr  pkt = new Packet(req, MemCmd::ReadReq);
            pkt->dataStatic(data);
            port.sendFunctional(pkt);
            (this->*doDescriptor)();
            delete req;
            delete pkt;
        }
    }
    return (isTiming);
}

void
TableWalker::insertTableEntry(DescriptorBase &descriptor, bool longDescriptor)
{
    TlbEntry te;

    // Create and fill a new page table entry
    te.valid          = true;
    te.longDescFormat = longDescriptor;
    te.isHyp          = currState->isHyp;
    te.asid           = currState->asid;
    te.vmid           = currState->vmid;
    te.N              = descriptor.offsetBits();
    te.vpn            = currState->vaddr >> te.N;
    te.size           = (1<<te.N) - 1;
    te.pfn            = descriptor.pfn();
    te.domain         = descriptor.domain();
    te.lookupLevel    = descriptor.lookupLevel;
    te.ns             = !descriptor.secure(haveSecurity, currState) || isStage2;
    te.nstid          = !currState->isSecure;
    te.xn             = descriptor.xn();
    if (currState->aarch64)
        te.el         = currState->el;
    else
        te.el         = 1;

    // ASID has no meaning for stage 2 TLB entries, so mark all stage 2 entries
    // as global
    te.global         = descriptor.global(currState) || isStage2;
    if (longDescriptor) {
        LongDescriptor lDescriptor =
            dynamic_cast<LongDescriptor &>(descriptor);

        te.xn |= currState->xnTable;
        te.pxn = currState->pxnTable || lDescriptor.pxn();
        if (isStage2) {
            // this is actually the HAP field, but its stored in the same bit
            // possitions as the AP field in a stage 1 translation.
            te.hap = lDescriptor.ap();
        } else {
           te.ap = ((!currState->rwTable || descriptor.ap() >> 1) << 1) |
               (currState->userTable && (descriptor.ap() & 0x1));
        }
        if (currState->aarch64)
            memAttrsAArch64(currState->tc, te, currState->longDesc.attrIndx(),
                            currState->longDesc.sh());
        else
            memAttrsLPAE(currState->tc, te, lDescriptor);
    } else {
        te.ap = descriptor.ap();
        memAttrs(currState->tc, te, currState->sctlr, descriptor.texcb(),
                 descriptor.shareable());
    }

    // Debug output
    DPRINTF(TLB, descriptor.dbgHeader().c_str());
    DPRINTF(TLB, " - N:%d pfn:%#x size:%#x global:%d valid:%d\n",
            te.N, te.pfn, te.size, te.global, te.valid);
    DPRINTF(TLB, " - vpn:%#x xn:%d pxn:%d ap:%d domain:%d asid:%d "
            "vmid:%d hyp:%d nc:%d ns:%d\n", te.vpn, te.xn, te.pxn,
            te.ap, static_cast<uint8_t>(te.domain), te.asid, te.vmid, te.isHyp,
            te.nonCacheable, te.ns);
    DPRINTF(TLB, " - domain from L%d desc:%d data:%#x\n",
            descriptor.lookupLevel, static_cast<uint8_t>(descriptor.domain()),
            descriptor.getRawData());

    // Insert the entry into the TLB
    tlb->insert(currState->vaddr, te);
    if (!currState->timing) {
        currState->tc  = NULL;
        currState->req = NULL;
    }
}

ArmISA::TableWalker *
ArmTableWalkerParams::create()
{
    return new ArmISA::TableWalker(this);
}

LookupLevel
TableWalker::toLookupLevel(uint8_t lookup_level_as_int)
{
    switch (lookup_level_as_int) {
      case L1:
        return L1;
      case L2:
        return L2;
      case L3:
        return L3;
      default:
        panic("Invalid lookup level conversion");
    }
}
