1#include <console/printf.h>
2#include <math/units.h>
3#include <mem/alloc.h>
4#include <mem/bitmap.h>
5#include <mem/hhdm.h>
6#include <mem/pmm.h>
7#include <stdbool.h>
8#include <stdint.h>
9
10uint8_t boot_bitmap[BOOT_BITMAP_SIZE] = {[0 ...(BOOT_BITMAP_SIZE - 1)] = 0xFF};
11uint64_t bitmap_size = BOOT_BITMAP_SIZE;
12
13uint8_t *bitmap;
14static uint64_t last_allocated_index = 0;
15
16paddr_t bitmap_alloc_page(void) {
17 return bitmap_alloc_pages(count: 1, f: 0);
18}
19
20paddr_t bitmap_alloc_pages(uint64_t count, enum alloc_flags flags) {
21 cc_ignore(flags);
22 if (count == 0)
23 panic("Zero pages requested");
24
25 uint64_t consecutive = 0;
26 uint64_t start_index = 0;
27 bool found = false;
28
29 for (uint64_t i = last_allocated_index; i < to_bits(bytes: bitmap_size); i++) {
30 if (!test_bit(index: i)) {
31 if (consecutive == 0)
32 start_index = i;
33
34 consecutive++;
35
36 if (consecutive == count) {
37 found = true;
38 break;
39 }
40 } else {
41 consecutive = 0;
42 }
43 }
44
45 if (!found) {
46 for (uint64_t i = 0; i < to_bits(bytes: bitmap_size); i++) {
47 if (!test_bit(index: i)) {
48 if (consecutive == 0)
49 start_index = i;
50
51 consecutive++;
52
53 if (consecutive == count) {
54 found = true;
55 break;
56 }
57 } else {
58 consecutive = 0;
59 }
60 }
61 }
62
63 /* fail */
64 if (!found)
65 return 0x0;
66
67 last_allocated_index = start_index;
68 for (uint64_t i = 0; i < count; i++) {
69 set_bit(start_index + i);
70 }
71
72 return (paddr_t) (start_index * PAGE_SIZE);
73}
74
75void bitmap_free_pages(paddr_t addr, uint64_t count) {
76 if (addr == 0 || count == 0) {
77 panic(INVALID_ARGUMENT, "addr 0x%lx, count %lu", (unsigned long) addr,
78 (unsigned long) count);
79 }
80
81 uint64_t start_index = (uint64_t) addr / PAGE_SIZE;
82
83 if (start_index >= to_bits(bytes: bitmap_size) ||
84 start_index + count > to_bits(bytes: bitmap_size)) {
85 printf(format: "Invalid address range to free: 0x%zx with count %zu\n",
86 (uint64_t) addr, count);
87 return;
88 }
89
90 for (uint64_t i = 0; i < count; i++) {
91 uint64_t index = start_index + i;
92 if (test_bit(index)) {
93 clear_bit(index);
94 } else {
95 printf(format: "Page at 0x%zx was already free\n",
96 hhdm_paddr_to_vaddr(p: index * PAGE_SIZE));
97 }
98 }
99}
100