/*
 * Copyright (c) 2010, 2012-2019, 2021-2022 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.
 */
#include "arch/arm/table_walker.hh"

#include <cassert>
#include <memory>

#include "arch/arm/faults.hh"
#include "arch/arm/mmu.hh"
#include "arch/arm/pagetable.hh"
#include "arch/arm/system.hh"
#include "arch/arm/tlb.hh"
#include "base/compiler.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "debug/Checkpoint.hh"
#include "debug/Drain.hh"
#include "debug/PageTableWalker.hh"
#include "debug/TLB.hh"
#include "debug/TLBVerbose.hh"
#include "sim/system.hh"

namespace gem5
{

using namespace ArmISA;

TableWalker::TableWalker(const Params &p)
    : ClockedObject(p),
      requestorId(p.sys->getRequestorId(this)),
      port(new Port(this, requestorId)),
      isStage2(p.is_stage2), tlb(NULL),
      currState(NULL), pending(false),
      numSquashable(p.num_squash_per_cycle),
      release(nullptr),
      stats(this),
      pendingReqs(0),
      pendingChangeTick(curTick()),
      doL1DescEvent([this]{ doL1DescriptorWrapper(); }, name()),
      doL2DescEvent([this]{ doL2DescriptorWrapper(); }, name()),
      doL0LongDescEvent([this]{ doL0LongDescriptorWrapper(); }, name()),
      doL1LongDescEvent([this]{ doL1LongDescriptorWrapper(); }, name()),
      doL2LongDescEvent([this]{ doL2LongDescriptorWrapper(); }, name()),
      doL3LongDescEvent([this]{ doL3LongDescriptorWrapper(); }, name()),
      LongDescEventByLevel { &doL0LongDescEvent, &doL1LongDescEvent,
                             &doL2LongDescEvent, &doL3LongDescEvent },
      doProcessEvent([this]{ processWalkWrapper(); }, name())
{
    sctlr = 0;

    // Cache system-level properties
    if (FullSystem) {
        ArmSystem *arm_sys = dynamic_cast<ArmSystem *>(p.sys);
        assert(arm_sys);
        _physAddrRange = arm_sys->physAddrRange();
        _haveLargeAsid64 = arm_sys->haveLargeAsid64();
    } else {
        _haveLargeAsid64 = false;
        _physAddrRange = 48;
    }

}

TableWalker::~TableWalker()
{
    ;
}

TableWalker::Port &
TableWalker::getTableWalkerPort()
{
    return static_cast<Port&>(getPort("port"));
}

Port &
TableWalker::getPort(const std::string &if_name, PortID idx)
{
    if (if_name == "port") {
        return *port;
    }
    return ClockedObject::getPort(if_name, idx);
}

void
TableWalker::setMmu(MMU *_mmu)
{
    mmu = _mmu;
    release = mmu->release();
}

TableWalker::WalkerState::WalkerState() :
    tc(nullptr), aarch64(false), el(EL0), physAddrRange(0), req(nullptr),
    asid(0), vmid(0), isHyp(false), transState(nullptr),
    vaddr(0), vaddr_tainted(0),
    sctlr(0), scr(0), cpsr(0), tcr(0),
    htcr(0), hcr(0), vtcr(0),
    isWrite(false), isFetch(false), isSecure(false),
    isUncacheable(false),
    secureLookup(false), rwTable(false), userTable(false), xnTable(false),
    pxnTable(false), hpd(false), stage2Req(false),
    stage2Tran(nullptr), timing(false), functional(false),
    mode(BaseMMU::Read), tranType(MMU::NormalTran), l2Desc(l1Desc),
    delayed(false), tableWalker(nullptr)
{
}

TableWalker::Port::Port(TableWalker *_walker, RequestorID id)
  : QueuedRequestPort(_walker->name() + ".port", _walker,
        reqQueue, snoopRespQueue),
    reqQueue(*_walker, *this), snoopRespQueue(*_walker, *this),
    requestorId(id)
{
}

PacketPtr
TableWalker::Port::createPacket(
    Addr desc_addr, int size,
    uint8_t *data, Request::Flags flags, Tick delay,
    Event *event)
{
    RequestPtr req = std::make_shared<Request>(
        desc_addr, size, flags, requestorId);
    req->taskId(context_switch_task_id::DMA);

    PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
    pkt->dataStatic(data);

    auto state = new TableWalkerState;
    state->event = event;
    state->delay = delay;

    pkt->senderState = state;
    return pkt;
}

void
TableWalker::Port::sendFunctionalReq(
    Addr desc_addr, int size,
    uint8_t *data, Request::Flags flags)
{
    auto pkt = createPacket(desc_addr, size, data, flags, 0, nullptr);

    sendFunctional(pkt);

    handleRespPacket(pkt);
}

void
TableWalker::Port::sendAtomicReq(
    Addr desc_addr, int size,
    uint8_t *data, Request::Flags flags, Tick delay)
{
    auto pkt = createPacket(desc_addr, size, data, flags, delay, nullptr);

    Tick lat = sendAtomic(pkt);

    handleRespPacket(pkt, lat);
}

void
TableWalker::Port::sendTimingReq(
    Addr desc_addr, int size,
    uint8_t *data, Request::Flags flags, Tick delay,
    Event *event)
{
    auto pkt = createPacket(desc_addr, size, data, flags, delay, event);

    schedTimingReq(pkt, curTick());
}

bool
TableWalker::Port::recvTimingResp(PacketPtr pkt)
{
    // We shouldn't ever get a cacheable block in Modified state.
    assert(pkt->req->isUncacheable() ||
           !(pkt->cacheResponding() && !pkt->hasSharers()));

    handleRespPacket(pkt);

    return true;
}

void
TableWalker::Port::handleRespPacket(PacketPtr pkt, Tick delay)
{
    // Should always see a response with a sender state.
    assert(pkt->isResponse());

    // Get the DMA sender state.
    auto *state = dynamic_cast<TableWalkerState*>(pkt->senderState);
    assert(state);

    handleResp(state, pkt->getAddr(), pkt->req->getSize(), delay);

    delete pkt;
}

void
TableWalker::Port::handleResp(TableWalkerState *state, Addr addr,
                              Addr size, Tick delay)
{
    if (state->event) {
        owner.schedule(state->event, curTick() + delay);
    }
    delete state;
}

void
TableWalker::completeDrain()
{
    if (drainState() == DrainState::Draining &&
        stateQueues[LookupLevel::L0].empty() &&
        stateQueues[LookupLevel::L1].empty() &&
        stateQueues[LookupLevel::L2].empty() &&
        stateQueues[LookupLevel::L3].empty() &&
        pendingQueue.empty()) {

        DPRINTF(Drain, "TableWalker done draining, processing drain event\n");
        signalDrainDone();
    }
}

DrainState
TableWalker::drain()
{
    bool state_queues_not_empty = false;

    for (int i = 0; i < LookupLevel::Num_ArmLookupLevel; ++i) {
        if (!stateQueues[i].empty()) {
            state_queues_not_empty = true;
            break;
        }
    }

    if (state_queues_not_empty || pendingQueue.size()) {
        DPRINTF(Drain, "TableWalker not drained\n");
        return DrainState::Draining;
    } else {
        DPRINTF(Drain, "TableWalker free, no need to drain\n");
        return DrainState::Drained;
    }
}

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

Fault
TableWalker::walk(const RequestPtr &_req, ThreadContext *_tc, uint16_t _asid,
                  vmid_t _vmid, bool _isHyp, MMU::Mode _mode,
                  MMU::Translation *_trans, bool _timing, bool _functional,
                  bool secure, MMU::ArmTranslationType tranType,
                  bool _stage2Req, const TlbEntry *walk_entry)
{
    assert(!(_functional && _timing));
    ++stats.walks;

    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(PageTableWalker, "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(PageTableWalker,
                "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()) {
            ++stats.squashedBefore;
            return std::make_shared<ReExec>();
        }
    }
    pendingChange();

    currState->startTime = curTick();
    currState->tc = _tc;
    // ARM DDI 0487A.f (ARMv8 ARM) pg J8-5672
    // aarch32/translation/translation/AArch32.TranslateAddress dictates
    // even AArch32 EL0 will use AArch64 translation if EL1 is in AArch64.
    if (isStage2) {
        currState->el = EL1;
        currState->aarch64 = ELIs64(_tc, EL2);
    } else {
        currState->el =
            MMU::tranTypeEL(_tc->readMiscReg(MISCREG_CPSR), tranType);
        currState->aarch64 =
            ELIs64(_tc, currState->el == EL0 ? EL1 : currState->el);
    }
    currState->transState = _trans;
    currState->req = _req;
    if (walk_entry) {
        currState->walkEntry = *walk_entry;
    } else {
        currState->walkEntry = TlbEntry();
    }
    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,
                                            currState->mode==BaseMMU::Execute);
    else
        currState->vaddr = currState->vaddr_tainted;

    if (currState->aarch64) {
        currState->hcr = currState->tc->readMiscReg(MISCREG_HCR_EL2);
        if (isStage2) {
            currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL1);
            if (currState->secureLookup) {
                currState->vtcr =
                    currState->tc->readMiscReg(MISCREG_VSTCR_EL2);
            } else {
                currState->vtcr =
                    currState->tc->readMiscReg(MISCREG_VTCR_EL2);
            }
        } else switch (currState->el) {
          case EL0:
            if (HaveExt(currState->tc, ArmExtension::FEAT_VHE) &&
                  currState->hcr.tge == 1 && currState->hcr.e2h ==1) {
              currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL2);
              currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL2);
            } else {
              currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL1);
              currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL1);
            }
            break;
          case EL1:
            currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL1);
            currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL1);
            break;
          case EL2:
            assert(release->has(ArmExtension::VIRTUALIZATION));
            currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL2);
            currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL2);
            break;
          case EL3:
            assert(release->has(ArmExtension::SECURITY));
            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(snsBankedIndex(
            MISCREG_SCTLR, currState->tc, !currState->isSecure));
        currState->ttbcr = currState->tc->readMiscReg(snsBankedIndex(
            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 == BaseMMU::Execute);
    currState->isWrite = (currState->mode == BaseMMU::Write);

    stats.requestOrigin[REQUESTED][currState->isFetch]++;

    currState->stage2Req = _stage2Req && !isStage2;

    bool long_desc_format = currState->aarch64 || _isHyp || isStage2 ||
                            longDescFormatInUse(currState->tc);

    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;

        ++stats.walksLongDescriptor;
    } else {
        ++stats.walksShortDescriptor;
    }

    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;
        pendingChange();
    } else {
        pending = true;
        pendingChange();
        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());
    pendingChange();
    currState = pendingQueue.front();

    // 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 = mmu->lookup(currState->vaddr, currState->asid,
        currState->vmid, currState->isHyp, currState->isSecure, true, false,
        currState->el, false, isStage2, currState->mode);

    // 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 || te->partial)) {
        // We've got a valid request, lets process it
        pending = true;
        pendingQueue.pop_front();
        // Keep currState in case one of the processWalk... calls NULLs it

        if (te && te->partial) {
            currState->walkEntry = *te;
        }
        WalkerState *curr_state_copy = currState;
        Fault f;
        if (currState->aarch64)
            f = processWalkAArch64();
        else if (longDescFormatInUse(currState->tc) ||
                 currState->isHyp || isStage2)
            f = processWalkLPAE();
        else
            f = processWalk();

        if (f != NoFault) {
            curr_state_copy->transState->finish(f, curr_state_copy->req,
                    curr_state_copy->tc, curr_state_copy->mode);

            delete curr_state_copy;
        }
        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 && !te->partial))) {
        pendingQueue.pop_front();
        num_squashed++;
        stats.squashedBefore++;

        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(
                std::make_shared<UnimpFault>("Squashed Inst"),
                currState->req, currState->tc, currState->mode);
        } else {
            // translate the request now that we know it will work
            stats.walkServiceTime.sample(curTick() - currState->startTime);
            mmu->translateTiming(currState->req, currState->tc,
                currState->transState, currState->mode,
                currState->tranType, isStage2);
        }

        // delete the current request
        delete currState;

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

    // if we still have pending translations, schedule more work
    nextWalk(tc);
    currState = NULL;
}

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

    // For short descriptors, translation configs are held in
    // TTBR1.
    RegVal ttbr1 = currState->tc->readMiscReg(snsBankedIndex(
        MISCREG_TTBR1, currState->tc, !currState->isSecure));

    const auto irgn0_mask = 0x1;
    const auto irgn1_mask = 0x40;
    currState->isUncacheable = (ttbr1 & (irgn0_mask | irgn1_mask)) == 0;

    // If translation isn't enabled, we shouldn't be here
    assert(currState->sctlr.m || isStage2);
    const bool is_atomic = currState->req->isAtomic();
    const bool have_security = release->has(ArmExtension::SECURITY);

    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));

    stats.walkWaitTime.sample(curTick() - currState->startTime);

    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 (have_security && currState->ttbcr.pd0) {
            if (currState->isFetch)
                return std::make_shared<PrefetchAbort>(
                    currState->vaddr_tainted,
                    ArmFault::TranslationLL + LookupLevel::L1,
                    isStage2,
                    ArmFault::VmsaTran);
            else
                return std::make_shared<DataAbort>(
                    currState->vaddr_tainted,
                    TlbEntry::DomainType::NoAccess,
                    is_atomic ? false : currState->isWrite,
                    ArmFault::TranslationLL + LookupLevel::L1, isStage2,
                    ArmFault::VmsaTran);
        }
        ttbr = currState->tc->readMiscReg(snsBankedIndex(
            MISCREG_TTBR0, currState->tc, !currState->isSecure));
    } else {
        DPRINTF(TLB, " - Selecting TTBR1\n");
        // Check if table walk is allowed when Security Extensions are enabled
        if (have_security && currState->ttbcr.pd1) {
            if (currState->isFetch)
                return std::make_shared<PrefetchAbort>(
                    currState->vaddr_tainted,
                    ArmFault::TranslationLL + LookupLevel::L1,
                    isStage2,
                    ArmFault::VmsaTran);
            else
                return std::make_shared<DataAbort>(
                    currState->vaddr_tainted,
                    TlbEntry::DomainType::NoAccess,
                    is_atomic ? false : currState->isWrite,
                    ArmFault::TranslationLL + LookupLevel::L1, isStage2,
                    ArmFault::VmsaTran);
        }
        ttbr = ttbr1;
        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 = testWalk(l1desc_addr, sizeof(uint32_t),
                 TlbEntry::DomainType::NoAccess, LookupLevel::L1, isStage2);
    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 = Request::PT_WALK;
    if (currState->sctlr.c == 0 || currState->isUncacheable) {
        flag.set(Request::UNCACHEABLE);
    }

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

    bool delayed;
    delayed = fetchDescriptor(l1desc_addr, (uint8_t*)&currState->l1Desc.data,
                              sizeof(uint32_t), flag, LookupLevel::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 = LookupLevel::L1;

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

    stats.walkWaitTime.sample(curTick() - currState->startTime);

    Request::Flags flag = Request::PT_WALK;
    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 ?
            LookupLevel::L1 : LookupLevel::L2;
        currState->isUncacheable = currState->vtcr.irgn0 == 0;
    } else if (currState->isHyp) {
        DPRINTF(TLB, " - Selecting HTTBR (long-desc.)\n");
        ttbr = currState->tc->readMiscReg(MISCREG_HTTBR);
        tsz  = currState->htcr.t0sz;
        currState->isUncacheable = currState->htcr.irgn0 == 0;
    } else {
        assert(longDescFormatInUse(currState->tc));

        // 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));

        const bool is_atomic = currState->req->isAtomic();

        // 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 std::make_shared<PrefetchAbort>(
                        currState->vaddr_tainted,
                        ArmFault::TranslationLL + LookupLevel::L1,
                        isStage2,
                        ArmFault::LpaeTran);
                else
                    return std::make_shared<DataAbort>(
                        currState->vaddr_tainted,
                        TlbEntry::DomainType::NoAccess,
                        is_atomic ? false : currState->isWrite,
                        ArmFault::TranslationLL + LookupLevel::L1,
                        isStage2,
                        ArmFault::LpaeTran);
            }
            ttbr = currState->tc->readMiscReg(snsBankedIndex(
                MISCREG_TTBR0, currState->tc, !currState->isSecure));
            tsz = currState->ttbcr.t0sz;
            currState->isUncacheable = currState->ttbcr.irgn0 == 0;
            if (ttbr0_max < (1ULL << 30))  // Upper limit < 1 GiB
                start_lookup_level = LookupLevel::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 std::make_shared<PrefetchAbort>(
                        currState->vaddr_tainted,
                        ArmFault::TranslationLL + LookupLevel::L1,
                        isStage2,
                        ArmFault::LpaeTran);
                else
                    return std::make_shared<DataAbort>(
                        currState->vaddr_tainted,
                        TlbEntry::DomainType::NoAccess,
                        is_atomic ? false : currState->isWrite,
                        ArmFault::TranslationLL + LookupLevel::L1,
                        isStage2,
                        ArmFault::LpaeTran);
            }
            ttbr = currState->tc->readMiscReg(snsBankedIndex(
                MISCREG_TTBR1, currState->tc, !currState->isSecure));
            tsz = currState->ttbcr.t1sz;
            currState->isUncacheable = currState->ttbcr.irgn1 == 0;
            // Lower limit >= 3 GiB
            if (ttbr1_min >= (1ULL << 31) + (1ULL << 30))
                start_lookup_level = LookupLevel::L2;
        } else {
            // Out of boundaries -> translation fault
            if (currState->isFetch)
                return std::make_shared<PrefetchAbort>(
                    currState->vaddr_tainted,
                    ArmFault::TranslationLL + LookupLevel::L1,
                    isStage2,
                    ArmFault::LpaeTran);
            else
                return std::make_shared<DataAbort>(
                    currState->vaddr_tainted,
                    TlbEntry::DomainType::NoAccess,
                    is_atomic ? false : currState->isWrite,
                    ArmFault::TranslationLL + LookupLevel::L1,
                    isStage2, ArmFault::LpaeTran);
        }

    }

    // Perform lookup (ARM ARM issue C B3.6.6)
    if (start_lookup_level == LookupLevel::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 = testWalk(desc_addr, sizeof(uint64_t),
                       TlbEntry::DomainType::NoAccess, start_lookup_level,
                       isStage2);
    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 || currState->isUncacheable) {
        flag.set(Request::UNCACHEABLE);
    }

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

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

    return f;
}

bool
TableWalker::checkVAddrSizeFaultAArch64(Addr addr, int top_bit,
    GrainSize tg, int tsz, bool low_range)
{
    // The effective maximum input size is 48 if ARMv8.2-LVA is not
    // supported or if the translation granule that is in use is 4KB or
    // 16KB in size. When ARMv8.2-LVA is supported, for the 64KB
    // translation granule size only, the effective minimum value of
    // 52.
    const bool have_lva = HaveExt(currState->tc, ArmExtension::FEAT_LVA);
    int in_max = (have_lva && tg == Grain64KB) ? 52 : 48;
    int in_min = 64 - (tg == Grain64KB ? 47 : 48);

    return tsz > in_max || tsz < in_min || (low_range ?
        bits(currState->vaddr, top_bit, tsz) != 0x0 :
        bits(currState->vaddr, top_bit, tsz) != mask(top_bit - tsz + 1));
}

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

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

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

    stats.walkWaitTime.sample(curTick() - currState->startTime);

    // 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;

    int top_bit = computeAddrTop(currState->tc,
        bits(currState->vaddr, 55),
        currState->mode==BaseMMU::Execute,
        currState->tcr,
        currState->el);

    bool vaddr_fault = false;
    switch (currState->el) {
      case EL0:
        {
            Addr ttbr0;
            Addr ttbr1;
            if (HaveExt(currState->tc, ArmExtension::FEAT_VHE) &&
                    currState->hcr.tge==1 && currState->hcr.e2h == 1) {
                // VHE code for EL2&0 regime
                ttbr0 = currState->tc->readMiscReg(MISCREG_TTBR0_EL2);
                ttbr1 = currState->tc->readMiscReg(MISCREG_TTBR1_EL2);
            } else {
                ttbr0 = currState->tc->readMiscReg(MISCREG_TTBR0_EL1);
                ttbr1 = currState->tc->readMiscReg(MISCREG_TTBR1_EL1);
            }
            switch (bits(currState->vaddr, 63,48)) {
              case 0:
                DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n");
                ttbr = ttbr0;
                tsz = 64 - currState->tcr.t0sz;
                tg = GrainMap_tg0[currState->tcr.tg0];
                currState->hpd = currState->tcr.hpd0;
                currState->isUncacheable = currState->tcr.irgn0 == 0;
                vaddr_fault = checkVAddrSizeFaultAArch64(currState->vaddr,
                    top_bit, tg, tsz, true);

                if (vaddr_fault || currState->tcr.epd0)
                    fault = true;
                break;
              case 0xffff:
                DPRINTF(TLB, " - Selecting TTBR1 (AArch64)\n");
                ttbr = ttbr1;
                tsz = 64 - currState->tcr.t1sz;
                tg = GrainMap_tg1[currState->tcr.tg1];
                currState->hpd = currState->tcr.hpd1;
                currState->isUncacheable = currState->tcr.irgn1 == 0;
                vaddr_fault = checkVAddrSizeFaultAArch64(currState->vaddr,
                    top_bit, tg, tsz, false);

                if (vaddr_fault || 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 EL1:
        if (isStage2) {
            if (currState->secureLookup) {
                DPRINTF(TLB, " - Selecting VSTTBR_EL2 (AArch64 stage 2)\n");
                ttbr = currState->tc->readMiscReg(MISCREG_VSTTBR_EL2);
            } else {
                DPRINTF(TLB, " - Selecting VTTBR_EL2 (AArch64 stage 2)\n");
                ttbr = currState->tc->readMiscReg(MISCREG_VTTBR_EL2);
            }
            tsz = 64 - currState->vtcr.t0sz64;
            tg = GrainMap_tg0[currState->vtcr.tg0];

            ps = currState->vtcr.ps;
            currState->isUncacheable = currState->vtcr.irgn0 == 0;
        } else {
            switch (bits(currState->vaddr, top_bit)) {
              case 0:
                DPRINTF(TLB, " - Selecting TTBR0_EL1 (AArch64)\n");
                ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL1);
                tsz = 64 - currState->tcr.t0sz;
                tg = GrainMap_tg0[currState->tcr.tg0];
                currState->hpd = currState->tcr.hpd0;
                currState->isUncacheable = currState->tcr.irgn0 == 0;
                vaddr_fault = checkVAddrSizeFaultAArch64(currState->vaddr,
                    top_bit, tg, tsz, true);

                if (vaddr_fault || currState->tcr.epd0)
                    fault = true;
                break;
              case 0x1:
                DPRINTF(TLB, " - Selecting TTBR1_EL1 (AArch64)\n");
                ttbr = currState->tc->readMiscReg(MISCREG_TTBR1_EL1);
                tsz = 64 - currState->tcr.t1sz;
                tg = GrainMap_tg1[currState->tcr.tg1];
                currState->hpd = currState->tcr.hpd1;
                currState->isUncacheable = currState->tcr.irgn1 == 0;
                vaddr_fault = checkVAddrSizeFaultAArch64(currState->vaddr,
                    top_bit, tg, tsz, false);

                if (vaddr_fault || 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:
        switch(bits(currState->vaddr, top_bit)) {
          case 0:
            DPRINTF(TLB, " - Selecting TTBR0_EL2 (AArch64)\n");
            ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL2);
            tsz = 64 - currState->tcr.t0sz;
            tg = GrainMap_tg0[currState->tcr.tg0];
            currState->hpd = currState->hcr.e2h ?
                currState->tcr.hpd0 : currState->tcr.hpd;
            currState->isUncacheable = currState->tcr.irgn0 == 0;
            vaddr_fault = checkVAddrSizeFaultAArch64(currState->vaddr,
                top_bit, tg, tsz, true);

            if (vaddr_fault || (currState->hcr.e2h && currState->tcr.epd0))
                fault = true;
            break;

          case 0x1:
            DPRINTF(TLB, " - Selecting TTBR1_EL2 (AArch64)\n");
            ttbr = currState->tc->readMiscReg(MISCREG_TTBR1_EL2);
            tsz = 64 - currState->tcr.t1sz;
            tg = GrainMap_tg1[currState->tcr.tg1];
            currState->hpd = currState->tcr.hpd1;
            currState->isUncacheable = currState->tcr.irgn1 == 0;
            vaddr_fault = checkVAddrSizeFaultAArch64(currState->vaddr,
                top_bit, tg, tsz, false);

            if (vaddr_fault || !currState->hcr.e2h || currState->tcr.epd1)
                fault = true;
            break;

           default:
              // invalid addr if top two bytes are not all 0s
              fault = true;
        }
        ps = currState->hcr.e2h ? currState->tcr.ips: currState->tcr.ps;
        break;
      case EL3:
        switch(bits(currState->vaddr, top_bit)) {
          case 0:
            DPRINTF(TLB, " - Selecting TTBR0_EL3 (AArch64)\n");
            ttbr = currState->tc->readMiscReg(MISCREG_TTBR0_EL3);
            tsz = 64 - currState->tcr.t0sz;
            tg = GrainMap_tg0[currState->tcr.tg0];
            currState->hpd = currState->tcr.hpd;
            currState->isUncacheable = currState->tcr.irgn0 == 0;
            vaddr_fault = checkVAddrSizeFaultAArch64(currState->vaddr,
                top_bit, tg, tsz, true);

            if (vaddr_fault)
                fault = true;
            break;
          default:
            // invalid addr if top two bytes are not all 0s
            fault = true;
        }
        ps = currState->tcr.ps;
        break;
    }

    const bool is_atomic = currState->req->isAtomic();

    if (fault) {
        Fault f;
        if (currState->isFetch)
            f =  std::make_shared<PrefetchAbort>(
                currState->vaddr_tainted,
                ArmFault::TranslationLL + LookupLevel::L0, isStage2,
                ArmFault::LpaeTran);
        else
            f = std::make_shared<DataAbort>(
                currState->vaddr_tainted,
                TlbEntry::DomainType::NoAccess,
                is_atomic ? false : currState->isWrite,
                ArmFault::TranslationLL + LookupLevel::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;
    }

    // Clamp to lower limit
    int pa_range = decodePhysAddrRange64(ps);
    if (pa_range > _physAddrRange) {
        currState->physAddrRange = _physAddrRange;
    } else {
        currState->physAddrRange = pa_range;
    }

    auto [table_addr, desc_addr, start_lookup_level] = walkAddresses(
        ttbr, tg, tsz, pa_range);

    // Determine physical address size and raise an Address Size Fault if
    // necessary
    if (checkAddrSizeFaultAArch64(table_addr, currState->physAddrRange)) {
        DPRINTF(TLB, "Address size fault before any lookup\n");
        Fault f;
        if (currState->isFetch)
            f = std::make_shared<PrefetchAbort>(
                currState->vaddr_tainted,
                ArmFault::AddressSizeLL + start_lookup_level,
                isStage2,
                ArmFault::LpaeTran);
        else
            f = std::make_shared<DataAbort>(
                currState->vaddr_tainted,
                TlbEntry::DomainType::NoAccess,
                is_atomic ? false : 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;

    }

    // Trickbox address check
    Fault f = testWalk(desc_addr, sizeof(uint64_t),
                       TlbEntry::DomainType::NoAccess, start_lookup_level, isStage2);
    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 = Request::PT_WALK;
    if (currState->sctlr.c == 0 || currState->isUncacheable) {
        flag.set(Request::UNCACHEABLE);
    }

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

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

    if (currState->timing) {
        fetchDescriptor(desc_addr, (uint8_t*) &currState->longDesc.data,
                        sizeof(uint64_t), flag, start_lookup_level,
                        LongDescEventByLevel[start_lookup_level], NULL);
    } else {
        fetchDescriptor(desc_addr, (uint8_t*)&currState->longDesc.data,
                        sizeof(uint64_t), flag, -1, NULL,
                        &TableWalker::doLongDescriptor);
        f = currState->fault;
    }

    return f;
}

std::tuple<Addr, Addr, TableWalker::LookupLevel>
TableWalker::walkAddresses(Addr ttbr, GrainSize tg, int tsz, int pa_range)
{
    const auto* ptops = getPageTableOps(tg);

    LookupLevel first_level = LookupLevel::Num_ArmLookupLevel;
    Addr table_addr = 0;
    Addr desc_addr = 0;

    if (currState->walkEntry.valid) {
        // WalkCache hit
        TlbEntry* entry = &currState->walkEntry;
        DPRINTF(PageTableWalker,
                "Walk Cache hit: va=%#x, level=%d, table address=%#x\n",
                currState->vaddr, entry->lookupLevel, entry->pfn);

        currState->xnTable = entry->xn;
        currState->pxnTable = entry->pxn;
        currState->rwTable = bits(entry->ap, 1);
        currState->userTable = bits(entry->ap, 0);

        table_addr = entry->pfn;
        first_level = (LookupLevel)(entry->lookupLevel + 1);
    } else {
        // WalkCache miss
        first_level = isStage2 ?
            ptops->firstS2Level(currState->vtcr.sl0) :
            ptops->firstLevel(64 - tsz);
        panic_if(first_level == LookupLevel::Num_ArmLookupLevel,
                 "Table walker couldn't find lookup level\n");

        int stride = tg - 3;
        int base_addr_lo = 3 + tsz - stride * (3 - first_level) - tg;

        if (pa_range == 52) {
            int z = (base_addr_lo < 6) ? 6 : base_addr_lo;
            table_addr = mbits(ttbr, 47, z);
            table_addr |= (bits(ttbr, 5, 2) << 48);
        } else {
            table_addr = mbits(ttbr, 47, base_addr_lo);
        }
    }

    desc_addr = table_addr + ptops->index(currState->vaddr, first_level, tsz);

    return std::make_tuple(table_addr, desc_addr, first_level);
}

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(snsBankedIndex(MISCREG_PRRR,
                                    currState->tc, !currState->isSecure));
        NMRR nmrr = tc->readMiscReg(snsBankedIndex(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 &l_descriptor)
{
    assert(release->has(ArmExtension::LPAE));

    uint8_t attr;
    uint8_t sh = l_descriptor.sh();
    // Different format and source of attributes if this is a stage 2
    // translation
    if (isStage2) {
        attr = l_descriptor.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 = l_descriptor.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 = snsBankedIndex(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,
                             LongDescriptor &l_descriptor)
{
    uint8_t attr;
    uint8_t attr_hi;
    uint8_t attr_lo;
    uint8_t sh = l_descriptor.sh();

    if (isStage2) {
        attr = l_descriptor.memAttr();
        uint8_t attr_hi = (attr >> 2) & 0x3;
        uint8_t attr_lo =  attr       & 0x3;

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

        if (attr_hi == 0) {
            te.mtype        = attr_lo == 0 ? TlbEntry::MemoryType::StronglyOrdered
                                            : TlbEntry::MemoryType::Device;
            te.outerAttrs   = 0;
            te.innerAttrs   = attr_lo == 0 ? 1 : 3;
            te.nonCacheable = true;
        } else {
            te.mtype        = TlbEntry::MemoryType::Normal;
            te.outerAttrs   = attr_hi == 1 ? 0 :
                              attr_hi == 2 ? 2 : 1;
            te.innerAttrs   = attr_lo == 1 ? 0 :
                              attr_lo == 2 ? 6 : 5;
            // Treat write-through memory as uncacheable, this is safe
            // but for performance reasons not optimal.
            te.nonCacheable = (attr_hi == 1) || (attr_hi == 2) ||
                (attr_lo == 1) || (attr_lo == 2);
        }
    } else {
        uint8_t attrIndx = l_descriptor.attrIndx();

        DPRINTF(TLBVerbose, "memAttrsAArch64 AttrIndx:%#x sh:%#x\n", attrIndx, sh);
        ExceptionLevel regime =  s1TranslationRegime(tc, currState->el);

        // Select MAIR
        uint64_t mair;
        switch (regime) {
          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
        attr = bits(mair, 8 * attrIndx + 7, 8 * attrIndx);
        attr_lo = bits(attr, 3, 0);
        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
            te.nonCacheable = true;
        }
        // Treat write-through memory as uncacheable, this is safe
        // but for performance reasons not optimal.
        switch (attr_hi) {
          case 0x1 ... 0x3: // Normal Memory, Outer Write-through transient
          case 0x4:         // Normal memory, Outer Non-cacheable
          case 0x8 ... 0xb: // Normal Memory, Outer Write-through non-transient
            te.nonCacheable = true;
        }
        switch (attr_lo) {
          case 0x1 ... 0x3: // Normal Memory, Inner Write-through transient
          case 0x9 ... 0xb: // Normal Memory, Inner Write-through non-transient
            warn_if(!attr_hi, "Unpredictable behavior");
            [[fallthrough]];
          case 0x4:         // Device-nGnRE memory or
                            // Normal memory, Inner Non-cacheable
          case 0x8:         // Device-nGRE memory or
                            // Normal memory, Inner Write-through non-transient
            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;
    }

    currState->l1Desc.data = htog(currState->l1Desc.data,
                                  byteOrder(currState->tc));

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

    const bool is_atomic = currState->req->isAtomic();

    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 =
                std::make_shared<PrefetchAbort>(
                    currState->vaddr_tainted,
                    ArmFault::TranslationLL + LookupLevel::L1,
                    isStage2,
                    ArmFault::VmsaTran);
        else
            currState->fault =
                std::make_shared<DataAbort>(
                    currState->vaddr_tainted,
                    TlbEntry::DomainType::NoAccess,
                    is_atomic ? false : currState->isWrite,
                    ArmFault::TranslationLL + LookupLevel::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 = std::make_shared<DataAbort>(
                currState->vaddr_tainted,
                currState->l1Desc.domain(),
                is_atomic ? false : currState->isWrite,
                ArmFault::AccessFlagLL + LookupLevel::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 = testWalk(l2desc_addr, sizeof(uint32_t),
                                        currState->l1Desc.domain(),
                                        LookupLevel::L2, isStage2);

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

            Request::Flags flag = Request::PT_WALK;

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

            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");
    }
}

Fault
TableWalker::generateLongDescFault(ArmFault::FaultSource src)
{
    if (currState->isFetch) {
        return std::make_shared<PrefetchAbort>(
            currState->vaddr_tainted,
            src + currState->longDesc.lookupLevel,
            isStage2,
            ArmFault::LpaeTran);
    } else {
        return std::make_shared<DataAbort>(
            currState->vaddr_tainted,
            TlbEntry::DomainType::NoAccess,
            currState->req->isAtomic() ? false : currState->isWrite,
            src + currState->longDesc.lookupLevel,
            isStage2,
            ArmFault::LpaeTran);
    }
}

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

    currState->longDesc.data = htog(currState->longDesc.data,
                                    byteOrder(currState->tc));

    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(PageTableWalker, "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(PageTableWalker, "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:
        DPRINTF(TLB, "L%d descriptor Invalid, causing fault type %d\n",
                currState->longDesc.lookupLevel,
                ArmFault::TranslationLL + currState->longDesc.lookupLevel);

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

      case LongDescriptor::Block:
      case LongDescriptor::Page:
        {
            auto fault_source = ArmFault::FaultSourceInvalid;
            // Check for address size fault
            if (checkAddrSizeFaultAArch64(currState->longDesc.paddr(),
                currState->physAddrRange)) {

                DPRINTF(TLB, "L%d descriptor causing Address Size Fault\n",
                        currState->longDesc.lookupLevel);
                fault_source = ArmFault::AddressSizeLL;

            // Check for access fault
            } else if (currState->longDesc.af() == 0) {

                DPRINTF(TLB, "L%d descriptor causing Access Fault\n",
                        currState->longDesc.lookupLevel);
                fault_source = ArmFault::AccessFlagLL;
            }

            if (fault_source != ArmFault::FaultSourceInvalid) {
                currState->fault = generateLongDescFault(fault_source);
            } 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->hpd);
            currState->userTable = currState->userTable &&
                (currState->longDesc.userTable() || currState->hpd);
            currState->xnTable = currState->xnTable ||
                (currState->longDesc.xnTable() && !currState->hpd);
            currState->pxnTable = currState->pxnTable ||
                (currState->longDesc.pxnTable() && !currState->hpd);

            // 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);

                currState->fault = generateLongDescFault(
                    ArmFault::AddressSizeLL);
                return;
            }

            // Trickbox address check
            currState->fault = testWalk(
                next_desc_addr, sizeof(uint64_t), TlbEntry::DomainType::Client,
                toLookupLevel(currState->longDesc.lookupLevel +1), isStage2);

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

            if (mmu->hasWalkCache()) {
                insertPartialTableEntry(currState->longDesc);
            }


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

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

            LookupLevel L = currState->longDesc.lookupLevel =
                (LookupLevel) (currState->longDesc.lookupLevel + 1);
            Event *event = NULL;
            switch (L) {
              case LookupLevel::L1:
                assert(currState->aarch64);
              case LookupLevel::L2:
              case LookupLevel::L3:
                event = LongDescEventByLevel[L];
                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;
    }

    currState->l2Desc.data = htog(currState->l2Desc.data,
                                  byteOrder(currState->tc));

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

    const bool is_atomic = currState->req->isAtomic();

    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 = std::make_shared<PrefetchAbort>(
                    currState->vaddr_tainted,
                    ArmFault::TranslationLL + LookupLevel::L2,
                    isStage2,
                    ArmFault::VmsaTran);
        else
            currState->fault = std::make_shared<DataAbort>(
                currState->vaddr_tainted, currState->l1Desc.domain(),
                is_atomic ? false : currState->isWrite,
                ArmFault::TranslationLL + LookupLevel::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 = std::make_shared<DataAbort>(
            currState->vaddr_tainted,
            TlbEntry::DomainType::NoAccess,
            is_atomic ? false : currState->isWrite,
            ArmFault::AccessFlagLL + LookupLevel::L2, isStage2,
            ArmFault::VmsaTran);
    }

    insertTableEntry(currState->l2Desc, false);
}

void
TableWalker::doL1DescriptorWrapper()
{
    currState = stateQueues[LookupLevel::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(PageTableWalker, "L1 Desc object host addr: %p\n",
            &currState->l1Desc.data);
    DPRINTF(PageTableWalker, "L1 Desc object      data: %08x\n",
            currState->l1Desc.data);

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

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

        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
        stats.walkServiceTime.sample(curTick() - currState->startTime);
        DPRINTF(PageTableWalker, "calling translateTiming again\n");

        mmu->translateTiming(currState->req, currState->tc,
            currState->transState, currState->mode,
            currState->tranType, isStage2);

        stats.walksShortTerminatedAtLevel[0]++;

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

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

void
TableWalker::doL2DescriptorWrapper()
{
    currState = stateQueues[LookupLevel::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(PageTableWalker, "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);
        stats.walksShortTerminatedAtLevel[1]++;
    } else {
        stats.walkServiceTime.sample(curTick() - currState->startTime);
        DPRINTF(PageTableWalker, "calling translateTiming again\n");

        mmu->translateTiming(currState->req, currState->tc,
            currState->transState, currState->mode,
            currState->tranType, isStage2);

        stats.walksShortTerminatedAtLevel[1]++;
    }


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

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

    delete currState;
    currState = NULL;
}

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

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

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

void
TableWalker::doL3LongDescriptorWrapper()
{
    doLongDescriptorWrapper(LookupLevel::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(PageTableWalker, "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
        DPRINTF(PageTableWalker, "calling translateTiming again\n");
        stats.walkServiceTime.sample(curTick() - currState->startTime);

        mmu->translateTiming(currState->req, currState->tc,
            currState->transState, currState->mode,
            currState->tranType, isStage2);

        stats.walksLongTerminatedAtLevel[(unsigned) curr_lookup_level]++;

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

        currState->req = NULL;
        currState->tc = NULL;
        currState->delayed = false;
        delete currState;
    } else {
        if (curr_lookup_level >= LookupLevel::Num_ArmLookupLevel - 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)));
    else
        completeDrain();
}

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

    DPRINTF(PageTableWalker,
            "Fetching descriptor at address: 0x%x stage2Req: %d\n",
            descAddr, currState->stage2Req);

    // If this translation has a stage 2 then we know descAddr is an IPA and
    // needs to be translated before we can access the page table. Do that
    // check here.
    if (currState->stage2Req) {
        Fault fault;

        if (isTiming) {
            auto *tran = new
                Stage2Walk(*this, data, event, currState->vaddr,
                    currState->mode, currState->tranType);
            currState->stage2Tran = tran;
            readDataTimed(currState->tc, descAddr, tran, numBytes, flags);
            fault = tran->fault;
        } else {
            fault = readDataUntimed(currState->tc,
                currState->vaddr, descAddr, data, numBytes, flags,
                currState->mode,
                currState->tranType,
                currState->functional);
        }

        if (fault != NoFault) {
            currState->fault = fault;
        }
        if (isTiming) {
            if (queueIndex >= 0) {
                DPRINTF(PageTableWalker, "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->sendTimingReq(descAddr, numBytes, data, flags,
                currState->tc->getCpuPtr()->clockPeriod(), event);

            if (queueIndex >= 0) {
                DPRINTF(PageTableWalker, "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->sendAtomicReq(descAddr, numBytes, data, flags,
                currState->tc->getCpuPtr()->clockPeriod());

            (this->*doDescriptor)();
        } else {
            port->sendFunctionalReq(descAddr, numBytes, data, flags);
            (this->*doDescriptor)();
        }
    }
    return (isTiming);
}

void
TableWalker::insertPartialTableEntry(LongDescriptor &descriptor)
{
    const bool have_security = release->has(ArmExtension::SECURITY);
    TlbEntry te;

    // Create and fill a new page table entry
    te.valid          = true;
    te.longDescFormat = true;
    te.partial        = true;
    // The entry is global if there is no address space identifier
    // to differentiate translation contexts
    te.global         = !mmu->hasUnprivRegime(
        currState->el, currState->hcr.e2h);
    te.isHyp          = currState->isHyp;
    te.asid           = currState->asid;
    te.vmid           = currState->vmid;
    te.N              = descriptor.offsetBits();
    te.vpn            = currState->vaddr >> te.N;
    te.size           = (1ULL << te.N) - 1;
    te.pfn            = descriptor.nextTableAddr();
    te.domain         = descriptor.domain();
    te.lookupLevel    = descriptor.lookupLevel;
    te.ns             = !descriptor.secure(have_security, currState);
    te.nstid          = !currState->isSecure;
    te.type           = TypeTLB::unified;

    if (currState->aarch64)
        te.el         = currState->el;
    else
        te.el         = EL1;

    te.xn = currState->xnTable;
    te.pxn = currState->pxnTable;
    te.ap = (currState->rwTable << 1) | (currState->userTable);

    // 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 TLBs
    tlb->multiInsert(te);
}

void
TableWalker::insertTableEntry(DescriptorBase &descriptor, bool long_descriptor)
{
    const bool have_security = release->has(ArmExtension::SECURITY);
    TlbEntry te;

    // Create and fill a new page table entry
    te.valid          = true;
    te.longDescFormat = long_descriptor;
    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(have_security, currState);
    te.nstid          = !currState->isSecure;
    te.xn             = descriptor.xn();
    te.type           = currState->mode == BaseMMU::Execute ?
        TypeTLB::instruction : TypeTLB::data;

    if (currState->aarch64)
        te.el         = currState->el;
    else
        te.el         = EL1;

    stats.pageSizes[pageSizeNtoStatBin(te.N)]++;
    stats.requestOrigin[COMPLETED][currState->isFetch]++;

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

        te.xn |= currState->xnTable;
        te.pxn = currState->pxnTable || l_descriptor.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 = l_descriptor.ap();
        } else {
           te.ap = ((!currState->rwTable || descriptor.ap() >> 1) << 1) |
               (currState->userTable && (descriptor.ap() & 0x1));
        }
        if (currState->aarch64)
            memAttrsAArch64(currState->tc, te, l_descriptor);
        else
            memAttrsLPAE(currState->tc, te, l_descriptor);
    } 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 TLBs
    tlb->multiInsert(te);
    if (!currState->timing) {
        currState->tc  = NULL;
        currState->req = NULL;
    }
}

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

/* this method keeps track of the table walker queue's residency, so
 * needs to be called whenever requests start and complete. */
void
TableWalker::pendingChange()
{
    unsigned n = pendingQueue.size();
    if ((currState != NULL) && (currState != pendingQueue.front())) {
        ++n;
    }

    if (n != pendingReqs) {
        Tick now = curTick();
        stats.pendingWalks.sample(pendingReqs, now - pendingChangeTick);
        pendingReqs = n;
        pendingChangeTick = now;
    }
}

Fault
TableWalker::testWalk(Addr pa, Addr size, TlbEntry::DomainType domain,
                      LookupLevel lookup_level, bool stage2)
{
    return mmu->testWalk(pa, size, currState->vaddr, currState->isSecure,
                         currState->mode, domain, lookup_level, stage2);
}


uint8_t
TableWalker::pageSizeNtoStatBin(uint8_t N)
{
    /* for stats.pageSizes */
    switch(N) {
        case 12: return 0; // 4K
        case 14: return 1; // 16K (using 16K granule in v8-64)
        case 16: return 2; // 64K
        case 20: return 3; // 1M
        case 21: return 4; // 2M-LPAE
        case 24: return 5; // 16M
        case 25: return 6; // 32M (using 16K granule in v8-64)
        case 29: return 7; // 512M (using 64K granule in v8-64)
        case 30: return 8; // 1G-LPAE
        case 42: return 9; // 1G-LPAE
        default:
            panic("unknown page size");
            return 255;
    }
}

Fault
TableWalker::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)
{
    Fault fault;

    // translate to physical address using the second stage MMU
    auto req = std::make_shared<Request>();
    req->setVirt(desc_addr, num_bytes, flags | Request::PT_WALK,
                requestorId, 0);

    if (functional) {
        fault = mmu->translateFunctional(req, tc, BaseMMU::Read,
            tran_type, true);
    } else {
        fault = mmu->translateAtomic(req, tc, BaseMMU::Read,
            tran_type, true);
    }

    // Now do the access.
    if (fault == NoFault && !req->getFlags().isSet(Request::NO_ACCESS)) {
        Packet pkt = Packet(req, MemCmd::ReadReq);
        pkt.dataStatic(data);
        if (functional) {
            port->sendFunctional(&pkt);
        } else {
            port->sendAtomic(&pkt);
        }
        assert(!pkt.isError());
    }

    // If there was a fault annotate it with the flag saying the foult occured
    // while doing a translation for a stage 1 page table walk.
    if (fault != NoFault) {
        ArmFault *arm_fault = reinterpret_cast<ArmFault *>(fault.get());
        arm_fault->annotate(ArmFault::S1PTW, true);
        arm_fault->annotate(ArmFault::OVA, vaddr);
    }
    return fault;
}

void
TableWalker::readDataTimed(ThreadContext *tc, Addr desc_addr,
                           Stage2Walk *translation, int num_bytes,
                           Request::Flags flags)
{
    // translate to physical address using the second stage MMU
    translation->setVirt(
            desc_addr, num_bytes, flags | Request::PT_WALK, requestorId);
    translation->translateTiming(tc);
}

TableWalker::Stage2Walk::Stage2Walk(TableWalker &_parent,
        uint8_t *_data, Event *_event, Addr vaddr, BaseMMU::Mode _mode,
        MMU::ArmTranslationType tran_type)
    : data(_data), numBytes(0), event(_event), parent(_parent),
      oVAddr(vaddr), mode(_mode), tranType(tran_type), fault(NoFault)
{
    req = std::make_shared<Request>();
}

void
TableWalker::Stage2Walk::finish(const Fault &_fault,
                                const RequestPtr &req,
                                ThreadContext *tc, BaseMMU::Mode mode)
{
    fault = _fault;

    // If there was a fault annotate it with the flag saying the foult occured
    // while doing a translation for a stage 1 page table walk.
    if (fault != NoFault) {
        ArmFault *arm_fault = reinterpret_cast<ArmFault *>(fault.get());
        arm_fault->annotate(ArmFault::S1PTW, true);
        arm_fault->annotate(ArmFault::OVA, oVAddr);
    }

    if (_fault == NoFault && !req->getFlags().isSet(Request::NO_ACCESS)) {
        parent.getTableWalkerPort().sendTimingReq(
            req->getPaddr(), numBytes, data, req->getFlags(),
            tc->getCpuPtr()->clockPeriod(), event);
    } else {
        // We can't do the DMA access as there's been a problem, so tell the
        // event we're done
        event->process();
    }
}

void
TableWalker::Stage2Walk::translateTiming(ThreadContext *tc)
{
    parent.mmu->translateTiming(req, tc, this, mode, tranType, true);
}

TableWalker::TableWalkerStats::TableWalkerStats(statistics::Group *parent)
    : statistics::Group(parent),
    ADD_STAT(walks, statistics::units::Count::get(),
             "Table walker walks requested"),
    ADD_STAT(walksShortDescriptor, statistics::units::Count::get(),
             "Table walker walks initiated with short descriptors"),
    ADD_STAT(walksLongDescriptor, statistics::units::Count::get(),
             "Table walker walks initiated with long descriptors"),
    ADD_STAT(walksShortTerminatedAtLevel, statistics::units::Count::get(),
             "Level at which table walker walks with short descriptors "
             "terminate"),
    ADD_STAT(walksLongTerminatedAtLevel, statistics::units::Count::get(),
             "Level at which table walker walks with long descriptors "
             "terminate"),
    ADD_STAT(squashedBefore, statistics::units::Count::get(),
             "Table walks squashed before starting"),
    ADD_STAT(squashedAfter, statistics::units::Count::get(),
             "Table walks squashed after completion"),
    ADD_STAT(walkWaitTime, statistics::units::Tick::get(),
             "Table walker wait (enqueue to first request) latency"),
    ADD_STAT(walkServiceTime, statistics::units::Tick::get(),
             "Table walker service (enqueue to completion) latency"),
    ADD_STAT(pendingWalks, statistics::units::Tick::get(),
             "Table walker pending requests distribution"),
    ADD_STAT(pageSizes, statistics::units::Count::get(),
             "Table walker page sizes translated"),
    ADD_STAT(requestOrigin, statistics::units::Count::get(),
             "Table walker requests started/completed, data/inst")
{
    walksShortDescriptor
        .flags(statistics::nozero);

    walksLongDescriptor
        .flags(statistics::nozero);

    walksShortTerminatedAtLevel
        .init(2)
        .flags(statistics::nozero);

    walksShortTerminatedAtLevel.subname(0, "Level1");
    walksShortTerminatedAtLevel.subname(1, "Level2");

    walksLongTerminatedAtLevel
        .init(4)
        .flags(statistics::nozero);
    walksLongTerminatedAtLevel.subname(0, "Level0");
    walksLongTerminatedAtLevel.subname(1, "Level1");
    walksLongTerminatedAtLevel.subname(2, "Level2");
    walksLongTerminatedAtLevel.subname(3, "Level3");

    squashedBefore
        .flags(statistics::nozero);

    squashedAfter
        .flags(statistics::nozero);

    walkWaitTime
        .init(16)
        .flags(statistics::pdf | statistics::nozero | statistics::nonan);

    walkServiceTime
        .init(16)
        .flags(statistics::pdf | statistics::nozero | statistics::nonan);

    pendingWalks
        .init(16)
        .flags(statistics::pdf | statistics::dist | statistics::nozero |
            statistics::nonan);

    pageSizes // see DDI 0487A D4-1661
        .init(10)
        .flags(statistics::total | statistics::pdf | statistics::dist |
            statistics::nozero);
    pageSizes.subname(0, "4KiB");
    pageSizes.subname(1, "16KiB");
    pageSizes.subname(2, "64KiB");
    pageSizes.subname(3, "1MiB");
    pageSizes.subname(4, "2MiB");
    pageSizes.subname(5, "16MiB");
    pageSizes.subname(6, "32MiB");
    pageSizes.subname(7, "512MiB");
    pageSizes.subname(8, "1GiB");
    pageSizes.subname(9, "4TiB");

    requestOrigin
        .init(2,2) // Instruction/Data, requests/completed
        .flags(statistics::total);
    requestOrigin.subname(0,"Requested");
    requestOrigin.subname(1,"Completed");
    requestOrigin.ysubname(0,"Data");
    requestOrigin.ysubname(1,"Inst");
}

} // namespace gem5
