Hi Heinrich,

On Mon, 21 Apr 2025 at 10:26, Heinrich Schuchardt
<heinrich.schucha...@canonical.com> wrote:
>
> Create a bootdev device for the EFI boot manager.
>
> Signed-off-by: Heinrich Schuchardt <heinrich.schucha...@canonical.com>
> ---
>  include/dm/uclass-id.h       |   1 +
>  lib/efi_loader/Makefile      |   1 +
>  lib/efi_loader/efi_bootdev.c | 102 +++++++++++++++++++++++++++++++++++
>  3 files changed, 104 insertions(+)
>  create mode 100644 lib/efi_loader/efi_bootdev.c
>
> diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
> index 270088ad94f..d0795c13d14 100644
> --- a/include/dm/uclass-id.h
> +++ b/include/dm/uclass-id.h
> @@ -59,6 +59,7 @@ enum uclass_id {
>         UCLASS_ECDSA,           /* Elliptic curve cryptographic device */
>         UCLASS_EFI_LOADER,      /* Devices created by UEFI applications */
>         UCLASS_EFI_MEDIA,       /* Devices provided by UEFI firmware */
> +       UCLASS_EFI_BOOT_MGR,    /* EFI boot manager */
>         UCLASS_ETH,             /* Ethernet device */
>         UCLASS_ETH_PHY,         /* Ethernet PHY device */
>         UCLASS_EXTCON,          /* External Connector Class */
> diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
> index ab50a69e48b..c37f05d70e4 100644
> --- a/lib/efi_loader/Makefile
> +++ b/lib/efi_loader/Makefile
> @@ -25,6 +25,7 @@ apps-$(CONFIG_BOOTEFI_TESTAPP_COMPILE) += testapp
>  obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o
>  obj-$(CONFIG_EFI_BOOTMGR) += efi_bootmgr.o
>  obj-$(CONFIG_EFI_BINARY_EXEC) += efi_bootbin.o
> +obj-$(CONFIG_BOOTMETH_EFI_BOOTMGR) += efi_bootdev.o
>  obj-y += efi_boottime.o
>  obj-y += efi_helper.o
>  obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o
> diff --git a/lib/efi_loader/efi_bootdev.c b/lib/efi_loader/efi_bootdev.c
> new file mode 100644
> index 00000000000..066df9462c8
> --- /dev/null
> +++ b/lib/efi_loader/efi_bootdev.c
> @@ -0,0 +1,102 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Bootdev for boot manager
> + *
> + * Copyright 2025, Heinrich Schuchardt <xypron.g...@gmx.de>
> + */
> +
> +#define LOG_CATEGORY UCLASS_BOOTSTD
> +
> +#include <bootdev.h>
> +#include <bootflow.h>
> +#include <dm.h>
> +#include <dm/lists.h>
> +
> +static int efi_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
> +                           struct bootflow *bflow)
> +{
> +       int ret;
> +
> +       ret = strcmp(iter->method->name, "efi_mgr");
> +       if (!ret)
> +               bflow->state = BOOTFLOWST_READY;
> +
> +       return ret;
> +}
> +
> +struct bootdev_ops efi_bootdev_ops = {
> +       .get_bootflow   = efi_get_bootflow,
> +};
> +
> +static int efi_bootdev_bind(struct udevice *dev)
> +{
> +       struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
> +
> +       ucp->prio = BOOTDEVP_6_EFI;
> +
> +       return 0;
> +}
> +
> +static const struct udevice_id efi_bootdev_ids[] = {
> +       { .compatible = "u-boot,bootdev-efi" },
> +       { }
> +};
> +
> +U_BOOT_DRIVER(efi_bootdev) = {
> +       .name           = "efi_bootdev",
> +       .id             = UCLASS_BOOTDEV,
> +       .ops            = &efi_bootdev_ops,
> +       .bind           = efi_bootdev_bind,
> +       .of_match       = efi_bootdev_ids,
> +};
> +
> +/**
> + * efi_bootdev_hunt() - find devices used by EFI boot manager
> + *
> + * Invoke all hunters that have not been invoked by now.
> + * This should only be the network hunter.
> + *
> + * @info:      info structure describing this hunter
> + * @show:      true to show information from the hunter
> + *
> + * Return:     0 if device found, -EINVAL otherwise
> + */
> +static int efi_bootdev_hunt(struct bootdev_hunter *info, bool show)
> +{
> +       return bootdev_hunt(NULL, 0);

This recursive calling of hunting is very strange. Since bootmgr seems
to need all the hunting to be done, you could move this line to
somewhere in bootmgr.

> +}
> +
> +BOOTDEV_HUNTER(efi_bootdev_hunt) = {
> +       .prio           = BOOTDEVP_6_EFI,
> +       .uclass         = UCLASS_EFI_BOOT_MGR,
> +       .hunt           = efi_bootdev_hunt,
> +       .drv            = DM_DRIVER_REF(efi_bootdev),
> +};
> +
> +static int efi_bootdev_create(void)
> +{
> +       int ret;
> +       struct udevice *dev_mgr;
> +       struct udevice *dev;
> +
> +       ret = device_bind_driver(gd->dm_root, "efimgr",
> +                                "efimgr", &dev_mgr);
> +       if (ret)
> +               return ret;
> +
> +       ret = device_bind_driver(dev_mgr, "efi_bootdev",
> +                                "efimgr.bootdev", &dev);
> +       return ret;
> +}
> +
> +EVENT_SPY_SIMPLE(EVT_DM_POST_INIT_R, efi_bootdev_create);
> +
> +U_BOOT_DRIVER(efimgr) = {
> +       .name           = "efimgr",
> +       .id             = UCLASS_EFI_BOOT_MGR,
> +};
> +
> +UCLASS_DRIVER(efimgr) = {
> +       .id             = UCLASS_EFI_BOOT_MGR,
> +       .name           = "efimgr",
> +};
> --
> 2.48.1
>

I am not seeing any tests in this series. At least we should update
the bootflow_efi() test or add something similar.

Regards,
SImon

Reply via email to