1 /*
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2020 Western Digital Corporation or its affiliates.
5 *
6 * Authors:
7 * Anup Patel <anup.patel@wdc.com>
8 */
9
10 #ifndef __SBI_BITMAP_H__
11 #define __SBI_BITMAP_H__
12
13 #include <sbi/sbi_bitops.h>
14
15 #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG))
16 #define BITMAP_LAST_WORD_MASK(nbits) \
17 ( \
18 ((nbits) % BITS_PER_LONG) ? \
19 ((1UL << ((nbits) % BITS_PER_LONG)) - 1) : ~0UL \
20 )
21
22 #define small_const_nbits(nbits) \
23 (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG)
24
25 #define DECLARE_BITMAP(name, nbits) unsigned long name[BITS_TO_LONGS(nbits)]
26 #define DEFINE_BITMAP(name) extern unsigned long name[]
27
bitmap_estimate_size(int nbits)28 static inline unsigned long bitmap_estimate_size(int nbits)
29 {
30 return (BITS_TO_LONGS(nbits) * sizeof(unsigned long));
31 }
32
33 void __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
34 const unsigned long *bitmap2, int bits);
35 void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
36 const unsigned long *bitmap2, int bits);
37 void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
38 const unsigned long *bitmap2, int bits);
39
bitmap_set(unsigned long * bmap,int start,int len)40 static inline void bitmap_set(unsigned long *bmap, int start, int len)
41 {
42 int bit;
43 for (bit = start; bit < (start + len); bit++)
44 bmap[BIT_WORD(bit)] |= (0x1UL << BIT_WORD_OFFSET(bit));
45 }
46
bitmap_clear(unsigned long * bmap,int start,int len)47 static inline void bitmap_clear(unsigned long *bmap, int start, int len)
48 {
49 int bit;
50 for (bit = start; bit < (start + len); bit++)
51 bmap[BIT_WORD(bit)] &= ~(0x1UL << BIT_WORD_OFFSET(bit));
52 }
53
bitmap_zero(unsigned long * dst,int nbits)54 static inline void bitmap_zero(unsigned long *dst, int nbits)
55 {
56 if (small_const_nbits(nbits))
57 *dst = 0UL;
58 else {
59 size_t i, len = BITS_TO_LONGS(nbits);
60 for (i = 0; i < len; i++)
61 dst[i] = 0;
62 }
63 }
64
bitmap_zero_except(unsigned long * dst,int exception,int nbits)65 static inline void bitmap_zero_except(unsigned long *dst,
66 int exception, int nbits)
67 {
68 if (small_const_nbits(nbits))
69 *dst = 0UL;
70 else {
71 size_t i, len = BITS_TO_LONGS(nbits);
72 for (i = 0; i < len; i++)
73 dst[i] = 0;
74 }
75 if (exception < nbits)
76 __set_bit(exception, dst);
77 }
78
bitmap_fill(unsigned long * dst,int nbits)79 static inline void bitmap_fill(unsigned long *dst, int nbits)
80 {
81 size_t i, nlongs = BITS_TO_LONGS(nbits);
82 if (!small_const_nbits(nbits)) {
83 for (i = 0; i < (nlongs - 1); i++)
84 dst[i] = -1UL;
85 }
86 dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
87 }
88
bitmap_copy(unsigned long * dst,const unsigned long * src,int nbits)89 static inline void bitmap_copy(unsigned long *dst,
90 const unsigned long *src, int nbits)
91 {
92 if (small_const_nbits(nbits))
93 *dst = *src;
94 else {
95 size_t i, len = BITS_TO_LONGS(nbits);
96 for (i = 0; i < len; i++)
97 dst[i] = src[i];
98 }
99 }
100
bitmap_and(unsigned long * dst,const unsigned long * src1,const unsigned long * src2,int nbits)101 static inline void bitmap_and(unsigned long *dst, const unsigned long *src1,
102 const unsigned long *src2, int nbits)
103 {
104 if (small_const_nbits(nbits))
105 *dst = *src1 & *src2;
106 else
107 __bitmap_and(dst, src1, src2, nbits);
108 }
109
bitmap_or(unsigned long * dst,const unsigned long * src1,const unsigned long * src2,int nbits)110 static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
111 const unsigned long *src2, int nbits)
112 {
113 if (small_const_nbits(nbits))
114 *dst = *src1 | *src2;
115 else
116 __bitmap_or(dst, src1, src2, nbits);
117 }
118
bitmap_xor(unsigned long * dst,const unsigned long * src1,const unsigned long * src2,int nbits)119 static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1,
120 const unsigned long *src2, int nbits)
121 {
122 if (small_const_nbits(nbits))
123 *dst = *src1 ^ *src2;
124 else
125 __bitmap_xor(dst, src1, src2, nbits);
126 }
127
128 #endif
129