void pmm_init(struct stivale2_struct *stivale2_struct) {
struct stivale2_struct_tag_memmap *mmap = stivale2_get_tag(stivale2_struct, STIVALE2_STRUCT_TAG_MEMMAP_ID);
uptr end = 0;
for (usiz i = 0; i < mmap->entries; i++) { // find end
struct stivale2_mmap_entry *m = &mmap->memmap[i]; uptr top = m->base + m->length;
if (m->type == STIVALE2_MMAP_USABLE && (top > end)) end = m->base + m->length;
}
usiz bitmap_siz = alignup_po2(end / (4096 * 8), 4096); uptr bitmap_base = 0;
for (usiz i = 0; i < mmap->entries; i++) { // place in the first region big enough to hold the bitmap
struct stivale2_mmap_entry *m = &mmap->memmap[i];
if (m->type == STIVALE2_MMAP_USABLE && (m->length > bitmap_siz)) {
bitmap_base = m->base, m->base += bitmap_siz; break;
}
}
u8 bitmap = MAP_HIGHERHALF(u8, bitmap_base);
memset(bitmap, 0xFF, bitmap_siz); // mark all as used
for (usiz i = 0; i < mmap->entries; i++) { // mark usable regions as free
struct stivale2_mmap_entry *m = &mmap->memmap[i];
if (m->type == STIVALE2_MMAP_USABLE) {
usiz bytelen = m->length / (4096 * 8);
memset(bitmap, 0, bytelen);
u8 bitlen = (m->length / 4096) % 8, *byte = bitmap+bytelen;
for (u8 i = 0; i < bitlen; i++) *byte &= ~(1 << i);
}
}