]> git.sur5r.net Git - u-boot/blob - arch/riscv/include/asm/bitops.h
riscv: Define PLATFORM__SET_BIT for generic_set_bit()
[u-boot] / arch / riscv / include / asm / bitops.h
1 /*
2  * Copyright 1995, Russell King.
3  * Various bits and pieces copyrights include:
4  * Linus Torvalds (test_bit).
5  *
6  * Copyright (C) 2017 Andes Technology Corporation
7  * Rick Chen, Andes Technology Corporation <rick@andestech.com>
8  *
9  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
10  *
11  * Please note that the code in this file should never be included
12  * from user space.  Many of these are not implemented in assembler
13  * since they would be too costly.  Also, they require priviledged
14  * instructions (which are not available from user mode) to ensure
15  * that they are atomic.
16  */
17
18 #ifndef __ASM_RISCV_BITOPS_H
19 #define __ASM_RISCV_BITOPS_H
20
21 #ifdef __KERNEL__
22
23 #include <asm/system.h>
24 #include <asm-generic/bitops/fls.h>
25 #include <asm-generic/bitops/__fls.h>
26 #include <asm-generic/bitops/fls64.h>
27 #include <asm-generic/bitops/__ffs.h>
28
29 #define smp_mb__before_clear_bit()      do { } while (0)
30 #define smp_mb__after_clear_bit()       do { } while (0)
31
32 /*
33  * Function prototypes to keep gcc -Wall happy.
34  */
35 static inline void __set_bit(int nr, void *addr)
36 {
37         int *a = (int *)addr;
38         int mask;
39
40         a += nr >> 5;
41         mask = 1 << (nr & 0x1f);
42         *a |= mask;
43 }
44
45 #define PLATFORM__SET_BIT
46
47 static inline void __clear_bit(int nr, void *addr)
48 {
49         int *a = (int *)addr;
50         int mask;
51
52         a += nr >> 5;
53         mask = 1 << (nr & 0x1f);
54         *a &= ~mask;
55 }
56
57 static inline void __change_bit(int nr, void *addr)
58 {
59         int mask;
60         unsigned long *ADDR = (unsigned long *)addr;
61
62         ADDR += nr >> 5;
63         mask = 1 << (nr & 31);
64         *ADDR ^= mask;
65 }
66
67 static inline int __test_and_set_bit(int nr, void *addr)
68 {
69         int mask, retval;
70         unsigned int *a = (unsigned int *)addr;
71
72         a += nr >> 5;
73         mask = 1 << (nr & 0x1f);
74         retval = (mask & *a) != 0;
75         *a |= mask;
76         return retval;
77 }
78
79 static inline int __test_and_clear_bit(int nr, void *addr)
80 {
81         int mask, retval;
82         unsigned int *a = (unsigned int *)addr;
83
84         a += nr >> 5;
85         mask = 1 << (nr & 0x1f);
86         retval = (mask & *a) != 0;
87         *a &= ~mask;
88         return retval;
89 }
90
91 static inline int __test_and_change_bit(int nr, void *addr)
92 {
93         int mask, retval;
94         unsigned int *a = (unsigned int *)addr;
95
96         a += nr >> 5;
97         mask = 1 << (nr & 0x1f);
98         retval = (mask & *a) != 0;
99         *a ^= mask;
100         return retval;
101 }
102
103 /*
104  * This routine doesn't need to be atomic.
105  */
106 static inline int test_bit(int nr, const void *addr)
107 {
108         return ((unsigned char *)addr)[nr >> 3] & (1U << (nr & 7));
109 }
110
111 /*
112  * ffz = Find First Zero in word. Undefined if no zero exists,
113  * so code should check against ~0UL first..
114  */
115 static inline unsigned long ffz(unsigned long word)
116 {
117         int k;
118
119         word = ~word;
120         k = 31;
121         if (word & 0x0000ffff) {
122                 k -= 16; word <<= 16;
123         }
124         if (word & 0x00ff0000) {
125                 k -= 8;  word <<= 8;
126         }
127         if (word & 0x0f000000) {
128                 k -= 4;  word <<= 4;
129         }
130         if (word & 0x30000000) {
131                 k -= 2;  word <<= 2;
132         }
133         if (word & 0x40000000)
134                 k -= 1;
135
136         return k;
137 }
138
139 /*
140  * ffs: find first bit set. This is defined the same way as
141  * the libc and compiler builtin ffs routines, therefore
142  * differs in spirit from the above ffz (man ffs).
143  */
144
145 /*
146  * redefined in include/linux/bitops.h
147  * #define ffs(x) generic_ffs(x)
148  */
149
150 /*
151  * hweightN: returns the hamming weight (i.e. the number
152  * of bits set) of a N-bit word
153  */
154
155 #define hweight32(x) generic_hweight32(x)
156 #define hweight16(x) generic_hweight16(x)
157 #define hweight8(x) generic_hweight8(x)
158
159 #define ext2_set_bit                    test_and_set_bit
160 #define ext2_clear_bit                  test_and_clear_bit
161 #define ext2_test_bit                   test_bit
162 #define ext2_find_first_zero_bit        find_first_zero_bit
163 #define ext2_find_next_zero_bit         find_next_zero_bit
164
165 /* Bitmap functions for the minix filesystem. */
166 #define minix_test_and_set_bit(nr, addr)        test_and_set_bit(nr, addr)
167 #define minix_set_bit(nr, addr)                 set_bit(nr, addr)
168 #define minix_test_and_clear_bit(nr, addr)      test_and_clear_bit(nr, addr)
169 #define minix_test_bit(nr, addr)                test_bit(nr, addr)
170 #define minix_find_first_zero_bit(addr, size)   find_first_zero_bit(addr, size)
171
172 #endif /* __KERNEL__ */
173
174 #endif /* __ASM_RISCV_BITOPS_H */