#include "syscall.h" #include "object.h" #include "handles.h" #include "device/processor.h" #include "print.h" #include "error.h" #include "lock.h" #include "memory.h" #include #include 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, uint8_t *payload) { size_t payload_at = 0; size_t target_pathw; objdir_entry_t *target_entry; SYSCALL_PAYLOAD_TAKEOBJ(payload, payload_at, target_pathw, target_entry); switch(target_entry->type) { case KO_NONE: return -KE_BADOBJ; case KO_OBJECT_DIRECTORY: 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: return _syscall_handler_arch(root_dir, target_entry, payload, payload_at); } } int _syscall_handler(uintmax_t argsi, int calli) { 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 -KE_BADMSG; } mtx_acquire(&payload_entry->lock); uint8_t *payload = ko_entry_data(payload_entry); switch(calli) { 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; default: klogf("Invalid syscall %i caught! Failing.\n", calli); mtx_release(&payload_entry->lock); return -KE_BADCALL; } }