From 98e15f73f090c32b5197ecec0845c408d4a54608 Mon Sep 17 00:00:00 2001
From: Marvin Borner
Date: Wed, 2 Jun 2021 22:27:59 +0200
Subject: Huge scheduler rewrite and other things

---
 kernel/features/io.c      |   2 +-
 kernel/features/load.c    |  50 +++-------------
 kernel/features/mm.c      |  38 ++++++++----
 kernel/features/proc.c    | 147 +++++++++++++++++++++++++++++-----------------
 kernel/features/syscall.c | 101 +++++++++++++++----------------
 5 files changed, 176 insertions(+), 162 deletions(-)

(limited to 'kernel/features')

diff --git a/kernel/features/io.c b/kernel/features/io.c
index 28388ae..8126ccf 100644
--- a/kernel/features/io.c
+++ b/kernel/features/io.c
@@ -5,7 +5,7 @@
 #include <def.h>
 #include <drivers/bga.h>
 #include <drivers/cpu.h>
-#include <drivers/interrupts.h>
+#include <drivers/int.h>
 #include <drivers/ps2.h>
 #include <drivers/timer.h>
 #include <drivers/vbe.h>
diff --git a/kernel/features/load.c b/kernel/features/load.c
index 1059240..4951351 100644
--- a/kernel/features/load.c
+++ b/kernel/features/load.c
@@ -14,13 +14,11 @@ res elf_load(const char *name, struct proc *proc)
 	if (!memory_readable(name))
 		return -EFAULT;
 
-	stac();
 	char path[64] = { "/apps/" };
-	strlcat(path, name, sizeof(path));
-	strlcpy(proc->dir, path, sizeof(proc->dir));
-	strlcat(path, "/exec", sizeof(path));
-	strlcpy(proc->name, name, sizeof(proc->name));
-	clac();
+	strlcat_user(path, name, sizeof(path));
+	strlcpy_user(proc->dir, path, sizeof(proc->dir));
+	strlcat_user(path, "/exec", sizeof(path));
+	strlcpy_user(proc->name, name, sizeof(proc->name));
 
 	struct stat s = { 0 };
 	memory_bypass_enable();
@@ -30,11 +28,11 @@ res elf_load(const char *name, struct proc *proc)
 		return stat;
 
 	struct elf_header header = { 0 };
-	stac();
 	memory_bypass_enable();
+	stac();
 	res read = vfs_read(path, &header, 0, sizeof(header));
-	memory_bypass_disable();
 	clac();
+	memory_bypass_disable();
 	if (read < 0)
 		return read;
 	if (read != sizeof(header))
@@ -124,22 +122,6 @@ res elf_load(const char *name, struct proc *proc)
 		}
 		memory_bypass_disable();
 
-		// TODO: Use section and symbol name for logging or something? (e.g. in page fault handler)
-		/* u32 offset = section_strings.offset + section.name; */
-		/* if (offset >= s.size) */
-		/* 	return -ENOEXEC; */
-		/* memory_bypass_enable(); */
-		/* char name[64] = { 0 }; // Max length? */
-		/* if (vfs_read(path, &name, offset, sizeof(name)) != sizeof(name)) { */
-		/* 	memory_bypass_disable(); */
-		/* 	return -ENOEXEC; */
-		/* } */
-		/* memory_bypass_disable(); */
-		/* printf("%d\n", section.name); */
-		/* if (section.type == ELF_SECTION_TYPE_SYMTAB) { */
-		/* } else if (section.type == ELF_SECTION_TYPE_STRTAB && i != header.shstrndx) { */
-		/* } */
-
 		// Remap readonly sections
 		if (!(section.flags & ELF_SECTION_FLAG_WRITE) && section.addr &&
 		    memory_is_user((void *)section.addr)) {
@@ -149,26 +131,8 @@ res elf_load(const char *name, struct proc *proc)
 		}
 	}
 
-	struct page_dir *prev;
-	memory_backup_dir(&prev);
-	memory_switch_dir(proc->page_dir);
-
-	// Allocate user stack with readonly lower and upper page boundary
-	u32 user_stack = (u32)memory_alloc_with_boundary(proc->page_dir, PROC_STACK_SIZE,
-							 MEMORY_CLEAR | MEMORY_USER);
-
-	// Allocate kernel stack with readonly lower and upper page boundary
-	u32 kernel_stack =
-		(u32)memory_alloc_with_boundary(proc->page_dir, PROC_STACK_SIZE, MEMORY_CLEAR);
-
-	proc->stack.user = user_stack + PROC_STACK_SIZE;
-	proc->stack.kernel = kernel_stack + PROC_STACK_SIZE;
-	proc->regs.esp = proc->stack.kernel;
-	proc->regs.ebp = proc->stack.user;
-	proc->regs.useresp = proc->stack.user;
-	proc->regs.eip = header.entry + rand_off;
 	proc->entry = header.entry + rand_off;
+	proc_make_regs(proc);
 
-	memory_switch_dir(prev);
 	return EOK;
 }
diff --git a/kernel/features/mm.c b/kernel/features/mm.c
index 227ba0a..0137256 100644
--- a/kernel/features/mm.c
+++ b/kernel/features/mm.c
@@ -14,6 +14,7 @@
 
 PROTECTED static struct page_dir kernel_dir ALIGNED(PAGE_SIZE) = { 0 };
 static struct page_table kernel_tables[PAGE_KERNEL_COUNT] ALIGNED(PAGE_SIZE) = { 0 };
+static struct page_dir *current_dir = NULL;
 
 extern u32 kernel_rw_start;
 extern u32 kernel_rw_end;
@@ -66,14 +67,15 @@ static const char *page_fault_section(u32 addr)
 	return section;
 }
 
-void page_fault_handler(struct regs *r)
+static void page_fault_handler(u32 esp)
 {
+	struct int_frame *frame = (struct int_frame *)esp;
 	print("--- PAGE FAULT! ---\n");
 
 	// Check error code
-	const char *type = (r->err_code & 1) ? "present" : "non-present";
-	const char *operation = (r->err_code & 2) ? "write" : "read";
-	const char *super = (r->err_code & 4) ? "User" : "Super";
+	const char *type = (frame->err_code & 1) ? "present" : "non-present";
+	const char *operation = (frame->err_code & 2) ? "write" : "read";
+	const char *super = (frame->err_code & 4) ? "User" : "Super";
 
 	// Check cr2 address (virtual and physical)
 	u32 vaddr;
@@ -87,16 +89,13 @@ void page_fault_handler(struct regs *r)
 	printf("%s process tried to %s a %s page at [vaddr=%x; paddr=%x]\n", super, operation, type,
 	       vaddr, paddr);
 
-	if (proc && vaddr > proc->regs.ebp - PROC_STACK_SIZE - PAGE_SIZE &&
-	    vaddr < proc->regs.ebp + PAGE_SIZE)
+	if (proc && vaddr > proc->stack.user_ptr - PROC_STACK_SIZE - PAGE_SIZE &&
+	    vaddr < proc->stack.user_ptr + PAGE_SIZE)
 		print("Probably a stack overflow\n");
 
 	printf("Sections: [vaddr_section=%s; paddr_section=%s; eip_section=%s]\n",
-	       page_fault_section(vaddr), page_fault_section(paddr), page_fault_section(r->eip));
-
-	/* printf("%b\n", virtual_entry(dir, vaddr)->uint); */
-
-	isr_panic(r);
+	       page_fault_section(vaddr), page_fault_section(paddr),
+	       page_fault_section(frame->eip));
 }
 
 /**
@@ -424,8 +423,18 @@ void *memory_alloc(struct page_dir *dir, u32 size, u32 flags)
 		goto err;
 	}
 
-	if (flags & MEMORY_CLEAR)
-		memset_user((void *)vaddr, 0, size);
+	if (flags & MEMORY_CLEAR) {
+		// TODO: Neater solution
+		if (dir == current_dir) {
+			memset_user((void *)vaddr, 0, size);
+		} else {
+			struct page_dir *bak;
+			memory_backup_dir(&bak);
+			memory_switch_dir(dir);
+			memset_user((void *)vaddr, 0, size);
+			memory_switch_dir(bak);
+		}
+	}
 
 	return (void *)vaddr;
 
@@ -587,6 +596,7 @@ res memory_sys_shaccess(struct page_dir *dir, u32 id, u32 *addr, u32 *size)
 
 void memory_switch_dir(struct page_dir *dir)
 {
+	current_dir = dir;
 	paging_switch_dir(virtual_to_physical(&kernel_dir, (u32)dir));
 }
 
@@ -760,4 +770,6 @@ CLEAR void memory_install(void)
 	paging_enable();
 
 	memory_objects = list_new();
+
+	int_trap_handler_add(14, page_fault_handler);
 }
diff --git a/kernel/features/proc.c b/kernel/features/proc.c
index 8fc922e..ce33495 100644
--- a/kernel/features/proc.c
+++ b/kernel/features/proc.c
@@ -27,24 +27,26 @@ PROTECTED static struct list *proc_list_idle = NULL;
 
 // TODO: Use less memcpy and only copy relevant registers
 // TODO: 20 priority queues (https://www.kernel.org/doc/html/latest/scheduler/sched-nice-design.html)
-HOT FLATTEN void scheduler(struct regs *regs)
+HOT FLATTEN u32 scheduler(u32 esp)
 {
 	spinlock(&locked);
 
-	if (RING(regs) == 3)
-		PROC(current)->ticks.user++;
-	else
-		PROC(current)->ticks.kernel++;
+	if (!current) {
+		current = idle_proc;
+		locked = 0;
+		return PROC(current)->stack.kernel_ptr;
+	}
 
 	if (PROC(current)->quantum.cnt >= PROC(current)->quantum.val) {
 		PROC(current)->quantum.cnt = 0;
 	} else {
 		PROC(current)->quantum.cnt++;
 		locked = 0;
-		return;
+		return esp;
 	}
 
-	memcpy(&PROC(current)->regs, regs, sizeof(*regs));
+	fpu_save(PROC(current));
+	PROC(current)->stack.kernel_ptr = esp;
 
 	if (current->next) {
 		current = current->next;
@@ -54,17 +56,21 @@ HOT FLATTEN void scheduler(struct regs *regs)
 		current = idle_proc;
 	}
 
-	tss_set_stack(PROC(current)->stack.kernel);
 	memory_switch_dir(PROC(current)->page_dir);
-	memcpy(regs, &PROC(current)->regs, sizeof(*regs));
+	tss_set_stack(PROC(current)->stack.kernel_ptr);
+	fpu_restore(PROC(current));
 
 #if DEBUG_SCHEDULER
-	if (current != idle_proc)
+	if (current != idle_proc) {
+		struct int_frame_user *frame =
+			(struct int_frame_user *)PROC(current)->stack.kernel_ptr;
 		printf("%s (%d): eip %x esp %x useresp %x\n", PROC(current)->name,
-		       PROC(current)->pid, regs->eip, regs->esp, regs->useresp);
+		       PROC(current)->pid, frame->eip, frame->esp, frame->useresp);
+	}
 #endif
 
 	locked = 0;
+	return PROC(current)->stack.kernel_ptr;
 }
 
 void proc_print(void)
@@ -151,7 +157,7 @@ void proc_state(struct proc *proc, enum proc_state state)
 	// else: Nothing to do!
 }
 
-void proc_exit(struct proc *proc, struct regs *r, s32 status)
+void proc_exit(struct proc *proc, s32 status)
 {
 	assert(proc != idle_proc->data);
 
@@ -162,8 +168,8 @@ void proc_exit(struct proc *proc, struct regs *r, s32 status)
 	}
 
 	if (current->data == proc) {
-		current = idle_proc;
-		memcpy(r, &PROC(idle_proc)->regs, sizeof(*r));
+		memory_switch_dir(virtual_kernel_dir());
+		current = NULL;
 	}
 
 	printf("Process %s (%d) exited with status %d (%s)\n",
@@ -188,28 +194,46 @@ void proc_exit(struct proc *proc, struct regs *r, s32 status)
 	stack_destroy(proc->messages);
 	list_destroy(proc->memory); // TODO: Decrement memory ref links
 	virtual_destroy_dir(proc->page_dir);
-
+	memset(proc, 0, sizeof(*proc));
 	free(proc);
 
-	proc_yield_regs(r);
+	proc_yield();
+	assert_not_reached();
 }
 
 void proc_yield(void)
 {
-	// TODO: Fix yielding without debug mode (File size?! Regs?! IDK?!)
-	proc_reset_quantum(PROC(current));
-	__asm__ volatile("int $127");
+	__asm__ volatile("int $129");
 }
 
-void proc_yield_regs(struct regs *r)
+void proc_stack_user_push(struct proc *proc, const void *data, u32 size)
 {
-	proc_reset_quantum(PROC(current));
-	scheduler(r);
+	struct page_dir *prev;
+	memory_backup_dir(&prev);
+	memory_switch_dir(proc->page_dir);
+
+	proc->stack.user_ptr -= size;
+	memcpy_user((void *)proc->stack.user_ptr, data, size);
+
+	memory_switch_dir(prev);
+}
+
+void proc_stack_kernel_push(struct proc *proc, const void *data, u32 size)
+{
+	struct page_dir *prev;
+	memory_backup_dir(&prev);
+	memory_switch_dir(proc->page_dir);
+
+	proc->stack.kernel_ptr -= size;
+	memcpy_user((void *)proc->stack.kernel_ptr, data, size);
+
+	memory_switch_dir(prev);
 }
 
 struct proc *proc_make(enum proc_priv priv)
 {
 	struct proc *proc = zalloc(sizeof(*proc));
+	fpu_init(proc);
 	proc->pid = current_pid++;
 	proc->priv = priv;
 	proc->messages = stack_new();
@@ -219,35 +243,55 @@ struct proc *proc_make(enum proc_priv priv)
 	proc->quantum.val = PROC_QUANTUM;
 	proc->quantum.cnt = 0;
 
-	// Init regs
-	u8 is_kernel = priv == PROC_PRIV_KERNEL;
-	u32 data = is_kernel ? GDT_SUPER_DATA_OFFSET : GDT_USER_DATA_OFFSET;
-	u32 code = is_kernel ? GDT_SUPER_CODE_OFFSET : GDT_USER_CODE_OFFSET;
-	proc->regs.gs = data;
-	proc->regs.fs = data;
-	proc->regs.es = data;
-	proc->regs.ds = data;
-	proc->regs.ss = data;
-	proc->regs.cs = code;
-	proc->regs.eflags = EFLAGS_ALWAYS | EFLAGS_INTERRUPTS;
-
-	list_add(proc_list_running, proc);
-
 	return proc;
 }
 
-void proc_stack_push(struct proc *proc, u32 data)
+void proc_make_regs(struct proc *proc)
 {
-	struct page_dir *prev;
-	memory_backup_dir(&prev);
-	memory_switch_dir(proc->page_dir);
+	struct int_frame_user frame = { 0 };
 
-	proc->regs.useresp -= sizeof(data);
-	stac();
-	*(u32 *)proc->regs.useresp = data;
-	clac();
+	assert(proc->entry);
+	frame.eip = proc->entry;
 
-	memory_switch_dir(prev);
+	// Allocate user stack with readonly lower and upper page boundary
+	u32 user_stack = (u32)memory_alloc_with_boundary(proc->page_dir, PROC_STACK_SIZE,
+							 MEMORY_CLEAR | MEMORY_USER);
+
+	// Allocate kernel stack with readonly lower and upper page boundary
+	u32 kernel_stack =
+		(u32)memory_alloc_with_boundary(proc->page_dir, PROC_STACK_SIZE, MEMORY_CLEAR);
+
+	proc->stack.user = user_stack + PROC_STACK_SIZE;
+	proc->stack.user_ptr = proc->stack.user;
+
+	proc->stack.kernel = kernel_stack + PROC_STACK_SIZE;
+	proc->stack.kernel_ptr = proc->stack.kernel;
+
+	frame.esp = proc->stack.kernel;
+	frame.ebp = proc->stack.kernel;
+	frame.useresp = proc->stack.user;
+
+	// Init regs
+	u8 is_kernel = proc->priv == PROC_PRIV_KERNEL;
+	u32 data = is_kernel ? GDT_SUPER_DATA_OFFSET : GDT_USER_DATA_OFFSET;
+	u32 code = is_kernel ? GDT_SUPER_CODE_OFFSET : GDT_USER_CODE_OFFSET;
+	frame.gs = data;
+	frame.fs = data;
+	frame.es = data;
+	frame.ds = data;
+	frame.ss = data;
+	frame.cs = code;
+	frame.eflags = EFLAGS_ALWAYS | EFLAGS_INTERRUPTS;
+
+	// Push frame as the values get popped (see int.asm)
+	proc_stack_kernel_push(proc, &frame, sizeof(frame));
+
+	// Push argc and argv // TODO
+	u32 arg = 0;
+	proc_stack_user_push(proc, &arg, sizeof(arg));
+	proc_stack_user_push(proc, &arg, sizeof(arg));
+
+	list_add(proc_list_running, proc);
 }
 
 // TODO: Procfs needs a simpler interface structure (memcmp and everything sucks)
@@ -331,8 +375,6 @@ void proc_init(void)
 	if (proc_list_running)
 		panic("Already initialized processes!");
 
-	cli();
-	scheduler_enable();
 	proc_list_running = list_new();
 	proc_list_blocked = list_new();
 	proc_list_idle = list_new();
@@ -354,8 +396,6 @@ void proc_init(void)
 	// TODO: Reimplement hlt privileges in idle proc (SMEP!)
 	struct proc *kernel_proc = proc_make(PROC_PRIV_NONE);
 	assert(elf_load("idle", kernel_proc) == EOK);
-	proc_stack_push(kernel_proc, 0);
-	proc_stack_push(kernel_proc, 0);
 	kernel_proc->state = PROC_BLOCKED;
 	kernel_proc->quantum.val = 0;
 	kernel_proc->quantum.cnt = 0;
@@ -365,12 +405,10 @@ void proc_init(void)
 	// Init proc (root)
 	struct proc *init = proc_make(PROC_PRIV_ROOT);
 	assert(elf_load("init", init) == EOK);
-	proc_stack_push(init, 0);
-	proc_stack_push(init, 0);
 	current = list_first_data(proc_list_running, init);
 
-	_eip = init->regs.eip;
-	_esp = init->regs.useresp;
+	_eip = init->entry;
+	_esp = init->stack.user_ptr;
 
 	// We'll shortly jump to usermode. Clear and protect every secret!
 	memory_user_hook();
@@ -381,6 +419,5 @@ void proc_init(void)
 
 	// You're waiting for a train. A train that will take you far away...
 	proc_jump_userspace();
-
-	panic("Returned from limbo!\n");
+	assert_not_reached();
 }
diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c
index 9efb849..93355db 100644
--- a/kernel/features/syscall.c
+++ b/kernel/features/syscall.c
@@ -1,7 +1,7 @@
 // MIT License, Copyright (c) 2020 Marvin Borner
 
 #include <drivers/cpu.h>
-#include <drivers/interrupts.h>
+#include <drivers/int.h>
 #include <drivers/timer.h>
 #include <errno.h>
 #include <fs.h>
@@ -15,103 +15,106 @@
 #include <sys.h>
 #include <syscall.h>
 
-static void syscall_handler(struct regs *r)
+static u32 syscall_handler(u32 esp)
 {
-	enum sys num = r->eax;
+	struct int_frame_user *frame = (struct int_frame_user *)esp;
+	enum sys num = frame->eax;
 
-	/* printf("[SYSCALL] %d from %s\n", num, proc_current()->name); */
+#if DEBUG_SYSCALLS
+	printf("[SYSCALL] %d from %s\n", num, proc_current()->name);
+#endif
 
 	switch (num) {
 	// Memory operations
 	case SYS_ALLOC: {
-		r->eax = memory_sys_alloc(proc_current()->page_dir, r->ebx, (u32 *)r->ecx,
-					  (u32 *)r->edx, (u8)r->esi);
+		frame->eax = memory_sys_alloc(proc_current()->page_dir, frame->ebx,
+					      (u32 *)frame->ecx, (u32 *)frame->edx, (u8)frame->esi);
 		break;
 	}
 	case SYS_FREE: {
-		r->eax = memory_sys_free(proc_current()->page_dir, r->ebx);
+		frame->eax = memory_sys_free(proc_current()->page_dir, frame->ebx);
 		break;
 	}
 	case SYS_SHACCESS: {
-		r->eax = memory_sys_shaccess(proc_current()->page_dir, r->ebx, (u32 *)r->ecx,
-					     (u32 *)r->edx);
+		frame->eax = memory_sys_shaccess(proc_current()->page_dir, frame->ebx,
+						 (u32 *)frame->ecx, (u32 *)frame->edx);
 		break;
 	}
 
 	// File operations
 	case SYS_STAT: {
-		r->eax = vfs_stat((char *)r->ebx, (struct stat *)r->ecx);
+		frame->eax = vfs_stat((char *)frame->ebx, (struct stat *)frame->ecx);
 		break;
 	}
 	case SYS_READ: {
-		r->eax = vfs_read((char *)r->ebx, (void *)r->ecx, r->edx, r->esi);
+		frame->eax =
+			vfs_read((char *)frame->ebx, (void *)frame->ecx, frame->edx, frame->esi);
 		break;
 	}
 	case SYS_WRITE: {
-		r->eax = vfs_write((char *)r->ebx, (void *)r->ecx, r->edx, r->esi);
+		frame->eax =
+			vfs_write((char *)frame->ebx, (void *)frame->ecx, frame->edx, frame->esi);
 		break;
 	}
 
 	// I/O operations
 	case SYS_IOPOLL: {
-		r->eax = io_poll((void *)r->ebx);
+		frame->eax = io_poll((void *)frame->ebx);
 		break;
 	}
 	case SYS_IOREAD: {
-		res ready = io_ready(r->ebx);
+		res ready = io_ready(frame->ebx);
 		if (ready == -EAGAIN) {
-			io_block(r->ebx, proc_current());
+			io_block(frame->ebx, proc_current());
 		} else if (ready != EOK) {
-			r->eax = ready;
+			frame->eax = ready;
 			break;
 		}
-		r->eax = io_read(r->ebx, (void *)r->ecx, r->edx, r->esi);
+		frame->eax = io_read(frame->ebx, (void *)frame->ecx, frame->edx, frame->esi);
 		break;
 	}
 	case SYS_IOWRITE: {
-		r->eax = io_write(r->ebx, (void *)r->ecx, r->edx, r->esi);
+		frame->eax = io_write(frame->ebx, (void *)frame->ecx, frame->edx, frame->esi);
 		break;
 	}
 	case SYS_IOCONTROL: {
-		r->eax = io_control(r->ebx, r->ecx, (void *)r->edx, (void *)r->esi, (void *)r->edi);
+		frame->eax = io_control(frame->ebx, frame->ecx, (void *)frame->edx,
+					(void *)frame->esi, (void *)frame->edi);
 		break;
 	}
 
 	// Process operations
 	case SYS_EXEC: {
-		char *path = (char *)r->ebx;
+		char *path = (char *)frame->ebx;
 		struct proc *proc = proc_make(PROC_PRIV_NONE);
-		r->eax = (u32)elf_load(path, proc);
-		if (r->eax != EOK) {
-			proc_exit(proc, r, -r->eax);
-		} else {
-			// TODO: Reimplement argc,argv
-			proc_stack_push(proc, 0);
-			proc_yield_regs(r);
-		}
+		frame->eax = (u32)elf_load(path, proc);
+		if (frame->eax != EOK)
+			proc_exit(proc, -frame->eax);
+		else
+			proc_yield();
 		break;
 	}
 	case SYS_EXIT: {
-		r->eax = EOK;
-		proc_exit(proc_current(), r, (s32)r->ebx);
+		frame->eax = EOK;
+		proc_exit(proc_current(), (s32)frame->ebx);
 		break;
 	}
 	case SYS_YIELD: {
-		r->eax = EOK;
-		proc_yield_regs(r);
+		frame->eax = EOK;
+		proc_yield();
 		break;
 	}
 
 	// System operations
 	case SYS_BOOT: { // TODO: Move
-		if (r->ebx != SYS_BOOT_MAGIC) {
-			r->eax = -EINVAL;
+		if (frame->ebx != SYS_BOOT_MAGIC) {
+			frame->eax = -EINVAL;
 			break;
 		}
 		if (!proc_super()) {
-			r->eax = -EACCES;
+			frame->eax = -EACCES;
 		}
-		switch (r->ecx) {
+		switch (frame->ecx) {
 		case SYS_BOOT_REBOOT:
 			print("Rebooting...\n");
 			outb(0x64, 0xfe);
@@ -126,38 +129,36 @@ static void syscall_handler(struct regs *r)
 			__asm__ volatile("cli\nud2");
 			break;
 		default:
-			r->eax = -EINVAL;
+			frame->eax = -EINVAL;
 		}
 		break;
 	}
 
 	case SYS_MIN:
 	case SYS_MAX:
-		r->eax = -EINVAL;
+		frame->eax = -EINVAL;
 		break;
 
-	// TODO: Reimplement network functions using VFS
 	default: {
-		r->eax = -EINVAL;
+		frame->eax = -EINVAL;
 		printf("Unknown syscall %d!\n", num);
 		break;
 	}
 	}
+
+	return esp;
 }
 
-// For kernel syscalls (internal)
-static void syscall_special_handler(struct regs *r)
+// Internal scheduler (=> yield) call
+static u32 syscall_special_handler(u32 esp)
 {
-	if (RING(r) != 0)
-		return;
-
-	scheduler(r);
+	if (proc_current())
+		proc_reset_quantum(proc_current());
+	return scheduler(esp);
 }
 
 CLEAR void syscall_init(void)
 {
-	idt_set_gate(0x7f, (u32)isr127, 0x08, 0x8e);
-	idt_set_gate(0x80, (u32)isr128, 0x08, 0xee);
-	isr_install_handler(0x7f, syscall_special_handler);
-	isr_install_handler(0x80, syscall_handler);
+	int_special_handler_add(0, syscall_handler);
+	int_special_handler_add(1, syscall_special_handler);
 }
-- 
cgit v1.2.3