34#define BITMAP_BITS_TO_QWORDS(bits) (((bits) + 63) / 64)
42#define BITMAP_BITS_TO_BYTES(bits) (BITMAP_BITS_TO_QWORDS(bits) * sizeof(uint64_t))
50#define BITMAP_QWORDS_TO_BITS(qwords) ((qwords) * 64)
58#define BITMAP_FOR_EACH_SET(idx, map) \
59 for (uint64_t qwordIdx = 0; qwordIdx < BITMAP_BITS_TO_QWORDS((map)->length); qwordIdx++) \
60 for (uint64_t tempQword = (map)->buffer[qwordIdx]; tempQword != 0; tempQword &= (tempQword - 1)) \
62 uint64_t bit = __builtin_ctzll(tempQword); \
63 *(idx) = qwordIdx * 64 + bit; \
64 *(idx) < (map)->length; \
73#define BITMAP_CREATE(name, bits) \
74 uint64_t name##Buffer[BITMAP_BITS_TO_QWORDS(bits)]; \
75 bitmap_t name = {.firstZeroIdx = 0, .length = (bits), .buffer = name##Buffer}
83#define BITMAP_CREATE_ZERO(name, bits) \
84 uint64_t name##Buffer[BITMAP_BITS_TO_QWORDS(bits)] = {0}; \
85 bitmap_t name = {.firstZeroIdx = 0, .length = (bits), .buffer = name##Buffer}
93#define BITMAP_CREATE_ONE(name, bits) \
94 uint64_t name##Buffer[BITMAP_BITS_TO_QWORDS(bits)] = {-1ULL}; \
95 bitmap_t name = {.firstZeroIdx = 0, .length = (bits), .buffer = name##Buffer}
107#define BITMAP_DEFINE(name, bits) \
108 uint64_t name##Buffer[BITMAP_BITS_TO_QWORDS(bits)]; \
117#define BITMAP_DEFINE_INIT(name, bits) \
118 bitmap_init(&(name), name##Buffer, bits); \
119 memset(name##Buffer, 0, BITMAP_BITS_TO_BYTES(bits))
130 map->firstZeroIdx = 0;
144 for (
uint64_t i = 0; i < fullQwords; i++)
146 if (
map->buffer[i] != 0)
153 if (remainingBits != 0)
155 uint64_t mask = (1ULL << remainingBits) - 1;
156 if ((
map->buffer[fullQwords] & mask) != 0)
181 return (
map->buffer[qwordIdx] & (1ULL << bitInQword));
199 map->buffer[qwordIdx] |= (1ULL << bitInQword);
217 uint64_t firstBitInQword = low % 64;
218 uint64_t lastQwordIdx = (high - 1) / 64;
219 uint64_t lastBitInQword = (high - 1) % 64;
221 if (firstQwordIdx == lastQwordIdx)
223 uint64_t mask = (~0ULL << firstBitInQword) & (~0ULL >> (63 - lastBitInQword));
224 map->buffer[firstQwordIdx] |= mask;
228 map->buffer[firstQwordIdx] |= (~0ULL << firstBitInQword);
230 for (
uint64_t i = firstQwordIdx + 1; i < lastQwordIdx; i++)
232 map->buffer[i] = ~0ULL;
235 map->buffer[lastQwordIdx] |= (~0ULL >> (63 - lastBitInQword));
253 map->buffer[qwordIdx] &= ~(1ULL << bitInQword);
254 map->firstZeroIdx =
MIN(
map->firstZeroIdx, index);
271 if (low < map->firstZeroIdx)
273 map->firstZeroIdx = low;
277 uint64_t firstBitInQword = low % 64;
278 uint64_t lastQwordIdx = (high - 1) / 64;
279 uint64_t lastBitInQword = (high - 1) % 64;
281 if (firstQwordIdx == lastQwordIdx)
283 uint64_t mask = (~0ULL << firstBitInQword) & (~0ULL >> (63 - lastBitInQword));
284 map->buffer[firstQwordIdx] &= ~mask;
288 map->buffer[firstQwordIdx] &= ~(~0ULL << firstBitInQword);
290 for (
uint64_t i = firstQwordIdx + 1; i < lastQwordIdx; i++)
292 map->buffer[i] = 0ULL;
295 map->buffer[lastQwordIdx] &= ~(~0ULL >> (63 - lastBitInQword));
313 startIdx =
MAX(startIdx,
map->firstZeroIdx);
321 uint64_t maskedQword = qword | ((1ULL << bitIdx) - 1);
322 if (maskedQword != ~0ULL)
324 uint64_t res = qwordIdx * 64 + __builtin_ctzll(~maskedQword);
330 for (
uint64_t i = qwordIdx; i < endQwordIdx; ++i)
332 if (
map->buffer[i] != ~0ULL)
334 uint64_t res = i * 64 + __builtin_ctzll(~
map->buffer[i]);
357 uint64_t startQwordIdx = startIdx / 64;
358 uint64_t startBitIdx = startIdx % 64;
361 while (startQwordIdx < endQwordIdx)
364 if (startBitIdx != 0)
366 qword &= ~((1ULL << startBitIdx) - 1);
371 uint64_t res = startQwordIdx * 64 + __builtin_ctzll(qword);
395 if (length == 0 || minIdx >= maxIdx || maxIdx >
map->
length)
408 while (idx <= maxIdx - length)
411 if (firstSet >= idx + length)
416 idx =
ROUND_UP(firstSet + 1, alignment);
EFI_PHYSICAL_ADDRESS buffer
static uint64_t bitmap_find_first_set(bitmap_t *map, uint64_t startIdx, uint64_t endIdx)
Find the first set bit in the bitmap.
static uint64_t bitmap_find_first_clear(bitmap_t *map, uint64_t startIdx, uint64_t endIdx)
Find the first clear bit in the bitmap.
static bool bitmap_is_empty(bitmap_t *map)
Check if the bitmap is empty (all bits clear).
static uint64_t bitmap_find_clear_region_and_set(bitmap_t *map, uint64_t minIdx, uintptr_t maxIdx, uint64_t length, uint64_t alignment)
Find a clear region of specified length and alignment, and set it.
static void bitmap_clear(bitmap_t *map, uint64_t index)
Clear a bit in the bitmap.
static bool bitmap_is_set(bitmap_t *map, uint64_t idx)
Check if a bit is set in the bitmap.
static void bitmap_set(bitmap_t *map, uint64_t index)
Set a bit in the bitmap.
static void bitmap_init(bitmap_t *map, void *buffer, uint64_t length)
Initialize a bitmap.
#define BITMAP_BITS_TO_QWORDS(bits)
Convert number of bits to number of qwords.
static void bitmap_set_range(bitmap_t *map, uint64_t low, uint64_t high)
Set a range of bits in the bitmap.
static void bitmap_clear_range(bitmap_t *map, uint64_t low, uint64_t high)
Clear a range of bits in the bitmap.
#define ROUND_UP(number, multiple)
__UINTPTR_TYPE__ uintptr_t