Skip to main content

syscall/arch/
x86_64.rs

1use core::{
2    mem,
3    ops::{Deref, DerefMut},
4    slice,
5};
6
7pub const PAGE_SIZE: usize = 4096;
8/// Size of the metadata region used to transfer information from the kernel to the bootstrapper.
9pub const KERNEL_METADATA_SIZE: usize = 4 * PAGE_SIZE;
10
11#[cfg(feature = "userspace")]
12macro_rules! syscall {
13    ($($name:ident($a:ident, $($b:ident, $($c:ident, $($d:ident, $($e:ident, $($f:ident, $($g:ident, )?)?)?)?)?)?);)+) => {
14        $(
15            pub unsafe fn $name(mut $a: usize, $($b: usize, $($c: usize, $($d: usize, $($e: usize, $($f: usize, $($g: usize)?)?)?)?)?)?) -> crate::error::Result<usize> {
16                core::arch::asm!(
17                    "syscall",
18                    inout("rax") $a,
19                    $(
20                        in("rdi") $b,
21                        $(
22                            in("rsi") $c,
23                            $(
24                                in("rdx") $d,
25                                $(
26                                    in("r10") $e,
27                                    $(
28                                        in("r8") $f,
29                                        $(
30                                            in("r9") $g,
31                                        )?
32                                    )?
33                                )?
34                            )?
35                        )?
36                    )?
37                    out("rcx") _,
38                    out("r11") _,
39                    out("xmm0") _,
40                    out("xmm1") _,
41                    out("xmm2") _,
42                    out("xmm3") _,
43                    out("xmm4") _,
44                    out("xmm5") _,
45                    out("xmm6") _,
46                    out("xmm7") _,
47                    out("xmm8") _,
48                    out("xmm9") _,
49                    out("xmm10") _,
50                    out("xmm11") _,
51                    out("xmm12") _,
52                    out("xmm13") _,
53                    out("xmm14") _,
54                    out("xmm15") _,
55                    options(nostack),
56                );
57
58                crate::error::Error::demux($a)
59            }
60        )+
61    };
62}
63
64#[cfg(feature = "userspace")]
65syscall! {
66    syscall0(a,);
67    syscall1(a, b,);
68    syscall2(a, b, c,);
69    syscall3(a, b, c, d,);
70    syscall4(a, b, c, d, e,);
71    syscall5(a, b, c, d, e, f,);
72    syscall6(a, b, c, d, e, f, g,);
73}
74
75#[derive(Copy, Clone, Debug, Default)]
76#[repr(C)]
77pub struct IntRegisters {
78    pub r15: usize,
79    pub r14: usize,
80    pub r13: usize,
81    pub r12: usize,
82    pub rbp: usize,
83    pub rbx: usize,
84    pub r11: usize,
85    pub r10: usize,
86    pub r9: usize,
87    pub r8: usize,
88    pub rax: usize,
89    pub rcx: usize,
90    pub rdx: usize,
91    pub rsi: usize,
92    pub rdi: usize,
93    pub rip: usize,
94    pub cs: usize,
95    pub rflags: usize,
96    pub rsp: usize,
97    pub ss: usize,
98}
99
100impl Deref for IntRegisters {
101    type Target = [u8];
102    fn deref(&self) -> &[u8] {
103        unsafe { slice::from_raw_parts(self as *const Self as *const u8, mem::size_of::<Self>()) }
104    }
105}
106
107impl DerefMut for IntRegisters {
108    fn deref_mut(&mut self) -> &mut [u8] {
109        unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut u8, mem::size_of::<Self>()) }
110    }
111}
112
113#[derive(Clone, Copy, Debug, Default)]
114#[repr(C, packed)]
115pub struct FloatRegisters {
116    pub fcw: u16,
117    pub fsw: u16,
118    pub ftw: u8,
119    pub _reserved: u8,
120    pub fop: u16,
121    pub fip: u64,
122    pub fdp: u64,
123    pub mxcsr: u32,
124    pub mxcsr_mask: u32,
125    pub st_space: [u128; 8],
126    pub xmm_space: [u128; 16],
127    // TODO: YMM/ZMM
128}
129
130impl Deref for FloatRegisters {
131    type Target = [u8];
132    fn deref(&self) -> &[u8] {
133        unsafe {
134            slice::from_raw_parts(
135                self as *const FloatRegisters as *const u8,
136                mem::size_of::<FloatRegisters>(),
137            )
138        }
139    }
140}
141
142impl DerefMut for FloatRegisters {
143    fn deref_mut(&mut self) -> &mut [u8] {
144        unsafe {
145            slice::from_raw_parts_mut(
146                self as *mut FloatRegisters as *mut u8,
147                mem::size_of::<FloatRegisters>(),
148            )
149        }
150    }
151}
152#[derive(Clone, Copy, Debug, Default)]
153#[repr(C, packed)]
154pub struct EnvRegisters {
155    pub fsbase: u64,
156    pub gsbase: u64,
157    // TODO: PKRU?
158}
159impl Deref for EnvRegisters {
160    type Target = [u8];
161    fn deref(&self) -> &[u8] {
162        unsafe {
163            slice::from_raw_parts(
164                self as *const EnvRegisters as *const u8,
165                mem::size_of::<EnvRegisters>(),
166            )
167        }
168    }
169}
170
171impl DerefMut for EnvRegisters {
172    fn deref_mut(&mut self) -> &mut [u8] {
173        unsafe {
174            slice::from_raw_parts_mut(
175                self as *mut EnvRegisters as *mut u8,
176                mem::size_of::<EnvRegisters>(),
177            )
178        }
179    }
180}
181
182#[derive(Clone, Copy, Debug, Default)]
183#[repr(C, packed)]
184pub struct Exception {
185    pub kind: usize,
186    pub code: usize,
187    pub address: usize,
188}
189impl Deref for Exception {
190    type Target = [u8];
191    fn deref(&self) -> &[u8] {
192        unsafe {
193            slice::from_raw_parts(
194                self as *const Exception as *const u8,
195                mem::size_of::<Exception>(),
196            )
197        }
198    }
199}
200
201impl DerefMut for Exception {
202    fn deref_mut(&mut self) -> &mut [u8] {
203        unsafe {
204            slice::from_raw_parts_mut(
205                self as *mut Exception as *mut u8,
206                mem::size_of::<Exception>(),
207            )
208        }
209    }
210}