global syscall_entry:function global ksyscall:function extern printk extern allstop extern need_schedule ; syscall to kernel ; syscall number in rax ; fourth argument (rcx) on stack? ksyscall: ; syscall over-writes rcx, save it push rcx syscall pop rcx ret %define STAR 0xC0000081 %define LSTAR 0xC0000082 %define FMASK 0xC0000084 extern enable_syscall global init_syscalls:function init_syscalls: ; STAR register mov ecx, STAR rdmsr mov edx, 0x23 ; user code segment / user data segment / 64 bit user code segment shr edx, 16 or edx, 0x10 ; kernel code segment wrmsr ; syscall rip mov rax, qword syscall_entry mov rdx, qword syscall_entry shr rdx, 32 mov ecx, LSTAR wrmsr ; rflags mask mov ecx, FMASK rdmsr mov eax, ~0x202 wrmsr ; turn on the enable bit (bit 1 of EFER, iirc) call enable_syscall ret ; still using user stack and memory map ; can't use user's stack because user may lie about where it is ; causing us to overwrite memory. extern sleep extern timer_ticks syscall_entry: mov dr0, rcx mov dr1, rax mov dr2, rdi ; TODO switch to kernel stack ; save values for sysret push r11 push rcx mov r10, rcx ; fourth arg in r10, since syscall clobbers rcx push rax push rdi push rsi mov r8, rdi mov r9, rsi mov rdi, qword sleepstr mov rdx, qword timer_ticks mov rsi, [rdx] mov edx, 0 mov ecx, eax call printk pop rsi pop rdi pop rax call sleep ; syscall number in rax ; rcx would be the fourth argument, but over-written by syscall ; so we pass it in r10, another scratch register ; may not need to check for schedule, the syscall itself ; should do a yield if it wants to ; need to check for schedule, could possible just do ; an interrupt if it needed scheduling call need_schedule mov dr1, rax ;call allstop test eax,eax jz .nosched mov eax, 0x1123f982 mov dr0, rax call allstop int 0x81 ; force a schedule call, any int would do actually .nosched: mov eax, __LINE__ mov dr3, rax mov dr2, r11 mov dr1, rcx ;call allstop pop rcx pop r11 db 0x48 ; no sysretq in yasm sysret ign: db 'ignoring syscall %u', 0xa, 0 sleepstr: db '%u pid %u syscall %u : %u %u', 0xa, 0