diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index 034340049..c093ceda9 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -226,12 +226,14 @@ ISA::ISA(Params *p) // Cache system-level properties if (FullSystem && system) { + highestELIs64 = system->highestELIs64(); haveSecurity = system->haveSecurity(); haveLPAE = system->haveLPAE(); haveVirtualization = system->haveVirtualization(); haveLargeAsid64 = system->haveLargeAsid64(); physAddrRange64 = system->physAddrRange64(); } else { + highestELIs64 = true; // ArmSystem::highestELIs64 does the same haveSecurity = haveLPAE = haveVirtualization = false; haveLargeAsid64 = false; physAddrRange64 = 32; // dummy value @@ -487,22 +489,10 @@ ISA::readMiscRegNoEffect(int misc_reg) const { assert(misc_reg < NumMiscRegs); - int flat_idx = flattenMiscIndex(misc_reg); // Note: indexes of AArch64 - // registers are left unchanged - MiscReg val; - - if (lookUpMiscReg[flat_idx].lower == 0 || flat_idx == MISCREG_SPSR) { - if (flat_idx == MISCREG_SPSR) - flat_idx = flattenMiscIndex(MISCREG_SPSR); - val = miscRegs[flat_idx]; - } else - if (lookUpMiscReg[flat_idx].upper > 0) - val = ((miscRegs[lookUpMiscReg[flat_idx].lower] & mask(32)) - | (miscRegs[lookUpMiscReg[flat_idx].upper] << 32)); - else - val = miscRegs[lookUpMiscReg[flat_idx].lower]; - - return val; + auto regs = getMiscIndices(misc_reg); + int lower = regs.first, upper = regs.second; + return !upper ? miscRegs[lower] : ((miscRegs[lower] & mask(32)) + |(miscRegs[upper] << 32)); } @@ -801,25 +791,17 @@ ISA::setMiscRegNoEffect(int misc_reg, const MiscReg &val) { assert(misc_reg < NumMiscRegs); - int flat_idx = flattenMiscIndex(misc_reg); // Note: indexes of AArch64 - // registers are left unchanged - - int flat_idx2 = lookUpMiscReg[flat_idx].upper; - - if (flat_idx2 > 0) { - miscRegs[lookUpMiscReg[flat_idx].lower] = bits(val, 31, 0); - miscRegs[flat_idx2] = bits(val, 63, 32); + auto regs = getMiscIndices(misc_reg); + int lower = regs.first, upper = regs.second; + if (upper > 0) { + miscRegs[lower] = bits(val, 31, 0); + miscRegs[upper] = bits(val, 63, 32); DPRINTF(MiscRegs, "Writing to misc reg %d (%d:%d) : %#x\n", - misc_reg, flat_idx, flat_idx2, val); + misc_reg, lower, upper, val); } else { - if (flat_idx == MISCREG_SPSR) - flat_idx = flattenMiscIndex(MISCREG_SPSR); - else - flat_idx = (lookUpMiscReg[flat_idx].lower > 0) ? - lookUpMiscReg[flat_idx].lower : flat_idx; - miscRegs[flat_idx] = val; + miscRegs[lower] = val; DPRINTF(MiscRegs, "Writing to misc reg %d (%d) : %#x\n", - misc_reg, flat_idx, val); + misc_reg, lower, val); } } diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 79db09e1d..e05f0e18a 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -79,6 +79,7 @@ namespace ArmISA std::unique_ptr timer; // Cached copies of system-level properties + bool highestELIs64; bool haveSecurity; bool haveLPAE; bool haveVirtualization; @@ -328,7 +329,7 @@ namespace ArmISA } } else { if (miscRegInfo[reg][MISCREG_BANKED]) { - bool secureReg = haveSecurity && + bool secureReg = haveSecurity && !highestELIs64 && inSecureState(miscRegs[MISCREG_SCR], miscRegs[MISCREG_CPSR]); flat_idx += secureReg ? 2 : 1; @@ -337,11 +338,33 @@ namespace ArmISA return flat_idx; } + std::pair getMiscIndices(int misc_reg) const + { + // Note: indexes of AArch64 registers are left unchanged + int flat_idx = flattenMiscIndex(misc_reg); + + if (lookUpMiscReg[flat_idx].lower == 0) { + return std::make_pair(flat_idx, 0); + } + + // do additional S/NS flattenings if mapped to NS while in S + bool S = haveSecurity && !highestELIs64 && + inSecureState(miscRegs[MISCREG_SCR], + miscRegs[MISCREG_CPSR]); + int lower = lookUpMiscReg[flat_idx].lower; + int upper = lookUpMiscReg[flat_idx].upper; + // upper == 0, which is CPSR, is not MISCREG_BANKED_CHILD (no-op) + lower += S && miscRegInfo[lower][MISCREG_BANKED_CHILD]; + upper += S && miscRegInfo[upper][MISCREG_BANKED_CHILD]; + return std::make_pair(lower, upper); + } + void serialize(CheckpointOut &cp) const { DPRINTF(Checkpoint, "Serializing Arm Misc Registers\n"); SERIALIZE_ARRAY(miscRegs, NumMiscRegs); + SERIALIZE_SCALAR(highestELIs64); SERIALIZE_SCALAR(haveSecurity); SERIALIZE_SCALAR(haveLPAE); SERIALIZE_SCALAR(haveVirtualization); @@ -355,6 +378,7 @@ namespace ArmISA CPSR tmp_cpsr = miscRegs[MISCREG_CPSR]; updateRegMap(tmp_cpsr); + UNSERIALIZE_SCALAR(highestELIs64); UNSERIALIZE_SCALAR(haveSecurity); UNSERIALIZE_SCALAR(haveLPAE); UNSERIALIZE_SCALAR(haveVirtualization); diff --git a/src/arch/arm/miscregs.cc b/src/arch/arm/miscregs.cc index c4915cb54..525d44810 100644 --- a/src/arch/arm/miscregs.cc +++ b/src/arch/arm/miscregs.cc @@ -2039,12 +2039,8 @@ canWriteCoprocReg(MiscRegIndex reg, SCR scr, CPSR cpsr, ThreadContext *tc) int flattenMiscRegNsBanked(MiscRegIndex reg, ThreadContext *tc) { - int reg_as_int = static_cast(reg); - if (miscRegInfo[reg][MISCREG_BANKED]) { - SCR scr = tc->readMiscReg(MISCREG_SCR); - reg_as_int += (ArmSystem::haveSecurity(tc) && !scr.ns) ? 2 : 1; - } - return reg_as_int; + SCR scr = tc->readMiscReg(MISCREG_SCR); + return flattenMiscRegNsBanked(reg, tc, scr.ns); } int @@ -2052,7 +2048,8 @@ flattenMiscRegNsBanked(MiscRegIndex reg, ThreadContext *tc, bool ns) { int reg_as_int = static_cast(reg); if (miscRegInfo[reg][MISCREG_BANKED]) { - reg_as_int += (ArmSystem::haveSecurity(tc) && !ns) ? 2 : 1; + reg_as_int += (ArmSystem::haveSecurity(tc) && + !ArmSystem::highestELIs64(tc) && !ns) ? 2 : 1; } return reg_as_int; }