acadia/zion/syscall/syscall_enter.s

59 lines
1.2 KiB
ArmAsm

.global syscall_enter
syscall_enter:
# Technically don't need to save all of these as
# the SYS V ABI will preserve some of them by
# default but I doubt that this costs us much.
push %rbx
push %rcx # Special! This is the return address
push %rdx
push %rsi
push %rdi
push %r8
push %r9
push %r10
push %r11
push %r12
push %r13
push %r14
push %r15
call GetKernelRsp
# RAX holds the kernel RSP now.
mov %rsp, %rbx
mov %rax, %rsp
push %rbx
# Now that we are on the kernel stack we can re-enable interrupts.
sti
# Restore caller registers using the userspace rsp in rbx
mov 0x40(%rbx), %rdi
mov 0x48(%rbx), %rsi
# Don't push the rbp and rsp as the callee will do so.
call SyscallHandler
# Clear interrupts since we are moving back to the user stack here.
# The sysret call will re-enable them for us.
cli
# Pop the userspace rsp off the stack
pop %rsp
pop %r15
pop %r14
pop %r13
pop %r12
pop %r11 # Contains rflags.
pop %r10
pop %r9
pop %r8
pop %rdi
pop %rsi
pop %rdx
pop %rcx # Contains return address.
pop %rbx
# Because we haven't touched rax since calling syscall_handler it should still have the return value.
sysretq