Explicitly check page boundaries when adding bootloader-provided memory regions
This commit is contained in:
parent
ebfeca47b5
commit
6b1de7c9d4
44
src/mm.c
44
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;
|
||||
}
|
||||
|
12
src/mm.h
12
src/mm.h
@ -4,6 +4,18 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user