--- /dev/null
+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
+