blob: 7b6427c4955e43bb2d9bda30d988493c8f1b5f49 [file] [log] [blame]
use libtock_platform::RawSyscalls;
unsafe impl RawSyscalls for crate::TockSyscalls {
// This yield implementation is currently limited to RISC-V versions without
// floating-point registers, as it does not mark them clobbered.
#[cfg(not(any(target_feature = "d", target_feature = "f")))]
unsafe fn yield1([r0]: [*mut (); 1]) {
// Safety: This matches the invariants required by the documentation on
// RawSyscalls::yield1
unsafe {
asm!("ecall",
// x0 is the zero register.
lateout("x1") _, // Return address
// x2-x4 are stack, global, and thread pointers. sp is
// callee-saved.
lateout("x5") _, // t0
lateout("x6") _, // t1
lateout("x7") _, // t2
// x8 and x9 are s0 and s1 and are callee-saved.
inlateout("x10") r0 => _, // a0
lateout("x11") _, // a1
lateout("x12") _, // a2
lateout("x13") _, // a3
inlateout("x14") 0 => _, // a4
lateout("x15") _, // a5
lateout("x16") _, // a6
lateout("x17") _, // a7
// x18-27 are s2-s11 and are callee-saved
lateout("x28") _, // t3
lateout("x29") _, // t4
lateout("x30") _, // t5
lateout("x31") _, // t6
);
}
}
// This yield implementation is currently limited to RISC-V versions without
// floating-point registers, as it does not mark them clobbered.
#[cfg(not(any(target_feature = "d", target_feature = "f")))]
unsafe fn yield2([r0, r1]: [*mut (); 2]) {
// Safety: This matches the invariants required by the documentation on
// RawSyscalls::yield2
unsafe {
asm!("ecall",
// x0 is the zero register.
lateout("x1") _, // Return address
// x2-x4 are stack, global, and thread pointers. sp is
// callee-saved.
lateout("x5") _, // t0
lateout("x6") _, // t1
lateout("x7") _, // t2
// x8 and x9 are s0 and s1 and are callee-saved.
inlateout("x10") r0 => _, // a0
inlateout("x11") r1 => _, // a1
lateout("x12") _, // a2
lateout("x13") _, // a3
inlateout("x14") 0 => _, // a4
lateout("x15") _, // a5
lateout("x16") _, // a6
lateout("x17") _, // a7
// x18-27 are s2-s11 and are callee-saved
lateout("x28") _, // t3
lateout("x29") _, // t4
lateout("x30") _, // t5
lateout("x31") _, // t6
);
}
}
unsafe fn syscall1<const CLASS: usize>([mut r0]: [*mut (); 1]) -> [*mut (); 2] {
let r1;
// Safety: This matches the invariants required by the documentation on
// RawSyscalls::syscall1
unsafe {
asm!("ecall",
inlateout("a0") r0,
lateout("a1") r1,
in("a4") CLASS,
options(preserves_flags, nostack, nomem),
);
}
[r0, r1]
}
unsafe fn syscall2<const CLASS: usize>([mut r0, mut r1]: [*mut (); 2]) -> [*mut (); 2] {
// Safety: This matches the invariants required by the documentation on
// RawSyscalls::syscall2
unsafe {
asm!("ecall",
inlateout("a0") r0,
inlateout("a1") r1,
in("a4") CLASS,
options(preserves_flags, nostack, nomem)
);
}
[r0, r1]
}
unsafe fn syscall4<const CLASS: usize>(
[mut r0, mut r1, mut r2, mut r3]: [*mut (); 4],
) -> [*mut (); 4] {
// Safety: This matches the invariants required by the documentation on
// RawSyscalls::syscall4
unsafe {
asm!("ecall",
inlateout("a0") r0,
inlateout("a1") r1,
inlateout("a2") r2,
inlateout("a3") r3,
in("a4") CLASS,
options(preserves_flags, nostack),
);
}
[r0, r1, r2, r3]
}
}