diff options
Diffstat (limited to 'syscall')
-rw-r--r-- | syscall/handler.c | 66 | ||||
-rw-r--r-- | syscall/handles.h | 8 | ||||
-rw-r--r-- | syscall/invoke_objdir.c | 34 |
3 files changed, 108 insertions, 0 deletions
diff --git a/syscall/handler.c b/syscall/handler.c new file mode 100644 index 0000000..efab179 --- /dev/null +++ b/syscall/handler.c @@ -0,0 +1,66 @@ +#include "syscall.h" +#include "object.h" +#include "handles.h" +#include "device/processor.h" +#include "print.h" +#include <stdint.h> +#include <stddef.h> + +static int +s_syscall_handle_invoke(objdir_t *root_dir, void *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); + + if(target_entry == NULL) return -1; + switch(target_entry->type) { + case KO_NONE: + return -1; + case KO_OBJECT_DIRECTORY: + return syscall_handle_invoke_objdir(root_dir, (objdir_t*)target_entry->data, payload); + default: + klogf("Missing implementation of invoke for type %i\n", target_entry->type); + return -1; + } +} + +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; + } + if(payload_entry->type != KO_MESSAGE) { + klogf("Tried to invoke syscall %i with invalid object %x\n", calli, argsi); + return -1; + } + + uintmax_t *payload = (void*)payload_entry->data; + + switch(calli) { + case SYSCALL_INVOKE: return s_syscall_handle_invoke(objdir, payload); + case SYSCALL_DEBUG_PUTC: + kprintf("%c", (char)payload[0]); + 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; + } + return -1; +} diff --git a/syscall/handles.h b/syscall/handles.h new file mode 100644 index 0000000..f9fd79c --- /dev/null +++ b/syscall/handles.h @@ -0,0 +1,8 @@ +#ifndef _JOVE_SYSCALL_HANDLES_H +#define _JOVE_SYSCALL_HANDLES_H 1 + +#include "object.h" + +int syscall_handle_invoke_objdir(objdir_t *root_dir, objdir_t *target_dir, void *payload); + +#endif diff --git a/syscall/invoke_objdir.c b/syscall/invoke_objdir.c new file mode 100644 index 0000000..4698f34 --- /dev/null +++ b/syscall/invoke_objdir.c @@ -0,0 +1,34 @@ +#include "handles.h" +#include "syscall.h" + +static int +s_handle_invoke_objdir_nmemb(objdir_t *root_dir, objdir_t *target_dir, void *payload) +{ + struct syscallInvoke_objdir_nmemb *payloadStruct = payload; + payloadStruct->value = target_dir->self.data; + return 0; +} + +static int +s_handle_invoke_objdir_getmemb(objdir_t *root_dir, objdir_t *target_dir, void *payload) +{ + struct syscallInvoke_objdir_getmemb *payloadStruct = payload; + payloadStruct->value = target_dir->entries[payloadStruct->member].type; + return 0; +} + +static int (*s_invoke_handles[])(objdir_t*, objdir_t*, void*) = { + [INVOKE_OBJDIR_NMEMB] = s_handle_invoke_objdir_nmemb, + [INVOKE_OBJDIR_GETMEMB] = s_handle_invoke_objdir_getmemb +}; +static size_t s_invoke_handles_count = sizeof(s_invoke_handles) / sizeof(void*); + +int +syscall_handle_invoke_objdir(objdir_t *root_dir, objdir_t *target_dir, void *payload) +{ + struct syscallInvokeHeader *invokeHeader = payload; + size_t funcid = invokeHeader->func_id; + + if(funcid >= s_invoke_handles_count) return -1; + return s_invoke_handles[funcid](root_dir, target_dir, payload); +} |