1use core::{
2 arch::asm,
3 mem,
4 ops::{Deref, DerefMut},
5 slice,
6};
7
8use super::error::{Error, Result};
9
10pub const PAGE_SIZE: usize = 4096;
11pub const KERNEL_METADATA_SIZE: usize = 4 * PAGE_SIZE;
13
14#[cfg(feature = "userspace")]
15macro_rules! syscall {
16 ($($name:ident($a:ident, $($b:ident, $($c:ident, $($d:ident, $($e:ident, $($f:ident, )?)?)?)?)?);)+) => {
17 $(
18 pub unsafe fn $name(mut $a: usize, $($b: usize, $($c: usize, $($d: usize, $($e: usize, $($f: usize)?)?)?)?)?) -> Result<usize> {
19 asm!(
20 "int 0x80",
21 inout("eax") $a,
22 $(
23 in("ebx") $b,
24 $(
25 in("ecx") $c,
26 $(
27 in("edx") $d,
28 $(
29 in("esi") $e,
30 $(
31 in("edi") $f,
32 )?
33 )?
34 )?
35 )?
36 )?
37 options(nostack),
38 );
39
40 Error::demux($a)
41 }
42 )+
43 };
44}
45
46#[cfg(feature = "userspace")]
47syscall! {
48 syscall0(a,);
49 syscall1(a, b,);
50 syscall2(a, b, c,);
51 syscall3(a, b, c, d,);
52 }
57
58#[cfg(feature = "userspace")]
59pub unsafe fn syscall4(mut a: usize, b: usize, c: usize, d: usize, e: usize) -> Result<usize> {
60 asm!(
61 "xchg esi, {e}
62 int 0x80
63 xchg esi, {e}",
64 e = in(reg) e,
65 inout("eax") a,
66 in("ebx") b,
67 in("ecx") c,
68 in("edx") d,
69 options(nostack),
70 );
71
72 Error::demux(a)
73}
74
75#[cfg(feature = "userspace")]
76pub unsafe fn syscall5(
77 mut a: usize,
78 b: usize,
79 c: usize,
80 d: usize,
81 e: usize,
82 f: usize,
83) -> Result<usize> {
84 asm!(
85 "xchg esi, {e}
86 int 0x80
87 xchg esi, {e}",
88 e = in(reg) e,
89 inout("eax") a,
90 in("ebx") b,
91 in("ecx") c,
92 in("edx") d,
93 in("edi") f,
94 options(nostack),
95 );
96
97 Error::demux(a)
98}
99
100#[cfg(feature = "userspace")]
101pub unsafe fn syscall6(
102 mut a: usize,
103 b: usize,
104 c: usize,
105 d: usize,
106 e: usize,
107 f: usize,
108 g: usize,
109) -> Result<usize> {
110 #[repr(C)]
111 struct PackedArgs {
112 arg4: usize,
113 arg6: usize,
114 nr: usize,
115 }
116 let args = PackedArgs {
117 arg4: e,
118 arg6: g,
119 nr: a,
120 };
121 let args_ptr = &args as *const PackedArgs;
122 asm!(
123 "push ebp",
124 "push esi",
125 "mov esi, [eax + 0]", "mov ebp, [eax + 4]", "mov eax, [eax + 8]", "int 0x80",
129 "pop esi",
130 "pop ebp",
131 inout("eax") args_ptr => a,
132 in("ebx") b,
133 in("ecx") c,
134 in("edx") d,
135 in("edi") f,
136 options(nostack),
137 );
138
139 Error::demux(a)
140}
141
142#[derive(Copy, Clone, Debug, Default)]
143#[repr(C)]
144pub struct IntRegisters {
145 pub ebp: usize,
147 pub esi: usize,
148 pub edi: usize,
149 pub ebx: usize,
150 pub eax: usize,
151 pub ecx: usize,
152 pub edx: usize,
153 pub eip: usize,
155 pub cs: usize,
156 pub eflags: usize,
157 pub esp: usize,
158 pub ss: usize,
159 pub fs: usize,
164 }
166
167impl Deref for IntRegisters {
168 type Target = [u8];
169 fn deref(&self) -> &[u8] {
170 unsafe {
171 slice::from_raw_parts(
172 self as *const IntRegisters as *const u8,
173 mem::size_of::<IntRegisters>(),
174 )
175 }
176 }
177}
178
179impl DerefMut for IntRegisters {
180 fn deref_mut(&mut self) -> &mut [u8] {
181 unsafe {
182 slice::from_raw_parts_mut(
183 self as *mut IntRegisters as *mut u8,
184 mem::size_of::<IntRegisters>(),
185 )
186 }
187 }
188}
189
190#[derive(Clone, Copy, Debug, Default)]
191#[repr(C, packed)]
192pub struct FloatRegisters {
193 pub fcw: u16,
194 pub fsw: u16,
195 pub ftw: u8,
196 pub _reserved: u8,
197 pub fop: u16,
198 pub fip: u64,
199 pub fdp: u64,
200 pub mxcsr: u32,
201 pub mxcsr_mask: u32,
202 pub st_space: [u128; 8],
203 pub xmm_space: [u128; 16],
204 }
206
207impl Deref for FloatRegisters {
208 type Target = [u8];
209 fn deref(&self) -> &[u8] {
210 unsafe {
211 slice::from_raw_parts(
212 self as *const FloatRegisters as *const u8,
213 mem::size_of::<FloatRegisters>(),
214 )
215 }
216 }
217}
218
219impl DerefMut for FloatRegisters {
220 fn deref_mut(&mut self) -> &mut [u8] {
221 unsafe {
222 slice::from_raw_parts_mut(
223 self as *mut FloatRegisters as *mut u8,
224 mem::size_of::<FloatRegisters>(),
225 )
226 }
227 }
228}
229
230#[derive(Clone, Copy, Debug, Default)]
231#[repr(C, packed)]
232pub struct EnvRegisters {
233 pub fsbase: u32,
234 pub gsbase: u32,
235}
236
237impl Deref for EnvRegisters {
238 type Target = [u8];
239 fn deref(&self) -> &[u8] {
240 unsafe {
241 slice::from_raw_parts(
242 self as *const EnvRegisters as *const u8,
243 mem::size_of::<EnvRegisters>(),
244 )
245 }
246 }
247}
248
249impl DerefMut for EnvRegisters {
250 fn deref_mut(&mut self) -> &mut [u8] {
251 unsafe {
252 slice::from_raw_parts_mut(
253 self as *mut EnvRegisters as *mut u8,
254 mem::size_of::<EnvRegisters>(),
255 )
256 }
257 }
258}
259
260#[derive(Clone, Copy, Debug, Default)]
261#[repr(C, packed)]
262pub struct Exception {
263 pub kind: usize,
264 pub code: usize,
265 pub address: usize,
266}
267impl Deref for Exception {
268 type Target = [u8];
269 fn deref(&self) -> &[u8] {
270 unsafe {
271 slice::from_raw_parts(
272 self as *const Exception as *const u8,
273 mem::size_of::<Exception>(),
274 )
275 }
276 }
277}
278
279impl DerefMut for Exception {
280 fn deref_mut(&mut self) -> &mut [u8] {
281 unsafe {
282 slice::from_raw_parts_mut(
283 self as *mut Exception as *mut u8,
284 mem::size_of::<Exception>(),
285 )
286 }
287 }
288}