/*
 * Copyright (c) 2010, 2012-2014, 2016-2017 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) 2003-2005 The Regents of The University of Michigan
 * Copyright (c) 2007-2008 The Florida State University
 * 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.
 *
 * Authors: Ali Saidi
 *          Gabe Black
 *          Giacomo Gabrielli
 *          Thomas Grocutt
 */

#include "arch/arm/faults.hh"

#include "arch/arm/insts/static_inst.hh"
#include "arch/arm/system.hh"
#include "arch/arm/utility.hh"
#include "base/compiler.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "debug/Faults.hh"
#include "sim/full_system.hh"

namespace ArmISA
{

uint8_t ArmFault::shortDescFaultSources[] = {
    0x01,  // AlignmentFault
    0x04,  // InstructionCacheMaintenance
    0xff,  // SynchExtAbtOnTranslTableWalkL0 (INVALID)
    0x0c,  // SynchExtAbtOnTranslTableWalkL1
    0x0e,  // SynchExtAbtOnTranslTableWalkL2
    0xff,  // SynchExtAbtOnTranslTableWalkL3 (INVALID)
    0xff,  // SynchPtyErrOnTranslTableWalkL0 (INVALID)
    0x1c,  // SynchPtyErrOnTranslTableWalkL1
    0x1e,  // SynchPtyErrOnTranslTableWalkL2
    0xff,  // SynchPtyErrOnTranslTableWalkL3 (INVALID)
    0xff,  // TranslationL0 (INVALID)
    0x05,  // TranslationL1
    0x07,  // TranslationL2
    0xff,  // TranslationL3 (INVALID)
    0xff,  // AccessFlagL0 (INVALID)
    0x03,  // AccessFlagL1
    0x06,  // AccessFlagL2
    0xff,  // AccessFlagL3 (INVALID)
    0xff,  // DomainL0 (INVALID)
    0x09,  // DomainL1
    0x0b,  // DomainL2
    0xff,  // DomainL3 (INVALID)
    0xff,  // PermissionL0 (INVALID)
    0x0d,  // PermissionL1
    0x0f,  // PermissionL2
    0xff,  // PermissionL3 (INVALID)
    0x02,  // DebugEvent
    0x08,  // SynchronousExternalAbort
    0x10,  // TLBConflictAbort
    0x19,  // SynchPtyErrOnMemoryAccess
    0x16,  // AsynchronousExternalAbort
    0x18,  // AsynchPtyErrOnMemoryAccess
    0xff,  // AddressSizeL0 (INVALID)
    0xff,  // AddressSizeL1 (INVALID)
    0xff,  // AddressSizeL2 (INVALID)
    0xff,  // AddressSizeL3 (INVALID)
    0x40,  // PrefetchTLBMiss
    0x80   // PrefetchUncacheable
};

static_assert(sizeof(ArmFault::shortDescFaultSources) ==
              ArmFault::NumFaultSources,
              "Invalid size of ArmFault::shortDescFaultSources[]");

uint8_t ArmFault::longDescFaultSources[] = {
    0x21,  // AlignmentFault
    0xff,  // InstructionCacheMaintenance (INVALID)
    0xff,  // SynchExtAbtOnTranslTableWalkL0 (INVALID)
    0x15,  // SynchExtAbtOnTranslTableWalkL1
    0x16,  // SynchExtAbtOnTranslTableWalkL2
    0x17,  // SynchExtAbtOnTranslTableWalkL3
    0xff,  // SynchPtyErrOnTranslTableWalkL0 (INVALID)
    0x1d,  // SynchPtyErrOnTranslTableWalkL1
    0x1e,  // SynchPtyErrOnTranslTableWalkL2
    0x1f,  // SynchPtyErrOnTranslTableWalkL3
    0xff,  // TranslationL0 (INVALID)
    0x05,  // TranslationL1
    0x06,  // TranslationL2
    0x07,  // TranslationL3
    0xff,  // AccessFlagL0 (INVALID)
    0x09,  // AccessFlagL1
    0x0a,  // AccessFlagL2
    0x0b,  // AccessFlagL3
    0xff,  // DomainL0 (INVALID)
    0x3d,  // DomainL1
    0x3e,  // DomainL2
    0xff,  // DomainL3 (RESERVED)
    0xff,  // PermissionL0 (INVALID)
    0x0d,  // PermissionL1
    0x0e,  // PermissionL2
    0x0f,  // PermissionL3
    0x22,  // DebugEvent
    0x10,  // SynchronousExternalAbort
    0x30,  // TLBConflictAbort
    0x18,  // SynchPtyErrOnMemoryAccess
    0x11,  // AsynchronousExternalAbort
    0x19,  // AsynchPtyErrOnMemoryAccess
    0xff,  // AddressSizeL0 (INVALID)
    0xff,  // AddressSizeL1 (INVALID)
    0xff,  // AddressSizeL2 (INVALID)
    0xff,  // AddressSizeL3 (INVALID)
    0x40,  // PrefetchTLBMiss
    0x80   // PrefetchUncacheable
};

static_assert(sizeof(ArmFault::longDescFaultSources) ==
              ArmFault::NumFaultSources,
              "Invalid size of ArmFault::longDescFaultSources[]");

uint8_t ArmFault::aarch64FaultSources[] = {
    0x21,  // AlignmentFault
    0xff,  // InstructionCacheMaintenance (INVALID)
    0x14,  // SynchExtAbtOnTranslTableWalkL0
    0x15,  // SynchExtAbtOnTranslTableWalkL1
    0x16,  // SynchExtAbtOnTranslTableWalkL2
    0x17,  // SynchExtAbtOnTranslTableWalkL3
    0x1c,  // SynchPtyErrOnTranslTableWalkL0
    0x1d,  // SynchPtyErrOnTranslTableWalkL1
    0x1e,  // SynchPtyErrOnTranslTableWalkL2
    0x1f,  // SynchPtyErrOnTranslTableWalkL3
    0x04,  // TranslationL0
    0x05,  // TranslationL1
    0x06,  // TranslationL2
    0x07,  // TranslationL3
    0x08,  // AccessFlagL0
    0x09,  // AccessFlagL1
    0x0a,  // AccessFlagL2
    0x0b,  // AccessFlagL3
    // @todo: Section & Page Domain Fault in AArch64?
    0xff,  // DomainL0 (INVALID)
    0xff,  // DomainL1 (INVALID)
    0xff,  // DomainL2 (INVALID)
    0xff,  // DomainL3 (INVALID)
    0x0c,  // PermissionL0
    0x0d,  // PermissionL1
    0x0e,  // PermissionL2
    0x0f,  // PermissionL3
    0xff,  // DebugEvent (INVALID)
    0x10,  // SynchronousExternalAbort
    0x30,  // TLBConflictAbort
    0x18,  // SynchPtyErrOnMemoryAccess
    0xff,  // AsynchronousExternalAbort (INVALID)
    0xff,  // AsynchPtyErrOnMemoryAccess (INVALID)
    0x00,  // AddressSizeL0
    0x01,  // AddressSizeL1
    0x02,  // AddressSizeL2
    0x03,  // AddressSizeL3
    0x40,  // PrefetchTLBMiss
    0x80   // PrefetchUncacheable
};

static_assert(sizeof(ArmFault::aarch64FaultSources) ==
              ArmFault::NumFaultSources,
              "Invalid size of ArmFault::aarch64FaultSources[]");

// Fields: name, offset, cur{ELT,ELH}Offset, lowerEL{64,32}Offset, next mode,
//         {ARM, Thumb, ARM_ELR, Thumb_ELR} PC offset, hyp trap,
//         {A, F} disable, class, stat
template<> ArmFault::FaultVals ArmFaultVals<Reset>::vals = {
    // Some dummy values (the reset vector has an IMPLEMENTATION DEFINED
    // location in AArch64)
    "Reset",                 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC,
    0, 0, 0, 0, false, true,  true,  EC_UNKNOWN, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<UndefinedInstruction>::vals = {
    "Undefined Instruction", 0x004, 0x000, 0x200, 0x400, 0x600, MODE_UNDEFINED,
    4, 2, 0, 0, true,  false, false, EC_UNKNOWN, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<SupervisorCall>::vals = {
    "Supervisor Call",       0x008, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
    4, 2, 4, 2, true,  false, false, EC_SVC_TO_HYP, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<SecureMonitorCall>::vals = {
    "Secure Monitor Call",   0x008, 0x000, 0x200, 0x400, 0x600, MODE_MON,
    4, 4, 4, 4, false, true,  true,  EC_SMC_TO_HYP, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<HypervisorCall>::vals = {
    "Hypervisor Call",       0x008, 0x000, 0x200, 0x400, 0x600, MODE_HYP,
    4, 4, 4, 4, true,  false, false, EC_HVC, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<PrefetchAbort>::vals = {
    "Prefetch Abort",        0x00C, 0x000, 0x200, 0x400, 0x600, MODE_ABORT,
    4, 4, 0, 0, true,  true,  false, EC_PREFETCH_ABORT_TO_HYP, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<DataAbort>::vals = {
    "Data Abort",            0x010, 0x000, 0x200, 0x400, 0x600, MODE_ABORT,
    8, 8, 0, 0, true,  true,  false, EC_DATA_ABORT_TO_HYP, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<VirtualDataAbort>::vals = {
    "Virtual Data Abort",    0x010, 0x000, 0x200, 0x400, 0x600, MODE_ABORT,
    8, 8, 0, 0, true,  true,  false, EC_INVALID, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<HypervisorTrap>::vals = {
    // @todo: double check these values
    "Hypervisor Trap",       0x014, 0x000, 0x200, 0x400, 0x600, MODE_HYP,
    0, 0, 0, 0, false, false, false, EC_UNKNOWN, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<Interrupt>::vals = {
    "IRQ",                   0x018, 0x080, 0x280, 0x480, 0x680, MODE_IRQ,
    4, 4, 0, 0, false, true,  false, EC_UNKNOWN, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<VirtualInterrupt>::vals = {
    "Virtual IRQ",           0x018, 0x080, 0x280, 0x480, 0x680, MODE_IRQ,
    4, 4, 0, 0, false, true,  false, EC_INVALID, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<FastInterrupt>::vals = {
    "FIQ",                   0x01C, 0x100, 0x300, 0x500, 0x700, MODE_FIQ,
    4, 4, 0, 0, false, true,  true,  EC_UNKNOWN, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<VirtualFastInterrupt>::vals = {
    "Virtual FIQ",           0x01C, 0x100, 0x300, 0x500, 0x700, MODE_FIQ,
    4, 4, 0, 0, false, true,  true,  EC_INVALID, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<SupervisorTrap>::vals = {
    // Some dummy values (SupervisorTrap is AArch64-only)
    "Supervisor Trap",   0x014, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
    0, 0, 0, 0, false, false, false, EC_UNKNOWN, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<SecureMonitorTrap>::vals = {
    // Some dummy values (SecureMonitorTrap is AArch64-only)
    "Secure Monitor Trap",   0x014, 0x000, 0x200, 0x400, 0x600, MODE_MON,
    0, 0, 0, 0, false, false, false, EC_UNKNOWN, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<PCAlignmentFault>::vals = {
    // Some dummy values (PCAlignmentFault is AArch64-only)
    "PC Alignment Fault",   0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
    0, 0, 0, 0, true, false, false, EC_PC_ALIGNMENT, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<SPAlignmentFault>::vals = {
    // Some dummy values (SPAlignmentFault is AArch64-only)
    "SP Alignment Fault",   0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
    0, 0, 0, 0, true, false, false, EC_STACK_PTR_ALIGNMENT, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<SystemError>::vals = {
    // Some dummy values (SError is AArch64-only)
    "SError",                0x000, 0x180, 0x380, 0x580, 0x780, MODE_SVC,
    0, 0, 0, 0, false, true,  true,  EC_SERROR, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<SoftwareBreakpoint>::vals = {
    // Some dummy values (SoftwareBreakpoint is AArch64-only)
    "Software Breakpoint",   0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
    0, 0, 0, 0, true, false, false,  EC_SOFTWARE_BREAKPOINT, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals = {
    // Some dummy values
    "ArmSev Flush",          0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC,
    0, 0, 0, 0, false, true,  true,  EC_UNKNOWN, FaultStat()
};
template<> ArmFault::FaultVals ArmFaultVals<IllegalInstSetStateFault>::vals = {
    // Some dummy values (SPAlignmentFault is AArch64-only)
    "Illegal Inst Set State Fault",   0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
    0, 0, 0, 0, true, false, false, EC_ILLEGAL_INST, FaultStat()
};

Addr
ArmFault::getVector(ThreadContext *tc)
{
    Addr base;

    // ARM ARM issue C B1.8.1
    bool haveSecurity = ArmSystem::haveSecurity(tc);

    // panic if SCTLR.VE because I have no idea what to do with vectored
    // interrupts
    SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
    assert(!sctlr.ve);
    // Check for invalid modes
    CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);
    assert(haveSecurity                      || cpsr.mode != MODE_MON);
    assert(ArmSystem::haveVirtualization(tc) || cpsr.mode != MODE_HYP);

    switch (cpsr.mode)
    {
      case MODE_MON:
        base = tc->readMiscReg(MISCREG_MVBAR);
        break;
      case MODE_HYP:
        base = tc->readMiscReg(MISCREG_HVBAR);
        break;
      default:
        if (sctlr.v) {
            base = HighVecs;
        } else {
            base = haveSecurity ? tc->readMiscReg(MISCREG_VBAR) : 0;
        }
        break;
    }
    return base + offset(tc);
}

Addr
ArmFault::getVector64(ThreadContext *tc)
{
    Addr vbar;
    switch (toEL) {
      case EL3:
        assert(ArmSystem::haveSecurity(tc));
        vbar = tc->readMiscReg(MISCREG_VBAR_EL3);
        break;
      case EL2:
        assert(ArmSystem::haveVirtualization(tc));
        vbar = tc->readMiscReg(MISCREG_VBAR_EL2);
        break;
      case EL1:
        vbar = tc->readMiscReg(MISCREG_VBAR_EL1);
        break;
      default:
        panic("Invalid target exception level");
        break;
    }
    return vbar + offset64();
}

MiscRegIndex
ArmFault::getSyndromeReg64() const
{
    switch (toEL) {
      case EL1:
        return MISCREG_ESR_EL1;
      case EL2:
        return MISCREG_ESR_EL2;
      case EL3:
        return MISCREG_ESR_EL3;
      default:
        panic("Invalid exception level");
        break;
    }
}

MiscRegIndex
ArmFault::getFaultAddrReg64() const
{
    switch (toEL) {
      case EL1:
        return MISCREG_FAR_EL1;
      case EL2:
        return MISCREG_FAR_EL2;
      case EL3:
        return MISCREG_FAR_EL3;
      default:
        panic("Invalid exception level");
        break;
    }
}

void
ArmFault::setSyndrome(ThreadContext *tc, MiscRegIndex syndrome_reg)
{
    uint32_t value;
    uint32_t exc_class = (uint32_t) ec(tc);
    uint32_t issVal = iss();
    assert(!from64 || ArmSystem::highestELIs64(tc));

    value = exc_class << 26;

    // HSR.IL not valid for Prefetch Aborts (0x20, 0x21) and Data Aborts (0x24,
    // 0x25) for which the ISS information is not valid (ARMv7).
    // @todo: ARMv8 revises AArch32 functionality: when HSR.IL is not
    // valid it is treated as RES1.
    if (to64) {
        value |= 1 << 25;
    } else if ((bits(exc_class, 5, 3) != 4) ||
               (bits(exc_class, 2) && bits(issVal, 24))) {
        if (!machInst.thumb || machInst.bigThumb)
            value |= 1 << 25;
    }
    // Condition code valid for EC[5:4] nonzero
    if (!from64 && ((bits(exc_class, 5, 4) == 0) &&
                    (bits(exc_class, 3, 0) != 0))) {
        if (!machInst.thumb) {
            uint32_t      cond;
            ConditionCode condCode = (ConditionCode) (uint32_t) machInst.condCode;
            // If its on unconditional instruction report with a cond code of
            // 0xE, ie the unconditional code
            cond  = (condCode == COND_UC) ? COND_AL : condCode;
            value |= cond << 20;
            value |= 1    << 24;
        }
        value |= bits(issVal, 19, 0);
    } else {
        value |= issVal;
    }
    tc->setMiscReg(syndrome_reg, value);
}

void
ArmFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);

    if (ArmSystem::highestELIs64(tc)) {  // ARMv8
        // Determine source exception level and mode
        fromMode = (OperatingMode) (uint8_t) cpsr.mode;
        fromEL = opModeToEL(fromMode);
        if (opModeIs64(fromMode))
            from64 = true;

        // Determine target exception level
        if (ArmSystem::haveSecurity(tc) && routeToMonitor(tc))
            toEL = EL3;
        else if (ArmSystem::haveVirtualization(tc) && routeToHyp(tc))
            toEL = EL2;
        else
            toEL = opModeToEL(nextMode());
        if (fromEL > toEL)
            toEL = fromEL;

        if (toEL == ArmSystem::highestEL(tc) || ELIs64(tc, toEL)) {
            // Invoke exception handler in AArch64 state
            to64 = true;
            invoke64(tc, inst);
            return;
        }
    }

    // ARMv7 (ARM ARM issue C B1.9)

    bool have_security       = ArmSystem::haveSecurity(tc);
    bool have_virtualization = ArmSystem::haveVirtualization(tc);

    FaultBase::invoke(tc);
    if (!FullSystem)
        return;
    countStat()++;

    SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
    SCR scr = tc->readMiscReg(MISCREG_SCR);
    CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR);
    saved_cpsr.nz = tc->readCCReg(CCREG_NZ);
    saved_cpsr.c = tc->readCCReg(CCREG_C);
    saved_cpsr.v = tc->readCCReg(CCREG_V);
    saved_cpsr.ge = tc->readCCReg(CCREG_GE);

    Addr curPc M5_VAR_USED = tc->pcState().pc();
    ITSTATE it = tc->pcState().itstate();
    saved_cpsr.it2 = it.top6;
    saved_cpsr.it1 = it.bottom2;

    // if we have a valid instruction then use it to annotate this fault with
    // extra information. This is used to generate the correct fault syndrome
    // information
    if (inst) {
        ArmStaticInst *armInst = reinterpret_cast<ArmStaticInst *>(inst.get());
        armInst->annotateFault(this);
    }

    if (have_security && routeToMonitor(tc))
        cpsr.mode = MODE_MON;
    else if (have_virtualization && routeToHyp(tc))
        cpsr.mode = MODE_HYP;
    else
        cpsr.mode = nextMode();

    // Ensure Secure state if initially in Monitor mode
    if (have_security && saved_cpsr.mode == MODE_MON) {
        SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR);
        if (scr.ns) {
            scr.ns = 0;
            tc->setMiscRegNoEffect(MISCREG_SCR, scr);
        }
    }

    // some bits are set differently if we have been routed to hyp mode
    if (cpsr.mode == MODE_HYP) {
        SCTLR hsctlr = tc->readMiscReg(MISCREG_HSCTLR);
        cpsr.t = hsctlr.te;
        cpsr.e = hsctlr.ee;
        if (!scr.ea)  {cpsr.a = 1;}
        if (!scr.fiq) {cpsr.f = 1;}
        if (!scr.irq) {cpsr.i = 1;}
    } else if (cpsr.mode == MODE_MON) {
        // Special case handling when entering monitor mode
        cpsr.t = sctlr.te;
        cpsr.e = sctlr.ee;
        cpsr.a = 1;
        cpsr.f = 1;
        cpsr.i = 1;
    } else {
        cpsr.t = sctlr.te;
        cpsr.e = sctlr.ee;

        // The *Disable functions are virtual and different per fault
        cpsr.a = cpsr.a | abortDisable(tc);
        cpsr.f = cpsr.f | fiqDisable(tc);
        cpsr.i = 1;
    }
    cpsr.it1 = cpsr.it2 = 0;
    cpsr.j = 0;
    tc->setMiscReg(MISCREG_CPSR, cpsr);

    // Make sure mailbox sets to one always
    tc->setMiscReg(MISCREG_SEV_MAILBOX, 1);

    // Clear the exclusive monitor
    tc->setMiscReg(MISCREG_LOCKFLAG, 0);

    if (cpsr.mode == MODE_HYP) {
        tc->setMiscReg(MISCREG_ELR_HYP, curPc +
                (saved_cpsr.t ? thumbPcOffset(true)  : armPcOffset(true)));
    } else {
        tc->setIntReg(INTREG_LR, curPc +
                (saved_cpsr.t ? thumbPcOffset(false) : armPcOffset(false)));
    }

    switch (cpsr.mode) {
      case MODE_FIQ:
        tc->setMiscReg(MISCREG_SPSR_FIQ, saved_cpsr);
        break;
      case MODE_IRQ:
        tc->setMiscReg(MISCREG_SPSR_IRQ, saved_cpsr);
        break;
      case MODE_SVC:
        tc->setMiscReg(MISCREG_SPSR_SVC, saved_cpsr);
        break;
      case MODE_MON:
        assert(have_security);
        tc->setMiscReg(MISCREG_SPSR_MON, saved_cpsr);
        break;
      case MODE_ABORT:
        tc->setMiscReg(MISCREG_SPSR_ABT, saved_cpsr);
        break;
      case MODE_UNDEFINED:
        tc->setMiscReg(MISCREG_SPSR_UND, saved_cpsr);
        if (ec(tc) != EC_UNKNOWN)
            setSyndrome(tc, MISCREG_HSR);
        break;
      case MODE_HYP:
        assert(have_virtualization);
        tc->setMiscReg(MISCREG_SPSR_HYP, saved_cpsr);
        setSyndrome(tc, MISCREG_HSR);
        break;
      default:
        panic("unknown Mode\n");
    }

    Addr newPc = getVector(tc);
    DPRINTF(Faults, "Invoking Fault:%s cpsr:%#x PC:%#x lr:%#x newVec: %#x\n",
            name(), cpsr, curPc, tc->readIntReg(INTREG_LR), newPc);
    PCState pc(newPc);
    pc.thumb(cpsr.t);
    pc.nextThumb(pc.thumb());
    pc.jazelle(cpsr.j);
    pc.nextJazelle(pc.jazelle());
    pc.aarch64(!cpsr.width);
    pc.nextAArch64(!cpsr.width);
    tc->pcState(pc);
}

void
ArmFault::invoke64(ThreadContext *tc, const StaticInstPtr &inst)
{
    // Determine actual misc. register indices for ELR_ELx and SPSR_ELx
    MiscRegIndex elr_idx, spsr_idx;
    switch (toEL) {
      case EL1:
        elr_idx = MISCREG_ELR_EL1;
        spsr_idx = MISCREG_SPSR_EL1;
        break;
      case EL2:
        assert(ArmSystem::haveVirtualization(tc));
        elr_idx = MISCREG_ELR_EL2;
        spsr_idx = MISCREG_SPSR_EL2;
        break;
      case EL3:
        assert(ArmSystem::haveSecurity(tc));
        elr_idx = MISCREG_ELR_EL3;
        spsr_idx = MISCREG_SPSR_EL3;
        break;
      default:
        panic("Invalid target exception level");
        break;
    }

    // Save process state into SPSR_ELx
    CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
    CPSR spsr = cpsr;
    spsr.nz = tc->readCCReg(CCREG_NZ);
    spsr.c = tc->readCCReg(CCREG_C);
    spsr.v = tc->readCCReg(CCREG_V);
    if (from64) {
        // Force some bitfields to 0
        spsr.q = 0;
        spsr.it1 = 0;
        spsr.j = 0;
        spsr.res0_23_22 = 0;
        spsr.ge = 0;
        spsr.it2 = 0;
        spsr.t = 0;
    } else {
        spsr.ge = tc->readCCReg(CCREG_GE);
        ITSTATE it = tc->pcState().itstate();
        spsr.it2 = it.top6;
        spsr.it1 = it.bottom2;
        // Force some bitfields to 0
        spsr.res0_23_22 = 0;
        spsr.ss = 0;
    }
    tc->setMiscReg(spsr_idx, spsr);

    // Save preferred return address into ELR_ELx
    Addr curr_pc = tc->pcState().pc();
    Addr ret_addr = curr_pc;
    if (from64)
        ret_addr += armPcElrOffset();
    else
        ret_addr += spsr.t ? thumbPcElrOffset() : armPcElrOffset();
    tc->setMiscReg(elr_idx, ret_addr);

    // Update process state
    OperatingMode64 mode = 0;
    mode.spX = 1;
    mode.el = toEL;
    mode.width = 0;
    cpsr.mode = mode;
    cpsr.daif = 0xf;
    cpsr.il = 0;
    cpsr.ss = 0;
    tc->setMiscReg(MISCREG_CPSR, cpsr);

    // Set PC to start of exception handler
    Addr new_pc = purifyTaggedAddr(getVector64(tc), tc, toEL);
    DPRINTF(Faults, "Invoking Fault (AArch64 target EL):%s cpsr:%#x PC:%#x "
            "elr:%#x newVec: %#x\n", name(), cpsr, curr_pc, ret_addr, new_pc);
    PCState pc(new_pc);
    pc.aarch64(!cpsr.width);
    pc.nextAArch64(!cpsr.width);
    tc->pcState(pc);

    // If we have a valid instruction then use it to annotate this fault with
    // extra information. This is used to generate the correct fault syndrome
    // information
    if (inst)
        reinterpret_cast<ArmStaticInst *>(inst.get())->annotateFault(this);
    // Save exception syndrome
    if ((nextMode() != MODE_IRQ) && (nextMode() != MODE_FIQ))
        setSyndrome(tc, getSyndromeReg64());
}

void
Reset::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    if (FullSystem) {
        tc->getCpuPtr()->clearInterrupts(tc->threadId());
        tc->clearArchRegs();
    }
    if (!ArmSystem::highestELIs64(tc)) {
        ArmFault::invoke(tc, inst);
        tc->setMiscReg(MISCREG_VMPIDR,
                       getMPIDR(dynamic_cast<ArmSystem*>(tc->getSystemPtr()), tc));

        // Unless we have SMC code to get us there, boot in HYP!
        if (ArmSystem::haveVirtualization(tc) &&
            !ArmSystem::haveSecurity(tc)) {
            CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
            cpsr.mode = MODE_HYP;
            tc->setMiscReg(MISCREG_CPSR, cpsr);
        }
    } else {
        // Advance the PC to the IMPLEMENTATION DEFINED reset value
        PCState pc = ArmSystem::resetAddr64(tc);
        pc.aarch64(true);
        pc.nextAArch64(true);
        tc->pcState(pc);
    }
}

void
UndefinedInstruction::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    if (FullSystem) {
        ArmFault::invoke(tc, inst);
        return;
    }

    // If the mnemonic isn't defined this has to be an unknown instruction.
    assert(unknown || mnemonic != NULL);
    if (disabled) {
        panic("Attempted to execute disabled instruction "
                "'%s' (inst 0x%08x)", mnemonic, machInst);
    } else if (unknown) {
        panic("Attempted to execute unknown instruction (inst 0x%08x)",
              machInst);
    } else {
        panic("Attempted to execute unimplemented instruction "
                "'%s' (inst 0x%08x)", mnemonic, machInst);
    }
}

bool
UndefinedInstruction::routeToHyp(ThreadContext *tc) const
{
    bool toHyp;

    SCR  scr  = tc->readMiscRegNoEffect(MISCREG_SCR);
    HCR  hcr  = tc->readMiscRegNoEffect(MISCREG_HCR);
    CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);

    // if in Hyp mode then stay in Hyp mode
    toHyp  = scr.ns && (cpsr.mode == MODE_HYP);
    // if HCR.TGE is set to 1, take to Hyp mode through Hyp Trap vector
    toHyp |= !inSecureState(scr, cpsr) && hcr.tge && (cpsr.mode == MODE_USER);
    return toHyp;
}

uint32_t
UndefinedInstruction::iss() const
{
    if (overrideEc == EC_INVALID)
        return issRaw;

    uint32_t new_iss = 0;
    uint32_t op0, op1, op2, CRn, CRm, Rt, dir;

    dir = bits(machInst, 21, 21);
    op0 = bits(machInst, 20, 19);
    op1 = bits(machInst, 18, 16);
    CRn = bits(machInst, 15, 12);
    CRm = bits(machInst, 11, 8);
    op2 = bits(machInst, 7, 5);
    Rt = bits(machInst, 4, 0);

    new_iss = op0 << 20 | op2 << 17 | op1 << 14 | CRn << 10 |
            Rt << 5 | CRm << 1 | dir;

    return new_iss;
}

void
SupervisorCall::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    if (FullSystem) {
        ArmFault::invoke(tc, inst);
        return;
    }

    // As of now, there isn't a 32 bit thumb version of this instruction.
    assert(!machInst.bigThumb);
    uint32_t callNum;
    CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
    OperatingMode mode = (OperatingMode)(uint8_t)cpsr.mode;
    if (opModeIs64(mode))
        callNum = tc->readIntReg(INTREG_X8);
    else
        callNum = tc->readIntReg(INTREG_R7);
    Fault fault;
    tc->syscall(callNum, &fault);

    // Advance the PC since that won't happen automatically.
    PCState pc = tc->pcState();
    assert(inst);
    inst->advancePC(pc);
    tc->pcState(pc);
}

bool
SupervisorCall::routeToHyp(ThreadContext *tc) const
{
    bool toHyp;

    SCR  scr  = tc->readMiscRegNoEffect(MISCREG_SCR);
    HCR  hcr  = tc->readMiscRegNoEffect(MISCREG_HCR);
    CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);

    // if in Hyp mode then stay in Hyp mode
    toHyp  = scr.ns && (cpsr.mode == MODE_HYP);
    // if HCR.TGE is set to 1, take to Hyp mode through Hyp Trap vector
    toHyp |= !inSecureState(scr, cpsr) && hcr.tge && (cpsr.mode == MODE_USER);
    return toHyp;
}

ExceptionClass
SupervisorCall::ec(ThreadContext *tc) const
{
    return (overrideEc != EC_INVALID) ? overrideEc :
        (from64 ? EC_SVC_64 : vals.ec);
}

uint32_t
SupervisorCall::iss() const
{
    // Even if we have a 24 bit imm from an arm32 instruction then we only use
    // the bottom 16 bits for the ISS value (it doesn't hurt for AArch64 SVC).
    return issRaw & 0xFFFF;
}

uint32_t
SecureMonitorCall::iss() const
{
    if (from64)
        return bits(machInst, 20, 5);
    return 0;
}

ExceptionClass
UndefinedInstruction::ec(ThreadContext *tc) const
{
    return (overrideEc != EC_INVALID) ? overrideEc : vals.ec;
}


HypervisorCall::HypervisorCall(ExtMachInst _machInst, uint32_t _imm) :
        ArmFaultVals<HypervisorCall>(_machInst, _imm)
{}

ExceptionClass
HypervisorCall::ec(ThreadContext *tc) const
{
    return from64 ? EC_HVC_64 : vals.ec;
}

ExceptionClass
HypervisorTrap::ec(ThreadContext *tc) const
{
    return (overrideEc != EC_INVALID) ? overrideEc : vals.ec;
}

template<class T>
FaultOffset
ArmFaultVals<T>::offset(ThreadContext *tc)
{
    bool isHypTrap = false;

    // Normally we just use the exception vector from the table at the top if
    // this file, however if this exception has caused a transition to hype
    // mode, and its an exception type that would only do this if it has been
    // trapped then we use the hyp trap vector instead of the normal vector
    if (vals.hypTrappable) {
        CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
        if (cpsr.mode == MODE_HYP) {
            CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP);
            isHypTrap = spsr.mode != MODE_HYP;
        }
    }
    return isHypTrap ? 0x14 : vals.offset;
}

// void
// SupervisorCall::setSyndrome64(ThreadContext *tc, MiscRegIndex esr_idx)
// {
//     ESR esr = 0;
//     esr.ec = machInst.aarch64 ? SvcAArch64 : SvcAArch32;
//     esr.il = !machInst.thumb;
//     if (machInst.aarch64)
//         esr.imm16 = bits(machInst.instBits, 20, 5);
//     else if (machInst.thumb)
//         esr.imm16 = bits(machInst.instBits, 7, 0);
//     else
//         esr.imm16 = bits(machInst.instBits, 15, 0);
//     tc->setMiscReg(esr_idx, esr);
// }

void
SecureMonitorCall::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    if (FullSystem) {
        ArmFault::invoke(tc, inst);
        return;
    }
}

ExceptionClass
SecureMonitorCall::ec(ThreadContext *tc) const
{
    return (from64 ? EC_SMC_64 : vals.ec);
}

ExceptionClass
SupervisorTrap::ec(ThreadContext *tc) const
{
    return (overrideEc != EC_INVALID) ? overrideEc : vals.ec;
}

ExceptionClass
SecureMonitorTrap::ec(ThreadContext *tc) const
{
    return (overrideEc != EC_INVALID) ? overrideEc :
        (from64 ? EC_SMC_64 : vals.ec);
}

template<class T>
void
AbortFault<T>::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    if (tranMethod == ArmFault::UnknownTran) {
        tranMethod = longDescFormatInUse(tc) ? ArmFault::LpaeTran
                                             : ArmFault::VmsaTran;

        if ((tranMethod == ArmFault::VmsaTran) && this->routeToMonitor(tc)) {
            // See ARM ARM B3-1416
            bool override_LPAE = false;
            TTBCR ttbcr_s = tc->readMiscReg(MISCREG_TTBCR_S);
            TTBCR M5_VAR_USED ttbcr_ns = tc->readMiscReg(MISCREG_TTBCR_NS);
            if (ttbcr_s.eae) {
                override_LPAE = true;
            } else {
                // Unimplemented code option, not seen in testing.  May need
                // extension according to the manual exceprt above.
                DPRINTF(Faults, "Warning: Incomplete translation method "
                        "override detected.\n");
            }
            if (override_LPAE)
                tranMethod = ArmFault::LpaeTran;
        }
    }

    if (source == ArmFault::AsynchronousExternalAbort) {
        tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0);
    }
    // Get effective fault source encoding
    CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
    FSR  fsr  = getFsr(tc);

    // source must be determined BEFORE invoking generic routines which will
    // try to set hsr etc. and are based upon source!
    ArmFaultVals<T>::invoke(tc, inst);

    if (!this->to64) {  // AArch32
        if (cpsr.mode == MODE_HYP) {
            tc->setMiscReg(T::HFarIndex, faultAddr);
        } else if (stage2) {
            tc->setMiscReg(MISCREG_HPFAR, (faultAddr >> 8) & ~0xf);
            tc->setMiscReg(T::HFarIndex,  OVAddr);
        } else {
            tc->setMiscReg(T::FsrIndex, fsr);
            tc->setMiscReg(T::FarIndex, faultAddr);
        }
        DPRINTF(Faults, "Abort Fault source=%#x fsr=%#x faultAddr=%#x "\
                "tranMethod=%#x\n", source, fsr, faultAddr, tranMethod);
    } else {  // AArch64
        // Set the FAR register.  Nothing else to do if we are in AArch64 state
        // because the syndrome register has already been set inside invoke64()
        if (stage2) {
            // stage 2 fault, set HPFAR_EL2 to the faulting IPA
            // and FAR_EL2 to the Original VA
            tc->setMiscReg(AbortFault<T>::getFaultAddrReg64(), OVAddr);
            tc->setMiscReg(MISCREG_HPFAR_EL2, bits(faultAddr, 47, 12) << 4);

            DPRINTF(Faults, "Abort Fault (Stage 2) VA: 0x%x IPA: 0x%x\n",
                    OVAddr, faultAddr);
        } else {
            tc->setMiscReg(AbortFault<T>::getFaultAddrReg64(), faultAddr);
        }
    }
}

template<class T>
FSR
AbortFault<T>::getFsr(ThreadContext *tc)
{
    FSR fsr = 0;

    if (((CPSR) tc->readMiscRegNoEffect(MISCREG_CPSR)).width) {
        // AArch32
        assert(tranMethod != ArmFault::UnknownTran);
        if (tranMethod == ArmFault::LpaeTran) {
            srcEncoded = ArmFault::longDescFaultSources[source];
            fsr.status = srcEncoded;
            fsr.lpae   = 1;
        } else {
            srcEncoded = ArmFault::shortDescFaultSources[source];
            fsr.fsLow  = bits(srcEncoded, 3, 0);
            fsr.fsHigh = bits(srcEncoded, 4);
            fsr.domain = static_cast<uint8_t>(domain);
        }
        fsr.wnr = (write ? 1 : 0);
        fsr.ext = 0;
    } else {
        // AArch64
        srcEncoded = ArmFault::aarch64FaultSources[source];
    }
    if (srcEncoded == ArmFault::FaultSourceInvalid) {
        panic("Invalid fault source\n");
    }
    return fsr;
}

template<class T>
bool
AbortFault<T>::abortDisable(ThreadContext *tc)
{
    if (ArmSystem::haveSecurity(tc)) {
        SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR);
        return (!scr.ns || scr.aw);
    }
    return true;
}

template<class T>
void
AbortFault<T>::annotate(ArmFault::AnnotationIDs id, uint64_t val)
{
    switch (id)
    {
      case ArmFault::S1PTW:
        s1ptw = val;
        break;
      case ArmFault::OVA:
        OVAddr = val;
        break;

      // Just ignore unknown ID's
      default:
        break;
    }
}

template<class T>
uint32_t
AbortFault<T>::iss() const
{
    uint32_t val;

    val  = srcEncoded & 0x3F;
    val |= write << 6;
    val |= s1ptw << 7;
    return (val);
}

template<class T>
bool
AbortFault<T>::isMMUFault() const
{
    // NOTE: Not relying on LL information being aligned to lowest bits here
    return
         (source == ArmFault::AlignmentFault)     ||
        ((source >= ArmFault::TranslationLL) &&
         (source <  ArmFault::TranslationLL + 4)) ||
        ((source >= ArmFault::AccessFlagLL) &&
         (source <  ArmFault::AccessFlagLL + 4))  ||
        ((source >= ArmFault::DomainLL) &&
         (source <  ArmFault::DomainLL + 4))      ||
        ((source >= ArmFault::PermissionLL) &&
         (source <  ArmFault::PermissionLL + 4));
}

ExceptionClass
PrefetchAbort::ec(ThreadContext *tc) const
{
    if (to64) {
        // AArch64
        if (toEL == fromEL)
            return EC_PREFETCH_ABORT_CURR_EL;
        else
            return EC_PREFETCH_ABORT_LOWER_EL;
    } else {
        // AArch32
        // Abort faults have different EC codes depending on whether
        // the fault originated within HYP mode, or not. So override
        // the method and add the extra adjustment of the EC value.

        ExceptionClass ec = ArmFaultVals<PrefetchAbort>::vals.ec;

        CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP);
        if (spsr.mode == MODE_HYP) {
            ec = ((ExceptionClass) (((uint32_t) ec) + 1));
        }
        return ec;
    }
}

bool
PrefetchAbort::routeToMonitor(ThreadContext *tc) const
{
    SCR scr = 0;
    if (from64)
        scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
    else
        scr = tc->readMiscRegNoEffect(MISCREG_SCR);

    return scr.ea && !isMMUFault();
}

bool
PrefetchAbort::routeToHyp(ThreadContext *tc) const
{
    bool toHyp;

    SCR  scr  = tc->readMiscRegNoEffect(MISCREG_SCR);
    HCR  hcr  = tc->readMiscRegNoEffect(MISCREG_HCR);
    CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);
    HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR);

    // if in Hyp mode then stay in Hyp mode
    toHyp  = scr.ns && (cpsr.mode == MODE_HYP);
    // otherwise, check whether to take to Hyp mode through Hyp Trap vector
    toHyp |= (stage2 ||
                ( (source ==               DebugEvent) && hdcr.tde && (cpsr.mode !=  MODE_HYP)) ||
                ( (source == SynchronousExternalAbort) && hcr.tge  && (cpsr.mode == MODE_USER))
             ) && !inSecureState(tc);
    return toHyp;
}

ExceptionClass
DataAbort::ec(ThreadContext *tc) const
{
    if (to64) {
        // AArch64
        if (source == ArmFault::AsynchronousExternalAbort) {
            panic("Asynchronous External Abort should be handled with "
                    "SystemErrors (SErrors)!");
        }
        if (toEL == fromEL)
            return EC_DATA_ABORT_CURR_EL;
        else
            return EC_DATA_ABORT_LOWER_EL;
    } else {
        // AArch32
        // Abort faults have different EC codes depending on whether
        // the fault originated within HYP mode, or not. So override
        // the method and add the extra adjustment of the EC value.

        ExceptionClass ec = ArmFaultVals<DataAbort>::vals.ec;

        CPSR spsr = tc->readMiscReg(MISCREG_SPSR_HYP);
        if (spsr.mode == MODE_HYP) {
            ec = ((ExceptionClass) (((uint32_t) ec) + 1));
        }
        return ec;
    }
}

bool
DataAbort::routeToMonitor(ThreadContext *tc) const
{
    SCR scr = 0;
    if (from64)
        scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
    else
        scr = tc->readMiscRegNoEffect(MISCREG_SCR);

    return scr.ea && !isMMUFault();
}

bool
DataAbort::routeToHyp(ThreadContext *tc) const
{
    bool toHyp;

    SCR  scr  = tc->readMiscRegNoEffect(MISCREG_SCR);
    HCR  hcr  = tc->readMiscRegNoEffect(MISCREG_HCR);
    CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);
    HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR);

    // if in Hyp mode then stay in Hyp mode
    toHyp  = scr.ns && (cpsr.mode == MODE_HYP);
    // otherwise, check whether to take to Hyp mode through Hyp Trap vector
    toHyp |= (stage2 ||
                ( (cpsr.mode != MODE_HYP) && ( ((source == AsynchronousExternalAbort) && hcr.amo) ||
                                               ((source == DebugEvent) && hdcr.tde) )
                ) ||
                ( (cpsr.mode == MODE_USER) && hcr.tge &&
                  ((source == AlignmentFault)            ||
                   (source == SynchronousExternalAbort))
                )
             ) && !inSecureState(tc);
    return toHyp;
}

uint32_t
DataAbort::iss() const
{
    uint32_t val;

    // Add on the data abort specific fields to the generic abort ISS value
    val  = AbortFault<DataAbort>::iss();
    // ISS is valid if not caused by a stage 1 page table walk, and when taken
    // to AArch64 only when directed to EL2
    if (!s1ptw && (!to64 || toEL == EL2)) {
        val |= isv << 24;
        if (isv) {
            val |= sas << 22;
            val |= sse << 21;
            val |= srt << 16;
            // AArch64 only. These assignments are safe on AArch32 as well
            // because these vars are initialized to false
            val |= sf << 15;
            val |= ar << 14;
        }
    }
    return (val);
}

void
DataAbort::annotate(AnnotationIDs id, uint64_t val)
{
    AbortFault<DataAbort>::annotate(id, val);
    switch (id)
    {
      case SAS:
        isv = true;
        sas = val;
        break;
      case SSE:
        isv = true;
        sse = val;
        break;
      case SRT:
        isv = true;
        srt = val;
        break;
      case SF:
        isv = true;
        sf  = val;
        break;
      case AR:
        isv = true;
        ar  = val;
        break;
      // Just ignore unknown ID's
      default:
        break;
    }
}

void
VirtualDataAbort::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    AbortFault<VirtualDataAbort>::invoke(tc, inst);
    HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR);
    hcr.va = 0;
    tc->setMiscRegNoEffect(MISCREG_HCR, hcr);
}

bool
Interrupt::routeToMonitor(ThreadContext *tc) const
{
    assert(ArmSystem::haveSecurity(tc));
    SCR scr = 0;
    if (from64)
        scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
    else
        scr = tc->readMiscRegNoEffect(MISCREG_SCR);
    return scr.irq;
}

bool
Interrupt::routeToHyp(ThreadContext *tc) const
{
    bool toHyp;

    SCR  scr  = tc->readMiscRegNoEffect(MISCREG_SCR);
    HCR  hcr  = tc->readMiscRegNoEffect(MISCREG_HCR);
    CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);
    // Determine whether IRQs are routed to Hyp mode.
    toHyp = (!scr.irq && hcr.imo && !inSecureState(tc)) ||
            (cpsr.mode == MODE_HYP);
    return toHyp;
}

bool
Interrupt::abortDisable(ThreadContext *tc)
{
    if (ArmSystem::haveSecurity(tc)) {
        SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR);
        return (!scr.ns || scr.aw);
    }
    return true;
}

VirtualInterrupt::VirtualInterrupt()
{}

bool
FastInterrupt::routeToMonitor(ThreadContext *tc) const
{
    assert(ArmSystem::haveSecurity(tc));
    SCR scr = 0;
    if (from64)
        scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
    else
        scr = tc->readMiscRegNoEffect(MISCREG_SCR);
    return scr.fiq;
}

bool
FastInterrupt::routeToHyp(ThreadContext *tc) const
{
    bool toHyp;

    SCR  scr  = tc->readMiscRegNoEffect(MISCREG_SCR);
    HCR  hcr  = tc->readMiscRegNoEffect(MISCREG_HCR);
    CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);
    // Determine whether IRQs are routed to Hyp mode.
    toHyp = (!scr.fiq && hcr.fmo && !inSecureState(tc)) ||
            (cpsr.mode == MODE_HYP);
    return toHyp;
}

bool
FastInterrupt::abortDisable(ThreadContext *tc)
{
    if (ArmSystem::haveSecurity(tc)) {
        SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR);
        return (!scr.ns || scr.aw);
    }
    return true;
}

bool
FastInterrupt::fiqDisable(ThreadContext *tc)
{
    if (ArmSystem::haveVirtualization(tc)) {
        return true;
    } else if (ArmSystem::haveSecurity(tc)) {
        SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR);
        return (!scr.ns || scr.fw);
    }
    return true;
}

VirtualFastInterrupt::VirtualFastInterrupt()
{}

void
PCAlignmentFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    ArmFaultVals<PCAlignmentFault>::invoke(tc, inst);
    assert(from64);
    // Set the FAR
    tc->setMiscReg(getFaultAddrReg64(), faultPC);
}

SPAlignmentFault::SPAlignmentFault()
{}

SystemError::SystemError()
{}

void
SystemError::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_ABT, 0);
    ArmFault::invoke(tc, inst);
}

bool
SystemError::routeToMonitor(ThreadContext *tc) const
{
    assert(ArmSystem::haveSecurity(tc));
    assert(from64);
    SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
    return scr.ea;
}

bool
SystemError::routeToHyp(ThreadContext *tc) const
{
    bool toHyp;
    assert(from64);

    SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
    HCR hcr  = tc->readMiscRegNoEffect(MISCREG_HCR);

    toHyp = (!scr.ea && hcr.amo && !inSecureState(tc)) ||
            (!scr.ea && !scr.rw && !hcr.amo && !inSecureState(tc));
    return toHyp;
}


SoftwareBreakpoint::SoftwareBreakpoint(ExtMachInst _mach_inst, uint32_t _iss)
    : ArmFaultVals<SoftwareBreakpoint>(_mach_inst, _iss)
{}

bool
SoftwareBreakpoint::routeToHyp(ThreadContext *tc) const
{
    assert(from64);

    const bool have_el2 = ArmSystem::haveVirtualization(tc);

    const HCR hcr  = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
    const HDCR mdcr  = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);

    return have_el2 && !inSecureState(tc) && fromEL <= EL1 &&
        (hcr.tge || mdcr.tde);
}

void
ArmSev::invoke(ThreadContext *tc, const StaticInstPtr &inst) {
    DPRINTF(Faults, "Invoking ArmSev Fault\n");
    if (!FullSystem)
        return;

    // Set sev_mailbox to 1, clear the pending interrupt from remote
    // SEV execution and let pipeline continue as pcState is still
    // valid.
    tc->setMiscReg(MISCREG_SEV_MAILBOX, 1);
    tc->getCpuPtr()->clearInterrupt(tc->threadId(), INT_SEV, 0);
}

// Instantiate all the templates to make the linker happy
template class ArmFaultVals<Reset>;
template class ArmFaultVals<UndefinedInstruction>;
template class ArmFaultVals<SupervisorCall>;
template class ArmFaultVals<SecureMonitorCall>;
template class ArmFaultVals<HypervisorCall>;
template class ArmFaultVals<PrefetchAbort>;
template class ArmFaultVals<DataAbort>;
template class ArmFaultVals<VirtualDataAbort>;
template class ArmFaultVals<HypervisorTrap>;
template class ArmFaultVals<Interrupt>;
template class ArmFaultVals<VirtualInterrupt>;
template class ArmFaultVals<FastInterrupt>;
template class ArmFaultVals<VirtualFastInterrupt>;
template class ArmFaultVals<SupervisorTrap>;
template class ArmFaultVals<SecureMonitorTrap>;
template class ArmFaultVals<PCAlignmentFault>;
template class ArmFaultVals<SPAlignmentFault>;
template class ArmFaultVals<SystemError>;
template class ArmFaultVals<SoftwareBreakpoint>;
template class ArmFaultVals<ArmSev>;
template class AbortFault<PrefetchAbort>;
template class AbortFault<DataAbort>;
template class AbortFault<VirtualDataAbort>;


IllegalInstSetStateFault::IllegalInstSetStateFault()
{}


} // namespace ArmISA
