1 /* $OpenBSD: atomic.h,v 1.5 2024/01/24 12:25:50 jca 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("fence w,rw")
11 #define membar_exit() __membar("fence rw,w")
12 #define membar_producer() __membar("fence w,w")
13 #define membar_consumer() __membar("fence r,r")
14 #define membar_sync() __membar("fence rw,rw")
15
16 #if defined(_KERNEL)
17
18 /* virtio needs MP membars even on SP kernels */
19 #define virtio_membar_producer() __membar("fence w,w")
20 #define virtio_membar_consumer() __membar("fence r,r")
21 #define virtio_membar_sync() __membar("fence rw,rw")
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 __asm volatile("amoor.w zero, %1, %0"
31 : "+A" (*p)
32 : "r" (v)
33 : "memory");
34 }
35
36 /*
37 * Clear bits
38 * *p = *p & (~v)
39 */
40 static inline void
atomic_clearbits_int(volatile unsigned int * p,unsigned int v)41 atomic_clearbits_int(volatile unsigned int *p, unsigned int v)
42 {
43 __asm volatile("amoand.w zero, %1, %0"
44 : "+A" (*p)
45 : "r" (~v)
46 : "memory");
47 }
48
49 #endif /* defined(_KERNEL) */
50 #endif /* _MACHINE_ATOMIC_H_ */
51