summaryrefslogtreecommitdiffstats
path: root/libc/arch-arm
diff options
context:
space:
mode:
authorvinay harugop <vinay.harugop@stericsson.com>2009-09-09 20:53:39 +0530
committervinay harugop <vinay.harugop@stericsson.com>2009-09-09 21:01:46 +0530
commit76ec6891e2bc18c9e12cd2f567358bb817b24cff (patch)
tree4623c956fcb7404faeb72a347620ce65406276a0 /libc/arch-arm
parenta90528ad3420c571987f2124955646dae88007b6 (diff)
downloadbionic-76ec6891e2bc18c9e12cd2f567358bb817b24cff.zip
bionic-76ec6891e2bc18c9e12cd2f567358bb817b24cff.tar.gz
bionic-76ec6891e2bc18c9e12cd2f567358bb817b24cff.tar.bz2
ARM architecture reference manuals for ARMv6 & ARMv7 state that the use of 'swp' instruction is deprecated
ARMv6 onwards. These architectures provide the load-linked, store-conditional pair of ldrex/strex whose use is recommended in place of 'swp'. Also, the description of the 'swp' instruction in the ARMv6 reference manual states that the swap operation does not include any memory barrier guarantees.This fix attempts to address these issues by providing an atomic swap implementation using ldrex/strex under _ARM_HAVE_LDREX_STREX macro. This Fix is verified on ST Ericsson's U8500 platform and Submitted on behalf of a third-party: Surinder-pal SINGH from STMicroelectronics.
Diffstat (limited to 'libc/arch-arm')
-rw-r--r--libc/arch-arm/bionic/atomics_arm.S10
-rw-r--r--libc/arch-arm/include/machine/cpu-features.h7
2 files changed, 17 insertions, 0 deletions
diff --git a/libc/arch-arm/bionic/atomics_arm.S b/libc/arch-arm/bionic/atomics_arm.S
index b2da09f..57c4239 100644
--- a/libc/arch-arm/bionic/atomics_arm.S
+++ b/libc/arch-arm/bionic/atomics_arm.S
@@ -129,8 +129,18 @@ __atomic_inc:
#endif
/* r0(new) r1(addr) -> r0(old) */
+/* replaced swp instruction with ldrex/strex for ARMv6 & ARMv7 */
__atomic_swap:
+#if defined (_ARM_HAVE_LDREX_STREX)
+1: ldrex r2, [r1]
+ strex r3, r0, [r1]
+ teq r3, #0
+ bne 1b
+ mov r0, r2
+ mcr p15, 0, r0, c7, c10, 5 /* or, use dmb */
+#else
swp r0, r0, [r1]
+#endif
bx lr
/* __futex_wait(*ftx, val, *timespec) */
diff --git a/libc/arch-arm/include/machine/cpu-features.h b/libc/arch-arm/include/machine/cpu-features.h
index f836006..ecf6ff6 100644
--- a/libc/arch-arm/include/machine/cpu-features.h
+++ b/libc/arch-arm/include/machine/cpu-features.h
@@ -149,6 +149,13 @@
# define __ARM_HAVE_PC_INTERWORK
#endif
+/* define _ARM_HAVE_LDREX_STREX for ARMv6 and ARMv7 architecure to be
+ * used in replacement of depricated swp instruction
+ */
+#if __ARM_ARCH__ >= 6
+# define _ARM_HAVE_LDREX_STREX
+#endif
+
/* Assembly-only macros */