/*
 * Copyright (c) 2010-2013, 2016-2021 Arm Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2001-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * 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/mmu.hh"

#include "arch/arm/isa.hh"
#include "arch/arm/reg_abi.hh"
#include "arch/arm/stage2_lookup.hh"
#include "arch/arm/table_walker.hh"
#include "arch/arm/tlbi_op.hh"
#include "debug/TLB.hh"
#include "debug/TLBVerbose.hh"
#include "mem/packet_access.hh"
#include "sim/pseudo_inst.hh"
#include "sim/process.hh"

namespace gem5
{

using namespace ArmISA;

MMU::MMU(const ArmMMUParams &p)
  : BaseMMU(p),
    itbStage2(p.stage2_itb), dtbStage2(p.stage2_dtb),
    itbWalker(p.itb_walker), dtbWalker(p.dtb_walker),
    itbStage2Walker(p.stage2_itb_walker),
    dtbStage2Walker(p.stage2_dtb_walker),
    test(nullptr),
    miscRegContext(0),
    s1State(this, false), s2State(this, true),
    _attr(0),
    _release(nullptr),
    _hasWalkCache(false),
    stats(this)
{
    // Cache system-level properties
    if (FullSystem) {
        ArmSystem *arm_sys = dynamic_cast<ArmSystem *>(p.sys);
        assert(arm_sys);
        haveLargeAsid64 = arm_sys->haveLargeAsid64();
        physAddrRange = arm_sys->physAddrRange();

        _release = arm_sys->releaseFS();
    } else {
        haveLargeAsid64 = false;
        physAddrRange = 48;

        _release = p.release_se;
    }

    m5opRange = p.sys->m5opRange();
}

void
MMU::init()
{
    itbWalker->setMmu(this);
    dtbWalker->setMmu(this);
    itbStage2Walker->setMmu(this);
    dtbStage2Walker->setMmu(this);

    itbStage2->setTableWalker(itbStage2Walker);
    dtbStage2->setTableWalker(dtbStage2Walker);

    getITBPtr()->setTableWalker(itbWalker);
    getDTBPtr()->setTableWalker(dtbWalker);

    BaseMMU::init();

    _hasWalkCache = checkWalkCache();
}

bool
MMU::checkWalkCache() const
{
    for (auto tlb : instruction) {
        if (static_cast<TLB*>(tlb)->walkCache())
            return true;
    }
    for (auto tlb : data) {
        if (static_cast<TLB*>(tlb)->walkCache())
            return true;
    }
    for (auto tlb : unified) {
        if (static_cast<TLB*>(tlb)->walkCache())
            return true;
    }

    return false;
}

void
MMU::drainResume()
{
    s1State.miscRegValid = false;
    s2State.miscRegValid = false;
}

TLB *
MMU::getTlb(BaseMMU::Mode mode, bool stage2) const
{
    if (mode == BaseMMU::Execute) {
        if (stage2)
            return itbStage2;
        else
            return getITBPtr();
    } else {
        if (stage2)
            return dtbStage2;
        else
            return getDTBPtr();
    }
}

TableWalker *
MMU::getTableWalker(BaseMMU::Mode mode, bool stage2) const
{
    if (mode == BaseMMU::Execute) {
        if (stage2)
            return itbStage2Walker;
        else
            return itbWalker;
    } else {
        if (stage2)
            return dtbStage2Walker;
        else
            return dtbWalker;
    }
}

bool
MMU::translateFunctional(ThreadContext *tc, Addr va, Addr &pa)
{
    CachedState& state = updateMiscReg(tc, NormalTran, false);

    auto tlb = getTlb(BaseMMU::Read, state.directToStage2);

    TlbEntry::Lookup lookup_data;

    lookup_data.va = va;
    lookup_data.asn = state.asid;
    lookup_data.ignoreAsn = false;
    lookup_data.vmid = state.vmid;
    lookup_data.hyp = state.isHyp;
    lookup_data.secure = state.isSecure;
    lookup_data.functional = true;
    lookup_data.targetEL = state.aarch64 ? state.aarch64EL : EL1;
    lookup_data.inHost = false;
    lookup_data.mode = BaseMMU::Read;

    TlbEntry *e = tlb->multiLookup(lookup_data);

    if (!e)
        return false;
    pa = e->pAddr(va);
    return true;
}

void
MMU::invalidateMiscReg()
{
    s1State.miscRegValid = false;
}

Fault
MMU::finalizePhysical(const RequestPtr &req,
                      ThreadContext *tc, Mode mode) const
{
    const Addr paddr = req->getPaddr();

    if (m5opRange.contains(paddr)) {
        uint8_t func;
        pseudo_inst::decodeAddrOffset(paddr - m5opRange.start(), func);
        req->setLocalAccessor(
            [func, mode](ThreadContext *tc, PacketPtr pkt) -> Cycles
            {
                uint64_t ret;
                if (inAArch64(tc))
                    pseudo_inst::pseudoInst<RegABI64>(tc, func, ret);
                else
                    pseudo_inst::pseudoInst<RegABI32>(tc, func, ret);

                if (mode == Read)
                    pkt->setLE(ret);

                return Cycles(1);
            }
        );
    }

    return NoFault;
}


Fault
MMU::translateSe(const RequestPtr &req, ThreadContext *tc, Mode mode,
                 Translation *translation, bool &delay, bool timing,
                 CachedState &state)
{
    updateMiscReg(tc, NormalTran, state.isStage2);
    Addr vaddr_tainted = req->getVaddr();
    Addr vaddr = 0;
    if (state.aarch64)
        vaddr = purifyTaggedAddr(vaddr_tainted, tc, state.aarch64EL,
                                 (TCR)state.ttbcr, mode==Execute);
    else
        vaddr = vaddr_tainted;
    Request::Flags flags = req->getFlags();

    bool is_fetch = (mode == Execute);
    bool is_write = (mode == Write);

    if (!is_fetch) {
        if (state.sctlr.a || !(flags & AllowUnaligned)) {
            if (vaddr & mask(flags & AlignmentMask)) {
                // LPAE is always disabled in SE mode
                return std::make_shared<DataAbort>(
                    vaddr_tainted,
                    TlbEntry::DomainType::NoAccess, is_write,
                    ArmFault::AlignmentFault, state.isStage2,
                    ArmFault::VmsaTran);
            }
        }
    }

    Addr paddr;
    Process *p = tc->getProcessPtr();

    if (!p->pTable->translate(vaddr, paddr))
        return std::make_shared<GenericPageTableFault>(vaddr_tainted);
    req->setPaddr(paddr);

    return finalizePhysical(req, tc, mode);
}

Fault
MMU::checkPermissions(TlbEntry *te, const RequestPtr &req, Mode mode,
                      bool stage2)
{
    return checkPermissions(te, req, mode, stage2 ? s2State : s1State);
}

Fault
MMU::checkPermissions(TlbEntry *te, const RequestPtr &req, Mode mode,
                      CachedState &state)
{
    // a data cache maintenance instruction that operates by MVA does
    // not generate a Data Abort exeception due to a Permission fault
    if (req->isCacheMaintenance()) {
        return NoFault;
    }

    Addr vaddr = req->getVaddr(); // 32-bit don't have to purify
    Request::Flags flags = req->getFlags();
    bool is_fetch  = (mode == Execute);
    bool is_write  = (mode == Write);
    bool is_priv   = state.isPriv && !(flags & UserMode);

    // Get the translation type from the actuall table entry
    ArmFault::TranMethod tranMethod = te->longDescFormat ? ArmFault::LpaeTran
                                                         : ArmFault::VmsaTran;

    // If this is the second stage of translation and the request is for a
    // stage 1 page table walk then we need to check the HCR.PTW bit. This
    // allows us to generate a fault if the request targets an area marked
    // as a device or strongly ordered.
    if (state.isStage2 && req->isPTWalk() && state.hcr.ptw &&
        (te->mtype != TlbEntry::MemoryType::Normal)) {
        return std::make_shared<DataAbort>(
            vaddr, te->domain, is_write,
            ArmFault::PermissionLL + te->lookupLevel,
            state.isStage2, tranMethod);
    }

    // Generate an alignment fault for unaligned data accesses to device or
    // strongly ordered memory
    if (!is_fetch) {
        if (te->mtype != TlbEntry::MemoryType::Normal) {
            if (vaddr & mask(flags & AlignmentMask)) {
                stats.alignFaults++;
                return std::make_shared<DataAbort>(
                    vaddr, TlbEntry::DomainType::NoAccess, is_write,
                    ArmFault::AlignmentFault, state.isStage2,
                    tranMethod);
            }
        }
    }

    if (te->nonCacheable) {
        // Prevent prefetching from I/O devices.
        if (req->isPrefetch()) {
            // Here we can safely use the fault status for the short
            // desc. format in all cases
            return std::make_shared<PrefetchAbort>(
                vaddr, ArmFault::PrefetchUncacheable,
                state.isStage2, tranMethod);
        }
    }

    if (!te->longDescFormat) {
        switch ((state.dacr >> (static_cast<uint8_t>(te->domain) * 2)) & 0x3) {
          case 0:
            stats.domainFaults++;
            DPRINTF(TLB, "TLB Fault: Data abort on domain. DACR: %#x"
                    " domain: %#x write:%d\n", state.dacr,
                    static_cast<uint8_t>(te->domain), is_write);
            if (is_fetch) {
                // Use PC value instead of vaddr because vaddr might
                // be aligned to cache line and should not be the
                // address reported in FAR
                return std::make_shared<PrefetchAbort>(
                    req->getPC(),
                    ArmFault::DomainLL + te->lookupLevel,
                    state.isStage2, tranMethod);
            } else
                return std::make_shared<DataAbort>(
                    vaddr, te->domain, is_write,
                    ArmFault::DomainLL + te->lookupLevel,
                    state.isStage2, tranMethod);
          case 1:
            // Continue with permissions check
            break;
          case 2:
            panic("UNPRED domain\n");
          case 3:
            return NoFault;
        }
    }

    // The 'ap' variable is AP[2:0] or {AP[2,1],1b'0}, i.e. always three bits
    uint8_t ap  = te->longDescFormat ? te->ap << 1 : te->ap;
    uint8_t hap = te->hap;

    if (state.sctlr.afe == 1 || te->longDescFormat)
        ap |= 1;

    bool abt;
    bool isWritable = true;
    // If this is a stage 2 access (eg for reading stage 1 page table entries)
    // then don't perform the AP permissions check, we stil do the HAP check
    // below.
    if (state.isStage2) {
        abt = false;
    } else {
        switch (ap) {
          case 0:
            DPRINTF(TLB, "Access permissions 0, checking rs:%#x\n",
                    (int)state.sctlr.rs);
            if (!state.sctlr.xp) {
                switch ((int)state.sctlr.rs) {
                  case 2:
                    abt = is_write;
                    break;
                  case 1:
                    abt = is_write || !is_priv;
                    break;
                  case 0:
                  case 3:
                  default:
                    abt = true;
                    break;
                }
            } else {
                abt = true;
            }
            break;
          case 1:
            abt = !is_priv;
            break;
          case 2:
            abt = !is_priv && is_write;
            isWritable = is_priv;
            break;
          case 3:
            abt = false;
            break;
          case 4:
            panic("UNPRED premissions\n");
          case 5:
            abt = !is_priv || is_write;
            isWritable = false;
            break;
          case 6:
          case 7:
            abt        = is_write;
            isWritable = false;
            break;
          default:
            panic("Unknown permissions %#x\n", ap);
        }
    }

    bool hapAbt = is_write ? !(hap & 2) : !(hap & 1);
    bool xn     = te->xn || (isWritable && state.sctlr.wxn) ||
                            (ap == 3    && state.sctlr.uwxn && is_priv);
    if (is_fetch && (abt || xn ||
                     (te->longDescFormat && te->pxn && is_priv) ||
                     (state.isSecure && te->ns && state.scr.sif))) {
        stats.permsFaults++;
        DPRINTF(TLB, "TLB Fault: Prefetch abort on permission check. AP:%d "
                     "priv:%d write:%d ns:%d sif:%d sctlr.afe: %d \n",
                     ap, is_priv, is_write, te->ns,
                     state.scr.sif, state.sctlr.afe);
        // Use PC value instead of vaddr because vaddr might be aligned to
        // cache line and should not be the address reported in FAR
        return std::make_shared<PrefetchAbort>(
            req->getPC(),
            ArmFault::PermissionLL + te->lookupLevel,
            state.isStage2, tranMethod);
    } else if (abt | hapAbt) {
        stats.permsFaults++;
        DPRINTF(TLB, "TLB Fault: Data abort on permission check. AP:%d priv:%d"
               " write:%d\n", ap, is_priv, is_write);
        return std::make_shared<DataAbort>(
            vaddr, te->domain, is_write,
            ArmFault::PermissionLL + te->lookupLevel,
            state.isStage2 | !abt, tranMethod);
    }
    return NoFault;
}

Fault
MMU::checkPermissions64(TlbEntry *te, const RequestPtr &req, Mode mode,
                        ThreadContext *tc, bool stage2)
{
    return checkPermissions64(te, req, mode, tc, stage2 ? s2State : s1State);
}

Fault
MMU::checkPermissions64(TlbEntry *te, const RequestPtr &req, Mode mode,
                        ThreadContext *tc, CachedState &state)
{
    assert(state.aarch64);

    // A data cache maintenance instruction that operates by VA does
    // not generate a Permission fault unless:
    // * It is a data cache invalidate (dc ivac) which requires write
    //   permissions to the VA, or
    // * It is executed from EL0
    if (req->isCacheClean() && state.aarch64EL != EL0 && !state.isStage2) {
        return NoFault;
    }

    Addr vaddr_tainted = req->getVaddr();
    Addr vaddr = purifyTaggedAddr(vaddr_tainted, tc, state.aarch64EL,
        (TCR)state.ttbcr, mode==Execute);

    Request::Flags flags = req->getFlags();
    bool is_fetch  = (mode == Execute);
    // Cache clean operations require read permissions to the specified VA
    bool is_write = !req->isCacheClean() && mode == Write;
    bool is_atomic = req->isAtomic();

    updateMiscReg(tc, state.curTranType, state.isStage2);

    // If this is the second stage of translation and the request is for a
    // stage 1 page table walk then we need to check the HCR.PTW bit. This
    // allows us to generate a fault if the request targets an area marked
    // as a device or strongly ordered.
    if (state.isStage2 && req->isPTWalk() && state.hcr.ptw &&
        (te->mtype != TlbEntry::MemoryType::Normal)) {
        return std::make_shared<DataAbort>(
            vaddr_tainted, te->domain, is_write,
            ArmFault::PermissionLL + te->lookupLevel,
            state.isStage2, ArmFault::LpaeTran);
    }

    // Generate an alignment fault for unaligned accesses to device or
    // strongly ordered memory
    if (!is_fetch) {
        if (te->mtype != TlbEntry::MemoryType::Normal) {
            if (vaddr & mask(flags & AlignmentMask)) {
                stats.alignFaults++;
                return std::make_shared<DataAbort>(
                    vaddr_tainted,
                    TlbEntry::DomainType::NoAccess,
                    is_atomic ? false : is_write,
                    ArmFault::AlignmentFault, state.isStage2,
                    ArmFault::LpaeTran);
            }
        }
    }

    if (te->nonCacheable) {
        // Prevent prefetching from I/O devices.
        if (req->isPrefetch()) {
            // Here we can safely use the fault status for the short
            // desc. format in all cases
            return std::make_shared<PrefetchAbort>(
                vaddr_tainted,
                ArmFault::PrefetchUncacheable,
                state.isStage2, ArmFault::LpaeTran);
        }
    }

    bool grant = false;
    // grant_read is used for faults from an atomic instruction that
    // both reads and writes from a memory location. From a ISS point
    // of view they count as read if a read to that address would have
    // generated the fault; they count as writes otherwise
    bool grant_read = true;

    if (state.isStage2) {
        std::tie(grant, grant_read) = s2PermBits64(te, req, mode, tc, state,
            (!is_write && !is_fetch), is_write, is_fetch);
    } else {
        std::tie(grant, grant_read) = s1PermBits64(te, req, mode, tc, state,
            (!is_write && !is_fetch), is_write, is_fetch);
    }

    if (!grant) {
        if (is_fetch) {
            stats.permsFaults++;
            DPRINTF(TLB, "TLB Fault: Prefetch abort on permission check. "
                    "ns:%d scr.sif:%d sctlr.afe: %d\n",
                    te->ns, state.scr.sif, state.sctlr.afe);
            // Use PC value instead of vaddr because vaddr might be aligned to
            // cache line and should not be the address reported in FAR
            return std::make_shared<PrefetchAbort>(
                req->getPC(),
                ArmFault::PermissionLL + te->lookupLevel,
                state.isStage2, ArmFault::LpaeTran);
        } else {
            stats.permsFaults++;
            DPRINTF(TLB, "TLB Fault: Data abort on permission check."
                    "ns:%d", te->ns);
            return std::make_shared<DataAbort>(
                vaddr_tainted, te->domain,
                (is_atomic && !grant_read) ? false : is_write,
                ArmFault::PermissionLL + te->lookupLevel,
                state.isStage2, ArmFault::LpaeTran);
        }
    }

    return NoFault;
}

std::pair<bool, bool>
MMU::s2PermBits64(TlbEntry *te, const RequestPtr &req, Mode mode,
                  ThreadContext *tc, CachedState &state, bool r, bool w, bool x)
{
    assert(ArmSystem::haveEL(tc, EL2) && state.aarch64EL != EL2);

    // In stage 2 we use the hypervisor access permission bits.
    // The following permissions are described in ARM DDI 0487A.f
    // D4-1802
    bool grant = false;
    bool grant_read = te->hap & 0b01;
    bool grant_write = te->hap & 0b10;

    uint8_t xn =  te->xn;
    uint8_t pxn = te->pxn;

    if (ArmSystem::haveEL(tc, EL3) && state.isSecure &&
        te->ns && state.scr.sif) {
        xn = true;
    }

    DPRINTF(TLBVerbose,
            "Checking S2 permissions: hap:%d, xn:%d, pxn:%d, r:%d, "
            "w:%d, x:%d\n", te->hap, xn, pxn, r, w, x);

    if (x) {
        grant = grant_read && !xn;
    } else if (req->isAtomic()) {
        grant = grant_read || grant_write;
    } else if (w) {
        grant = grant_write;
    } else if (r) {
        grant = grant_read;
    } else {
        panic("Invalid Operation\n");
    }

    return std::make_pair(grant, grant_read);
}

std::pair<bool, bool>
MMU::s1PermBits64(TlbEntry *te, const RequestPtr &req, Mode mode,
                  ThreadContext *tc, CachedState &state, bool r, bool w, bool x)
{
    bool grant = false, grant_read = true;

    const uint8_t ap  = te->ap & 0b11;  // 2-bit access protection field
    const bool is_priv = state.isPriv && !(req->getFlags() & UserMode);

    bool wxn = state.sctlr.wxn;
    uint8_t xn =  te->xn;
    uint8_t pxn = te->pxn;

    if (ArmSystem::haveEL(tc, EL3) && state.isSecure &&
        te->ns && state.scr.sif) {
        xn = true;
    }

    DPRINTF(TLBVerbose, "Checking S1 permissions: ap:%d, xn:%d, pxn:%d, r:%d, "
                        "w:%d, x:%d, is_priv: %d, wxn: %d\n", ap, xn,
                        pxn, r, w, x, is_priv, wxn);

    if (faultPAN(tc, ap, req, mode, is_priv, state)) {
        return std::make_pair(false, false);
    }

    ExceptionLevel regime = !is_priv ? EL0 : state.aarch64EL;
    switch (regime) {
      case EL0:
        {
            grant_read = ap & 0x1;
            uint8_t perm = (ap << 2)  | (xn << 1) | pxn;
            switch (perm) {
              case 0:
              case 1:
              case 8:
              case 9:
                grant = x;
                break;
              case 4:
              case 5:
                grant = r || w || (x && !wxn);
                break;
              case 6:
              case 7:
                grant = r || w;
                break;
              case 12:
              case 13:
                grant = r || x;
                break;
              case 14:
              case 15:
                grant = r;
                break;
              default:
                grant = false;
            }
        }
        break;
      case EL1:
        {
            uint8_t perm = (ap << 2)  | (xn << 1) | pxn;
            switch (perm) {
              case 0:
              case 2:
                grant = r || w || (x && !wxn);
                break;
              case 1:
              case 3:
              case 4:
              case 5:
              case 6:
              case 7:
                // regions that are writeable at EL0 should not be
                // executable at EL1
                grant = r || w;
                break;
              case 8:
              case 10:
              case 12:
              case 14:
                grant = r || x;
                break;
              case 9:
              case 11:
              case 13:
              case 15:
                grant = r;
                break;
              default:
                grant = false;
            }
        }
        break;
      case EL2:
      case EL3:
        {
            uint8_t perm = (ap & 0x2) | xn;
            switch (perm) {
              case 0:
                grant = r || w || (x && !wxn);
                break;
              case 1:
                grant = r || w;
                break;
              case 2:
                grant = r || x;
                break;
              case 3:
                grant = r;
                break;
              default:
                grant = false;
            }
        }
        break;
    }

    return std::make_pair(grant, grant_read);
}

bool
MMU::faultPAN(ThreadContext *tc, uint8_t ap, const RequestPtr &req, Mode mode,
              const bool is_priv, CachedState &state)
{
    bool exception = false;
    switch (state.aarch64EL) {
      case EL0:
        break;
      case EL1:
        if (checkPAN(tc, ap, req, mode, is_priv, state)) {
            exception = true;;
        }
        break;
      case EL2:
        if (state.hcr.e2h && checkPAN(tc, ap, req, mode, is_priv, state)) {
            exception = true;;
        }
        break;
      case EL3:
        break;
    }

    return exception;
}

bool
MMU::checkPAN(ThreadContext *tc, uint8_t ap, const RequestPtr &req, Mode mode,
              const bool is_priv, CachedState &state)
{
    // The PAN bit has no effect on:
    // 1) Instruction accesses.
    // 2) Data Cache instructions other than DC ZVA
    // 3) Address translation instructions, other than ATS1E1RP and
    // ATS1E1WP when ARMv8.2-ATS1E1 is implemented. (Unimplemented in
    // gem5)
    // 4) Instructions to be treated as unprivileged, unless
    // HCR_EL2.{E2H, TGE} == {1, 0}
    const AA64MMFR1 mmfr1 = tc->readMiscReg(MISCREG_ID_AA64MMFR1_EL1);
    if (mmfr1.pan && state.cpsr.pan && (ap & 0x1) &&
        mode != BaseMMU::Execute) {

        if (req->isCacheMaintenance() &&
            !(req->getFlags() & Request::CACHE_BLOCK_ZERO)) {
            // Cache maintenance other than DC ZVA
            return false;
        } else if (!is_priv && !(state.hcr.e2h && !state.hcr.tge)) {
            // Treated as unprivileged unless HCR_EL2.{E2H, TGE} == {1, 0}
            return false;
        }
        return true;
    }

    return false;
}

Fault
MMU::translateMmuOff(ThreadContext *tc, const RequestPtr &req, Mode mode,
        ArmTranslationType tran_type, Addr vaddr, bool long_desc_format,
        CachedState &state)
{
    bool is_fetch  = (mode == Execute);
    bool is_atomic = req->isAtomic();
    req->setPaddr(vaddr);
    // When the MMU is off the security attribute corresponds to the
    // security state of the processor
    if (state.isSecure)
        req->setFlags(Request::SECURE);

    if (state.aarch64) {
        bool selbit = bits(vaddr, 55);
        TCR tcr1 = tc->readMiscReg(MISCREG_TCR_EL1);
        int topbit = computeAddrTop(tc, selbit, is_fetch, tcr1, currEL(tc));
        int addr_sz = bits(vaddr, topbit, physAddrRange);
        if (addr_sz != 0){
            Fault f;
            if (is_fetch)
                f = std::make_shared<PrefetchAbort>(vaddr,
                    ArmFault::AddressSizeLL, state.isStage2,
                    ArmFault::LpaeTran);
            else
                f = std::make_shared<DataAbort>( vaddr,
                    TlbEntry::DomainType::NoAccess,
                    is_atomic ? false : mode==Write,
                    ArmFault::AddressSizeLL, state.isStage2,
                    ArmFault::LpaeTran);
            return f;
        }
    }

    // @todo: double check this (ARM ARM issue C B3.2.1)
    if (long_desc_format || state.sctlr.tre == 0 || state.nmrr.ir0 == 0 ||
        state.nmrr.or0 == 0 || state.prrr.tr0 != 0x2) {
        if (!req->isCacheMaintenance()) {
            req->setFlags(Request::UNCACHEABLE);
        }
        req->setFlags(Request::STRICT_ORDER);
    }

    // Set memory attributes
    TlbEntry temp_te;
    temp_te.ns = !state.isSecure;
    bool dc = (HaveVirtHostExt(tc)
               && state.hcr.e2h == 1 && state.hcr.tge == 1) ? 0: state.hcr.dc;
    bool i_cacheability = state.sctlr.i && !state.sctlr.m;
    if (state.isStage2 || !dc || state.isSecure ||
       (state.isHyp && !(tran_type & S1CTran))) {

        temp_te.mtype      = is_fetch ? TlbEntry::MemoryType::Normal
                                      : TlbEntry::MemoryType::StronglyOrdered;
        temp_te.innerAttrs = i_cacheability? 0x2: 0x0;
        temp_te.outerAttrs = i_cacheability? 0x2: 0x0;
        temp_te.shareable  = true;
        temp_te.outerShareable = true;
    } else {
        temp_te.mtype      = TlbEntry::MemoryType::Normal;
        temp_te.innerAttrs = 0x3;
        temp_te.outerAttrs = 0x3;
        temp_te.shareable  = false;
        temp_te.outerShareable = false;
    }
    temp_te.setAttributes(long_desc_format);
    DPRINTF(TLBVerbose, "(No MMU) setting memory attributes: shareable: "
            "%d, innerAttrs: %d, outerAttrs: %d, stage2: %d\n",
            temp_te.shareable, temp_te.innerAttrs, temp_te.outerAttrs,
            state.isStage2);
    setAttr(temp_te.attributes);

    return testTranslation(req, mode, TlbEntry::DomainType::NoAccess, state);
}

Fault
MMU::translateMmuOn(ThreadContext* tc, const RequestPtr &req, Mode mode,
                    Translation *translation, bool &delay, bool timing,
                    bool functional, Addr vaddr,
                    ArmFault::TranMethod tranMethod, CachedState &state)
{
    TlbEntry *te = NULL;
    bool is_fetch  = (mode == Execute);
    TlbEntry mergeTe;

    Request::Flags flags = req->getFlags();
    Addr vaddr_tainted = req->getVaddr();

    Fault fault = getResultTe(&te, req, tc, mode, translation, timing,
                              functional, &mergeTe, state);
    // only proceed if we have a valid table entry
    if (!isCompleteTranslation(te) && (fault == NoFault)) delay = true;

    // If we have the table entry transfer some of the attributes to the
    // request that triggered the translation
    if (isCompleteTranslation(te)) {
        // Set memory attributes
        DPRINTF(TLBVerbose,
                "Setting memory attributes: shareable: %d, innerAttrs: %d, "
                "outerAttrs: %d, mtype: %d, stage2: %d\n",
                te->shareable, te->innerAttrs, te->outerAttrs,
                static_cast<uint8_t>(te->mtype), state.isStage2);
        setAttr(te->attributes);

        if (te->nonCacheable && !req->isCacheMaintenance())
            req->setFlags(Request::UNCACHEABLE);

        // Require requests to be ordered if the request goes to
        // strongly ordered or device memory (i.e., anything other
        // than normal memory requires strict order).
        if (te->mtype != TlbEntry::MemoryType::Normal)
            req->setFlags(Request::STRICT_ORDER);

        Addr pa = te->pAddr(vaddr);
        req->setPaddr(pa);

        if (state.isSecure && !te->ns) {
            req->setFlags(Request::SECURE);
        }
        if (!is_fetch && fault == NoFault &&
            (vaddr & mask(flags & AlignmentMask)) &&
            (te->mtype != TlbEntry::MemoryType::Normal)) {
                // Unaligned accesses to Device memory should always cause an
                // abort regardless of sctlr.a
                stats.alignFaults++;
                bool is_write  = (mode == Write);
                return std::make_shared<DataAbort>(
                    vaddr_tainted,
                    TlbEntry::DomainType::NoAccess, is_write,
                    ArmFault::AlignmentFault, state.isStage2,
                    tranMethod);
        }

        // Check for a trickbox generated address fault
        if (fault == NoFault)
            fault = testTranslation(req, mode, te->domain, state);
    }

    if (fault == NoFault) {
        // Don't try to finalize a physical address unless the
        // translation has completed (i.e., there is a table entry).
        return te ? finalizePhysical(req, tc, mode) : NoFault;
    } else {
        return fault;
    }
}

Fault
MMU::translateFs(const RequestPtr &req, ThreadContext *tc, Mode mode,
        Translation *translation, bool &delay, bool timing,
        ArmTranslationType tran_type, bool functional,
        CachedState &state)
{
    // No such thing as a functional timing access
    assert(!(timing && functional));

    Addr vaddr_tainted = req->getVaddr();
    Addr vaddr = 0;
    if (state.aarch64)
        vaddr = purifyTaggedAddr(vaddr_tainted, tc, state.aarch64EL,
            (TCR)state.ttbcr, mode==Execute);
    else
        vaddr = vaddr_tainted;
    Request::Flags flags = req->getFlags();

    bool is_fetch  = (mode == Execute);
    bool is_write  = (mode == Write);
    bool long_desc_format = state.aarch64 || longDescFormatInUse(tc);
    ArmFault::TranMethod tranMethod = long_desc_format ? ArmFault::LpaeTran
                                                       : ArmFault::VmsaTran;

    DPRINTF(TLBVerbose,
            "CPSR is priv:%d UserMode:%d secure:%d S1S2NsTran:%d\n",
            state.isPriv, flags & UserMode, state.isSecure,
            tran_type & S1S2NsTran);

    DPRINTF(TLB, "translateFs addr %#x, mode %d, st2 %d, scr %#x sctlr %#x "
                 "flags %#lx tranType 0x%x\n", vaddr_tainted, mode,
                 state.isStage2, state.scr, state.sctlr, flags, tran_type);

    if (!state.isStage2) {
        if ((req->isInstFetch() && (!state.sctlr.i)) ||
            ((!req->isInstFetch()) && (!state.sctlr.c))){
            if (!req->isCacheMaintenance()) {
                req->setFlags(Request::UNCACHEABLE);
            }
            req->setFlags(Request::STRICT_ORDER);
        }
    }
    if (!is_fetch) {
        if (state.sctlr.a || !(flags & AllowUnaligned)) {
            if (vaddr & mask(flags & AlignmentMask)) {
                stats.alignFaults++;
                return std::make_shared<DataAbort>(
                    vaddr_tainted,
                    TlbEntry::DomainType::NoAccess, is_write,
                    ArmFault::AlignmentFault, state.isStage2,
                    tranMethod);
            }
        }
    }

    bool vm = state.hcr.vm;
    if (HaveVirtHostExt(tc) && state.hcr.e2h == 1 && state.hcr.tge ==1)
        vm = 0;
    else if (state.hcr.dc == 1)
        vm = 1;

    Fault fault = NoFault;
    // If guest MMU is off or hcr.vm=0 go straight to stage2
    if ((state.isStage2 && !vm) || (!state.isStage2 && !state.sctlr.m)) {
        fault = translateMmuOff(tc, req, mode, tran_type, vaddr,
                                long_desc_format, state);
    } else {
        DPRINTF(TLBVerbose, "Translating %s=%#x context=%d\n",
                state.isStage2 ? "IPA" : "VA", vaddr_tainted, state.asid);
        // Translation enabled
        fault = translateMmuOn(tc, req, mode, translation, delay, timing,
                               functional, vaddr, tranMethod, state);
    }

    // Check for Debug Exceptions
    SelfDebug *sd = ArmISA::ISA::getSelfDebug(tc);

    if (sd->enabled() && fault == NoFault) {
        fault = sd->testDebug(tc, req, mode);
    }

    return fault;
}

Fault
MMU::translateAtomic(const RequestPtr &req, ThreadContext *tc, Mode mode,
    ArmTranslationType tran_type)
{
    return translateAtomic(req, tc, mode, tran_type, false);
}

Fault
MMU::translateAtomic(const RequestPtr &req, ThreadContext *tc, Mode mode,
    ArmTranslationType tran_type, bool stage2)
{
    auto& state = updateMiscReg(tc, tran_type, stage2);

    bool delay = false;
    Fault fault;
    if (FullSystem)
        fault = translateFs(req, tc, mode, NULL, delay, false,
            tran_type, false, state);
    else
        fault = translateSe(req, tc, mode, NULL, delay, false, state);
    assert(!delay);
    return fault;
}

Fault
MMU::translateFunctional(const RequestPtr &req, ThreadContext *tc, Mode mode)
{
    return translateFunctional(req, tc, mode, NormalTran, false);
}

Fault
MMU::translateFunctional(const RequestPtr &req, ThreadContext *tc, Mode mode,
    ArmTranslationType tran_type)
{
    return translateFunctional(req, tc, mode, tran_type, false);
}

Fault
MMU::translateFunctional(const RequestPtr &req, ThreadContext *tc, Mode mode,
    ArmTranslationType tran_type, bool stage2)
{
    auto& state = updateMiscReg(tc, tran_type, stage2);

    bool delay = false;
    Fault fault;
    if (FullSystem)
        fault = translateFs(req, tc, mode, NULL, delay, false,
            tran_type, true, state);
   else
        fault = translateSe(req, tc, mode, NULL, delay, false, state);
    assert(!delay);
    return fault;
}

void
MMU::translateTiming(const RequestPtr &req, ThreadContext *tc,
    Translation *translation, Mode mode, ArmTranslationType tran_type,
    bool stage2)
{
    auto& state = updateMiscReg(tc, tran_type, stage2);

    assert(translation);

    translateComplete(req, tc, translation, mode, tran_type,
        stage2, state);
}

Fault
MMU::translateComplete(const RequestPtr &req, ThreadContext *tc,
        Translation *translation, Mode mode, ArmTranslationType tran_type,
        bool call_from_s2)
{
    return translateComplete(req, tc, translation, mode, tran_type,
        call_from_s2, s1State);
}

Fault
MMU::translateComplete(const RequestPtr &req, ThreadContext *tc,
        Translation *translation, Mode mode, ArmTranslationType tran_type,
        bool call_from_s2, CachedState &state)
{
    bool delay = false;
    Fault fault;
    if (FullSystem)
        fault = translateFs(req, tc, mode, translation, delay, true, tran_type,
            false, state);
    else
        fault = translateSe(req, tc, mode, translation, delay, true, state);

    DPRINTF(TLBVerbose, "Translation returning delay=%d fault=%d\n", delay,
            fault != NoFault);
    // If we have a translation, and we're not in the middle of doing a stage
    // 2 translation tell the translation that we've either finished or its
    // going to take a while. By not doing this when we're in the middle of a
    // stage 2 translation we prevent marking the translation as delayed twice,
    // one when the translation starts and again when the stage 1 translation
    // completes.

    if (translation && (call_from_s2 || !state.stage2Req || req->hasPaddr() ||
        fault != NoFault)) {
        if (!delay)
            translation->finish(fault, req, tc, mode);
        else
            translation->markDelayed();
    }
    return fault;
}

vmid_t
MMU::CachedState::getVMID(ThreadContext *tc) const
{
    AA64MMFR1 mmfr1 = tc->readMiscReg(MISCREG_ID_AA64MMFR1_EL1);
    VTCR_t vtcr = tc->readMiscReg(MISCREG_VTCR_EL2);
    vmid_t vmid = 0;

    switch (mmfr1.vmidbits) {
      case 0b0000:
        // 8 bits
        vmid = bits(tc->readMiscReg(MISCREG_VTTBR_EL2), 55, 48);
        break;
      case 0b0010:
        if (vtcr.vs && ELIs64(tc, EL2)) {
            // 16 bits
            vmid = bits(tc->readMiscReg(MISCREG_VTTBR_EL2), 63, 48);
        } else {
            // 8 bits
            vmid = bits(tc->readMiscReg(MISCREG_VTTBR_EL2), 55, 48);
        }
        break;
      default:
        panic("Reserved ID_AA64MMFR1_EL1.VMIDBits value: %#x",
              mmfr1.vmidbits);
    }

    return vmid;
}

MMU::CachedState&
MMU::updateMiscReg(ThreadContext *tc,
    ArmTranslationType tran_type, bool stage2)
{
    // check if the regs have changed, or the translation mode is different.
    // NOTE: the tran type doesn't affect stage 2 TLB's as they only handle
    // one type of translation anyway

    auto& state = stage2 ? s2State : s1State;
    if (state.miscRegValid && miscRegContext == tc->contextId() &&
        ((tran_type == state.curTranType) || stage2)) {

    } else {
        DPRINTF(TLBVerbose, "TLB variables changed!\n");
        state.updateMiscReg(tc, tran_type);

        itbStage2->setVMID(state.vmid);
        dtbStage2->setVMID(state.vmid);

        for (auto tlb : instruction) {
            static_cast<TLB*>(tlb)->setVMID(state.vmid);
        }
        for (auto tlb : data) {
            static_cast<TLB*>(tlb)->setVMID(state.vmid);
        }
        for (auto tlb : unified) {
            static_cast<TLB*>(tlb)->setVMID(state.vmid);
        }

        miscRegContext = tc->contextId();
    }

    if (state.directToStage2) {
        s2State.updateMiscReg(tc, tran_type);
        return s2State;
    } else {
        return state;
    }
}

void
MMU::CachedState::updateMiscReg(ThreadContext *tc,
    ArmTranslationType tran_type)
{
    cpsr = tc->readMiscReg(MISCREG_CPSR);

    // Dependencies: SCR/SCR_EL3, CPSR
    isSecure = ArmISA::isSecure(tc) &&
        !(tran_type & HypMode) && !(tran_type & S1S2NsTran);

    aarch64EL = tranTypeEL(cpsr, tran_type);
    aarch64 = isStage2 ?
        ELIs64(tc, EL2) :
        ELIs64(tc, aarch64EL == EL0 ? EL1 : aarch64EL);

    hcr = tc->readMiscReg(MISCREG_HCR_EL2);
    if (aarch64) {  // AArch64
        // determine EL we need to translate in
        switch (aarch64EL) {
          case EL0:
            if (HaveVirtHostExt(tc) && hcr.tge == 1 && hcr.e2h == 1) {
                // VHE code for EL2&0 regime
                sctlr = tc->readMiscReg(MISCREG_SCTLR_EL2);
                ttbcr = tc->readMiscReg(MISCREG_TCR_EL2);
                uint64_t ttbr_asid = ttbcr.a1 ?
                    tc->readMiscReg(MISCREG_TTBR1_EL2) :
                    tc->readMiscReg(MISCREG_TTBR0_EL2);
                asid = bits(ttbr_asid,
                            (mmu->haveLargeAsid64 && ttbcr.as) ? 63 : 55, 48);

            } else {
                sctlr = tc->readMiscReg(MISCREG_SCTLR_EL1);
                ttbcr = tc->readMiscReg(MISCREG_TCR_EL1);
                uint64_t ttbr_asid = ttbcr.a1 ?
                    tc->readMiscReg(MISCREG_TTBR1_EL1) :
                    tc->readMiscReg(MISCREG_TTBR0_EL1);
                asid = bits(ttbr_asid,
                            (mmu->haveLargeAsid64 && ttbcr.as) ? 63 : 55, 48);

            }
            break;
          case EL1:
            {
                sctlr = tc->readMiscReg(MISCREG_SCTLR_EL1);
                ttbcr = tc->readMiscReg(MISCREG_TCR_EL1);
                uint64_t ttbr_asid = ttbcr.a1 ?
                    tc->readMiscReg(MISCREG_TTBR1_EL1) :
                    tc->readMiscReg(MISCREG_TTBR0_EL1);
                asid = bits(ttbr_asid,
                            (mmu->haveLargeAsid64 && ttbcr.as) ? 63 : 55, 48);
            }
            break;
          case EL2:
            sctlr = tc->readMiscReg(MISCREG_SCTLR_EL2);
            ttbcr = tc->readMiscReg(MISCREG_TCR_EL2);
            if (hcr.e2h == 1) {
                // VHE code for EL2&0 regime
                uint64_t ttbr_asid = ttbcr.a1 ?
                    tc->readMiscReg(MISCREG_TTBR1_EL2) :
                    tc->readMiscReg(MISCREG_TTBR0_EL2);
                asid = bits(ttbr_asid,
                            (mmu->haveLargeAsid64 && ttbcr.as) ? 63 : 55, 48);
            } else {
                asid = -1;
            }
            break;
          case EL3:
            sctlr = tc->readMiscReg(MISCREG_SCTLR_EL3);
            ttbcr = tc->readMiscReg(MISCREG_TCR_EL3);
            asid = -1;
            break;
        }

        scr = tc->readMiscReg(MISCREG_SCR_EL3);
        isPriv = aarch64EL != EL0;
        if (mmu->release()->has(ArmExtension::VIRTUALIZATION)) {
            vmid = getVMID(tc);
            isHyp = aarch64EL == EL2;
            isHyp |= tran_type & HypMode;
            isHyp &= (tran_type & S1S2NsTran) == 0;
            isHyp &= (tran_type & S1CTran)    == 0;
            bool vm = hcr.vm;
            if (HaveVirtHostExt(tc) && hcr.e2h == 1 && hcr.tge ==1) {
                vm = 0;
            }

            if (hcr.e2h == 1 && (aarch64EL == EL2
                                  || (hcr.tge ==1 && aarch64EL == EL0))) {
                isHyp = true;
                directToStage2 = false;
                stage2Req      = false;
                stage2DescReq  = false;
            } else {
            // Work out if we should skip the first stage of translation and go
            // directly to stage 2. This value is cached so we don't have to
            // compute it for every translation.
                bool sec = !isSecure || (isSecure && IsSecureEL2Enabled(tc));
                stage2Req = isStage2 ||
                            (vm && !isHyp && sec &&
                             !(tran_type & S1CTran) && (aarch64EL < EL2) &&
                             !(tran_type & S1E1Tran)); // <--- FIX THIS HACK
                stage2DescReq = isStage2 ||  (vm && !isHyp && sec &&
                                (aarch64EL < EL2));
                directToStage2 = !isStage2 && stage2Req && !sctlr.m;
            }
        } else {
            vmid           = 0;
            isHyp          = false;
            directToStage2 = false;
            stage2Req      = false;
            stage2DescReq  = false;
        }
    } else {  // AArch32
        sctlr  = tc->readMiscReg(snsBankedIndex(MISCREG_SCTLR, tc,
                                 !isSecure));
        ttbcr  = tc->readMiscReg(snsBankedIndex(MISCREG_TTBCR, tc,
                                 !isSecure));
        scr    = tc->readMiscReg(MISCREG_SCR);
        isPriv = cpsr.mode != MODE_USER;
        if (longDescFormatInUse(tc)) {
            uint64_t ttbr_asid = tc->readMiscReg(
                snsBankedIndex(ttbcr.a1 ? MISCREG_TTBR1 :
                                          MISCREG_TTBR0,
                                       tc, !isSecure));
            asid = bits(ttbr_asid, 55, 48);
        } else { // Short-descriptor translation table format in use
            CONTEXTIDR context_id = tc->readMiscReg(snsBankedIndex(
                MISCREG_CONTEXTIDR, tc,!isSecure));
            asid = context_id.asid;
        }
        prrr = tc->readMiscReg(snsBankedIndex(MISCREG_PRRR, tc,
                               !isSecure));
        nmrr = tc->readMiscReg(snsBankedIndex(MISCREG_NMRR, tc,
                               !isSecure));
        dacr = tc->readMiscReg(snsBankedIndex(MISCREG_DACR, tc,
                               !isSecure));
        hcr  = tc->readMiscReg(MISCREG_HCR);

        if (mmu->release()->has(ArmExtension::VIRTUALIZATION)) {
            vmid   = bits(tc->readMiscReg(MISCREG_VTTBR), 55, 48);
            isHyp  = cpsr.mode == MODE_HYP;
            isHyp |=  tran_type & HypMode;
            isHyp &= (tran_type & S1S2NsTran) == 0;
            isHyp &= (tran_type & S1CTran)    == 0;
            if (isHyp) {
                sctlr = tc->readMiscReg(MISCREG_HSCTLR);
            }
            // Work out if we should skip the first stage of translation and go
            // directly to stage 2. This value is cached so we don't have to
            // compute it for every translation.
            bool sec = !isSecure || (isSecure && IsSecureEL2Enabled(tc));
            stage2Req      = hcr.vm && !isStage2 && !isHyp && sec &&
                             !(tran_type & S1CTran);
            stage2DescReq  = hcr.vm && !isStage2 && !isHyp && sec;
            directToStage2 = stage2Req && !sctlr.m;
        } else {
            vmid           = 0;
            stage2Req      = false;
            isHyp          = false;
            directToStage2 = false;
            stage2DescReq  = false;
        }
    }
    miscRegValid = true;
    curTranType  = tran_type;
}

ExceptionLevel
MMU::tranTypeEL(CPSR cpsr, ArmTranslationType type)
{
    switch (type) {
      case S1E0Tran:
      case S12E0Tran:
        return EL0;

      case S1E1Tran:
      case S12E1Tran:
        return EL1;

      case S1E2Tran:
        return EL2;

      case S1E3Tran:
        return EL3;

      case NormalTran:
      case S1CTran:
      case S1S2NsTran:
      case HypMode:
        return currEL(cpsr);

      default:
        panic("Unknown translation mode!\n");
    }
}

Fault
MMU::getTE(TlbEntry **te, const RequestPtr &req, ThreadContext *tc, Mode mode,
        Translation *translation, bool timing, bool functional,
        bool is_secure, ArmTranslationType tran_type,
        bool stage2)
{
    return getTE(te, req, tc, mode, translation, timing, functional,
        is_secure, tran_type, stage2 ? s2State : s1State);
}

TlbEntry*
MMU::lookup(Addr va, uint16_t asid, vmid_t vmid, bool hyp, bool secure,
            bool functional, bool ignore_asn, ExceptionLevel target_el,
            bool in_host, bool stage2, BaseMMU::Mode mode)
{
    TLB *tlb = getTlb(mode, stage2);

    TlbEntry::Lookup lookup_data;

    lookup_data.va = va;
    lookup_data.asn = asid;
    lookup_data.ignoreAsn = ignore_asn;
    lookup_data.vmid = vmid;
    lookup_data.hyp = hyp;
    lookup_data.secure = secure;
    lookup_data.functional = functional;
    lookup_data.targetEL = target_el;
    lookup_data.inHost = in_host;
    lookup_data.mode = mode;

    return tlb->multiLookup(lookup_data);
}

Fault
MMU::getTE(TlbEntry **te, const RequestPtr &req, ThreadContext *tc, Mode mode,
        Translation *translation, bool timing, bool functional,
        bool is_secure, ArmTranslationType tran_type,
        CachedState& state)
{
    // In a 2-stage system, the IPA->PA translation can be started via this
    // call so make sure the miscRegs are correct.
    if (state.isStage2) {
        updateMiscReg(tc, tran_type, true);
    }

    Addr vaddr_tainted = req->getVaddr();
    Addr vaddr = 0;
    ExceptionLevel target_el = state.aarch64 ? state.aarch64EL : EL1;
    if (state.aarch64) {
        vaddr = purifyTaggedAddr(vaddr_tainted, tc, target_el,
            (TCR)state.ttbcr, mode==Execute);
    } else {
        vaddr = vaddr_tainted;
    }

    *te = lookup(vaddr, state.asid, state.vmid, state.isHyp, is_secure, false,
                 false, target_el, false, state.isStage2, mode);

    if (!isCompleteTranslation(*te)) {
        if (req->isPrefetch()) {
            // if the request is a prefetch don't attempt to fill the TLB or go
            // any further with the memory access (here we can safely use the
            // fault status for the short desc. format in all cases)
           stats.prefetchFaults++;
           return std::make_shared<PrefetchAbort>(
               vaddr_tainted, ArmFault::PrefetchTLBMiss, state.isStage2);
        }

        // start translation table walk, pass variables rather than
        // re-retreaving in table walker for speed
        DPRINTF(TLB,
                "TLB Miss: Starting hardware table walker for %#x(%d:%d)\n",
                vaddr_tainted, state.asid, state.vmid);

        Fault fault;
        fault = getTableWalker(mode, state.isStage2)->walk(
            req, tc, state.asid, state.vmid, state.isHyp, mode,
            translation, timing, functional, is_secure,
            tran_type, state.stage2DescReq, *te);

        // for timing mode, return and wait for table walk,
        if (timing || fault != NoFault) {
            return fault;
        }

        *te = lookup(vaddr, state.asid, state.vmid, state.isHyp, is_secure,
                     true, false, target_el, false, state.isStage2, mode);
        assert(*te);
    }
    return NoFault;
}

Fault
MMU::getResultTe(TlbEntry **te, const RequestPtr &req,
        ThreadContext *tc, Mode mode,
        Translation *translation, bool timing, bool functional,
        TlbEntry *mergeTe, CachedState &state)
{
    Fault fault;

    if (state.isStage2) {
        // We are already in the stage 2 TLB. Grab the table entry for stage
        // 2 only. We are here because stage 1 translation is disabled.
        TlbEntry *s2_te = nullptr;
        // Get the stage 2 table entry
        fault = getTE(&s2_te, req, tc, mode, translation, timing, functional,
                      state.isSecure, state.curTranType, state);
        // Check permissions of stage 2
        if (isCompleteTranslation(s2_te) && (fault == NoFault)) {
            if (state.aarch64)
                fault = checkPermissions64(s2_te, req, mode, tc, state);
            else
                fault = checkPermissions(s2_te, req, mode, state);
        }
        *te = s2_te;
        return fault;
    }

    TlbEntry *s1_te = nullptr;

    Addr vaddr_tainted = req->getVaddr();

    // Get the stage 1 table entry
    fault = getTE(&s1_te, req, tc, mode, translation, timing, functional,
                  state.isSecure, state.curTranType, state);
    // only proceed if we have a valid table entry
    if (isCompleteTranslation(s1_te) && (fault == NoFault)) {
        // Check stage 1 permissions before checking stage 2
        if (state.aarch64)
            fault = checkPermissions64(s1_te, req, mode, tc, state);
        else
            fault = checkPermissions(s1_te, req, mode, state);
        if (state.stage2Req & (fault == NoFault)) {
            Stage2LookUp *s2_lookup = new Stage2LookUp(this, *s1_te,
                req, translation, mode, timing, functional, state.isSecure,
                state.curTranType);
            fault = s2_lookup->getTe(tc, mergeTe);
            if (s2_lookup->isComplete()) {
                *te = mergeTe;
                // We've finished with the lookup so delete it
                delete s2_lookup;
            } else {
                // The lookup hasn't completed, so we can't delete it now. We
                // get round this by asking the object to self delete when the
                // translation is complete.
                s2_lookup->setSelfDelete();
            }
        } else {
            // This case deals with an S1 hit (or bypass), followed by
            // an S2 hit-but-perms issue
            if (state.isStage2) {
                DPRINTF(TLBVerbose, "s2TLB: reqVa %#x, reqPa %#x, fault %p\n",
                        vaddr_tainted, req->hasPaddr() ? req->getPaddr() : ~0,
                        fault);
                if (fault != NoFault) {
                    auto arm_fault = reinterpret_cast<ArmFault*>(fault.get());
                    arm_fault->annotate(ArmFault::S1PTW, false);
                    arm_fault->annotate(ArmFault::OVA, vaddr_tainted);
                }
            }
            *te = s1_te;
        }
    }
    return fault;
}

bool
MMU::isCompleteTranslation(TlbEntry *entry) const
{
    return entry && !entry->partial;
}

void
MMU::takeOverFrom(BaseMMU *old_mmu)
{
    BaseMMU::takeOverFrom(old_mmu);

    auto *ommu = dynamic_cast<MMU*>(old_mmu);
    assert(ommu);

    _attr = ommu->_attr;

    s1State = ommu->s1State;
    s2State = ommu->s2State;
}

void
MMU::setTestInterface(SimObject *_ti)
{
    if (!_ti) {
        test = nullptr;
    } else {
        TlbTestInterface *ti(dynamic_cast<TlbTestInterface *>(_ti));
        fatal_if(!ti, "%s is not a valid ARM TLB tester\n", _ti->name());
        test = ti;
    }
}

Fault
MMU::testTranslation(const RequestPtr &req, Mode mode,
                     TlbEntry::DomainType domain, CachedState &state)
{
    if (!test || !req->hasSize() || req->getSize() == 0 ||
        req->isCacheMaintenance()) {
        return NoFault;
    } else {
        return test->translationCheck(req, state.isPriv, mode, domain);
    }
}

Fault
MMU::testWalk(Addr pa, Addr size, Addr va, bool is_secure, Mode mode,
              TlbEntry::DomainType domain, LookupLevel lookup_level,
              bool stage2)
{
    return testWalk(pa, size, va, is_secure, mode, domain, lookup_level,
        stage2 ? s2State : s1State);
}

Fault
MMU::testWalk(Addr pa, Addr size, Addr va, bool is_secure, Mode mode,
              TlbEntry::DomainType domain, LookupLevel lookup_level,
              CachedState &state)
{
    if (!test) {
        return NoFault;
    } else {
        return test->walkCheck(pa, size, va, is_secure, state.isPriv, mode,
                               domain, lookup_level);
    }
}

MMU::Stats::Stats(statistics::Group *parent)
  : statistics::Group(parent),
    ADD_STAT(alignFaults, statistics::units::Count::get(),
             "Number of MMU faults due to alignment restrictions"),
    ADD_STAT(prefetchFaults, statistics::units::Count::get(),
             "Number of MMU faults due to prefetch"),
    ADD_STAT(domainFaults, statistics::units::Count::get(),
             "Number of MMU faults due to domain restrictions"),
    ADD_STAT(permsFaults, statistics::units::Count::get(),
             "Number of MMU faults due to permissions restrictions")
{
}

} // namespace gem5
