From 4a05d12cf52a9a40759f11f28543bd75715c8f00 Mon Sep 17 00:00:00 2001
From: David 'Digit' Turner <digit@google.com>
Date: Fri, 18 Sep 2009 13:35:05 -0700
Subject: Fix TLS access for ARMv6 and beyond.

For performance reasons, we don't call the kernel helper. Instead, we directly
access the TLS register on ARMv6 and higher. For ARMv5TE, keep using the hard-coded
address populated by the kernel on each task switch.

NOTE: Since we don't call the kernel helper, this must precisely match your
      kernel configuration. This is controlled by setting the ARCH_ARM_HAVE_TLS_REGISTER
      variable to 'true' in your board configuration file.
---
 libc/private/bionic_tls.h | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

(limited to 'libc/private')

diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 82c8cd9..2e7a82b 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -88,7 +88,18 @@ extern int __set_tls(void *ptr);
 
 /* get the TLS */
 #ifdef __arm__
-#  define __get_tls() ( *((volatile void **) 0xffff0ff0) )
+/* For performance reasons, avoid calling the kernel helper
+ * Note that HAVE_ARM_TLS_REGISTER is build-specific
+ * (it must match your kernel configuration)
+ */
+#  ifdef HAVE_ARM_TLS_REGISTER
+#    define __get_tls() \
+    ({ register unsigned int __val asm("r0"); \
+       asm ("mrc p15, 0, r0, c13, c0, 3" : "=r"(__val) ); \
+       (volatile void*)__val; })
+#  else /* !HAVE_ARM_TLS_REGISTER */
+#    define __get_tls() ( *((volatile void **) 0xffff0ff0) )
+#  endif
 #else
 extern void*  __get_tls( void );
 #endif
-- 
cgit v1.1