summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPatrick Rudolph <patrick.rudolph@9elements.com>2023-12-31 12:30:50 +0100
committerFelix Held <felix-coreboot@felixheld.de>2024-01-05 14:36:14 +0000
commitddc19b334168f51d9c9919ec5aaf073daf7fbb35 (patch)
tree813db7c86154f2982e6aa692a8e044beab47267d /src
parent1d718def057770194f9fb5111201baf43ce7c838 (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>
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86/include/mode_switch.h36
-rw-r--r--src/cpu/x86/64bit/mode_switch.S4
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