From b4283a4fbbcc8702afa4d992789ca458a7df923a Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Thu, 28 Dec 2023 07:44:26 +0100 Subject: cpu/x86/64bit/mode_switch: Simplify assembly code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the first argument specifying the number of arguments pushed to the stack. Instead always push the 3 arguments to stack and use the first one as function pointer to call while in protected mode. While on it add more comments and simplify register restore code. Tested: - On qemu can call x86_32 function and pass argument and return value. - Booted Lenovo X220 in x86_64 mode using x86_32 MRC. Change-Id: I30809453a1800ba3c0df60acd7eca778841c520f Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/79752 Reviewed-by: Arthur Heymans Reviewed-by: Jérémy Compostella Tested-by: build bot (Jenkins) --- src/arch/x86/include/mode_switch.h | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'src/arch/x86') diff --git a/src/arch/x86/include/mode_switch.h b/src/arch/x86/include/mode_switch.h index 24efb1ef58..4235db9be3 100644 --- a/src/arch/x86/include/mode_switch.h +++ b/src/arch/x86/include/mode_switch.h @@ -3,10 +3,18 @@ #include #if ENV_X86_64 -int protected_mode_call_narg(uint32_t arg_count, - uint32_t func_ptr, +/* + * Assembly code that drops into protected mode and calls the function + * specified as first argument, 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. + * + * 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_arg2, + uint32_t opt_arg3); /* * Drops into protected mode and calls the function, which must have been compiled for x86_32. @@ -17,7 +25,7 @@ int protected_mode_call_narg(uint32_t arg_count, */ static inline int protected_mode_call(void *func) { - return protected_mode_call_narg(0, (uintptr_t)func, 0, 0); + return protected_mode_call_3arg((uintptr_t)func, 0, 0, 0); } /* @@ -30,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_narg(1, (uintptr_t)func, arg1, 0); + return protected_mode_call_3arg((uintptr_t)func, arg1, 0, 0); } /* @@ -43,7 +51,7 @@ 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_narg(2, (uintptr_t)func, arg1, arg2); + return protected_mode_call_3arg((uintptr_t)func, arg1, arg2, 0); } #else static inline int protected_mode_call(void *func) -- cgit v1.2.3