summaryrefslogtreecommitdiffstats
path: root/sys/syscall_pagedir.c
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2026-09-12 22:00:09 -0400
committerJon Santmyer <jon@jonsantmyer.com>2026-09-12 22:00:09 -0400
commit53fa3cd2bfdb122d773024612d8c1d71f0dd8188 (patch)
tree5ffe81718b400031ca9b3b68a6d152c574270af2 /sys/syscall_pagedir.c
parent1d1a5cde7de28752727e3d56305a74afac8848ff (diff)
downloadjove-kernel-53fa3cd2bfdb122d773024612d8c1d71f0dd8188.tar.gz
jove-kernel-53fa3cd2bfdb122d773024612d8c1d71f0dd8188.tar.bz2
jove-kernel-53fa3cd2bfdb122d773024612d8c1d71f0dd8188.zip
add paging support
Diffstat (limited to 'sys/syscall_pagedir.c')
-rw-r--r--sys/syscall_pagedir.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/sys/syscall_pagedir.c b/sys/syscall_pagedir.c
new file mode 100644
index 0000000..144a02b
--- /dev/null
+++ b/sys/syscall_pagedir.c
@@ -0,0 +1,112 @@
+#include "hal/memory.h"
+#include "jove.h"
+#include "lib/printf.h"
+#include "syscall.h"
+
+static int
+s_syscall_pagedir_map(
+ jove_owned_obj_t *objdir,
+ jove_owned_obj_t *target_obj,
+ size_t payload_bytes,
+ void *payload_data,
+ jove_owned_obj_t **untyped_ret)
+{
+ size_t bytes_needed = sizeof(struct syscall_pagedir_map);
+ CHECK_TOOSMALL(bytes_needed, payload_bytes,
+ "Message too small for payload.");
+
+ struct syscall_pagedir_map *payload = payload_data;
+ if(payload->virtual_address > 0xFFFF800000000000ULL) {
+ kprintf("%s: Virtual address is above user limit.\n", __func__);
+ return EBADARG;
+ }
+
+ bytes_needed += payload->untyped_pathlen << 1;
+ CHECK_TOOSMALL(bytes_needed, payload_bytes,
+ "Message too small for untyped path.");
+
+ errno = 0;
+ jove_owned_obj_t *untyped_obj = objdir_getobj(objdir,
+ payload->untyped_path, payload->untyped_pathlen);
+ if(errno) {
+ kprintf("%s: Untyped path does not point to a valid object.\n", __func__);
+ return errno;
+ }
+
+ CHECK_OBJTYPE(untyped_obj, JOVE_OBJ_UNTYPED,
+ "Untyped path does not point to an untyped object.");
+ jove_untyped_t *untyped_data = obj_deref(untyped_obj);
+
+ if((uintptr_t)untyped_data & 0xFFF) {
+ kprintf("%s: Untyped object is not page aligned.\n", __func__);
+ obj_release(untyped_obj);
+ return EALIGN;
+ }
+ if(untyped_data->limit != 0x1000) {
+ kprintf("%s: Untyped object is not page sized.\n", __func__);
+ obj_release(untyped_obj);
+ return EBADSIZE;
+ }
+
+ *untyped_ret = untyped_obj;
+ return 0;
+}
+
+static int
+s_syscall_pagedir_map_frame(
+ jove_owned_obj_t *objdir,
+ jove_owned_obj_t *target_obj,
+ size_t payload_bytes,
+ void *payload_data)
+{
+ jove_owned_obj_t *untyped_obj = NULL;
+ int sysret = s_syscall_pagedir_map(objdir, target_obj, payload_bytes, payload_data, &untyped_obj);
+ if(sysret != 0) {
+ return sysret;
+ }
+
+ struct syscall_pagedir_map *payload = payload_data;
+ sysret = pagedir_map_frame(target_obj, untyped_obj, payload->virtual_address, payload->flags);
+ obj_release(untyped_obj);
+ return sysret;
+}
+
+static int
+s_syscall_pagedir_map_table(
+ jove_owned_obj_t *objdir,
+ jove_owned_obj_t *target_obj,
+ size_t payload_bytes,
+ void *payload_data)
+{
+ jove_owned_obj_t *untyped_obj = NULL;
+ int sysret = s_syscall_pagedir_map(objdir, target_obj, payload_bytes, payload_data, &untyped_obj);
+ if(sysret != 0) {
+ return sysret;
+ }
+
+ struct syscall_pagedir_map *payload = payload_data;
+ sysret = pagedir_map_frame(target_obj, untyped_obj, payload->virtual_address, payload->flags);
+ obj_release(untyped_obj);
+ return sysret;
+}
+
+int
+_syscall_handle_pagedir(
+ jove_owned_obj_t *pcb_obj,
+ jove_owned_obj_t *objdir,
+ jove_owned_obj_t *message_obj,
+ jove_owned_obj_t *target_obj,
+ struct syscall_header *header,
+ size_t bytes_left,
+ void *payload)
+{
+ switch(header->callid) {
+ case SYSCALL_PAGEDIR_MAP_FRAME:
+ return s_syscall_pagedir_map_frame(objdir, target_obj, bytes_left, payload);
+ case SYSCALL_PAGEDIR_MAP_TABLE:
+ return s_syscall_pagedir_map_table(objdir, target_obj, bytes_left, payload);
+ default:
+ kprintf("syscall_handle_pagedir: Pagedir does not support syscall %i\n", header->callid);
+ return EBADARG;
+ }
+}