diff options
author | Gary King <gking@nvidia.com> | 2010-03-04 16:06:41 -0800 |
---|---|---|
committer | Brint E. Kriebel <github@bekit.net> | 2010-12-21 14:57:18 -0800 |
commit | 0c7118ebce06618014e697454649420e39438885 (patch) | |
tree | b2d708a899a361664df470eeab659b6ae071d95f | |
parent | 562404678bae93371290243d196040a74dd57d83 (diff) | |
download | bionic-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.mk | 3 | ||||
-rw-r--r-- | libc/private/bionic_tls.h | 7 | ||||
-rw-r--r-- | linker/Android.mk | 3 |
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 |