diff options
| author | Jon Santmyer <jon@jonsantmyer.com> | 2026-09-07 19:19:24 -0400 |
|---|---|---|
| committer | Jon Santmyer <jon@jonsantmyer.com> | 2026-09-07 19:19:24 -0400 |
| commit | df0688efa326a03a22bcbc36d1900926b7b1c986 (patch) | |
| tree | c67df82b0a6cd94693278a809ed0c9a69daf840f | |
| parent | 4ca0bdf61196d0c3fd3f0fdbfb2d72481025cca2 (diff) | |
| download | jove-kernel-df0688efa326a03a22bcbc36d1900926b7b1c986.tar.gz jove-kernel-df0688efa326a03a22bcbc36d1900926b7b1c986.tar.bz2 jove-kernel-df0688efa326a03a22bcbc36d1900926b7b1c986.zip | |
split syscall info into api subfolder. untyped syscalls
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | api/obj.h | 23 | ||||
| -rw-r--r-- | api/syscall.h | 48 | ||||
| -rw-r--r-- | arch/x86_64/sys/serial.c | 16 | ||||
| -rw-r--r-- | arch/x86_64/sys/syscall.h | 5 | ||||
| -rw-r--r-- | hal/memory.h | 12 | ||||
| -rw-r--r-- | hal/obj.h | 15 | ||||
| -rw-r--r-- | hal/untyped.c | 54 | ||||
| -rw-r--r-- | jove.h | 3 | ||||
| -rw-r--r-- | sys/syscall.c | 4 | ||||
| -rw-r--r-- | sys/syscall.h | 32 | ||||
| -rw-r--r-- | sys/syscall_objdir.c | 46 | ||||
| -rw-r--r-- | sys/syscall_untyped.c | 69 | ||||
| -rw-r--r-- | sys/syscall_vtt.c | 17 |
14 files changed, 291 insertions, 55 deletions
@@ -1,7 +1,7 @@ include $(CONFIG) include config.mk -CDIRS := boot lib hal sys +CDIRS := boot lib hal sys api CDIRS += boot/$(TARGET_BOOTLOADER) CFILES := $(wildcard *.c) diff --git a/api/obj.h b/api/obj.h new file mode 100644 index 0000000..4d5e829 --- /dev/null +++ b/api/obj.h @@ -0,0 +1,23 @@ +#ifndef _JOVE_API_OBJ_H +#define _JOVE_API_OBJ_H 1 + +#include <stdint.h> + +enum +{ + JOVE_OBJ_NONE = 0, + JOVE_OBJ_UNTYPED, + JOVE_OBJ_OBJDIR, + JOVE_OBJ_PAGEDIR, + JOVE_OBJ_PROCESSOR, + JOVE_OBJ_PROCESS, + JOVE_OBJ_PAGEFRAME, + JOVE_OBJ_INITRD_FILE, + JOVE_OBJ_FRAMEBUFFER, + JOVE_OBJ_VIRTTERM, + JOVE_OBJ_MESSAGE +}; + +typedef uint16_t objpath_part_t; + +#endif diff --git a/api/syscall.h b/api/syscall.h new file mode 100644 index 0000000..cf8b1c1 --- /dev/null +++ b/api/syscall.h @@ -0,0 +1,48 @@ +#ifndef _JOVE_API_SYSCALL_H +#define _JOVE_API_SYSCALL_H 1 + +#include <stddef.h> +#include <stdint.h> + +#include "obj.h" + +struct syscall_header +{ + uint16_t callid; + uint16_t pathlen; + uint16_t path[]; +}; + +#define SYSCALL_VTT_WRITE 0 +struct syscall_generic_write +{ + size_t len; + char data[]; +}; + +#define SYSCALL_UNTYPED_SIZE 0 +#define SYSCALL_UNTYPED_ALIGN 1 + +#define SYSCALL_UNTYPED_RETYPE 2 +struct syscall_untyped_retype +{ + uint16_t newtype; +}; + +#define SYSCALL_UNTYPED_SPLIT 3 +#define SYSCALL_UNTYPED_MERGE 4 +struct syscall_untyped_split +{ + size_t bytes; + uint16_t dest_pathlen; + objpath_part_t dest_path[]; +}; +struct syscall_generic_objpath +{ + uint16_t second_pathlen; + objpath_part_t second_path[]; +}; + +#define SYSCALL_OBJDIR_OBJTYPE 0 + +#endif diff --git a/arch/x86_64/sys/serial.c b/arch/x86_64/sys/serial.c index 48a14c7..12db6fd 100644 --- a/arch/x86_64/sys/serial.c +++ b/arch/x86_64/sys/serial.c @@ -9,15 +9,13 @@ s_syscall_serial_write( size_t payload_bytes, void *payload_data) { - if(payload_bytes < sizeof(struct syscall_serial_write)) { - kprintf("syscall_serial_write: message is too small for this syscall!\n"); - return EOOB; - } - struct syscall_serial_write *payload = payload_data; - if(payload_bytes < sizeof(struct syscall_serial_write) + payload->len) { - kprintf("syscall_serial_write: message is to small for payload!\n"); - return EOOB; - } + size_t bytes_needed = sizeof(struct syscall_generic_write); + CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for this syscall!"); + + struct syscall_generic_write *payload = payload_data; + bytes_needed += payload->len * 2; + CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for write buffer!"); + return serial_com_write(serial_com, payload->data, payload->len); } diff --git a/arch/x86_64/sys/syscall.h b/arch/x86_64/sys/syscall.h index 9138101..868ce0b 100644 --- a/arch/x86_64/sys/syscall.h +++ b/arch/x86_64/sys/syscall.h @@ -3,11 +3,6 @@ #include "sys/syscall.h" -struct syscall_serial_write -{ - size_t len; - char data[]; -}; int _syscall_handle_serial(SYSCALL_FUNCTION_ARGS); #define SYSCALL_SERIAL_COM_WRITE 0 diff --git a/hal/memory.h b/hal/memory.h index 4d866d0..659263c 100644 --- a/hal/memory.h +++ b/hal/memory.h @@ -1,16 +1,24 @@ #ifndef _JOVE_HAL_MEMORY_H #define _JOVE_HAL_MEMORY_H 1 -#include <stddef.h> -#include <stdint.h> +#include "obj.h" typedef struct jove_obj_untyped { size_t limit; } jove_untyped_t; +#define JOVE_UNTYPED_MINSIZE 0x10 + void mem_setup_untyped(void); void *phys_tovirt(uintptr_t phys); +size_t untyped_size(jove_owned_obj_t *tgt); +size_t untyped_align(jove_owned_obj_t *tgt); + +int untyped_split(jove_owned_obj_t *tgt, jove_owned_obj_t *dst, size_t bytes); +int untyped_merge(jove_owned_obj_t *a, jove_owned_obj_t *b); +int untyped_retype(jove_owned_obj_t *tgt, uint8_t newtype); + #endif @@ -3,20 +3,7 @@ #include <stddef.h> -enum -{ - JOVE_OBJ_NONE = 0, - JOVE_OBJ_UNTYPED, - JOVE_OBJ_OBJDIR, - JOVE_OBJ_PAGEDIR, - JOVE_OBJ_PROCESSOR, - JOVE_OBJ_PROCESS, - JOVE_OBJ_PAGEFRAME, - JOVE_OBJ_INITRD_FILE, - JOVE_OBJ_FRAMEBUFFER, - JOVE_OBJ_VIRTTERM, - JOVE_OBJ_MESSAGE -}; +#include "api/obj.h" #ifdef __x86_64__ #include "arch/x86_64/hal/obj.h" diff --git a/hal/untyped.c b/hal/untyped.c new file mode 100644 index 0000000..243f3ec --- /dev/null +++ b/hal/untyped.c @@ -0,0 +1,54 @@ +#include "arch/x86_64/hal/obj.h" +#include "jove.h" +#include "memory.h" + +size_t +untyped_size(jove_owned_obj_t *tgt) +{ + return ((jove_untyped_t*)obj_deref(tgt))->limit; +} + +size_t +untyped_align(jove_owned_obj_t *tgt) +{ + return (uintptr_t)obj_deref(tgt) & 0xFFF; +} + +int +untyped_split(jove_owned_obj_t *tgt, jove_owned_obj_t *dst, size_t bytes) +{ + jove_untyped_t *tgt_untyped = obj_deref(tgt); + if(bytes < JOVE_UNTYPED_MINSIZE) return EBADARG; + if(tgt_untyped->limit - bytes < JOVE_UNTYPED_MINSIZE) return ETOOSMALL; + + tgt_untyped->limit -= bytes; + obj_settype(dst, JOVE_OBJ_UNTYPED); + obj_setvalue(dst, (uintptr_t)tgt_untyped + tgt_untyped->limit); + + jove_untyped_t *dst_untyped = obj_deref(dst); + dst_untyped->limit = bytes; + return 0; +} + +int +untyped_merge(jove_owned_obj_t *a, jove_owned_obj_t *b) +{ + jove_untyped_t *a_untyped = obj_deref(a); + jove_untyped_t *b_untyped = obj_deref(b); + if((uintptr_t)a_untyped + a_untyped->limit == (uintptr_t)b_untyped) { + return EBADARG; + } + if((uintptr_t)b_untyped + b_untyped->limit == (uintptr_t)a_untyped) { + return untyped_merge(b, a); + } + + a_untyped->limit += b_untyped->limit; + obj_settype(b, JOVE_OBJ_NONE); + return 0; +} + +int untyped_retype(jove_owned_obj_t *tgt, uint8_t newtype) +{ + obj_settype(tgt, newtype); + return 0; +} @@ -17,5 +17,8 @@ extern int errno; #define EBADOBJ -1 #define EOOB -2 #define EBADPATH -3 +#define EBADARG -4 +#define ETOOSMALL -5 +#define ETOOBIG -6 #endif diff --git a/sys/syscall.c b/sys/syscall.c index 6c3fa33..68a5ae6 100644 --- a/sys/syscall.c +++ b/sys/syscall.c @@ -23,8 +23,8 @@ _syscall_handle_generic( 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_UNTYPED] = _syscall_handle_untyped, + [JOVE_OBJ_OBJDIR] = _syscall_handle_objdir, [JOVE_OBJ_PAGEDIR] = _syscall_handle_generic, [JOVE_OBJ_PROCESSOR] = _syscall_handle_generic, [JOVE_OBJ_PROCESS] = _syscall_handle_generic, diff --git a/sys/syscall.h b/sys/syscall.h index 6ad221f..ea75152 100644 --- a/sys/syscall.h +++ b/sys/syscall.h @@ -1,15 +1,27 @@ #ifndef _JOVE_SYS_SYSCALL_H #define _JOVE_SYS_SYSCALL_H 1 +#include "api/syscall.h" #include "hal/obj.h" #include <stdint.h> -struct syscall_header -{ - uint16_t callid; - uint16_t pathlen; - uint16_t path[]; -}; +#define CHECK_TOOSMALL(required, present, fail_msg) \ + do { if(present < required) { \ + kprintf("%s: %s\n", __func__, fail_msg); \ + return ETOOSMALL; \ + } } while(0) + +#define CHECK_OBJEXISTS(obj, fail_msg) \ +do { if(obj == NULL) { \ + kprintf("%s: %s\n", __func__, fail_msg); \ + return EBADOBJ; \ +} } while(0) + +#define CHECK_OBJTYPE(obj, type, fail_msg) \ + do { if(obj_gettype(obj) != type) { \ + kprintf("%s: %s\n", __func__, fail_msg); \ + return EBADOBJ; \ + } } while(0) #define SYSCALL_FUNCTION_ARGS \ jove_owned_obj_t*, /*PCB object*/ \ @@ -25,12 +37,8 @@ typedef int (*syscall_handle_t)(SYSCALL_FUNCTION_ARGS); int _syscall_handle_generic(SYSCALL_FUNCTION_ARGS); int _syscall_handle_arch(SYSCALL_FUNCTION_ARGS); -#define SYSCALL_VTT_WRITE 0 -struct syscall_vtt_write -{ - size_t len; - char data[]; -}; int _syscall_handle_vtt(SYSCALL_FUNCTION_ARGS); +int _syscall_handle_objdir(SYSCALL_FUNCTION_ARGS); +int _syscall_handle_untyped(SYSCALL_FUNCTION_ARGS); #endif diff --git a/sys/syscall_objdir.c b/sys/syscall_objdir.c new file mode 100644 index 0000000..cf1e5b7 --- /dev/null +++ b/sys/syscall_objdir.c @@ -0,0 +1,46 @@ +#include "hal/process.h" +#include "jove.h" +#include "lib/printf.h" +#include "syscall.h" + +int +s_syscall_objdir_objtype( + jove_owned_obj_t *objdir, + jove_owned_obj_t *target_dir, + size_t payload_size, + void *payload_data) +{ + int bytes_needed = sizeof(struct syscall_generic_objpath); + CHECK_TOOSMALL(bytes_needed, payload_size, "Message is too small for this payload!"); + + struct syscall_generic_objpath *payload = payload_data; + bytes_needed += payload->second_pathlen * 2; + CHECK_TOOSMALL(bytes_needed, payload_size, "Message is too small for second target path!"); + + int retval = 0; + jove_owned_obj_t *second_obj = objdir_getobj(objdir, payload->second_path, payload->second_pathlen); + CHECK_OBJEXISTS(second_obj, "Second target does not exist!"); + + retval = obj_gettype(second_obj); + obj_release(second_obj); + return retval; +} + +int +_syscall_handle_objdir( + 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_OBJDIR_OBJTYPE: + return s_syscall_objdir_objtype(objdir, target_obj, bytes_left, payload); + default: + kprintf("syscall_handle_objdir: Objdir does not support syscall %i\n", header->callid); + return EOOB; + } +} diff --git a/sys/syscall_untyped.c b/sys/syscall_untyped.c new file mode 100644 index 0000000..52a0715 --- /dev/null +++ b/sys/syscall_untyped.c @@ -0,0 +1,69 @@ +#include "arch/x86_64/hal/obj.h" +#include "hal/memory.h" +#include "jove.h" +#include "lib/printf.h" +#include "syscall.h" + +static int +s_syscall_untyped_split( + jove_owned_obj_t *objdir, + jove_owned_obj_t *target_obj, + size_t payload_bytes, + void *payload_data) +{ + int bytes_needed = sizeof(struct syscall_untyped_split); + CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for payload!"); + + struct syscall_untyped_split *payload = payload_data; + bytes_needed += payload->dest_pathlen * 2; + CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for destination path!"); + + jove_owned_obj_t *dst_obj = objdir_getobj(objdir, payload->dest_path, payload->dest_pathlen); + CHECK_OBJTYPE(dst_obj, JOVE_OBJ_NONE, "Destination path is occupied!"); + + return untyped_split(target_obj, dst_obj, payload->bytes); +} + +static int +s_syscall_untyped_merge( + jove_owned_obj_t *objdir, + jove_owned_obj_t *target_obj, + size_t payload_bytes, + void *payload_data) +{ + int bytes_needed = sizeof(struct syscall_generic_objpath); + CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for payload!"); + + struct syscall_generic_objpath *payload = payload_data; + bytes_needed += payload->second_pathlen * 2; + CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for second path!"); + + jove_owned_obj_t *snd_obj = objdir_getobj(objdir, payload->second_path, payload->second_pathlen); + CHECK_OBJTYPE(snd_obj, JOVE_OBJ_UNTYPED, "Second object is not an untyped!"); + + return untyped_merge(target_obj, snd_obj); +} + + +int _syscall_handle_untyped( + 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 payload_bytes, + void* payload) +{ + switch(header->callid) { + case SYSCALL_UNTYPED_SIZE: + return untyped_size(target_obj); + case SYSCALL_UNTYPED_ALIGN: + return untyped_align(target_obj); + case SYSCALL_UNTYPED_SPLIT: + return s_syscall_untyped_split(objdir, target_obj, payload_bytes, payload); + default: + kprintf("syscall_untyped: Untyped object does not support syscall %i\n", header->callid); + return EBADARG; + } + return 0; +} diff --git a/sys/syscall_vtt.c b/sys/syscall_vtt.c index 4b58b2c..4dadd6c 100644 --- a/sys/syscall_vtt.c +++ b/sys/syscall_vtt.c @@ -9,16 +9,13 @@ s_syscall_vtt_write( size_t payload_bytes, void *payload_data) { - if(payload_bytes < sizeof(struct syscall_vtt_write)) { - kprintf("syscall_vtt_write: message is too small for this syscall!\n"); - return EOOB; - } - struct syscall_vtt_write *payload = payload_data; - if(payload_bytes < sizeof(struct syscall_vtt_write) + payload->len) { - kprintf("syscall_vtt_write: message is to small for payload! (%i vs %i)\n", - payload->len, payload_bytes); - return EOOB; - } + size_t bytes_needed = sizeof(struct syscall_generic_write); + CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for this syscall!"); + + struct syscall_generic_write *payload = payload_data; + bytes_needed += payload->len * 2; + CHECK_TOOSMALL(bytes_needed, payload_bytes, "Message is too small for write buffer!"); + return vt_write(vtt, payload->data, payload->len); } |
