1/* @title: Bitmap allocator */
2#pragma once
3#include <math/bit.h>
4#include <mem/alloc.h>
5#include <mem/page.h>
6#include <mem/vmm.h>
7#include <stdbool.h>
8#include <stdint.h>
9#include <types/types.h>
10
11#define BOOT_BITMAP_SIZE (MIB(128) / PAGE_SIZE / 8)
12
13extern uint8_t boot_bitmap[BOOT_BITMAP_SIZE];
14extern uint8_t *bitmap;
15extern uint64_t bitmap_size;
16
17paddr_t bitmap_alloc_pages(uint64_t count, enum alloc_flags f);
18void bitmap_free_pages(paddr_t addr, uint64_t count);
19
20static inline cc_no_asan void set_bit(uint64_t index) {
21 uint64_t byte = index / 8;
22 uint8_t mask = 0;
23 mask = BIT_SET(mask, index % 8);
24 if (byte >= BOOT_BITMAP_SIZE)
25 return;
26
27 __atomic_fetch_or(&bitmap[byte], mask, __ATOMIC_SEQ_CST);
28}
29
30static inline cc_no_asan void clear_bit(uint64_t index) {
31 uint64_t byte = index / 8;
32 uint8_t mask = UINT8_MAX;
33 mask = BIT_CLEAR(mask, index % 8);
34 if (byte >= BOOT_BITMAP_SIZE)
35 return;
36
37 __atomic_fetch_and(&bitmap[byte], mask, __ATOMIC_SEQ_CST);
38}
39
40static inline cc_no_asan bool test_bit(uint64_t index) {
41 uint64_t byte = index / 8;
42 uint8_t value;
43 if (byte >= BOOT_BITMAP_SIZE)
44 return false;
45
46 __atomic_load(&bitmap[byte], &value, __ATOMIC_SEQ_CST);
47 return BIT_TEST(value, index % 8);
48}
49
50paddr_t bitmap_alloc_page(void);
51