diff options
author | Patrick Rudolph <patrick.rudolph@9elements.com> | 2023-12-31 12:30:50 +0100 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2024-01-05 14:36:14 +0000 |
commit | ddc19b334168f51d9c9919ec5aaf073daf7fbb35 (patch) | |
tree | 813db7c86154f2982e6aa692a8e044beab47267d | |
parent | 1d718def057770194f9fb5111201baf43ce7c838 (diff) |
arch/x86/include/mode_switch: Add more wrapper functions
Add a protected mode wrapper function that takes three arguments.
This is already supported by the called assembly code.
Change-Id: Ia8c91eebae17e4ca27e391454c2d130a71c4c9f3
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/79756
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
-rw-r--r-- | src/arch/x86/include/mode_switch.h | 36 | ||||
-rw-r--r-- | src/cpu/x86/64bit/mode_switch.S | 4 |
2 files changed, 31 insertions, 9 deletions
diff --git a/src/arch/x86/include/mode_switch.h b/src/arch/x86/include/mode_switch.h index 4235db9be3..54969b2e67 100644 --- a/src/arch/x86/include/mode_switch.h +++ b/src/arch/x86/include/mode_switch.h @@ -11,10 +11,10 @@ * * The called function has 0-3 arguments and returns an int. */ -int protected_mode_call_3arg(uint32_t func_ptr, - uint32_t opt_arg1, - uint32_t opt_arg2, - uint32_t opt_arg3); +int protected_mode_call_wrapper(uint32_t func_ptr, + uint32_t opt_arg1, + uint32_t opt_arg2, + uint32_t opt_arg3); /* * Drops into protected mode and calls the function, which must have been compiled for x86_32. @@ -25,7 +25,7 @@ int protected_mode_call_3arg(uint32_t func_ptr, */ static inline int protected_mode_call(void *func) { - return protected_mode_call_3arg((uintptr_t)func, 0, 0, 0); + return protected_mode_call_wrapper((uintptr_t)func, 0, 0, 0); } /* @@ -38,7 +38,7 @@ static inline int protected_mode_call(void *func) */ static inline int protected_mode_call_1arg(void *func, uint32_t arg1) { - return protected_mode_call_3arg((uintptr_t)func, arg1, 0, 0); + return protected_mode_call_wrapper((uintptr_t)func, arg1, 0, 0); } /* @@ -51,7 +51,21 @@ static inline int protected_mode_call_1arg(void *func, uint32_t arg1) */ static inline int protected_mode_call_2arg(void *func, uint32_t arg1, uint32_t arg2) { - return protected_mode_call_3arg((uintptr_t)func, arg1, arg2, 0); + return protected_mode_call_wrapper((uintptr_t)func, arg1, arg2, 0); +} + +/* + * Drops into protected mode and calls the function, which must have been compiled for x86_32. + * After the function returns it enters long mode again. + * The function pointer destination must be below 4GiB in physical memory. + * Only the lower 32bits of the argument are passed to the called function. + * + * The called function has two arguments and returns an int. + */ +static inline int protected_mode_call_3arg(void *func, uint32_t arg1, uint32_t arg2, + uint32_t arg3) +{ + return protected_mode_call_wrapper((uintptr_t)func, arg1, arg2, arg3); } #else static inline int protected_mode_call(void *func) @@ -74,4 +88,12 @@ static inline int protected_mode_call_2arg(void *func, uint32_t arg1, uint32_t a return doit(arg1, arg2); } + +static inline int protected_mode_call_3arg(void *func, uint32_t arg1, uint32_t arg2, + uint32_t arg3) +{ + int (*doit)(uint32_t arg1, uint32_t arg2, uint32_t arg3) = func; + + return doit(arg1, arg2, arg3); +} #endif diff --git a/src/cpu/x86/64bit/mode_switch.S b/src/cpu/x86/64bit/mode_switch.S index f9f784e8c4..c4198f3dad 100644 --- a/src/cpu/x86/64bit/mode_switch.S +++ b/src/cpu/x86/64bit/mode_switch.S @@ -4,8 +4,8 @@ .text .code64 .section ".text.protected_mode_call", "ax", @progbits - .globl protected_mode_call_3arg -protected_mode_call_3arg: + .globl protected_mode_call_wrapper +protected_mode_call_wrapper: /* Preserve registers */ push %rbp push %rbx |