While we are keeping handover the default for now, this should change in
future and the first step towards doing that is allowing users to try
both at runtime.

Add a new $global.linux.efi.handover variable to control this.

Signed-off-by: Ahmad Fatoum <[email protected]>
---
 arch/x86/configs/efi_defconfig |  1 +
 efi/payload/Kconfig            | 24 ++++++++++++++++++++++--
 efi/payload/Makefile           |  2 +-
 efi/payload/bootm.c            | 29 ++++++++++++++++++++++++++---
 efi/payload/handover.c         |  5 +++--
 efi/payload/image.h            | 11 +++++++++++
 6 files changed, 64 insertions(+), 8 deletions(-)

diff --git a/arch/x86/configs/efi_defconfig b/arch/x86/configs/efi_defconfig
index 1dd823af40ea..e21ac4fda3e7 100644
--- a/arch/x86/configs/efi_defconfig
+++ b/arch/x86/configs/efi_defconfig
@@ -18,6 +18,7 @@ CONFIG_STATE=y
 CONFIG_BOOTCHOOSER=y
 CONFIG_RESET_SOURCE=y
 CONFIG_DEBUG_LL=y
+CONFIG_EFI_PAYLOAD_BOOTM=y
 CONFIG_CMD_DMESG=y
 CONFIG_LONGHELP=y
 CONFIG_CMD_IOMEM=y
diff --git a/efi/payload/Kconfig b/efi/payload/Kconfig
index 31eab4f3ef88..782e974d8f58 100644
--- a/efi/payload/Kconfig
+++ b/efi/payload/Kconfig
@@ -26,9 +26,29 @@ config EFI_STUB
        def_bool HAVE_EFI_STUB
 
 config EFI_HANDOVER_PROTOCOL
-       bool "EFI Handover protocol"
-       depends on !EFI_PAYLOAD_BOOTM
+       bool "EFI Handover protocol (DEPRECATED)"
        depends on X86
+       default y
+       help
+         Select this in order to include support for booting Linux
+         over the deprecated EFI handover protocol, which defines alternative
+         entry points into the EFI stub.
+
+         This is a practice that has no basis in the UEFI specification,
+         and requires a priori knowledge on the part of the bootloader about
+         Linux/x86 specific ways of passing the command line and initrd,
+         and where in memory those assets may be loaded.
+
+         This method of booting has been deprecated in Linux v6.2 in favor
+         of the StartImage() boot service and should not be required with
+         Linux v5.7 and above.
+
+         If you say y here, the handover protocol will be used, unless
+         global.linux.efi.handover=0 was set.
+
+         If unsure, keep the default of y. The StartImage support for booting
+         Linux is still new in barebox and will be made the default once we
+         gain more confidence in its implementation.
 
 config EFI_PAYLOAD_BOOTM
        bool "EFI bootm protocol"
diff --git a/efi/payload/Makefile b/efi/payload/Makefile
index 083728c53cb4..34efe6105d22 100644
--- a/efi/payload/Makefile
+++ b/efi/payload/Makefile
@@ -3,7 +3,7 @@
 obj-y += init.o
 obj-y += image.o
 obj-$(CONFIG_EFI_HANDOVER_PROTOCOL) += handover.o
-obj-$(CONFIG_EFI_PAYLOAD_BOOTM) += bootm.o
+obj-y += bootm.o
 obj-y += efi-initrd.o
 obj-$(CONFIG_OFTREE) += fdt.o
 bbenv-y += env-efi
diff --git a/efi/payload/bootm.c b/efi/payload/bootm.c
index da53e3939d26..2e060762f238 100644
--- a/efi/payload/bootm.c
+++ b/efi/payload/bootm.c
@@ -9,6 +9,7 @@
 
 #include <clock.h>
 #include <common.h>
+#include <globalvar.h>
 #include <linux/sizes.h>
 #include <linux/ktime.h>
 #include <memory.h>
@@ -284,16 +285,32 @@ static int efi_app_execute(struct image_data *data)
        return efi_execute_image(handle, loaded_image, type);
 }
 
+static int linux_efi_handover = true;
+
+bool efi_x86_boot_method_check(struct image_handler *handler,
+                              struct image_data *data,
+                              enum filetype detected_filetype)
+{
+       if (handler->filetype != detected_filetype)
+               return false;
+
+       if (IS_ENABLED(CONFIG_EFI_HANDOVER_PROTOCOL) && linux_efi_handover)
+               return handler == &efi_x86_linux_handle_handover;
+       else
+               return handler == &efi_x86_linux_handle_tr;
+}
+
 static struct image_handler efi_app_handle_tr = {
        .name = "EFI Application",
        .bootm = efi_app_execute,
        .filetype = filetype_exe,
 };
 
-static struct image_handler efi_x86_linux_handle_tr = {
-       .name = "EFI X86 Linux kernel",
+struct image_handler efi_x86_linux_handle_tr = {
+       .name = "EFI X86 Linux kernel (StartImage)",
        .bootm = do_bootm_efi_stub,
        .filetype = filetype_x86_efi_linux_image,
+       .check_image = efi_x86_boot_method_check,
 };
 
 static struct image_handler efi_arm64_handle_tr = {
@@ -302,12 +319,18 @@ static struct image_handler efi_arm64_handle_tr = {
        .filetype = filetype_arm64_efi_linux_image,
 };
 
+BAREBOX_MAGICVAR(global.linux.efi.handover,
+                "Use legacy x86 handover protocol instead of StartImage 
BootService");
+
 static int efi_register_bootm_handler(void)
 {
        register_image_handler(&efi_app_handle_tr);
 
-       if (IS_ENABLED(CONFIG_X86))
+       if (IS_ENABLED(CONFIG_X86)) {
+               if (IS_ENABLED(CONFIG_EFI_HANDOVER_PROTOCOL))
+                       globalvar_add_simple_bool("linux.efi.handover", 
&linux_efi_handover);
                register_image_handler(&efi_x86_linux_handle_tr);
+       }
 
        if (IS_ENABLED(CONFIG_ARM64))
                register_image_handler(&efi_arm64_handle_tr);
diff --git a/efi/payload/handover.c b/efi/payload/handover.c
index f549568b6d03..8c6dd2896f47 100644
--- a/efi/payload/handover.c
+++ b/efi/payload/handover.c
@@ -128,10 +128,11 @@ static int do_bootm_efi(struct image_data *data)
        return 0;
 }
 
-static struct image_handler efi_x86_linux_handle_handover = {
-       .name = "EFI Application",
+struct image_handler efi_x86_linux_handle_handover = {
+       .name = "EFI X86 Linux kernel (Legacy Handover)",
        .bootm = do_bootm_efi,
        .filetype = filetype_x86_efi_linux_image,
+       .check_image = efi_x86_boot_method_check,
 };
 
 static int efi_register_handover_handler(void)
diff --git a/efi/payload/image.h b/efi/payload/image.h
index 673b21db839a..bab1be368c21 100644
--- a/efi/payload/image.h
+++ b/efi/payload/image.h
@@ -3,6 +3,10 @@
 #define __EFI_PAYLOAD_IMAGE_H__
 
 #include <efi/types.h>
+#include <filetype.h>
+
+struct efi_loaded_image;
+struct image_data;
 
 int efi_load_image(const char *file, struct efi_loaded_image **loaded_image,
                   efi_handle_t *h);
@@ -11,4 +15,11 @@ int efi_execute_image(efi_handle_t handle,
                      struct efi_loaded_image *loaded_image,
                      enum filetype filetype);
 
+extern struct image_handler efi_x86_linux_handle_tr;
+extern struct image_handler efi_x86_linux_handle_handover;
+
+bool efi_x86_boot_method_check(struct image_handler *handler,
+                              struct image_data *data,
+                              enum filetype detected_filetype);
+
 #endif
-- 
2.47.3


Reply via email to