xref: /openbsd-src/sys/arch/riscv64/include/atomic.h (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
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