Merge tag 'efi-2023-10-rc1-2' of https://source.denx.de/u-boot/custodians/u-boot-efi

Pull request efi-2023-10-rc1-2

UEFI:

* test: avoid function name 'setup' in capsule tests to not treat it as
  a fixture
* ensure that device paths for USB block devices are unique
* enable having multiple EFI_LOADER block devices
* use InstallMultipleProtocolInterfaces() in TCG protocol implementation to
  increase UEFI compliance
diff --git a/include/efi_api.h b/include/efi_api.h
index 55a4c98..8f5ef5f 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -579,6 +579,13 @@
 	u8 vendor_data[];
 } __packed;
 
+struct efi_device_path_udevice {
+	struct efi_device_path dp;
+	efi_guid_t guid;
+	int uclass_id;
+	int dev_number;
+} __packed;
+
 struct efi_device_path_controller {
 	struct efi_device_path dp;
 	u32 controller_number;
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 604fd76..b5fa0fe 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -662,10 +662,6 @@
 			       void **protocol_interface, void *agent_handle,
 			       void *controller_handle, uint32_t attributes);
 
-/* Delete protocol from a handle */
-efi_status_t efi_remove_protocol(const efi_handle_t handle,
-				 const efi_guid_t *protocol,
-				 void *protocol_interface);
 /* Install multiple protocol interfaces */
 efi_status_t EFIAPI
 efi_install_multiple_protocol_interfaces(efi_handle_t *handle, ...);
diff --git a/lib/efi_driver/efi_block_device.c b/lib/efi_driver/efi_block_device.c
index add00ee..e3abd90 100644
--- a/lib/efi_driver/efi_block_device.c
+++ b/lib/efi_driver/efi_block_device.c
@@ -124,10 +124,8 @@
 	struct efi_block_io *io = interface;
 	struct efi_blk_plat *plat;
 
-	devnum = blk_find_max_devnum(UCLASS_EFI_LOADER);
-	if (devnum == -ENODEV)
-		devnum = 0;
-	else if (devnum < 0)
+	devnum = blk_next_free_devnum(UCLASS_EFI_LOADER);
+	if (devnum < 0)
 		return EFI_OUT_OF_RESOURCES;
 
 	name = calloc(1, 18); /* strlen("efiblk#2147483648") + 1 */
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 2ca7359..052fe48 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -575,9 +575,9 @@
  *
  * Return: status code
  */
-efi_status_t efi_remove_protocol(const efi_handle_t handle,
-				 const efi_guid_t *protocol,
-				 void *protocol_interface)
+static efi_status_t efi_remove_protocol(const efi_handle_t handle,
+					const efi_guid_t *protocol,
+					void *protocol_interface)
 {
 	struct efi_handler *handler;
 	efi_status_t ret;
@@ -1357,18 +1357,11 @@
 			(efi_handle_t handle, const efi_guid_t *protocol,
 			 void *protocol_interface)
 {
-	struct efi_object *efiobj;
 	struct efi_handler *handler;
 	struct efi_open_protocol_info_item *item;
 	struct efi_open_protocol_info_item *pos;
 	efi_status_t r;
 
-	/* Check handle */
-	efiobj = efi_search_obj(handle);
-	if (!efiobj) {
-		r = EFI_INVALID_PARAMETER;
-		goto out;
-	}
 	/* Find the protocol on the handle */
 	r = efi_search_protocol(handle, protocol, &handler);
 	if (r != EFI_SUCCESS)
@@ -1376,7 +1369,7 @@
 	if (handler->protocol_interface != protocol_interface)
 		return EFI_NOT_FOUND;
 	/* Disconnect controllers */
-	r = efi_disconnect_all_drivers(efiobj, protocol, NULL);
+	r = efi_disconnect_all_drivers(handle, protocol, NULL);
 	if (r != EFI_SUCCESS) {
 		r = EFI_ACCESS_DENIED;
 		goto out;
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index 04ebb44..19e8861 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -10,6 +10,7 @@
 #include <common.h>
 #include <blk.h>
 #include <dm.h>
+#include <dm/root.h>
 #include <log.h>
 #include <net.h>
 #include <usb.h>
@@ -38,16 +39,6 @@
 	.length   = sizeof(END),
 };
 
-/* template ROOT node: */
-static const struct efi_device_path_vendor ROOT = {
-	.dp = {
-		.type     = DEVICE_PATH_TYPE_HARDWARE_DEVICE,
-		.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR,
-		.length   = sizeof(ROOT),
-	},
-	.guid = U_BOOT_GUID,
-};
-
 #if defined(CONFIG_MMC)
 /*
  * Determine if an MMC device is an SD card.
@@ -497,13 +488,12 @@
 __maybe_unused static unsigned int dp_size(struct udevice *dev)
 {
 	if (!dev || !dev->driver)
-		return sizeof(ROOT);
+		return sizeof(struct efi_device_path_udevice);
 
 	switch (device_get_uclass_id(dev)) {
 	case UCLASS_ROOT:
-	case UCLASS_SIMPLE_BUS:
 		/* stop traversing parents at this point: */
-		return sizeof(ROOT);
+		return sizeof(struct efi_device_path_udevice);
 	case UCLASS_ETH:
 		return dp_size(dev->parent) +
 			sizeof(struct efi_device_path_mac_addr);
@@ -582,8 +572,8 @@
 		return dp_size(dev->parent) +
 			sizeof(struct efi_device_path_usb);
 	default:
-		/* just skip over unknown classes: */
-		return dp_size(dev->parent);
+		return dp_size(dev->parent) +
+			sizeof(struct efi_device_path_udevice);
 	}
 }
 
@@ -600,13 +590,6 @@
 		return buf;
 
 	switch (device_get_uclass_id(dev)) {
-	case UCLASS_ROOT:
-	case UCLASS_SIMPLE_BUS: {
-		/* stop traversing parents at this point: */
-		struct efi_device_path_vendor *vdp = buf;
-		*vdp = ROOT;
-		return &vdp[1];
-	}
 #ifdef CONFIG_NETDEVICES
 	case UCLASS_ETH: {
 		struct efi_device_path_mac_addr *dp =
@@ -631,9 +614,7 @@
 			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_fill(buf, dev->parent);
 			dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
 			dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR;
 			dp->dp.length = sizeof(*dp) + 1;
@@ -649,9 +630,7 @@
 			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_fill(buf, dev->parent);
 			dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
 			dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR;
 			dp->dp.length = sizeof(*dp) + 1;
@@ -666,9 +645,7 @@
 			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_fill(buf, dev->parent);
 			dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
 			dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR;
 			dp->dp.length = sizeof(*dp) + 1;
@@ -811,11 +788,24 @@
 
 		return &udp[1];
 	}
-	default:
-		/* If the uclass driver is missing, this will show NULL */
-		log_debug("unhandled device class: %s (%s)\n", dev->name,
-			  dev_get_uclass_name(dev));
-		return dp_fill(buf, dev->parent);
+	default: {
+		struct efi_device_path_udevice *vdp;
+		enum uclass_id uclass_id = device_get_uclass_id(dev);
+
+		if (uclass_id == UCLASS_ROOT)
+			vdp = buf;
+		else
+			vdp = dp_fill(buf, dev->parent);
+
+		vdp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
+		vdp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR;
+		vdp->dp.length = sizeof(*vdp);
+		memcpy(&vdp->guid, &efi_u_boot_guid, sizeof(efi_guid_t));
+		vdp->uclass_id = uclass_id;
+		vdp->dev_number = dev->seq_;
+
+		return &vdp[1];
+	    }
 	}
 }
 
@@ -1052,14 +1042,12 @@
 {
 	void *buf, *pos;
 	struct efi_device_path_uart *uart;
-	size_t dpsize = sizeof(ROOT) + sizeof(*uart) + sizeof(END);
+	size_t dpsize = dp_size(dm_root()) + sizeof(*uart) + sizeof(END);
 
 	buf = efi_alloc(dpsize);
 	if (!buf)
 		return NULL;
-	pos = buf;
-	memcpy(pos, &ROOT, sizeof(ROOT));
-	pos += sizeof(ROOT);
+	pos = dp_fill(buf, dm_root());
 	uart = pos;
 	uart->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
 	uart->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_UART;
diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index a83ae7a..49f8a5e 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -1680,8 +1680,8 @@
 	if (!is_tcg2_protocol_installed())
 		return;
 
-	ret = efi_remove_protocol(efi_root, &efi_guid_tcg2_protocol,
-				  (void *)&efi_tcg2_protocol);
+	ret = efi_uninstall_multiple_protocol_interfaces(efi_root, &efi_guid_tcg2_protocol,
+							 &efi_tcg2_protocol, NULL);
 	if (ret != EFI_SUCCESS)
 		log_err("Failed to remove EFI TCG2 protocol\n");
 }
@@ -2507,8 +2507,8 @@
 		goto fail;
 	}
 
-	ret = efi_add_protocol(efi_root, &efi_guid_tcg2_protocol,
-			       (void *)&efi_tcg2_protocol);
+	ret = efi_install_multiple_protocol_interfaces(&efi_root, &efi_guid_tcg2_protocol,
+						       &efi_tcg2_protocol, NULL);
 	if (ret != EFI_SUCCESS) {
 		tcg2_uninit();
 		goto fail;
diff --git a/test/py/tests/test_efi_capsule/capsule_common.py b/test/py/tests/test_efi_capsule/capsule_common.py
index 9eef676..fc0d851 100644
--- a/test/py/tests/test_efi_capsule/capsule_common.py
+++ b/test/py/tests/test_efi_capsule/capsule_common.py
@@ -6,7 +6,7 @@
 
 from capsule_defs import CAPSULE_DATA_DIR, CAPSULE_INSTALL_DIR
 
-def setup(u_boot_console, disk_img, osindications):
+def capsule_setup(u_boot_console, disk_img, osindications):
     """setup the test
 
     Args:
diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py
index a3094c3..11bcdc2 100644
--- a/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py
+++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py
@@ -8,7 +8,7 @@
 
 import pytest
 from capsule_common import (
-    setup,
+    capsule_setup,
     init_content,
     place_capsule_file,
     exec_manual_update,
@@ -49,7 +49,7 @@
         disk_img = efi_capsule_data
         capsule_files = ['Test05']
         with u_boot_console.log.section('Test Case 1-a, before reboot'):
-            setup(u_boot_console, disk_img, '0x0000000000000004')
+            capsule_setup(u_boot_console, disk_img, '0x0000000000000004')
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             init_content(u_boot_console, '150000', 'u-boot.env.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)
@@ -81,7 +81,7 @@
         disk_img = efi_capsule_data
         capsule_files = ['Test04']
         with u_boot_console.log.section('Test Case 2-a, before reboot'):
-            setup(u_boot_console, disk_img, '0x0000000000000004')
+            capsule_setup(u_boot_console, disk_img, '0x0000000000000004')
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             init_content(u_boot_console, '150000', 'u-boot.env.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)
@@ -116,7 +116,7 @@
         disk_img = efi_capsule_data
         capsule_files = ['Test104']
         with u_boot_console.log.section('Test Case 3-a, before reboot'):
-            setup(u_boot_console, disk_img, '0x0000000000000004')
+            capsule_setup(u_boot_console, disk_img, '0x0000000000000004')
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             init_content(u_boot_console, '150000', 'u-boot.env.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)
@@ -165,7 +165,7 @@
         disk_img = efi_capsule_data
         capsule_files = ['Test105']
         with u_boot_console.log.section('Test Case 4-a, before reboot'):
-            setup(u_boot_console, disk_img, '0x0000000000000004')
+            capsule_setup(u_boot_console, disk_img, '0x0000000000000004')
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)
 
diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py
index 80d791e..a5b5c8a 100644
--- a/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py
+++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py
@@ -8,7 +8,7 @@
 
 import pytest
 from capsule_common import (
-    setup,
+    capsule_setup,
     init_content,
     place_capsule_file,
     exec_manual_update,
@@ -51,7 +51,7 @@
         disk_img = efi_capsule_data
         capsule_files = ['Test03']
         with u_boot_console.log.section('Test Case 1-a, before reboot'):
-            setup(u_boot_console, disk_img, '0x0000000000000004')
+            capsule_setup(u_boot_console, disk_img, '0x0000000000000004')
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             init_content(u_boot_console, '150000', 'u-boot.env.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)
@@ -83,7 +83,7 @@
         disk_img = efi_capsule_data
         capsule_files = ['Test01', 'Test02']
         with u_boot_console.log.section('Test Case 2-a, before reboot'):
-            setup(u_boot_console, disk_img, None)
+            capsule_setup(u_boot_console, disk_img, None)
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             init_content(u_boot_console, '150000', 'u-boot.env.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)
@@ -111,7 +111,7 @@
         disk_img = efi_capsule_data
         capsule_files = ['Test01', 'Test02']
         with u_boot_console.log.section('Test Case 3-a, before reboot'):
-            setup(u_boot_console, disk_img, '0x0000000000000004')
+            capsule_setup(u_boot_console, disk_img, '0x0000000000000004')
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             init_content(u_boot_console, '150000', 'u-boot.env.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)
@@ -157,7 +157,7 @@
         disk_img = efi_capsule_data
         capsule_files = ['Test101', 'Test102']
         with u_boot_console.log.section('Test Case 4-a, before reboot'):
-            setup(u_boot_console, disk_img, '0x0000000000000004')
+            capsule_setup(u_boot_console, disk_img, '0x0000000000000004')
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             init_content(u_boot_console, '150000', 'u-boot.env.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)
@@ -211,7 +211,7 @@
         disk_img = efi_capsule_data
         capsule_files = ['Test103']
         with u_boot_console.log.section('Test Case 5-a, before reboot'):
-            setup(u_boot_console, disk_img, '0x0000000000000004')
+            capsule_setup(u_boot_console, disk_img, '0x0000000000000004')
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)
 
diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py
index 94d6c3e..44a58ba 100644
--- a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py
+++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py
@@ -11,7 +11,7 @@
 
 import pytest
 from capsule_common import (
-    setup,
+    capsule_setup,
     init_content,
     place_capsule_file,
     exec_manual_update,
@@ -47,7 +47,7 @@
         disk_img = efi_capsule_data
         capsule_files = ['Test13']
         with u_boot_console.log.section('Test Case 1-a, before reboot'):
-            setup(u_boot_console, disk_img, '0x0000000000000004')
+            capsule_setup(u_boot_console, disk_img, '0x0000000000000004')
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)
 
@@ -76,7 +76,7 @@
         disk_img = efi_capsule_data
         capsule_files = ['Test14']
         with u_boot_console.log.section('Test Case 2-a, before reboot'):
-            setup(u_boot_console, disk_img, '0x0000000000000004')
+            capsule_setup(u_boot_console, disk_img, '0x0000000000000004')
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)
 
@@ -107,7 +107,7 @@
         disk_img = efi_capsule_data
         capsule_files = ['Test02']
         with u_boot_console.log.section('Test Case 3-a, before reboot'):
-            setup(u_boot_console, disk_img, '0x0000000000000004')
+            capsule_setup(u_boot_console, disk_img, '0x0000000000000004')
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)
 
@@ -137,7 +137,7 @@
         disk_img = efi_capsule_data
         capsule_files = ['Test114']
         with u_boot_console.log.section('Test Case 4-a, before reboot'):
-            setup(u_boot_console, disk_img, '0x0000000000000004')
+            capsule_setup(u_boot_console, disk_img, '0x0000000000000004')
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)
 
@@ -176,7 +176,7 @@
         disk_img = efi_capsule_data
         capsule_files = ['Test115']
         with u_boot_console.log.section('Test Case 5-a, before reboot'):
-            setup(u_boot_console, disk_img, '0x0000000000000004')
+            capsule_setup(u_boot_console, disk_img, '0x0000000000000004')
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)
 
diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py
index ad2b1c6..83a10e1 100644
--- a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py
+++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py
@@ -9,7 +9,7 @@
 
 import pytest
 from capsule_common import (
-    setup,
+    capsule_setup,
     init_content,
     place_capsule_file,
     exec_manual_update,
@@ -44,7 +44,7 @@
         disk_img = efi_capsule_data
         capsule_files =  ['Test11']
         with u_boot_console.log.section('Test Case 1-a, before reboot'):
-            setup(u_boot_console, disk_img, '0x0000000000000004')
+            capsule_setup(u_boot_console, disk_img, '0x0000000000000004')
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)
 
@@ -72,7 +72,7 @@
         disk_img = efi_capsule_data
         capsule_files = ['Test12']
         with u_boot_console.log.section('Test Case 2-a, before reboot'):
-            setup(u_boot_console, disk_img, '0x0000000000000004')
+            capsule_setup(u_boot_console, disk_img, '0x0000000000000004')
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)
 
@@ -101,7 +101,7 @@
         disk_img = efi_capsule_data
         capsule_files = ['Test02']
         with u_boot_console.log.section('Test Case 3-a, before reboot'):
-            setup(u_boot_console, disk_img, '0x0000000000000004')
+            capsule_setup(u_boot_console, disk_img, '0x0000000000000004')
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)
 
@@ -131,7 +131,7 @@
         disk_img = efi_capsule_data
         capsule_files = ['Test111', 'Test112']
         with u_boot_console.log.section('Test Case 4-a, before reboot'):
-            setup(u_boot_console, disk_img, '0x0000000000000004')
+            capsule_setup(u_boot_console, disk_img, '0x0000000000000004')
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)
 
@@ -175,7 +175,7 @@
         disk_img = efi_capsule_data
         capsule_files = ['Test113']
         with u_boot_console.log.section('Test Case 5-a, before reboot'):
-            setup(u_boot_console, disk_img, '0x0000000000000004')
+            capsule_setup(u_boot_console, disk_img, '0x0000000000000004')
             init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old')
             place_capsule_file(u_boot_console, capsule_files)