1use crate::Sysno;
2
3use core::sync::atomic::{AtomicBool, Ordering};
4
5static mut HAS_SCV: AtomicBool = AtomicBool::new(false);
6
7macro_rules! sys {
8 ($($tt:tt)+) => {
9 if HAS_SCV.load(Ordering::SeqCst) {
10 ::core::arch::asm!(
12 ".byte 0x44",
13 ".byte 0x00",
14 ".byte 0x00",
15 ".byte 0x01",
16 $($tt)+
17 );
18 } else {
19 ::core::arch::asm!(
20 "sc",
21 "bns 0f",
22 "neg 3, 3",
23 "0:",
24 $($tt)+
25 );
26 }
27 };
28}
29
30#[allow(clippy::missing_safety_doc)]
31#[inline(always)]
32pub unsafe fn raw_syscall0(sysno: Sysno) -> usize {
33 let ret;
34 sys!(
35 inlateout("r0") sysno as usize => _,
36 lateout("r3") ret,
37 lateout("r4") _,
38 lateout("r5") _,
39 lateout("r6") _,
40 lateout("r7") _,
41 lateout("r8") _,
42 lateout("r9") _,
43 lateout("r10") _,
44 lateout("r11") _,
45 lateout("r12") _,
46 lateout("cr0") _,
47 options(nostack, preserves_flags, readonly)
48
49 );
50 ret
51}
52
53pub use raw_syscall0 as raw_syscall0_readonly;
54
55#[allow(clippy::missing_safety_doc)]
56#[inline(always)]
57pub unsafe fn raw_syscall1(sysno: Sysno, arg0: usize) -> usize {
58 let ret;
59 sys!(
60 inlateout("r0") sysno as usize => _,
61 inlateout("r3") arg0 => ret,
62 lateout("r4") _,
63 lateout("r5") _,
64 lateout("r6") _,
65 lateout("r7") _,
66 lateout("r8") _,
67 lateout("r9") _,
68 lateout("r10") _,
69 lateout("r11") _,
70 lateout("r12") _,
71 lateout("cr0") _,
72 options(nostack, preserves_flags)
73 );
74 ret
75}
76
77#[allow(clippy::missing_safety_doc)]
78#[inline(always)]
79pub unsafe fn raw_syscall1_readonly(sysno: Sysno, arg0: usize) -> usize {
80 let ret;
81 sys!(
82 inlateout("r0") sysno as usize => _,
83 inlateout("r3") arg0 => ret,
84 lateout("r4") _,
85 lateout("r5") _,
86 lateout("r6") _,
87 lateout("r7") _,
88 lateout("r8") _,
89 lateout("r9") _,
90 lateout("r10") _,
91 lateout("r11") _,
92 lateout("r12") _,
93 lateout("cr0") _,
94 options(nostack, preserves_flags, readonly)
95 );
96 ret
97}
98
99#[allow(clippy::missing_safety_doc)]
100#[inline(always)]
101pub unsafe fn syscall1_noreturn(sysno: Sysno, arg0: usize) -> ! {
102 ::core::arch::asm!(
103 "sc",
104 "trap",
105 in("r0") sysno as usize,
106 in("r3") arg0,
107 options(noreturn)
108 );
109}
110
111#[allow(clippy::missing_safety_doc)]
112#[inline(always)]
113pub unsafe fn raw_syscall2(sysno: Sysno, arg0: usize, arg1: usize) -> usize {
114 let ret;
115 sys!(
116 inlateout("r0") sysno as usize => _,
117 inlateout("r3") arg0 => ret,
118 inlateout("r4") arg1 => _,
119 lateout("r5") _,
120 lateout("r6") _,
121 lateout("r7") _,
122 lateout("r8") _,
123 lateout("r9") _,
124 lateout("r10") _,
125 lateout("r11") _,
126 lateout("r12") _,
127 lateout("cr0") _,
128 options(nostack, preserves_flags)
129 );
130 ret
131}
132
133#[allow(clippy::missing_safety_doc)]
134#[inline(always)]
135pub unsafe fn raw_syscall2_readonly(sysno: Sysno, arg0: usize, arg1: usize) -> usize {
136 let ret;
137 sys!(
138 inlateout("r0") sysno as usize => _,
139 inlateout("r3") arg0 => ret,
140 inlateout("r4") arg1 => _,
141 lateout("r5") _,
142 lateout("r6") _,
143 lateout("r7") _,
144 lateout("r8") _,
145 lateout("r9") _,
146 lateout("r10") _,
147 lateout("r11") _,
148 lateout("r12") _,
149 lateout("cr0") _,
150 options(nostack, preserves_flags, readonly)
151 );
152 ret
153}
154
155#[allow(clippy::missing_safety_doc)]
156#[inline(always)]
157pub unsafe fn raw_syscall3(sysno: Sysno, arg0: usize, arg1: usize, arg2: usize) -> usize {
158 let ret;
159 sys!(
160 inlateout("r0") sysno as usize => _,
161 inlateout("r3") arg0 => ret,
162 inlateout("r4") arg1 => _,
163 inlateout("r5") arg2 => _,
164 lateout("r6") _,
165 lateout("r7") _,
166 lateout("r8") _,
167 lateout("r9") _,
168 lateout("r10") _,
169 lateout("r11") _,
170 lateout("r12") _,
171 lateout("cr0") _,
172 options(nostack, preserves_flags)
173 );
174 ret
175}
176
177#[allow(clippy::missing_safety_doc)]
178#[inline(always)]
179pub unsafe fn raw_syscall3_readonly(sysno: Sysno, arg0: usize, arg1: usize, arg2: usize) -> usize {
180 let ret;
181 sys!(
182 inlateout("r0") sysno as usize => _,
183 inlateout("r3") arg0 => ret,
184 inlateout("r4") arg1 => _,
185 inlateout("r5") arg2 => _,
186 lateout("r6") _,
187 lateout("r7") _,
188 lateout("r8") _,
189 lateout("r9") _,
190 lateout("r10") _,
191 lateout("r11") _,
192 lateout("r12") _,
193 lateout("cr0") _,
194 options(nostack, preserves_flags, readonly)
195 );
196 ret
197}
198
199#[allow(clippy::missing_safety_doc)]
200#[inline(always)]
201pub unsafe fn raw_syscall4(
202 sysno: Sysno,
203 arg0: usize,
204 arg1: usize,
205 arg2: usize,
206 arg3: usize,
207) -> usize {
208 let ret;
209 sys!(
210 inlateout("r0") sysno as usize => _,
211 inlateout("r3") arg0 => ret,
212 inlateout("r4") arg1 => _,
213 inlateout("r5") arg2 => _,
214 inlateout("r6") arg3 => _,
215 lateout("r7") _,
216 lateout("r8") _,
217 lateout("r9") _,
218 lateout("r10") _,
219 lateout("r11") _,
220 lateout("r12") _,
221 lateout("cr0") _,
222 options(nostack, preserves_flags)
223 );
224 ret
225}
226
227#[allow(clippy::missing_safety_doc)]
228#[inline(always)]
229pub unsafe fn raw_syscall4_readonly(
230 sysno: Sysno,
231 arg0: usize,
232 arg1: usize,
233 arg2: usize,
234 arg3: usize,
235) -> usize {
236 let ret;
237 sys!(
238 inlateout("r0") sysno as usize => _,
239 inlateout("r3") arg0 => ret,
240 inlateout("r4") arg1 => _,
241 inlateout("r5") arg2 => _,
242 inlateout("r6") arg3 => _,
243 lateout("r7") _,
244 lateout("r8") _,
245 lateout("r9") _,
246 lateout("r10") _,
247 lateout("r11") _,
248 lateout("r12") _,
249 lateout("cr0") _,
250 options(nostack, preserves_flags, readonly)
251 );
252 ret
253}
254
255#[allow(clippy::missing_safety_doc)]
256#[inline(always)]
257pub unsafe fn raw_syscall5(
258 sysno: Sysno,
259 arg0: usize,
260 arg1: usize,
261 arg2: usize,
262 arg3: usize,
263 arg4: usize,
264) -> usize {
265 let ret;
266 sys!(
267 inlateout("r0") sysno as usize => _,
268 inlateout("r3") arg0 => ret,
269 inlateout("r4") arg1 => _,
270 inlateout("r5") arg2 => _,
271 inlateout("r6") arg3 => _,
272 inlateout("r7") arg4 => _,
273 lateout("r8") _,
274 lateout("r9") _,
275 lateout("r10") _,
276 lateout("r11") _,
277 lateout("r12") _,
278 lateout("cr0") _,
279 options(nostack, preserves_flags)
280 );
281 ret
282}
283
284#[allow(clippy::missing_safety_doc)]
285#[inline(always)]
286pub unsafe fn raw_syscall5_readonly(
287 sysno: Sysno,
288 arg0: usize,
289 arg1: usize,
290 arg2: usize,
291 arg3: usize,
292 arg4: usize,
293) -> usize {
294 let ret;
295 sys!(
296 inlateout("r0") sysno as usize => _,
297 inlateout("r3") arg0 => ret,
298 inlateout("r4") arg1 => _,
299 inlateout("r5") arg2 => _,
300 inlateout("r6") arg3 => _,
301 inlateout("r7") arg4 => _,
302 lateout("r8") _,
303 lateout("r9") _,
304 lateout("r10") _,
305 lateout("r11") _,
306 lateout("r12") _,
307 lateout("cr0") _,
308 options(nostack, preserves_flags, readonly)
309 );
310 ret
311}
312
313#[allow(clippy::missing_safety_doc)]
314#[inline(always)]
315pub unsafe fn raw_syscall6(
316 sysno: Sysno,
317 arg0: usize,
318 arg1: usize,
319 arg2: usize,
320 arg3: usize,
321 arg4: usize,
322 arg5: usize,
323) -> usize {
324 let ret;
325 sys!(
326 inlateout("r0") sysno as usize => _,
327 inlateout("r3") arg0 => ret,
328 inlateout("r4") arg1 => _,
329 inlateout("r5") arg2 => _,
330 inlateout("r6") arg3 => _,
331 inlateout("r7") arg4 => _,
332 inlateout("r8") arg5 => _,
333 lateout("r9") _,
334 lateout("r10") _,
335 lateout("r11") _,
336 lateout("r12") _,
337 lateout("cr0") _,
338 options(nostack, preserves_flags)
339 );
340 ret
341}
342
343#[allow(clippy::missing_safety_doc)]
344#[inline(always)]
345pub unsafe fn raw_syscall6_readonly(
346 sysno: Sysno,
347 arg0: usize,
348 arg1: usize,
349 arg2: usize,
350 arg3: usize,
351 arg4: usize,
352 arg5: usize,
353) -> usize {
354 let ret;
355 sys!(
356 inlateout("r0") sysno as usize => _,
357 inlateout("r3") arg0 => ret,
358 inlateout("r4") arg1 => _,
359 inlateout("r5") arg2 => _,
360 inlateout("r6") arg3 => _,
361 inlateout("r7") arg4 => _,
362 inlateout("r8") arg5 => _,
363 lateout("r9") _,
364 lateout("r10") _,
365 lateout("r11") _,
366 lateout("r12") _,
367 lateout("cr0") _,
368 options(nostack, preserves_flags, readonly)
369 );
370 ret
371}
372
373include!("_syscalls.rs");
374
375pub(crate) unsafe fn init() {
376 if crate::env::aux::get::<crate::env::aux::HardwareCapabilities2>().map_or(false, |flags| {
377 flags.contains(crate::env::aux::Features2::SCV)
378 }) {
379 HAS_SCV.store(true, Ordering::SeqCst);
380 }
381}
382
383pub fn has_scv() -> bool {
384 unsafe { HAS_SCV.load(Ordering::SeqCst) }
385}