From 779b7fc1fe91e5a355b6e15de882d46b26ab2270 Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Sat, 5 Sep 2026 20:24:13 -0400 Subject: working syscalls. --- sys/message.c | 15 ++++++++ sys/message.h | 13 +++++++ sys/syscall.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sys/syscall.h | 43 +++++++++++++++++++++++ 4 files changed, 182 insertions(+) create mode 100644 sys/message.c create mode 100644 sys/message.h create mode 100644 sys/syscall.c create mode 100644 sys/syscall.h (limited to 'sys') 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 + +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 -- cgit v1.2.3