/*
 * 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),
    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();
}

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 ((te == NULL) && (fault == NoFault)) delay = true;

    // If we have the table entry transfer some of the attributes to the
    // request that triggered the translation
    if (te != NULL) {
        // 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 (*te == NULL) {
        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);

        // 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 = NULL;
        // 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 ((s2_te != NULL) && (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 *s1Te = NULL;

    Addr vaddr_tainted = req->getVaddr();

    // Get the stage 1 table entry
    fault = getTE(&s1Te, req, tc, mode, translation, timing, functional,
                  state.isSecure, state.curTranType, state);
    // only proceed if we have a valid table entry
    if ((s1Te != NULL) && (fault == NoFault)) {
        // Check stage 1 permissions before checking stage 2
        if (state.aarch64)
            fault = checkPermissions64(s1Te, req, mode, tc, state);
        else
            fault = checkPermissions(s1Te, req, mode, state);
        if (state.stage2Req & (fault == NoFault)) {
            Stage2LookUp *s2_lookup = new Stage2LookUp(this, *s1Te,
                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 = s1Te;
        }
    }
    return fault;
}

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
