summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsg <jsg@openbsd.org>2017-02-04 04:17:43 +0000
committerjsg <jsg@openbsd.org>2017-02-04 04:17:43 +0000
commit2fd5b62e6b51eea6fe821a44ca4d5cf4eb24facf (patch)
tree1e9a88243217bfeb3247b2ea89b759f4819473ba
parentMove the typedefs for in_{addr,port}_t from <sys/types.h> to (diff)
downloadwireguard-openbsd-2fd5b62e6b51eea6fe821a44ca4d5cf4eb24facf.tar.xz
wireguard-openbsd-2fd5b62e6b51eea6fe821a44ca4d5cf4eb24facf.zip
Implement atomic_{set,clear}bits_int and membars for arm64.
With feedback from Dale Rahn, ok patrick@.
-rw-r--r--sys/arch/arm64/include/atomic.h63
1 files changed, 44 insertions, 19 deletions
diff --git a/sys/arch/arm64/include/atomic.h b/sys/arch/arm64/include/atomic.h
index 0c19c752bac..7de934ca7d0 100644
--- a/sys/arch/arm64/include/atomic.h
+++ b/sys/arch/arm64/include/atomic.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: atomic.h,v 1.1 2016/12/17 23:38:33 patrick Exp $ */
+/* $OpenBSD: atomic.h,v 1.2 2017/02/04 04:17:43 jsg Exp $ */
/* Public Domain */
@@ -6,34 +6,59 @@
#define _MACHINE_ATOMIC_H_
#if defined(_KERNEL)
-//#include <sys/stdatomic.h>
#define __membar(_f) do { __asm __volatile(_f ::: "memory"); } while (0)
+#define membar_enter() __membar("dmb sy")
+#define membar_exit() __membar("dmb sy")
+#define membar_producer() __membar("dmb st")
+#define membar_consumer() __membar("dmb ld")
+#define membar_sync() __membar("dmb sy")
+
/* virtio needs MP membars even on SP kernels */
-#define virtio_membar_producer() __membar("")
-#define virtio_membar_consumer() __membar("")
-#define virtio_membar_sync() __membar("dmb sy") /* XXX dmb? */
+#define virtio_membar_producer() __membar("dmb st")
+#define virtio_membar_consumer() __membar("dmb ld")
+#define virtio_membar_sync() __membar("dmb sy")
+/*
+ * Set bits
+ * *p = *p | v
+ */
static inline void
-atomic_setbits_int(__volatile unsigned int *ptr, unsigned int val)
+atomic_setbits_int(volatile unsigned int *p, unsigned int v)
{
-#if 0
- //FIXME
- atomic_fetch_or_explicit((atomic_uint *)ptr, val, memory_order_seq_cst);
-#else
- *ptr |= val;
-#endif
+ unsigned int modified, tmp;
+
+ __asm volatile (
+ "1: ldxr %w0, [%x3] \n\t"
+ " orr %w0, %w0, %w2 \n\t"
+ " stxr %w1, %w0, [%x3] \n\t"
+ " cbnz %w1, 1b \n\t"
+ : "=&r" (tmp), "=&r" (modified)
+ : "r" (v), "r" (p)
+ : "memory", "cc"
+ );
}
+
+/*
+ * Clear bits
+ * *p = *p & (~v)
+ */
static inline void
-atomic_clearbits_int(__volatile unsigned int *ptr, unsigned int val)
+atomic_clearbits_int(volatile unsigned int *p, unsigned int v)
{
-#if 0
- //FIXME
- atomic_fetch_and_explicit((atomic_uint *)ptr, ~val, memory_order_seq_cst);
-#else
- *ptr &= ~val;
-#endif
+ unsigned int modified, tmp;
+
+ __asm volatile (
+ "1: ldxr %w0, [%x3] \n\t"
+ " bic %w0, %w0, %w2 \n\t"
+ " stxr %w1, %w0, [%x3] \n\t"
+ " cbnz %w1, 1b \n\t"
+ : "=&r" (tmp), "=&r" (modified)
+ : "r" (v), "r" (p)
+ : "memory", "cc"
+ );
}
+
#endif /* defined(_KERNEL) */
#endif /* _MACHINE_ATOMIC_H_ */