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 */
27static inline void
28atomic_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 */
40static inline void
41atomic_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