mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-10-26 01:28:14 +00:00 
			
		
		
		
	Replace @return and @param. Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
		
			
				
	
	
		
			281 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			281 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| // SPDX-License-Identifier: GPL-2.0+
 | |
| /*
 | |
|  * efi_selftest_devicepath_util
 | |
|  *
 | |
|  * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
 | |
|  *
 | |
|  * This unit test checks the device path utilities protocol.
 | |
|  */
 | |
| 
 | |
| #include <efi_selftest.h>
 | |
| 
 | |
| static struct efi_boot_services *boottime;
 | |
| 
 | |
| static efi_guid_t guid_device_path_utilities_protocol =
 | |
| 	EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID;
 | |
| 
 | |
| struct efi_device_path_utilities_protocol *dpu;
 | |
| 
 | |
| /*
 | |
|  * Setup unit test.
 | |
|  *
 | |
|  * Locate the device path utilities protocol.
 | |
|  *
 | |
|  * @handle:	handle of the loaded image
 | |
|  * @systable:	system table
 | |
|  */
 | |
| static int setup(const efi_handle_t img_handle,
 | |
| 		 const struct efi_system_table *systable)
 | |
| {
 | |
| 	int ret;
 | |
| 
 | |
| 	boottime = systable->boottime;
 | |
| 
 | |
| 	ret = boottime->locate_protocol(&guid_device_path_utilities_protocol,
 | |
| 					NULL, (void **)&dpu);
 | |
| 	if (ret != EFI_SUCCESS) {
 | |
| 		dpu = NULL;
 | |
| 		efi_st_error(
 | |
| 			"Device path to text protocol is not available.\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 
 | |
| 	return EFI_ST_SUCCESS;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Create a device path consisting of a single media device node followed by an
 | |
|  * end node.
 | |
|  *
 | |
|  * @length:	length of the media device node
 | |
|  * @dp:		device path
 | |
|  * Return:	status code
 | |
|  */
 | |
| static int create_single_node_device_path(unsigned int length,
 | |
| 					  struct efi_device_path **dp)
 | |
| {
 | |
| 	struct efi_device_path *node;
 | |
| 	efi_uintn_t len;
 | |
| 	int ret;
 | |
| 
 | |
| 	node = dpu->create_device_node(DEVICE_PATH_TYPE_MEDIA_DEVICE,
 | |
| 				       DEVICE_PATH_SUB_TYPE_FILE_PATH, length);
 | |
| 	if (!node) {
 | |
| 		efi_st_error("CreateDeviceNode failed\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	*dp = dpu->append_device_node(NULL, node);
 | |
| 	if (!*dp) {
 | |
| 		efi_st_error("AppendDeviceNode failed\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	ret = boottime->free_pool(node);
 | |
| 	if (ret != EFI_ST_SUCCESS) {
 | |
| 		efi_st_error("FreePool failed\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	len = dpu->get_device_path_size(*dp);
 | |
| 	if (len != length + 4) {
 | |
| 		efi_st_error("Wrong device path length %u, expected %u\n",
 | |
| 			     (unsigned int)len, length);
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	return EFI_ST_SUCCESS;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Execute unit test.
 | |
|  *
 | |
|  * In the test device paths are created, copied, and concatenated. The device
 | |
|  * path length is used as a measure of success.
 | |
|  */
 | |
| static int execute(void)
 | |
| {
 | |
| 	struct efi_device_path *dp1;
 | |
| 	struct efi_device_path *dp2;
 | |
| 	struct efi_device_path *dp3;
 | |
| 
 | |
| 	efi_uintn_t len;
 | |
| 	int ret;
 | |
| 
 | |
| 	/* IsDevicePathMultiInstance(NULL) */
 | |
| 	if (dpu->is_device_path_multi_instance(NULL)) {
 | |
| 		efi_st_error("IsDevicePathMultiInstance(NULL) returned true\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	/* GetDevicePathSize(NULL) */
 | |
| 	len = dpu->get_device_path_size(NULL);
 | |
| 	if (len) {
 | |
| 		efi_st_error("Wrong device path length %u, expected 0\n",
 | |
| 			     (unsigned int)len);
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	/* DuplicateDevicePath(NULL) */
 | |
| 	dp1 = dpu->duplicate_device_path(NULL);
 | |
| 	if (dp1) {
 | |
| 		efi_st_error("DuplicateDevicePath(NULL) failed\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	/* AppendDevicePath(NULL, NULL) */
 | |
| 	dp1 = dpu->append_device_path(NULL, NULL);
 | |
| 	if (!dp1) {
 | |
| 		efi_st_error("AppendDevicePath(NULL, NULL) failed\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	len = dpu->get_device_path_size(dp1);
 | |
| 	if (len != 4) {
 | |
| 		efi_st_error("Wrong device path length %u, expected 4\n",
 | |
| 			     (unsigned int)len);
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	ret = boottime->free_pool(dp1);
 | |
| 	if (ret != EFI_ST_SUCCESS) {
 | |
| 		efi_st_error("FreePool failed\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	/* CreateDeviceNode */
 | |
| 	ret = create_single_node_device_path(21, &dp1);
 | |
| 	if (ret != EFI_ST_SUCCESS)
 | |
| 		return ret;
 | |
| 	ret = create_single_node_device_path(17, &dp2);
 | |
| 	if (ret != EFI_ST_SUCCESS)
 | |
| 		return ret;
 | |
| 	/* AppendDevicePath */
 | |
| 	dp3 = dpu->append_device_path(dp1, dp2);
 | |
| 	if (!dp3) {
 | |
| 		efi_st_error("AppendDevicePath failed\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	if (dp3 == dp1 || dp3 == dp2) {
 | |
| 		efi_st_error("AppendDevicePath reused buffer\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	len = dpu->get_device_path_size(dp3);
 | |
| 	/* 21 + 17 + 4 */
 | |
| 	if (len != 42) {
 | |
| 		efi_st_error("Wrong device path length %u, expected 42\n",
 | |
| 			     (unsigned int)len);
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	ret = boottime->free_pool(dp2);
 | |
| 	if (ret != EFI_ST_SUCCESS) {
 | |
| 		efi_st_error("FreePool failed\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	/* AppendDeviceNode */
 | |
| 	dp2 = dpu->append_device_node(dp1, dp3);
 | |
| 	if (!dp2) {
 | |
| 		efi_st_error("AppendDevicePath failed\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	len = dpu->get_device_path_size(dp2);
 | |
| 	/* 21 + 21 + 4 */
 | |
| 	if (len != 46) {
 | |
| 		printf("%s(%d) %s\n", __FILE__, __LINE__, __func__);
 | |
| 		efi_st_error("Wrong device path length %u, expected 46\n",
 | |
| 			     (unsigned int)len);
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	ret = boottime->free_pool(dp1);
 | |
| 	if (ret != EFI_ST_SUCCESS) {
 | |
| 		efi_st_error("FreePool failed\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	/* IsDevicePathMultiInstance */
 | |
| 	if (dpu->is_device_path_multi_instance(dp2)) {
 | |
| 		printf("%s(%d) %s\n", __FILE__, __LINE__, __func__);
 | |
| 		efi_st_error("IsDevicePathMultiInstance returned true\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	/* AppendDevicePathInstance */
 | |
| 	dp1 = dpu->append_device_path_instance(dp2, dp3);
 | |
| 	if (!dp1) {
 | |
| 		efi_st_error("AppendDevicePathInstance failed\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	len = dpu->get_device_path_size(dp1);
 | |
| 	/* 46 + 42 */
 | |
| 	if (len != 88) {
 | |
| 		efi_st_error("Wrong device path length %u, expected 88\n",
 | |
| 			     (unsigned int)len);
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	/* IsDevicePathMultiInstance */
 | |
| 	if (!dpu->is_device_path_multi_instance(dp1)) {
 | |
| 		efi_st_error("IsDevicePathMultiInstance returned false\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	ret = boottime->free_pool(dp2);
 | |
| 	if (ret != EFI_ST_SUCCESS) {
 | |
| 		efi_st_error("FreePool failed\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	ret = boottime->free_pool(dp3);
 | |
| 	if (ret != EFI_ST_SUCCESS) {
 | |
| 		efi_st_error("FreePool failed\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	/* GetNextDevicePathInstance */
 | |
| 	dp3 = dp1;
 | |
| 	dp2 = dpu->get_next_device_path_instance(&dp1, &len);
 | |
| 	if (!dp2) {
 | |
| 		efi_st_error("GetNextDevicePathInstance failed\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	if (!dp1) {
 | |
| 		efi_st_error("GetNextDevicePathInstance no 2nd instance\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	if (len != 46) {
 | |
| 		efi_st_error("Wrong device path length %u, expected 46\n",
 | |
| 			     (unsigned int)len);
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	len = dpu->get_device_path_size(dp1);
 | |
| 	if (len != 42) {
 | |
| 		efi_st_error("Wrong device path length %u, expected 42\n",
 | |
| 			     (unsigned int)len);
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	ret = boottime->free_pool(dp2);
 | |
| 	if (ret != EFI_ST_SUCCESS) {
 | |
| 		efi_st_error("FreePool failed\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	dp2 = dpu->get_next_device_path_instance(&dp1, &len);
 | |
| 	if (!dp2) {
 | |
| 		efi_st_error("GetNextDevicePathInstance failed\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	if (len != 42) {
 | |
| 		efi_st_error("Wrong device path length %u, expected 46\n",
 | |
| 			     (unsigned int)len);
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	if (dp1) {
 | |
| 		efi_st_error("GetNextDevicePathInstance did not signal end\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 
 | |
| 	/* Clean up */
 | |
| 	ret = boottime->free_pool(dp2);
 | |
| 	if (ret != EFI_ST_SUCCESS) {
 | |
| 		efi_st_error("FreePool failed\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 	ret = boottime->free_pool(dp3);
 | |
| 	if (ret != EFI_ST_SUCCESS) {
 | |
| 		efi_st_error("FreePool failed\n");
 | |
| 		return EFI_ST_FAILURE;
 | |
| 	}
 | |
| 
 | |
| 	return EFI_ST_SUCCESS;
 | |
| }
 | |
| 
 | |
| EFI_UNIT_TEST(dputil) = {
 | |
| 	.name = "device path utilities protocol",
 | |
| 	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
 | |
| 	.setup = setup,
 | |
| 	.execute = execute,
 | |
| };
 |