Create a distinct EFI device path for each blkmap device.

Signed-off-by: Tobias Waldekranz <tob...@waldekranz.com>
---
 include/efi_loader.h             |  4 ++++
 lib/efi_loader/efi_device_path.c | 30 ++++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/include/efi_loader.h b/include/efi_loader.h
index c664d6cdf2..eb3818b457 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -134,6 +134,10 @@ static inline efi_status_t efi_launch_capsules(void)
 #define U_BOOT_GUID \
        EFI_GUID(0xe61d73b9, 0xa384, 0x4acc, \
                 0xae, 0xab, 0x82, 0xe8, 0x28, 0xf3, 0x62, 0x8b)
+/* GUID used as root for blkmap devices */
+#define U_BOOT_BLKMAP_DEV_GUID \
+       EFI_GUID(0x4cad859d, 0xd644, 0x42ff,    \
+                0x87, 0x0b, 0xc0, 0x2e, 0xac, 0x05, 0x58, 0x63)
 /* GUID used as host device on sandbox */
 #define U_BOOT_HOST_DEV_GUID \
        EFI_GUID(0xbbe4e671, 0x5773, 0x4ea1, \
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index 3b267b713e..4b4c96bc2e 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -21,6 +21,9 @@
 #include <asm-generic/unaligned.h>
 #include <linux/compat.h> /* U16_MAX */
 
+#ifdef CONFIG_BLKMAP
+const efi_guid_t efi_guid_blkmap_dev = U_BOOT_BLKMAP_DEV_GUID;
+#endif
 #ifdef CONFIG_SANDBOX
 const efi_guid_t efi_guid_host_dev = U_BOOT_HOST_DEV_GUID;
 #endif
@@ -573,6 +576,16 @@ __maybe_unused static unsigned int dp_size(struct udevice 
*dev)
                          */
                        return dp_size(dev->parent)
                                + sizeof(struct efi_device_path_vendor) + 1;
+#endif
+#ifdef CONFIG_BLKMAP
+               case UCLASS_BLKMAP:
+                        /*
+                         * blkmap devices will be represented as a vendor
+                         * device node with an extra byte for the device
+                         * number.
+                         */
+                       return dp_size(dev->parent)
+                               + sizeof(struct efi_device_path_vendor) + 1;
 #endif
                default:
                        return dp_size(dev->parent);
@@ -631,6 +644,23 @@ __maybe_unused static void *dp_fill(void *buf, struct 
udevice *dev)
 #endif
        case UCLASS_BLK:
                switch (dev->parent->uclass->uc_drv->id) {
+#ifdef CONFIG_BLKMAP
+               case UCLASS_BLKMAP: {
+                       struct efi_device_path_vendor *dp;
+                       struct blk_desc *desc = dev_get_uclass_plat(dev);
+
+                       dp_fill(buf, dev->parent);
+                       dp = buf;
+                       ++dp;
+                       dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
+                       dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR;
+                       dp->dp.length = sizeof(*dp) + 1;
+                       memcpy(&dp->guid, &efi_guid_blkmap_dev,
+                              sizeof(efi_guid_t));
+                       dp->vendor_data[0] = desc->devnum;
+                       return &dp->vendor_data[1];
+                       }
+#endif
 #ifdef CONFIG_SANDBOX
                case UCLASS_HOST: {
                        /* stop traversing parents at this point: */
-- 
2.34.1

Reply via email to