summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGary King <gking@nvidia.com>2010-03-04 16:06:41 -0800
committerBrint E. Kriebel <github@bekit.net>2010-12-21 14:57:18 -0800
commit0c7118ebce06618014e697454649420e39438885 (patch)
treeb2d708a899a361664df470eeab659b6ae071d95f
parent562404678bae93371290243d196040a74dd57d83 (diff)
downloadbionic-0c7118ebce06618014e697454649420e39438885.zip
bionic-0c7118ebce06618014e697454649420e39438885.tar.gz
bionic-0c7118ebce06618014e697454649420e39438885.tar.bz2
[bionic] implement work around for tegra errata 657451
tegra 2 processors have a bug in the register read path of bit 20 of the CP15 c13, 3 register (used for software thread local storage) the kernel work-around for this bug is to mux the value from bit 20 into bit 0; since the TLS value used by Android is an aligned address, bit 0 is known to be available. Change-Id: If70afa52585d327f9dd5eca479c14ca92532ddd8 Reviewed-on: http://git-master/r/773 Reviewed-by: Gary King <gking@nvidia.com> Tested-by: Gary King <gking@nvidia.com>
-rw-r--r--libc/Android.mk3
-rw-r--r--libc/private/bionic_tls.h7
-rw-r--r--linker/Android.mk3
3 files changed, 13 insertions, 0 deletions
diff --git a/libc/Android.mk b/libc/Android.mk
index e6f8ece..0ebbd78 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -494,6 +494,9 @@ ifeq ($(TARGET_ARCH),arm)
ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true)
libc_common_cflags += -DHAVE_ARM_TLS_REGISTER
endif
+ ifeq ($(TARGET_HAVE_TEGRA_ERRATA_657451),true)
+ libc_common_cflags += -DHAVE_TEGRA_ERRATA_657451
+ endif
else # !arm
ifeq ($(TARGET_ARCH),x86)
libc_crt_target_cflags := -m32
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 008fd2f..94a81cd 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -111,6 +111,12 @@ extern int __set_tls(void *ptr);
* Note that HAVE_ARM_TLS_REGISTER is build-specific
* (it must match your kernel configuration)
*/
+# ifdef HAVE_TEGRA_ERRATA_657451
+# define __munge_tls(_v) ( ((_v)&~((1ul<<20)|1ul)) | (((_v)&0x1)<<20) )
+# else
+# define __munge_tls(_v) (_v)
+#endif
+
# ifdef HAVE_ARM_TLS_REGISTER
/* We can read the address directly from a coprocessor
* register, which avoids touching the data cache
@@ -119,6 +125,7 @@ extern int __set_tls(void *ptr);
# define __get_tls() \
({ register unsigned int __val asm("r0"); \
asm ("mrc p15, 0, r0, c13, c0, 3" : "=r"(__val) ); \
+ __val = __munge_tls(__val); \
(volatile void*)__val; })
# else /* !HAVE_ARM_TLS_REGISTER */
/* The kernel provides the address of the TLS at a fixed
diff --git a/linker/Android.mk b/linker/Android.mk
index c518c72..c4447bb 100644
--- a/linker/Android.mk
+++ b/linker/Android.mk
@@ -42,6 +42,9 @@ LOCAL_CFLAGS += -DLINKER_DEBUG=0
ifeq ($(TARGET_ARCH)-$(ARCH_ARM_HAVE_TLS_REGISTER),arm-true)
LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
endif
+ifeq ($(TARGET_HAVE_TEGRA_ERRATA_657451),true)
+ LOCAL_CFLAGS += -DHAVE_TEGRA_ERRATA_657451
+endif
ifeq ($(TARGET_HAVE_TEGRA_ERRATA_657451),true)
LOCAL_CFLAGS += -DHAVE_TEGRA_ERRATA_657451