1*dd81489dSjsg /* $OpenBSD: atomic.h,v 1.16 2022/08/29 02:01:18 jsg Exp $ */
2f57756c9Sart
3f57756c9Sart /* Public Domain */
4f57756c9Sart
52fa72412Spirofti #ifndef _M88K_ATOMIC_H_
62fa72412Spirofti #define _M88K_ATOMIC_H_
7f57756c9Sart
88aa3ef09Sderaadt #if defined(_KERNEL)
98aa3ef09Sderaadt
1014c2d172Smiod #ifdef MULTIPROCESSOR
11bb0d2ff6Smiod
12bb0d2ff6Smiod /* actual implementation is hairy, see atomic.S */
132df76cc2Sguenther void atomic_setbits_int(volatile unsigned int *, unsigned int);
142df76cc2Sguenther void atomic_clearbits_int(volatile unsigned int *, unsigned int);
1538fd2302Smiod unsigned int atomic_add_int_nv_mp(volatile unsigned int *, unsigned int);
1638fd2302Smiod unsigned int atomic_sub_int_nv_mp(volatile unsigned int *, unsigned int);
1738fd2302Smiod unsigned int atomic_cas_uint_mp(unsigned int *, unsigned int, unsigned int);
1838fd2302Smiod unsigned int atomic_swap_uint_mp(unsigned int *, unsigned int);
1938fd2302Smiod
2038fd2302Smiod #define atomic_add_int_nv atomic_add_int_nv_mp
2138fd2302Smiod #define atomic_sub_int_nv atomic_sub_int_nv_mp
2238fd2302Smiod #define atomic_cas_uint atomic_cas_uint_mp
2338fd2302Smiod #define atomic_swap_uint atomic_swap_uint_mp
24bb0d2ff6Smiod
25bb0d2ff6Smiod #else
26bb0d2ff6Smiod
27bb0d2ff6Smiod #include <machine/asm_macro.h>
28bb0d2ff6Smiod #include <machine/psl.h>
2914c2d172Smiod
30f57756c9Sart static __inline void
atomic_setbits_int(volatile unsigned int * uip,unsigned int v)312df76cc2Sguenther atomic_setbits_int(volatile unsigned int *uip, unsigned int v)
32f57756c9Sart {
3314c2d172Smiod u_int psr;
34f70b2a0dSmiod
3514c2d172Smiod psr = get_psr();
3614c2d172Smiod set_psr(psr | PSR_IND);
3714c2d172Smiod *uip |= v;
3814c2d172Smiod set_psr(psr);
39f57756c9Sart }
40f57756c9Sart
41f57756c9Sart static __inline void
atomic_clearbits_int(volatile unsigned int * uip,unsigned int v)422df76cc2Sguenther atomic_clearbits_int(volatile unsigned int *uip, unsigned int v)
43f57756c9Sart {
4414c2d172Smiod u_int psr;
45f70b2a0dSmiod
4614c2d172Smiod psr = get_psr();
4714c2d172Smiod set_psr(psr | PSR_IND);
4814c2d172Smiod *uip &= ~v;
4914c2d172Smiod set_psr(psr);
50f57756c9Sart }
51f57756c9Sart
5238fd2302Smiod static __inline unsigned int
atomic_add_int_nv_sp(volatile unsigned int * uip,unsigned int v)5338fd2302Smiod atomic_add_int_nv_sp(volatile unsigned int *uip, unsigned int v)
5438fd2302Smiod {
5538fd2302Smiod u_int psr;
5638fd2302Smiod unsigned int nv;
5738fd2302Smiod
5838fd2302Smiod psr = get_psr();
5938fd2302Smiod set_psr(psr | PSR_IND);
6038fd2302Smiod *uip += v;
6138fd2302Smiod nv = *uip;
6238fd2302Smiod set_psr(psr);
6338fd2302Smiod
6438fd2302Smiod return nv;
6538fd2302Smiod }
6638fd2302Smiod
6738fd2302Smiod static __inline unsigned int
atomic_sub_int_nv_sp(volatile unsigned int * uip,unsigned int v)6838fd2302Smiod atomic_sub_int_nv_sp(volatile unsigned int *uip, unsigned int v)
6938fd2302Smiod {
7038fd2302Smiod u_int psr;
7138fd2302Smiod unsigned int nv;
7238fd2302Smiod
7338fd2302Smiod psr = get_psr();
7438fd2302Smiod set_psr(psr | PSR_IND);
7538fd2302Smiod *uip -= v;
7638fd2302Smiod nv = *uip;
7738fd2302Smiod set_psr(psr);
7838fd2302Smiod
7938fd2302Smiod return nv;
8038fd2302Smiod }
8138fd2302Smiod
8238fd2302Smiod static inline unsigned int
atomic_cas_uint_sp(unsigned int * p,unsigned int o,unsigned int n)8338fd2302Smiod atomic_cas_uint_sp(unsigned int *p, unsigned int o, unsigned int n)
8438fd2302Smiod {
8538fd2302Smiod u_int psr;
8638fd2302Smiod unsigned int ov;
8738fd2302Smiod
8838fd2302Smiod psr = get_psr();
8938fd2302Smiod set_psr(psr | PSR_IND);
9038fd2302Smiod ov = *p;
9138fd2302Smiod if (ov == o)
9238fd2302Smiod *p = n;
9338fd2302Smiod set_psr(psr);
9438fd2302Smiod
9538fd2302Smiod return ov;
9638fd2302Smiod }
9738fd2302Smiod
9838fd2302Smiod static inline unsigned int
atomic_swap_uint_sp(unsigned int * p,unsigned int v)9938fd2302Smiod atomic_swap_uint_sp(unsigned int *p, unsigned int v)
10038fd2302Smiod {
10138fd2302Smiod u_int psr;
10238fd2302Smiod unsigned int ov;
10338fd2302Smiod
10438fd2302Smiod psr = get_psr();
10538fd2302Smiod set_psr(psr | PSR_IND);
10638fd2302Smiod ov = *p;
10738fd2302Smiod *p = v;
10838fd2302Smiod set_psr(psr);
10938fd2302Smiod
11038fd2302Smiod return ov;
11138fd2302Smiod }
11238fd2302Smiod
11338fd2302Smiod #define atomic_add_int_nv atomic_add_int_nv_sp
11438fd2302Smiod #define atomic_sub_int_nv atomic_sub_int_nv_sp
11538fd2302Smiod #define atomic_cas_uint atomic_cas_uint_sp
11638fd2302Smiod #define atomic_swap_uint atomic_swap_uint_sp
11738fd2302Smiod
118bb0d2ff6Smiod #endif /* MULTIPROCESSOR */
119bb0d2ff6Smiod
120d10dcf91Smiod static __inline__ unsigned int
atomic_clear_int(volatile unsigned int * uip)1212df76cc2Sguenther atomic_clear_int(volatile unsigned int *uip)
122d10dcf91Smiod {
123d10dcf91Smiod u_int oldval;
124d10dcf91Smiod
125d10dcf91Smiod oldval = 0;
1262df76cc2Sguenther __asm__ volatile
1270b514a07Smiod ("xmem %0, %2, %%r0" : "+r"(oldval), "+m"(*uip) : "r"(uip));
128d10dcf91Smiod return oldval;
129d10dcf91Smiod }
130d10dcf91Smiod
13138fd2302Smiod #define atomic_add_long_nv(p,v) \
13238fd2302Smiod ((unsigned long)atomic_add_int_nv((unsigned int *)p, (unsigned int)v))
13338fd2302Smiod #define atomic_sub_long_nv(p,v) \
13438fd2302Smiod ((unsigned long)atomic_sub_int_nv((unsigned int *)p, (unsigned int)v))
13538fd2302Smiod
13638fd2302Smiod #define atomic_cas_ulong(p,o,n) \
13738fd2302Smiod ((unsigned long)atomic_cas_uint((unsigned int *)p, (unsigned int)o, \
13838fd2302Smiod (unsigned int)n))
13938fd2302Smiod #define atomic_cas_ptr(p,o,n) \
14027955740Saoyama ((void *)atomic_cas_uint((void *)p, (unsigned int)o, (unsigned int)n))
14138fd2302Smiod
14238fd2302Smiod #define atomic_swap_ulong(p,o) \
14338fd2302Smiod ((unsigned long)atomic_swap_uint((unsigned int *)p, (unsigned int)o)
14438fd2302Smiod #define atomic_swap_ptr(p,o) \
14500ec56dcSmiod ((void *)atomic_swap_uint((void *)p, (unsigned int)o))
14638fd2302Smiod
14738fd2302Smiod static inline void
__sync_synchronize(void)14838fd2302Smiod __sync_synchronize(void)
14938fd2302Smiod {
15038fd2302Smiod /* flush_pipeline(); */
15138fd2302Smiod __asm__ volatile ("tb1 0, %%r0, 0" ::: "memory");
15238fd2302Smiod }
15338fd2302Smiod
154fc343cf9Saoyama #else /* _KERNEL */
155fc343cf9Saoyama
156fc343cf9Saoyama #if !defined(__GNUC__) || (__GNUC__ < 4)
157fc343cf9Saoyama
158fc343cf9Saoyama /*
159fc343cf9Saoyama * Atomic routines are not available to userland, but we need to prevent
160fc343cf9Saoyama * <sys/atomic.h> from declaring them as inline wrappers of __sync_* functions,
161fc343cf9Saoyama * which are not available with gcc 3.
162fc343cf9Saoyama */
163fc343cf9Saoyama
164fc343cf9Saoyama #define atomic_cas_uint UNIMPLEMENTED
165fc343cf9Saoyama #define atomic_cas_ulong UNIMPLEMENTED
166fc343cf9Saoyama #define atomic_cas_ptr UNIMPLEMENTED
167fc343cf9Saoyama
168fc343cf9Saoyama #define atomic_swap_uint UNIMPLEMENTED
169fc343cf9Saoyama #define atomic_swap_ulong UNIMPLEMENTED
170fc343cf9Saoyama #define atomic_swap_ptr UNIMPLEMENTED
171fc343cf9Saoyama
172fc343cf9Saoyama #define atomic_add_int_nv UNIMPLEMENTED
173fc343cf9Saoyama #define atomic_add_long_nv UNIMPLEMENTED
174fc343cf9Saoyama #define atomic_add_int UNIMPLEMENTED
175fc343cf9Saoyama #define atomic_add_long UNIMPLEMENTED
176fc343cf9Saoyama
177fc343cf9Saoyama #define atomic_inc_int UNIMPLEMENTED
178fc343cf9Saoyama #define atomic_inc_long UNIMPLEMENTED
179fc343cf9Saoyama
180fc343cf9Saoyama #define atomic_sub_int_nv UNIMPLEMENTED
181fc343cf9Saoyama #define atomic_sub_long_nv UNIMPLEMENTED
182fc343cf9Saoyama #define atomic_sub_int UNIMPLEMENTED
183fc343cf9Saoyama #define atomic_sub_long UNIMPLEMENTED
184fc343cf9Saoyama
185fc343cf9Saoyama #define atomic_dec_int UNIMPLEMENTED
186fc343cf9Saoyama #define atomic_dec_long UNIMPLEMENTED
187fc343cf9Saoyama
188fc343cf9Saoyama /* trap numbers below 128 would cause a privileged instruction fault */
189fc343cf9Saoyama #define __membar() do { \
190*dd81489dSjsg __asm volatile("tb1 0, %%r0, 128" ::: "memory"); \
191fc343cf9Saoyama } while (0)
192fc343cf9Saoyama
193fc343cf9Saoyama #endif /* gcc < 4 */
194fc343cf9Saoyama
195fc343cf9Saoyama #define membar_enter() __membar()
196fc343cf9Saoyama #define membar_exit() __membar()
197fc343cf9Saoyama #define membar_producer() __membar()
198fc343cf9Saoyama #define membar_consumer() __membar()
199fc343cf9Saoyama #define membar_sync() __membar()
200fc343cf9Saoyama
2018aa3ef09Sderaadt #endif /* defined(_KERNEL) */
202fc343cf9Saoyama
2032fa72412Spirofti #endif /* _M88K_ATOMIC_H_ */
204