improve vmm api
This commit is contained in:
@@ -12,8 +12,9 @@
|
|||||||
|
|
||||||
void pmm_init(multiboot_info_t* info);
|
void pmm_init(multiboot_info_t* info);
|
||||||
|
|
||||||
// Allocate a 2mb physical page
|
// Low level function to allocate a 2mb physical page and return the physical address
|
||||||
|
// Return value 0 indicates out of memory
|
||||||
u64 pmm_alloc();
|
u64 pmm_alloc();
|
||||||
|
|
||||||
// Free the 2mb physical page at the specified address
|
// Low level function to free a 2mb physical page
|
||||||
void pmm_free(u64 physical_address);
|
void pmm_free(u64 physical_address);
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
extern u64 pml4[];
|
extern u64 pml4[];
|
||||||
|
|
||||||
static u64 create_pte(u64 physical_address)
|
static u64 create_pte(u64 physical_address, u32 flags)
|
||||||
{
|
{
|
||||||
if (physical_address & (PAGE_SIZE - 1))
|
if (physical_address & (PAGE_SIZE - 1))
|
||||||
{
|
{
|
||||||
@@ -23,10 +23,10 @@ static u64 create_pte(u64 physical_address)
|
|||||||
panic("Failed to create PTE");
|
panic("Failed to create PTE");
|
||||||
}
|
}
|
||||||
|
|
||||||
return (physical_address & PTE_MASK) | PTE_PRESENT | PTE_WRITABLE | PTE_PS;
|
return (physical_address & PTE_MASK) | (flags | PTE_PRESENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vmm_map(u64 physical_address, u64 virtual_address)
|
void vmm_map(u64 physical_address, u64 virtual_address, u32 flags)
|
||||||
{
|
{
|
||||||
u64 pml4_idx = PML4_INDEX(virtual_address);
|
u64 pml4_idx = PML4_INDEX(virtual_address);
|
||||||
u64 pdpt_idx = PDPT_INDEX(virtual_address);
|
u64 pdpt_idx = PDPT_INDEX(virtual_address);
|
||||||
@@ -58,7 +58,7 @@ void vmm_map(u64 physical_address, u64 virtual_address)
|
|||||||
panic("Failed to map virtual to physical page");
|
panic("Failed to map virtual to physical page");
|
||||||
}
|
}
|
||||||
|
|
||||||
pd_physical_address[pd_idx] = create_pte(physical_address);
|
pd_physical_address[pd_idx] = create_pte(physical_address, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 vmm_unmap(u64 virtual_address)
|
u64 vmm_unmap(u64 virtual_address)
|
||||||
@@ -97,20 +97,39 @@ u64 vmm_unmap(u64 virtual_address)
|
|||||||
return physical_address;
|
return physical_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* vmm_alloc(u64 virtual_address)
|
u64 vmm_alloc_address(u64 page_count)
|
||||||
{
|
{
|
||||||
|
panic("not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 vmm_free_address(u64 virtual_address, u64 page_count)
|
||||||
|
{
|
||||||
|
panic("not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
void* vmm_alloc(u64 page_count)
|
||||||
|
{
|
||||||
|
u64 virtual_address = vmm_alloc_address(page_count);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < page_count; i++)
|
||||||
|
{
|
||||||
u64 physical_address = pmm_alloc();
|
u64 physical_address = pmm_alloc();
|
||||||
if (!physical_address)
|
if (!physical_address)
|
||||||
{
|
{
|
||||||
panic("Out of physical memory");
|
panic("Out of physical memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
vmm_map(physical_address, virtual_address);
|
vmm_map(physical_address, virtual_address + (i * PAGE_SIZE), PTE_WRITABLE | PTE_PS);
|
||||||
|
}
|
||||||
|
|
||||||
return (void*)virtual_address;
|
return (void*)virtual_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vmm_free(u64 virtual_address)
|
void vmm_free(u64 virtual_address, u64 page_count)
|
||||||
{
|
{
|
||||||
u64 physical_address = vmm_unmap(virtual_address);
|
for (size_t i = 0; i < page_count; i++)
|
||||||
|
{
|
||||||
|
u64 physical_address = vmm_unmap(virtual_address + (i * PAGE_SIZE));
|
||||||
pmm_free(physical_address);
|
pmm_free(physical_address);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,8 +2,19 @@
|
|||||||
|
|
||||||
#include "std.h"
|
#include "std.h"
|
||||||
|
|
||||||
void vmm_map(u64 physical_address, u64 virtual_address);
|
// Low level function to map a virtual address to a physical address
|
||||||
|
void vmm_map(u64 physical_address, u64 virtual_address, u32 flags);
|
||||||
|
// Low level function to unmap a virtual address from a physical address
|
||||||
u64 vmm_unmap(u64 virtual_address);
|
u64 vmm_unmap(u64 virtual_address);
|
||||||
|
|
||||||
void* vmm_alloc(u64 virtual_address);
|
// Allocates a free page aligned block of virtual addresses
|
||||||
void vmm_free(u64 virtual_address);
|
u64 vmm_alloc_address(u64 page_count);
|
||||||
|
// Frees a block of virtual addresses previously allocated via `vmm_alloc_address`
|
||||||
|
// Only use this function for pages mapped via `vmm_alloc_address`
|
||||||
|
u64 vmm_free_address(u64 virtual_address, u64 page_count);
|
||||||
|
|
||||||
|
// Allocates and maps `page_count` continuous pages and returns the virtual address of the first page
|
||||||
|
void* vmm_alloc(u64 page_count);
|
||||||
|
// Frees the pages allocated via `vmm_alloc` at the specified virtual address
|
||||||
|
// Only use this function for pages mapped via `vmm_alloc`
|
||||||
|
void vmm_free(u64 virtual_address, u64 page_count);
|
||||||
Reference in New Issue
Block a user