diff --git a/src/mm.c b/src/mm.c index f794801..d33be73 100644 --- a/src/mm.c +++ b/src/mm.c @@ -1,15 +1,15 @@ #include "mm.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_free_pages; static size_t mm_total_ram; +static size_t kernel_start_address; +static size_t kernel_size; extern uint8_t _hos_mem_start; extern uint8_t _hos_mem_end; @@ -22,12 +22,11 @@ static void mm_add_ram_region(size_t base, size_t size) region->next = mm_next_free_region; mm_next_free_region = region; mm_total_ram += size; - mm_free_page_count = pages; + mm_free_pages = pages; } void mm_register_ram_region(uint64_t base, size_t size) { - size &= ~(PAGE_SIZE - 1u); /* Ignore any RAM region above 4GB. */ if (base >= 0x100000000ull) { @@ -37,34 +36,43 @@ void mm_register_ram_region(uint64_t base, size_t size) { size = (size_t)(0x100000000ull - base); } + size_t end_address = mm_page_floor((size_t)base + size); + size_t start_address = mm_page_ceil(base); + size = end_address - start_address; + if (size < PAGE_SIZE) + { + return; + } + size_t kernel_end_address = kernel_start_address + kernel_size; /* Add regions before and after kernel RAM. */ - size_t region_base = (size_t)base; - if (region_base < (size_t)&_hos_mem_start) + if (start_address < kernel_start_address) { /* RAM region begins before kernel RAM. */ size_t this_sz = size; - if ((region_base + this_sz) > (size_t)&_hos_mem_start) + if ((start_address + this_sz) > kernel_start_address) { - this_sz = (size_t)&_hos_mem_start - region_base; + this_sz = kernel_start_address - start_address; } - mm_add_ram_region(region_base, this_sz); + mm_add_ram_region(start_address, this_sz); } - if ((region_base + size) > (size_t)&_hos_mem_end) + if ((start_address + size) > kernel_end_address) { /* RAM region ends after kernel RAM. */ size_t this_sz = size; - if (region_base < (size_t)&_hos_mem_end) + if (start_address < kernel_end_address) { - this_sz = (region_base + size) - (size_t)&_hos_mem_end; - region_base = (size_t)&_hos_mem_end; + this_sz = (start_address + size) - kernel_end_address; + start_address = kernel_end_address; } - mm_add_ram_region(region_base, this_sz); + mm_add_ram_region(start_address, this_sz); } } void mm_init(void) { - mm_total_ram = mm_get_kernel_size();; + kernel_start_address = mm_page_floor((size_t)&_hos_mem_start); + kernel_size = mm_page_ceil((size_t)&_hos_mem_end - kernel_start_address); + mm_total_ram = kernel_size; } size_t mm_get_total_ram(void) @@ -74,10 +82,10 @@ size_t mm_get_total_ram(void) size_t mm_get_kernel_address(void) { - return (size_t)&_hos_mem_start; + return kernel_start_address; } size_t mm_get_kernel_size(void) { - return &_hos_mem_end - &_hos_mem_start; + return kernel_size; } diff --git a/src/mm.h b/src/mm.h index 9ac0665..f195412 100644 --- a/src/mm.h +++ b/src/mm.h @@ -4,6 +4,18 @@ #include #include +#define PAGE_SIZE 4096u + +static inline size_t mm_page_floor(size_t bytes) +{ + return bytes & ~(PAGE_SIZE - 1u); +} + +static inline size_t mm_page_ceil(size_t bytes) +{ + return (bytes + PAGE_SIZE - 1u) & ~(PAGE_SIZE - 1u); +} + void mm_init(void); void mm_register_ram_region(uint64_t base, size_t size); size_t mm_get_total_ram(void);