/*
 * Copyright (c) 2010-2023 Arm Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "arch/arm/isa.hh"

#include "arch/arm/decoder.hh"
#include "arch/arm/faults.hh"
#include "arch/arm/htm.hh"
#include "arch/arm/interrupts.hh"
#include "arch/arm/mmu.hh"
#include "arch/arm/pmu.hh"
#include "arch/arm/regs/misc.hh"
#include "arch/arm/self_debug.hh"
#include "arch/arm/system.hh"
#include "arch/arm/utility.hh"
#include "arch/generic/decoder.hh"
#include "base/cprintf.hh"
#include "base/random.hh"
#include "cpu/base.hh"
#include "cpu/checker/cpu.hh"
#include "cpu/reg_class.hh"
#include "debug/Arm.hh"
#include "debug/LLSC.hh"
#include "debug/MatRegs.hh"
#include "debug/VecPredRegs.hh"
#include "debug/VecRegs.hh"
#include "dev/arm/generic_timer.hh"
#include "dev/arm/gic_v3.hh"
#include "dev/arm/gic_v3_cpu_interface.hh"
#include "params/ArmISA.hh"
#include "sim/faults.hh"
#include "sim/stat_control.hh"
#include "sim/system.hh"

namespace gem5
{

namespace ArmISA
{

namespace
{

/* Not applicable to ARM */
RegClass floatRegClass(FloatRegClass, FloatRegClassName, 0, debug::FloatRegs);

} // anonymous namespace

ISA::ISA(const Params &p) : BaseISA(p), system(NULL),
    _decoderFlavor(p.decoderFlavor), pmu(p.pmu), impdefAsNop(p.impdef_nop)
{
    _regClasses.push_back(&flatIntRegClass);
    _regClasses.push_back(&floatRegClass);
    _regClasses.push_back(&vecRegClass);
    _regClasses.push_back(&vecElemClass);
    _regClasses.push_back(&vecPredRegClass);
    _regClasses.push_back(&matRegClass);
    _regClasses.push_back(&ccRegClass);
    _regClasses.push_back(&miscRegClass);

    // Hook up a dummy device if we haven't been configured with a
    // real PMU. By using a dummy device, we don't need to check that
    // the PMU exist every time we try to access a PMU register.
    if (!pmu)
        pmu = &dummyDevice;

    // Give all ISA devices a pointer to this ISA
    pmu->setISA(this);

    system = dynamic_cast<ArmSystem *>(p.system);

    // Cache system-level properties
    if (FullSystem && system) {
        highestELIs64 = system->highestELIs64();
        haveLargeAsid64 = system->haveLargeAsid64();
        physAddrRange = system->physAddrRange();
        sveVL = system->sveVL();
        smeVL = system->smeVL();

        release = system->releaseFS();
    } else {
        highestELIs64 = true; // ArmSystem::highestELIs64 does the same
        haveLargeAsid64 = false;
        physAddrRange = 32;  // dummy value
        sveVL = p.sve_vl_se;
        smeVL = p.sme_vl_se;

        release = p.release_se;
    }

    selfDebug = new SelfDebug();
    initializeMiscRegMetadata();
    preUnflattenMiscReg();

    clear();
}

void
ISA::clear()
{
    // Invalidate cached copies of miscregs in the TLBs
    if (tc) {
        getMMUPtr(tc)->invalidateMiscReg();
    }

    for (auto idx = 0; idx < NUM_MISCREGS; idx++) {
        miscRegs[idx] = lookUpMiscReg[idx].reset();
    }

    updateRegMap(miscRegs[MISCREG_CPSR]);
}

void
ISA::startup()
{
    BaseISA::startup();

    if (tc) {
        setupThreadContext();

        if (release->has(ArmExtension::TME)) {
            std::unique_ptr<BaseHTMCheckpoint> cpt(new HTMCheckpoint());
            tc->setHtmCheckpointPtr(std::move(cpt));
        }
    }
}

void
ISA::setupThreadContext()
{
    pmu->setThreadContext(tc);

    if (!system)
        return;

    selfDebug->init(tc);

    if (auto gicv3_ifc = getGICv3CPUInterface(tc); gicv3_ifc) {
        gicv3_ifc->setISA(this);
        gicv3_ifc->setThreadContext(tc);
    }
}

void
ISA::takeOverFrom(ThreadContext *new_tc, ThreadContext *old_tc)
{
    tc = new_tc;
    setupThreadContext();
}

void
ISA::copyRegsFrom(ThreadContext *src)
{
    for (auto &id: flatIntRegClass)
        tc->setReg(id, src->getReg(id));

    for (auto &id: ccRegClass)
        tc->setReg(id, src->getReg(id));

    for (int i = 0; i < NUM_MISCREGS; i++)
        tc->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));

    ArmISA::VecRegContainer vc;
    for (auto &id: vecRegClass) {
        src->getReg(id, &vc);
        tc->setReg(id, &vc);
    }

    for (auto &id: vecElemClass)
        tc->setReg(id, src->getReg(id));

    ArmISA::MatRegContainer mc;
    for (auto &id: matRegClass) {
        src->getReg(id, &mc);
        tc->setReg(id, &mc);
    }

    // setMiscReg "with effect" will set the misc register mapping correctly.
    // e.g. updateRegMap(val)
    tc->setMiscReg(MISCREG_CPSR, src->readMiscRegNoEffect(MISCREG_CPSR));

    // Copy over the PC State
    tc->pcState(src->pcState());

    // Invalidate the tlb misc register cache
    static_cast<MMU *>(tc->getMMUPtr())->invalidateMiscReg();
}

/**
 * Returns the enconcing equivalent when VHE is implemented and
 * HCR_EL2.E2H is enabled and executing at EL2
 */
int
ISA::redirectRegVHE(int misc_reg)
{
    const HCR hcr = readMiscRegNoEffect(MISCREG_HCR_EL2);
    if (hcr.e2h == 0x0)
        return misc_reg;
    SCR scr = readMiscRegNoEffect(MISCREG_SCR_EL3);
    bool sec_el2 = scr.eel2 && release->has(ArmExtension::FEAT_SEL2);
    switch(misc_reg) {
      case MISCREG_SPSR_EL1:
        return currEL() == EL2 ? MISCREG_SPSR_EL2 : misc_reg;
      case MISCREG_ELR_EL1:
        return currEL() == EL2 ? MISCREG_ELR_EL2 : misc_reg;
      case MISCREG_SCTLR_EL1:
        return currEL() == EL2 ? MISCREG_SCTLR_EL2 : misc_reg;
      case MISCREG_CPACR_EL1:
        return currEL() == EL2 ? MISCREG_CPTR_EL2 : misc_reg;
//    case MISCREG_TRFCR_EL1:
//      return currEL() == EL2 ? MISCREG_TRFCR_EL2 : misc_reg;
      case MISCREG_TTBR0_EL1:
        return currEL() == EL2 ? MISCREG_TTBR0_EL2 : misc_reg;
      case MISCREG_TTBR1_EL1:
        return currEL() == EL2 ? MISCREG_TTBR1_EL2 : misc_reg;
      case MISCREG_TCR_EL1:
        return currEL() == EL2 ? MISCREG_TCR_EL2 : misc_reg;
      case MISCREG_AFSR0_EL1:
        return currEL() == EL2 ? MISCREG_AFSR0_EL2 : misc_reg;
      case MISCREG_AFSR1_EL1:
        return currEL() == EL2 ? MISCREG_AFSR1_EL2 : misc_reg;
      case MISCREG_ESR_EL1:
        return currEL() == EL2 ? MISCREG_ESR_EL2 : misc_reg;
      case MISCREG_FAR_EL1:
        return currEL() == EL2 ? MISCREG_FAR_EL2 : misc_reg;
      case MISCREG_MAIR_EL1:
        return currEL() == EL2 ? MISCREG_MAIR_EL2 : misc_reg;
      case MISCREG_AMAIR_EL1:
        return currEL() == EL2 ? MISCREG_AMAIR_EL2 : misc_reg;
      case MISCREG_VBAR_EL1:
        return currEL() == EL2 ? MISCREG_VBAR_EL2 : misc_reg;
      case MISCREG_CONTEXTIDR_EL1:
        return currEL() == EL2 ? MISCREG_CONTEXTIDR_EL2 : misc_reg;
      case MISCREG_CNTKCTL_EL1:
        return currEL() == EL2 ? MISCREG_CNTHCTL_EL2 : misc_reg;
      case MISCREG_CNTP_TVAL:
      case MISCREG_CNTP_TVAL_EL0:
        if (ELIsInHost(tc, currEL())) {
            return sec_el2 && !scr.ns ? MISCREG_CNTHPS_TVAL_EL2:
                                        MISCREG_CNTHP_TVAL_EL2;
        } else {
            return misc_reg;
        }
      case MISCREG_CNTP_CTL:
      case MISCREG_CNTP_CTL_EL0:
        if (ELIsInHost(tc, currEL())) {
            return sec_el2 && !scr.ns ? MISCREG_CNTHPS_CTL_EL2:
                                        MISCREG_CNTHP_CTL_EL2;
        } else {
            return misc_reg;
        }
      case MISCREG_CNTP_CVAL:
      case MISCREG_CNTP_CVAL_EL0:
        if (ELIsInHost(tc, currEL())) {
            return sec_el2 && !scr.ns ? MISCREG_CNTHPS_CVAL_EL2:
                                        MISCREG_CNTHP_CVAL_EL2;
        } else {
            return misc_reg;
        }
      case MISCREG_CNTV_TVAL:
      case MISCREG_CNTV_TVAL_EL0:
        if (ELIsInHost(tc, currEL())) {
            return sec_el2 && !scr.ns ? MISCREG_CNTHVS_TVAL_EL2:
                                        MISCREG_CNTHV_TVAL_EL2;
        } else {
            return misc_reg;
        }
      case MISCREG_CNTV_CTL:
      case MISCREG_CNTV_CTL_EL0:
        if (ELIsInHost(tc, currEL())) {
            return sec_el2 && !scr.ns ? MISCREG_CNTHVS_CTL_EL2:
                                        MISCREG_CNTHV_CTL_EL2;
        } else {
            return misc_reg;
        }
      case MISCREG_CNTV_CVAL:
      case MISCREG_CNTV_CVAL_EL0:
        if (ELIsInHost(tc, currEL())) {
            return sec_el2 && !scr.ns ? MISCREG_CNTHVS_CVAL_EL2:
                                        MISCREG_CNTHV_CVAL_EL2;
        } else {
            return misc_reg;
        }
      case MISCREG_CNTVCT:
      case MISCREG_CNTVCT_EL0:
        return ELIsInHost(tc, currEL()) ? MISCREG_CNTPCT_EL0 : misc_reg;
      case MISCREG_SCTLR_EL12:
        return MISCREG_SCTLR_EL1;
      case MISCREG_CPACR_EL12:
        return MISCREG_CPACR_EL1;
      case MISCREG_ZCR_EL12:
        return MISCREG_ZCR_EL1;
      case MISCREG_TTBR0_EL12:
        return MISCREG_TTBR0_EL1;
      case MISCREG_TTBR1_EL12:
        return MISCREG_TTBR1_EL1;
      case MISCREG_TCR_EL12:
        return MISCREG_TCR_EL1;
      case MISCREG_SPSR_EL12:
        return MISCREG_SPSR_EL1;
      case MISCREG_ELR_EL12:
        return MISCREG_ELR_EL1;
      case MISCREG_AFSR0_EL12:
        return MISCREG_AFSR0_EL1;
      case MISCREG_AFSR1_EL12:
        return MISCREG_AFSR1_EL1;
      case MISCREG_ESR_EL12:
        return MISCREG_ESR_EL1;
      case MISCREG_FAR_EL12:
        return MISCREG_FAR_EL1;
      case MISCREG_MAIR_EL12:
        return MISCREG_MAIR_EL1;
      case MISCREG_AMAIR_EL12:
        return MISCREG_AMAIR_EL1;
      case MISCREG_VBAR_EL12:
        return MISCREG_VBAR_EL1;
      case MISCREG_CONTEXTIDR_EL12:
        return MISCREG_CONTEXTIDR_EL1;
      case MISCREG_CNTKCTL_EL12:
        return MISCREG_CNTKCTL_EL1;
      // _EL02 registers
      case MISCREG_CNTP_TVAL_EL02:
        return MISCREG_CNTP_TVAL_EL0;
      case MISCREG_CNTP_CTL_EL02:
        return MISCREG_CNTP_CTL_EL0;
      case MISCREG_CNTP_CVAL_EL02:
        return MISCREG_CNTP_CVAL_EL0;
      case MISCREG_CNTV_TVAL_EL02:
        return MISCREG_CNTV_TVAL_EL0;
      case MISCREG_CNTV_CTL_EL02:
        return MISCREG_CNTV_CTL_EL0;
      case MISCREG_CNTV_CVAL_EL02:
        return MISCREG_CNTV_CVAL_EL0;
      default:
        return misc_reg;
    }
}

RegVal
ISA::readMiscRegNoEffect(RegIndex idx) const
{
    assert(idx < NUM_MISCREGS);

    const auto &reg = lookUpMiscReg[idx]; // bit masks
    const auto &map = getMiscIndices(idx);
    int lower = map.first, upper = map.second;
    // NB!: apply architectural masks according to desired register,
    // despite possibly getting value from different (mapped) register.
    auto val = !upper ? miscRegs[lower] : ((miscRegs[lower] & mask(32))
                                          |(miscRegs[upper] << 32));
    if (val & reg.res0()) {
        DPRINTF(MiscRegs, "Reading MiscReg %s with set res0 bits: %#x\n",
                miscRegName[idx], val & reg.res0());
    }
    if ((val & reg.res1()) != reg.res1()) {
        DPRINTF(MiscRegs, "Reading MiscReg %s with clear res1 bits: %#x\n",
                miscRegName[idx], (val & reg.res1()) ^ reg.res1());
    }
    return (val & ~reg.raz()) | reg.rao(); // enforce raz/rao
}


RegVal
ISA::readMiscReg(RegIndex idx)
{
    CPSR cpsr = 0;
    SCR scr = 0;

    if (idx == MISCREG_CPSR) {
        cpsr = miscRegs[idx];
        auto pc = tc->pcState().as<PCState>();
        cpsr.j = pc.jazelle() ? 1 : 0;
        cpsr.t = pc.thumb() ? 1 : 0;
        return cpsr;
    }

#ifndef NDEBUG
    auto& miscreg_info = lookUpMiscReg[idx].info;
    if (!miscreg_info[MISCREG_IMPLEMENTED]) {
        if (miscreg_info[MISCREG_WARN_NOT_FAIL])
            warn("Unimplemented system register %s read.\n",
                 miscRegName[idx]);
        else
            panic("Unimplemented system register %s read.\n",
                  miscRegName[idx]);
    }
#endif
    idx = redirectRegVHE(idx);

    switch (unflattenMiscReg(idx)) {
      case MISCREG_CPACR:
        {
            const uint32_t ones = (uint32_t)(-1);
            CPACR cpacrMask = 0;
            // Only cp10, cp11, and ase are implemented, nothing else should
            // be readable? (straight copy from the write code)
            cpacrMask.cp10 = ones;
            cpacrMask.cp11 = ones;
            cpacrMask.asedis = ones;

            // Security Extensions may limit the readability of CPACR
            if (release->has(ArmExtension::SECURITY)) {
                scr = readMiscRegNoEffect(MISCREG_SCR_EL3);
                cpsr = readMiscRegNoEffect(MISCREG_CPSR);
                if (scr.ns && (cpsr.mode != MODE_MON) && ELIs32(tc, EL3)) {
                    NSACR nsacr = readMiscRegNoEffect(MISCREG_NSACR);
                    // NB: Skipping the full loop, here
                    if (!nsacr.cp10) cpacrMask.cp10 = 0;
                    if (!nsacr.cp11) cpacrMask.cp11 = 0;
                }
            }
            RegVal val = readMiscRegNoEffect(MISCREG_CPACR);
            val &= cpacrMask;
            DPRINTF(MiscRegs, "Reading misc reg %s: %#x\n",
                    miscRegName[idx], val);
            return val;
        }
      case MISCREG_MPIDR:
      case MISCREG_MPIDR_EL1:
        return readMPIDR(system, tc);
      case MISCREG_ID_AFR0: // not implemented, so alias MIDR
      case MISCREG_REVIDR:  // not implemented, so alias MIDR
      case MISCREG_MIDR:
      case MISCREG_MIDR_EL1:
        if (currEL() == EL1 && EL2Enabled(tc)) {
            return readMiscRegNoEffect(MISCREG_VPIDR);
        } else {
            return readMiscRegNoEffect(idx);
        }
        break;

      case MISCREG_CLIDR:
        warn_once("The clidr register always reports 0 caches.\n");
        warn_once("clidr LoUIS field of 0b001 to match current "
                  "ARM implementations.\n");
        return 0x00200000;
      case MISCREG_CCSIDR:
        warn_once("The ccsidr register isn't implemented and "
                "always reads as 0.\n");
        break;
      case MISCREG_ACTLR:
        warn("Not doing anything for miscreg ACTLR\n");
        break;

      case MISCREG_PMXEVTYPER_PMCCFILTR:
      case MISCREG_PMINTENSET_EL1 ... MISCREG_PMOVSSET_EL0:
      case MISCREG_PMEVCNTR0_EL0 ... MISCREG_PMEVTYPER5_EL0:
      case MISCREG_PMCR ... MISCREG_PMOVSSET:
        return pmu->readMiscReg(idx);

      case MISCREG_CPSR_Q:
        panic("shouldn't be reading this register seperately\n");
      case MISCREG_FPSCR_QC:
        return readMiscRegNoEffect(MISCREG_FPSCR) & ~FpscrQcMask;
      case MISCREG_FPSCR_EXC:
        return readMiscRegNoEffect(MISCREG_FPSCR) & ~FpscrExcMask;
      case MISCREG_FPSR:
        {
            const uint32_t ones = (uint32_t)(-1);
            FPSCR fpscrMask = 0;
            fpscrMask.ioc = ones;
            fpscrMask.dzc = ones;
            fpscrMask.ofc = ones;
            fpscrMask.ufc = ones;
            fpscrMask.ixc = ones;
            fpscrMask.idc = ones;
            fpscrMask.qc = ones;
            fpscrMask.v = ones;
            fpscrMask.c = ones;
            fpscrMask.z = ones;
            fpscrMask.n = ones;
            return readMiscRegNoEffect(MISCREG_FPSCR) & (uint32_t)fpscrMask;
        }
      case MISCREG_FPCR:
        {
            const uint32_t ones = (uint32_t)(-1);
            FPSCR fpscrMask  = 0;
            fpscrMask.len    = ones;
            fpscrMask.fz16   = ones;
            fpscrMask.stride = ones;
            fpscrMask.rMode  = ones;
            fpscrMask.fz     = ones;
            fpscrMask.dn     = ones;
            fpscrMask.ahp    = ones;
            return readMiscRegNoEffect(MISCREG_FPSCR) & (uint32_t)fpscrMask;
        }
      case MISCREG_NZCV:
        {
            CPSR cpsr = 0;
            cpsr.nz   = tc->getReg(cc_reg::Nz);
            cpsr.c    = tc->getReg(cc_reg::C);
            cpsr.v    = tc->getReg(cc_reg::V);
            return cpsr;
        }
      case MISCREG_DAIF:
        {
            CPSR cpsr = 0;
            cpsr.daif = (uint8_t) ((CPSR) miscRegs[MISCREG_CPSR]).daif;
            return cpsr;
        }
      case MISCREG_SP_EL0:
        {
            return tc->getReg(int_reg::Sp0);
        }
      case MISCREG_SP_EL1:
        {
            return tc->getReg(int_reg::Sp1);
        }
      case MISCREG_SP_EL2:
        {
            return tc->getReg(int_reg::Sp2);
        }
      case MISCREG_SPSEL:
        {
            return miscRegs[MISCREG_CPSR] & 0x1;
        }
      case MISCREG_CURRENTEL:
        {
            return miscRegs[MISCREG_CPSR] & 0xc;
        }
      case MISCREG_PAN:
        {
            return miscRegs[MISCREG_CPSR] & 0x400000;
        }
      case MISCREG_UAO:
        {
            return miscRegs[MISCREG_CPSR] & 0x800000;
        }
      case MISCREG_L2CTLR:
        {
            // mostly unimplemented, just set NumCPUs field from sim and return
            L2CTLR l2ctlr = 0;
            // b00:1CPU to b11:4CPUs
            l2ctlr.numCPUs = tc->getSystemPtr()->threads.size() - 1;
            return l2ctlr;
        }
      case MISCREG_ISR:
      case MISCREG_ISR_EL1:
        {
            auto ic = dynamic_cast<ArmISA::Interrupts *>(
                    tc->getCpuPtr()->getInterruptController(tc->threadId()));
            return ic->getISR(
                readMiscRegNoEffect(MISCREG_HCR_EL2),
                readMiscRegNoEffect(MISCREG_CPSR),
                readMiscRegNoEffect(MISCREG_SCR_EL3));
        }
      case MISCREG_HCPTR:
        {
            HCPTR val = readMiscRegNoEffect(idx);
            bool secure_lookup = release->has(ArmExtension::SECURITY) &&
                isSecure(tc);
            if (!secure_lookup) {
                NSACR nsacr = readMiscRegNoEffect(MISCREG_NSACR);
                if (!nsacr.cp10) {
                    val.tcp10 = 1;
                    val.tcp11 = 1;
                }
            }
            return val;
        }
      case MISCREG_HDFAR: // alias for secure DFAR
        return readMiscRegNoEffect(MISCREG_DFAR_S);
      case MISCREG_HIFAR: // alias for secure IFAR
        return readMiscRegNoEffect(MISCREG_IFAR_S);

      case MISCREG_RNDR:
        tc->setReg(cc_reg::Nz, (RegVal)0);
        tc->setReg(cc_reg::C, (RegVal)0);
        tc->setReg(cc_reg::V, (RegVal)0);
        return random_mt.random<RegVal>();
      case MISCREG_RNDRRS:
        tc->setReg(cc_reg::Nz, (RegVal)0);
        tc->setReg(cc_reg::C, (RegVal)0);
        tc->setReg(cc_reg::V, (RegVal)0);
        // Note: we are not reseeding
        // The random number generator already has an hardcoded
        // seed for the sake of determinism. There is no point
        // in simulating non-determinism here
        return random_mt.random<RegVal>();

      // Generic Timer registers
      case MISCREG_CNTFRQ ... MISCREG_CNTVOFF:
      case MISCREG_CNTFRQ_EL0 ... MISCREG_CNTVOFF_EL2:
        return getGenericTimer().readMiscReg(idx);

      case MISCREG_ICC_AP0R0 ... MISCREG_ICH_LRC15:
      case MISCREG_ICC_PMR_EL1 ... MISCREG_ICC_IGRPEN1_EL3:
      case MISCREG_ICH_AP0R0_EL2 ... MISCREG_ICH_LR15_EL2:
        return getGICv3CPUInterface().readMiscReg(idx);

      default:
        break;

    }
    return readMiscRegNoEffect(idx);
}

void
ISA::setMiscRegNoEffect(RegIndex idx, RegVal val)
{
    assert(idx < NUM_MISCREGS);

    const auto &reg = lookUpMiscReg[idx]; // bit masks
    const auto &map = getMiscIndices(idx);
    int lower = map.first, upper = map.second;

    auto v = (val & ~reg.wi()) | reg.rao();
    if (upper > 0) {
        miscRegs[lower] = bits(v, 31, 0);
        miscRegs[upper] = bits(v, 63, 32);
        DPRINTF(MiscRegs, "Writing MiscReg %s (%d %d:%d) : %#x\n",
                miscRegName[idx], idx, lower, upper, v);
    } else {
        miscRegs[lower] = v;
        DPRINTF(MiscRegs, "Writing MiscReg %s (%d %d) : %#x\n",
                miscRegName[idx], idx, lower, v);
    }
}

void
ISA::setMiscReg(RegIndex idx, RegVal val)
{

    RegVal newVal = val;
    bool secure_lookup;
    SCR scr;

    if (idx == MISCREG_CPSR) {
        updateRegMap(val);


        CPSR old_cpsr = miscRegs[MISCREG_CPSR];
        int old_mode = old_cpsr.mode;
        CPSR cpsr = val;
        if (cpsr.pan != old_cpsr.pan || cpsr.il != old_cpsr.il) {
            getMMUPtr(tc)->invalidateMiscReg();
        }

        DPRINTF(Arm, "Updating CPSR from %#x to %#x f:%d i:%d a:%d mode:%#x\n",
                miscRegs[idx], cpsr, cpsr.f, cpsr.i, cpsr.a, cpsr.mode);
        PCState pc = tc->pcState().as<PCState>();
        pc.nextThumb(cpsr.t);
        pc.nextJazelle(cpsr.j);
        pc.illegalExec(cpsr.il == 1);
        selfDebug->setDebugMask(cpsr.d == 1);

        tc->getDecoderPtr()->as<Decoder>().setSveLen(
                (getCurSveVecLenInBits() >> 7) - 1);
        tc->getDecoderPtr()->as<Decoder>().setSmeLen(
                (getCurSmeVecLenInBits() >> 7) - 1);

        // Follow slightly different semantics if a CheckerCPU object
        // is connected
        CheckerCPU *checker = tc->getCheckerCpuPtr();
        if (checker) {
            tc->pcStateNoRecord(pc);
        } else {
            tc->pcState(pc);
        }

        setMiscRegNoEffect(idx, newVal);

        if (old_mode != cpsr.mode) {
            getMMUPtr(tc)->invalidateMiscReg();
            if (gicv3CpuInterface) {
                // The assertion and de-assertion of IRQs and FIQs are
                // affected by the current Exception level and Security
                // state of the PE. As part of the Context
                // Synchronization that occurs as the result of taking
                // or returning from an exception, the CPU interface
                // ensures that IRQ and FIQ are both appropriately
                // asserted or deasserted for the Exception level and
                // Security state that the PE is entering.
                static_cast<Gicv3CPUInterface&>(
                    getGICv3CPUInterface()).update();
            }
        }
    } else {
#ifndef NDEBUG
        auto& miscreg_info = lookUpMiscReg[idx].info;
        if (!miscreg_info[MISCREG_IMPLEMENTED]) {
            if (miscreg_info[MISCREG_WARN_NOT_FAIL])
                warn("Unimplemented system register %s write with %#x.\n",
                    miscRegName[idx], val);
            else
                panic("Unimplemented system register %s write with %#x.\n",
                    miscRegName[idx], val);
        }
#endif
        idx = redirectRegVHE(idx);

        switch (unflattenMiscReg(idx)) {
          case MISCREG_CPACR:
            {

                const uint32_t ones = (uint32_t)(-1);
                CPACR cpacrMask = 0;
                // Only cp10, cp11, and ase are implemented, nothing else should
                // be writable
                cpacrMask.cp10 = ones;
                cpacrMask.cp11 = ones;
                cpacrMask.asedis = ones;

                // Security Extensions may limit the writability of CPACR
                if (release->has(ArmExtension::SECURITY)) {
                    scr = readMiscRegNoEffect(MISCREG_SCR_EL3);
                    CPSR cpsr = readMiscRegNoEffect(MISCREG_CPSR);
                    if (scr.ns && (cpsr.mode != MODE_MON) && ELIs32(tc, EL3)) {
                        NSACR nsacr = readMiscRegNoEffect(MISCREG_NSACR);
                        // NB: Skipping the full loop, here
                        if (!nsacr.cp10) cpacrMask.cp10 = 0;
                        if (!nsacr.cp11) cpacrMask.cp11 = 0;
                    }
                }

                RegVal old_val = readMiscRegNoEffect(MISCREG_CPACR);
                newVal &= cpacrMask;
                newVal |= old_val & ~cpacrMask;
                DPRINTF(MiscRegs, "Writing misc reg %s: %#x\n",
                        miscRegName[idx], newVal);
            }
            break;
          case MISCREG_CPACR_EL1:
            {
                const uint32_t ones = (uint32_t)(-1);
                CPACR cpacrMask = 0;
                cpacrMask.tta = ones;
                cpacrMask.fpen = ones;
                if (release->has(ArmExtension::FEAT_SVE)) {
                    cpacrMask.zen = ones;
                }
                if (release->has(ArmExtension::FEAT_SME)) {
                    cpacrMask.smen = ones;
                }
                newVal &= cpacrMask;
                DPRINTF(MiscRegs, "Writing misc reg %s: %#x\n",
                        miscRegName[idx], newVal);
            }
            break;
          case MISCREG_CPTR_EL2:
            {
                const HCR hcr = readMiscRegNoEffect(MISCREG_HCR_EL2);
                const uint32_t ones = (uint32_t)(-1);
                CPTR cptrMask = 0;
                cptrMask.tcpac = ones;
                cptrMask.tta = ones;
                cptrMask.tfp = ones;
                if (release->has(ArmExtension::FEAT_SVE)) {
                    cptrMask.tz = ones;
                    cptrMask.zen = hcr.e2h ? ones : 0;
                }
                if (release->has(ArmExtension::FEAT_SME)) {
                    cptrMask.tsm = ones;
                    cptrMask.smen = hcr.e2h ? ones : 0;
                }
                cptrMask.fpen = hcr.e2h ? ones : 0;
                newVal &= cptrMask;
                cptrMask = 0;
                cptrMask.res1_13_el2 = ones;
                cptrMask.res1_7_0_el2 = ones;
                if (!release->has(ArmExtension::FEAT_SVE)) {
                    cptrMask.res1_8_el2 = ones;
                }
                if (!release->has(ArmExtension::FEAT_SME)) {
                    cptrMask.res1_12_el2 = ones;
                }
                cptrMask.res1_9_el2 = ones;
                newVal |= cptrMask;
                DPRINTF(MiscRegs, "Writing misc reg %s: %#x\n",
                        miscRegName[idx], newVal);
            }
            break;
          case MISCREG_CPTR_EL3:
            {
                const uint32_t ones = (uint32_t)(-1);
                CPTR cptrMask = 0;
                cptrMask.tcpac = ones;
                cptrMask.tta = ones;
                cptrMask.tfp = ones;
                if (release->has(ArmExtension::FEAT_SVE)) {
                    cptrMask.ez = ones;
                }
                if (release->has(ArmExtension::FEAT_SME)) {
                    cptrMask.esm = ones;
                }
                newVal &= cptrMask;
                DPRINTF(MiscRegs, "Writing misc reg %s: %#x\n",
                        miscRegName[idx], newVal);
            }
            break;
          case MISCREG_CSSELR:
            warn_once("The csselr register isn't implemented.\n");
            return;

          case MISCREG_DC_ZVA_Xt:
            warn("Calling DC ZVA! Not Implemeted! Expect WEIRD results\n");
            return;

          case MISCREG_FPSCR:
            tc->getDecoderPtr()->as<Decoder>().setContext(newVal);
            break;
          case MISCREG_FPSR:
            {
                const uint32_t ones = (uint32_t)(-1);
                FPSCR fpscrMask = 0;
                fpscrMask.ioc = ones;
                fpscrMask.dzc = ones;
                fpscrMask.ofc = ones;
                fpscrMask.ufc = ones;
                fpscrMask.ixc = ones;
                fpscrMask.idc = ones;
                fpscrMask.qc = ones;
                fpscrMask.v = ones;
                fpscrMask.c = ones;
                fpscrMask.z = ones;
                fpscrMask.n = ones;
                newVal = (newVal & (uint32_t)fpscrMask) |
                         (readMiscRegNoEffect(MISCREG_FPSCR) &
                          ~(uint32_t)fpscrMask);
                idx = MISCREG_FPSCR;
            }
            break;
          case MISCREG_FPCR:
            {
                const uint32_t ones = (uint32_t)(-1);
                FPSCR fpscrMask  = 0;
                fpscrMask.len    = ones;
                fpscrMask.fz16   = ones;
                fpscrMask.stride = ones;
                fpscrMask.rMode  = ones;
                fpscrMask.fz     = ones;
                fpscrMask.dn     = ones;
                fpscrMask.ahp    = ones;
                newVal = (newVal & (uint32_t)fpscrMask) |
                         (readMiscRegNoEffect(MISCREG_FPSCR) &
                          ~(uint32_t)fpscrMask);
                idx = MISCREG_FPSCR;
            }
            break;
          case MISCREG_CPSR_Q:
            {
                assert(!(newVal & ~CpsrMaskQ));
                newVal = readMiscRegNoEffect(MISCREG_CPSR) | newVal;
                idx = MISCREG_CPSR;
            }
            break;
          case MISCREG_FPSCR_QC:
            {
                newVal = readMiscRegNoEffect(MISCREG_FPSCR) |
                         (newVal & FpscrQcMask);
                idx = MISCREG_FPSCR;
            }
            break;
          case MISCREG_FPSCR_EXC:
            {
                newVal = readMiscRegNoEffect(MISCREG_FPSCR) |
                         (newVal & FpscrExcMask);
                idx = MISCREG_FPSCR;
            }
            break;
          case MISCREG_FPEXC:
            {
                // vfpv3 architecture, section B.6.1 of DDI04068
                // bit 29 - valid only if fpexc[31] is 0
                const uint32_t fpexcMask = 0x60000000;
                newVal = (newVal & fpexcMask) |
                         (readMiscRegNoEffect(MISCREG_FPEXC) & ~fpexcMask);
            }
            break;
          case MISCREG_HCR:
            {
                const HDCR mdcr  = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
                selfDebug->setenableTDETGE((HCR)val, mdcr);
            }
            break;

          case MISCREG_HDCR:
            {
                const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
                selfDebug->setenableTDETGE(hcr, (HDCR)val);
            }
            break;
          case MISCREG_DBGOSLAR:
            {
                OSL r = tc->readMiscReg(MISCREG_DBGOSLSR);
                const uint32_t temp = (val == 0xC5ACCE55)? 0x1 : 0x0;
                selfDebug->updateOSLock((RegVal) temp);
                r.oslk = bits(temp,0);
                tc->setMiscReg(MISCREG_DBGOSLSR, r);
            }
            break;
          case MISCREG_DBGBCR0 ... MISCREG_DBGBCR15:
            selfDebug->updateDBGBCR(idx - MISCREG_DBGBCR0, val);
            break;
          case MISCREG_DBGWCR0 ... MISCREG_DBGWCR15:
            selfDebug->updateDBGWCR(idx - MISCREG_DBGWCR0, val);
            break;

          case MISCREG_MDCR_EL2:
            {
                const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
                selfDebug->setenableTDETGE(hcr, (HDCR)val);
            }
            break;
          case MISCREG_SDCR:
          case MISCREG_MDCR_EL3:
            {
                selfDebug->setbSDD(val);
            }
            break;
          case MISCREG_DBGDSCRext:
            {
                selfDebug->setMDBGen(val);
                DBGDS32 r = tc->readMiscReg(MISCREG_DBGDSCRint);
                DBGDS32 v = val;
                r.moe = v.moe;
                r.udccdis = v.udccdis;
                r.mdbgen = v.mdbgen;
                tc->setMiscReg(MISCREG_DBGDSCRint, r);
                r = tc->readMiscReg(MISCREG_DBGDSCRint);
            }

            break;
          case MISCREG_MDSCR_EL1:
            {
                selfDebug->setMDSCRvals(val);
            }
            break;

          case MISCREG_OSLAR_EL1:
            {
                selfDebug->updateOSLock(val);
                OSL r = tc->readMiscReg(MISCREG_OSLSR_EL1);
                r.oslk = bits(val, 0);
                r.oslm_3 = 1;
                tc->setMiscReg(MISCREG_OSLSR_EL1, r);
            }
            break;

          case MISCREG_DBGBCR0_EL1 ... MISCREG_DBGBCR15_EL1:
            selfDebug->updateDBGBCR(idx - MISCREG_DBGBCR0_EL1, val);
            break;
          case MISCREG_DBGWCR0_EL1 ... MISCREG_DBGWCR15_EL1:
            selfDebug->updateDBGWCR(idx - MISCREG_DBGWCR0_EL1, val);
            break;
          case MISCREG_SCR:
            getMMUPtr(tc)->invalidateMiscReg();
            break;
          case MISCREG_SCTLR:
            {
                DPRINTF(MiscRegs, "Writing SCTLR: %#x\n", newVal);
                scr = readMiscRegNoEffect(MISCREG_SCR_EL3);

                MiscRegIndex sctlr_idx;
                if (release->has(ArmExtension::SECURITY) &&
                    !highestELIs64 && !scr.ns) {
                    sctlr_idx = MISCREG_SCTLR_S;
                } else {
                    sctlr_idx =  MISCREG_SCTLR_NS;
                }

                SCTLR sctlr = miscRegs[sctlr_idx];
                SCTLR new_sctlr = newVal;
                new_sctlr.nmfi =  ((bool)sctlr.nmfi) &&
                    !release->has(ArmExtension::VIRTUALIZATION);
                miscRegs[sctlr_idx] = (RegVal)new_sctlr;
                getMMUPtr(tc)->invalidateMiscReg();
            }
          case MISCREG_MIDR:
          case MISCREG_ID_PFR0:
          case MISCREG_ID_PFR1:
          case MISCREG_ID_DFR0:
          case MISCREG_ID_MMFR0:
          case MISCREG_ID_MMFR1:
          case MISCREG_ID_MMFR2:
          case MISCREG_ID_MMFR3:
          case MISCREG_ID_MMFR4:
          case MISCREG_ID_ISAR0:
          case MISCREG_ID_ISAR1:
          case MISCREG_ID_ISAR2:
          case MISCREG_ID_ISAR3:
          case MISCREG_ID_ISAR4:
          case MISCREG_ID_ISAR5:

          case MISCREG_MPIDR:
          case MISCREG_FPSID:
          case MISCREG_TLBTR:
          case MISCREG_MVFR0:
          case MISCREG_MVFR1:

          case MISCREG_ID_AA64AFR0_EL1:
          case MISCREG_ID_AA64AFR1_EL1:
          case MISCREG_ID_AA64DFR0_EL1:
          case MISCREG_ID_AA64DFR1_EL1:
          case MISCREG_ID_AA64ISAR0_EL1:
          case MISCREG_ID_AA64ISAR1_EL1:
          case MISCREG_ID_AA64MMFR0_EL1:
          case MISCREG_ID_AA64MMFR1_EL1:
          case MISCREG_ID_AA64MMFR2_EL1:
          case MISCREG_ID_AA64PFR0_EL1:
          case MISCREG_ID_AA64PFR1_EL1:
            // ID registers are constants.
            return;

          // TLB Invalidate All
          case MISCREG_ACTLR:
            warn("Not doing anything for write of miscreg ACTLR\n");
            break;

          case MISCREG_PMXEVTYPER_PMCCFILTR:
          case MISCREG_PMINTENSET_EL1 ... MISCREG_PMOVSSET_EL0:
          case MISCREG_PMEVCNTR0_EL0 ... MISCREG_PMEVTYPER5_EL0:
          case MISCREG_PMCR ... MISCREG_PMOVSSET:
            pmu->setMiscReg(idx, newVal);
            break;


          case MISCREG_HSTR: // TJDBX, now redifined to be RES0
            {
                HSTR hstrMask = 0;
                hstrMask.tjdbx = 1;
                newVal &= ~((uint32_t) hstrMask);
                break;
            }
          case MISCREG_HCPTR:
            {
                // If a CP bit in NSACR is 0 then the corresponding bit in
                // HCPTR is RAO/WI. Same applies to NSASEDIS
                secure_lookup = release->has(ArmExtension::SECURITY) &&
                    isSecure(tc);
                if (!secure_lookup) {
                    RegVal oldValue = readMiscRegNoEffect(MISCREG_HCPTR);
                    RegVal mask =
                        (readMiscRegNoEffect(MISCREG_NSACR) ^ 0x7FFF) & 0xBFFF;
                    newVal = (newVal & ~mask) | (oldValue & mask);
                }
                break;
            }
          case MISCREG_HDFAR: // alias for secure DFAR
            idx = MISCREG_DFAR_S;
            break;
          case MISCREG_HIFAR: // alias for secure IFAR
            idx = MISCREG_IFAR_S;
            break;
          case MISCREG_ATS1CPR:
            addressTranslation(MMU::S1CTran, BaseMMU::Read, 0, val);
            return;
          case MISCREG_ATS1CPW:
            addressTranslation(MMU::S1CTran, BaseMMU::Write, 0, val);
            return;
          case MISCREG_ATS1CUR:
            addressTranslation(MMU::S1CTran, BaseMMU::Read,
                MMU::UserMode, val);
            return;
          case MISCREG_ATS1CUW:
            addressTranslation(MMU::S1CTran, BaseMMU::Write,
                MMU::UserMode, val);
            return;
          case MISCREG_ATS12NSOPR:
            if (!release->has(ArmExtension::SECURITY))
                panic("Security Extensions required for ATS12NSOPR");
            addressTranslation(MMU::S1S2NsTran, BaseMMU::Read, 0, val);
            return;
          case MISCREG_ATS12NSOPW:
            if (!release->has(ArmExtension::SECURITY))
                panic("Security Extensions required for ATS12NSOPW");
            addressTranslation(MMU::S1S2NsTran, BaseMMU::Write, 0, val);
            return;
          case MISCREG_ATS12NSOUR:
            if (!release->has(ArmExtension::SECURITY))
                panic("Security Extensions required for ATS12NSOUR");
            addressTranslation(MMU::S1S2NsTran, BaseMMU::Read,
                MMU::UserMode, val);
            return;
          case MISCREG_ATS12NSOUW:
            if (!release->has(ArmExtension::SECURITY))
                panic("Security Extensions required for ATS12NSOUW");
            addressTranslation(MMU::S1S2NsTran, BaseMMU::Write,
                MMU::UserMode, val);
            return;
          case MISCREG_ATS1HR:
            addressTranslation(MMU::HypMode, BaseMMU::Read, 0, val);
            return;
          case MISCREG_ATS1HW:
            addressTranslation(MMU::HypMode, BaseMMU::Write, 0, val);
            return;
          case MISCREG_TTBCR:
            {
                TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
                const uint32_t ones = (uint32_t)(-1);
                TTBCR ttbcrMask = 0;
                TTBCR ttbcrNew = newVal;

                // ARM DDI 0406C.b, ARMv7-32
                ttbcrMask.n = ones; // T0SZ
                if (release->has(ArmExtension::SECURITY)) {
                    ttbcrMask.pd0 = ones;
                    ttbcrMask.pd1 = ones;
                }
                ttbcrMask.epd0 = ones;
                ttbcrMask.irgn0 = ones;
                ttbcrMask.orgn0 = ones;
                ttbcrMask.sh0 = ones;
                ttbcrMask.ps = ones; // T1SZ
                ttbcrMask.a1 = ones;
                ttbcrMask.epd1 = ones;
                ttbcrMask.irgn1 = ones;
                ttbcrMask.orgn1 = ones;
                ttbcrMask.sh1 = ones;
                if (release->has(ArmExtension::LPAE))
                    ttbcrMask.eae = ones;

                if (release->has(ArmExtension::LPAE) && ttbcrNew.eae) {
                    newVal = newVal & ttbcrMask;
                } else {
                    newVal = (newVal & ttbcrMask) | (ttbcr & (~ttbcrMask));
                }
                // Invalidate TLB MiscReg
                getMMUPtr(tc)->invalidateMiscReg();
                break;
            }
          case MISCREG_TTBR0:
          case MISCREG_TTBR1:
            {
                TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
                if (release->has(ArmExtension::LPAE)) {
                    if (ttbcr.eae) {
                        // ARMv7 bit 63-56, 47-40 reserved, UNK/SBZP
                        // ARMv8 AArch32 bit 63-56 only
                        uint64_t ttbrMask = mask(63,56) | mask(47,40);
                        newVal = (newVal & (~ttbrMask));
                    }
                }
                // Invalidate TLB MiscReg
                getMMUPtr(tc)->invalidateMiscReg();
                break;
            }
          case MISCREG_SCTLR_EL1:
          case MISCREG_CONTEXTIDR:
          case MISCREG_PRRR:
          case MISCREG_NMRR:
          case MISCREG_MAIR0:
          case MISCREG_MAIR1:
          case MISCREG_DACR:
          case MISCREG_VTTBR:
          case MISCREG_SCR_EL3:
          case MISCREG_TCR_EL1:
          case MISCREG_TCR_EL2:
          case MISCREG_TCR_EL3:
          case MISCREG_VTCR_EL2:
          case MISCREG_SCTLR_EL2:
          case MISCREG_SCTLR_EL3:
          case MISCREG_HSCTLR:
          case MISCREG_TTBR0_EL1:
          case MISCREG_TTBR1_EL1:
          case MISCREG_TTBR0_EL2:
          case MISCREG_TTBR1_EL2:
          case MISCREG_TTBR0_EL3:
            getMMUPtr(tc)->invalidateMiscReg();
            break;
          case MISCREG_HCR_EL2:
            {
                const HDCR mdcr  = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
                selfDebug->setenableTDETGE((HCR)val, mdcr);
                getMMUPtr(tc)->invalidateMiscReg();
            }
            break;
          case MISCREG_NZCV:
            {
                CPSR cpsr = val;

                tc->setReg(cc_reg::Nz, cpsr.nz);
                tc->setReg(cc_reg::C,  cpsr.c);
                tc->setReg(cc_reg::V,  cpsr.v);
            }
            break;
          case MISCREG_DAIF:
            {
                CPSR cpsr = miscRegs[MISCREG_CPSR];
                cpsr.daif = (uint8_t) ((CPSR) newVal).daif;
                newVal = cpsr;
                idx = MISCREG_CPSR;
            }
            break;
          case MISCREG_SP_EL0:
            tc->setReg(int_reg::Sp0, newVal);
            break;
          case MISCREG_SP_EL1:
            tc->setReg(int_reg::Sp1, newVal);
            break;
          case MISCREG_SP_EL2:
            tc->setReg(int_reg::Sp2, newVal);
            break;
          case MISCREG_SPSEL:
            {
                CPSR cpsr = miscRegs[MISCREG_CPSR];
                cpsr.sp = (uint8_t) ((CPSR) newVal).sp;
                newVal = cpsr;
                idx = MISCREG_CPSR;
            }
            break;
          case MISCREG_CURRENTEL:
            {
                CPSR cpsr = miscRegs[MISCREG_CPSR];
                cpsr.el = (uint8_t) ((CPSR) newVal).el;
                newVal = cpsr;
                idx = MISCREG_CPSR;
            }
            break;
          case MISCREG_PAN:
            {
                // PAN is affecting data accesses
                getMMUPtr(tc)->invalidateMiscReg();

                CPSR cpsr = miscRegs[MISCREG_CPSR];
                cpsr.pan = (uint8_t) ((CPSR) newVal).pan;
                newVal = cpsr;
                idx = MISCREG_CPSR;
            }
            break;
          case MISCREG_UAO:
            {
                // UAO is affecting data accesses
                getMMUPtr(tc)->invalidateMiscReg();

                CPSR cpsr = miscRegs[MISCREG_CPSR];
                cpsr.uao = (uint8_t) ((CPSR) newVal).uao;
                newVal = cpsr;
                idx = MISCREG_CPSR;
            }
            break;
          case MISCREG_AT_S1E1R_Xt:
            addressTranslation64(MMU::S1E1Tran, BaseMMU::Read, 0, val);
            return;
          case MISCREG_AT_S1E1W_Xt:
            addressTranslation64(MMU::S1E1Tran, BaseMMU::Write, 0, val);
            return;
          case MISCREG_AT_S1E0R_Xt:
            addressTranslation64(MMU::S1E0Tran, BaseMMU::Read,
                MMU::UserMode, val);
            return;
          case MISCREG_AT_S1E0W_Xt:
            addressTranslation64(MMU::S1E0Tran, BaseMMU::Write,
                MMU::UserMode, val);
            return;
          case MISCREG_AT_S1E2R_Xt:
            addressTranslation64(MMU::S1E2Tran, BaseMMU::Read, 0, val);
            return;
          case MISCREG_AT_S1E2W_Xt:
            addressTranslation64(MMU::S1E2Tran, BaseMMU::Write, 0, val);
            return;
          case MISCREG_AT_S12E1R_Xt:
            addressTranslation64(MMU::S12E1Tran, BaseMMU::Read, 0, val);
            return;
          case MISCREG_AT_S12E1W_Xt:
            addressTranslation64(MMU::S12E1Tran, BaseMMU::Write, 0, val);
            return;
          case MISCREG_AT_S12E0R_Xt:
            addressTranslation64(MMU::S12E0Tran, BaseMMU::Read,
                MMU::UserMode, val);
            return;
          case MISCREG_AT_S12E0W_Xt:
            addressTranslation64(MMU::S12E0Tran, BaseMMU::Write,
                MMU::UserMode, val);
            return;
          case MISCREG_AT_S1E3R_Xt:
            addressTranslation64(MMU::S1E3Tran, BaseMMU::Read, 0, val);
            return;
          case MISCREG_AT_S1E3W_Xt:
            addressTranslation64(MMU::S1E3Tran, BaseMMU::Write, 0, val);
            return;
          case MISCREG_L2CTLR:
            warn("miscreg L2CTLR (%s) written with %#x. ignored...\n",
                 miscRegName[idx], uint32_t(val));
            break;

          // Generic Timer registers
          case MISCREG_CNTFRQ ... MISCREG_CNTVOFF:
          case MISCREG_CNTFRQ_EL0 ... MISCREG_CNTVOFF_EL2:
            getGenericTimer().setMiscReg(idx, newVal);
            break;
          case MISCREG_ICC_AP0R0 ... MISCREG_ICH_LRC15:
          case MISCREG_ICC_PMR_EL1 ... MISCREG_ICC_IGRPEN1_EL3:
          case MISCREG_ICH_AP0R0_EL2 ... MISCREG_ICH_LR15_EL2:
            getGICv3CPUInterface().setMiscReg(idx, newVal);
            return;
          case MISCREG_ZCR_EL3:
          case MISCREG_ZCR_EL2:
          case MISCREG_ZCR_EL1:
            // Set the value here as we need to update the regs before
            // reading them back in getCurSveVecLenInBits to avoid
            // setting stale vector lengths in the decoder.
            setMiscRegNoEffect(idx, newVal);
            tc->getDecoderPtr()->as<Decoder>().setSveLen(
                    (getCurSveVecLenInBits() >> 7) - 1);
            return;
          case MISCREG_SMCR_EL3:
          case MISCREG_SMCR_EL2:
          case MISCREG_SMCR_EL1:
            // Set the value here as we need to update the regs before
            // reading them back in getCurSmeVecLenInBits to avoid
            // setting stale vector lengths in the decoder.
            setMiscRegNoEffect(idx, newVal);
            tc->getDecoderPtr()->as<Decoder>().setSmeLen(
                    (getCurSmeVecLenInBits() >> 7) - 1);
            return;
        }
        setMiscRegNoEffect(idx, newVal);
    }
}

RegVal
ISA::readMiscRegReset(RegIndex idx) const
{
    int flat_idx = flattenMiscIndex(idx);
    return lookUpMiscReg[flat_idx].reset();
}

void
ISA::setMiscRegReset(RegIndex idx, RegVal val)
{
    int flat_idx = flattenMiscIndex(idx);
    InitReg(flat_idx).reset(val);
}

BaseISADevice &
ISA::getGenericTimer()
{
    // We only need to create an ISA interface the first time we try
    // to access the timer.
    if (timer)
        return *timer.get();

    assert(system);
    GenericTimer *generic_timer(system->getGenericTimer());
    if (!generic_timer) {
        panic("Trying to get a generic timer from a system that hasn't "
              "been configured to use a generic timer.\n");
    }

    timer.reset(new GenericTimerISA(*generic_timer, tc->contextId()));
    timer->setThreadContext(tc);

    return *timer.get();
}

BaseISADevice &
ISA::getGICv3CPUInterface()
{
    if (gicv3CpuInterface)
        return *gicv3CpuInterface.get();

    auto gicv3_ifc = getGICv3CPUInterface(tc);
    panic_if(!gicv3_ifc, "The system does not have a GICv3 irq controller\n");
    gicv3CpuInterface.reset(gicv3_ifc);

    return *gicv3CpuInterface.get();
}

BaseISADevice*
ISA::getGICv3CPUInterface(ThreadContext *tc)
{
    assert(system);
    Gicv3 *gicv3 = dynamic_cast<Gicv3 *>(system->getGIC());
    if (gicv3) {
        return gicv3->getCPUInterface(tc->contextId());
    } else {
        return nullptr;
    }
}

bool
ISA::inSecureState() const
{
    if (!release->has(ArmExtension::SECURITY)) {
        return false;
    }

    SCR scr = miscRegs[MISCREG_SCR];
    CPSR cpsr = miscRegs[MISCREG_CPSR];

    switch ((OperatingMode) (uint8_t) cpsr.mode) {
      case MODE_MON:
      case MODE_EL3T:
      case MODE_EL3H:
        return true;
      case MODE_HYP:
      case MODE_EL2T:
      case MODE_EL2H:
        return false;
      default:
        return !scr.ns;
    }
}

ExceptionLevel
ISA::currEL() const
{
    CPSR cpsr = readMiscRegNoEffect(MISCREG_CPSR);

    return opModeToEL((OperatingMode)(uint8_t)cpsr.mode);
}

unsigned
ISA::getCurSveVecLenInBits() const
{
    SVCR svcr = miscRegs[MISCREG_SVCR];
    // If we are in Streaming Mode, we should return the Streaming Mode vector
    // length instead.
    if (svcr.sm) {
        return getCurSmeVecLenInBits();
    }

    if (!FullSystem) {
        return sveVL * 128;
    }

    panic_if(!tc,
             "A ThreadContext is needed to determine the SVE vector length "
             "in full-system mode");

    CPSR cpsr = miscRegs[MISCREG_CPSR];
    ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;

    unsigned len = 0;

    if (el == EL1 || (el == EL0 && !ELIsInHost(tc, el))) {
        len = static_cast<ZCR>(miscRegs[MISCREG_ZCR_EL1]).len;
    }

    if (el == EL2 || (el == EL0 && ELIsInHost(tc, el))) {
        len = static_cast<ZCR>(miscRegs[MISCREG_ZCR_EL2]).len;
    } else if (release->has(ArmExtension::VIRTUALIZATION) && !isSecure(tc) &&
               (el == EL0 || el == EL1)) {
        len = std::min(
            len,
            static_cast<unsigned>(
                static_cast<ZCR>(miscRegs[MISCREG_ZCR_EL2]).len));
    }

    if (el == EL3) {
        len = static_cast<ZCR>(miscRegs[MISCREG_ZCR_EL3]).len;
    } else if (release->has(ArmExtension::SECURITY)) {
        len = std::min(
            len,
            static_cast<unsigned>(
                static_cast<ZCR>(miscRegs[MISCREG_ZCR_EL3]).len));
    }

    len = std::min(len, sveVL - 1);

    return (len + 1) * 128;
}

unsigned
ISA::getCurSmeVecLenInBits() const
{
    if (!FullSystem) {
        return smeVL * 128;
    }

    panic_if(!tc,
             "A ThreadContext is needed to determine the SME vector length "
             "in full-system mode");

    CPSR cpsr = miscRegs[MISCREG_CPSR];
    ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;

    unsigned len = 0;

    if (el == EL1 || (el == EL0 && !ELIsInHost(tc, el))) {
        len = static_cast<SMCR>(miscRegs[MISCREG_SMCR_EL1]).len;
    }

    if (el == EL2 || (el == EL0 && ELIsInHost(tc, el))) {
        len = static_cast<SMCR>(miscRegs[MISCREG_SMCR_EL2]).len;
    } else if (release->has(ArmExtension::VIRTUALIZATION) && !isSecure(tc) &&
               (el == EL0 || el == EL1)) {
        len = std::min(
            len,
            static_cast<unsigned>(
                static_cast<SMCR>(miscRegs[MISCREG_SMCR_EL2]).len));
    }

    if (el == EL3) {
        len = static_cast<SMCR>(miscRegs[MISCREG_SMCR_EL3]).len;
    } else if (release->has(ArmExtension::SECURITY)) {
        len = std::min(
            len,
            static_cast<unsigned>(
                static_cast<SMCR>(miscRegs[MISCREG_SMCR_EL3]).len));
    }

    len = std::min(len, smeVL - 1);

    // len + 1 must be a power of 2! Round down to the nearest whole power of
    // two.
    static const unsigned LUT[16] = {0, 1, 1, 3, 3, 3, 3, 7,
                                     7, 7, 7, 7, 7, 7, 7, 15};
    len = LUT[len];

    return (len + 1) * 128;
}

void
ISA::serialize(CheckpointOut &cp) const
{
    DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n");
    SERIALIZE_MAPPING(miscRegs, miscRegName, NUM_PHYS_MISCREGS);
}

void
ISA::unserialize(CheckpointIn &cp)
{
    DPRINTF(Checkpoint, "Unserializing Arm Misc Registers\n");
    UNSERIALIZE_MAPPING(miscRegs, miscRegName, NUM_PHYS_MISCREGS);

    for (auto idx = 0; idx < NUM_MISCREGS; idx++) {
        if (!lookUpMiscReg[idx].info[MISCREG_UNSERIALIZE] &&
            miscRegs[idx] != lookUpMiscReg[idx].reset()) {
            warn("Checkpoint value for register %s does not match "
                 "current configuration (checkpointed: %#x, current: %#x)",
                 miscRegName[idx], miscRegs[idx],
                 lookUpMiscReg[idx].reset());
            miscRegs[idx] = lookUpMiscReg[idx].reset();
        }
    }

    CPSR tmp_cpsr = miscRegs[MISCREG_CPSR];
    updateRegMap(tmp_cpsr);
}

void
ISA::addressTranslation64(MMU::ArmTranslationType tran_type,
    BaseMMU::Mode mode, Request::Flags flags, RegVal val)
{
    // If we're in timing mode then doing the translation in
    // functional mode then we're slightly distorting performance
    // results obtained from simulations. The translation should be
    // done in the same mode the core is running in. NOTE: This
    // can't be an atomic translation because that causes problems
    // with unexpected atomic snoop requests.
    warn_once("Doing AT (address translation) in functional mode! Fix Me!\n");

    auto req = std::make_shared<Request>(
        val, 0, flags,  Request::funcRequestorId,
        tc->pcState().instAddr(), tc->contextId());

    Fault fault = getMMUPtr(tc)->translateFunctional(
        req, tc, mode, tran_type);

    PAR par = 0;
    if (fault == NoFault) {
        Addr paddr = req->getPaddr();
        uint64_t attr = getMMUPtr(tc)->getAttr();
        uint64_t attr1 = attr >> 56;
        if (!attr1 || attr1 ==0x44) {
            attr |= 0x100;
            attr &= ~ uint64_t(0x80);
        }
        par = (paddr & mask(47, 12)) | attr;
        DPRINTF(MiscRegs,
              "MISCREG: Translated addr %#x: PAR_EL1: %#xx\n",
              val, par);
    } else {
        ArmFault *arm_fault = static_cast<ArmFault *>(fault.get());
        arm_fault->update(tc);
        // Set fault bit and FSR
        FSR fsr = arm_fault->getFsr(tc);

        par.f = 1; // F bit
        par.fst = fsr.status; // FST
        par.ptw = (arm_fault->iss() >> 7) & 0x1; // S1PTW
        par.s = arm_fault->isStage2() ? 1 : 0; // S

        DPRINTF(MiscRegs,
                "MISCREG: Translated addr %#x fault fsr %#x: PAR: %#x\n",
                val, fsr, par);
    }
    setMiscRegNoEffect(MISCREG_PAR_EL1, par);
    return;
}

void
ISA::addressTranslation(MMU::ArmTranslationType tran_type,
    BaseMMU::Mode mode, Request::Flags flags, RegVal val)
{
    // If we're in timing mode then doing the translation in
    // functional mode then we're slightly distorting performance
    // results obtained from simulations. The translation should be
    // done in the same mode the core is running in. NOTE: This
    // can't be an atomic translation because that causes problems
    // with unexpected atomic snoop requests.
    warn_once("Doing AT (address translation) in functional mode! Fix Me!\n");

    auto req = std::make_shared<Request>(
        val, 0, flags,  Request::funcRequestorId,
        tc->pcState().instAddr(), tc->contextId());

    Fault fault = getMMUPtr(tc)->translateFunctional(
        req, tc, mode, tran_type);

    PAR par = 0;
    if (fault == NoFault) {
        Addr paddr = req->getPaddr();
        TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
        HCR hcr = readMiscRegNoEffect(MISCREG_HCR_EL2);

        uint8_t max_paddr_bit = 0;
        if (release->has(ArmExtension::LPAE) &&
            (ttbcr.eae || tran_type & MMU::HypMode ||
            ((tran_type & MMU::S1S2NsTran) && hcr.vm) )) {

            max_paddr_bit = 39;
        } else {
            max_paddr_bit = 31;
        }

        par = (paddr & mask(max_paddr_bit, 12)) |
            (getMMUPtr(tc)->getAttr());

        DPRINTF(MiscRegs,
               "MISCREG: Translated addr 0x%08x: PAR: 0x%08x\n",
               val, par);
    } else {
        ArmFault *arm_fault = static_cast<ArmFault *>(fault.get());
        arm_fault->update(tc);
        // Set fault bit and FSR
        FSR fsr = arm_fault->getFsr(tc);

        par.f = 0x1; // F bit
        par.lpae = fsr.lpae;
        par.ptw = (arm_fault->iss() >> 7) & 0x1;
        par.s = arm_fault->isStage2() ? 1 : 0;

        if (par.lpae) {
            // LPAE - rearange fault status
            par.fst = fsr.status;
        } else {
            // VMSA - rearange fault status
            par.fs4_0 = fsr.fsLow | (fsr.fsHigh << 5);
            par.fs5 = fsr.ext;
        }
        DPRINTF(MiscRegs,
               "MISCREG: Translated addr 0x%08x fault fsr %#x: PAR: 0x%08x\n",
               val, fsr, par);
    }
    setMiscRegNoEffect(MISCREG_PAR, par);
    return;
}

template <class XC>
static inline void
lockedSnoopHandler(ThreadContext *tc, XC *xc, PacketPtr pkt,
        Addr cacheBlockMask)
{
    // Should only every see invalidations / direct writes
    assert(pkt->isInvalidate() || pkt->isWrite());

    DPRINTF(LLSC, "%s:  handling snoop for address: %#x locked: %d\n",
            tc->getCpuPtr()->name(), pkt->getAddr(),
            xc->readMiscReg(MISCREG_LOCKFLAG));
    if (!xc->readMiscReg(MISCREG_LOCKFLAG))
        return;

    Addr locked_addr = xc->readMiscReg(MISCREG_LOCKADDR) & cacheBlockMask;
    // If no caches are attached, the snoop address always needs to be masked
    Addr snoop_addr = pkt->getAddr() & cacheBlockMask;

    DPRINTF(LLSC, "%s:  handling snoop for address: %#x locked addr: %#x\n",
            tc->getCpuPtr()->name(), snoop_addr, locked_addr);
    if (locked_addr == snoop_addr) {
        DPRINTF(LLSC, "%s: address match, clearing lock and signaling sev\n",
                tc->getCpuPtr()->name());
        xc->setMiscReg(MISCREG_LOCKFLAG, false);
        // Implement ARMv8 WFE/SEV semantics
        sendEvent(tc);
        xc->setMiscReg(MISCREG_SEV_MAILBOX, true);
    }
}

void
ISA::handleLockedSnoop(PacketPtr pkt, Addr cacheBlockMask)
{
    lockedSnoopHandler(tc, tc, pkt, cacheBlockMask);
}

void
ISA::handleLockedSnoop(ExecContext *xc, PacketPtr pkt, Addr cacheBlockMask)
{
    lockedSnoopHandler(xc->tcBase(), xc, pkt, cacheBlockMask);
}

void
ISA::handleLockedRead(const RequestPtr &req)
{
    tc->setMiscReg(MISCREG_LOCKADDR, req->getPaddr());
    tc->setMiscReg(MISCREG_LOCKFLAG, true);
    DPRINTF(LLSC, "%s: Placing address %#x in monitor\n",
            tc->getCpuPtr()->name(), req->getPaddr());
}

void
ISA::handleLockedRead(ExecContext *xc, const RequestPtr &req)
{
    xc->setMiscReg(MISCREG_LOCKADDR, req->getPaddr());
    xc->setMiscReg(MISCREG_LOCKFLAG, true);
    DPRINTF(LLSC, "%s: Placing address %#x in monitor\n",
            xc->tcBase()->getCpuPtr()->name(), req->getPaddr());
}

void
ISA::handleLockedSnoopHit()
{
    DPRINTF(LLSC, "%s:  handling snoop lock hit address: %#x\n",
            tc->getCpuPtr()->name(), tc->readMiscReg(MISCREG_LOCKADDR));
    tc->setMiscReg(MISCREG_LOCKFLAG, false);
    tc->setMiscReg(MISCREG_SEV_MAILBOX, true);
}

void
ISA::handleLockedSnoopHit(ExecContext *xc)
{
    DPRINTF(LLSC, "%s:  handling snoop lock hit address: %#x\n",
            xc->tcBase()->getCpuPtr()->name(),
            xc->readMiscReg(MISCREG_LOCKADDR));
    xc->setMiscReg(MISCREG_LOCKFLAG, false);
    xc->setMiscReg(MISCREG_SEV_MAILBOX, true);
}

template <class XC>
static inline bool
lockedWriteHandler(ThreadContext *tc, XC *xc, const RequestPtr &req,
        Addr cacheBlockMask)
{
    if (req->isSwap())
        return true;

    DPRINTF(LLSC, "Handling locked write for address %#x in monitor.\n",
            req->getPaddr());
    // Verify that the lock flag is still set and the address
    // is correct
    bool lock_flag = xc->readMiscReg(MISCREG_LOCKFLAG);
    Addr lock_addr = xc->readMiscReg(MISCREG_LOCKADDR) & cacheBlockMask;
    if (!lock_flag || (req->getPaddr() & cacheBlockMask) != lock_addr) {
        // Lock flag not set or addr mismatch in CPU;
        // don't even bother sending to memory system
        req->setExtraData(0);
        xc->setMiscReg(MISCREG_LOCKFLAG, false);
        DPRINTF(LLSC, "clearing lock flag in handle locked write\n",
                tc->getCpuPtr()->name());
        // the rest of this code is not architectural;
        // it's just a debugging aid to help detect
        // livelock by warning on long sequences of failed
        // store conditionals
        int stCondFailures = xc->readStCondFailures();
        stCondFailures++;
        xc->setStCondFailures(stCondFailures);
        if (stCondFailures % 100000 == 0) {
            warn("context %d: %d consecutive "
                 "store conditional failures\n",
                 tc->contextId(), stCondFailures);
        }

        // store conditional failed already, so don't issue it to mem
        return false;
    }
    return true;
}

bool
ISA::handleLockedWrite(const RequestPtr &req, Addr cacheBlockMask)
{
    return lockedWriteHandler(tc, tc, req, cacheBlockMask);
}

bool
ISA::handleLockedWrite(ExecContext *xc, const RequestPtr &req,
        Addr cacheBlockMask)
{
    return lockedWriteHandler(xc->tcBase(), xc, req, cacheBlockMask);
}

void
ISA::globalClearExclusive()
{
    // A spinlock would typically include a Wait For Event (WFE) to
    // conserve energy. The ARMv8 architecture specifies that an event
    // is automatically generated when clearing the exclusive monitor
    // to wake up the processor in WFE.
    DPRINTF(LLSC, "Clearing lock and signaling sev\n");
    tc->setMiscReg(MISCREG_LOCKFLAG, false);
    // Implement ARMv8 WFE/SEV semantics
    sendEvent(tc);
    tc->setMiscReg(MISCREG_SEV_MAILBOX, true);
}

void
ISA::globalClearExclusive(ExecContext *xc)
{
    // A spinlock would typically include a Wait For Event (WFE) to
    // conserve energy. The ARMv8 architecture specifies that an event
    // is automatically generated when clearing the exclusive monitor
    // to wake up the processor in WFE.
    DPRINTF(LLSC, "Clearing lock and signaling sev\n");
    xc->setMiscReg(MISCREG_LOCKFLAG, false);
    // Implement ARMv8 WFE/SEV semantics
    sendEvent(xc->tcBase());
    xc->setMiscReg(MISCREG_SEV_MAILBOX, true);
}

} // namespace ArmISA
} // namespace gem5
