[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2 4/8] linux-user: arm: handle CPSR.E correctly
From: |
Paolo Bonzini |
Subject: |
Re: [Qemu-devel] [PATCH v2 4/8] linux-user: arm: handle CPSR.E correctly in strex emulation |
Date: |
Tue, 03 Jun 2014 13:12:58 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.5.0 |
Il 03/06/2014 11:54, Peter Maydell ha scritto:
> In user emulation, things are more complicated for BE32,
> because we're sort of emulating the word-invariant
> bigendian using byte-invariant big-endian (this is
> safe because there's no way for a userspace program
> to get at anything that would let it tell the
> difference). So we can't just say "set SCTLR.B
> and handle as if SCTLR.B is set in the way system
> emulation would", because the behaviour has to
> be different.
>
> So in summary I'm not sure of the right approach
> any more...
I think overall sctlr_b makes for more accurate and overall
clearer code.
Here are the functions I'm using to map between the various properties:
+static inline bool bswap_code(bool sctlr_b)
+{
+#ifdef CONFIG_USER_ONLY
+ /* Mixed-endian modes are BE8 (SCTLR.B = 0, TARGET_WORDS_BIGENDIAN = 1)
+ * and LE8 (SCTLR.B = 1, TARGET_WORDS_BIGENDIAN = 0).
+ */
+ return
+#ifdef TARGET_WORDS_BIGENDIAN
+ 1 ^
+#endif
+ sctlr_b;
+#else
+ /* We do not implement BE32 mode for system-mode emulation, but
+ * anyway it would always do little-endian accesses with
+ * TARGET_WORDS_BIGENDIAN = 0.
+ */
+ return 0;
+#endif
+}
+
+#ifdef CONFIG_USER_ONLY
+static inline bool arm_cpu_bswap_data(CPUARMState *env)
+{
+ return
+#ifdef TARGET_WORDS_BIGENDIAN
+ 1 ^
+#endif
+ !!(env->cp15.c1_sys & SCTLR_B) ^
+ !!(env->uncached_cpsr & CPSR_E);
+}
+#endif
+
+static inline bool arm_tbflag_is_data_be(unsigned tbflags)
+{
+ return
+#ifdef CONFIG_USER_ONLY
+ ARM_TBFLAG_SCTLR_B(tbflags) ^
+#endif
+ ARM_TBFLAG_CPSR_E(tbflags);
+}
+
I think this is reasonably close to what you would have for SCTLR.B
emulation, only the XORing of addresses is missing.
bswap_code is used in much fewer places than the current env->bswap_code,
basically only in the definitions of arm_ld*_code and get_user_code_*.
Everywhere else the code is accessing SCTLR.B, which is "real"
architectural state. The confusing manner of handling it in user-mode
emulation is wrapped by the above three inline functions.
Paolo