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