efi: Allow excluding efi_main()

In some cases this function may be provided outside the library, e.g. by
a Rust main program. Add a Kconfig to control this and refactor the code
so that it is optional.

Signed-off-by: Simon Glass <simon.glass@canonical.com>
This commit is contained in:
Simon Glass
2025-11-02 16:39:30 +01:00
parent 3df466ada2
commit 7477fe4d9b
5 changed files with 66 additions and 13 deletions

View File

@@ -92,6 +92,15 @@ config EFI_APP_DEBUG
possible to set the symbol offset. Since the app is relocated to an
unknown address, breakpoints will only work if this is done.
config EFI_APP_ENTRY
bool "Provide efi_main() entry point"
default y
help
Enable this to have libu-boot provide the efi_main() entry point
function. This is the standard entry point called by EFI when loading
the application. Disable this if you want to provide your own
efi_main() implementation.
endif # EFI_APP
endmenu

View File

@@ -4,6 +4,7 @@
obj-$(CONFIG_EFI_APP) += efi_app.o efi.o efi_app_init.o efi_vars.o efi_dtb.o
obj-$(CONFIG_EFI_APP) += sdram.o app_run.o
obj-$(CONFIG_EFI_APP_ENTRY) += efi_main.o
obj-$(CONFIG_EFI_STUB) += efi_info.o
ifeq ($(CONFIG_ARM64),y)

View File

@@ -389,21 +389,13 @@ U_BOOT_DRIVER(efi_sysreset) = {
.ops = &efi_sysreset_ops,
};
/**
* efi_main() - Start an EFI image
*
* This function is called by our EFI start-up code. It handles running
* U-Boot. If it returns, EFI will continue. Another way to get back to EFI
* is via reset_cpu().
*/
efi_status_t EFIAPI efi_main(efi_handle_t image,
struct efi_system_table *sys_table)
efi_status_t efi_startup(efi_handle_t image, struct efi_system_table *systab)
{
struct efi_priv local_priv, *priv = &local_priv;
efi_status_t ret;
/* Set up access to EFI data structures */
ret = efi_init(priv, "App", image, sys_table);
ret = efi_init(priv, "App", image, systab);
if (ret) {
printf("Failed to set up U-Boot: err=%lx\n", ret);
return ret;
@@ -441,8 +433,17 @@ efi_status_t EFIAPI efi_main(efi_handle_t image,
(detect_emulator() ? GD_FLG_EMUL : 0));
gd = gd->new_gd;
board_init_r(NULL, 0);
free_memory(priv);
efi_exit();
return EFI_SUCCESS;
return 0;
}
void efi_shutdown(void)
{
struct efi_priv *priv;
/* TODO: this causes a crash as efi_exit() makes use of priv */
priv = efi_get_priv();
if (0)
free_memory(priv);
efi_exit();
}

24
lib/efi_client/efi_main.c Normal file
View File

@@ -0,0 +1,24 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* EFI application entry point
*
* This file provides the efi_main() entry point function called by EFI firmware.
* It is separate from the library so applications can provide their own efi_main().
*/
#include <efi.h>
#include <efi_api.h>
efi_status_t EFIAPI efi_main(efi_handle_t image,
struct efi_system_table *sys_table)
{
efi_status_t ret;
ret = efi_startup(image, sys_table);
if (ret)
return ret;
efi_shutdown();
return EFI_SUCCESS;
}