[PATCH v6 13/17] arm: Add spinlock implementation

Andrew Jones
2014-07-11T08:20:21Z

From: Christoffer Dall <christoffer.dall@linaro.org>

Add simple busy-wait spinlock implementation for ARM.

Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
config/config-arm.mak | 3 ++-
lib/arm/asm/spinlock.h | 9 ++-------
lib/arm/spinlock.c | 28 ++++++++++++++++++++++++++++
3 files changed, 32 insertions(+), 8 deletions(-)
create mode 100644 lib/arm/spinlock.c

diff --git a/config/config-arm.mak b/config/config-arm.mak
index 3225018faf933..fb160b6c65e2a 100644
--- a/config/config-arm.mak
+++ b/config/config-arm.mak
@@ -36,7 +36,8 @@ cflatobjs += \
lib/virtio.o \
lib/chr-testdev.o \
lib/arm/io.o \
- lib/arm/setup.o
+ lib/arm/setup.o \
+ lib/arm/spinlock.o

libeabi = lib/arm/libeabi.a
eabiobjs = lib/arm/eabi_compat.o
diff --git a/lib/arm/asm/spinlock.h b/lib/arm/asm/spinlock.h
index 04f5a1a5538e2..2118a4b3751e0 100644
--- a/lib/arm/asm/spinlock.h
+++ b/lib/arm/asm/spinlock.h
@@ -5,12 +5,7 @@ struct spinlock {
int v;
};

-//TODO
-static inline void spin_lock(struct spinlock *lock __unused)
-{
-}
-static inline void spin_unlock(struct spinlock *lock __unused)
-{
-}
+extern void spin_lock(struct spinlock *lock);
+extern void spin_unlock(struct spinlock *lock);

#endif /* _ASMARM_SPINLOCK_H_ */
diff --git a/lib/arm/spinlock.c b/lib/arm/spinlock.c
new file mode 100644
index 0000000000000..d8a6d4c3383d6
--- /dev/null
+++ b/lib/arm/spinlock.c
@@ -0,0 +1,28 @@
+#include "libcflat.h"
+#include "asm/spinlock.h"
+#include "asm/barrier.h"
+
+void spin_lock(struct spinlock *lock)
+{
+ u32 val, fail;
+
+ dmb();
+ do {
+ asm volatile(
+ "1: ldrex %0, [%2]\n"
+ " teq %0, #0\n"
+ " bne 1b\n"
+ " mov %0, #1\n"
+ " strex %1, %0, [%2]\n"
+ : "=&r" (val), "=&r" (fail)
+ : "r" (&lock->v)
+ : "cc" );
+ } while (fail);
+ dmb();
+}
+
+void spin_unlock(struct spinlock *lock)
+{
+ lock->v = 0;
+ dmb();
+}
--
1.9.3