Hi Heinrich,
This patch fixes my issue with am335x: EFI Grub works as expected now. чт, 17 июн. 2021 г. в 18:15, Heinrich Schuchardt <xypron.g...@gmx.de>: > > Up to now when devices became available after executing the UEFI > sub-system initialization where not available for EFI applications. > > With the patch block devices are added to the UEFI object list whenever > they are probed. > > Signed-off-by: Heinrich Schuchardt <xypron.g...@gmx.de> Tested-by: Matwey V. Kornilov <matwey.korni...@gmail.com> > --- > drivers/core/device.c | 7 +++ > include/efi_loader.h | 6 +++ > lib/efi_driver/Makefile | 1 + > lib/efi_driver/efi_dm_integration.c | 36 +++++++++++++++ > lib/efi_loader/efi_disk.c | 72 +++++++++++++++++------------ > 5 files changed, 93 insertions(+), 29 deletions(-) > create mode 100644 lib/efi_driver/efi_dm_integration.c > > diff --git a/drivers/core/device.c b/drivers/core/device.c > index cb960f8ec4..7355a5c2a9 100644 > --- a/drivers/core/device.c > +++ b/drivers/core/device.c > @@ -14,6 +14,7 @@ > #include <asm/global_data.h> > #include <asm/io.h> > #include <clk.h> > +#include <efi_loader.h> > #include <fdtdec.h> > #include <fdt_support.h> > #include <malloc.h> > @@ -579,6 +580,12 @@ int device_probe(struct udevice *dev) > if (dev->parent && device_get_uclass_id(dev) == UCLASS_PINCTRL) > pinctrl_select_state(dev, "default"); > > + if (CONFIG_IS_ENABLED(EFI_LOADER)) { > + ret = efi_post_probe_device(dev); > + if (ret) > + goto fail_uclass; > + } > + > return 0; > fail_uclass: > if (device_remove(dev, DM_REMOVE_NORMAL)) { > diff --git a/include/efi_loader.h b/include/efi_loader.h > index 0a9c82a257..78dd687913 100644 > --- a/include/efi_loader.h > +++ b/include/efi_loader.h > @@ -17,6 +17,7 @@ > #include <pe.h> > > struct blk_desc; > +struct udevice; > > static inline int guidcmp(const void *g1, const void *g2) > { > @@ -28,6 +29,9 @@ static inline void *guidcpy(void *dst, const void *src) > return memcpy(dst, src, sizeof(efi_guid_t)); > } > > +/* Called by device_probe() */ > +int efi_post_probe_device(struct udevice *dev); > + > /* No need for efi loader support in SPL */ > #if CONFIG_IS_ENABLED(EFI_LOADER) > > @@ -420,6 +424,8 @@ efi_status_t EFIAPI efi_convert_pointer(efi_uintn_t > debug_disposition, > void efi_carve_out_dt_rsv(void *fdt); > /* Called by bootefi to make console interface available */ > efi_status_t efi_console_register(void); > +/* Called when a block devices has been probed */ > +efi_status_t efi_block_device_register(struct udevice *dev); > /* Called by bootefi to make all disk storage accessible as EFI objects */ > efi_status_t efi_disk_register(void); > /* Called by efi_init_obj_list() to install EFI_RNG_PROTOCOL */ > diff --git a/lib/efi_driver/Makefile b/lib/efi_driver/Makefile > index 83baa1c9a4..f0d5fa5074 100644 > --- a/lib/efi_driver/Makefile > +++ b/lib/efi_driver/Makefile > @@ -5,6 +5,7 @@ > # This file only gets included with CONFIG_EFI_LOADER set, so all > # object inclusion implicitly depends on it > > +obj-y += efi_dm_integration.o > obj-y += efi_uclass.o > ifeq ($(CONFIG_BLK)$(CONFIG_PARTITIONS),yy) > obj-y += efi_block_device.o > diff --git a/lib/efi_driver/efi_dm_integration.c > b/lib/efi_driver/efi_dm_integration.c > new file mode 100644 > index 0000000000..9c6c339473 > --- /dev/null > +++ b/lib/efi_driver/efi_dm_integration.c > @@ -0,0 +1,36 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright 2021, Heinrich Schuchardt <xypron.g...@gmx.de> > + */ > + > +#define LOG_CATEGORY LOGC_EFI > + > +#include <common.h> > +#include <dm.h> > +#include <efi_loader.h> > +#include <log.h> > + > +/** > + * efi_post_probe_device() - set up handle for probed device > + * > + * This function is called by device_probe(). After the UEFI sub-system is > + * initialized this function adds handles for new devices. > + * > + * @dev: probed device > + * Return: 0 on success > + */ > +int efi_post_probe_device(struct udevice *dev) > +{ > + if (!dev || !dev->uclass) > + return -EINVAL; > + > + switch (dev->uclass->uc_drv->id) { > + case UCLASS_BLK: > + if (efi_block_device_register(dev) != EFI_SUCCESS) > + log_err("Failed to register %s\n", dev->name); > + default: > + break; > + } > + > + return 0; > +} > diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c > index 988907ecb9..b798cab345 100644 > --- a/lib/efi_loader/efi_disk.c > +++ b/lib/efi_loader/efi_disk.c > @@ -10,6 +10,7 @@ > #include <common.h> > #include <blk.h> > #include <dm.h> > +#include <dm/device-internal.h> > #include <efi_loader.h> > #include <fs.h> > #include <log.h> > @@ -535,6 +536,41 @@ int efi_disk_create_partitions(efi_handle_t parent, > struct blk_desc *desc, > return disks; > } > > +/** > + * efi_block_device_register() - register a block device in the UEFI > sub-system > + * > + * @dev: block device > + * Return: status code > + */ > +efi_status_t efi_block_device_register(struct udevice *dev) > +{ > + struct blk_desc *desc = dev_get_uclass_plat(dev); > + const char *if_typename = blk_get_if_type_name(desc->if_type); > + struct efi_disk_obj *disk; > + efi_status_t ret; > + > + /* Add block device for the full device */ > + ret = device_probe(dev); > + if (ret) > + return EFI_NOT_FOUND; > + log_info("Scanning disk %s...\n", dev->name); > + ret = efi_disk_add_dev(NULL, NULL, if_typename, > + desc, desc->devnum, NULL, 0, &disk); > + if (ret == EFI_NOT_READY) { > + log_notice("Disk %s not ready\n", dev->name); > + return ret; > + } else if (ret != EFI_SUCCESS) { > + log_err("ERROR: failure to add disk device %s, r = %lu\n", > + dev->name, ret & ~EFI_ERROR_MASK); > + return ret; > + } > + > + /* Partitions show up as block devices in EFI */ > + efi_disk_create_partitions(&disk->header, desc, if_typename, > + desc->devnum, dev->name); > + return ret; > +} > + > /** > * efi_disk_register() - register block devices > * > @@ -552,38 +588,16 @@ int efi_disk_create_partitions(efi_handle_t parent, > struct blk_desc *desc, > */ > efi_status_t efi_disk_register(void) > { > - struct efi_disk_obj *disk; > - int disks = 0; > - efi_status_t ret; > #ifdef CONFIG_BLK > struct udevice *dev; > - > + /* Probe all block devices */ > for (uclass_first_device_check(UCLASS_BLK, &dev); dev; > - uclass_next_device_check(&dev)) { > - struct blk_desc *desc = dev_get_uclass_plat(dev); > - const char *if_typename = blk_get_if_type_name(desc->if_type); > - > - /* Add block device for the full device */ > - log_info("Scanning disk %s...\n", dev->name); > - ret = efi_disk_add_dev(NULL, NULL, if_typename, > - desc, desc->devnum, NULL, 0, &disk); > - if (ret == EFI_NOT_READY) { > - log_notice("Disk %s not ready\n", dev->name); > - continue; > - } > - if (ret) { > - log_err("ERROR: failure to add disk device %s, r = > %lu\n", > - dev->name, ret & ~EFI_ERROR_MASK); > - return ret; > - } > - disks++; > - > - /* Partitions show up as block devices in EFI */ > - disks += efi_disk_create_partitions( > - &disk->header, desc, if_typename, > - desc->devnum, dev->name); > - } > + uclass_next_device_check(&dev)) > + ; > #else > + struct efi_disk_obj *disk; > + int disks = 0; > + efi_status_t ret; > int i, if_type; > > /* Search for all available disk devices */ > @@ -630,8 +644,8 @@ efi_status_t efi_disk_register(void) > if_typename, i, devname); > } > } > -#endif > log_info("Found %d disks\n", disks); > +#endif > > return EFI_SUCCESS; > } > -- > 2.30.2 > -- With best regards, Matwey V. Kornilov