@@ -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
@@ -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_ */
new file mode 100644
@@ -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();
+}