73 lines
1.1 KiB
C
73 lines
1.1 KiB
C
/*
|
|
* vim:tabstop=4
|
|
* vim:noexpandtab
|
|
*/
|
|
#include <system.h>
|
|
#include <syscall.h>
|
|
|
|
|
|
/*
|
|
* System calls themselves
|
|
*/
|
|
|
|
/*
|
|
* print something to the core terminal
|
|
*/
|
|
static int print(char * s) {
|
|
kprintf(s);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Exit the current task.
|
|
* DOES NOT RETURN!
|
|
*/
|
|
static int exit(int retval) {
|
|
/* Deschedule the current task */
|
|
task_exit(retval);
|
|
while (1) { };
|
|
return retval;
|
|
}
|
|
|
|
/*
|
|
* System Call Internals
|
|
*/
|
|
static void syscall_handler(struct regs * r);
|
|
static uintptr_t syscalls[] = {
|
|
/* System Call Table */
|
|
(uintptr_t)&exit,
|
|
(uintptr_t)&print
|
|
};
|
|
uint32_t num_syscalls = 2;
|
|
|
|
void
|
|
syscalls_install() {
|
|
isrs_install_handler(0x7F, &syscall_handler);
|
|
}
|
|
|
|
void
|
|
syscall_handler(
|
|
struct regs * r
|
|
) {
|
|
if (r->eax >= num_syscalls) {
|
|
return;
|
|
}
|
|
uintptr_t location = syscalls[r->eax];
|
|
|
|
uint32_t ret;
|
|
__asm__ __volatile__ (
|
|
"push %1\n"
|
|
"push %2\n"
|
|
"push %3\n"
|
|
"push %4\n"
|
|
"push %5\n"
|
|
"call *%6\n"
|
|
"pop %%ebx\n"
|
|
"pop %%ebx\n"
|
|
"pop %%ebx\n"
|
|
"pop %%ebx\n"
|
|
"pop %%ebx\n"
|
|
: "=a" (ret) : "r" (r->edi), "r" (r->esi), "r" (r->edx), "r" (r->ecx), "r" (r->ebx), "r" (location));
|
|
r->eax = ret;
|
|
}
|