summaryrefslogtreecommitdiffstats
path: root/syscall/handler.c
blob: efab1792dc7ed66ab57bbc3523eb772acb9dec8c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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;
}