arch-arm: don't expose FEAT_VHE by default
[gem5.git] / src / arch / arm / isa.cc
index a4ebfc1dbd52047102145b03b32dae8fe61a884a..8adbdabdb0af1d8e111d39ce9724225e3e5d7bc8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2018 ARM Limited
+ * Copyright (c) 2010-2021 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
  * 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: Gabe Black
- *          Ali Saidi
  */
 
 #include "arch/arm/isa.hh"
+
+#include "arch/arm/faults.hh"
+#include "arch/arm/htm.hh"
+#include "arch/arm/interrupts.hh"
 #include "arch/arm/pmu.hh"
+#include "arch/arm/self_debug.hh"
 #include "arch/arm/system.hh"
 #include "arch/arm/tlb.hh"
 #include "arch/arm/tlbi_op.hh"
@@ -48,6 +50,8 @@
 #include "debug/Arm.hh"
 #include "debug/MiscRegs.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"
 namespace ArmISA
 {
 
-ISA::ISA(Params *p)
-    : SimObject(p),
-      system(NULL),
-      _decoderFlavour(p->decoderFlavour),
-      _vecRegRenameMode(p->vecRegRenameMode),
-      pmu(p->pmu),
-      impdefAsNop(p->impdef_nop)
+ISA::ISA(Params *p) : BaseISA(p), system(NULL),
+    _decoderFlavor(p->decoderFlavor), _vecRegRenameMode(Enums::Full),
+    pmu(p->pmu), impdefAsNop(p->impdef_nop),
+    afterStartup(false)
 {
     miscRegs[MISCREG_SCTLR_RST] = 0;
 
@@ -86,14 +87,33 @@ ISA::ISA(Params *p)
         haveVirtualization = system->haveVirtualization();
         haveLargeAsid64 = system->haveLargeAsid64();
         physAddrRange = system->physAddrRange();
+        haveSVE = system->haveSVE();
+        haveVHE = system->haveVHE();
+        havePAN = system->havePAN();
+        haveSecEL2 = system->haveSecEL2();
+        sveVL = system->sveVL();
+        haveLSE = system->haveLSE();
+        haveTME = system->haveTME();
     } else {
         highestELIs64 = true; // ArmSystem::highestELIs64 does the same
         haveSecurity = haveLPAE = haveVirtualization = false;
-        haveCrypto = false;
+        haveCrypto = true;
         haveLargeAsid64 = false;
         physAddrRange = 32;  // dummy value
+        haveSVE = true;
+        haveVHE = false;
+        havePAN = false;
+        haveSecEL2 = true;
+        sveVL = p->sve_vl_se;
+        haveLSE = true;
+        haveTME = true;
     }
 
+    // Initial rename mode depends on highestEL
+    const_cast<Enums::VecRegRenameMode&>(_vecRegRenameMode) =
+        highestELIs64 ? Enums::Full : Enums::Elem;
+
+    selfDebug = new SelfDebug();
     initializeMiscRegMetadata();
     preUnflattenMiscReg();
 
@@ -113,6 +133,12 @@ ISA::clear()
 {
     const Params *p(params());
 
+    // Invalidate cached copies of miscregs in the TLBs
+    if (tc) {
+        getITBPtr(tc)->invalidateMiscReg();
+        getDTBPtr(tc)->invalidateMiscReg();
+    }
+
     SCTLR sctlr_rst = miscRegs[MISCREG_SCTLR_RST];
     memset(miscRegs, 0, sizeof(miscRegs));
 
@@ -300,9 +326,20 @@ void
 ISA::initID32(const ArmISAParams *p)
 {
     // Initialize configurable default values
-    miscRegs[MISCREG_MIDR] = p->midr;
-    miscRegs[MISCREG_MIDR_EL1] = p->midr;
-    miscRegs[MISCREG_VPIDR] = p->midr;
+
+    uint32_t midr;
+    if (p->midr != 0x0)
+        midr = p->midr;
+    else if (highestELIs64)
+        // Cortex-A57 TRM r0p0 MIDR
+        midr = 0x410fd070;
+    else
+        // Cortex-A15 TRM r0p0 MIDR
+        midr = 0x410fc0f0;
+
+    miscRegs[MISCREG_MIDR] = midr;
+    miscRegs[MISCREG_MIDR_EL1] = midr;
+    miscRegs[MISCREG_VPIDR] = midr;
 
     miscRegs[MISCREG_ID_ISAR0] = p->id_isar0;
     miscRegs[MISCREG_ID_ISAR1] = p->id_isar1;
@@ -315,6 +352,10 @@ ISA::initID32(const ArmISAParams *p)
     miscRegs[MISCREG_ID_MMFR1] = p->id_mmfr1;
     miscRegs[MISCREG_ID_MMFR2] = p->id_mmfr2;
     miscRegs[MISCREG_ID_MMFR3] = p->id_mmfr3;
+
+    miscRegs[MISCREG_ID_ISAR5] = insertBits(
+        miscRegs[MISCREG_ID_ISAR5], 19, 4,
+        haveCrypto ? 0x1112 : 0x0);
 }
 
 void
@@ -339,6 +380,16 @@ ISA::initID64(const ArmISAParams *p)
 
     miscRegs[MISCREG_ID_DFR0] = miscRegs[MISCREG_ID_DFR0_EL1];
 
+    // SVE
+    miscRegs[MISCREG_ID_AA64ZFR0_EL1] = 0;  // SVEver 0
+    if (haveSecurity) {
+        miscRegs[MISCREG_ZCR_EL3] = sveVL - 1;
+    } else if (haveVirtualization) {
+        miscRegs[MISCREG_ZCR_EL2] = sveVL - 1;
+    } else {
+        miscRegs[MISCREG_ZCR_EL1] = sveVL - 1;
+    }
+
     // Enforce consistency with system-level settings...
 
     // EL3
@@ -349,6 +400,17 @@ ISA::initID64(const ArmISAParams *p)
     miscRegs[MISCREG_ID_AA64PFR0_EL1] = insertBits(
         miscRegs[MISCREG_ID_AA64PFR0_EL1], 11, 8,
         haveVirtualization ? 0x2 : 0x0);
+    // SVE
+    miscRegs[MISCREG_ID_AA64PFR0_EL1] = insertBits(
+        miscRegs[MISCREG_ID_AA64PFR0_EL1], 35, 32,
+        haveSVE ? 0x1 : 0x0);
+    // SecEL2
+    miscRegs[MISCREG_ID_AA64PFR0_EL1] = insertBits(
+        miscRegs[MISCREG_ID_AA64PFR0_EL1], 39, 36,
+        haveSecEL2 ? 0x1 : 0x0);
+    miscRegs[MISCREG_ID_AA64ISAR0_EL1] = insertBits(
+        miscRegs[MISCREG_ID_AA64ISAR0_EL1], 39, 36,
+        haveSecEL2 ? 0x1 : 0x0);
     // Large ASID support
     miscRegs[MISCREG_ID_AA64MMFR0_EL1] = insertBits(
         miscRegs[MISCREG_ID_AA64MMFR0_EL1], 7, 4,
@@ -361,17 +423,70 @@ ISA::initID64(const ArmISAParams *p)
     miscRegs[MISCREG_ID_AA64ISAR0_EL1] = insertBits(
         miscRegs[MISCREG_ID_AA64ISAR0_EL1], 19, 4,
         haveCrypto ? 0x1112 : 0x0);
+    // LSE
+    miscRegs[MISCREG_ID_AA64ISAR0_EL1] = insertBits(
+        miscRegs[MISCREG_ID_AA64ISAR0_EL1], 23, 20,
+        haveLSE ? 0x2 : 0x0);
+    // VHE
+    miscRegs[MISCREG_ID_AA64MMFR1_EL1] = insertBits(
+        miscRegs[MISCREG_ID_AA64MMFR1_EL1], 11, 8,
+        haveVHE ? 0x1 : 0x0);
+    // PAN
+    miscRegs[MISCREG_ID_AA64MMFR1_EL1] = insertBits(
+        miscRegs[MISCREG_ID_AA64MMFR1_EL1], 23, 20,
+        havePAN ? 0x1 : 0x0);
+    // TME
+    miscRegs[MISCREG_ID_AA64ISAR0_EL1] = insertBits(
+        miscRegs[MISCREG_ID_AA64ISAR0_EL1], 27, 24,
+        haveTME ? 0x1 : 0x0);
 }
 
 void
-ISA::startup(ThreadContext *tc)
+ISA::startup()
+{
+    BaseISA::startup();
+
+    if (tc) {
+        setupThreadContext();
+
+        if (haveTME) {
+            std::unique_ptr<BaseHTMCheckpoint> cpt(new HTMCheckpoint());
+            tc->setHtmCheckpointPtr(std::move(cpt));
+        }
+    }
+
+    afterStartup = true;
+}
+
+void
+ISA::setupThreadContext()
 {
     pmu->setThreadContext(tc);
 
+    if (!system)
+        return;
+
+    selfDebug->init(tc);
+
+    Gicv3 *gicv3 = dynamic_cast<Gicv3 *>(system->getGIC());
+    if (!gicv3)
+        return;
+
+    if (!gicv3CpuInterface)
+        gicv3CpuInterface.reset(gicv3->getCPUInterface(tc->contextId()));
+
+    gicv3CpuInterface->setISA(this);
+    gicv3CpuInterface->setThreadContext(tc);
 }
 
+void
+ISA::takeOverFrom(ThreadContext *new_tc, ThreadContext *old_tc)
+{
+    tc = new_tc;
+    setupThreadContext();
+}
 
-MiscReg
+RegVal
 ISA::readMiscRegNoEffect(int misc_reg) const
 {
     assert(misc_reg < NumMiscRegs);
@@ -395,8 +510,8 @@ ISA::readMiscRegNoEffect(int misc_reg) const
 }
 
 
-MiscReg
-ISA::readMiscReg(int misc_reg, ThreadContext *tc)
+RegVal
+ISA::readMiscReg(int misc_reg)
 {
     CPSR cpsr = 0;
     PCState pc = 0;
@@ -420,15 +535,14 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
                   miscRegName[misc_reg]);
     }
 #endif
+    misc_reg = redirectRegVHE(tc, misc_reg);
 
     switch (unflattenMiscReg(misc_reg)) {
       case MISCREG_HCR:
-        {
+      case MISCREG_HCR2:
             if (!haveVirtualization)
                 return 0;
-            else
-                return readMiscRegNoEffect(MISCREG_HCR);
-        }
+            break;
       case MISCREG_CPACR:
         {
             const uint32_t ones = (uint32_t)(-1);
@@ -450,25 +564,17 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
                     if (!nsacr.cp11) cpacrMask.cp11 = 0;
                 }
             }
-            MiscReg val = readMiscRegNoEffect(MISCREG_CPACR);
+            RegVal val = readMiscRegNoEffect(MISCREG_CPACR);
             val &= cpacrMask;
             DPRINTF(MiscRegs, "Reading misc reg %s: %#x\n",
                     miscRegName[misc_reg], val);
             return val;
         }
       case MISCREG_MPIDR:
-        cpsr = readMiscRegNoEffect(MISCREG_CPSR);
-        scr  = readMiscRegNoEffect(MISCREG_SCR);
-        if ((cpsr.mode == MODE_HYP) || inSecureState(scr, cpsr)) {
-            return getMPIDR(system, tc);
-        } else {
-            return readMiscReg(MISCREG_VMPIDR, tc);
-        }
-            break;
       case MISCREG_MPIDR_EL1:
-        // @todo in the absence of v8 virtualization support just return MPIDR_EL1
-        return getMPIDR(system, tc) & 0xffffffff;
+        return readMPIDR(system, tc);
       case MISCREG_VMPIDR:
+      case MISCREG_VMPIDR_EL2:
         // top bit defined as RES1
         return readMiscRegNoEffect(misc_reg) | 0x80000000;
       case MISCREG_ID_AFR0: // not implemented, so alias MIDR
@@ -476,7 +582,7 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
       case MISCREG_MIDR:
         cpsr = readMiscRegNoEffect(MISCREG_CPSR);
         scr  = readMiscRegNoEffect(MISCREG_SCR);
-        if ((cpsr.mode == MODE_HYP) || inSecureState(scr, cpsr)) {
+        if ((cpsr.mode == MODE_HYP) || isSecure(tc)) {
             return readMiscRegNoEffect(misc_reg);
         } else {
             return readMiscRegNoEffect(MISCREG_VPIDR);
@@ -565,6 +671,7 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
             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;
@@ -606,12 +713,16 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
         {
             return miscRegs[MISCREG_CPSR] & 0xc;
         }
+      case MISCREG_PAN:
+        {
+            return miscRegs[MISCREG_CPSR] & 0x400000;
+        }
       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()->numContexts() - 1;
+            l2ctlr.numCPUs = tc->getSystemPtr()->threads.size() - 1;
             return l2ctlr;
         }
       case MISCREG_DBGDIDR:
@@ -620,31 +731,37 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
          */
         return 0x5 << 16;
       case MISCREG_DBGDSCRint:
-        return 0;
+        return readMiscRegNoEffect(MISCREG_DBGDSCRint);
       case MISCREG_ISR:
-        return tc->getCpuPtr()->getInterruptController(tc->threadId())->getISR(
-            readMiscRegNoEffect(MISCREG_HCR),
-            readMiscRegNoEffect(MISCREG_CPSR),
-            readMiscRegNoEffect(MISCREG_SCR));
+        {
+            auto ic = dynamic_cast<ArmISA::Interrupts *>(
+                    tc->getCpuPtr()->getInterruptController(tc->threadId()));
+            return ic->getISR(
+                readMiscRegNoEffect(MISCREG_HCR),
+                readMiscRegNoEffect(MISCREG_CPSR),
+                readMiscRegNoEffect(MISCREG_SCR));
+        }
       case MISCREG_ISR_EL1:
-        return tc->getCpuPtr()->getInterruptController(tc->threadId())->getISR(
-            readMiscRegNoEffect(MISCREG_HCR_EL2),
-            readMiscRegNoEffect(MISCREG_CPSR),
-            readMiscRegNoEffect(MISCREG_SCR_EL3));
+        {
+            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_DCZID_EL0:
         return 0x04;  // DC ZVA clear 64-byte chunks
       case MISCREG_HCPTR:
         {
-            MiscReg val = readMiscRegNoEffect(misc_reg);
+            RegVal val = readMiscRegNoEffect(misc_reg);
             // The trap bit associated with CP14 is defined as RAZ
             val &= ~(1 << 14);
             // If a CP bit in NSACR is 0 then the corresponding bit in
             // HCPTR is RAO/WI
-            bool secure_lookup = haveSecurity &&
-                inSecureState(readMiscRegNoEffect(MISCREG_SCR),
-                              readMiscRegNoEffect(MISCREG_CPSR));
+            bool secure_lookup = haveSecurity && isSecure(tc);
             if (!secure_lookup) {
-                MiscReg mask = readMiscRegNoEffect(MISCREG_NSACR);
+                RegVal mask = readMiscRegNoEffect(MISCREG_NSACR);
                 val |= (mask ^ 0x7FFF) & 0xBFFF;
             }
             // Set the bits for unimplemented coprocessors to RAO/WI
@@ -655,16 +772,6 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
         return readMiscRegNoEffect(MISCREG_DFAR_S);
       case MISCREG_HIFAR: // alias for secure IFAR
         return readMiscRegNoEffect(MISCREG_IFAR_S);
-      case MISCREG_HVBAR: // bottom bits reserved
-        return readMiscRegNoEffect(MISCREG_HVBAR) & 0xFFFFFFE0;
-      case MISCREG_SCTLR:
-        return (readMiscRegNoEffect(misc_reg) & 0x72DD39FF) | 0x00C00818;
-      case MISCREG_SCTLR_EL1:
-        return (readMiscRegNoEffect(misc_reg) & 0x37DDDBBF) | 0x30D00800;
-      case MISCREG_SCTLR_EL2:
-      case MISCREG_SCTLR_EL3:
-      case MISCREG_HSCTLR:
-        return (readMiscRegNoEffect(misc_reg) & 0x32CD183F) | 0x30C50830;
 
       case MISCREG_ID_PFR0:
         // !ThumbEE | !Jazelle | Thumb | ARM
@@ -678,22 +785,25 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
                  | (haveTimer          ? 0x00010000 : 0x0);
         }
       case MISCREG_ID_AA64PFR0_EL1:
-        return 0x0000000000000002   // AArch{64,32} supported at EL0
-             | 0x0000000000000020                             // EL1
-             | (haveVirtualization ? 0x0000000000000200 : 0)  // EL2
-             | (haveSecurity       ? 0x0000000000002000 : 0); // EL3
+        return 0x0000000000000002 | // AArch{64,32} supported at EL0
+               0x0000000000000020                               | // EL1
+               (haveVirtualization    ? 0x0000000000000200 : 0) | // EL2
+               (haveSecurity          ? 0x0000000000002000 : 0) | // EL3
+               (haveSVE               ? 0x0000000100000000 : 0) | // SVE
+               (haveSecEL2            ? 0x0000001000000000 : 0) | // SecEL2
+               (gicv3CpuInterface     ? 0x0000000001000000 : 0);
       case MISCREG_ID_AA64PFR1_EL1:
         return 0; // bits [63:0] RES0 (reserved for future use)
 
       // Generic Timer registers
-      case MISCREG_CNTHV_CTL_EL2:
-      case MISCREG_CNTHV_CVAL_EL2:
-      case MISCREG_CNTHV_TVAL_EL2:
-      case MISCREG_CNTFRQ ... MISCREG_CNTHP_CTL:
-      case MISCREG_CNTPCT ... MISCREG_CNTHP_CVAL:
-      case MISCREG_CNTKCTL_EL1 ... MISCREG_CNTV_CVAL_EL0:
-      case MISCREG_CNTVOFF_EL2 ... MISCREG_CNTPS_CVAL_EL1:
-        return getGenericTimer(tc).readMiscReg(misc_reg);
+      case MISCREG_CNTFRQ ... MISCREG_CNTVOFF:
+      case MISCREG_CNTFRQ_EL0 ... MISCREG_CNTVOFF_EL2:
+        return getGenericTimer().readMiscReg(misc_reg);
+
+      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(misc_reg);
 
       default:
         break;
@@ -703,7 +813,7 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
 }
 
 void
-ISA::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
+ISA::setMiscRegNoEffect(int misc_reg, RegVal val)
 {
     assert(misc_reg < NumMiscRegs);
 
@@ -715,20 +825,20 @@ ISA::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
     if (upper > 0) {
         miscRegs[lower] = bits(v, 31, 0);
         miscRegs[upper] = bits(v, 63, 32);
-        DPRINTF(MiscRegs, "Writing to misc reg %d (%d:%d) : %#x\n",
-                misc_reg, lower, upper, v);
+        DPRINTF(MiscRegs, "Writing MiscReg %s (%d %d:%d) : %#x\n",
+                miscRegName[misc_reg], misc_reg, lower, upper, v);
     } else {
         miscRegs[lower] = v;
-        DPRINTF(MiscRegs, "Writing to misc reg %d (%d) : %#x\n",
-                misc_reg, lower, v);
+        DPRINTF(MiscRegs, "Writing MiscReg %s (%d %d) : %#x\n",
+                miscRegName[misc_reg], misc_reg, lower, v);
     }
 }
 
 void
-ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
+ISA::setMiscReg(int misc_reg, RegVal val)
 {
 
-    MiscReg newVal = val;
+    RegVal newVal = val;
     bool secure_lookup;
     SCR scr;
 
@@ -744,12 +854,19 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
             getDTBPtr(tc)->invalidateMiscReg();
         }
 
+        if (cpsr.pan != old_cpsr.pan) {
+            getDTBPtr(tc)->invalidateMiscReg();
+        }
+
         DPRINTF(Arm, "Updating CPSR from %#x to %#x f:%d i:%d a:%d mode:%#x\n",
                 miscRegs[misc_reg], cpsr, cpsr.f, cpsr.i, cpsr.a, cpsr.mode);
         PCState pc = tc->pcState();
         pc.nextThumb(cpsr.t);
         pc.nextJazelle(cpsr.j);
         pc.illegalExec(cpsr.il == 1);
+        selfDebug->setDebugMask(cpsr.d == 1);
+
+        tc->getDecoderPtr()->setSveLen((getCurSveVecLenInBits() >> 7) - 1);
 
         // Follow slightly different semantics if a CheckerCPU object
         // is connected
@@ -770,6 +887,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
                     miscRegName[misc_reg], val);
         }
 #endif
+        misc_reg = redirectRegVHE(tc, misc_reg);
+
         switch (unflattenMiscReg(misc_reg)) {
           case MISCREG_CPACR:
             {
@@ -794,13 +913,27 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
                     }
                 }
 
-                MiscReg old_val = readMiscRegNoEffect(MISCREG_CPACR);
+                RegVal old_val = readMiscRegNoEffect(MISCREG_CPACR);
                 newVal &= cpacrMask;
                 newVal |= old_val & ~cpacrMask;
                 DPRINTF(MiscRegs, "Writing misc reg %s: %#x\n",
                         miscRegName[misc_reg], newVal);
             }
             break;
+          case MISCREG_CPACR_EL1:
+            {
+                const uint32_t ones = (uint32_t)(-1);
+                CPACR cpacrMask = 0;
+                cpacrMask.tta = ones;
+                cpacrMask.fpen = ones;
+                if (haveSVE) {
+                    cpacrMask.zen = ones;
+                }
+                newVal &= cpacrMask;
+                DPRINTF(MiscRegs, "Writing misc reg %s: %#x\n",
+                        miscRegName[misc_reg], newVal);
+            }
+            break;
           case MISCREG_CPTR_EL2:
             {
                 const uint32_t ones = (uint32_t)(-1);
@@ -808,10 +941,17 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
                 cptrMask.tcpac = ones;
                 cptrMask.tta = ones;
                 cptrMask.tfp = ones;
+                if (haveSVE) {
+                    cptrMask.tz = ones;
+                }
                 newVal &= cptrMask;
                 cptrMask = 0;
                 cptrMask.res1_13_12_el2 = ones;
-                cptrMask.res1_9_0_el2 = ones;
+                cptrMask.res1_7_0_el2 = ones;
+                if (!haveSVE) {
+                    cptrMask.res1_8_el2 = ones;
+                }
+                cptrMask.res1_9_el2 = ones;
                 newVal |= cptrMask;
                 DPRINTF(MiscRegs, "Writing misc reg %s: %#x\n",
                         miscRegName[misc_reg], newVal);
@@ -824,6 +964,9 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
                 cptrMask.tcpac = ones;
                 cptrMask.tta = ones;
                 cptrMask.tfp = ones;
+                if (haveSVE) {
+                    cptrMask.ez = ones;
+                }
                 newVal &= cptrMask;
                 DPRINTF(MiscRegs, "Writing misc reg %s: %#x\n",
                         miscRegName[misc_reg], newVal);
@@ -854,6 +997,7 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
                 fpscrMask.ixe = ones;
                 fpscrMask.ide = ones;
                 fpscrMask.len = ones;
+                fpscrMask.fz16 = ones;
                 fpscrMask.stride = ones;
                 fpscrMask.rMode = ones;
                 fpscrMask.fz = ones;
@@ -896,6 +1040,7 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
                 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;
@@ -937,12 +1082,268 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
                          (readMiscRegNoEffect(MISCREG_FPEXC) & ~fpexcMask);
             }
             break;
+          case MISCREG_HCR2:
+                if (!haveVirtualization)
+                    return;
+                break;
           case MISCREG_HCR:
             {
+                const HDCR mdcr  = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
+                selfDebug->setenableTDETGE((HCR)val, mdcr);
                 if (!haveVirtualization)
                     return;
             }
             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:
+            selfDebug->updateDBGBCR(0, val);
+            break;
+          case MISCREG_DBGBCR1:
+            selfDebug->updateDBGBCR(1, val);
+            break;
+          case MISCREG_DBGBCR2:
+            selfDebug->updateDBGBCR(2, val);
+            break;
+          case MISCREG_DBGBCR3:
+            selfDebug->updateDBGBCR(3, val);
+            break;
+          case MISCREG_DBGBCR4:
+            selfDebug->updateDBGBCR(4, val);
+            break;
+          case MISCREG_DBGBCR5:
+            selfDebug->updateDBGBCR(5, val);
+            break;
+          case MISCREG_DBGBCR6:
+            selfDebug->updateDBGBCR(6, val);
+            break;
+          case MISCREG_DBGBCR7:
+            selfDebug->updateDBGBCR(7, val);
+            break;
+          case MISCREG_DBGBCR8:
+            selfDebug->updateDBGBCR(8, val);
+            break;
+          case MISCREG_DBGBCR9:
+            selfDebug->updateDBGBCR(9, val);
+            break;
+          case MISCREG_DBGBCR10:
+            selfDebug->updateDBGBCR(10, val);
+            break;
+          case MISCREG_DBGBCR11:
+            selfDebug->updateDBGBCR(11, val);
+            break;
+          case MISCREG_DBGBCR12:
+            selfDebug->updateDBGBCR(12, val);
+            break;
+          case MISCREG_DBGBCR13:
+            selfDebug->updateDBGBCR(13, val);
+            break;
+          case MISCREG_DBGBCR14:
+            selfDebug->updateDBGBCR(14, val);
+            break;
+          case MISCREG_DBGBCR15:
+            selfDebug->updateDBGBCR(15, val);
+            break;
+          case MISCREG_DBGWCR0:
+            selfDebug->updateDBGWCR(0, val);
+            break;
+          case MISCREG_DBGWCR1:
+            selfDebug->updateDBGWCR(1, val);
+            break;
+          case MISCREG_DBGWCR2:
+            selfDebug->updateDBGWCR(2, val);
+            break;
+          case MISCREG_DBGWCR3:
+            selfDebug->updateDBGWCR(3, val);
+            break;
+          case MISCREG_DBGWCR4:
+            selfDebug->updateDBGWCR(4, val);
+            break;
+          case MISCREG_DBGWCR5:
+            selfDebug->updateDBGWCR(5, val);
+            break;
+          case MISCREG_DBGWCR6:
+            selfDebug->updateDBGWCR(6, val);
+            break;
+          case MISCREG_DBGWCR7:
+            selfDebug->updateDBGWCR(7, val);
+            break;
+          case MISCREG_DBGWCR8:
+            selfDebug->updateDBGWCR(8, val);
+            break;
+          case MISCREG_DBGWCR9:
+            selfDebug->updateDBGWCR(9, val);
+            break;
+          case MISCREG_DBGWCR10:
+            selfDebug->updateDBGWCR(10, val);
+            break;
+          case MISCREG_DBGWCR11:
+            selfDebug->updateDBGWCR(11, val);
+            break;
+          case MISCREG_DBGWCR12:
+            selfDebug->updateDBGWCR(12, val);
+            break;
+          case MISCREG_DBGWCR13:
+            selfDebug->updateDBGWCR(13, val);
+            break;
+          case MISCREG_DBGWCR14:
+            selfDebug->updateDBGWCR(14, val);
+            break;
+          case MISCREG_DBGWCR15:
+            selfDebug->updateDBGWCR(15, 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:
+            selfDebug->updateDBGBCR(0, val);
+            break;
+          case MISCREG_DBGBCR1_EL1:
+            selfDebug->updateDBGBCR(1, val);
+            break;
+          case MISCREG_DBGBCR2_EL1:
+            selfDebug->updateDBGBCR(2, val);
+            break;
+          case MISCREG_DBGBCR3_EL1:
+            selfDebug->updateDBGBCR(3, val);
+            break;
+          case MISCREG_DBGBCR4_EL1:
+            selfDebug->updateDBGBCR(4, val);
+            break;
+          case MISCREG_DBGBCR5_EL1:
+            selfDebug->updateDBGBCR(5, val);
+            break;
+          case MISCREG_DBGBCR6_EL1:
+            selfDebug->updateDBGBCR(6, val);
+            break;
+          case MISCREG_DBGBCR7_EL1:
+            selfDebug->updateDBGBCR(7, val);
+            break;
+          case MISCREG_DBGBCR8_EL1:
+            selfDebug->updateDBGBCR(8, val);
+            break;
+          case MISCREG_DBGBCR9_EL1:
+            selfDebug->updateDBGBCR(9, val);
+            break;
+          case MISCREG_DBGBCR10_EL1:
+            selfDebug->updateDBGBCR(10, val);
+            break;
+          case MISCREG_DBGBCR11_EL1:
+            selfDebug->updateDBGBCR(11, val);
+            break;
+          case MISCREG_DBGBCR12_EL1:
+            selfDebug->updateDBGBCR(12, val);
+            break;
+          case MISCREG_DBGBCR13_EL1:
+            selfDebug->updateDBGBCR(13, val);
+            break;
+          case MISCREG_DBGBCR14_EL1:
+            selfDebug->updateDBGBCR(14, val);
+            break;
+          case MISCREG_DBGBCR15_EL1:
+            selfDebug->updateDBGBCR(15, val);
+            break;
+          case MISCREG_DBGWCR0_EL1:
+            selfDebug->updateDBGWCR(0, val);
+            break;
+          case MISCREG_DBGWCR1_EL1:
+            selfDebug->updateDBGWCR(1, val);
+            break;
+          case MISCREG_DBGWCR2_EL1:
+            selfDebug->updateDBGWCR(2, val);
+            break;
+          case MISCREG_DBGWCR3_EL1:
+            selfDebug->updateDBGWCR(3, val);
+            break;
+          case MISCREG_DBGWCR4_EL1:
+            selfDebug->updateDBGWCR(4, val);
+            break;
+          case MISCREG_DBGWCR5_EL1:
+            selfDebug->updateDBGWCR(5, val);
+            break;
+          case MISCREG_DBGWCR6_EL1:
+            selfDebug->updateDBGWCR(6, val);
+            break;
+          case MISCREG_DBGWCR7_EL1:
+            selfDebug->updateDBGWCR(7, val);
+            break;
+          case MISCREG_DBGWCR8_EL1:
+            selfDebug->updateDBGWCR(8, val);
+            break;
+          case MISCREG_DBGWCR9_EL1:
+            selfDebug->updateDBGWCR(9, val);
+            break;
+          case MISCREG_DBGWCR10_EL1:
+            selfDebug->updateDBGWCR(10, val);
+            break;
+          case MISCREG_DBGWCR11_EL1:
+            selfDebug->updateDBGWCR(11, val);
+            break;
+          case MISCREG_DBGWCR12_EL1:
+            selfDebug->updateDBGWCR(12, val);
+            break;
+          case MISCREG_DBGWCR13_EL1:
+            selfDebug->updateDBGWCR(13, val);
+            break;
+          case MISCREG_DBGWCR14_EL1:
+            selfDebug->updateDBGWCR(14, val);
+            break;
+          case MISCREG_DBGWCR15_EL1:
+            selfDebug->updateDBGWCR(15, val);
+            break;
           case MISCREG_IFSR:
             {
                 // ARM ARM (ARM DDI 0406C.b) B4.1.96
@@ -987,7 +1388,7 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
                 SCTLR sctlr = miscRegs[sctlr_idx];
                 SCTLR new_sctlr = newVal;
                 new_sctlr.nmfi =  ((bool)sctlr.nmfi) && !haveVirtualization;
-                miscRegs[sctlr_idx] = (MiscReg)new_sctlr;
+                miscRegs[sctlr_idx] = (RegVal)new_sctlr;
                 getITBPtr(tc)->invalidateMiscReg();
                 getDTBPtr(tc)->invalidateMiscReg();
             }
@@ -1029,8 +1430,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           // TLB Invalidate All
           case MISCREG_TLBIALL: // TLBI all entries, EL0&1,
             {
-                assert32(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert32();
+                scr = readMiscReg(MISCREG_SCR);
 
                 TLBIALL tlbiOp(EL1, haveSecurity && !scr.ns);
                 tlbiOp(tc);
@@ -1039,8 +1440,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           // TLB Invalidate All, Inner Shareable
           case MISCREG_TLBIALLIS:
             {
-                assert32(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert32();
+                scr = readMiscReg(MISCREG_SCR);
 
                 TLBIALL tlbiOp(EL1, haveSecurity && !scr.ns);
                 tlbiOp.broadcast(tc);
@@ -1049,8 +1450,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           // Instruction TLB Invalidate All
           case MISCREG_ITLBIALL:
             {
-                assert32(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert32();
+                scr = readMiscReg(MISCREG_SCR);
 
                 ITLBIALL tlbiOp(EL1, haveSecurity && !scr.ns);
                 tlbiOp(tc);
@@ -1059,8 +1460,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           // Data TLB Invalidate All
           case MISCREG_DTLBIALL:
             {
-                assert32(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert32();
+                scr = readMiscReg(MISCREG_SCR);
 
                 DTLBIALL tlbiOp(EL1, haveSecurity && !scr.ns);
                 tlbiOp(tc);
@@ -1073,8 +1474,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_TLBIMVA:
           case MISCREG_TLBIMVAL:
             {
-                assert32(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert32();
+                scr = readMiscReg(MISCREG_SCR);
 
                 TLBIMVA tlbiOp(EL1,
                                haveSecurity && !scr.ns,
@@ -1088,8 +1489,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_TLBIMVAIS:
           case MISCREG_TLBIMVALIS:
             {
-                assert32(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert32();
+                scr = readMiscReg(MISCREG_SCR);
 
                 TLBIMVA tlbiOp(EL1,
                                haveSecurity && !scr.ns,
@@ -1102,8 +1503,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           // TLB Invalidate by ASID match
           case MISCREG_TLBIASID:
             {
-                assert32(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert32();
+                scr = readMiscReg(MISCREG_SCR);
 
                 TLBIASID tlbiOp(EL1,
                                 haveSecurity && !scr.ns,
@@ -1115,8 +1516,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           // TLB Invalidate by ASID match, Inner Shareable
           case MISCREG_TLBIASIDIS:
             {
-                assert32(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert32();
+                scr = readMiscReg(MISCREG_SCR);
 
                 TLBIASID tlbiOp(EL1,
                                 haveSecurity && !scr.ns,
@@ -1132,11 +1533,11 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_TLBIMVAA:
           case MISCREG_TLBIMVAAL:
             {
-                assert32(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert32();
+                scr = readMiscReg(MISCREG_SCR);
 
                 TLBIMVAA tlbiOp(EL1, haveSecurity && !scr.ns,
-                                mbits(newVal, 31,12), false);
+                                mbits(newVal, 31,12));
 
                 tlbiOp(tc);
                 return;
@@ -1145,11 +1546,11 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_TLBIMVAAIS:
           case MISCREG_TLBIMVAALIS:
             {
-                assert32(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert32();
+                scr = readMiscReg(MISCREG_SCR);
 
                 TLBIMVAA tlbiOp(EL1, haveSecurity && !scr.ns,
-                                mbits(newVal, 31,12), false);
+                                mbits(newVal, 31,12));
 
                 tlbiOp.broadcast(tc);
                 return;
@@ -1161,11 +1562,11 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_TLBIMVAH:
           case MISCREG_TLBIMVALH:
             {
-                assert32(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert32();
+                scr = readMiscReg(MISCREG_SCR);
 
-                TLBIMVAA tlbiOp(EL1, haveSecurity && !scr.ns,
-                                mbits(newVal, 31,12), true);
+                TLBIMVAA tlbiOp(EL2, haveSecurity && !scr.ns,
+                                mbits(newVal, 31,12));
 
                 tlbiOp(tc);
                 return;
@@ -1174,11 +1575,11 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_TLBIMVAHIS:
           case MISCREG_TLBIMVALHIS:
             {
-                assert32(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert32();
+                scr = readMiscReg(MISCREG_SCR);
 
-                TLBIMVAA tlbiOp(EL1, haveSecurity && !scr.ns,
-                                mbits(newVal, 31,12), true);
+                TLBIMVAA tlbiOp(EL2, haveSecurity && !scr.ns,
+                                mbits(newVal, 31,12));
 
                 tlbiOp.broadcast(tc);
                 return;
@@ -1190,8 +1591,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_TLBIIPAS2:
           case MISCREG_TLBIIPAS2L:
             {
-                assert32(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert32();
+                scr = readMiscReg(MISCREG_SCR);
 
                 TLBIIPA tlbiOp(EL1,
                                haveSecurity && !scr.ns,
@@ -1205,8 +1606,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_TLBIIPAS2IS:
           case MISCREG_TLBIIPAS2LIS:
             {
-                assert32(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert32();
+                scr = readMiscReg(MISCREG_SCR);
 
                 TLBIIPA tlbiOp(EL1,
                                haveSecurity && !scr.ns,
@@ -1218,8 +1619,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           // Instruction TLB Invalidate by VA
           case MISCREG_ITLBIMVA:
             {
-                assert32(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert32();
+                scr = readMiscReg(MISCREG_SCR);
 
                 ITLBIMVA tlbiOp(EL1,
                                 haveSecurity && !scr.ns,
@@ -1232,8 +1633,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           // Data TLB Invalidate by VA
           case MISCREG_DTLBIMVA:
             {
-                assert32(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert32();
+                scr = readMiscReg(MISCREG_SCR);
 
                 DTLBIMVA tlbiOp(EL1,
                                 haveSecurity && !scr.ns,
@@ -1246,8 +1647,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           // Instruction TLB Invalidate by ASID match
           case MISCREG_ITLBIASID:
             {
-                assert32(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert32();
+                scr = readMiscReg(MISCREG_SCR);
 
                 ITLBIASID tlbiOp(EL1,
                                  haveSecurity && !scr.ns,
@@ -1259,8 +1660,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           // Data TLB Invalidate by ASID match
           case MISCREG_DTLBIASID:
             {
-                assert32(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert32();
+                scr = readMiscReg(MISCREG_SCR);
 
                 DTLBIASID tlbiOp(EL1,
                                  haveSecurity && !scr.ns,
@@ -1272,43 +1673,43 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           // TLB Invalidate All, Non-Secure Non-Hyp
           case MISCREG_TLBIALLNSNH:
             {
-                assert32(tc);
+                assert32();
 
-                TLBIALLN tlbiOp(EL1, false);
+                TLBIALLN tlbiOp(EL1);
                 tlbiOp(tc);
                 return;
             }
           // TLB Invalidate All, Non-Secure Non-Hyp, Inner Shareable
           case MISCREG_TLBIALLNSNHIS:
             {
-                assert32(tc);
+                assert32();
 
-                TLBIALLN tlbiOp(EL1, false);
+                TLBIALLN tlbiOp(EL1);
                 tlbiOp.broadcast(tc);
                 return;
             }
           // TLB Invalidate All, Hyp mode
           case MISCREG_TLBIALLH:
             {
-                assert32(tc);
+                assert32();
 
-                TLBIALLN tlbiOp(EL1, true);
+                TLBIALLN tlbiOp(EL2);
                 tlbiOp(tc);
                 return;
             }
           // TLB Invalidate All, Hyp mode, Inner Shareable
           case MISCREG_TLBIALLHIS:
             {
-                assert32(tc);
+                assert32();
 
-                TLBIALLN tlbiOp(EL1, true);
+                TLBIALLN tlbiOp(EL2);
                 tlbiOp.broadcast(tc);
                 return;
             }
           // AArch64 TLB Invalidate All, EL3
           case MISCREG_TLBI_ALLE3:
             {
-                assert64(tc);
+                assert64();
 
                 TLBIALL tlbiOp(EL3, true);
                 tlbiOp(tc);
@@ -1317,41 +1718,73 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           // AArch64 TLB Invalidate All, EL3, Inner Shareable
           case MISCREG_TLBI_ALLE3IS:
             {
-                assert64(tc);
+                assert64();
 
                 TLBIALL tlbiOp(EL3, true);
                 tlbiOp.broadcast(tc);
                 return;
             }
-          // @todo: uncomment this to enable Virtualization
-          // case MISCREG_TLBI_ALLE2IS:
-          // case MISCREG_TLBI_ALLE2:
+          // AArch64 TLB Invalidate All, EL2, Inner Shareable
+          case MISCREG_TLBI_ALLE2:
+          case MISCREG_TLBI_ALLE2IS:
+            {
+                assert64();
+                scr = readMiscReg(MISCREG_SCR);
+
+                TLBIALL tlbiOp(EL2, haveSecurity && !scr.ns);
+                tlbiOp(tc);
+                return;
+            }
           // AArch64 TLB Invalidate All, EL1
           case MISCREG_TLBI_ALLE1:
-          case MISCREG_TLBI_VMALLE1:
           case MISCREG_TLBI_VMALLS12E1:
             // @todo: handle VMID and stage 2 to enable Virtualization
             {
-                assert64(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert64();
+                scr = readMiscReg(MISCREG_SCR);
 
                 TLBIALL tlbiOp(EL1, haveSecurity && !scr.ns);
                 tlbiOp(tc);
                 return;
             }
+          case MISCREG_TLBI_VMALLE1:
+            // @todo: handle VMID and stage 2 to enable Virtualization
+            {
+                assert64();
+                scr = readMiscReg(MISCREG_SCR);
+
+                HCR hcr = readMiscReg(MISCREG_HCR_EL2);
+                bool is_host = (hcr.tge && hcr.e2h);
+                ExceptionLevel target_el = is_host ?  EL2 : EL1;
+                TLBIALL tlbiOp(target_el, haveSecurity && !scr.ns);
+                tlbiOp(tc);
+                return;
+            }
           // AArch64 TLB Invalidate All, EL1, Inner Shareable
           case MISCREG_TLBI_ALLE1IS:
-          case MISCREG_TLBI_VMALLE1IS:
           case MISCREG_TLBI_VMALLS12E1IS:
             // @todo: handle VMID and stage 2 to enable Virtualization
             {
-                assert64(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert64();
+                scr = readMiscReg(MISCREG_SCR);
 
                 TLBIALL tlbiOp(EL1, haveSecurity && !scr.ns);
                 tlbiOp.broadcast(tc);
                 return;
             }
+          case MISCREG_TLBI_VMALLE1IS:
+            // @todo: handle VMID and stage 2 to enable Virtualization
+            {
+                assert64();
+                scr = readMiscReg(MISCREG_SCR);
+
+                HCR hcr = readMiscReg(MISCREG_HCR_EL2);
+                bool is_host = (hcr.tge && hcr.e2h);
+                ExceptionLevel target_el = is_host ?  EL2 : EL1;
+                TLBIALL tlbiOp(target_el, haveSecurity && !scr.ns);
+                tlbiOp.broadcast(tc);
+                return;
+            }
           // VAEx(IS) and VALEx(IS) are the same because TLBs
           // only store entries
           // from the last level of translation table walks
@@ -1360,7 +1793,7 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_TLBI_VAE3_Xt:
           case MISCREG_TLBI_VALE3_Xt:
             {
-                assert64(tc);
+                assert64();
 
                 TLBIMVA tlbiOp(EL3, true,
                                static_cast<Addr>(bits(newVal, 43, 0)) << 12,
@@ -1372,7 +1805,7 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_TLBI_VAE3IS_Xt:
           case MISCREG_TLBI_VALE3IS_Xt:
             {
-                assert64(tc);
+                assert64();
 
                 TLBIMVA tlbiOp(EL3, true,
                                static_cast<Addr>(bits(newVal, 43, 0)) << 12,
@@ -1385,8 +1818,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_TLBI_VAE2_Xt:
           case MISCREG_TLBI_VALE2_Xt:
             {
-                assert64(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert64();
+                scr = readMiscReg(MISCREG_SCR);
 
                 TLBIMVA tlbiOp(EL2, haveSecurity && !scr.ns,
                                static_cast<Addr>(bits(newVal, 43, 0)) << 12,
@@ -1398,8 +1831,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_TLBI_VAE2IS_Xt:
           case MISCREG_TLBI_VALE2IS_Xt:
             {
-                assert64(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert64();
+                scr = readMiscReg(MISCREG_SCR);
 
                 TLBIMVA tlbiOp(EL2, haveSecurity && !scr.ns,
                                static_cast<Addr>(bits(newVal, 43, 0)) << 12,
@@ -1412,12 +1845,15 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_TLBI_VAE1_Xt:
           case MISCREG_TLBI_VALE1_Xt:
             {
-                assert64(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert64();
+                scr = readMiscReg(MISCREG_SCR);
                 auto asid = haveLargeAsid64 ? bits(newVal, 63, 48) :
                                               bits(newVal, 55, 48);
 
-                TLBIMVA tlbiOp(EL1, haveSecurity && !scr.ns,
+                HCR hcr = readMiscReg(MISCREG_HCR_EL2);
+                bool is_host = (hcr.tge && hcr.e2h);
+                ExceptionLevel target_el = is_host ?  EL2 : EL1;
+                TLBIMVA tlbiOp(target_el, haveSecurity && !scr.ns,
                                static_cast<Addr>(bits(newVal, 43, 0)) << 12,
                                asid);
 
@@ -1428,14 +1864,17 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_TLBI_VAE1IS_Xt:
           case MISCREG_TLBI_VALE1IS_Xt:
             {
-                assert64(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert64();
+                scr = readMiscReg(MISCREG_SCR);
                 auto asid = haveLargeAsid64 ? bits(newVal, 63, 48) :
                                               bits(newVal, 55, 48);
 
-                TLBIMVA tlbiOp(EL1, haveSecurity && !scr.ns,
-                               static_cast<Addr>(bits(newVal, 43, 0)) << 12,
-                               asid);
+                HCR hcr = readMiscReg(MISCREG_HCR_EL2);
+                bool is_host = (hcr.tge && hcr.e2h);
+                ExceptionLevel target_el = is_host ?  EL2 : EL1;
+                TLBIMVA tlbiOp(target_el, haveSecurity && !scr.ns,
+                                static_cast<Addr>(bits(newVal, 43, 0)) << 12,
+                                asid);
 
                 tlbiOp.broadcast(tc);
                 return;
@@ -1444,24 +1883,30 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           // @todo: handle VMID to enable Virtualization
           case MISCREG_TLBI_ASIDE1_Xt:
             {
-                assert64(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert64();
+                scr = readMiscReg(MISCREG_SCR);
                 auto asid = haveLargeAsid64 ? bits(newVal, 63, 48) :
                                               bits(newVal, 55, 48);
 
-                TLBIASID tlbiOp(EL1, haveSecurity && !scr.ns, asid);
+                HCR hcr = readMiscReg(MISCREG_HCR_EL2);
+                bool is_host = (hcr.tge && hcr.e2h);
+                ExceptionLevel target_el = is_host ?  EL2 : EL1;
+                TLBIASID tlbiOp(target_el, haveSecurity && !scr.ns, asid);
                 tlbiOp(tc);
                 return;
             }
           // AArch64 TLB Invalidate by ASID, EL1, Inner Shareable
           case MISCREG_TLBI_ASIDE1IS_Xt:
             {
-                assert64(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert64();
+                scr = readMiscReg(MISCREG_SCR);
                 auto asid = haveLargeAsid64 ? bits(newVal, 63, 48) :
                                               bits(newVal, 55, 48);
 
-                TLBIASID tlbiOp(EL1, haveSecurity && !scr.ns, asid);
+                HCR hcr = readMiscReg(MISCREG_HCR_EL2);
+                bool is_host = (hcr.tge && hcr.e2h);
+                ExceptionLevel target_el = is_host ?  EL2 : EL1;
+                TLBIASID tlbiOp(target_el, haveSecurity && !scr.ns, asid);
                 tlbiOp.broadcast(tc);
                 return;
             }
@@ -1471,11 +1916,14 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_TLBI_VAAE1_Xt:
           case MISCREG_TLBI_VAALE1_Xt:
             {
-                assert64(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert64();
+                scr = readMiscReg(MISCREG_SCR);
 
-                TLBIMVAA tlbiOp(EL1, haveSecurity && !scr.ns,
-                    static_cast<Addr>(bits(newVal, 43, 0)) << 12, false);
+                HCR hcr = readMiscReg(MISCREG_HCR_EL2);
+                bool is_host = (hcr.tge && hcr.e2h);
+                ExceptionLevel target_el = is_host ?  EL2 : EL1;
+                TLBIMVAA tlbiOp(target_el, haveSecurity && !scr.ns,
+                    static_cast<Addr>(bits(newVal, 43, 0)) << 12);
 
                 tlbiOp(tc);
                 return;
@@ -1484,11 +1932,14 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_TLBI_VAAE1IS_Xt:
           case MISCREG_TLBI_VAALE1IS_Xt:
             {
-                assert64(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert64();
+                scr = readMiscReg(MISCREG_SCR);
 
-                TLBIMVAA tlbiOp(EL1, haveSecurity && !scr.ns,
-                    static_cast<Addr>(bits(newVal, 43, 0)) << 12, false);
+                HCR hcr = readMiscReg(MISCREG_HCR_EL2);
+                bool is_host = (hcr.tge && hcr.e2h);
+                ExceptionLevel target_el = is_host ?  EL2 : EL1;
+                TLBIMVAA tlbiOp(target_el, haveSecurity && !scr.ns,
+                    static_cast<Addr>(bits(newVal, 43, 0)) << 12);
 
                 tlbiOp.broadcast(tc);
                 return;
@@ -1498,8 +1949,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_TLBI_IPAS2E1_Xt:
           case MISCREG_TLBI_IPAS2LE1_Xt:
             {
-                assert64(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert64();
+                scr = readMiscReg(MISCREG_SCR);
 
                 TLBIIPA tlbiOp(EL1, haveSecurity && !scr.ns,
                                static_cast<Addr>(bits(newVal, 35, 0)) << 12);
@@ -1512,8 +1963,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_TLBI_IPAS2E1IS_Xt:
           case MISCREG_TLBI_IPAS2LE1IS_Xt:
             {
-                assert64(tc);
-                scr = readMiscReg(MISCREG_SCR, tc);
+                assert64();
+                scr = readMiscReg(MISCREG_SCR);
 
                 TLBIIPA tlbiOp(EL1, haveSecurity && !scr.ns,
                                static_cast<Addr>(bits(newVal, 35, 0)) << 12);
@@ -1544,12 +1995,11 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
             {
                 // If a CP bit in NSACR is 0 then the corresponding bit in
                 // HCPTR is RAO/WI. Same applies to NSASEDIS
-                secure_lookup = haveSecurity &&
-                    inSecureState(readMiscRegNoEffect(MISCREG_SCR),
-                                  readMiscRegNoEffect(MISCREG_CPSR));
+                secure_lookup = haveSecurity && isSecure(tc);
                 if (!secure_lookup) {
-                    MiscReg oldValue = readMiscRegNoEffect(MISCREG_HCPTR);
-                    MiscReg mask = (readMiscRegNoEffect(MISCREG_NSACR) ^ 0x7FFF) & 0xBFFF;
+                    RegVal oldValue = readMiscRegNoEffect(MISCREG_HCPTR);
+                    RegVal mask =
+                        (readMiscRegNoEffect(MISCREG_NSACR) ^ 0x7FFF) & 0xBFFF;
                     newVal = (newVal & ~mask) | (oldValue & mask);
                 }
                 break;
@@ -1561,139 +2011,47 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
             misc_reg = MISCREG_IFAR_S;
             break;
           case MISCREG_ATS1CPR:
+            addressTranslation(TLB::S1CTran, BaseTLB::Read, 0, val);
+            return;
           case MISCREG_ATS1CPW:
+            addressTranslation(TLB::S1CTran, BaseTLB::Write, 0, val);
+            return;
           case MISCREG_ATS1CUR:
+            addressTranslation(TLB::S1CTran, BaseTLB::Read,
+                TLB::UserMode, val);
+            return;
           case MISCREG_ATS1CUW:
+            addressTranslation(TLB::S1CTran, BaseTLB::Write,
+                TLB::UserMode, val);
+            return;
           case MISCREG_ATS12NSOPR:
+            if (!haveSecurity)
+                panic("Security Extensions required for ATS12NSOPR");
+            addressTranslation(TLB::S1S2NsTran, BaseTLB::Read, 0, val);
+            return;
           case MISCREG_ATS12NSOPW:
+            if (!haveSecurity)
+                panic("Security Extensions required for ATS12NSOPW");
+            addressTranslation(TLB::S1S2NsTran, BaseTLB::Write, 0, val);
+            return;
           case MISCREG_ATS12NSOUR:
+            if (!haveSecurity)
+                panic("Security Extensions required for ATS12NSOUR");
+            addressTranslation(TLB::S1S2NsTran, BaseTLB::Read,
+                TLB::UserMode, val);
+            return;
           case MISCREG_ATS12NSOUW:
+            if (!haveSecurity)
+                panic("Security Extensions required for ATS12NSOUW");
+            addressTranslation(TLB::S1S2NsTran, BaseTLB::Write,
+                TLB::UserMode, val);
+            return;
           case MISCREG_ATS1HR:
+            addressTranslation(TLB::HypMode, BaseTLB::Read, 0, val);
+            return;
           case MISCREG_ATS1HW:
-            {
-              Request::Flags flags = 0;
-              BaseTLB::Mode mode = BaseTLB::Read;
-              TLB::ArmTranslationType tranType = TLB::NormalTran;
-              Fault fault;
-              switch(misc_reg) {
-                case MISCREG_ATS1CPR:
-                  flags    = TLB::MustBeOne;
-                  tranType = TLB::S1CTran;
-                  mode     = BaseTLB::Read;
-                  break;
-                case MISCREG_ATS1CPW:
-                  flags    = TLB::MustBeOne;
-                  tranType = TLB::S1CTran;
-                  mode     = BaseTLB::Write;
-                  break;
-                case MISCREG_ATS1CUR:
-                  flags    = TLB::MustBeOne | TLB::UserMode;
-                  tranType = TLB::S1CTran;
-                  mode     = BaseTLB::Read;
-                  break;
-                case MISCREG_ATS1CUW:
-                  flags    = TLB::MustBeOne | TLB::UserMode;
-                  tranType = TLB::S1CTran;
-                  mode     = BaseTLB::Write;
-                  break;
-                case MISCREG_ATS12NSOPR:
-                  if (!haveSecurity)
-                      panic("Security Extensions required for ATS12NSOPR");
-                  flags    = TLB::MustBeOne;
-                  tranType = TLB::S1S2NsTran;
-                  mode     = BaseTLB::Read;
-                  break;
-                case MISCREG_ATS12NSOPW:
-                  if (!haveSecurity)
-                      panic("Security Extensions required for ATS12NSOPW");
-                  flags    = TLB::MustBeOne;
-                  tranType = TLB::S1S2NsTran;
-                  mode     = BaseTLB::Write;
-                  break;
-                case MISCREG_ATS12NSOUR:
-                  if (!haveSecurity)
-                      panic("Security Extensions required for ATS12NSOUR");
-                  flags    = TLB::MustBeOne | TLB::UserMode;
-                  tranType = TLB::S1S2NsTran;
-                  mode     = BaseTLB::Read;
-                  break;
-                case MISCREG_ATS12NSOUW:
-                  if (!haveSecurity)
-                      panic("Security Extensions required for ATS12NSOUW");
-                  flags    = TLB::MustBeOne | TLB::UserMode;
-                  tranType = TLB::S1S2NsTran;
-                  mode     = BaseTLB::Write;
-                  break;
-                case MISCREG_ATS1HR: // only really useful from secure mode.
-                  flags    = TLB::MustBeOne;
-                  tranType = TLB::HypMode;
-                  mode     = BaseTLB::Read;
-                  break;
-                case MISCREG_ATS1HW:
-                  flags    = TLB::MustBeOne;
-                  tranType = TLB::HypMode;
-                  mode     = BaseTLB::Write;
-                  break;
-              }
-              // 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("Translating via %s in functional mode! Fix Me!\n",
-                   miscRegName[misc_reg]);
-
-              auto req = std::make_shared<Request>(
-                  0, val, 0, flags,  Request::funcMasterId,
-                  tc->pcState().pc(), tc->contextId());
-
-              fault = getDTBPtr(tc)->translateFunctional(
-                      req, tc, mode, tranType);
-
-              TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
-              HCR   hcr   = readMiscRegNoEffect(MISCREG_HCR);
-
-              MiscReg newVal;
-              if (fault == NoFault) {
-                  Addr paddr = req->getPaddr();
-                  if (haveLPAE && (ttbcr.eae || tranType & TLB::HypMode ||
-                     ((tranType & TLB::S1S2NsTran) && hcr.vm) )) {
-                      newVal = (paddr & mask(39, 12)) |
-                               (getDTBPtr(tc)->getAttr());
-                  } else {
-                      newVal = (paddr & 0xfffff000) |
-                               (getDTBPtr(tc)->getAttr());
-                  }
-                  DPRINTF(MiscRegs,
-                          "MISCREG: Translated addr 0x%08x: PAR: 0x%08x\n",
-                          val, newVal);
-              } else {
-                  ArmFault *armFault = static_cast<ArmFault *>(fault.get());
-                  armFault->update(tc);
-                  // Set fault bit and FSR
-                  FSR fsr = armFault->getFsr(tc);
-
-                  newVal = ((fsr >> 9) & 1) << 11;
-                  if (newVal) {
-                    // LPAE - rearange fault status
-                    newVal |= ((fsr >>  0) & 0x3f) << 1;
-                  } else {
-                    // VMSA - rearange fault status
-                    newVal |= ((fsr >>  0) & 0xf) << 1;
-                    newVal |= ((fsr >> 10) & 0x1) << 5;
-                    newVal |= ((fsr >> 12) & 0x1) << 6;
-                  }
-                  newVal |= 0x1; // F bit
-                  newVal |= ((armFault->iss() >> 7) & 0x1) << 8;
-                  newVal |= armFault->isStage2() ? 0x200 : 0;
-                  DPRINTF(MiscRegs,
-                          "MISCREG: Translated addr 0x%08x fault fsr %#x: PAR: 0x%08x\n",
-                          val, fsr, newVal);
-              }
-              setMiscRegNoEffect(MISCREG_PAR, newVal);
-              return;
-            }
+            addressTranslation(TLB::HypMode, BaseTLB::Write, 0, val);
+            return;
           case MISCREG_TTBCR:
             {
                 TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
@@ -1756,7 +2114,6 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
           case MISCREG_DACR:
           case MISCREG_VTTBR:
           case MISCREG_SCR_EL3:
-          case MISCREG_HCR_EL2:
           case MISCREG_TCR_EL1:
           case MISCREG_TCR_EL2:
           case MISCREG_TCR_EL3:
@@ -1771,6 +2128,14 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
             getITBPtr(tc)->invalidateMiscReg();
             getDTBPtr(tc)->invalidateMiscReg();
             break;
+          case MISCREG_HCR_EL2:
+            {
+                const HDCR mdcr  = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
+                selfDebug->setenableTDETGE((HCR)val, mdcr);
+                getITBPtr(tc)->invalidateMiscReg();
+                getDTBPtr(tc)->invalidateMiscReg();
+            }
+            break;
           case MISCREG_NZCV:
             {
                 CPSR cpsr = val;
@@ -1813,163 +2178,86 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
                 misc_reg = MISCREG_CPSR;
             }
             break;
+          case MISCREG_PAN:
+            {
+                // PAN is affecting data accesses
+                getDTBPtr(tc)->invalidateMiscReg();
+
+                CPSR cpsr = miscRegs[MISCREG_CPSR];
+                cpsr.pan = (uint8_t) ((CPSR) newVal).pan;
+                newVal = cpsr;
+                misc_reg = MISCREG_CPSR;
+            }
+            break;
           case MISCREG_AT_S1E1R_Xt:
+            addressTranslation64(TLB::S1E1Tran, BaseTLB::Read, 0, val);
+            return;
           case MISCREG_AT_S1E1W_Xt:
+            addressTranslation64(TLB::S1E1Tran, BaseTLB::Write, 0, val);
+            return;
           case MISCREG_AT_S1E0R_Xt:
+            addressTranslation64(TLB::S1E0Tran, BaseTLB::Read,
+                TLB::UserMode, val);
+            return;
           case MISCREG_AT_S1E0W_Xt:
+            addressTranslation64(TLB::S1E0Tran, BaseTLB::Write,
+                TLB::UserMode, val);
+            return;
           case MISCREG_AT_S1E2R_Xt:
+            addressTranslation64(TLB::S1E2Tran, BaseTLB::Read, 0, val);
+            return;
           case MISCREG_AT_S1E2W_Xt:
+            addressTranslation64(TLB::S1E2Tran, BaseTLB::Write, 0, val);
+            return;
           case MISCREG_AT_S12E1R_Xt:
+            addressTranslation64(TLB::S12E1Tran, BaseTLB::Read, 0, val);
+            return;
           case MISCREG_AT_S12E1W_Xt:
+            addressTranslation64(TLB::S12E1Tran, BaseTLB::Write, 0, val);
+            return;
           case MISCREG_AT_S12E0R_Xt:
+            addressTranslation64(TLB::S12E0Tran, BaseTLB::Read,
+                TLB::UserMode, val);
+            return;
           case MISCREG_AT_S12E0W_Xt:
+            addressTranslation64(TLB::S12E0Tran, BaseTLB::Write,
+                TLB::UserMode, val);
+            return;
           case MISCREG_AT_S1E3R_Xt:
+            addressTranslation64(TLB::S1E3Tran, BaseTLB::Read, 0, val);
+            return;
           case MISCREG_AT_S1E3W_Xt:
-            {
-                RequestPtr req = std::make_shared<Request>();
-                Request::Flags flags = 0;
-                BaseTLB::Mode mode = BaseTLB::Read;
-                TLB::ArmTranslationType tranType = TLB::NormalTran;
-                Fault fault;
-                switch(misc_reg) {
-                  case MISCREG_AT_S1E1R_Xt:
-                    flags    = TLB::MustBeOne;
-                    tranType = TLB::S1E1Tran;
-                    mode     = BaseTLB::Read;
-                    break;
-                  case MISCREG_AT_S1E1W_Xt:
-                    flags    = TLB::MustBeOne;
-                    tranType = TLB::S1E1Tran;
-                    mode     = BaseTLB::Write;
-                    break;
-                  case MISCREG_AT_S1E0R_Xt:
-                    flags    = TLB::MustBeOne | TLB::UserMode;
-                    tranType = TLB::S1E0Tran;
-                    mode     = BaseTLB::Read;
-                    break;
-                  case MISCREG_AT_S1E0W_Xt:
-                    flags    = TLB::MustBeOne | TLB::UserMode;
-                    tranType = TLB::S1E0Tran;
-                    mode     = BaseTLB::Write;
-                    break;
-                  case MISCREG_AT_S1E2R_Xt:
-                    flags    = TLB::MustBeOne;
-                    tranType = TLB::S1E2Tran;
-                    mode     = BaseTLB::Read;
-                    break;
-                  case MISCREG_AT_S1E2W_Xt:
-                    flags    = TLB::MustBeOne;
-                    tranType = TLB::S1E2Tran;
-                    mode     = BaseTLB::Write;
-                    break;
-                  case MISCREG_AT_S12E0R_Xt:
-                    flags    = TLB::MustBeOne | TLB::UserMode;
-                    tranType = TLB::S12E0Tran;
-                    mode     = BaseTLB::Read;
-                    break;
-                  case MISCREG_AT_S12E0W_Xt:
-                    flags    = TLB::MustBeOne | TLB::UserMode;
-                    tranType = TLB::S12E0Tran;
-                    mode     = BaseTLB::Write;
-                    break;
-                  case MISCREG_AT_S12E1R_Xt:
-                    flags    = TLB::MustBeOne;
-                    tranType = TLB::S12E1Tran;
-                    mode     = BaseTLB::Read;
-                    break;
-                  case MISCREG_AT_S12E1W_Xt:
-                    flags    = TLB::MustBeOne;
-                    tranType = TLB::S12E1Tran;
-                    mode     = BaseTLB::Write;
-                    break;
-                  case MISCREG_AT_S1E3R_Xt:
-                    flags    = TLB::MustBeOne;
-                    tranType = TLB::S1E3Tran;
-                    mode     = BaseTLB::Read;
-                    break;
-                  case MISCREG_AT_S1E3W_Xt:
-                    flags    = TLB::MustBeOne;
-                    tranType = TLB::S1E3Tran;
-                    mode     = BaseTLB::Write;
-                    break;
-                }
-                // 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("Translating via %s in functional mode! Fix Me!\n",
-                     miscRegName[misc_reg]);
-
-                req->setVirt(0, val, 0, flags,  Request::funcMasterId,
-                               tc->pcState().pc());
-                req->setContext(tc->contextId());
-                fault = getDTBPtr(tc)->translateFunctional(req, tc, mode,
-                                                           tranType);
-
-                MiscReg newVal;
-                if (fault == NoFault) {
-                    Addr paddr = req->getPaddr();
-                    uint64_t attr = getDTBPtr(tc)->getAttr();
-                    uint64_t attr1 = attr >> 56;
-                    if (!attr1 || attr1 ==0x44) {
-                        attr |= 0x100;
-                        attr &= ~ uint64_t(0x80);
-                    }
-                    newVal = (paddr & mask(47, 12)) | attr;
-                    DPRINTF(MiscRegs,
-                          "MISCREG: Translated addr %#x: PAR_EL1: %#xx\n",
-                          val, newVal);
-                } else {
-                    ArmFault *armFault = static_cast<ArmFault *>(fault.get());
-                    armFault->update(tc);
-                    // Set fault bit and FSR
-                    FSR fsr = armFault->getFsr(tc);
-
-                    CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
-                    if (cpsr.width) { // AArch32
-                        newVal = ((fsr >> 9) & 1) << 11;
-                        // rearrange fault status
-                        newVal |= ((fsr >>  0) & 0x3f) << 1;
-                        newVal |= 0x1; // F bit
-                        newVal |= ((armFault->iss() >> 7) & 0x1) << 8;
-                        newVal |= armFault->isStage2() ? 0x200 : 0;
-                    } else { // AArch64
-                        newVal = 1; // F bit
-                        newVal |= fsr << 1; // FST
-                        // TODO: DDI 0487A.f D7-2083, AbortFault's s1ptw bit.
-                        newVal |= armFault->isStage2() ? 1 << 8 : 0; // PTW
-                        newVal |= armFault->isStage2() ? 1 << 9 : 0; // S
-                        newVal |= 1 << 11; // RES1
-                    }
-                    DPRINTF(MiscRegs,
-                            "MISCREG: Translated addr %#x fault fsr %#x: PAR: %#x\n",
-                            val, fsr, newVal);
-                }
-                setMiscRegNoEffect(MISCREG_PAR_EL1, newVal);
-                return;
-            }
+            addressTranslation64(TLB::S1E3Tran, BaseTLB::Write, 0, val);
+            return;
           case MISCREG_SPSR_EL3:
           case MISCREG_SPSR_EL2:
           case MISCREG_SPSR_EL1:
-            // Force bits 23:21 to 0
-            newVal = val & ~(0x7 << 21);
-            break;
+            {
+                RegVal spsr_mask = havePAN ?
+                    ~(0x2 << 22) : ~(0x3 << 22);
+
+                newVal = val & spsr_mask;
+                break;
+            }
           case MISCREG_L2CTLR:
             warn("miscreg L2CTLR (%s) written with %#x. ignored...\n",
                  miscRegName[misc_reg], uint32_t(val));
             break;
 
           // Generic Timer registers
-          case MISCREG_CNTHV_CTL_EL2:
-          case MISCREG_CNTHV_CVAL_EL2:
-          case MISCREG_CNTHV_TVAL_EL2:
-          case MISCREG_CNTFRQ ... MISCREG_CNTHP_CTL:
-          case MISCREG_CNTPCT ... MISCREG_CNTHP_CVAL:
-          case MISCREG_CNTKCTL_EL1 ... MISCREG_CNTV_CVAL_EL0:
-          case MISCREG_CNTVOFF_EL2 ... MISCREG_CNTPS_CVAL_EL1:
-            getGenericTimer(tc).setMiscReg(misc_reg, newVal);
+          case MISCREG_CNTFRQ ... MISCREG_CNTVOFF:
+          case MISCREG_CNTFRQ_EL0 ... MISCREG_CNTVOFF_EL2:
+            getGenericTimer().setMiscReg(misc_reg, 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(misc_reg, newVal);
+            return;
+          case MISCREG_ZCR_EL3:
+          case MISCREG_ZCR_EL2:
+          case MISCREG_ZCR_EL1:
+            tc->getDecoderPtr()->setSveLen((getCurSveVecLenInBits() >> 7) - 1);
             break;
         }
     }
@@ -1977,7 +2265,7 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
 }
 
 BaseISADevice &
-ISA::getGenericTimer(ThreadContext *tc)
+ISA::getGenericTimer()
 {
     // We only need to create an ISA interface the first time we try
     // to access the timer.
@@ -1997,8 +2285,198 @@ ISA::getGenericTimer(ThreadContext *tc)
     return *timer.get();
 }
 
+BaseISADevice &
+ISA::getGICv3CPUInterface()
+{
+    panic_if(!gicv3CpuInterface, "GICV3 cpu interface is not registered!");
+    return *gicv3CpuInterface.get();
+}
+
+unsigned
+ISA::getCurSveVecLenInBits() const
+{
+    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 (haveVirtualization && !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 (haveSecurity) {
+        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;
+}
+
+void
+ISA::zeroSveVecRegUpperPart(VecRegContainer &vc, unsigned eCount)
+{
+    auto vv = vc.as<uint64_t>();
+    for (int i = 2; i < eCount; ++i) {
+        vv[i] = 0;
+    }
+}
+
+void
+ISA::addressTranslation64(TLB::ArmTranslationType tran_type,
+    BaseTLB::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().pc(), tc->contextId());
+
+    Fault fault = getDTBPtr(tc)->translateFunctional(
+        req, tc, mode, tran_type);
+
+    PAR par = 0;
+    if (fault == NoFault) {
+        Addr paddr = req->getPaddr();
+        uint64_t attr = getDTBPtr(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(TLB::ArmTranslationType tran_type,
+    BaseTLB::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().pc(), tc->contextId());
+
+    Fault fault = getDTBPtr(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);
+
+        uint8_t max_paddr_bit = 0;
+        if (haveLPAE && (ttbcr.eae || tran_type & TLB::HypMode ||
+            ((tran_type & TLB::S1S2NsTran) && hcr.vm) )) {
+
+            max_paddr_bit = 39;
+        } else {
+            max_paddr_bit = 31;
+        }
+
+        par = (paddr & mask(max_paddr_bit, 12)) |
+            (getDTBPtr(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;
+}
+
+ISA::MiscRegLUTEntryInitializer::chain
+ISA::MiscRegLUTEntryInitializer::highest(ArmSystem *const sys) const
+{
+    switch (FullSystem ? sys->highestEL() : EL1) {
+      case EL0:
+      case EL1: priv(); break;
+      case EL2: hyp(); break;
+      case EL3: mon(); break;
+    }
+    return *this;
 }
 
+}  // namespace ArmISA
+
 ArmISA::ISA *
 ArmISAParams::create()
 {