twizzler_abi/arch/x86_64/
syscall.rs

1use crate::syscall::Syscall;
2
3#[allow(dead_code)]
4/// Call into the kernel to perform a synchronous system call. The args array can be at most 6 long,
5/// and the meaning of the args depends on the system call.
6/// The kernel can return two 64-bit values, whose meaning depends on the system call.
7///
8/// You probably don't want to call this function directly, and you should instead use the wrappers
9/// in [crate::syscall].
10///
11/// # Safety
12/// The caller must ensure that the args have the correct meaning for the syscall in question, and
13/// to handle the return values correctly. Additionally, calling the kernel can invoke any kind of
14/// weirdness if you do something wrong.
15pub unsafe fn raw_syscall(call: Syscall, args: &[u64]) -> (u64, u64) {
16    if core::intrinsics::unlikely(args.len() > 6) {
17        crate::print_err("too many arguments to raw_syscall");
18        crate::internal_abort();
19    }
20    let a0 = *args.first().unwrap_or(&0u64);
21    let a1 = *args.get(1).unwrap_or(&0u64);
22    let mut a2 = *args.get(2).unwrap_or(&0u64);
23    let a3 = *args.get(3).unwrap_or(&0u64);
24    let a4 = *args.get(4).unwrap_or(&0u64);
25    let a5 = *args.get(5).unwrap_or(&0u64);
26
27    let mut num = call.num();
28    core::arch::asm!("syscall", inout("rax") num, in("rdi") a0, in("rsi") a1, inout("rdx") a2, in("r10") a3, in("r9") a4, in("r8") a5, lateout("rcx") _, lateout("r11") _, clobber_abi("system"));
29    (num, a2)
30}