diff options
Diffstat (limited to 'arch/x86_64/memory')
-rw-r--r-- | arch/x86_64/memory/koentry-ptr.c | 16 | ||||
-rw-r--r-- | arch/x86_64/memory/message.c | 40 | ||||
-rw-r--r-- | arch/x86_64/memory/page-mapping.c | 34 | ||||
-rw-r--r-- | arch/x86_64/memory/pml4.c (renamed from arch/x86_64/memory/page_directory.c) | 86 | ||||
-rw-r--r-- | arch/x86_64/memory/untyped_retype_page.c | 38 |
5 files changed, 84 insertions, 130 deletions
diff --git a/arch/x86_64/memory/koentry-ptr.c b/arch/x86_64/memory/koentry-ptr.c deleted file mode 100644 index b32d4e7..0000000 --- a/arch/x86_64/memory/koentry-ptr.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "memory.h" -#include "arch/x86_64/page.h" -#include <stdint.h> - -void* -ko_entry_data(objdir_entry_t *entry) -{ - if((intmax_t)entry->data < 0) return (void*)entry->data; - return vmem_phys_tovirt(entry->data); -} - -uintptr_t -ko_data_toentry(uintptr_t vptr) -{ - return vmem_ident_tophys((void*)vptr); -} diff --git a/arch/x86_64/memory/message.c b/arch/x86_64/memory/message.c index 1fbdfc8..d5bedb7 100644 --- a/arch/x86_64/memory/message.c +++ b/arch/x86_64/memory/message.c @@ -6,43 +6,3 @@ #include "arch/x86_64/page-mapping.h" #include "print.h" -int -ko_message_unmap(objdir_entry_t *message, uintptr_t *saveptr) -{ - /* message data should point to the virtual address. */ - /* If it doesn't, fail*/ - if(!(message->extra & KODE_EX_MESSAGE_MAPPED)) return KE_BADCALL; - uintptr_t vptr = message->data; - - processor_t *cproc = processor_current(); - pmle_t *pml4 = vmem_phys_tovirt(cproc->pdir); - - pmle_t *message_pmle = mem_mapping_vptr_mapping(pml4, 4, vptr); - *saveptr = (uintptr_t)vmem_phys_tovirt(message_pmle->paddr << 12); - - message_pmle->p = 0; - __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory"); - - message->extra &= ~KODE_EX_MESSAGE_MAPPED; - return 0; -} - -int -ko_message_remap(objdir_entry_t *message) -{ - if(message->extra & KODE_EX_MESSAGE_MAPPED) return KE_BADCALL; - uintptr_t vptr = message->data; - - processor_t *cproc = processor_current(); - pmle_t *pml4 = vmem_phys_tovirt(cproc->pdir); - - pmle_t *message_pmle = mem_mapping_vptr_mapping(pml4, 4, vptr); - - message_pmle->p = 1; - __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory"); - - message->extra |= KODE_EX_MESSAGE_MAPPED; - return 0; -} - -void ko_message_move(objdir_entry_t *message, uintptr_t vptr); diff --git a/arch/x86_64/memory/page-mapping.c b/arch/x86_64/memory/page-mapping.c index d4b4e98..bbf210a 100644 --- a/arch/x86_64/memory/page-mapping.c +++ b/arch/x86_64/memory/page-mapping.c @@ -1,28 +1,28 @@ #include "arch/x86_64/page-mapping.h" #include "arch/x86_64/page.h" +#include "memory.h" +#include "error.h" #include <stddef.h> #include "print.h" -pmle_t* -page_mapping_traverse(pmle_t *pml4, uint8_t depth, uint16_t *path) +void +mapping_setup_init() { - uint16_t pathi = path[0]; - - pmle_t *pmle = &pml4[pathi]; - pmle_t *pmle_table = vmem_phys_tovirt(pmle->paddr << 12); - if(depth == 0) return pmle; - if(!pmle->p) return NULL; - return page_mapping_traverse(pmle_table, depth - 1, path + 1); + pml4_setup_init(); } -pmle_t* -mem_mapping_vptr_mapping(pmle_t *pml4, uint8_t depth, uintptr_t vptr) +void +mapping_setup(objdir_entry_t *mapping) { - uint64_t pathval = 0; - uint16_t *path = (uint16_t*)&pathval; + pmle_t *pml4 = (pmle_t*)ko_entry_data(mapping); + pml4_setup(pml4); +} - for(uint8_t i = 0; i < depth; i++) { - path[i] = PML_I_FOR_LAYER(vptr, 4 - i); - } - return page_mapping_traverse(pml4, depth - 1, path); +int +mapping_try_map_obj(objdir_entry_t *mapping, uintptr_t vptr, objdir_entry_t *obj) +{ + if(vptr & 0xFFFF800000000000) return KE_OOB; + pmle_t *pml4 = (pmle_t*)ko_entry_data(mapping); + uintptr_t pptr = (uintptr_t)ko_entry_data(obj); + return pml4_try_map(pml4, pptr, vptr); } diff --git a/arch/x86_64/memory/page_directory.c b/arch/x86_64/memory/pml4.c index 11e4861..fcfc897 100644 --- a/arch/x86_64/memory/page_directory.c +++ b/arch/x86_64/memory/pml4.c @@ -5,37 +5,78 @@ #include "object.h" #include "string.h" #include "jove.h" +#include "error.h" #include <stdint.h> +#define IDENTITY_BASE 0xFFFF800000000000 +uintptr_t vptr_tophys(void *vptr) +{ + return ((uintptr_t)vptr) - IDENTITY_BASE; +} + physptr_t -vmem_tophys_koff(virtptr_t v) +vptr_tophys_koff(virtptr_t v) { return v - (physptr_t)&_kernel_start + _boot_kernel_phys_base; } -#define IDENTITY_BASE 0xFFFF800000000000 void* -vmem_phys_tovirt(physptr_t p) +pptr_tovirt_ident(physptr_t p) { return (void*)(p + IDENTITY_BASE); } -uintptr_t vmem_ident_tophys(void *vptr) -{ - return ((uintptr_t)vptr) - IDENTITY_BASE; -} - void* pmle_get_page(pmle_t entry) { uintptr_t pptr = entry.paddr << 12; - return vmem_phys_tovirt(pptr); + return pptr_tovirt_ident(pptr); +} + +void +pml4_get_path(uintptr_t vptr, uint8_t depth, uint16_t *path) +{ + for(uint8_t i = 0; i < depth; i++) { + path[i] = PML_I_FOR_LAYER(vptr, 4 - i); + } } -uint8_t -pmle_level(pmle_t entry) +pmle_t* +pml4_traverse(pmle_t *pml4, uint8_t depth, uint16_t *path) { - return entry.osflg; + uint16_t pathi = path[0]; + + pmle_t *pmle = &pml4[pathi]; + pmle_t *pmle_table = pptr_tovirt_ident(pmle->paddr << 12); + if(depth == 0) return pmle; + if(!pmle->p) return NULL; + return pml4_traverse(pmle_table, depth - 1, path + 1); +} + +pmle_t* +pml4_get_mapping(pmle_t *pml4, uint8_t depth, uintptr_t vptr) +{ + uint64_t pathval = 0; + uint16_t *path = (uint16_t*)&pathval; + + pml4_get_path(vptr, depth, path); + return pml4_traverse(pml4, depth - 1, path); +} + +int +pml4_try_map(pmle_t *pml4, uintptr_t pptr, uintptr_t vptr) +{ + uint64_t pathval = 0; + uint16_t *path = (uint16_t*)&pathval; + + pml4_get_path(vptr, 4, path); + pmle_t *mapping = pml4_traverse(pml4, 3, path); + + if(mapping == NULL) return KE_DNE; + if(mapping->p) return KE_FULL; + + mapping->value = pptr | PAGE_PRESENT | PAGE_RW | PAGE_US; + return KE_OK; } __attribute__((aligned(0x1000))) pmle_t s_kernel_pml4[512]; // Page L4 @@ -47,7 +88,7 @@ __attribute__((aligned(0x1000))) pmle_t s_idmap_pml3[512]; __attribute__((aligned(0x1000))) pmle_t s_idmap_pml2[512]; void -vmem_setup(void) +pml4_setup_init(void) { memset(s_kernel_pml4, 0, 0x1000); memset(s_kernel_pml3, 0, 0x1000); @@ -63,13 +104,13 @@ vmem_setup(void) size_t kernel_size = kernel_end - kernel_start; size_t kernel_size_pages = (kernel_size / 0x1000) + 1; - physptr_t kernel_pml4_base = vmem_tophys_koff((virtptr_t)&s_kernel_pml4); - physptr_t kernel_pml3_base = vmem_tophys_koff((virtptr_t)&s_kernel_pml3); - physptr_t kernel_pml2_base = vmem_tophys_koff((virtptr_t)&s_kernel_pml2); - physptr_t kernel_pml1_base = vmem_tophys_koff((virtptr_t)&s_kernel_pml1); + physptr_t kernel_pml4_base = vptr_tophys_koff((virtptr_t)&s_kernel_pml4); + physptr_t kernel_pml3_base = vptr_tophys_koff((virtptr_t)&s_kernel_pml3); + physptr_t kernel_pml2_base = vptr_tophys_koff((virtptr_t)&s_kernel_pml2); + physptr_t kernel_pml1_base = vptr_tophys_koff((virtptr_t)&s_kernel_pml1); - physptr_t idmap_pml3_base = vmem_tophys_koff((virtptr_t)&s_idmap_pml3); - physptr_t idmap_pml2_base = vmem_tophys_koff((virtptr_t)&s_idmap_pml2); + physptr_t idmap_pml3_base = vptr_tophys_koff((virtptr_t)&s_idmap_pml3); + physptr_t idmap_pml2_base = vptr_tophys_koff((virtptr_t)&s_idmap_pml2); processor_t *processor = processor_current(); processor->pdir = kernel_pml4_base; @@ -103,3 +144,10 @@ vmem_setup(void) .data = kernel_pml4_base }; } + +void +pml4_setup(pmle_t *pml4) +{ + memset(pml4, 0, 0x800); + memcpy(&pml4[256], &s_kernel_pml4[256], 0x800); +} diff --git a/arch/x86_64/memory/untyped_retype_page.c b/arch/x86_64/memory/untyped_retype_page.c deleted file mode 100644 index 32afe2c..0000000 --- a/arch/x86_64/memory/untyped_retype_page.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "memory.h" -#include "arch/x86_64/page.h" -#include "print.h" -#include <stddef.h> - -static int -s_untyped_retype( - objdir_entry_t *untyped_entry, - size_t size, - size_t align, - void **dest) -{ - if(untyped_entry->type != KO_MEMORY_UNTYPED) return -1; - if((untyped_entry->data & (align - 1)) != 0) return -2; //EALIGN - - uintptr_t *untyped_data = vmem_phys_tovirt(untyped_entry->data); - uintmax_t untyped_size = *untyped_data; - - if(untyped_size <= size) { - return -3; - } - - *untyped_data -= size; - *dest = (void*)(untyped_entry->data + untyped_size - size); - - return 0; -} - -int untyped_retype_page(objdir_entry_t *untyped_entry, void **dest) -{ - int r = s_untyped_retype(untyped_entry, 0x1000, 0x1000, dest); - if(r != 0) return r; - - #ifdef DBG_MEM - klogf("Untyped block %p retyped to page at %p\n", untyped_entry->data, *dest); - #endif - return r; -} |