summaryrefslogtreecommitdiff
path: root/linux-user
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-01-04 22:15:45 +0000
committerPeter Maydell <peter.maydell@linaro.org>2014-01-07 19:17:59 +0000
commite4fe830b50b56561dae5b5c79c6eb63cc2e94a3d (patch)
tree8e2675c04f8ce7d50a91a7de75735b42770d6e4c /linux-user
parentb0d2b7d0f084f6b33acf7c722790da683916fee3 (diff)
downloadqemu-e4fe830b50b56561dae5b5c79c6eb63cc2e94a3d.tar.gz
target-arm: Widen thread-local register state fields to 64 bits
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 <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'linux-user')
-rw-r--r--linux-user/aarch64/target_cpu.h5
-rw-r--r--linux-user/arm/target_cpu.h2
-rw-r--r--linux-user/main.c2
3 files changed, 6 insertions, 3 deletions
diff --git a/linux-user/aarch64/target_cpu.h b/linux-user/aarch64/target_cpu.h
index 6f5539b50f..21560ef832 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 ed323c079d..39d65b692b 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 54f71fe8f6..c0df8b5cd4 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);