qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] arm1136 CPU emulation won't run current kernels?
@ 2011-06-08  0:32 Rob Landley
  2011-06-08 13:03 ` Peter Maydell
  0 siblings, 1 reply; 2+ messages in thread
From: Rob Landley @ 2011-06-08  0:32 UTC (permalink / raw)
  To: qemu-devel

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 <tony@atomide.com>
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

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [Qemu-devel] arm1136 CPU emulation won't run current kernels?
  2011-06-08  0:32 [Qemu-devel] arm1136 CPU emulation won't run current kernels? Rob Landley
@ 2011-06-08 13:03 ` Peter Maydell
  0 siblings, 0 replies; 2+ messages in thread
From: Peter Maydell @ 2011-06-08 13:03 UTC (permalink / raw)
  To: Rob Landley; +Cc: qemu-devel

On 8 June 2011 01:32, Rob Landley <rob@landley.net> wrote:
> 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})

> 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),

The QEMU bug here is that we provide the TLS cp15 registers only
if ARM_FEATURE_V6K, which is almost right except that they are also
available on the ARM1136 r1p0 and above. (I note in passing that the
QEMU CPU name "arm1136-r2" is rather misleading because in fact it's
providing an r0p2. The only difference to "arm1136" in the QEMU model
currently is the CPUID register value.)

1136r1p0 and above are a kind of halfway-house between v6 and v6K:
they have TLS regs, CLREX, load-store-exclusive for non-word sizes
and the NOP instruction, but are missing the v6K VA-PA translation,
SEV, WFE, WFI and YIELD.

I guess we need some more finegrained feature switches here
(also I think some actual code which implements "V7 implies
V6K, V6, V5, V4T" and so on rather than having each CPU set
them all by hand).

> (Is there a data sheet somewhere...?)

CPU-specific manuals (TRMs) are available from http://infocenter.arm.com/
The architecture reference manual is also available if you register as
a user on the website, which I'm told is a fairly hassle-free process.

-- PMM

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2011-06-08 13:03 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-06-08  0:32 [Qemu-devel] arm1136 CPU emulation won't run current kernels? Rob Landley
2011-06-08 13:03 ` Peter Maydell

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).