Merge tag 'u-boot-rockchip-20200522' of https://gitlab.denx.de/u-boot/custodians...
[oweals/u-boot.git] / lib / efi_loader / efi_device_path.c
index 17a0c5bb450cc6aef769c5866b722aaf9d389533..7ae14f342396ad2235e8b9b8edffb139d5451dc0 100644 (file)
@@ -8,6 +8,8 @@
 #include <common.h>
 #include <blk.h>
 #include <dm.h>
+#include <log.h>
+#include <net.h>
 #include <usb.h>
 #include <mmc.h>
 #include <nvme.h>
@@ -20,6 +22,9 @@
 #ifdef CONFIG_SANDBOX
 const efi_guid_t efi_guid_host_dev = U_BOOT_HOST_DEV_GUID;
 #endif
+#ifdef CONFIG_VIRTIO_BLK
+const efi_guid_t efi_guid_virtio_dev = U_BOOT_VIRTIO_DEV_GUID;
+#endif
 
 /* template END node: */
 static const struct efi_device_path END = {
@@ -422,7 +427,7 @@ bool efi_dp_is_multi_instance(const struct efi_device_path *dp)
 /* size of device-path not including END node for device and all parents
  * up to the root device.
  */
-static unsigned dp_size(struct udevice *dev)
+__maybe_unused static unsigned int dp_size(struct udevice *dev)
 {
        if (!dev || !dev->driver)
                return sizeof(ROOT);
@@ -453,6 +458,11 @@ static unsigned dp_size(struct udevice *dev)
                        return dp_size(dev->parent) +
                                sizeof(struct efi_device_path_sd_mmc_path);
 #endif
+#if defined(CONFIG_AHCI) || defined(CONFIG_SATA)
+               case UCLASS_AHCI:
+                       return dp_size(dev->parent) +
+                               sizeof(struct efi_device_path_sata);
+#endif
 #if defined(CONFIG_NVME)
                case UCLASS_NVME:
                        return dp_size(dev->parent) +
@@ -467,6 +477,16 @@ static unsigned dp_size(struct udevice *dev)
                          */
                        return dp_size(dev->parent)
                                + sizeof(struct efi_device_path_vendor) + 1;
+#endif
+#ifdef CONFIG_VIRTIO_BLK
+               case UCLASS_VIRTIO:
+                        /*
+                         * Virtio 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);
@@ -494,7 +514,7 @@ static unsigned dp_size(struct udevice *dev)
  * @dev                device
  * @return     pointer to the end of the device path
  */
-static void *dp_fill(void *buf, struct udevice *dev)
+__maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
 {
        if (!dev || !dev->driver)
                return buf;
@@ -530,7 +550,7 @@ static void *dp_fill(void *buf, struct udevice *dev)
 #ifdef CONFIG_SANDBOX
                case UCLASS_ROOT: {
                        /* stop traversing parents at this point: */
-                       struct efi_device_path_vendor *dp = buf;
+                       struct efi_device_path_vendor *dp;
                        struct blk_desc *desc = dev_get_uclass_platdata(dev);
 
                        dp_fill(buf, dev->parent);
@@ -545,6 +565,23 @@ static void *dp_fill(void *buf, struct udevice *dev)
                        return &dp->vendor_data[1];
                        }
 #endif
+#ifdef CONFIG_VIRTIO_BLK
+               case UCLASS_VIRTIO: {
+                       struct efi_device_path_vendor *dp;
+                       struct blk_desc *desc = dev_get_uclass_platdata(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_virtio_dev,
+                              sizeof(efi_guid_t));
+                       dp->vendor_data[0] = desc->devnum;
+                       return &dp->vendor_data[1];
+                       }
+#endif
 #ifdef CONFIG_IDE
                case UCLASS_IDE: {
                        struct efi_device_path_atapi *dp =
@@ -591,6 +628,22 @@ static void *dp_fill(void *buf, struct udevice *dev)
                        return &sddp[1];
                        }
 #endif
+#if defined(CONFIG_AHCI) || defined(CONFIG_SATA)
+               case UCLASS_AHCI: {
+                       struct efi_device_path_sata *dp =
+                               dp_fill(buf, dev->parent);
+                       struct blk_desc *desc = dev_get_uclass_platdata(dev);
+
+                       dp->dp.type     = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
+                       dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_SATA;
+                       dp->dp.length   = sizeof(*dp);
+                       dp->hba_port = desc->devnum;
+                       /* default 0xffff implies no port multiplier */
+                       dp->port_multiplier_port = 0xffff;
+                       dp->logical_unit_number = desc->lun;
+                       return &dp[1];
+                       }
+#endif
 #if defined(CONFIG_NVME)
                case UCLASS_NVME: {
                        struct efi_device_path_nvme *dp =
@@ -654,20 +707,6 @@ static void *dp_fill(void *buf, struct udevice *dev)
                return dp_fill(buf, dev->parent);
        }
 }
-
-/* Construct a device-path from a device: */
-struct efi_device_path *efi_dp_from_dev(struct udevice *dev)
-{
-       void *buf, *start;
-
-       start = buf = dp_alloc(dp_size(dev) + sizeof(END));
-       if (!buf)
-               return NULL;
-       buf = dp_fill(buf, dev);
-       *((struct efi_device_path *)buf) = END;
-
-       return start;
-}
 #endif
 
 static unsigned dp_part_size(struct blk_desc *desc, int part)
@@ -707,7 +746,7 @@ static unsigned dp_part_size(struct blk_desc *desc, int part)
  */
 static void *dp_part_node(void *buf, struct blk_desc *desc, int part)
 {
-       disk_partition_t info;
+       struct disk_partition info;
 
        part_get_info(desc, part, &info);
 
@@ -1049,7 +1088,7 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
 {
        int is_net;
        struct blk_desc *desc = NULL;
-       disk_partition_t fs_partition;
+       struct disk_partition fs_partition;
        int part = 0;
        char filename[32] = { 0 }; /* dp->str is u16[32] long */
        char *s;