diff options
author | 2017-02-04 04:17:43 +0000 | |
---|---|---|
committer | 2017-02-04 04:17:43 +0000 | |
commit | 2fd5b62e6b51eea6fe821a44ca4d5cf4eb24facf (patch) | |
tree | 1e9a88243217bfeb3247b2ea89b759f4819473ba | |
parent | Move the typedefs for in_{addr,port}_t from <sys/types.h> to (diff) | |
download | wireguard-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.h | 63 |
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_ */ |