linux_syscall/arch/arm/
syscall_asm.rs

1// Copyright (c) 2022 John Millikin <john@john-millikin.com>
2//
3// Permission to use, copy, modify, and/or distribute this software for any
4// purpose with or without fee is hereby granted.
5//
6// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
7// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
8// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
9// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
10// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
11// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
12// PERFORMANCE OF THIS SOFTWARE.
13//
14// SPDX-License-Identifier: 0BSD
15
16/// Linux syscall result for the `arm` architecture.
17#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
18#[must_use]
19pub struct Result(u32);
20
21impl Result {
22	#[inline]
23	pub const fn new(register_r0: u32) -> Self {
24		Self(register_r0)
25	}
26
27	#[inline]
28	pub const fn as_u32_unchecked(self) -> u32 {
29		self.0
30	}
31
32	#[inline]
33	pub const fn as_usize_unchecked(self) -> usize {
34		self.0 as usize
35	}
36}
37
38single_register_result32!(Result);
39
40#[cfg(not(doc))]
41#[macro_export]
42macro_rules! syscall {
43	($nr:expr $(,)?) => {{
44		let mut out_r0;
45		core::arch::asm!(
46			"svc #0",
47			in("r7") u32::from(Into::<$crate::Syscall>::into($nr)),
48			lateout("r0") out_r0,
49			options(nostack),
50		);
51		$crate::arch::arm::Result::new(out_r0)
52	}};
53	($nr:expr, $a1:expr $(,)?) => {{
54		let mut out_r0;
55		core::arch::asm!(
56			"svc #0",
57			in("r7") u32::from(Into::<$crate::Syscall>::into($nr)),
58			in("r0") $a1,
59			lateout("r0") out_r0,
60			options(nostack),
61		);
62		$crate::arch::arm::Result::new(out_r0)
63	}};
64	($nr:expr, $a1:expr, $a2:expr $(,)?) => {{
65		let mut out_r0;
66		core::arch::asm!(
67			"svc #0",
68			in("r7") u32::from(Into::<$crate::Syscall>::into($nr)),
69			in("r0") $a1,
70			in("r1") $a2,
71			lateout("r0") out_r0,
72			options(nostack),
73		);
74		$crate::arch::arm::Result::new(out_r0)
75	}};
76	($nr:expr, $a1:expr, $a2:expr, $a3:expr $(,)?) => {{
77		let mut out_r0;
78		core::arch::asm!(
79			"svc #0",
80			in("r7") u32::from(Into::<$crate::Syscall>::into($nr)),
81			in("r0") $a1,
82			in("r1") $a2,
83			in("r2") $a3,
84			lateout("r0") out_r0,
85			options(nostack),
86		);
87		$crate::arch::arm::Result::new(out_r0)
88	}};
89	($nr:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr $(,)?) => {{
90		let mut out_r0;
91		core::arch::asm!(
92			"svc #0",
93			in("r7") u32::from(Into::<$crate::Syscall>::into($nr)),
94			in("r0") $a1,
95			in("r1") $a2,
96			in("r2") $a3,
97			in("r3") $a4,
98			lateout("r0") out_r0,
99			options(nostack),
100		);
101		$crate::arch::arm::Result::new(out_r0)
102	}};
103	($nr:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr $(,)?) => {{
104		let mut out_r0;
105		core::arch::asm!(
106			"svc #0",
107			in("r7") u32::from(Into::<$crate::Syscall>::into($nr)),
108			in("r0") $a1,
109			in("r1") $a2,
110			in("r2") $a3,
111			in("r3") $a4,
112			in("r4") $a5,
113			lateout("r0") out_r0,
114			options(nostack),
115		);
116		$crate::arch::arm::Result::new(out_r0)
117	}};
118	($nr:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr, $a6:expr $(,)?) => {{
119		let mut out_r0;
120		core::arch::asm!(
121			"svc #0",
122			in("r7") u32::from(Into::<$crate::Syscall>::into($nr)),
123			in("r0") $a1,
124			in("r1") $a2,
125			in("r2") $a3,
126			in("r3") $a4,
127			in("r4") $a5,
128			in("r5") $a6,
129			lateout("r0") out_r0,
130			options(nostack),
131		);
132		$crate::arch::arm::Result::new(out_r0)
133	}};
134}