target-arm: implement SCTLR.EE

Implement SCTLR.EE bit which controls data endianess for exceptions
and page table translations. SCTLR.EE is mirrored to the CPSR.E bit
on exception entry.

Backports commit 73462dddf670c32c45c8ea359658092b0365b2d4 from qemu
This commit is contained in:
Peter Crosthwaite 2018-02-21 02:14:53 -05:00 committed by Lioncash
parent 38f4a833a4
commit e5cfcc3221
No known key found for this signature in database
GPG Key ID: 4E3C3CC1031BA9C7

View File

@ -5489,6 +5489,11 @@ static void arm_cpu_do_interrupt_aarch32_(CPUState *cs)
env->condexec_bits = 0;
/* Switch to the new mode, and to the correct instruction set. */
env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;
/* Set new mode endianness */
env->uncached_cpsr &= ~CPSR_E;
if (env->cp15.sctlr_el[arm_current_el(env)] & SCTLR_EE) {
env->uncached_cpsr |= ~CPSR_E;
}
env->daif |= mask;
/* this is a lie, as the was no c1_sys on V4T/V5, but who cares
* and we should just guard the thumb mode on V4 */
@ -5784,6 +5789,12 @@ static inline bool regime_translation_disabled(CPUARMState *env,
return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
}
static inline bool regime_translation_big_endian(CPUARMState *env,
ARMMMUIdx mmu_idx)
{
return (regime_sctlr(env, mmu_idx) & SCTLR_EE) != 0;
}
/* Return the TCR controlling this translation regime */
static inline TCR *regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx)
{
@ -6107,7 +6118,11 @@ static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure,
if (fi->s1ptw) {
return 0;
}
return address_space_ldl(as, addr, attrs, NULL);
if (regime_translation_big_endian(env, mmu_idx)) {
return address_space_ldl_be(as, addr, attrs, NULL);
} else {
return address_space_ldl_le(as, addr, attrs, NULL);
}
}
static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
@ -6125,7 +6140,11 @@ static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
if (fi->s1ptw) {
return 0;
}
return address_space_ldq(as, addr, attrs, NULL);
if (regime_translation_big_endian(env, mmu_idx)) {
return address_space_ldq_be(as, addr, attrs, NULL);
} else {
return address_space_ldq_le(as, addr, attrs, NULL);
}
}
static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,