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