blob: 4235db9be308fbf37fd2973649a719511a91001d [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
Patrick Rudolphb4283a42023-12-28 07:44:26 +01006/*
7 * Assembly code that drops into protected mode and calls the function
8 * specified as first argument, which must have been compiled for x86_32.
9 * After the function returns it enters long mode again.
10 * The function pointer destination must be below 4GiB in physical memory.
11 *
12 * The called function has 0-3 arguments and returns an int.
13 */
14int protected_mode_call_3arg(uint32_t func_ptr,
Patrick Rudolph7a359492020-11-30 15:56:59 +010015 uint32_t opt_arg1,
Patrick Rudolphb4283a42023-12-28 07:44:26 +010016 uint32_t opt_arg2,
17 uint32_t opt_arg3);
Patrick Rudolph7a359492020-11-30 15:56:59 +010018
19/*
20 * Drops into protected mode and calls the function, which must have been compiled for x86_32.
21 * After the function returns it enters long mode again.
22 * The function pointer destination must be below 4GiB in physical memory.
23 *
24 * The called function doesn't have arguments and returns an int.
25 */
26static inline int protected_mode_call(void *func)
27{
Patrick Rudolphb4283a42023-12-28 07:44:26 +010028 return protected_mode_call_3arg((uintptr_t)func, 0, 0, 0);
Patrick Rudolph7a359492020-11-30 15:56:59 +010029}
30
31/*
32 * Drops into protected mode and calls the function, which must have been compiled for x86_32.
33 * After the function returns it enters long mode again.
34 * The function pointer destination must be below 4GiB in physical memory.
35 * Only the lower 32bits of the argument are passed to the called function.
36 *
37 * The called function have one argument and returns an int.
38 */
39static inline int protected_mode_call_1arg(void *func, uint32_t arg1)
40{
Patrick Rudolphb4283a42023-12-28 07:44:26 +010041 return protected_mode_call_3arg((uintptr_t)func, arg1, 0, 0);
Patrick Rudolph7a359492020-11-30 15:56:59 +010042}
43
44/*
45 * Drops into protected mode and calls the function, which must have been compiled for x86_32.
46 * After the function returns it enters long mode again.
47 * The function pointer destination must be below 4GiB in physical memory.
48 * Only the lower 32bits of the argument are passed to the called function.
49 *
50 * The called function has two arguments and returns an int.
51 */
52static inline int protected_mode_call_2arg(void *func, uint32_t arg1, uint32_t arg2)
53{
Patrick Rudolphb4283a42023-12-28 07:44:26 +010054 return protected_mode_call_3arg((uintptr_t)func, arg1, arg2, 0);
Patrick Rudolph7a359492020-11-30 15:56:59 +010055}
56#else
57static inline int protected_mode_call(void *func)
58{
59 int (*doit)(void) = func;
60
61 return doit();
62}
63
64static inline int protected_mode_call_1arg(void *func, uint32_t arg1)
65{
66 int (*doit)(uint32_t arg1) = func;
67
68 return doit(arg1);
69}
70
71static inline int protected_mode_call_2arg(void *func, uint32_t arg1, uint32_t arg2)
72{
73 int (*doit)(uint32_t arg1, uint32_t arg2) = func;
74
75 return doit(arg1, arg2);
76}
77#endif