diff options
-rw-r--r-- | src/arch/arm/isa.hh | 18 | ||||
-rw-r--r-- | src/arch/arm/isa/insts/data64.isa | 12 | ||||
-rw-r--r-- | src/arch/arm/miscregs.cc | 6 | ||||
-rw-r--r-- | src/arch/arm/miscregs.hh | 6 |
4 files changed, 38 insertions, 4 deletions
diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 5e337c223..ff889fa7d 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -183,6 +183,10 @@ namespace ArmISA info[MISCREG_BANKED] = v; return *this; } + chain banked64(bool v = true) const { + info[MISCREG_BANKED64] = v; + return *this; + } chain bankedChild(bool v = true) const { info[MISCREG_BANKED_CHILD] = v; return *this; @@ -642,11 +646,25 @@ namespace ArmISA inSecureState(miscRegs[MISCREG_SCR], miscRegs[MISCREG_CPSR]); flat_idx += secureReg ? 2 : 1; + } else { + flat_idx = snsBankedIndex64((MiscRegIndex)reg, + !inSecureState(miscRegs[MISCREG_SCR], + miscRegs[MISCREG_CPSR])); } } return flat_idx; } + int + snsBankedIndex64(MiscRegIndex reg, bool ns) const + { + int reg_as_int = static_cast<int>(reg); + if (miscRegInfo[reg][MISCREG_BANKED64]) { + reg_as_int += (haveSecurity && !ns) ? 2 : 1; + } + return reg_as_int; + } + std::pair<int,int> getMiscIndices(int misc_reg) const { // Note: indexes of AArch64 registers are left unchanged diff --git a/src/arch/arm/isa/insts/data64.isa b/src/arch/arm/isa/insts/data64.isa index a2ffb9f5a..f5be4763a 100644 --- a/src/arch/arm/isa/insts/data64.isa +++ b/src/arch/arm/isa/insts/data64.isa @@ -331,16 +331,18 @@ let {{ ''' msr_check_code = ''' + auto pre_flat = (MiscRegIndex)snsBankedIndex64(dest, xc->tcBase()); MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()-> - flattenRegId(RegId(MiscRegClass, dest)).index(); + flattenRegId(RegId(MiscRegClass, pre_flat)).index(); CPSR cpsr = Cpsr; ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el; %s ''' % (msrMrs64EnabledCheckCode % ('Write'),) mrs_check_code = ''' + auto pre_flat = (MiscRegIndex)snsBankedIndex64(op1, xc->tcBase()); MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()-> - flattenRegId(RegId(MiscRegClass, op1)).index(); + flattenRegId(RegId(MiscRegClass, pre_flat)).index(); CPSR cpsr = Cpsr; ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el; %s @@ -509,8 +511,10 @@ let {{ def buildMsrImmInst(mnem, inst_name, code): global header_output, decoder_output, exec_output msrImmPermission = ''' - auto misc_index = (MiscRegIndex) xc->tcBase()->flattenRegId( - RegId(MiscRegClass, dest)).index(); + auto pre_flat = + (MiscRegIndex)snsBankedIndex64(dest, xc->tcBase()); + MiscRegIndex misc_index = (MiscRegIndex) xc->tcBase()-> + flattenRegId(RegId(MiscRegClass, pre_flat)).index(); if (!miscRegInfo[misc_index][MISCREG_IMPLEMENTED]) { return std::make_shared<UndefinedInstruction>( diff --git a/src/arch/arm/miscregs.cc b/src/arch/arm/miscregs.cc index cad123fcc..0bae01893 100644 --- a/src/arch/arm/miscregs.cc +++ b/src/arch/arm/miscregs.cc @@ -1075,6 +1075,12 @@ snsBankedIndex(MiscRegIndex reg, ThreadContext *tc, bool ns) return reg_as_int; } +int +snsBankedIndex64(MiscRegIndex reg, ThreadContext *tc) +{ + SCR scr = tc->readMiscReg(MISCREG_SCR); + return tc->getIsaPtr()->snsBankedIndex64(reg, scr.ns); +} /** * If the reg is a child reg of a banked set, then the parent is the last diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh index a95168bf3..3ce371bfe 100644 --- a/src/arch/arm/miscregs.hh +++ b/src/arch/arm/miscregs.hh @@ -949,6 +949,9 @@ namespace ArmISA MISCREG_BANKED, // True if the register is banked between the two // security states, and this is the parent node of the // two banked registers + MISCREG_BANKED64, // True if the register is banked between the two + // security states, and this is the parent node of + // the two banked registers. Used in AA64 only. MISCREG_BANKED_CHILD, // The entry is one of the child registers that // forms a banked set of regs (along with the // other child regs) @@ -1941,6 +1944,9 @@ namespace ArmISA int snsBankedIndex(MiscRegIndex reg, ThreadContext *tc, bool ns); + int + snsBankedIndex64(MiscRegIndex reg, ThreadContext *tc); + // Takes a misc reg index and returns the root reg if its one of a set of // banked registers void |