|
1 | | -use core::arch::{asm, naked_asm}; |
2 | | -use core::{mem, ptr}; |
| 1 | +use core::arch::naked_asm; |
3 | 2 |
|
4 | | -use crate::core_local::CoreLocal; |
5 | 3 | use crate::set_current_kernel_stack; |
6 | 4 |
|
7 | 5 | #[cfg(not(feature = "common-os"))] |
@@ -209,104 +207,3 @@ pub(crate) unsafe extern "C" fn switch_to_fpu_owner(_old_stack: *mut usize, _new |
209 | 207 | set_current_kernel_stack = sym set_current_kernel_stack, |
210 | 208 | ); |
211 | 209 | } |
212 | | - |
213 | | -macro_rules! kernel_function_impl { |
214 | | - ($kernel_function:ident($($arg:ident: $A:ident),*) { $($operands:tt)* }) => { |
215 | | - /// Executes `f` on the kernel stack. |
216 | | - #[allow(dead_code)] |
217 | | - pub unsafe fn $kernel_function<R, $($A),*>(f: unsafe extern "C" fn($($A),*) -> R, $($arg: $A),*) -> R { |
218 | | - unsafe { |
219 | | - assert!(mem::size_of::<R>() <= mem::size_of::<usize>()); |
220 | | - |
221 | | - $( |
222 | | - assert!(mem::size_of::<$A>() <= mem::size_of::<usize>()); |
223 | | - let $arg = { |
224 | | - let mut reg = 0usize; |
225 | | - // SAFETY: $A is smaller than usize and directly fits in a register |
226 | | - // Since f takes $A as argument via C calling convention, any upper bytes do not matter. |
227 | | - ptr::write(ptr::from_mut(&mut reg).cast(), $arg); |
228 | | - reg |
229 | | - }; |
230 | | - )* |
231 | | - |
232 | | - let ret: u64; |
233 | | - asm!( |
234 | | - // Save user stack pointer and switch to kernel stack |
235 | | - "cli", |
236 | | - "mov r12, rsp", |
237 | | - "mov rsp, {kernel_stack_ptr}", |
238 | | - "sti", |
239 | | - |
240 | | - // To make sure, Rust manages the stack in `f` correctly, |
241 | | - // we keep all arguments and return values in registers |
242 | | - // until we switch the stack back. Thus follows the sizing |
243 | | - // requirements for arguments and return types. |
244 | | - "call {f}", |
245 | | - |
246 | | - // Switch back to user stack |
247 | | - "cli", |
248 | | - "mov rsp, r12", |
249 | | - "sti", |
250 | | - |
251 | | - f = in(reg) f, |
252 | | - kernel_stack_ptr = in(reg) CoreLocal::get().kernel_stack.get(), |
253 | | - |
254 | | - $($operands)* |
255 | | - |
256 | | - // user_stack_ptr saved in r12 |
257 | | - out("r12") _, |
258 | | - |
259 | | - // Return argument in rax |
260 | | - out("rax") ret, |
261 | | - |
262 | | - clobber_abi("C"), |
263 | | - ); |
264 | | - |
265 | | - // SAFETY: R is smaller than usize and directly fits in rax |
266 | | - // Since f returns R, we can safely convert ret to R |
267 | | - mem::transmute_copy(&ret) |
268 | | - } |
269 | | - } |
270 | | - }; |
271 | | -} |
272 | | - |
273 | | -kernel_function_impl!(kernel_function0() {}); |
274 | | - |
275 | | -kernel_function_impl!(kernel_function1(arg1: A1) { |
276 | | - in("rdi") arg1, |
277 | | -}); |
278 | | - |
279 | | -kernel_function_impl!(kernel_function2(arg1: A1, arg2: A2) { |
280 | | - in("rdi") arg1, |
281 | | - in("rsi") arg2, |
282 | | -}); |
283 | | - |
284 | | -kernel_function_impl!(kernel_function3(arg1: A1, arg2: A2, arg3: A3) { |
285 | | - in("rdi") arg1, |
286 | | - in("rsi") arg2, |
287 | | - in("rdx") arg3, |
288 | | -}); |
289 | | - |
290 | | -kernel_function_impl!(kernel_function4(arg1: A1, arg2: A2, arg3: A3, arg4: A4) { |
291 | | - in("rdi") arg1, |
292 | | - in("rsi") arg2, |
293 | | - in("rdx") arg3, |
294 | | - in("rcx") arg4, |
295 | | -}); |
296 | | - |
297 | | -kernel_function_impl!(kernel_function5(arg1: A1, arg2: A2, arg3: A3, arg4: A4, arg5: A5) { |
298 | | - in("rdi") arg1, |
299 | | - in("rsi") arg2, |
300 | | - in("rdx") arg3, |
301 | | - in("rcx") arg4, |
302 | | - in("r8") arg5, |
303 | | -}); |
304 | | - |
305 | | -kernel_function_impl!(kernel_function6(arg1: A1, arg2: A2, arg3: A3, arg4: A4, arg5: A5, arg6: A6) { |
306 | | - in("rdi") arg1, |
307 | | - in("rsi") arg2, |
308 | | - in("rdx") arg3, |
309 | | - in("rcx") arg4, |
310 | | - in("r8") arg5, |
311 | | - in("r9") arg6, |
312 | | -}); |
0 commit comments