[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-arm] [PATCH v1 04/17] target-arm: implement SCTLR.EE
From: |
Peter Crosthwaite |
Subject: |
[Qemu-arm] [PATCH v1 04/17] target-arm: implement SCTLR.EE |
Date: |
Sun, 17 Jan 2016 23:12:31 -0800 |
From: Peter Crosthwaite <address@hidden>
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.
Signed-off-by: Peter Crosthwaite <address@hidden>
---
target-arm/helper.c | 42 ++++++++++++++++++++++++++++++++----------
1 file changed, 32 insertions(+), 10 deletions(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 59d5a41..afac1b2 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -5889,7 +5889,10 @@ void arm_cpu_do_interrupt(CPUState *cs)
/* Clear IT bits. */
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;
+ env->uncached_cpsr = (env->uncached_cpsr & ~(CPSR_M)) | new_mode;
+ /* Set new mode endianess */
+ env->uncached_cpsr = (env->uncached_cpsr & ~(CPSR_E)) |
+ (env->cp15.sctlr_el[arm_current_el(env)] & SCTLR_EE ? CPSR_E : 0);
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 */
@@ -5958,6 +5961,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)
{
@@ -6263,7 +6272,7 @@ static hwaddr S1_ptw_translate(CPUARMState *env,
ARMMMUIdx mmu_idx,
*/
static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure,
ARMMMUIdx mmu_idx, uint32_t *fsr,
- ARMMMUFaultInfo *fi)
+ ARMMMUFaultInfo *fi, bool be)
{
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;
@@ -6274,12 +6283,16 @@ static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr,
bool is_secure,
if (fi->s1ptw) {
return 0;
}
- return address_space_ldl(cs->as, addr, attrs, NULL);
+ if (be) {
+ return address_space_ldl_be(cs->as, addr, attrs, NULL);
+ } else {
+ return address_space_ldl_le(cs->as, addr, attrs, NULL);
+ }
}
static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
ARMMMUIdx mmu_idx, uint32_t *fsr,
- ARMMMUFaultInfo *fi)
+ ARMMMUFaultInfo *fi, bool be)
{
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;
@@ -6290,7 +6303,11 @@ static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr,
bool is_secure,
if (fi->s1ptw) {
return 0;
}
- return address_space_ldq(cs->as, addr, attrs, NULL);
+ if (be) {
+ return address_space_ldq_be(cs->as, addr, attrs, NULL);
+ } else {
+ return address_space_ldq_le(cs->as, addr, attrs, NULL);
+ }
}
static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
@@ -6318,7 +6335,8 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t
address,
goto do_fault;
}
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
- mmu_idx, fsr, fi);
+ mmu_idx, fsr, fi,
+ regime_translation_big_endian(env, mmu_idx));
type = (desc & 3);
domain = (desc >> 5) & 0x0f;
if (regime_el(env, mmu_idx) == 1) {
@@ -6355,7 +6373,8 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t
address,
table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
}
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
- mmu_idx, fsr, fi);
+ mmu_idx, fsr, fi,
+ regime_translation_big_endian(env, mmu_idx));
switch (desc & 3) {
case 0: /* Page translation fault. */
code = 7;
@@ -6437,7 +6456,8 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t
address,
goto do_fault;
}
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
- mmu_idx, fsr, fi);
+ mmu_idx, fsr, fi,
+ regime_translation_big_endian(env, mmu_idx));
type = (desc & 3);
if (type == 0 || (type == 3 && !arm_feature(env, ARM_FEATURE_PXN))) {
/* Section translation fault, or attempt to use the encoding
@@ -6489,7 +6509,8 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t
address,
/* Lookup l2 entry. */
table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
- mmu_idx, fsr, fi);
+ mmu_idx, fsr, fi,
+ regime_translation_big_endian(env, mmu_idx));
ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);
switch (desc & 3) {
case 0: /* Page translation fault. */
@@ -6862,7 +6883,8 @@ static bool get_phys_addr_lpae(CPUARMState *env,
target_ulong address,
descaddr |= (address >> (stride * (4 - level))) & descmask;
descaddr &= ~7ULL;
nstable = extract32(tableattrs, 4, 1);
- descriptor = arm_ldq_ptw(cs, descaddr, !nstable, mmu_idx, fsr, fi);
+ descriptor = arm_ldq_ptw(cs, descaddr, !nstable, mmu_idx, fsr, fi,
+ regime_translation_big_endian(env, mmu_idx));
if (fi->s1ptw) {
goto do_fault;
}
--
1.9.1
- [Qemu-arm] [PATCH v1 00/17] ARM big-endian and setend support, Peter Crosthwaite, 2016/01/18
- [Qemu-arm] [PATCH v1 01/17] linux-user: arm: fix coding style for some linux-user signal functions, Peter Crosthwaite, 2016/01/18
- [Qemu-arm] [PATCH v1 03/17] linux-user: arm: handle CPSR.E correctly in strex emulation, Peter Crosthwaite, 2016/01/18
- [Qemu-arm] [PATCH v1 02/17] linux-user: arm: set CPSR.E/SCTLR.E0E correctly for BE mode, Peter Crosthwaite, 2016/01/18
- [Qemu-arm] [PATCH v1 04/17] target-arm: implement SCTLR.EE,
Peter Crosthwaite <=
- [Qemu-arm] [PATCH v1 06/17] target-arm: introduce disas flag for endianness, Peter Crosthwaite, 2016/01/18
- [Qemu-arm] [PATCH v1 09/17] target-arm: introduce tbflag for endianness, Peter Crosthwaite, 2016/01/18
- [Qemu-arm] [PATCH v1 07/17] target-arm: a64: Add endianness support, Peter Crosthwaite, 2016/01/18
- [Qemu-arm] [PATCH v1 05/17] target-arm: pass DisasContext to gen_aa32_ld*/st*, Peter Crosthwaite, 2016/01/18
- [Qemu-arm] [PATCH v1 08/17] target-arm: cpu: Move cpu_is_big_endian to header, Peter Crosthwaite, 2016/01/18