summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2022-07-30 15:52:21 -0600
committerTom Rini <trini@konsulko.com>2022-08-12 08:17:10 -0400
commitbc06aa035d8f78a713a3d339d45f3d05ef0f0d67 (patch)
tree4869d2b427ae2bd73839b0d254f593fa3a51f744
parenta18686cda14cf0281a00fe1cd44c2647d351d4aa (diff)
downloadu-boot-bc06aa035d8f78a713a3d339d45f3d05ef0f0d67.tar.gz
u-boot-bc06aa035d8f78a713a3d339d45f3d05ef0f0d67.tar.bz2
u-boot-bc06aa035d8f78a713a3d339d45f3d05ef0f0d67.zip
bootstd: Allow bootmeths to be marked as global
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>
-rw-r--r--boot/Kconfig7
-rw-r--r--boot/bootmeth-uclass.c14
-rw-r--r--boot/bootmeth_efi_mgr.c3
-rw-r--r--cmd/bootmeth.c4
-rw-r--r--include/bootmeth.h23
-rw-r--r--lib/efi_loader/Kconfig1
6 files changed, 50 insertions, 2 deletions
diff --git a/boot/Kconfig b/boot/Kconfig
index a294ad769e..b8db8cd796 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -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
diff --git a/boot/bootmeth-uclass.c b/boot/bootmeth-uclass.c
index 1e276c0f26..88bbb32c47 100644
--- a/boot/bootmeth-uclass.c
+++ b/boot/bootmeth-uclass.c
@@ -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
*
diff --git a/boot/bootmeth_efi_mgr.c b/boot/bootmeth_efi_mgr.c
index a6914466db..08d9328af4 100644
--- a/boot/bootmeth_efi_mgr.c
+++ b/boot/bootmeth_efi_mgr.c
@@ -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,
diff --git a/cmd/bootmeth.c b/cmd/bootmeth.c
index c9a27fe8ac..9fbcccdba7 100644
--- a/cmd/bootmeth.c
+++ b/cmd/bootmeth.c
@@ -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);
diff --git a/include/bootmeth.h b/include/bootmeth.h
index 4967031a0a..c93367b099 100644
--- a/include/bootmeth.h
+++ b/include/bootmeth.h
@@ -13,12 +13,23 @@ 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
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index e3f2402d0e..5cfff8c56b 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -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