add mm module to manage free physical page regions

This commit is contained in:
Josh Holtrop 2020-10-26 20:17:08 -04:00
parent a084ab296c
commit 0f73efbdc3
4 changed files with 90 additions and 0 deletions

View File

@ -3,6 +3,7 @@
#include "mbinfo.h"
#include "klog.h"
#include "gdt.h"
#include "mm.h"
void hos_main(uint32_t mbinfo_addr)
{
@ -17,5 +18,7 @@ void hos_main(uint32_t mbinfo_addr)
}
klog_init();
klog_printf("Welcome to HOS!\n");
mm_init();
mbinfo_load();
klog_printf("Found %dKB of usable RAM\n", mm_get_total_ram() / 1024u);
}

View File

@ -3,6 +3,7 @@
#include "mem.h"
#include <stdint.h>
#include "klog.h"
#include "mm.h"
static uint32_t mbinfo[2048];
@ -46,6 +47,7 @@ static void mbinfo_process_tag(const multiboot2_info_tag_t * tag)
klog_printf("Memory region %16lx : %16lx\n",
entry->base_addr,
entry->length);
mm_register_ram_region(entry->base_addr, entry->length);
}
entry = (multiboot2_info_memory_map_entry_t *)((uintptr_t)entry + mmap_info->entry_size);
}

74
src/mm.c Normal file
View File

@ -0,0 +1,74 @@
#include "mm.h"
#include "klog.h"
#define PAGE_SIZE 4096u
typedef struct mm_page_entry_s {
size_t count;
struct mm_page_entry_s * next;
} mm_region_entry_t;
static mm_region_entry_t * mm_next_free_region;
static size_t mm_free_page_count;
static size_t mm_total_ram;
extern uint8_t _hos_mem_start;
extern uint8_t _hos_mem_end;
static void mm_add_ram_region(uint32_t base, uint32_t size)
{
mm_region_entry_t * region = (mm_region_entry_t *)base;
size_t pages = size / PAGE_SIZE;
region->count = pages;
region->next = mm_next_free_region;
mm_next_free_region = region;
mm_total_ram += size;
mm_free_page_count = pages;
}
void mm_register_ram_region(uint64_t base, uint32_t size)
{
size &= ~(PAGE_SIZE - 1u);
/* Ignore any RAM region above 4GB. */
if (base >= 0x100000000ull)
{
return;
}
if ((base + size) > 0x100000000ull)
{
size = (uint32_t)(0x100000000ull - base);
}
/* Add regions before and after kernel RAM. */
uint32_t region_base = (uint32_t)base;
if (region_base < (uint32_t)&_hos_mem_start)
{
/* RAM region begins before kernel RAM. */
uint32_t this_sz = size;
if ((region_base + this_sz) > (uint32_t)&_hos_mem_start)
{
this_sz = (uint32_t)&_hos_mem_start - region_base;
}
mm_add_ram_region(region_base, this_sz);
}
if ((region_base + size) > (uint32_t)&_hos_mem_end)
{
/* RAM region ends after kernel RAM. */
uint32_t this_sz = size;
if (region_base < (uint32_t)&_hos_mem_end)
{
this_sz = (region_base + size) - (uint32_t)&_hos_mem_end;
region_base = (uint32_t)&_hos_mem_end;
}
mm_add_ram_region(region_base, this_sz);
}
}
void mm_init(void)
{
mm_total_ram = &_hos_mem_end - &_hos_mem_start;
}
size_t mm_get_total_ram(void)
{
return mm_total_ram;
}

11
src/mm.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef MM_H
#define MM_H
#include <stdint.h>
#include <stddef.h>
void mm_init(void);
void mm_register_ram_region(uint64_t base, uint32_t size);
size_t mm_get_total_ram(void);
#endif