syscall/arch/
aarch64.rs

1use core::{
2    mem,
3    ops::{Deref, DerefMut},
4    slice,
5};
6
7use super::error::{Error, Result};
8
9pub const PAGE_SIZE: usize = 4096;
10/// Size of the metadata region used to transfer information from the kernel to the bootstrapper.
11pub const KERNEL_METADATA_SIZE: usize = 4 * PAGE_SIZE;
12
13#[cfg(feature = "userspace")]
14macro_rules! syscall {
15    ($($name:ident($a:ident, $($b:ident, $($c:ident, $($d:ident, $($e:ident, $($f:ident, $($g:ident, )?)?)?)?)?)?);)+) => {
16        $(
17            pub unsafe fn $name($a: usize, $($b: usize, $($c: usize, $($d: usize, $($e: usize, $($f: usize, $($g: usize)?)?)?)?)?)?) -> Result<usize> {
18                let ret: usize;
19
20                core::arch::asm!(
21                    "svc 0",
22                    in("x8") $a,
23                    $(
24                        in("x0") $b,
25                        $(
26                            in("x1") $c,
27                            $(
28                                in("x2") $d,
29                                $(
30                                    in("x3") $e,
31                                    $(
32                                        in("x4") $f,
33                                        $(
34                                            in("x5") $g,
35                                        )?
36                                    )?
37                                )?
38                            )?
39                        )?
40                    )?
41                    lateout("x0") ret,
42                    options(nostack),
43                );
44
45                Error::demux(ret)
46            }
47        )+
48    };
49}
50
51#[cfg(feature = "userspace")]
52syscall! {
53    syscall0(a,);
54    syscall1(a, b,);
55    syscall2(a, b, c,);
56    syscall3(a, b, c, d,);
57    syscall4(a, b, c, d, e,);
58    syscall5(a, b, c, d, e, f,);
59    syscall6(a, b, c, d, e, f, g,);
60}
61
62#[derive(Copy, Clone, Debug, Default)]
63#[repr(C)]
64pub struct IntRegisters {
65    pub x30: usize,
66    pub x29: usize,
67    pub x28: usize,
68    pub x27: usize,
69    pub x26: usize,
70    pub x25: usize,
71    pub x24: usize,
72    pub x23: usize,
73    pub x22: usize,
74    pub x21: usize,
75    pub x20: usize,
76    pub x19: usize,
77    pub x18: usize,
78    pub x17: usize,
79    pub x16: usize,
80    pub x15: usize,
81    pub x14: usize,
82    pub x13: usize,
83    pub x12: usize,
84    pub x11: usize,
85    pub x10: usize,
86    pub x9: usize,
87    pub x8: usize,
88    pub x7: usize,
89    pub x6: usize,
90    pub x5: usize,
91    pub x4: usize,
92    pub x3: usize,
93    pub x2: usize,
94    pub x1: usize,
95    pub x0: usize,
96}
97
98impl Deref for IntRegisters {
99    type Target = [u8];
100    fn deref(&self) -> &[u8] {
101        unsafe {
102            slice::from_raw_parts(
103                self as *const IntRegisters as *const u8,
104                mem::size_of::<IntRegisters>(),
105            )
106        }
107    }
108}
109
110impl DerefMut for IntRegisters {
111    fn deref_mut(&mut self) -> &mut [u8] {
112        unsafe {
113            slice::from_raw_parts_mut(
114                self as *mut IntRegisters as *mut u8,
115                mem::size_of::<IntRegisters>(),
116            )
117        }
118    }
119}
120
121#[derive(Clone, Copy, Debug, Default)]
122#[repr(C, packed)]
123pub struct FloatRegisters {
124    pub fp_simd_regs: [u128; 32],
125    pub fpsr: u32,
126    pub fpcr: u32,
127}
128
129impl Deref for FloatRegisters {
130    type Target = [u8];
131    fn deref(&self) -> &[u8] {
132        unsafe {
133            slice::from_raw_parts(
134                self as *const FloatRegisters as *const u8,
135                mem::size_of::<FloatRegisters>(),
136            )
137        }
138    }
139}
140
141impl DerefMut for FloatRegisters {
142    fn deref_mut(&mut self) -> &mut [u8] {
143        unsafe {
144            slice::from_raw_parts_mut(
145                self as *mut FloatRegisters as *mut u8,
146                mem::size_of::<FloatRegisters>(),
147            )
148        }
149    }
150}
151
152#[derive(Clone, Copy, Debug, Default)]
153#[repr(C, packed)]
154pub struct EnvRegisters {
155    pub tpidr_el0: usize,
156    pub tpidrro_el0: usize,
157}
158impl Deref for EnvRegisters {
159    type Target = [u8];
160    fn deref(&self) -> &[u8] {
161        unsafe {
162            slice::from_raw_parts(
163                self as *const EnvRegisters as *const u8,
164                mem::size_of::<EnvRegisters>(),
165            )
166        }
167    }
168}
169
170impl DerefMut for EnvRegisters {
171    fn deref_mut(&mut self) -> &mut [u8] {
172        unsafe {
173            slice::from_raw_parts_mut(
174                self as *mut EnvRegisters as *mut u8,
175                mem::size_of::<EnvRegisters>(),
176            )
177        }
178    }
179}
180#[derive(Clone, Copy, Debug, Default)]
181#[repr(C, packed)]
182pub struct Exception {
183    pub kind: usize,
184    // TODO
185}
186impl Deref for Exception {
187    type Target = [u8];
188    fn deref(&self) -> &[u8] {
189        unsafe {
190            slice::from_raw_parts(
191                self as *const Exception as *const u8,
192                mem::size_of::<Exception>(),
193            )
194        }
195    }
196}
197
198impl DerefMut for Exception {
199    fn deref_mut(&mut self) -> &mut [u8] {
200        unsafe {
201            slice::from_raw_parts_mut(
202                self as *mut Exception as *mut u8,
203                mem::size_of::<Exception>(),
204            )
205        }
206    }
207}