mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-21 18:44:01 +00:00
Stage 2
This commit is contained in:
105
clks/kernel/pmm.c
Normal file
105
clks/kernel/pmm.c
Normal file
@@ -0,0 +1,105 @@
|
||||
#include <clks/pmm.h>
|
||||
#include <clks/string.h>
|
||||
#include <clks/types.h>
|
||||
|
||||
#define CLKS_PMM_MAX_TRACKED_PAGES 262144ULL
|
||||
#define CLKS_PMM_MIN_USABLE_ADDR 0x100000ULL
|
||||
|
||||
static u64 clks_pmm_free_stack[CLKS_PMM_MAX_TRACKED_PAGES];
|
||||
static u64 clks_pmm_free_top = 0;
|
||||
static u64 clks_pmm_managed_pages = 0;
|
||||
static u64 clks_pmm_dropped_pages = 0;
|
||||
|
||||
static u64 clks_align_up_u64(u64 value, u64 alignment) {
|
||||
return (value + alignment - 1ULL) & ~(alignment - 1ULL);
|
||||
}
|
||||
|
||||
static u64 clks_align_down_u64(u64 value, u64 alignment) {
|
||||
return value & ~(alignment - 1ULL);
|
||||
}
|
||||
|
||||
void clks_pmm_init(const struct limine_memmap_response *memmap) {
|
||||
u64 i;
|
||||
|
||||
clks_pmm_free_top = 0;
|
||||
clks_pmm_managed_pages = 0;
|
||||
clks_pmm_dropped_pages = 0;
|
||||
clks_memset(clks_pmm_free_stack, 0, sizeof(clks_pmm_free_stack));
|
||||
|
||||
if (memmap == CLKS_NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < memmap->entry_count; i++) {
|
||||
const struct limine_memmap_entry *entry = memmap->entries[i];
|
||||
u64 start;
|
||||
u64 end;
|
||||
u64 addr;
|
||||
|
||||
if (entry == CLKS_NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry->type != LIMINE_MEMMAP_USABLE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
start = clks_align_up_u64(entry->base, CLKS_PAGE_SIZE);
|
||||
end = clks_align_down_u64(entry->base + entry->length, CLKS_PAGE_SIZE);
|
||||
|
||||
if (end <= start) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (addr = start; addr < end; addr += CLKS_PAGE_SIZE) {
|
||||
if (addr < CLKS_PMM_MIN_USABLE_ADDR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (clks_pmm_free_top < CLKS_PMM_MAX_TRACKED_PAGES) {
|
||||
clks_pmm_free_stack[clks_pmm_free_top] = addr;
|
||||
clks_pmm_free_top++;
|
||||
clks_pmm_managed_pages++;
|
||||
} else {
|
||||
clks_pmm_dropped_pages++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u64 clks_pmm_alloc_page(void) {
|
||||
if (clks_pmm_free_top == 0) {
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
clks_pmm_free_top--;
|
||||
return clks_pmm_free_stack[clks_pmm_free_top];
|
||||
}
|
||||
|
||||
void clks_pmm_free_page(u64 phys_addr) {
|
||||
if (phys_addr == 0ULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((phys_addr & (CLKS_PAGE_SIZE - 1ULL)) != 0ULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (clks_pmm_free_top >= CLKS_PMM_MAX_TRACKED_PAGES) {
|
||||
return;
|
||||
}
|
||||
|
||||
clks_pmm_free_stack[clks_pmm_free_top] = phys_addr;
|
||||
clks_pmm_free_top++;
|
||||
}
|
||||
|
||||
struct clks_pmm_stats clks_pmm_get_stats(void) {
|
||||
struct clks_pmm_stats stats;
|
||||
|
||||
stats.managed_pages = clks_pmm_managed_pages;
|
||||
stats.free_pages = clks_pmm_free_top;
|
||||
stats.used_pages = clks_pmm_managed_pages - clks_pmm_free_top;
|
||||
stats.dropped_pages = clks_pmm_dropped_pages;
|
||||
|
||||
return stats;
|
||||
}
|
||||
Reference in New Issue
Block a user