summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2026-09-05 20:24:13 -0400
committerJon Santmyer <jon@jonsantmyer.com>2026-09-05 20:24:13 -0400
commit779b7fc1fe91e5a355b6e15de882d46b26ab2270 (patch)
treec62da25a0a0b02488550e856921350fd94668c2b /sys
parent73cbb23130f634bf52ac92da063efd3e6016f8ee (diff)
downloadjove-kernel-779b7fc1fe91e5a355b6e15de882d46b26ab2270.tar.gz
jove-kernel-779b7fc1fe91e5a355b6e15de882d46b26ab2270.tar.bz2
jove-kernel-779b7fc1fe91e5a355b6e15de882d46b26ab2270.zip
working syscalls.
Diffstat (limited to 'sys')
-rw-r--r--sys/message.c15
-rw-r--r--sys/message.h13
-rw-r--r--sys/syscall.c111
-rw-r--r--sys/syscall.h43
4 files changed, 182 insertions, 0 deletions
diff --git a/sys/message.c b/sys/message.c
new file mode 100644
index 0000000..7c871ce
--- /dev/null
+++ b/sys/message.c
@@ -0,0 +1,15 @@
+#include "message.h"
+#include "hal/obj.h"
+
+void *
+message_data(jove_owned_obj_t *obj)
+{
+ uintptr_t objptr = (uintptr_t)obj_deref(obj);
+ return (void*)(objptr & ~0xFFF);
+}
+
+size_t
+message_len(jove_owned_obj_t *obj)
+{
+ return (obj_getvalue(obj) & 0xFFF) << 12;
+}
diff --git a/sys/message.h b/sys/message.h
new file mode 100644
index 0000000..2ae6e03
--- /dev/null
+++ b/sys/message.h
@@ -0,0 +1,13 @@
+#ifndef _JOVE_SYS_MESSAGE_H
+#define _JOVE_SYS_MESSAGE_H 1
+
+#include "hal/obj.h"
+
+#define MESSAGE_MAX_PAGES (1<<12)
+#define MESSAGE_MAX_BYTES (MESSAGE_MAX_PAGES * 0x1000)
+#define MESSAGE_ALIGN 0x1000
+
+void *message_data(jove_owned_obj_t *obj);
+size_t message_len(jove_owned_obj_t *obj);
+
+#endif
diff --git a/sys/syscall.c b/sys/syscall.c
new file mode 100644
index 0000000..1eadf50
--- /dev/null
+++ b/sys/syscall.c
@@ -0,0 +1,111 @@
+#include "sys/syscall.h"
+#include "arch/x86_64/hal/obj.h"
+#include "hal/smp.h"
+#include "hal/process.h"
+#include "jove.h"
+#include "lib/printf.h"
+#include "sys/message.h"
+
+int
+_syscall_handle_generic(
+ 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)
+{
+ pcb_t *pcb = obj_deref(pcb_obj);
+ kprintf("syscall: Process %i encountered stub syscall on object %P\n", pcb_pid(pcb), header->path, header->pathlen);
+ return EBADOBJ;
+}
+
+static const syscall_handle_t s_syscall_handles[128] = {
+ [JOVE_OBJ_NONE] = NULL,
+ [JOVE_OBJ_UNTYPED] = _syscall_handle_generic,
+ [JOVE_OBJ_OBJDIR] = _syscall_handle_generic,
+ [JOVE_OBJ_PAGEDIR] = _syscall_handle_generic,
+ [JOVE_OBJ_PROCESSOR] = _syscall_handle_generic,
+ [JOVE_OBJ_PROCESS] = _syscall_handle_generic,
+ [JOVE_OBJ_PAGEFRAME] = _syscall_handle_generic,
+ [JOVE_OBJ_INITRD_FILE] = _syscall_handle_generic,
+ [JOVE_OBJ_FRAMEBUFFER] = _syscall_handle_generic,
+ [JOVE_OBJ_VIRTTERM] = _syscall_handle_generic,
+ [JOVE_OBJ_MESSAGE] = _syscall_handle_generic,
+};
+
+int
+syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen)
+{
+ uint16_t *message_path = (uint16_t*)&message_path_raw;
+ if(message_pathlen > sizeof(uintmax_t) >> 1) {
+ return EBADPATH;
+ }
+
+ jove_owned_obj_t *pcb_obj = process_current();
+ pcb_t *pcb = obj_deref(pcb_obj);
+
+ jove_owned_obj_t *objdir = pcb_rootdir(pcb);
+ kprintf("Syscall: %p : %P \n", objdir, message_path, message_pathlen);
+
+ jove_owned_obj_t *message_obj = objdir_getobj(objdir, message_path, message_pathlen);
+ if(message_obj == 0) {
+ obj_release(objdir);
+ obj_release(pcb_obj);
+ return errno;
+ }
+
+#define SYSCALL_MIDWAY_CLEANUP \
+ obj_release(message_obj); \
+ obj_release(objdir); \
+ obj_release(pcb_obj)
+
+ if(obj_gettype(message_obj) != JOVE_OBJ_MESSAGE) {
+ kprintf("syscall: Process %i tried to call syscall with invalid object: %P\n", pcb_pid(pcb), message_path, message_pathlen);
+ SYSCALL_MIDWAY_CLEANUP;
+ return EBADOBJ;
+ }
+
+ size_t messagelen = message_len(message_obj);
+ void *messagedata = message_data(message_obj);
+ struct syscall_header *header = messagedata;
+
+ size_t header_bytes = sizeof(struct syscall_header) + header->pathlen * 2;
+ int bytes_left = messagelen - header_bytes;
+ kprintf("syscall: Payload %p len %i\n", messagedata, header->pathlen);
+ if(bytes_left < 0) {
+ //Target path exceeds message length.
+ kprintf("syscall: Process %i tried to call syscall with OOB target path.\n", pcb_pid(pcb));
+ SYSCALL_MIDWAY_CLEANUP;
+ return EBADPATH;
+ }
+ jove_owned_obj_t *target = objdir_getobj(objdir, header->path, header->pathlen);
+ if(target == 0) {
+ //Could not find payload target in pcb rootdir.
+ kprintf("syscall: Process %i tried to call syscall with bad target path %P\n",
+ pcb_pid(pcb), header->path, header->pathlen);
+ SYSCALL_MIDWAY_CLEANUP;
+ return errno;
+ }
+ int sysret = 0;
+
+ uint8_t target_type = obj_gettype(target);
+ if(target_type > 0x7F) {
+ sysret = syscall_handle_arch(pcb_obj, objdir, message_obj, target,
+ header, bytes_left, messagedata + header_bytes);
+ }else{
+ syscall_handle_t call_handle = s_syscall_handles[obj_gettype(target)];
+ if(call_handle == NULL) {
+ kprintf("syscall: Process %i tried to call syscall on object %P which doesn't support syscalls!\n",
+ pcb_pid(pcb), header->path, header->pathlen);
+ sysret = EBADOBJ;
+ }else
+ sysret = call_handle(pcb_obj, objdir, message_obj, target,
+ header, bytes_left, message_data + header_bytes);
+ }
+
+ obj_release(target);
+ SYSCALL_MIDWAY_CLEANUP;
+ return sysret;
+}
diff --git a/sys/syscall.h b/sys/syscall.h
new file mode 100644
index 0000000..efd3f64
--- /dev/null
+++ b/sys/syscall.h
@@ -0,0 +1,43 @@
+#ifndef _JOVE_SYS_SYSCALL_H
+#define _JOVE_SYS_SYSCALL_H 1
+
+#include "hal/obj.h"
+#include <stdint.h>
+
+struct syscall_header
+{
+ uint16_t callid;
+ uint16_t pathlen;
+ uint16_t path[];
+};
+
+typedef int (*syscall_handle_t)(
+ jove_owned_obj_t*, //PCB object
+ jove_owned_obj_t*, //Objdir object
+ jove_owned_obj_t*, //Message object
+ jove_owned_obj_t*, //Target object
+ struct syscall_header*, //Syscall header
+ size_t, //How many bytes are left in the message
+ void*); //The bytes left in the message.
+
+int
+_syscall_handle_generic(
+ 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);
+
+int
+syscall_handle_arch(
+ 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);
+
+#endif