diff --git a/kernel-src/arch/x86-64/syscall.asm b/kernel-src/arch/x86-64/syscall.asm new file mode 100644 index 00000000..7940cf00 --- /dev/null +++ b/kernel-src/arch/x86-64/syscall.asm @@ -0,0 +1,109 @@ +section .rodata +syscalltab: + +syscallcount equ 0 +section .text +global arch_syscall_entry +; on entry: +; rcx has the return address +; r11 has the old rflags +; syscall arguments: +; rax has the syscall number +; rdi has the first argument +; rsi has the second argument +; rdx has the third argument +; r10 has the fourth argument +; r8 has the fifth argument +; r9 has the sixth argument +; return: +; rdx has errno +; rax has return value +arch_syscall_entry: + swapgs + ; save return address on user stack + push rcx + mov rcx, [gs:0x0] ; thread pointer + mov rcx, [rcx] ; kernel stack top + xchg rsp, rcx ; switch stack pointers + + ; push context + push qword 0x1b ; user SS + push qword rcx + add qword [rsp], 8 ; correct the old stack pointer to before the return address push + push r11 ; rflags is stored in r11 + push qword 0x23 ; user CS + push qword [rcx] ; save return RIP + push qword 0 ; error + push rbp + push rsi + push rdi + push r15 + push r14 + push r13 + push r12 + push r11 + push r10 + push r9 + push r8 + push rdx + push rcx + push rbx + push rax + mov rbx, ds + push rbx + mov rbx, es + push rbx + mov rbx, fs + push rbx + mov rbx, gs + push rbx + mov rbx, cr2 + push rbx + + ; prepare arguments for the functions + push r9 + mov r9, r8 + mov r8, r10 + mov rcx, rdx + mov rdx, rsi + mov rsi, rdi + mov rdi, rsp + sti + + cmp rax, syscallcount + jae .nosyscall + call [syscalltab + rax * 8] + jmp .return + .nosyscall: + extern syscall_invalid + call syscall_invalid + .return: + cli + ; restore context + add rsp, 32 ; r9 argument, cr2, gs, and fs are not popped. + pop rbx + mov es,rbx + pop rbx + mov ds,rbx + add rsp, 8 ; rax + pop rbx + pop rcx + add rsp, 8 ; rdx + pop r8 + pop r9 + pop r10 + pop r11 + pop r12 + pop r13 + pop r14 + pop r15 + pop rdi + pop rsi + pop rbp + add rsp, 8 ; remove error code + pop rcx + add rsp, 8 ; user CS + pop r11 ; rflags + pop rsp + swapgs + o64 sysret diff --git a/kernel-src/include/kernel/scheduler.h b/kernel-src/include/kernel/scheduler.h index 799e4aaa..234482d5 100644 --- a/kernel-src/include/kernel/scheduler.h +++ b/kernel-src/include/kernel/scheduler.h @@ -14,6 +14,7 @@ struct proc_t; typedef struct thread_t { + void *kernelstacktop; struct thread_t *next; struct thread_t *prev; struct proc_t *proc; @@ -21,7 +22,6 @@ typedef struct thread_t { context_t context; extracontext_t extracontext; void *kernelstack; - void *kernelstacktop; size_t kernelstacksize; vmmcontext_t *vmmctx; tid_t tid; diff --git a/kernel-src/include/kernel/syscalls.h b/kernel-src/include/kernel/syscalls.h new file mode 100644 index 00000000..06030b42 --- /dev/null +++ b/kernel-src/include/kernel/syscalls.h @@ -0,0 +1,11 @@ +#ifndef _SYSCALLS_H +#define _SYSCALLS_H + +#include + +typedef struct { + uint64_t ret; + uint64_t errno; +} syscallret_t; + +#endif diff --git a/kernel-src/sys/syscalls/invalid.c b/kernel-src/sys/syscalls/invalid.c new file mode 100644 index 00000000..1ab56656 --- /dev/null +++ b/kernel-src/sys/syscalls/invalid.c @@ -0,0 +1,10 @@ +#include +#include + +syscallret_t syscall_invalid() { + syscallret_t ret = { + .errno = ENOSYS, + .ret = -1 + }; + return ret; +}