From 53fa3cd2bfdb122d773024612d8c1d71f0dd8188 Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Sat, 12 Sep 2026 22:00:09 -0400 Subject: add paging support --- arch/x86_64/hal/obj.c | 29 +++++++++++++++++-- arch/x86_64/hal/obj.h | 2 ++ arch/x86_64/hal/paging.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++- arch/x86_64/hal/paging.h | 5 ++++ 4 files changed, 107 insertions(+), 3 deletions(-) (limited to 'arch/x86_64') diff --git a/arch/x86_64/hal/obj.c b/arch/x86_64/hal/obj.c index c5d5c69..b8924a6 100644 --- a/arch/x86_64/hal/obj.c +++ b/arch/x86_64/hal/obj.c @@ -37,6 +37,12 @@ obj_gettype(jove_owned_obj_t *obj) return obj->locked.type; } +uint8_t +obj_peektype(jove_obj_t obj) +{ + return obj.type; +} + void obj_settype(jove_owned_obj_t *obj, uint8_t type) { @@ -55,6 +61,24 @@ obj_setvalue(jove_owned_obj_t *obj, uintmax_t value) obj->locked.value = value & 0x00007FFFFFFFFFFFULL; } +jove_obj_t +objdir_peeklocal( + jove_owned_obj_t *objdir_obj, + uint16_t entry) +{ + if(obj_gettype_linked(objdir_obj) != JOVE_OBJ_OBJDIR) { + errno = EBADOBJ; + return (jove_obj_t) { 0 }; + } + if(entry >= JOVE_OBJDIR_ENTRIES) { + errno = EBADPATH; + return (jove_obj_t) { 0 }; + } + + jove_objdir_t *objtab = obj_deref_linked(objdir_obj); + return objtab->entries[entry]; +} + jove_owned_obj_t* objdir_getlocal( jove_owned_obj_t *objdir_obj, @@ -64,7 +88,7 @@ objdir_getlocal( reterr(EBADOBJ); } if(entry >= JOVE_OBJDIR_ENTRIES) { - reterr(EOOB); + reterr(EBADPATH); } jove_objdir_t *objtab = obj_deref_linked(objdir_obj); @@ -81,9 +105,10 @@ objdir_getobj( return objdir_obj; } { + errno = 0; jove_owned_obj_t *child_objdir = objdir_getlocal(objdir_obj, path[0]); if(child_objdir == 0) { - return 0; + reterr(EBADPATH); } jove_owned_obj_t *target_obj = objdir_getobj(child_objdir, path + 1, path_len - 1); diff --git a/arch/x86_64/hal/obj.h b/arch/x86_64/hal/obj.h index 51f2d6a..d28d81b 100644 --- a/arch/x86_64/hal/obj.h +++ b/arch/x86_64/hal/obj.h @@ -49,6 +49,7 @@ void *obj_deref(jove_owned_obj_t *obj); /*Getters and setters for accessing the type field of the kernel object. */ uint8_t obj_gettype(jove_owned_obj_t *obj); +uint8_t obj_peektype(jove_obj_t obj); void obj_settype(jove_owned_obj_t *obj, uint8_t type); /*Getters and setters for accessing the value field of the kernel object. */ @@ -59,6 +60,7 @@ void obj_setvalue(jove_owned_obj_t *obj, uintmax_t value); * If the passed object is not an objdir, returns NULL and sets errno to EBADOBJ. * If the passed entry index is out of bounds, returns NULL and sets errno to EOOB.*/ jove_owned_obj_t *objdir_getlocal(jove_owned_obj_t *objdir_obj, uint16_t entry); +jove_obj_t objdir_peeklocal(jove_owned_obj_t *objdir_obj, uint16_t entry); /*Recursively seeks through an object directory for an object following the passed * path variable. diff --git a/arch/x86_64/hal/paging.c b/arch/x86_64/hal/paging.c index fb6dea7..507dfce 100644 --- a/arch/x86_64/hal/paging.c +++ b/arch/x86_64/hal/paging.c @@ -3,12 +3,12 @@ #include "jove.h" #include "init.h" #include "config.h" -#include "smp.h" #include "hal/obj.h" #include "lib/string.h" #include "lib/printf.h" #include "lib/panic.h" #include "idt.h" +#include "api/syscall.h" PAGEALIGN page_t _kernel_pml4[512]; PAGEALIGN page_t _kernel_pml3[512]; @@ -73,6 +73,78 @@ s_int_handle_pf_early(struct int_stackframe *frame) hcf(); } +int pagedir_map_frame( + jove_owned_obj_t *tgt, jove_owned_obj_t *untyped_obj, + uintptr_t vptr, struct syscall_pagedir_flags flg) +{ + page_t *pml4 = obj_deref(tgt); + uintptr_t frame = obj_getvalue(untyped_obj); + + size_t pml4i = PML4I(vptr); + if(!pml4[pml4i].p) return ENOMAP; + + page_t *pml3 = (page_t*)(((uintptr_t)pml4[pml4i].paddr << 12) | IDENT_VIRT_BASE); + size_t pml3i = PML3I(vptr); + if(!pml3[pml3i].p) return ENOMAP; + + page_t *pml2 = (page_t*)(((uintptr_t)pml3[pml3i].paddr << 12) | IDENT_VIRT_BASE); + size_t pml2i = PML2I(vptr); + if(!pml2[pml2i].p) return ENOMAP; + + page_t *pml1 = (page_t*)(((uintptr_t)pml2[pml2i].paddr << 12) | IDENT_VIRT_BASE); + size_t pml1i = PML1I(vptr); + if(pml1[pml1i].p) return EEXIST; + + pml1[pml1i].value = frame | + PAGE_PRESENT | + PAGE_USER | + (flg.writeable ? PAGE_WRITETHROUGH : 0) | + (flg.executable ? 0 : PAGE_XD); + return 0; +} + +int pagedir_map_table( + jove_owned_obj_t *tgt, jove_owned_obj_t *untyped_obj, + uintptr_t vptr, struct syscall_pagedir_flags flg) +{ + page_t *target_table = NULL; + page_t *pml4 = obj_deref(tgt); + uintptr_t frame = obj_getvalue(untyped_obj); + + void *frame_ident = obj_deref(untyped_obj); + memset(frame_ident, 0, 0x1000); + + size_t pml4i = PML4I(vptr); + if(!pml4[pml4i].p) { + target_table = &pml4[pml4i]; + goto map_table; + } + + page_t *pml3 = (page_t*)(((uintptr_t)pml4[pml4i].paddr << 12) | IDENT_VIRT_BASE); + size_t pml3i = PML3I(vptr); + if(!pml3[pml3i].p) { + target_table = &pml3[pml3i]; + goto map_table; + } + + page_t *pml2 = (page_t*)(((uintptr_t)pml3[pml3i].paddr << 12) | IDENT_VIRT_BASE); + size_t pml2i = PML2I(vptr); + if(!pml2[pml2i].p) { + target_table = &pml2[pml2i]; + goto map_table; + } + return EHASMAP; + +map_table: + target_table->value = frame | + PAGE_PRESENT | + PAGE_USER | + (flg.writeable ? PAGE_WRITETHROUGH : 0) | + (flg.executable ? 0 : PAGE_XD); + return 0; +} + + void paging_pml4_init(void) { diff --git a/arch/x86_64/hal/paging.h b/arch/x86_64/hal/paging.h index 5736326..754ac99 100644 --- a/arch/x86_64/hal/paging.h +++ b/arch/x86_64/hal/paging.h @@ -42,6 +42,11 @@ extern void *_kernel_physptr; #define PMLI_SHL(l) (12 + (l * 9)) #define PMLI_MASK(l) (~0xFFFFULL << PMLI_SHL(l)) +#define PML4I(v) (((v) >> 39) & 0x1FF) +#define PML3I(v) (((v) >> 30) & 0x1FF) +#define PML2I(v) (((v) >> 21) & 0x1FF) +#define PML1I(v) (((v) >> 12) & 0x1FF) + #define IDENT_VIRT_BASE 0xFFFF800000000000ULL #define KERNEL_VIRT_BASE 0xFFFFFFFF80000000ULL #define KPTR_TOPHYS(v) (((uintptr_t)v) - KERNEL_VIRT_BASE + (uintptr_t)_kernel_physptr) -- cgit v1.2.3