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 */
27static inline void
28atomic_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 */
47static inline void
48atomic_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_ */