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                                        // TODO
30                                        //$(
31                                        //  in("r9") $g,
32                                        //)?
33                                    )?
34                                )?
35                            )?
36                        )?
37                    )?
38                    out("rcx") _,
39                    out("r11") _,
40                    out("r9") _,
41                    out("xmm0") _,
42                    out("xmm1") _,
43                    out("xmm2") _,
44                    out("xmm3") _,
45                    out("xmm4") _,
46                    out("xmm5") _,
47                    out("xmm6") _,
48                    out("xmm7") _,
49                    out("xmm8") _,
50                    out("xmm9") _,
51                    out("xmm10") _,
52                    out("xmm11") _,
53                    out("xmm12") _,
54                    out("xmm13") _,
55                    out("xmm14") _,
56                    out("xmm15") _,
57                    options(nostack),
58                );
59
60                crate::error::Error::demux($a)
61            }
62        )+
63    };
64}
65
66#[cfg(feature = "userspace")]
67syscall! {
68    syscall0(a,);
69    syscall1(a, b,);
70    syscall2(a, b, c,);
71    syscall3(a, b, c, d,);
72    syscall4(a, b, c, d, e,);
73    syscall5(a, b, c, d, e, f,);
74    // TODO: Once syscall count is reduced, consider passing syscall number using RFLAGS
75    // (LAHF/SAHF), freeing up rax register. That is necessary to avoid SWAPGS, for performance.
76    //syscall6(a, b, c, d, e, f, g,);
77}
78
79#[derive(Copy, Clone, Debug, Default)]
80#[repr(C)]
81pub struct IntRegisters {
82    pub r15: usize,
83    pub r14: usize,
84    pub r13: usize,
85    pub r12: usize,
86    pub rbp: usize,
87    pub rbx: usize,
88    pub r11: usize,
89    pub r10: usize,
90    pub r9: usize,
91    pub r8: usize,
92    pub rax: usize,
93    pub rcx: usize,
94    pub rdx: usize,
95    pub rsi: usize,
96    pub rdi: usize,
97    pub rip: usize,
98    pub cs: usize,
99    pub rflags: usize,
100    pub rsp: usize,
101    pub ss: usize,
102}
103
104impl Deref for IntRegisters {
105    type Target = [u8];
106    fn deref(&self) -> &[u8] {
107        unsafe { slice::from_raw_parts(self as *const Self as *const u8, mem::size_of::<Self>()) }
108    }
109}
110
111impl DerefMut for IntRegisters {
112    fn deref_mut(&mut self) -> &mut [u8] {
113        unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut u8, mem::size_of::<Self>()) }
114    }
115}
116
117#[derive(Clone, Copy, Debug, Default)]
118#[repr(C, packed)]
119pub struct FloatRegisters {
120    pub fcw: u16,
121    pub fsw: u16,
122    pub ftw: u8,
123    pub _reserved: u8,
124    pub fop: u16,
125    pub fip: u64,
126    pub fdp: u64,
127    pub mxcsr: u32,
128    pub mxcsr_mask: u32,
129    pub st_space: [u128; 8],
130    pub xmm_space: [u128; 16],
131    // TODO: YMM/ZMM
132}
133
134impl Deref for FloatRegisters {
135    type Target = [u8];
136    fn deref(&self) -> &[u8] {
137        unsafe {
138            slice::from_raw_parts(
139                self as *const FloatRegisters as *const u8,
140                mem::size_of::<FloatRegisters>(),
141            )
142        }
143    }
144}
145
146impl DerefMut for FloatRegisters {
147    fn deref_mut(&mut self) -> &mut [u8] {
148        unsafe {
149            slice::from_raw_parts_mut(
150                self as *mut FloatRegisters as *mut u8,
151                mem::size_of::<FloatRegisters>(),
152            )
153        }
154    }
155}
156#[derive(Clone, Copy, Debug, Default)]
157#[repr(C, packed)]
158pub struct EnvRegisters {
159    pub fsbase: u64,
160    pub gsbase: u64,
161    // TODO: PKRU?
162}
163impl Deref for EnvRegisters {
164    type Target = [u8];
165    fn deref(&self) -> &[u8] {
166        unsafe {
167            slice::from_raw_parts(
168                self as *const EnvRegisters as *const u8,
169                mem::size_of::<EnvRegisters>(),
170            )
171        }
172    }
173}
174
175impl DerefMut for EnvRegisters {
176    fn deref_mut(&mut self) -> &mut [u8] {
177        unsafe {
178            slice::from_raw_parts_mut(
179                self as *mut EnvRegisters as *mut u8,
180                mem::size_of::<EnvRegisters>(),
181            )
182        }
183    }
184}
185
186#[derive(Clone, Copy, Debug, Default)]
187#[repr(C, packed)]
188pub struct Exception {
189    pub kind: usize,
190    pub code: usize,
191    pub address: usize,
192}
193
194impl Exception {
195    pub fn pack(&self) -> (usize, usize) {
196        let code = (self.kind << 32) | (self.code & 0xFFFF_FFFF);
197        (code, self.address)
198    }
199    pub fn unpack(code: usize, address: usize) -> Self {
200        Exception {
201            kind: code >> 32,
202            code: code & 0xFFFF_FFFF,
203            address,
204        }
205    }
206}
207
208impl Deref for Exception {
209    type Target = [u8];
210    fn deref(&self) -> &[u8] {
211        unsafe {
212            slice::from_raw_parts(
213                self as *const Exception as *const u8,
214                mem::size_of::<Exception>(),
215            )
216        }
217    }
218}
219
220impl DerefMut for Exception {
221    fn deref_mut(&mut self) -> &mut [u8] {
222        unsafe {
223            slice::from_raw_parts_mut(
224                self as *mut Exception as *mut u8,
225                mem::size_of::<Exception>(),
226            )
227        }
228    }
229}