Patrick Rudolph | 3052e9e | 2023-12-28 07:45:19 +0100 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | /* |
| 3 | * Calls a x86_64 function from x86_32 context. |
| 4 | * Must not be directly invoked from C code! |
| 5 | */ |
| 6 | |
| 7 | .text |
| 8 | .code32 |
| 9 | .section ".text.long_mode_call_3arg", "ax", @progbits |
| 10 | .global long_mode_call_3arg |
| 11 | long_mode_call_3arg: |
| 12 | |
| 13 | /* Function to call is passed in EAX. */ |
| 14 | |
| 15 | /* Backup registers */ |
| 16 | pushal |
| 17 | |
| 18 | /* Backup stack pointer */ |
| 19 | mov %esp, %ebp |
| 20 | |
| 21 | /* Enter long mode, preserves ebx */ |
| 22 | #include <cpu/x86/64bit/entry64.inc> |
| 23 | |
| 24 | /* Align stack */ |
| 25 | movabs $0xfffffffffffffff0, %rax |
| 26 | andq %rax, %rsp |
| 27 | |
| 28 | movl 28(%rbp), %ebx /* Function to call */ |
| 29 | movl 36(%rbp), %edi /* 1st arg */ |
| 30 | movl 40(%rbp), %esi /* 2nd arg */ |
| 31 | movl 44(%rbp), %edx /* 3rd arg */ |
| 32 | |
| 33 | call *%rbx |
| 34 | |
| 35 | /* Store return value on stack. popal will fetch it. */ |
| 36 | mov %eax, 28(%rbp) |
| 37 | shr $32, %rax |
| 38 | movl %eax, 24(%rbp) |
| 39 | |
| 40 | #include <cpu/x86/64bit/exit32.inc> |
| 41 | |
| 42 | /* Restore stack pointer */ |
| 43 | mov %ebp, %esp |
| 44 | |
| 45 | /* Restore registers */ |
| 46 | popal |
| 47 | |
| 48 | ret |