#include #include #include #include #include #include #include #include // Declare all syscalls. #include #undef SYSCALL_DECLARE // Define them. const struct syscall syscall_table[256] = { #define SYSCALL_DECLARE(number, name, num_args) [number] = {sys_##name, num_args}, #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; return; } void (*func)(struct arch_context* ctx) = syscall_table[num].func; func(ctx); }