efi_driver: create a parent device for all EFI block devices

Up to now root has been the parent device for all block devices created via
calling ConnectController(). This does not work well together with the
implementation of bootstd.

Add a dummy parent device for all EFI block devices.

With this change EFI block devices are also accessible via commands like
'cat', 'load', and 'ls'.

    => dm tree
     Class     Seq    Probed  Driver                Name
    -----------------------------------------------------------
     efi           0  [ + ]   EFI block driver      `-- efi
     blk           3  [ + ]   efi_blk                   `-- efi.efiblk#0
     partition     0  [ + ]   blk_partition                 `-- efi.efiblk#0:1

    => ls efiloader 0:1
           13   hello.txt
            7   u-boot.txt
    2 file(s), 0 dir(s)

    => cat efiloader 0:1 hello.txt
    Hello world!

    => efidebug dh
    0000000018df1700 (efi.efiblk#0:1)
      /VenHw(dbca4c98-6cb0-694d-0872-819c650cb7b8)/HD(1,MBR,0xd1535d21,0x1,0x7f)
      Block IO
      Simple File System

Adjust the event dump unit test to consider the new event spy.

Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
diff --git a/lib/efi_driver/efi_block_device.c b/lib/efi_driver/efi_block_device.c
index d3c668d..070747d 100644
--- a/lib/efi_driver/efi_block_device.c
+++ b/lib/efi_driver/efi_block_device.c
@@ -35,8 +35,10 @@
 #include <efi_driver.h>
 #include <malloc.h>
 #include <dm/device-internal.h>
+#include <dm/lists.h>
 #include <dm/root.h>
 #include <dm/tag.h>
+#include <dm/uclass-internal.h>
 
 /**
  * struct efi_blk_plat - attributes of a block device
@@ -118,13 +120,18 @@
 static efi_status_t
 efi_bl_create_block_device(efi_handle_t handle, void *interface)
 {
-	struct udevice *bdev = NULL, *parent = dm_root();
+	struct udevice *bdev = NULL, *parent;
 	efi_status_t ret;
+	int r;
 	int devnum;
 	char *name;
 	struct efi_block_io *io = interface;
 	struct efi_blk_plat *plat;
 
+	r = uclass_find_first_device(UCLASS_EFI_LOADER, &parent);
+	if (r)
+		return EFI_OUT_OF_RESOURCES;
+
 	devnum = blk_next_free_devnum(UCLASS_EFI_LOADER);
 	if (devnum < 0)
 		return EFI_OUT_OF_RESOURCES;
@@ -221,6 +228,24 @@
 	return EFI_SUCCESS;
 }
 
+/**
+ * efi_block_device_create() - create parent for EFI block devices
+ *
+ * Create a device that serves as parent for all block devices created via
+ * ConnectController().
+ *
+ * Return:	0 for success
+ */
+static int efi_block_device_create(void)
+{
+	int ret;
+	struct udevice *dev;
+
+	ret = device_bind_driver(gd->dm_root, "EFI block driver", "efi", &dev);
+
+	return ret;
+}
+
 /* Block device driver operators */
 static const struct blk_ops efi_blk_ops = {
 	.read	= efi_bl_read,
@@ -249,3 +274,5 @@
 	.id		= UCLASS_EFI_LOADER,
 	.ops		= &driver_ops,
 };
+
+EVENT_SPY_SIMPLE(EVT_LAST_STAGE_INIT, efi_block_device_create);
diff --git a/test/py/tests/test_event_dump.py b/test/py/tests/test_event_dump.py
index 45143c1..177b982 100644
--- a/test/py/tests/test_event_dump.py
+++ b/test/py/tests/test_event_dump.py
@@ -19,6 +19,7 @@
 EVT_FT_FIXUP          bootmeth_vbe_ft_fixup           .*boot/vbe_request.c:.*
 EVT_FT_FIXUP          bootmeth_vbe_simple_ft_fixup    .*boot/vbe_simple_os.c:.*
 EVT_LAST_STAGE_INIT   alloc_write_acpi_tables         .*lib/acpi/acpi_table.c:.*
+EVT_LAST_STAGE_INIT   efi_block_device_create         .*lib/efi_driver/efi_block_device.c:.*
 EVT_LAST_STAGE_INIT   install_smbios_table            .*lib/efi_loader/efi_smbios.c:.*
 EVT_MISC_INIT_F       sandbox_early_getopt_check      .*arch/sandbox/cpu/start.c:.*
 EVT_TEST              h_adder_simple                  .*test/common/event.c:'''