diff --git a/hermit/arch/x86/kernel/entry.asm b/hermit/arch/x86/kernel/entry.asm index fc5e50681..f03e0a152 100644 --- a/hermit/arch/x86/kernel/entry.asm +++ b/hermit/arch/x86/kernel/entry.asm @@ -545,23 +545,28 @@ isrsyscall: push rdi push rsi + ; push system call number + push rax + ; get kernel stack call get_kernel_stack ; restore registers - mov r8, [rsp+56] - mov r9, [rsp+48] - mov r10, [rsp+40] - mov r11, [rsp+32] - mov rdx, [rsp+24] + mov r8, [rsp+64] + mov r9, [rsp+56] + mov r10, [rsp+48] + mov r11, [rsp+40] + mov rdx, [rsp+32] ; see below - ; mov rcx, [rsp+16] - mov rdi, [rsp+8] - mov rsi, [rsp+0] + ; mov rcx, [rsp+24] + mov rdi, [rsp+16] + mov rsi, [rsp+8] xchg rsp, rax ; => rax contains pointer to the kernel stack + push rax ; store user-level stack pointer - push rax ; contains original rsp + ; restore system call number + mov rax, [rax+0] ; syscall stores in rcx the return address ; => using of r10 for the temporary storage of the 4th argument @@ -569,14 +574,16 @@ isrsyscall: ; during a system call, HermitCore allows interrupts sti - call syscall_handler + extern syscall_table + call [rax*8+syscall_table] cli - ; restore user-level stack + ; restore user-level stack pointer pop r10 mov rsp, r10 ; restore registers + add rsp, 8 ; ignore old value of rax pop rsi pop rdi pop rcx diff --git a/hermit/include/hermit/syscall.h b/hermit/include/hermit/syscall.h index 1883de984..eb40abd27 100644 --- a/hermit/include/hermit/syscall.h +++ b/hermit/include/hermit/syscall.h @@ -47,33 +47,33 @@ extern "C" { #define __NR_open 2 #define __NR_close 3 #define __NR_read 4 -#define __NR_lseek 6 -#define __NR_unlink 7 -#define __NR_getpid 8 -#define __NR_kill 9 -#define __NR_fstat 10 -#define __NR_sbrk 11 -#define __NR_fork 12 -#define __NR_wait 13 -#define __NR_execve 14 -#define __NR_times 15 -#define __NR_accept 16 -#define __NR_bind 17 -#define __NR_closesocket 18 -#define __NR_connect 19 -#define __NR_listen 20 -#define __NR_recv 21 -#define __NR_send 22 -#define __NR_socket 23 -#define __NR_getsockopt 24 -#define __NR_setsockopt 25 -#define __NR_gethostbyname 26 -#define __NR_sendto 27 -#define __NR_recvfrom 28 -#define __NR_select 29 -#define __NR_stat 30 -#define __NR_dup 31 -#define __NR_dup2 32 +#define __NR_lseek 5 +#define __NR_unlink 6 +#define __NR_getpid 7 +#define __NR_kill 8 +#define __NR_fstat 9 +#define __NR_sbrk 10 +#define __NR_fork 11 +#define __NR_wait 12 +#define __NR_execve 13 +#define __NR_times 14 +#define __NR_accept 15 +#define __NR_bind 16 +#define __NR_closesocket 17 +#define __NR_connect 18 +#define __NR_listen 19 +#define __NR_recv 20 +#define __NR_send 21 +#define __NR_socket 22 +#define __NR_getsockopt 23 +#define __NR_setsockopt 24 +#define __NR_gethostbyname 25 +#define __NR_sendto 26 +#define __NR_recvfrom 27 +#define __NR_select 28 +#define __NR_stat 29 +#define __NR_dup 30 +#define __NR_dup2 31 #ifdef __cplusplus } diff --git a/hermit/kernel/syscall.c b/hermit/kernel/syscall.c index 32355700c..eae55cdcc 100644 --- a/hermit/kernel/syscall.c +++ b/hermit/kernel/syscall.c @@ -73,46 +73,55 @@ static ssize_t sys_sbrk(int incr) return ret; } -ssize_t syscall_handler(uint32_t sys_nr, ...) +static int sys_open(const char* name, int flags, int mode) { - ssize_t ret = -EINVAL; - va_list vl; - - check_workqueues(); - - va_start(vl, sys_nr); - - switch(sys_nr) - { - case __NR_exit: - sys_exit(va_arg(vl, uint32_t)); - ret = 0; - break; - case __NR_write: { - int fd = va_arg(vl, int); - const char* buf = va_arg(vl, const char*); - size_t len = va_arg(vl, size_t); - ret = sys_write(fd, buf, len); - break; - } - //TODO: Currently, we ignore file descriptors - case __NR_open: - case __NR_close: - ret = 0; - break; - case __NR_sbrk: { - int incr = va_arg(vl, int); - - ret = sys_sbrk(incr); - break; - } - default: - kprintf("invalid system call: 0x%lx\n", sys_nr); - ret = -ENOSYS; - break; - }; - - va_end(vl); - - return ret; + return 0; } + +static int sys_close(int fd) +{ + return 0; +} + +static int default_handler(void) +{ + kprintf("Invalid system call\n"); + + return -ENOSYS; +} + +size_t syscall_table[] = { + (size_t) sys_exit, /* __NR_exit */ + (size_t) sys_write, /* __NR_write */ + (size_t) sys_open, /* __NR_open */ + (size_t) sys_close, /* __NR_close */ + (size_t) default_handler, /* __NR_read */ + (size_t) default_handler, /* __NR_lseek */ + (size_t) default_handler, /* __NR_unlink */ + (size_t) default_handler, /* __NR_getpid */ + (size_t) default_handler, /* __NR_kill */ + (size_t) default_handler, /* __NR_fstat */ + (size_t) sys_sbrk, /* __NR_sbrk */ + (size_t) default_handler, /* __NR_fork */ + (size_t) default_handler, /* __NR_wait */ + (size_t) default_handler, /* __NR_execve */ + (size_t) default_handler, /* __NR_times */ + (size_t) default_handler, /* __NR_accept */ + (size_t) default_handler, /* __NR_bind */ + (size_t) default_handler, /* __NR_closesocket */ + (size_t) default_handler, /* __NR_connect */ + (size_t) default_handler, /* __NR_listen */ + (size_t) default_handler, /* __NR_recv */ + (size_t) default_handler, /* __NR_send */ + (size_t) default_handler, /* __NR_socket */ + (size_t) default_handler, /* __NR_getsockopt */ + (size_t) default_handler, /* __NR_setsockopt */ + (size_t) default_handler, /* __NR_gethostbyname */ + (size_t) default_handler, /* __NR_sendto */ + (size_t) default_handler, /* __NR_recvfrom */ + (size_t) default_handler, /* __NR_select */ + (size_t) default_handler, /* __NR_stat */ + (size_t) default_handler, /* __NR_dup */ + (size_t) default_handler, /* __NR_dup2 */ + +};