xref: /openbsd-src/sys/arch/arm64/include/atomic.h (revision dd81489db8c6745c0e25d81d82e97f90d8886b12)
1 /* $OpenBSD: atomic.h,v 1.4 2022/08/29 02:01:18 jsg Exp $ */
2 
3 /* Public Domain */
4 
5 #ifndef _MACHINE_ATOMIC_H_
6 #define _MACHINE_ATOMIC_H_
7 
8 #define __membar(_f) do { __asm volatile(_f ::: "memory"); } while (0)
9 
10 #define membar_enter()		__membar("dmb sy")
11 #define membar_exit()		__membar("dmb sy")
12 #define membar_producer()	__membar("dmb st")
13 #define membar_consumer()	__membar("dmb ld")
14 #define membar_sync()		__membar("dmb sy")
15 
16 #if defined(_KERNEL)
17 
18 /* virtio needs MP membars even on SP kernels */
19 #define virtio_membar_producer()	__membar("dmb st")
20 #define virtio_membar_consumer()	__membar("dmb ld")
21 #define virtio_membar_sync()		__membar("dmb sy")
22 
23 /*
24  * Set bits
25  * *p = *p | v
26  */
27 static inline void
atomic_setbits_int(volatile unsigned int * p,unsigned int v)28 atomic_setbits_int(volatile unsigned int *p, unsigned int v)
29 {
30 	unsigned int modified, tmp;
31 
32 	__asm volatile (
33 	    "1:	ldxr %w0, [%x3]		\n\t"
34 	    "	orr %w0, %w0, %w2	\n\t"
35 	    "	stxr %w1, %w0, [%x3]	\n\t"
36 	    "	cbnz %w1, 1b		\n\t"
37 	    : "=&r" (tmp), "=&r" (modified)
38 	    : "r" (v), "r" (p)
39 	    : "memory", "cc"
40 	);
41 }
42 
43 /*
44  * Clear bits
45  * *p = *p & (~v)
46  */
47 static inline void
atomic_clearbits_int(volatile unsigned int * p,unsigned int v)48 atomic_clearbits_int(volatile unsigned int *p, unsigned int v)
49 {
50 	unsigned int modified, tmp;
51 
52 	__asm volatile (
53 	    "1:	ldxr %w0, [%x3]		\n\t"
54 	    "	bic %w0, %w0, %w2	\n\t"
55 	    "	stxr %w1, %w0, [%x3]	\n\t"
56 	    "	cbnz %w1, 1b		\n\t"
57 	    : "=&r" (tmp), "=&r" (modified)
58 	    : "r" (v), "r" (p)
59 	    : "memory", "cc"
60 	);
61 }
62 
63 #endif /* defined(_KERNEL) */
64 #endif /* _MACHINE_ATOMIC_H_ */
65