bootstd: Allow bootmeths to be marked as global
authorSimon Glass <sjg@chromium.org>
Sat, 30 Jul 2022 21:52:21 +0000 (15:52 -0600)
committerTom Rini <trini@konsulko.com>
Fri, 12 Aug 2022 12:17:10 +0000 (08:17 -0400)
The current way of handling things like EFI bootmgr is a bit odd, since
that bootmeth handles selection of the bootdev itself. VBE needs to work
the same way, so we should support it properly.

Add a flag that indicates that the bootmeth is global, rather than being
invoked on each bootdev. Provide a helper to read a bootflow from the
bootmeth.

Signed-off-by: Simon Glass <sjg@chromium.org>
boot/Kconfig
boot/bootmeth-uclass.c
boot/bootmeth_efi_mgr.c
cmd/bootmeth.c
include/bootmeth.h
lib/efi_loader/Kconfig

index a294ad769edb9eb35ad536ea5146af8bf155d59d..b8db8cd7961734f0764d783ce3572513ff1a38c3 100644 (file)
@@ -349,6 +349,13 @@ config BOOTSTD_BOOTCOMMAND
          standard boot does not support all of the features of distro boot
          yet.
 
+config BOOTMETH_GLOBAL
+       bool
+       help
+         Add support for global bootmeths. This feature is used by VBE and
+         EFI bootmgr, since they take full control over which bootdevs are
+         selected to boot.
+
 config BOOTMETH_DISTRO
        bool "Bootdev support for distro boot"
        select PXE_UTILS
index 1e276c0f26bbfc9090a9bc759f26d9e59e1876e1..88bbb32c47fbe19b015bcfd56d725f4cd6bd5313 100644 (file)
@@ -71,6 +71,20 @@ int bootmeth_read_file(struct udevice *dev, struct bootflow *bflow,
        return ops->read_file(dev, bflow, file_path, addr, sizep);
 }
 
+int bootmeth_get_bootflow(struct udevice *dev, struct bootflow *bflow)
+{
+       const struct bootmeth_ops *ops = bootmeth_get_ops(dev);
+
+       if (!ops->read_bootflow)
+               return -ENOSYS;
+       memset(bflow, '\0', sizeof(*bflow));
+       bflow->dev = NULL;
+       bflow->method = dev;
+       bflow->state = BOOTFLOWST_BASE;
+
+       return ops->read_bootflow(dev, bflow);
+}
+
 /**
  * bootmeth_setup_iter_order() - Set up the ordering of bootmeths to scan
  *
index a6914466db7031dcac312e2dd494efe86cb306b0..08d9328af4e83e13a48b23d21f7d45d137d2d262 100644 (file)
@@ -61,6 +61,7 @@ static int bootmeth_efi_mgr_bind(struct udevice *dev)
        struct bootmeth_uc_plat *plat = dev_get_uclass_plat(dev);
 
        plat->desc = "EFI bootmgr flow";
+       plat->flags = BOOTMETHF_GLOBAL;
 
        return 0;
 }
@@ -77,7 +78,7 @@ static const struct udevice_id efi_mgr_bootmeth_ids[] = {
        { }
 };
 
-U_BOOT_DRIVER(bootmeth_zefi_mgr) = {
+U_BOOT_DRIVER(bootmeth_efi_mgr) = {
        .name           = "bootmeth_efi_mgr",
        .id             = UCLASS_BOOTMETH,
        .of_match       = efi_mgr_bootmeth_ids,
index c9a27fe8ac685081bf473ef57ffec8d2f9334172..9fbcccdba7ef4ce1e18f80d4ac86e7eb69982c97 100644 (file)
@@ -69,7 +69,9 @@ static int do_bootmeth_list(struct cmd_tbl *cmdtp, int flag, int argc,
                        }
                }
 
-               if (order == -1)
+               if (ucp->flags & BOOTMETHF_GLOBAL)
+                       printf("%5s", "glob");
+               else if (order == -1)
                        printf("%5s", "-");
                else
                        printf("%5x", order);
index 4967031a0a8bdf6135032f43317c079cacba428b..c93367b0995fbe42d6f53164b958a044e13188e9 100644 (file)
@@ -12,13 +12,24 @@ struct bootflow;
 struct bootflow_iter;
 struct udevice;
 
+/**
+ * enum bootmeth_flags - Flags for bootmeths
+ *
+ * @BOOTMETHF_GLOBAL: bootmeth handles bootdev selection automatically
+ */
+enum bootmeth_flags {
+       BOOTMETHF_GLOBAL        = BIT(0),
+};
+
 /**
  * struct bootmeth_uc_plat - information the uclass keeps about each bootmeth
  *
  * @desc: A long description of the bootmeth
+ * @flags: Flags for this bootmeth (enum bootmeth_flags)
  */
 struct bootmeth_uc_plat {
        const char *desc;
+       int flags;
 };
 
 /** struct bootmeth_ops - Operations for boot methods */
@@ -267,4 +278,16 @@ int bootmeth_alloc_file(struct bootflow *bflow, uint size_limit, uint align);
 int bootmeth_common_read_file(struct udevice *dev, struct bootflow *bflow,
                              const char *file_path, ulong addr, ulong *sizep);
 
+/**
+ * bootmeth_get_bootflow() - Get a bootflow from a global bootmeth
+ *
+ * Check the bootmeth for a bootflow which can be used. In this case the
+ * bootmeth handles all bootdev selection, etc.
+ *
+ * @dev: bootmeth device to read from
+ * @bflow: Bootflow information
+ * @return 0 on success, -ve if a bootflow could not be found or had an error
+ */
+int bootmeth_get_bootflow(struct udevice *dev, struct bootflow *bflow);
+
 #endif
index e3f2402d0e8e4f7e60b45b89086d9846c15e26cf..5cfff8c56bc33ffc846f77590d71ea6b9102e175 100644 (file)
@@ -37,6 +37,7 @@ if EFI_LOADER
 config CMD_BOOTEFI_BOOTMGR
        bool "UEFI Boot Manager"
        default y
+       select BOOTMETH_GLOBAL if BOOTSTD
        help
          Select this option if you want to select the UEFI binary to be booted
          via UEFI variables Boot####, BootOrder, and BootNext. This enables the