[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] arm1136 CPU emulation won't run current kernels?
From: |
Rob Landley |
Subject: |
[Qemu-devel] arm1136 CPU emulation won't run current kernels? |
Date: |
Tue, 07 Jun 2011 19:32:07 -0500 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110424 Thunderbird/3.1.10 |
QEMU's -cpu arm1136 emulation stopped working in the 2.6.35 and later
kernels, now QEMU dies early in the kernel boot with:
qemu: fatal: Unimplemented cp15 register write (c13, c0, {0, 3})
This is due to this change to the Linux kernel:
commit f159f4ed55bb0fa5470800641e03a13a7e0eae6e
Author: Tony Lindgren <address@hidden>
Date: Mon Jul 5 14:53:10 2010 +0100
ARM: 6207/1: Replace CONFIG_HAS_TLS_REG with HWCAP_TLS and check for
it on V6
The TLS register is only available on ARM1136 r1p0 and later.
Set HWCAP_TLS flags if hardware TLS is available and test for
it if CONFIG_CPU_32v6K is not set for V6.
Which does is remove the CONFIG_HAS_TLS_REG kernel config symbol, and
replaces it with a probe. I.E. this code:
+++ b/arch/arm/kernel/entry-armv.S
-#if defined(CONFIG_HAS_TLS_REG)
- mcr p15, 0, r3, c13, c0, 3 @ set TLS register
-#elif !defined(CONFIG_TLS_REG_EMUL)
- mov r4, #0xffff0fff
- str r3, [r4, #-15] @ TLS val at 0xffff0ff0
-#endif
Becomes this code:
+++ b/arch/arm/include/asm/hwcap.h
+#define HWCAP_TLS 32768
+ .macro set_tls_v6, tp, tmp1, tmp2
+ ldr \tmp1, =elf_hwcap
+ ldr \tmp1, [\tmp1, #0]
+ mov \tmp2, #0xffff0fff
+ tst \tmp1, #HWCAP_TLS @ hardware TLS available?
+ mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register
+ streq \tp, [\tmp2, #-15] @ set TLS value at
0xffff0ff0
+ .endm
The elf_hwcap variable with the HWCAP_TLS bit is initialized (in
mm/proc-v6.S) with HWCAP_TLS always set, and then this switches it off:
+static void __init feat_v6_fixup(void)
+{
+ int id = read_cpuid_id();
+
+ if ((id & 0xff0f0000) != 0x41070000)
+ return;
+
+ /*
+ * HWCAP_TLS is available only on 1136 r1p0 and later,
+ * see also kuser_get_tls_init.
+ */
+ if ((((id >> 4) & 0xfff) == 0xb36) && (((id >> 20) & 3) == 0))
+ elf_hwcap &= ~HWCAP_TLS;
+}
+
The CPUID for arm1136 QEMU emulates a process that should have hardware
TLS (target-arm/cpu.h):
#define ARM_CPUID_ARM1136 0x4117b363
Meaning the above "switch it off" test doesn't trigger, the kernel tries
to access a hardware feature QEMU doesn't emulate, and QEMU aborts.
Note: I can work around this with -cpu arm1136-r2 (0x4107b363), but it
seems like the correct fix would be to add "hardware" TLS support to arm
kernels. Is this currently on anybody's todo list? (Is there a data
sheet somewhere...?)
Rob
- [Qemu-devel] arm1136 CPU emulation won't run current kernels?,
Rob Landley <=