diff options
Diffstat (limited to 'kernel/mm/virtual_mm/virtual_mm.cc')
-rw-r--r-- | kernel/mm/virtual_mm/virtual_mm.cc | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/kernel/mm/virtual_mm/virtual_mm.cc b/kernel/mm/virtual_mm/virtual_mm.cc index e5cd5cc..5c766ea 100644 --- a/kernel/mm/virtual_mm/virtual_mm.cc +++ b/kernel/mm/virtual_mm/virtual_mm.cc @@ -17,6 +17,7 @@ */ #include <kernel/halt.h> +#include <libk/kmalloc.h> #include <libk/stdio.h> #include <mm/physical_mm.h> #include <mm/virtual_mm.h> @@ -38,11 +39,6 @@ uint32_t fourMiB_page_table[1024] ALIGNED(4096); /* Page table for the next 4 MiB */ uint32_t eightMiB_page_table[1024] ALIGNED(4096); -/* Let's reserve a page table at the end of each new page table we allocate, so - * that we know that at any point time, we will always have space for a new - * page table */ -uint32_t *next_page_table; - ALWAYS_INLINE void load_page_directory(uint32_t *page_directory) { @@ -103,19 +99,32 @@ initialize(void) } uint32_t * -get_or_make_table(uint32_t *pd_entry) +make_table(uint32_t *pd_entry) { - uint32_t *table; - if (!PDE_IS_PRESENT(pd_entry)) { - table = (uint32_t *) PhysicalMM::allocate_block(); - if (!table) - ASSERT_NOT_REACHED(); + uint32_t *table = 0; + if (!kmalloc_initialized()) + /* If we don't have a dynamic memory allocator yet (this will happen only + * once, when we initialize the dynamic allocator), then we hard code the + * next page table to be at 7MiB */ + table = (uint32_t *) (7 * MiB); + else + table = (uint32_t *) kmalloc(sizeof(uint32_t) * 1024); + + for (uint32_t i = 0; i < 1024; i++) + table[i] = 0x0; + + *pd_entry = PDE_FRAME((uint32_t) table) | PDE_PRESENT(1) | PDE_WRITABLE(1); + return table; +} - for (uint32_t i = 0; i < 1024; i++) - table[i] = 0x0; +ALWAYS_INLINE static uint32_t * +get_or_make_table(uint32_t *pd_entry) +{ + uint32_t *table = 0; - *pd_entry = PDE_FRAME((uint32_t) table) | PDE_PRESENT(1) | PDE_WRITABLE(1); - } else + if (!PDE_IS_PRESENT(pd_entry)) + table = make_table(pd_entry); + else table = (uint32_t *) PDE_GET_TABLE(pd_entry); return table; @@ -157,7 +166,8 @@ unmap_page(void *virtual_address) void * find_free_addresses(uint32_t n) { - /* Skip the first page directory, we don't wanna touch the first 8MiB. */ + /* Skip the first two page directory entries; we don't wanna touch the first + * 8MiB. */ for (uint32_t pd_index = 2; pd_index < PAGE_DIRECTORY_SIZE; pd_index++) { uint32_t starting_pd_index = pd_index; uint32_t *pd_entry = ¤t_page_directory[pd_index]; |