From 43db8c57ebe496bea03d66e2ddd0aa6bc298738c Mon Sep 17 00:00:00 2001
From: Christian Cunningham <cc@localhost>
Date: Sun, 19 Dec 2021 14:50:45 -0800
Subject: Added atomic swap

---
 src/cpu/atomic/swap.a.h | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)
 create mode 100644 src/cpu/atomic/swap.a.h

(limited to 'src')

diff --git a/src/cpu/atomic/swap.a.h b/src/cpu/atomic/swap.a.h
new file mode 100644
index 0000000..63dd50b
--- /dev/null
+++ b/src/cpu/atomic/swap.a.h
@@ -0,0 +1,32 @@
+#ifndef CPU_ATOMIC_SWAP_A_H
+#define CPU_ATOMIC_SWAP_A_H
+
+/// https://stackoverflow.com/questions/16329123/use-of-strexeq-instead-of-strex-for-spinlock-implementation-in-arm
+
+static inline void atm_lock(unsigned long pid, unsigned long* addr) {
+	unsigned long tmp, current_lock_value;
+	asm volatile(
+"1:	ldrex	%0, [%3]\n"
+"	cmp	%0, #0\n"
+"	wfene\n"
+"	strexeq	%1, %2, [%3]\n"
+"	teq	%1, #0\n"
+"	bne	1b\n"
+"	dmb"
+	: "=&r" (current_lock_value), "=&r" (tmp)
+	: "r" (pid), "r" (addr)
+	: "cc");
+}
+
+static inline void atm_unlock(unsigned long* addr) {
+	unsigned long cleared = 0;
+	asm volatile(
+"	dmb\n"
+"	str %0, [%1]\n"
+"	dsb\n"
+"	sev"
+	:: "r" (cleared), "r" (addr)
+	: "cc");
+}
+
+#endif
-- 
cgit v1.2.1