summaryrefslogtreecommitdiffstats
path: root/arch/x86_64/hal/paging.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/hal/paging.c')
-rw-r--r--arch/x86_64/hal/paging.c74
1 files changed, 73 insertions, 1 deletions
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)
{