Orion
Barry Importing existing Orion kernel d41a53c (3 years, 3 months ago)
diff --git a/task/syscall.c b/task/syscall.c
new file mode 100644
index 0000000..d43542d
--- /dev/null
+++ b/task/syscall.c
@@ -0,0 +1,96 @@
+/*
+ * This file handles system calls. Every system call gets passed to the
+ * syscall_handler() function, which decides which Kernel function to run.
+ * There is an array of syscalls, which are indexed numerically, these are the
+ * syscall numbers.
+ */
+
+#include <sys/syscall.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include "task.h"
+#include "../screen.h"
+
+/* List of syscalls */
+void *syscalls[] = {
+ /* Tasking */
+ [SYSCALL_DBGPRINTF] = dbgprintf,
+ [SYSCALL_CLONE] = clone,
+ [SYSCALL_EXIT] = exit,
+ [SYSCALL_GETPID] = getpid,
+ [SYSCALL_GETUID] = getuid,
+ [SYSCALL_SETUID] = setuid,
+ [SYSCALL_GETEUID] = geteuid,
+ [SYSCALL_SETEUID] = seteuid,
+ [SYSCALL_GETGID] = getgid,
+ [SYSCALL_SETGID] = setgid,
+ [SYSCALL_GETEGID] = getegid,
+ [SYSCALL_SETEGID] = setegid,
+ [SYSCALL_EXECVE] = execve,
+ [SYSCALL_WAITPID] = waitpid,
+ [SYSCALL_TGKILL] = tgkill,
+ [SYSCALL_KILL] = kill,
+ [SYSCALL_TIME] = time,
+ [SYSCALL_TIMES] = times,
+ [SYSCALL_SLEEP] = sleep,
+
+ /* Files */
+ [SYSCALL_OPEN] = open,
+ [SYSCALL_CLOSE] = close,
+ [SYSCALL_READ] = read,
+ [SYSCALL_WRITE] = write,
+ [SYSCALL_IOCTL] = ioctl,
+ [SYSCALL_LSEEK] = lseek,
+ [SYSCALL_STAT] = stat,
+ [SYSCALL_GETDENTS] = getdents,
+ [SYSCALL_MKDIR] = mkdir,
+ [SYSCALL_RMDIR] = rmdir,
+ [SYSCALL_MKNOD] = mknod,
+ [SYSCALL_RENAME] = rename,
+ [SYSCALL_DUP] = dup,
+ [SYSCALL_DUP2] = dup2,
+ [SYSCALL_ISATTY] = isatty,
+
+ /* File System */
+ [SYSCALL_MOUNT] = mount,
+ [SYSCALL_CHDIR] = chdir,
+ [SYSCALL_CHROOT] = chroot,
+ [SYSCALL_GETCWD] = getcwd,
+
+ /* Memory */
+ [SYSCALL_MMAP] = mmap,
+
+ /* Messaging */
+ [SYSCALL_NB_SEND_MSG] = nb_send_msg,
+ [SYSCALL_SEND_MSG] = send_msg,
+ [SYSCALL_NB_RECV_MSG] = nb_recv_msg,
+ [SYSCALL_RECV_MSG] = recv_msg,
+};
+
+/* Handle a syscall */
+void
+syscall_handler(InterruptFrame *frame)
+{
+ if (frame->eax >= sizeof(syscalls)/sizeof(syscalls[0])) {
+ frame->eax = -EINVAL;
+ return;
+ }
+ void *handler = syscalls[frame->eax];
+ int ret;
+ current->inSyscall = 1;
+
+ size_t num;
+ int *val = (int *) frame->esi;
+ if (!verify_access(val, frame->ecx * sizeof(int), PROT_READ)) {
+ frame->eax = -EINVAL;
+ return;
+ }
+ /* Push args onto stack */
+ for (num = frame->ecx; num; num--)
+ asm volatile("pushl %0" :: "r" (val[num - 1]));
+ /* Call handler */
+ asm volatile("call *%1" : "=a" (ret) : "r" (handler));
+
+ frame->eax = ret;
+ current->inSyscall = 0;
+}