blob: 24efb1ef58245329fd5df950ee67dfef36f9c850 [file] [log] [blame]
Patrick Rudolph7a359492020-11-30 15:56:59 +01001/* SPDX-License-Identifier: GPL-2.0-only */
2
Patrick Rudolph7a359492020-11-30 15:56:59 +01003#include <stdint.h>
4
5#if ENV_X86_64
6int 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 */
18static 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 */
31static 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 */
44static 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
49static inline int protected_mode_call(void *func)
50{
51 int (*doit)(void) = func;
52
53 return doit();
54}
55
56static 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
63static 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