qemu-devel
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]