49 lines
1.4 KiB
C
49 lines
1.4 KiB
C
#include <zinnia/compiler.h>
|
|
#include <zinnia/errno.h>
|
|
#include <zinnia/print.h>
|
|
#include <zinnia/sched.h>
|
|
#include <zinnia/syscall.h>
|
|
#include <zinnia/types.h>
|
|
#include <zinnia/utils.h>
|
|
#include <bits/sched.h>
|
|
|
|
// Declare all syscalls.
|
|
#define SYSCALL_DECLARE(number, name, num_args) extern void sys_##name(...);
|
|
#include <zinnia/syscall_list.inc>
|
|
#undef SYSCALL_DECLARE
|
|
|
|
// Define them.
|
|
const struct syscall syscall_table[256] = {
|
|
#define SYSCALL_DECLARE(number, name, num_args) [number] = {sys_##name, num_args},
|
|
#include <zinnia/syscall_list.inc>
|
|
};
|
|
|
|
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_RET1 = ENOSYS;
|
|
return;
|
|
}
|
|
|
|
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.error;
|
|
}
|