diff --git a/syscalls/dispatch.c b/syscalls/dispatch.c index e935f9c..12f419d 100644 --- a/syscalls/dispatch.c +++ b/syscalls/dispatch.c @@ -17,37 +17,31 @@ const struct syscall syscall_table[256] = { #include }; -// TODO: Implement this -[[gnu::no_caller_saved_registers]] -struct syscall_ret syscall_dispatch_fast( - uintptr_t a0, - uintptr_t a1, - uintptr_t a2, - uintptr_t a3, - uintptr_t a4, - uintptr_t a5, - size_t num -) { - // No need to check the table size here. In order to get to this point, - // we already have to check if this is a fast syscall. - if (syscall_table[num].func == nullptr) { - return (struct syscall_ret){.errno = ENOSYS}; - } - - struct syscall_ret (*func)(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t) = - syscall_table[num].func; - - return func(a0, a1, a2, a3, a4, a5); -} - void syscall_dispatch(struct arch_context* ctx) { const size_t num = ctx->ARCH_CTX_NUM; if (num >= ARRAY_SIZE(syscall_table) || syscall_table[num].func == nullptr) { - ctx->ARCH_CTX_RET0 = ENOSYS; + ctx->ARCH_CTX_RET1 = ENOSYS; return; } - void (*func)(struct arch_context* ctx) = syscall_table[num].func; - func(ctx); + struct syscall_ret ret; + if (syscall_table[num].num_args == -1) { + struct syscall_ret (*func)(struct arch_context*) = syscall_table[num].func; + ret = func(ctx); + } else { + struct syscall_ret (*func)(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t) = + syscall_table[num].func; + ret = func( + ctx->ARCH_CTX_A0, + ctx->ARCH_CTX_A1, + ctx->ARCH_CTX_A2, + ctx->ARCH_CTX_A3, + ctx->ARCH_CTX_A4, + ctx->ARCH_CTX_A5 + ); + } + + ctx->ARCH_CTX_RET0 = ret.value; + ctx->ARCH_CTX_RET1 = ret.errno; }