summaryrefslogtreecommitdiffstats
path: root/target-arm
diff options
context:
space:
mode:
authorPeter Crosthwaite <crosthwaitepeter@gmail.com>2016-03-04 11:30:19 +0000
committerTimothy Pearson <tpearson@raptorengineering.com>2019-11-29 19:49:12 -0600
commitd6ae1524fd151b28c819a380e3e164e6e3fb561c (patch)
treeaec6c197d2b62987d580434734d55368ad89cfda /target-arm
parent73095f13798b044196573cf5f0a87a28c6ca76ad (diff)
downloadhqemu-d6ae1524fd151b28c819a380e3e164e6e3fb561c.zip
hqemu-d6ae1524fd151b28c819a380e3e164e6e3fb561c.tar.gz
arm: cpu: handle BE32 user-mode as BE
endian with address manipulations on subword accesses (to give the illusion of BE). But user-mode cannot tell the difference and is already implemented as straight BE. So handle the difference in the endianess query, where USER mode is BE and system is not. Signed-off-by: Peter Crosthwaite <crosthwaite.peter@gmail.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-arm')
-rw-r--r--target-arm/cpu.h17
1 files changed, 16 insertions, 1 deletions
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 6c4e1a1..d425d1b 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1917,7 +1917,22 @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
/* In 32bit endianness is determined by looking at CPSR's E bit */
if (!is_a64(env)) {
- return (env->uncached_cpsr & CPSR_E) ? 1 : 0;
+ return
+#ifdef CONFIG_USER_ONLY
+ /* In system mode, BE32 is modelled in line with the
+ * architecture (as word-invariant big-endianness), where loads
+ * and stores are done little endian but from addresses which
+ * are adjusted by XORing with the appropriate constant. So the
+ * endianness to use for the raw data access is not affected by
+ * SCTLR.B.
+ * In user mode, however, we model BE32 as byte-invariant
+ * big-endianness (because user-only code cannot tell the
+ * difference), and so we need to use a data access endianness
+ * that depends on SCTLR.B.
+ */
+ arm_sctlr_b(env) ||
+#endif
+ ((env->uncached_cpsr & CPSR_E) ? 1 : 0);
}
cur_el = arm_current_el(env);
OpenPOWER on IntegriCloud