xref: /kvm-unit-tests/lib/arm/asm/bitops.h (revision f20e256197855a9e604be2c9f0b0388887cb57e3)
1*f20e2561SAndrew Jones #ifndef _ASMARM_BITOPS_H_
2*f20e2561SAndrew Jones #define _ASMARM_BITOPS_H_
3*f20e2561SAndrew Jones /*
4*f20e2561SAndrew Jones  * Adapated from
5*f20e2561SAndrew Jones  *   include/linux/bitops.h
6*f20e2561SAndrew Jones  *   arch/arm/lib/bitops.h
7*f20e2561SAndrew Jones  *
8*f20e2561SAndrew Jones  * Copyright (C) 2015, Red Hat Inc, Andrew Jones <drjones@redhat.com>
9*f20e2561SAndrew Jones  *
10*f20e2561SAndrew Jones  * This work is licensed under the terms of the GNU LGPL, version 2.
11*f20e2561SAndrew Jones  */
12*f20e2561SAndrew Jones 
13*f20e2561SAndrew Jones #define BITS_PER_LONG	32
14*f20e2561SAndrew Jones #define BIT(nr)		(1UL << (nr))
15*f20e2561SAndrew Jones #define BIT_MASK(nr)	(1UL << ((nr) % BITS_PER_LONG))
16*f20e2561SAndrew Jones #define BIT_WORD(nr)	((nr) / BITS_PER_LONG)
17*f20e2561SAndrew Jones 
18*f20e2561SAndrew Jones #define ATOMIC_BITOP(insn, mask, word)				\
19*f20e2561SAndrew Jones ({								\
20*f20e2561SAndrew Jones 	unsigned long tmp1, tmp2;				\
21*f20e2561SAndrew Jones 	asm volatile(						\
22*f20e2561SAndrew Jones 	"1:	ldrex	%0, [%2]\n"				\
23*f20e2561SAndrew Jones 		insn"	%0, %0, %3\n"				\
24*f20e2561SAndrew Jones 	"	strex	%1, %0, [%2]\n"				\
25*f20e2561SAndrew Jones 	"	cmp	%1, #0\n"				\
26*f20e2561SAndrew Jones 	"	bne	1b\n"					\
27*f20e2561SAndrew Jones 	: "=&r" (tmp1), "=&r" (tmp2)				\
28*f20e2561SAndrew Jones 	: "r" (word), "r" (mask)				\
29*f20e2561SAndrew Jones 	: "cc");						\
30*f20e2561SAndrew Jones })
31*f20e2561SAndrew Jones 
32*f20e2561SAndrew Jones #define ATOMIC_TESTOP(insn, mask, word, old)			\
33*f20e2561SAndrew Jones ({								\
34*f20e2561SAndrew Jones 	unsigned long tmp1, tmp2;				\
35*f20e2561SAndrew Jones 	asm volatile(						\
36*f20e2561SAndrew Jones 	"1:	ldrex	%0, [%3]\n"				\
37*f20e2561SAndrew Jones 	"	and	%1, %0, %4\n"				\
38*f20e2561SAndrew Jones 		insn"	%0, %0, %4\n"				\
39*f20e2561SAndrew Jones 	"	strex	%2, %0, [%3]\n"				\
40*f20e2561SAndrew Jones 	"	cmp	%2, #0\n"				\
41*f20e2561SAndrew Jones 	"	bne	1b\n"					\
42*f20e2561SAndrew Jones 	: "=&r" (tmp1), "=&r" (old), "=&r" (tmp2)		\
43*f20e2561SAndrew Jones 	: "r" (word), "r" (mask)				\
44*f20e2561SAndrew Jones 	: "cc");						\
45*f20e2561SAndrew Jones })
46*f20e2561SAndrew Jones 
47*f20e2561SAndrew Jones extern void set_bit(int nr, volatile unsigned long *addr);
48*f20e2561SAndrew Jones extern void clear_bit(int nr, volatile unsigned long *addr);
49*f20e2561SAndrew Jones extern int test_bit(int nr, const volatile unsigned long *addr);
50*f20e2561SAndrew Jones extern int test_and_set_bit(int nr, volatile unsigned long *addr);
51*f20e2561SAndrew Jones extern int test_and_clear_bit(int nr, volatile unsigned long *addr);
52*f20e2561SAndrew Jones 
53*f20e2561SAndrew Jones #endif /* _ASMARM_BITOPS_H_ */
54