aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/syscall/syscall.c
diff options
context:
space:
mode:
authorMarvin Borner2019-10-31 00:49:00 +0100
committerMarvin Borner2019-10-31 00:49:00 +0100
commit7d5a9792e57b4088cce5cc97837eb04016b57a4d (patch)
tree11eac7aa426f3cb597a3ebd2b08cef0d99e9c0cf /src/kernel/syscall/syscall.c
parent91439462f5ad77eb128658229724c9a3660a2068 (diff)
Implemented basic syscalls and user mode
Doesn't completely work right now
Diffstat (limited to 'src/kernel/syscall/syscall.c')
-rw-r--r--src/kernel/syscall/syscall.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/kernel/syscall/syscall.c b/src/kernel/syscall/syscall.c
new file mode 100644
index 0000000..d1dbd6b
--- /dev/null
+++ b/src/kernel/syscall/syscall.c
@@ -0,0 +1,45 @@
+#include <stdint.h>
+#include <kernel/syscall/syscall.h>
+#include <kernel/interrupts/interrupts.h>
+#include <kernel/graphics/vesa.h>
+#include <kernel/io/io.h>
+
+DEFN_SYSCALL1(vesa_draw_string, 0, const char *);
+
+DEFN_SYSCALL1(vesa_draw_number, 1, int);
+
+DEFN_SYSCALL1(serial_write, 2, const char *);
+
+static void *syscalls[3] = {
+ &vesa_draw_string,
+ &vesa_draw_number,
+ &serial_write,
+};
+uint32_t num_syscalls = 3;
+
+void syscall_handler(struct regs *r) {
+ if (r->eax >= num_syscalls)
+ return;
+
+ void *location = syscalls[r->eax];
+
+ int ret;
+ asm volatile (" \
+ push %1; \
+ push %2; \
+ push %3; \
+ push %4; \
+ push %5; \
+ call *%6; \
+ pop %%ebx; \
+ pop %%ebx; \
+ pop %%ebx; \
+ pop %%ebx; \
+ pop %%ebx; \
+ " : "=a" (ret) : "r" (r->edi), "r" (r->esi), "r" (r->edx), "r" (r->ecx), "r" (r->ebx), "r" (location));
+ r->eax = ret;
+}
+
+void syscalls_install() {
+ irq_install_handler(0x80, &syscall_handler);
+}