Updated virtual memory manager
Added page flags Added function current_address_space() Fixed create_address_space() Renamed some fields in page_table_entry_t to fit naming scheme
This commit is contained in:
@@ -3,6 +3,15 @@
|
|||||||
#include "pageallocator.h"
|
#include "pageallocator.h"
|
||||||
#include "types/physaddr.h"
|
#include "types/physaddr.h"
|
||||||
|
|
||||||
|
enum page_flag_t
|
||||||
|
{
|
||||||
|
PAGE_RW = 1,
|
||||||
|
PAGE_EXECUTABLE = 1 << 1,
|
||||||
|
PAGE_USERMODE = 1 << 2
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const size_t page_size;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a new top-level page table and map the kernel in it.
|
* @brief Create a new top-level page table and map the kernel in it.
|
||||||
*
|
*
|
||||||
@@ -19,6 +28,15 @@ physaddr_t create_address_space(struct page_stack_t *page_stack);
|
|||||||
*/
|
*/
|
||||||
void load_address_space(physaddr_t table);
|
void load_address_space(physaddr_t table);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the physical address of the top-level page table currently in
|
||||||
|
* use.
|
||||||
|
*
|
||||||
|
* @param table
|
||||||
|
* @return physaddr_t
|
||||||
|
*/
|
||||||
|
physaddr_t current_address_space();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Maps a single page with the specified flags.
|
* @brief Maps a single page with the specified flags.
|
||||||
*
|
*
|
||||||
@@ -36,4 +54,4 @@ int map_page(struct page_stack_t *page_stack, void *page, physaddr_t frame, int
|
|||||||
* @param page
|
* @param page
|
||||||
* @return physaddr_t
|
* @return physaddr_t
|
||||||
*/
|
*/
|
||||||
physaddr_t unmap_page(void *page);
|
physaddr_t unmap_page(void *page);
|
||||||
|
|||||||
@@ -11,28 +11,17 @@ const size_t page_bits = 12;
|
|||||||
struct page_table_entry_t
|
struct page_table_entry_t
|
||||||
{
|
{
|
||||||
uint32_t present : 1;
|
uint32_t present : 1;
|
||||||
|
|
||||||
uint32_t rw : 1;
|
uint32_t rw : 1;
|
||||||
|
|
||||||
uint32_t usermode : 1;
|
uint32_t usermode : 1;
|
||||||
|
uint32_t write_through : 1;
|
||||||
uint32_t writeThrough : 1;
|
uint32_t cache_disable : 1;
|
||||||
|
|
||||||
uint32_t cacheDisable : 1;
|
|
||||||
|
|
||||||
uint32_t accessed : 1;
|
uint32_t accessed : 1;
|
||||||
|
|
||||||
uint32_t dirty : 1;
|
uint32_t dirty : 1;
|
||||||
|
|
||||||
uint32_t pat : 1;
|
uint32_t pat : 1;
|
||||||
|
|
||||||
uint32_t global : 1;
|
uint32_t global : 1;
|
||||||
|
|
||||||
uint32_t shared : 1;
|
uint32_t shared : 1;
|
||||||
|
|
||||||
uint32_t ignored : 2;
|
uint32_t ignored : 2;
|
||||||
|
uint32_t physical_address : 20;
|
||||||
uint32_t physicalAddress : 20;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct page_table_entry_t *page_tables = (struct page_table_entry_t *)0xFFC00000;
|
struct page_table_entry_t *page_tables = (struct page_table_entry_t *)0xFFC00000;
|
||||||
@@ -47,12 +36,14 @@ physaddr_t create_address_space(struct page_stack_t *page_stack)
|
|||||||
return S_OUT_OF_MEMORY;
|
return S_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
struct page_table_entry_t buffer = page_directory[0];
|
struct page_table_entry_t buffer = page_directory[0];
|
||||||
page_directory[0].physicalAddress = table >> page_bits;
|
page_directory[0].physical_address = table >> page_bits;
|
||||||
asm volatile("invlpg 0xFFC00000" ::
|
asm volatile("invlpg 0xFFC00000" ::
|
||||||
: "memory");
|
: "memory");
|
||||||
memset((void *)page_tables, 0, 1022 * 4);
|
memset((void *)page_tables, 0, 1022 * 4);
|
||||||
page_tables[1022] = page_directory[1022];
|
page_tables[1022] = page_directory[1022];
|
||||||
page_tables[1023] = page_directory[1023];
|
page_tables[1023].physical_address = table >> page_bits;
|
||||||
|
page_tables[1023].present = 1;
|
||||||
|
page_tables[1023].rw = 1;
|
||||||
page_directory[0] = buffer;
|
page_directory[0] = buffer;
|
||||||
asm volatile("invlpg 0xFFC00000" ::
|
asm volatile("invlpg 0xFFC00000" ::
|
||||||
: "memory");
|
: "memory");
|
||||||
@@ -67,6 +58,11 @@ void load_address_space(physaddr_t table)
|
|||||||
: "memory");
|
: "memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
physaddr_t current_address_space()
|
||||||
|
{
|
||||||
|
return page_directory[1023].physical_address << 12;
|
||||||
|
}
|
||||||
|
|
||||||
int map_page(struct page_stack_t *page_stack, void *page, physaddr_t frame, int flags)
|
int map_page(struct page_stack_t *page_stack, void *page, physaddr_t frame, int flags)
|
||||||
{
|
{
|
||||||
if ((size_t)page % page_size != 0 || frame % page_size != 0)
|
if ((size_t)page % page_size != 0 || frame % page_size != 0)
|
||||||
@@ -82,15 +78,15 @@ int map_page(struct page_stack_t *page_stack, void *page, physaddr_t frame, int
|
|||||||
{
|
{
|
||||||
return S_OUT_OF_MEMORY;
|
return S_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
page_directory[directory_index].physicalAddress = new_table >> page_bits;
|
page_directory[directory_index].physical_address = new_table >> page_bits;
|
||||||
page_directory[directory_index].present = 1;
|
page_directory[directory_index].present = 1;
|
||||||
page_directory[directory_index].usermode = 0;
|
page_directory[directory_index].usermode = (directory_index < 1022) ? 1 : 0;
|
||||||
page_directory[directory_index].rw = 1;
|
page_directory[directory_index].rw = 1;
|
||||||
}
|
}
|
||||||
page_tables[table_index].physicalAddress = frame >> 12;
|
page_tables[table_index].physical_address = frame >> 12;
|
||||||
page_tables[table_index].present = 1;
|
page_tables[table_index].present = 1;
|
||||||
page_tables[table_index].usermode = 1;
|
page_tables[table_index].usermode = (flags & PAGE_USERMODE) ? 1 : 0;
|
||||||
page_tables[table_index].rw = 1;
|
page_tables[table_index].rw = (flags & PAGE_RW) ? 1 : 0;
|
||||||
asm volatile("invlpg (%0)"
|
asm volatile("invlpg (%0)"
|
||||||
:
|
:
|
||||||
: "r"(page)
|
: "r"(page)
|
||||||
@@ -112,7 +108,7 @@ physaddr_t unmap_page(void *page)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
physaddr_t frame = page_tables[table_index].physicalAddress << page_bits;
|
physaddr_t frame = page_tables[table_index].physical_address << page_bits;
|
||||||
memset(&page_tables[table_index], 0, sizeof(struct page_table_entry_t));
|
memset(&page_tables[table_index], 0, sizeof(struct page_table_entry_t));
|
||||||
asm volatile("invlpg (%0)"
|
asm volatile("invlpg (%0)"
|
||||||
:
|
:
|
||||||
|
|||||||
Reference in New Issue
Block a user