diff options
Diffstat (limited to 'syscall/handler.c')
-rw-r--r-- | syscall/handler.c | 76 |
1 files changed, 43 insertions, 33 deletions
diff --git a/syscall/handler.c b/syscall/handler.c index efab179..6ac71da 100644 --- a/syscall/handler.c +++ b/syscall/handler.c @@ -3,64 +3,74 @@ #include "handles.h" #include "device/processor.h" #include "print.h" +#include "error.h" +#include "lock.h" +#include "memory.h" #include <stdint.h> #include <stddef.h> +extern int _syscall_handler_arch(objdir_t *root_dir, objdir_entry_t *target, uint8_t *payload, size_t payload_at); + +static inline int +s_invoke_release( + objdir_t *root_dir, + objdir_entry_t *target, + uint8_t *payload, + size_t payload_at, + int (*invoke)(objdir_t*, objdir_entry_t*, uint8_t*, size_t)) +{ + int e = invoke(root_dir, target, payload, payload_at); + return e; +} + static int -s_syscall_handle_invoke(objdir_t *root_dir, void *payload) +s_syscall_handle_invoke(objdir_t *root_dir, uint8_t *payload) { - struct syscallInvokeHeader *invokeHeader = payload; - uintmax_t target_path = invokeHeader->target_path; - objdir_entry_t *target_entry = objdir_seek(root_dir, target_path); - - klogf("target entry %x:%p func %i\n", target_path, target_entry->data, invokeHeader->func_id); + size_t payload_at = 0; + size_t target_pathw; + objdir_entry_t *target_entry; + SYSCALL_PAYLOAD_TAKEOBJ(payload, payload_at, target_pathw, target_entry); - if(target_entry == NULL) return -1; switch(target_entry->type) { case KO_NONE: - return -1; + return -KE_BADOBJ; case KO_OBJECT_DIRECTORY: - return syscall_handle_invoke_objdir(root_dir, (objdir_t*)target_entry->data, payload); + return s_invoke_release(root_dir, target_entry, payload, payload_at, syscall_handle_invoke_objdir); + case KO_MEMORY_UNTYPED: + return s_invoke_release(root_dir, target_entry, payload, payload_at, syscall_handle_invoke_untyped); + case KO_MEMORY_MAPPING: + return s_invoke_release(root_dir, target_entry, payload, payload_at, syscall_handle_invoke_mapping); default: - klogf("Missing implementation of invoke for type %i\n", target_entry->type); - return -1; + return _syscall_handler_arch(root_dir, target_entry, payload, payload_at); } } int _syscall_handler(uintmax_t argsi, int calli) { - objdir_t *objdir = ((processor_t*)processor_current())->odir; - objdir_entry_t *payload_entry = objdir_seek(objdir, argsi); - if(payload_entry == NULL) { - klogf("Missing object for syscall %i (%x)\n", calli, argsi); - return -1; - } + objdir_t *root_dir = ((processor_t*)processor_current())->odir; + objdir_entry_t *payload_entry = objdir_seek(root_dir, (uint8_t*)&argsi, sizeof(uintmax_t)); + if(payload_entry->type != KO_MESSAGE) { klogf("Tried to invoke syscall %i with invalid object %x\n", calli, argsi); - return -1; + return -KE_BADMSG; } - - uintmax_t *payload = (void*)payload_entry->data; + mtx_acquire(&payload_entry->lock); + uint8_t *payload = ko_entry_data(payload_entry); switch(calli) { - case SYSCALL_INVOKE: return s_syscall_handle_invoke(objdir, payload); + case SYSCALL_INVOKE: { + int e = s_syscall_handle_invoke(root_dir, payload); + mtx_release(&payload_entry->lock); + return e; + } case SYSCALL_DEBUG_PUTC: kprintf("%c", (char)payload[0]); + mtx_release(&payload_entry->lock); return 0; - case SYSCALL_DEBUG_IDENTIFY: - { - objdir_entry_t *target_entry = objdir_seek(objdir, payload[0]); - if(payload_entry == NULL) { - payload[0] = KO_NONE; - } else { - payload[0] = target_entry->type; - } - return 0; - } default: klogf("Invalid syscall %i caught! Failing.\n", calli); - return -1; + mtx_release(&payload_entry->lock); + return -KE_BADCALL; } - return -1; } |