linux_unsafe/raw/
arm.rs

1//! Thin wrappers around the CPU instructions for making system calls on ARM.
2
3use core::arch::asm;
4
5/// The type of all system call arguments and return values on this platform.
6pub type V = u32;
7
8/// Call into a system function with one argument.
9#[inline(always)]
10pub unsafe fn syscall0(n: V) -> V {
11    let ret: V;
12    asm!(
13        "svc 0",
14        in("r7") n,
15        out("r0") ret,
16    );
17    ret
18}
19
20/// Call into a system function with one argument.
21#[inline(always)]
22pub unsafe fn syscall1(n: V, a0: V) -> V {
23    let ret: V;
24    asm!(
25        "svc 0",
26        in("r7") n,
27        inout("r0") a0 => ret,
28    );
29    ret
30}
31
32/// Call into a system function with two arguments.
33#[inline(always)]
34pub unsafe fn syscall2(n: V, a0: V, a1: V) -> V {
35    let ret: V;
36    asm!(
37        "svc 0",
38        in("r7") n,
39        inout("r0") a0 => ret,
40        in("r1") a1,
41    );
42    ret
43}
44
45/// Call into a system function with three arguments.
46#[inline(always)]
47pub unsafe fn syscall3(n: V, a0: V, a1: V, a2: V) -> V {
48    let ret: V;
49    asm!(
50        "svc 0",
51        in("r7") n,
52        inout("r0") a0 => ret,
53        in("r1") a1,
54        in("r2") a2,
55    );
56    ret
57}
58
59/// Call into a system function with four arguments.
60#[inline(always)]
61pub unsafe fn syscall4(n: V, a0: V, a1: V, a2: V, a3: V) -> V {
62    let ret: V;
63    asm!(
64        "svc 0",
65        in("r7") n,
66        inout("r0") a0 => ret,
67        in("r1") a1,
68        in("r2") a2,
69        in("r3") a3,
70    );
71    ret
72}
73
74/// Call into a system function with five arguments.
75#[inline(always)]
76pub unsafe fn syscall5(n: V, a0: V, a1: V, a2: V, a3: V, a4: V) -> V {
77    let ret: V;
78    asm!(
79        "svc 0",
80        in("r7") n,
81        inout("r0") a0 => ret,
82        in("r1") a1,
83        in("r2") a2,
84        in("r3") a3,
85        in("r4") a4,
86    );
87    ret
88}
89
90/// Call into a system function with six arguments.
91#[inline(always)]
92pub unsafe fn syscall6(n: V, a0: V, a1: V, a2: V, a3: V, a4: V, a5: V) -> V {
93    let ret: V;
94    asm!(
95        "svc 0",
96        in("r7") n,
97        inout("r0") a0 => ret,
98        in("r1") a1,
99        in("r2") a2,
100        in("r3") a3,
101        in("r4") a4,
102        in("r5") a5,
103    );
104    ret
105}
106
107/// Given a result value from a system call that follows the standard error
108/// return convention for this platform, returns either the given value
109/// verbatim or the kernel error code extracted from it.
110///
111/// For ARM, the standard way to signal an error is to return a result
112/// between -4095 and -1 inclusive, with all other values representing
113/// successful results.
114///
115/// A small number of system calls signal errors in different ways. This
116/// function is not compatible with the results from those calls.
117#[inline]
118pub fn unpack_standard_result(raw: V) -> Result<V, i32> {
119    if (raw as u64) >= ((-4095 as i64) as u64) {
120        let err = -(raw as i32);
121        Err(err)
122    } else {
123        Ok(raw)
124    }
125}
126
127include!(concat!(env!("OUT_DIR"), "/syscall_nrs_arm.rs"));
128pub(crate) mod errno {
129    include!(concat!(env!("OUT_DIR"), "/errnos_arm.rs"));
130}
131
132// Architecture-specific types and constants
133pub(crate) mod types {}