From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PULL 13/30] target-arm: implement SCTLR.B, drop bswap_code
Date: Fri, 4 Mar 2016 11:41:36 +0000 [thread overview]
Message-ID: <1457091713-10138-14-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1457091713-10138-1-git-send-email-peter.maydell@linaro.org>
From: Paolo Bonzini <pbonzini@redhat.com>
bswap_code is a CPU property of sorts ("is the iside endianness the
opposite way round to TARGET_WORDS_BIGENDIAN?") but it is not the
actual CPU state involved here which is SCTLR.B (set for BE32
binaries, clear for BE8).
Replace bswap_code with SCTLR.B, and pass that to arm_ld*_code.
The next patches will make data fetches honor both SCTLR.B and
CPSR.E appropriately.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[PC changes:
* rebased on master (Jan 2016)
* s/TARGET_USER_ONLY/CONFIG_USER_ONLY
* Use bswap_code() for disas_set_info() instead of raw sctlr_b
]
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>
---
linux-user/main.c | 10 +++++++---
target-arm/arm_ldst.h | 8 ++++----
target-arm/cpu.c | 2 +-
target-arm/cpu.h | 47 ++++++++++++++++++++++++++++++++++++++--------
target-arm/helper.c | 8 ++++----
target-arm/translate-a64.c | 6 +++---
target-arm/translate.c | 16 ++++++++--------
target-arm/translate.h | 2 +-
8 files changed, 67 insertions(+), 32 deletions(-)
diff --git a/linux-user/main.c b/linux-user/main.c
index bcb9f66..fe2a8dd 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -437,7 +437,7 @@ void cpu_loop(CPUX86State *env)
#define get_user_code_u32(x, gaddr, env) \
({ abi_long __r = get_user_u32((x), (gaddr)); \
- if (!__r && (env)->bswap_code) { \
+ if (!__r && bswap_code(arm_sctlr_b(env))) { \
(x) = bswap32(x); \
} \
__r; \
@@ -445,7 +445,7 @@ void cpu_loop(CPUX86State *env)
#define get_user_code_u16(x, gaddr, env) \
({ abi_long __r = get_user_u16((x), (gaddr)); \
- if (!__r && (env)->bswap_code) { \
+ if (!__r && bswap_code(arm_sctlr_b(env))) { \
(x) = bswap16(x); \
} \
__r; \
@@ -4449,11 +4449,15 @@ int main(int argc, char **argv, char **envp)
for(i = 0; i < 16; i++) {
env->regs[i] = regs->uregs[i];
}
+#ifdef TARGET_WORDS_BIGENDIAN
/* Enable BE8. */
if (EF_ARM_EABI_VERSION(info->elf_flags) >= EF_ARM_EABI_VER4
&& (info->elf_flags & EF_ARM_BE8)) {
- env->bswap_code = 1;
+ /* nothing for now, CPSR.E not emulated yet */
+ } else {
+ env->cp15.sctlr_el[1] |= SCTLR_B;
}
+#endif
}
#elif defined(TARGET_UNICORE32)
{
diff --git a/target-arm/arm_ldst.h b/target-arm/arm_ldst.h
index b1ece01..35c2c43 100644
--- a/target-arm/arm_ldst.h
+++ b/target-arm/arm_ldst.h
@@ -25,10 +25,10 @@
/* Load an instruction and return it in the standard little-endian order */
static inline uint32_t arm_ldl_code(CPUARMState *env, target_ulong addr,
- bool do_swap)
+ bool sctlr_b)
{
uint32_t insn = cpu_ldl_code(env, addr);
- if (do_swap) {
+ if (bswap_code(sctlr_b)) {
return bswap32(insn);
}
return insn;
@@ -36,10 +36,10 @@ static inline uint32_t arm_ldl_code(CPUARMState *env, target_ulong addr,
/* Ditto, for a halfword (Thumb) instruction */
static inline uint16_t arm_lduw_code(CPUARMState *env, target_ulong addr,
- bool do_swap)
+ bool sctlr_b)
{
uint16_t insn = cpu_lduw_code(env, addr);
- if (do_swap) {
+ if (bswap_code(sctlr_b)) {
return bswap16(insn);
}
return insn;
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index e95b030..001fccf 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -427,7 +427,7 @@ static void arm_disas_set_info(CPUState *cpu, disassemble_info *info)
} else {
info->print_insn = print_insn_arm;
}
- if (env->bswap_code) {
+ if (bswap_code(arm_sctlr_b(env))) {
#ifdef TARGET_WORDS_BIGENDIAN
info->endian = BFD_ENDIAN_LITTLE;
#else
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 744f052..61b8b03 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -478,9 +478,6 @@ typedef struct CPUARMState {
uint32_t cregs[16];
} iwmmxt;
- /* For mixed endian mode. */
- bool bswap_code;
-
#if defined(CONFIG_USER_ONLY)
/* For usermode syscall translation. */
int eabi;
@@ -1898,6 +1895,19 @@ static inline bool arm_singlestep_active(CPUARMState *env)
&& arm_generate_debug_exceptions(env);
}
+static inline bool arm_sctlr_b(CPUARMState *env)
+{
+ return
+ /* We need not implement SCTLR.ITD in user-mode emulation, so
+ * let linux-user ignore the fact that it conflicts with SCTLR_B.
+ * This lets people run BE32 binaries with "-cpu any".
+ */
+#ifndef CONFIG_USER_ONLY
+ !arm_feature(env, ARM_FEATURE_V7) &&
+#endif
+ (env->cp15.sctlr_el[1] & SCTLR_B) != 0;
+}
+
#include "exec/cpu-all.h"
/* Bit usage in the TB flags field: bit 31 indicates whether we are
@@ -1928,8 +1938,8 @@ static inline bool arm_singlestep_active(CPUARMState *env)
#define ARM_TBFLAG_VFPEN_MASK (1 << ARM_TBFLAG_VFPEN_SHIFT)
#define ARM_TBFLAG_CONDEXEC_SHIFT 8
#define ARM_TBFLAG_CONDEXEC_MASK (0xff << ARM_TBFLAG_CONDEXEC_SHIFT)
-#define ARM_TBFLAG_BSWAP_CODE_SHIFT 16
-#define ARM_TBFLAG_BSWAP_CODE_MASK (1 << ARM_TBFLAG_BSWAP_CODE_SHIFT)
+#define ARM_TBFLAG_SCTLR_B_SHIFT 16
+#define ARM_TBFLAG_SCTLR_B_MASK (1 << ARM_TBFLAG_SCTLR_B_SHIFT)
/* We store the bottom two bits of the CPAR as TB flags and handle
* checks on the other bits at runtime
*/
@@ -1965,13 +1975,34 @@ static inline bool arm_singlestep_active(CPUARMState *env)
(((F) & ARM_TBFLAG_VFPEN_MASK) >> ARM_TBFLAG_VFPEN_SHIFT)
#define ARM_TBFLAG_CONDEXEC(F) \
(((F) & ARM_TBFLAG_CONDEXEC_MASK) >> ARM_TBFLAG_CONDEXEC_SHIFT)
-#define ARM_TBFLAG_BSWAP_CODE(F) \
- (((F) & ARM_TBFLAG_BSWAP_CODE_MASK) >> ARM_TBFLAG_BSWAP_CODE_SHIFT)
+#define ARM_TBFLAG_SCTLR_B(F) \
+ (((F) & ARM_TBFLAG_SCTLR_B_MASK) >> ARM_TBFLAG_SCTLR_B_SHIFT)
#define ARM_TBFLAG_XSCALE_CPAR(F) \
(((F) & ARM_TBFLAG_XSCALE_CPAR_MASK) >> ARM_TBFLAG_XSCALE_CPAR_SHIFT)
#define ARM_TBFLAG_NS(F) \
(((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT)
+static inline bool bswap_code(bool sctlr_b)
+{
+#ifdef CONFIG_USER_ONLY
+ /* BE8 (SCTLR.B = 0, TARGET_WORDS_BIGENDIAN = 1) is mixed endian.
+ * The invalid combination SCTLR.B=1/CPSR.E=1/TARGET_WORDS_BIGENDIAN=0
+ * would also end up as a mixed-endian mode with BE code, LE data.
+ */
+ 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
+}
+
/* Return the exception level to which FP-disabled exceptions should
* be taken, or 0 if FP is enabled.
*/
@@ -2049,7 +2080,7 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
| (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
| (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
| (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
- | (env->bswap_code << ARM_TBFLAG_BSWAP_CODE_SHIFT);
+ | (arm_sctlr_b(env) << ARM_TBFLAG_SCTLR_B_SHIFT);
if (!(access_secure_reg(env))) {
*flags |= ARM_TBFLAG_NS_MASK;
}
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 935f13b..0a0e85d 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -5848,7 +5848,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
case EXCP_BKPT:
if (semihosting_enabled()) {
int nr;
- nr = arm_lduw_code(env, env->regs[15], env->bswap_code) & 0xff;
+ nr = arm_lduw_code(env, env->regs[15], arm_sctlr_b(env)) & 0xff;
if (nr == 0xab) {
env->regs[15] += 2;
qemu_log_mask(CPU_LOG_INT,
@@ -6386,13 +6386,13 @@ static inline bool check_for_semihosting(CPUState *cs)
case EXCP_SWI:
/* Check for semihosting interrupt. */
if (env->thumb) {
- imm = arm_lduw_code(env, env->regs[15] - 2, env->bswap_code)
+ imm = arm_lduw_code(env, env->regs[15] - 2, arm_sctlr_b(env))
& 0xff;
if (imm == 0xab) {
break;
}
} else {
- imm = arm_ldl_code(env, env->regs[15] - 4, env->bswap_code)
+ imm = arm_ldl_code(env, env->regs[15] - 4, arm_sctlr_b(env))
& 0xffffff;
if (imm == 0x123456) {
break;
@@ -6402,7 +6402,7 @@ static inline bool check_for_semihosting(CPUState *cs)
case EXCP_BKPT:
/* See if this is a semihosting syscall. */
if (env->thumb) {
- imm = arm_lduw_code(env, env->regs[15], env->bswap_code)
+ imm = arm_lduw_code(env, env->regs[15], arm_sctlr_b(env))
& 0xff;
if (imm == 0xab) {
env->regs[15] += 2;
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 7f65aea..f6dd44b 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -10966,7 +10966,7 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
- insn = arm_ldl_code(env, s->pc, s->bswap_code);
+ insn = arm_ldl_code(env, s->pc, s->sctlr_b);
s->insn = insn;
s->pc += 4;
@@ -11031,7 +11031,7 @@ void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb)
dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
!arm_el_is_aa64(env, 3);
dc->thumb = 0;
- dc->bswap_code = 0;
+ dc->sctlr_b = 0;
dc->condexec_mask = 0;
dc->condexec_cond = 0;
dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
@@ -11217,7 +11217,7 @@ done_generating:
qemu_log("----------------\n");
qemu_log("IN: %s\n", lookup_symbol(pc_start));
log_target_disas(cs, pc_start, dc->pc - pc_start,
- 4 | (dc->bswap_code << 1));
+ 4 | (bswap_code(dc->sctlr_b) ? 2 : 0));
qemu_log("\n");
}
#endif
diff --git a/target-arm/translate.c b/target-arm/translate.c
index c29c47f..b52bbc3 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -7770,7 +7770,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
if ((insn & 0x0ffffdff) == 0x01010000) {
ARCH(6);
/* setend */
- if (((insn >> 9) & 1) != s->bswap_code) {
+ if (((insn >> 9) & 1) != bswap_code(s->sctlr_b)) {
/* Dynamic endianness switching not implemented. */
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
goto illegal_op;
@@ -9286,7 +9286,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
/* Fall through to 32-bit decode. */
}
- insn = arm_lduw_code(env, s->pc, s->bswap_code);
+ insn = arm_lduw_code(env, s->pc, s->sctlr_b);
s->pc += 2;
insn |= (uint32_t)insn_hw1 << 16;
@@ -10528,7 +10528,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
}
}
- insn = arm_lduw_code(env, s->pc, s->bswap_code);
+ insn = arm_lduw_code(env, s->pc, s->sctlr_b);
s->pc += 2;
switch (insn >> 12) {
@@ -11099,7 +11099,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
case 2:
/* setend */
ARCH(6);
- if (((insn >> 3) & 1) != s->bswap_code) {
+ if (((insn >> 3) & 1) != bswap_code(s->sctlr_b)) {
/* Dynamic endianness switching not implemented. */
qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
goto illegal_op;
@@ -11253,7 +11253,7 @@ static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
}
/* This must be a Thumb insn */
- insn = arm_lduw_code(env, s->pc, s->bswap_code);
+ insn = arm_lduw_code(env, s->pc, s->sctlr_b);
if ((insn >> 11) >= 0x1d) {
/* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
@@ -11307,7 +11307,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
!arm_el_is_aa64(env, 3);
dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
- dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
+ dc->sctlr_b = ARM_TBFLAG_SCTLR_B(tb->flags);
dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
@@ -11487,7 +11487,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
}
}
} else {
- unsigned int insn = arm_ldl_code(env, dc->pc, dc->bswap_code);
+ unsigned int insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
dc->pc += 4;
disas_arm_insn(dc, insn);
}
@@ -11644,7 +11644,7 @@ done_generating:
qemu_log("----------------\n");
qemu_log("IN: %s\n", lookup_symbol(pc_start));
log_target_disas(cs, pc_start, dc->pc - pc_start,
- dc->thumb | (dc->bswap_code << 1));
+ dc->thumb | (dc->sctlr_b << 1));
qemu_log("\n");
}
#endif
diff --git a/target-arm/translate.h b/target-arm/translate.h
index 82e3f6b..5445232 100644
--- a/target-arm/translate.h
+++ b/target-arm/translate.h
@@ -16,7 +16,7 @@ typedef struct DisasContext {
struct TranslationBlock *tb;
int singlestep_enabled;
int thumb;
- int bswap_code;
+ int sctlr_b;
#if !defined(CONFIG_USER_ONLY)
int user;
#endif
--
1.9.1
next prev parent reply other threads:[~2016-03-04 11:42 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-04 11:41 [Qemu-devel] [PULL 00/30] target-arm queue Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 01/30] target-arm: Correct handling of writes to CPSR mode bits from gdb in usermode Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 02/30] virt: Lift the maximum RAM limit from 30GB to 255GB Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 03/30] sd.c: Handle NULL block backend in sd_get_inserted() Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 04/30] sdhci: Implement DeviceClass reset Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 05/30] hw/arm/virt: Provide a secure-only RAM if booting in Secure mode Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 06/30] loader: Add load_image_mr() to load ROM image to a MemoryRegion Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 07/30] hw/arm/virt: Load bios image to MemoryRegion, not physaddr Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 08/30] hw/arm/virt: Make first flash device Secure-only if booting secure Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 09/30] hw/arm/virt: Assume EL3 boot rom will handle PSCI if one is provided Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 10/30] bcm2835_mbox/property: replace ldl_phys/stl_phys with endian-specific accesses Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 11/30] linux-user: arm: fix coding style for some linux-user signal functions Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 12/30] linux-user: arm: pass env to get_user_code_* Peter Maydell
2016-03-04 11:41 ` Peter Maydell [this message]
2016-03-04 11:41 ` [Qemu-devel] [PULL 14/30] target-arm: cpu: Move cpu_is_big_endian to header Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 15/30] arm: cpu: handle BE32 user-mode as BE Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 16/30] linux-user: arm: set CPSR.E/SCTLR.E0E correctly for BE mode Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 17/30] linux-user: arm: handle CPSR.E correctly in strex emulation Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 18/30] target-arm: implement SCTLR.EE Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 19/30] target-arm: pass DisasContext to gen_aa32_ld*/st* Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 20/30] target-arm: introduce disas flag for endianness Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 21/30] target-arm: a64: Add endianness support Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 22/30] target-arm: introduce tbflag for endianness Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 23/30] target-arm: implement setend Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 24/30] target-arm: implement BE32 mode in system emulation Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 25/30] loader: add API to load elf header Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 26/30] loader: load_elf(): Add doc comment Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 27/30] loader: Add data swap option to load-elf Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 28/30] arm: boot: Support big-endian elfs Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 29/30] hw/intc/arm_gic.c: Implement GICv2 GICC_DIR Peter Maydell
2016-03-04 11:41 ` [Qemu-devel] [PULL 30/30] target-arm: Only trap SRS from S-EL1 if specified mode is MON Peter Maydell
2016-03-04 14:05 ` [Qemu-devel] [PULL 00/30] target-arm queue Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1457091713-10138-14-git-send-email-peter.maydell@linaro.org \
--to=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).