[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 16/76] target-arm: Widen thread-local register state
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 16/76] target-arm: Widen thread-local register state fields to 64 bits |
Date: |
Tue, 7 Jan 2014 20:03:12 +0000 |
The common pattern for system registers in a 64-bit capable ARM
CPU is that when in AArch32 the cp15 register is a view of the
bottom 32 bits of the 64-bit AArch64 system register; writes in
AArch32 leave the top half unchanged. The most natural way to
model this is to have the state field in the CPU struct be a
64 bit value, and simply have the AArch32 TCG code operate on
a pointer to its lower half.
For aarch64-linux-user the only registers we need to share like
this are the thread-local-storage ones. Widen their fields to
64 bits and provide the 64 bit reginfo struct to make them
visible in AArch64 state. Note that minor cleanup of the AArch64
system register encoding space means We can share the TPIDR_EL1
reginfo but need split encodings for TPIDR_EL0 and TPIDRRO_EL0.
Since we're touching almost every line in QEMU that uses the
c13_tls* fields in this patch anyway, we take the opportunity
to rename them in line with the standard ARM architectural names
for these registers.
Signed-off-by: Peter Maydell <address@hidden>
Reviewed-by: Richard Henderson <address@hidden>
---
linux-user/aarch64/target_cpu.h | 5 ++++-
linux-user/arm/target_cpu.h | 2 +-
linux-user/main.c | 2 +-
target-arm/cpu.h | 18 +++++++++++++++---
target-arm/helper.c | 22 +++++++++++++++-------
5 files changed, 36 insertions(+), 13 deletions(-)
diff --git a/linux-user/aarch64/target_cpu.h b/linux-user/aarch64/target_cpu.h
index 6f5539b..21560ef 100644
--- a/linux-user/aarch64/target_cpu.h
+++ b/linux-user/aarch64/target_cpu.h
@@ -29,7 +29,10 @@ static inline void cpu_clone_regs(CPUARMState *env,
target_ulong newsp)
static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls)
{
- env->sr.tpidr_el0 = newtls;
+ /* Note that AArch64 Linux keeps the TLS pointer in TPIDR; this is
+ * different from AArch32 Linux, which uses TPIDRRO.
+ */
+ env->cp15.tpidr_el0 = newtls;
}
#endif
diff --git a/linux-user/arm/target_cpu.h b/linux-user/arm/target_cpu.h
index ed323c0..39d65b6 100644
--- a/linux-user/arm/target_cpu.h
+++ b/linux-user/arm/target_cpu.h
@@ -29,7 +29,7 @@ static inline void cpu_clone_regs(CPUARMState *env,
target_ulong newsp)
static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls)
{
- env->cp15.c13_tls2 = newtls;
+ env->cp15.tpidrro_el0 = newtls;
}
#endif
diff --git a/linux-user/main.c b/linux-user/main.c
index 54f71fe..c0df8b5 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -566,7 +566,7 @@ do_kernel_trap(CPUARMState *env)
end_exclusive();
break;
case 0xffff0fe0: /* __kernel_get_tls */
- env->regs[0] = env->cp15.c13_tls2;
+ env->regs[0] = env->cp15.tpidrro_el0;
break;
case 0xffff0f60: /* __kernel_cmpxchg64 */
arm_kernel_cmpxchg64_helper(env);
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index ab8ef17..fc36514 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -66,6 +66,18 @@
/* ARM-specific interrupt pending bits. */
#define CPU_INTERRUPT_FIQ CPU_INTERRUPT_TGT_EXT_1
+/* The usual mapping for an AArch64 system register to its AArch32
+ * counterpart is for the 32 bit world to have access to the lower
+ * half only (with writes leaving the upper half untouched). It's
+ * therefore useful to be able to pass TCG the offset of the least
+ * significant half of a uint64_t struct member.
+ */
+#ifdef HOST_WORDS_BIGENDIAN
+#define offsetoflow32(S, M) (offsetof(S, M + sizeof(uint32_t))
+#else
+#define offsetoflow32(S, M) offsetof(S, M)
+#endif
+
/* Meanings of the ARMCPU object's two inbound GPIO lines */
#define ARM_CPU_IRQ 0
#define ARM_CPU_FIQ 1
@@ -188,9 +200,9 @@ typedef struct CPUARMState {
uint32_t c12_vbar; /* vector base address register */
uint32_t c13_fcse; /* FCSE PID. */
uint32_t c13_context; /* Context ID. */
- uint32_t c13_tls1; /* User RW Thread register. */
- uint32_t c13_tls2; /* User RO Thread register. */
- uint32_t c13_tls3; /* Privileged Thread register. */
+ uint64_t tpidr_el0; /* User RW Thread register. */
+ uint64_t tpidrro_el0; /* User RO Thread register. */
+ uint64_t tpidr_el1; /* Privileged Thread register. */
uint32_t c14_cntfrq; /* Counter Frequency register */
uint32_t c14_cntkctl; /* Timer Control register */
ARMGenericTimer c14_timer[NUM_GTIMERS];
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 3efe8b4..f91e3fd 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -740,18 +740,26 @@ static const ARMCPRegInfo t2ee_cp_reginfo[] = {
};
static const ARMCPRegInfo v6k_cp_reginfo[] = {
+ { .name = "TPIDR_EL0", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 3, .opc2 = 2, .crn = 13, .crm = 0,
+ .access = PL0_RW,
+ .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el0), .resetvalue = 0 },
{ .name = "TPIDRURW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 2,
.access = PL0_RW,
- .fieldoffset = offsetof(CPUARMState, cp15.c13_tls1),
- .resetvalue = 0 },
+ .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidr_el0),
+ .resetfn = arm_cp_reset_ignore },
+ { .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 3, .opc2 = 3, .crn = 13, .crm = 0,
+ .access = PL0_R|PL1_W,
+ .fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el0), .resetvalue = 0
},
{ .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3,
.access = PL0_R|PL1_W,
- .fieldoffset = offsetof(CPUARMState, cp15.c13_tls2),
- .resetvalue = 0 },
- { .name = "TPIDRPRW", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 4,
+ .fieldoffset = offsetoflow32(CPUARMState, cp15.tpidrro_el0),
+ .resetfn = arm_cp_reset_ignore },
+ { .name = "TPIDR_EL1", .state = ARM_CP_STATE_BOTH,
+ .opc0 = 3, .opc1 = 0, .opc2 = 4, .crn = 13, .crm = 0,
.access = PL1_RW,
- .fieldoffset = offsetof(CPUARMState, cp15.c13_tls3),
- .resetvalue = 0 },
+ .fieldoffset = offsetof(CPUARMState, cp15.tpidr_el1), .resetvalue = 0 },
REGINFO_SENTINEL
};
--
1.8.5
- [Qemu-devel] [PULL 56/76] softfloat: Make the int-to-float functions take exact-width types, (continued)
- [Qemu-devel] [PULL 56/76] softfloat: Make the int-to-float functions take exact-width types, Peter Maydell, 2014/01/07
- [Qemu-devel] [PULL 13/76] target-arm: Remove ARMCPU/CPUARMState from cpregs APIs used by decoder, Peter Maydell, 2014/01/07
- [Qemu-devel] [PULL 01/76] target-arm: A64: add support for ld/st pair, Peter Maydell, 2014/01/07
- [Qemu-devel] [PULL 07/76] target-arm: A64: add support for 3 src data proc insns, Peter Maydell, 2014/01/07
- [Qemu-devel] [PULL 06/76] target-arm: A64: add support for move wide instructions, Peter Maydell, 2014/01/07
- [Qemu-devel] [PULL 05/76] target-arm: A64: add support for add, addi, sub, subi, Peter Maydell, 2014/01/07
- [Qemu-devel] [PULL 25/76] default-configs: Add config for aarch64-linux-user, Peter Maydell, 2014/01/07
- [Qemu-devel] [PULL 26/76] target-arm: A64: Add support for dumping AArch64 VFP register state, Peter Maydell, 2014/01/07
- [Qemu-devel] [PULL 17/76] target-arm: A64: add support for add/sub with carry, Peter Maydell, 2014/01/07
- [Qemu-devel] [PULL 28/76] target-arm: Use VFP_BINOP macro for min, max, minnum, maxnum, Peter Maydell, 2014/01/07
- [Qemu-devel] [PULL 16/76] target-arm: Widen thread-local register state fields to 64 bits,
Peter Maydell <=
- [Qemu-devel] [PULL 21/76] target-arm: A64: support for ld/st/cl exclusive, Peter Maydell, 2014/01/07
- [Qemu-devel] [PULL 02/76] target-arm: A64: add support for ld/st unsigned imm, Peter Maydell, 2014/01/07
- [Qemu-devel] [PULL 15/76] target-arm: A64: Implement minimal set of EL0-visible sysregs, Peter Maydell, 2014/01/07
- [Qemu-devel] [PULL 04/76] target-arm: A64: add support for ld/st with index, Peter Maydell, 2014/01/07
- [Qemu-devel] [PULL 08/76] target-arm: A64: implement SVC, BRK, Peter Maydell, 2014/01/07
- [Qemu-devel] [PULL 74/76] target-arm: A64: Add floating-point<->integer conversion instructions, Peter Maydell, 2014/01/07
- [Qemu-devel] [PULL 32/76] target-arm: A64: Add support for floating point compare, Peter Maydell, 2014/01/07
- [Qemu-devel] [PULL 37/76] char/cadence_uart: Add missing uart_update_state, Peter Maydell, 2014/01/07
- [Qemu-devel] [PULL 14/76] target-arm: A64: Implement MRS/MSR/SYS/SYSL, Peter Maydell, 2014/01/07