diff mbox

[v3,06/11] target-arm: implement SCTLR.EE

Message ID 1403355502-12288-7-git-send-email-pbonzini@redhat.com
State New
Headers show

Commit Message

Paolo Bonzini June 21, 2014, 12:58 p.m. UTC
Set CPSR.E to SCTLR.EE on exception, and use SCTLR.EE also to
determine endianness for loads during TLB misses.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target-arm/helper.c | 38 ++++++++++++++++++++++++++++++++------
 1 file changed, 32 insertions(+), 6 deletions(-)

Comments

Peter Maydell June 26, 2014, 2:29 p.m. UTC | #1
On 21 June 2014 13:58, Paolo Bonzini <pbonzini@redhat.com> wrote:
> Set CPSR.E to SCTLR.EE on exception, and use SCTLR.EE also to
> determine endianness for loads during TLB misses.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

-- PMM
diff mbox

Patch

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 6e4fc55..2e3816d 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3213,6 +3213,30 @@  void switch_mode(CPUARMState *env, int mode)
     env->spsr = env->banked_spsr[i];
 }
 
+static uint32_t ldl_ptw_phys(CPUState *cs, target_ulong physaddr)
+{
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
+
+    if (unlikely(env->cp15.c1_sys & SCTLR_EE)) {
+        return ldl_be_phys(cs->as, physaddr);
+    } else {
+        return ldl_le_phys(cs->as, physaddr);
+    }
+}
+
+static uint64_t ldq_ptw_phys(CPUState *cs, target_ulong physaddr)
+{
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
+
+    if (unlikely(env->cp15.c1_sys & SCTLR_EE)) {
+        return ldq_be_phys(cs->as, physaddr);
+    } else {
+        return ldq_le_phys(cs->as, physaddr);
+    }
+}
+
 static void v7m_push(CPUARMState *env, uint32_t val)
 {
     CPUState *cs = CPU(arm_env_get_cpu(env));
@@ -3483,7 +3507,9 @@  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 | CPSR_E))
+        | new_mode
+        | (env->cp15.c1_sys & 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 */
@@ -3592,7 +3618,7 @@  static int get_phys_addr_v5(CPUARMState *env, uint32_t address, int access_type,
         code = 5;
         goto do_fault;
     }
-    desc = ldl_phys(cs->as, table);
+    desc = ldl_ptw_phys(cs, table);
     type = (desc & 3);
     domain = (desc >> 5) & 0x0f;
     domain_prot = (env->cp15.c3 >> (domain * 2)) & 3;
@@ -3623,7 +3649,7 @@  static int get_phys_addr_v5(CPUARMState *env, uint32_t address, int access_type,
 	    /* Fine pagetable.  */
 	    table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
 	}
-        desc = ldl_phys(cs->as, table);
+        desc = ldl_ptw_phys(cs, table);
         switch (desc & 3) {
         case 0: /* Page translation fault.  */
             code = 7;
@@ -3694,7 +3720,7 @@  static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type,
         code = 5;
         goto do_fault;
     }
-    desc = ldl_phys(cs->as, table);
+    desc = ldl_ptw_phys(cs, table);
     type = (desc & 3);
     if (type == 0 || (type == 3 && !arm_feature(env, ARM_FEATURE_PXN))) {
         /* Section translation fault, or attempt to use the encoding
@@ -3736,7 +3762,7 @@  static int get_phys_addr_v6(CPUARMState *env, uint32_t address, int access_type,
         }
         /* Lookup l2 entry.  */
         table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
-        desc = ldl_phys(cs->as, table);
+        desc = ldl_ptw_phys(cs, table);
         ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);
         switch (desc & 3) {
         case 0: /* Page translation fault.  */
@@ -3930,7 +3956,7 @@  static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,
 
         descaddr |= (address >> (granule_sz * (4 - level))) & descmask;
         descaddr &= ~7ULL;
-        descriptor = ldq_phys(cs->as, descaddr);
+        descriptor = ldq_ptw_phys(cs, descaddr);
         if (!(descriptor & 1) ||
             (!(descriptor & 2) && (level == 3))) {
             /* Invalid, or the Reserved level 3 encoding */