Patrick Rudolph | 7a35949 | 2020-11-30 15:56:59 +0100 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | |
Patrick Rudolph | 7a35949 | 2020-11-30 15:56:59 +0100 | [diff] [blame] | 3 | #include <stdint.h> |
| 4 | |
| 5 | #if ENV_X86_64 |
| 6 | int protected_mode_call_narg(uint32_t arg_count, |
| 7 | uint32_t func_ptr, |
| 8 | uint32_t opt_arg1, |
| 9 | uint32_t opt_arg2); |
| 10 | |
| 11 | /* |
| 12 | * Drops into protected mode and calls the function, which must have been compiled for x86_32. |
| 13 | * After the function returns it enters long mode again. |
| 14 | * The function pointer destination must be below 4GiB in physical memory. |
| 15 | * |
| 16 | * The called function doesn't have arguments and returns an int. |
| 17 | */ |
| 18 | static inline int protected_mode_call(void *func) |
| 19 | { |
| 20 | return protected_mode_call_narg(0, (uintptr_t)func, 0, 0); |
| 21 | } |
| 22 | |
| 23 | /* |
| 24 | * Drops into protected mode and calls the function, which must have been compiled for x86_32. |
| 25 | * After the function returns it enters long mode again. |
| 26 | * The function pointer destination must be below 4GiB in physical memory. |
| 27 | * Only the lower 32bits of the argument are passed to the called function. |
| 28 | * |
| 29 | * The called function have one argument and returns an int. |
| 30 | */ |
| 31 | static inline int protected_mode_call_1arg(void *func, uint32_t arg1) |
| 32 | { |
| 33 | return protected_mode_call_narg(1, (uintptr_t)func, arg1, 0); |
| 34 | } |
| 35 | |
| 36 | /* |
| 37 | * Drops into protected mode and calls the function, which must have been compiled for x86_32. |
| 38 | * After the function returns it enters long mode again. |
| 39 | * The function pointer destination must be below 4GiB in physical memory. |
| 40 | * Only the lower 32bits of the argument are passed to the called function. |
| 41 | * |
| 42 | * The called function has two arguments and returns an int. |
| 43 | */ |
| 44 | static inline int protected_mode_call_2arg(void *func, uint32_t arg1, uint32_t arg2) |
| 45 | { |
| 46 | return protected_mode_call_narg(2, (uintptr_t)func, arg1, arg2); |
| 47 | } |
| 48 | #else |
| 49 | static inline int protected_mode_call(void *func) |
| 50 | { |
| 51 | int (*doit)(void) = func; |
| 52 | |
| 53 | return doit(); |
| 54 | } |
| 55 | |
| 56 | static inline int protected_mode_call_1arg(void *func, uint32_t arg1) |
| 57 | { |
| 58 | int (*doit)(uint32_t arg1) = func; |
| 59 | |
| 60 | return doit(arg1); |
| 61 | } |
| 62 | |
| 63 | static inline int protected_mode_call_2arg(void *func, uint32_t arg1, uint32_t arg2) |
| 64 | { |
| 65 | int (*doit)(uint32_t arg1, uint32_t arg2) = func; |
| 66 | |
| 67 | return doit(arg1, arg2); |
| 68 | } |
| 69 | #endif |