summaryrefslogtreecommitdiffstats
path: root/arch/x86_64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64')
-rw-r--r--arch/x86_64/hal/obj.c29
-rw-r--r--arch/x86_64/hal/obj.h2
-rw-r--r--arch/x86_64/hal/paging.c74
-rw-r--r--arch/x86_64/hal/paging.h5
4 files changed, 107 insertions, 3 deletions
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)