Merge tag 'efi-2020-07-rc3-2' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi
authorTom Rini <trini@konsulko.com>
Fri, 22 May 2020 14:27:24 +0000 (10:27 -0400)
committerTom Rini <trini@konsulko.com>
Fri, 22 May 2020 14:27:24 +0000 (10:27 -0400)
Pull request for UEFI sub-system for efi-2020-07-rc3 (2)

Problems fixed with these patches are:

* UEFI sub-system not working with virtio block devices
* Missing SATA support in UEFI sub-system
* A superfluous debug statement

cmd/efi.c
cmd/efidebug.c
include/efi.h
include/efi_api.h
include/efi_loader.h
lib/efi_loader/efi_device_path.c
lib/efi_loader/efi_device_path_to_text.c
lib/efi_loader/efi_disk.c
lib/efi_loader/efi_setup.c
lib/efi_loader/efi_variable.c

index 9aeb913..b3a3bf8 100644 (file)
--- a/cmd/efi.c
+++ b/cmd/efi.c
@@ -44,6 +44,7 @@ static struct attr_info {
        { EFI_MEMORY_NV, "non-volatile" },
        { EFI_MEMORY_MORE_RELIABLE, "higher reliability" },
        { EFI_MEMORY_RO, "read-only" },
+       { EFI_MEMORY_SP, "specific purpose" },
        { EFI_MEMORY_RUNTIME, "needs runtime mapping" }
 };
 
index 703dab0..32430e6 100644 (file)
@@ -414,6 +414,7 @@ static const struct efi_mem_attrs {
        {EFI_MEMORY_NV, "NV"},
        {EFI_MEMORY_MORE_RELIABLE, "REL"},
        {EFI_MEMORY_RO, "RO"},
+       {EFI_MEMORY_SP, "SP"},
        {EFI_MEMORY_RUNTIME, "RT"},
 };
 
index e12697a..f986aad 100644 (file)
@@ -196,6 +196,7 @@ enum efi_mem_type {
 #define EFI_MEMORY_MORE_RELIABLE \
                                ((u64)0x0000000000010000ULL)    /* higher reliability */
 #define EFI_MEMORY_RO          ((u64)0x0000000000020000ULL)    /* read-only */
+#define EFI_MEMORY_SP          ((u64)0x0000000000040000ULL)    /* specific-purpose memory (SPM) */
 #define EFI_MEMORY_RUNTIME     ((u64)0x8000000000000000ULL)    /* range requires runtime mapping */
 #define EFI_MEM_DESC_VERSION   1
 
index 77d6bf2..759d911 100644 (file)
@@ -457,6 +457,7 @@ struct efi_device_path_acpi_path {
 #  define DEVICE_PATH_SUB_TYPE_MSG_USB         0x05
 #  define DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR    0x0b
 #  define DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS   0x0f
+#  define DEVICE_PATH_SUB_TYPE_MSG_SATA                0x12
 #  define DEVICE_PATH_SUB_TYPE_MSG_NVME                0x17
 #  define DEVICE_PATH_SUB_TYPE_MSG_SD          0x1a
 #  define DEVICE_PATH_SUB_TYPE_MSG_MMC         0x1d
@@ -480,6 +481,13 @@ struct efi_device_path_usb {
        u8 usb_interface;
 } __packed;
 
+struct efi_device_path_sata {
+       struct efi_device_path dp;
+       u16 hba_port;
+       u16 port_multiplier_port;
+       u16 logical_unit_number;
+} __packed;
+
 struct efi_device_path_mac_addr {
        struct efi_device_path dp;
        struct efi_mac_addr mac;
index 4b48f99..9533df2 100644 (file)
@@ -45,6 +45,10 @@ static inline void *guidcpy(void *dst, const void *src)
 #define U_BOOT_HOST_DEV_GUID \
        EFI_GUID(0xbbe4e671, 0x5773, 0x4ea1, \
                 0x9a, 0xab, 0x3a, 0x7d, 0xbf, 0x40, 0xc4, 0x82)
+/* GUID used as root for virtio devices */
+#define U_BOOT_VIRTIO_DEV_GUID \
+       EFI_GUID(0x63293792, 0xadf5, 0x9325, \
+                0xb9, 0x9f, 0x4e, 0x0e, 0x45, 0x5c, 0x1b, 0x1e)
 
 /* Use internal device tree when starting UEFI application */
 #define EFI_FDT_USE_INTERNAL NULL
index 2b537c1..7ae14f3 100644 (file)
@@ -22,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 = {
@@ -455,6 +458,11 @@ __maybe_unused static unsigned int 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) +
@@ -470,6 +478,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_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);
                }
@@ -547,6 +565,23 @@ __maybe_unused 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 =
@@ -593,6 +628,22 @@ __maybe_unused 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 =
index 49bebb5..5ae4833 100644 (file)
@@ -149,6 +149,16 @@ static char *dp_msging(char *s, struct efi_device_path *dp)
 
                break;
        }
+       case DEVICE_PATH_SUB_TYPE_MSG_SATA: {
+               struct efi_device_path_sata *sdp =
+                       (struct efi_device_path_sata *) dp;
+
+               s += sprintf(s, "Sata(0x%x,0x%x,0x%x)",
+                            sdp->hba_port,
+                            sdp->port_multiplier_port,
+                            sdp->logical_unit_number);
+               break;
+       }
        case DEVICE_PATH_SUB_TYPE_MSG_NVME: {
                struct efi_device_path_nvme *ndp =
                        (struct efi_device_path_nvme *)dp;
index 9176008..670bf2b 100644 (file)
@@ -356,6 +356,7 @@ static efi_status_t efi_disk_add_dev(
                                struct efi_disk_obj **disk)
 {
        struct efi_disk_obj *diskobj;
+       struct efi_object *handle;
        efi_status_t ret;
 
        /* Don't add empty devices */
@@ -379,15 +380,25 @@ static efi_status_t efi_disk_add_dev(
                diskobj->dp = efi_dp_from_part(desc, part);
        }
        diskobj->part = part;
-       ret = efi_add_protocol(&diskobj->header, &efi_block_io_guid,
-                              &diskobj->ops);
-       if (ret != EFI_SUCCESS)
-               return ret;
-       ret = efi_add_protocol(&diskobj->header, &efi_guid_device_path,
-                              diskobj->dp);
+
+       /*
+        * Install the device path and the block IO protocol.
+        *
+        * InstallMultipleProtocolInterfaces() checks if the device path is
+        * already installed on an other handle and returns EFI_ALREADY_STARTED
+        * in this case.
+        */
+       handle = &diskobj->header;
+       ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
+                       &handle, &efi_guid_device_path, diskobj->dp,
+                       &efi_block_io_guid, &diskobj->ops, NULL));
        if (ret != EFI_SUCCESS)
                return ret;
-       /* partitions or whole disk without partitions */
+
+       /*
+        * On partitions or whole disks without partitions install the
+        * simple file system protocol if a file system is available.
+        */
        if ((part || desc->part_type == PART_TYPE_UNKNOWN) &&
            efi_fs_exists(desc, part)) {
                diskobj->volume = efi_simple_file_system(desc, part,
index 26a7423..dd0c53f 100644 (file)
@@ -135,6 +135,11 @@ efi_status_t efi_init_obj_list(void)
        /* On ARM switch from EL3 or secure mode to EL2 or non-secure mode */
        switch_to_non_secure_mode();
 
+       /* Initialize root node */
+       ret = efi_root_node_register();
+       if (ret != EFI_SUCCESS)
+               goto out;
+
 #ifdef CONFIG_PARTITIONS
        ret = efi_disk_register();
        if (ret != EFI_SUCCESS)
@@ -175,11 +180,6 @@ efi_status_t efi_init_obj_list(void)
        if (ret != EFI_SUCCESS)
                goto out;
 
-       /* Initialize root node */
-       ret = efi_root_node_register();
-       if (ret != EFI_SUCCESS)
-               goto out;
-
        /* Initialize EFI driver uclass */
        ret = efi_driver_init();
        if (ret != EFI_SUCCESS)
index fc7ae73..0a43db5 100644 (file)
@@ -886,8 +886,6 @@ static efi_status_t efi_set_variable_common(u16 *variable_name,
        u32 attr;
        efi_status_t ret = EFI_SUCCESS;
 
-       debug("%s: set '%s'\n", __func__, native_name);
-
        if (!variable_name || !*variable_name || !vendor ||
            ((attributes & EFI_VARIABLE_RUNTIME_ACCESS) &&
             !(attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS))) {