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("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 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 static inline void 37 atomic_store_64(volatile uint64_t *p, uint64_t v) 38 { 39 __asm volatile("amoor.d zero, %1, %0" 40 : "+A" (*p) 41 : "r" (v) 42 : "memory"); 43 } 44 45 /* 46 * Clear bits 47 * *p = *p & (~v) 48 */ 49 static inline void 50 atomic_clearbits_int(volatile unsigned int *p, unsigned int v) 51 { 52 __asm volatile("amoand.w zero, %1, %0" 53 : "+A" (*p) 54 : "r" (~v) 55 : "memory"); 56 } 57 58 #endif /* defined(_KERNEL) */ 59 #endif /* _MACHINE_ATOMIC_H_ */ 60