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