183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2bf19064bSHeinrich Schuchardt /*
3bf19064bSHeinrich Schuchardt  * efi_selftest_devicepath
4bf19064bSHeinrich Schuchardt  *
5bf19064bSHeinrich Schuchardt  * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de>
6bf19064bSHeinrich Schuchardt  *
7bf19064bSHeinrich Schuchardt  * This unit test checks the following protocol services:
8bf19064bSHeinrich Schuchardt  * DevicePathToText
9bf19064bSHeinrich Schuchardt  */
10bf19064bSHeinrich Schuchardt 
11bf19064bSHeinrich Schuchardt #include <efi_selftest.h>
12bf19064bSHeinrich Schuchardt 
13bf19064bSHeinrich Schuchardt static struct efi_boot_services *boottime;
14bf19064bSHeinrich Schuchardt 
15bf19064bSHeinrich Schuchardt static efi_handle_t handle1;
16bf19064bSHeinrich Schuchardt static efi_handle_t handle2;
17bf19064bSHeinrich Schuchardt static efi_handle_t handle3;
18bf19064bSHeinrich Schuchardt 
19bf19064bSHeinrich Schuchardt struct interface {
20bf19064bSHeinrich Schuchardt 	void (EFIAPI * inc)(void);
21bf19064bSHeinrich Schuchardt } interface;
22bf19064bSHeinrich Schuchardt 
23bf19064bSHeinrich Schuchardt static efi_guid_t guid_device_path = DEVICE_PATH_GUID;
24bf19064bSHeinrich Schuchardt 
25bf19064bSHeinrich Schuchardt static efi_guid_t guid_device_path_to_text_protocol =
26bf19064bSHeinrich Schuchardt 	EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID;
27bf19064bSHeinrich Schuchardt 
28bf19064bSHeinrich Schuchardt static efi_guid_t guid_protocol =
29bf19064bSHeinrich Schuchardt 	EFI_GUID(0xdbca4c98, 0x6cb0, 0x694d,
30bf19064bSHeinrich Schuchardt 		 0x08, 0x72, 0x81, 0x9c, 0x65, 0x0c, 0xbb, 0x7d);
31bf19064bSHeinrich Schuchardt 
32bf19064bSHeinrich Schuchardt static efi_guid_t guid_vendor1 =
33bf19064bSHeinrich Schuchardt 	EFI_GUID(0xdbca4c98, 0x6cb0, 0x694d,
34bf19064bSHeinrich Schuchardt 		 0x08, 0x72, 0x81, 0x9c, 0x65, 0x0c, 0xbb, 0xb1);
35bf19064bSHeinrich Schuchardt 
36bf19064bSHeinrich Schuchardt static efi_guid_t guid_vendor2 =
37bf19064bSHeinrich Schuchardt 	EFI_GUID(0xdbca4c98, 0x6cb0, 0x694d,
38bf19064bSHeinrich Schuchardt 		 0x08, 0x72, 0x81, 0x9c, 0x65, 0x0c, 0xbb, 0xa2);
39bf19064bSHeinrich Schuchardt 
40bf19064bSHeinrich Schuchardt static efi_guid_t guid_vendor3 =
41bf19064bSHeinrich Schuchardt 	EFI_GUID(0xdbca4c98, 0x6cb0, 0x694d,
42bf19064bSHeinrich Schuchardt 		 0x08, 0x72, 0x81, 0x9c, 0x65, 0x0c, 0xbb, 0xc3);
43bf19064bSHeinrich Schuchardt 
44bf19064bSHeinrich Schuchardt static u8 *dp1;
45bf19064bSHeinrich Schuchardt static u8 *dp2;
46bf19064bSHeinrich Schuchardt static u8 *dp3;
47bf19064bSHeinrich Schuchardt 
48bf19064bSHeinrich Schuchardt struct efi_device_path_to_text_protocol *device_path_to_text;
49bf19064bSHeinrich Schuchardt 
50bf19064bSHeinrich Schuchardt /*
51bf19064bSHeinrich Schuchardt  * Setup unit test.
52bf19064bSHeinrich Schuchardt  *
53bf19064bSHeinrich Schuchardt  * Create three handles. Install a new protocol on two of them and
54065a8ecaSHeinrich Schuchardt  * provide device paths.
55bf19064bSHeinrich Schuchardt  *
56bf19064bSHeinrich Schuchardt  * handle1
57bf19064bSHeinrich Schuchardt  *   guid interface
58bf19064bSHeinrich Schuchardt  * handle2
59bf19064bSHeinrich Schuchardt  *   guid interface
60bf19064bSHeinrich Schuchardt  * handle3
61bf19064bSHeinrich Schuchardt  *
62bf19064bSHeinrich Schuchardt  * @handle:	handle of the loaded image
63bf19064bSHeinrich Schuchardt  * @systable:	system table
64bf19064bSHeinrich Schuchardt  */
setup(const efi_handle_t img_handle,const struct efi_system_table * systable)65bf19064bSHeinrich Schuchardt static int setup(const efi_handle_t img_handle,
66bf19064bSHeinrich Schuchardt 		 const struct efi_system_table *systable)
67bf19064bSHeinrich Schuchardt {
68bf19064bSHeinrich Schuchardt 	struct efi_device_path_vendor vendor_node;
69bf19064bSHeinrich Schuchardt 	struct efi_device_path end_node;
70bf19064bSHeinrich Schuchardt 	efi_status_t ret;
71bf19064bSHeinrich Schuchardt 
72bf19064bSHeinrich Schuchardt 	boottime = systable->boottime;
73bf19064bSHeinrich Schuchardt 
74bf19064bSHeinrich Schuchardt 	ret = boottime->locate_protocol(&guid_device_path_to_text_protocol,
75bf19064bSHeinrich Schuchardt 					NULL, (void **)&device_path_to_text);
76bf19064bSHeinrich Schuchardt 	if (ret != EFI_SUCCESS) {
77bf19064bSHeinrich Schuchardt 		device_path_to_text = NULL;
78bf19064bSHeinrich Schuchardt 		efi_st_error(
79bf19064bSHeinrich Schuchardt 			"Device path to text protocol is not available.\n");
80bf19064bSHeinrich Schuchardt 		return EFI_ST_FAILURE;
81bf19064bSHeinrich Schuchardt 	}
82bf19064bSHeinrich Schuchardt 
83bf19064bSHeinrich Schuchardt 	ret = boottime->allocate_pool(EFI_LOADER_DATA,
84bf19064bSHeinrich Schuchardt 				      sizeof(struct efi_device_path_vendor) +
85bf19064bSHeinrich Schuchardt 				      sizeof(struct efi_device_path),
86bf19064bSHeinrich Schuchardt 				      (void **)&dp1);
87bf19064bSHeinrich Schuchardt 	if (ret != EFI_SUCCESS)
88bf19064bSHeinrich Schuchardt 		goto out_of_memory;
89bf19064bSHeinrich Schuchardt 
90bf19064bSHeinrich Schuchardt 	ret = boottime->allocate_pool(EFI_LOADER_DATA, 2 *
91bf19064bSHeinrich Schuchardt 				      sizeof(struct efi_device_path_vendor) +
92bf19064bSHeinrich Schuchardt 				      sizeof(struct efi_device_path),
93bf19064bSHeinrich Schuchardt 				      (void **)&dp2);
94bf19064bSHeinrich Schuchardt 	if (ret != EFI_SUCCESS)
95bf19064bSHeinrich Schuchardt 		goto out_of_memory;
96bf19064bSHeinrich Schuchardt 
97bf19064bSHeinrich Schuchardt 	ret = boottime->allocate_pool(EFI_LOADER_DATA, 3 *
98bf19064bSHeinrich Schuchardt 				      sizeof(struct efi_device_path_vendor) +
99bf19064bSHeinrich Schuchardt 				      sizeof(struct efi_device_path),
100bf19064bSHeinrich Schuchardt 				      (void **)&dp3);
101bf19064bSHeinrich Schuchardt 	if (ret != EFI_SUCCESS)
102bf19064bSHeinrich Schuchardt 		goto out_of_memory;
103bf19064bSHeinrich Schuchardt 
104bf19064bSHeinrich Schuchardt 	vendor_node.dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
105bf19064bSHeinrich Schuchardt 	vendor_node.dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR;
106bf19064bSHeinrich Schuchardt 	vendor_node.dp.length = sizeof(struct efi_device_path_vendor);
107bf19064bSHeinrich Schuchardt 
108bf19064bSHeinrich Schuchardt 	boottime->copy_mem(&vendor_node.guid, &guid_vendor1,
109bf19064bSHeinrich Schuchardt 			   sizeof(efi_guid_t));
110bf19064bSHeinrich Schuchardt 	boottime->copy_mem(dp1, &vendor_node,
111bf19064bSHeinrich Schuchardt 			   sizeof(struct efi_device_path_vendor));
112bf19064bSHeinrich Schuchardt 	boottime->copy_mem(dp2, &vendor_node,
113bf19064bSHeinrich Schuchardt 			   sizeof(struct efi_device_path_vendor));
114bf19064bSHeinrich Schuchardt 	boottime->copy_mem(dp3, &vendor_node,
115bf19064bSHeinrich Schuchardt 			   sizeof(struct efi_device_path_vendor));
116bf19064bSHeinrich Schuchardt 
117bf19064bSHeinrich Schuchardt 	boottime->copy_mem(&vendor_node.guid, &guid_vendor2,
118bf19064bSHeinrich Schuchardt 			   sizeof(efi_guid_t));
119bf19064bSHeinrich Schuchardt 	boottime->copy_mem(dp2 + sizeof(struct efi_device_path_vendor),
120bf19064bSHeinrich Schuchardt 			   &vendor_node, sizeof(struct efi_device_path_vendor));
121bf19064bSHeinrich Schuchardt 	boottime->copy_mem(dp3 + sizeof(struct efi_device_path_vendor),
122bf19064bSHeinrich Schuchardt 			   &vendor_node, sizeof(struct efi_device_path_vendor));
123bf19064bSHeinrich Schuchardt 
124bf19064bSHeinrich Schuchardt 	boottime->copy_mem(&vendor_node.guid, &guid_vendor3,
125bf19064bSHeinrich Schuchardt 			   sizeof(efi_guid_t));
126bf19064bSHeinrich Schuchardt 	boottime->copy_mem(dp3 + 2 * sizeof(struct efi_device_path_vendor),
127bf19064bSHeinrich Schuchardt 			   &vendor_node, sizeof(struct efi_device_path_vendor));
128bf19064bSHeinrich Schuchardt 
129bf19064bSHeinrich Schuchardt 	end_node.type = DEVICE_PATH_TYPE_END;
130bf19064bSHeinrich Schuchardt 	end_node.sub_type = DEVICE_PATH_SUB_TYPE_END;
131bf19064bSHeinrich Schuchardt 	end_node.length = sizeof(struct efi_device_path);
132bf19064bSHeinrich Schuchardt 	boottime->copy_mem(dp1 + sizeof(struct efi_device_path_vendor),
133bf19064bSHeinrich Schuchardt 			   &end_node, sizeof(struct efi_device_path));
134bf19064bSHeinrich Schuchardt 	boottime->copy_mem(dp2 + 2 * sizeof(struct efi_device_path_vendor),
135bf19064bSHeinrich Schuchardt 			   &end_node, sizeof(struct efi_device_path));
136bf19064bSHeinrich Schuchardt 	boottime->copy_mem(dp3 + 3 * sizeof(struct efi_device_path_vendor),
137bf19064bSHeinrich Schuchardt 			   &end_node, sizeof(struct efi_device_path));
138bf19064bSHeinrich Schuchardt 
139bf19064bSHeinrich Schuchardt 	ret = boottime->install_protocol_interface(&handle1,
140bf19064bSHeinrich Schuchardt 						   &guid_device_path,
141bf19064bSHeinrich Schuchardt 						   EFI_NATIVE_INTERFACE,
142bf19064bSHeinrich Schuchardt 						   dp1);
143bf19064bSHeinrich Schuchardt 	if (ret != EFI_SUCCESS) {
144bf19064bSHeinrich Schuchardt 		efi_st_error("InstallProtocolInterface failed\n");
145bf19064bSHeinrich Schuchardt 		return EFI_ST_FAILURE;
146bf19064bSHeinrich Schuchardt 	}
147bf19064bSHeinrich Schuchardt 	ret = boottime->install_protocol_interface(&handle1,
148bf19064bSHeinrich Schuchardt 						   &guid_protocol,
149bf19064bSHeinrich Schuchardt 						   EFI_NATIVE_INTERFACE,
150bf19064bSHeinrich Schuchardt 						   &interface);
151bf19064bSHeinrich Schuchardt 	if (ret != EFI_SUCCESS) {
152bf19064bSHeinrich Schuchardt 		efi_st_error("InstallProtocolInterface failed\n");
153bf19064bSHeinrich Schuchardt 		return EFI_ST_FAILURE;
154bf19064bSHeinrich Schuchardt 	}
155bf19064bSHeinrich Schuchardt 	ret = boottime->install_protocol_interface(&handle2,
156bf19064bSHeinrich Schuchardt 						   &guid_device_path,
157bf19064bSHeinrich Schuchardt 						   EFI_NATIVE_INTERFACE,
158bf19064bSHeinrich Schuchardt 						   dp2);
159bf19064bSHeinrich Schuchardt 	if (ret != EFI_SUCCESS) {
160bf19064bSHeinrich Schuchardt 		efi_st_error("InstallProtocolInterface failed\n");
161bf19064bSHeinrich Schuchardt 		return EFI_ST_FAILURE;
162bf19064bSHeinrich Schuchardt 	}
163bf19064bSHeinrich Schuchardt 	ret = boottime->install_protocol_interface(&handle2,
164bf19064bSHeinrich Schuchardt 						   &guid_protocol,
165bf19064bSHeinrich Schuchardt 						   EFI_NATIVE_INTERFACE,
166bf19064bSHeinrich Schuchardt 						   &interface);
167bf19064bSHeinrich Schuchardt 	if (ret != EFI_SUCCESS) {
168bf19064bSHeinrich Schuchardt 		efi_st_error("InstallProtocolInterface failed\n");
169bf19064bSHeinrich Schuchardt 		return EFI_ST_FAILURE;
170bf19064bSHeinrich Schuchardt 	}
171bf19064bSHeinrich Schuchardt 	ret = boottime->install_protocol_interface(&handle3,
172bf19064bSHeinrich Schuchardt 						   &guid_device_path,
173bf19064bSHeinrich Schuchardt 						   EFI_NATIVE_INTERFACE,
174bf19064bSHeinrich Schuchardt 						   dp3);
175bf19064bSHeinrich Schuchardt 	if (ret != EFI_SUCCESS) {
176bf19064bSHeinrich Schuchardt 		efi_st_error("InstallProtocolInterface failed\n");
177bf19064bSHeinrich Schuchardt 		return EFI_ST_FAILURE;
178bf19064bSHeinrich Schuchardt 	}
179bf19064bSHeinrich Schuchardt 	return EFI_ST_SUCCESS;
180bf19064bSHeinrich Schuchardt 
181bf19064bSHeinrich Schuchardt out_of_memory:
182bf19064bSHeinrich Schuchardt 	efi_st_error("Out of memory\n");
183bf19064bSHeinrich Schuchardt 	return EFI_ST_FAILURE;
184bf19064bSHeinrich Schuchardt }
185bf19064bSHeinrich Schuchardt 
186bf19064bSHeinrich Schuchardt /*
187bf19064bSHeinrich Schuchardt  * Tear down unit test.
188bf19064bSHeinrich Schuchardt  *
189bf19064bSHeinrich Schuchardt  */
teardown(void)190bf19064bSHeinrich Schuchardt static int teardown(void)
191bf19064bSHeinrich Schuchardt {
192bf19064bSHeinrich Schuchardt 	efi_status_t ret;
193bf19064bSHeinrich Schuchardt 
1948d7cf390SHeinrich Schuchardt 	ret = boottime->uninstall_protocol_interface(handle1,
195bf19064bSHeinrich Schuchardt 						     &guid_device_path,
196bf19064bSHeinrich Schuchardt 						     dp1);
1978d7cf390SHeinrich Schuchardt 	if (ret != EFI_SUCCESS) {
1988d7cf390SHeinrich Schuchardt 		efi_st_error("UninstallProtocolInterface failed\n");
1998d7cf390SHeinrich Schuchardt 		return EFI_ST_FAILURE;
2008d7cf390SHeinrich Schuchardt 	}
2018d7cf390SHeinrich Schuchardt 	ret = boottime->uninstall_protocol_interface(handle1,
202bf19064bSHeinrich Schuchardt 						     &guid_protocol,
203bf19064bSHeinrich Schuchardt 						     &interface);
2048d7cf390SHeinrich Schuchardt 	if (ret != EFI_SUCCESS) {
2058d7cf390SHeinrich Schuchardt 		efi_st_error("UninstallProtocolInterface failed\n");
2068d7cf390SHeinrich Schuchardt 		return EFI_ST_FAILURE;
2078d7cf390SHeinrich Schuchardt 	}
2088d7cf390SHeinrich Schuchardt 	ret = boottime->uninstall_protocol_interface(handle2,
209bf19064bSHeinrich Schuchardt 						     &guid_device_path,
210bf19064bSHeinrich Schuchardt 						     dp2);
2118d7cf390SHeinrich Schuchardt 	if (ret != EFI_SUCCESS) {
2128d7cf390SHeinrich Schuchardt 		efi_st_error("UninstallProtocolInterface failed\n");
2138d7cf390SHeinrich Schuchardt 		return EFI_ST_FAILURE;
2148d7cf390SHeinrich Schuchardt 	}
2158d7cf390SHeinrich Schuchardt 	ret = boottime->uninstall_protocol_interface(handle2,
216bf19064bSHeinrich Schuchardt 						     &guid_protocol,
217bf19064bSHeinrich Schuchardt 						     &interface);
2188d7cf390SHeinrich Schuchardt 	if (ret != EFI_SUCCESS) {
2198d7cf390SHeinrich Schuchardt 		efi_st_error("UninstallProtocolInterface failed\n");
2208d7cf390SHeinrich Schuchardt 		return EFI_ST_FAILURE;
2218d7cf390SHeinrich Schuchardt 	}
2228d7cf390SHeinrich Schuchardt 	ret = boottime->uninstall_protocol_interface(handle3,
223bf19064bSHeinrich Schuchardt 						     &guid_device_path,
224bf19064bSHeinrich Schuchardt 						     dp3);
2258d7cf390SHeinrich Schuchardt 	if (ret != EFI_SUCCESS) {
2268d7cf390SHeinrich Schuchardt 		efi_st_error("UninstallProtocolInterface failed\n");
2278d7cf390SHeinrich Schuchardt 		return EFI_ST_FAILURE;
2288d7cf390SHeinrich Schuchardt 	}
229bf19064bSHeinrich Schuchardt 	if (dp1) {
230bf19064bSHeinrich Schuchardt 		ret = boottime->free_pool(dp1);
231bf19064bSHeinrich Schuchardt 		if (ret != EFI_SUCCESS) {
232bf19064bSHeinrich Schuchardt 			efi_st_error("FreePool failed\n");
233bf19064bSHeinrich Schuchardt 			return EFI_ST_FAILURE;
234bf19064bSHeinrich Schuchardt 		}
235bf19064bSHeinrich Schuchardt 	}
236bf19064bSHeinrich Schuchardt 	if (dp2) {
237bf19064bSHeinrich Schuchardt 		ret = boottime->free_pool(dp2);
238bf19064bSHeinrich Schuchardt 		if (ret != EFI_SUCCESS) {
239bf19064bSHeinrich Schuchardt 			efi_st_error("FreePool failed\n");
240bf19064bSHeinrich Schuchardt 			return EFI_ST_FAILURE;
241bf19064bSHeinrich Schuchardt 		}
242bf19064bSHeinrich Schuchardt 	}
243bf19064bSHeinrich Schuchardt 	if (dp3) {
244bf19064bSHeinrich Schuchardt 		ret = boottime->free_pool(dp3);
245bf19064bSHeinrich Schuchardt 		if (ret != EFI_SUCCESS) {
246bf19064bSHeinrich Schuchardt 			efi_st_error("FreePool failed\n");
247bf19064bSHeinrich Schuchardt 			return EFI_ST_FAILURE;
248bf19064bSHeinrich Schuchardt 		}
249bf19064bSHeinrich Schuchardt 	}
250bf19064bSHeinrich Schuchardt 	return EFI_ST_SUCCESS;
251bf19064bSHeinrich Schuchardt }
252bf19064bSHeinrich Schuchardt 
253bf19064bSHeinrich Schuchardt /*
254bf19064bSHeinrich Schuchardt  * Execute unit test.
255bf19064bSHeinrich Schuchardt  *
256bf19064bSHeinrich Schuchardt  */
execute(void)257bf19064bSHeinrich Schuchardt static int execute(void)
258bf19064bSHeinrich Schuchardt {
259bf19064bSHeinrich Schuchardt 	struct efi_device_path *remaining_dp;
260*faea1041SHeinrich Schuchardt 	efi_handle_t handle;
261bf19064bSHeinrich Schuchardt 	/*
262bf19064bSHeinrich Schuchardt 	 * This device path node ends with the letter 't' of 'u-boot'.
263bf19064bSHeinrich Schuchardt 	 * The following '.bin' does not belong to the node but is
264bf19064bSHeinrich Schuchardt 	 * helps to test the correct truncation.
265bf19064bSHeinrich Schuchardt 	 */
266bf19064bSHeinrich Schuchardt 	struct {
267bf19064bSHeinrich Schuchardt 		struct efi_device_path dp;
268bf19064bSHeinrich Schuchardt 		u16 text[12];
269bf19064bSHeinrich Schuchardt 	} __packed dp_node = {
270bf19064bSHeinrich Schuchardt 			{ DEVICE_PATH_TYPE_MEDIA_DEVICE,
271bf19064bSHeinrich Schuchardt 			  DEVICE_PATH_SUB_TYPE_FILE_PATH,
272bf19064bSHeinrich Schuchardt 			  sizeof(struct efi_device_path) + 12},
273bf19064bSHeinrich Schuchardt 			L"u-boot.bin",
274bf19064bSHeinrich Schuchardt 		};
275bf19064bSHeinrich Schuchardt 	u16 *string;
276bf19064bSHeinrich Schuchardt 	efi_status_t ret;
277bf19064bSHeinrich Schuchardt 	efi_uintn_t i, no_handles;
278bf19064bSHeinrich Schuchardt 	efi_handle_t *handles;
279bf19064bSHeinrich Schuchardt 	struct efi_device_path *dp;
280bf19064bSHeinrich Schuchardt 
281bf19064bSHeinrich Schuchardt 	/* Display all available device paths */
282bf19064bSHeinrich Schuchardt 	ret = boottime->locate_handle_buffer(BY_PROTOCOL,
283bf19064bSHeinrich Schuchardt 					     &guid_device_path,
284bf19064bSHeinrich Schuchardt 					     NULL, &no_handles, &handles);
285bf19064bSHeinrich Schuchardt 	if (ret != EFI_SUCCESS) {
286bf19064bSHeinrich Schuchardt 		efi_st_error("Cannot retrieve device path protocols.\n");
287bf19064bSHeinrich Schuchardt 		return EFI_ST_FAILURE;
288bf19064bSHeinrich Schuchardt 	}
289bf19064bSHeinrich Schuchardt 
290bf19064bSHeinrich Schuchardt 	efi_st_printf("Installed device path protocols:\n");
291bf19064bSHeinrich Schuchardt 	for (i = 0; i < no_handles; ++i) {
292bf19064bSHeinrich Schuchardt 		ret = boottime->open_protocol(handles[i], &guid_device_path,
293bf19064bSHeinrich Schuchardt 					      (void **)&dp, NULL, NULL,
294bf19064bSHeinrich Schuchardt 					      EFI_OPEN_PROTOCOL_GET_PROTOCOL);
295bf19064bSHeinrich Schuchardt 		if (ret != EFI_SUCCESS) {
296bf19064bSHeinrich Schuchardt 			efi_st_error("Cannot open device path protocol.\n");
297bf19064bSHeinrich Schuchardt 			return EFI_ST_FAILURE;
298bf19064bSHeinrich Schuchardt 		}
299bf19064bSHeinrich Schuchardt 		string = device_path_to_text->convert_device_path_to_text(
300bf19064bSHeinrich Schuchardt 					dp, true, false);
301bf19064bSHeinrich Schuchardt 		if (!string) {
302bf19064bSHeinrich Schuchardt 			efi_st_error("ConvertDevicePathToText failed\n");
303bf19064bSHeinrich Schuchardt 			return EFI_ST_FAILURE;
304bf19064bSHeinrich Schuchardt 		}
305bf19064bSHeinrich Schuchardt 		efi_st_printf("%ps\n", string);
306bf19064bSHeinrich Schuchardt 		ret = boottime->free_pool(string);
307bf19064bSHeinrich Schuchardt 		if (ret != EFI_SUCCESS) {
308bf19064bSHeinrich Schuchardt 			efi_st_error("FreePool failed\n");
309bf19064bSHeinrich Schuchardt 			return EFI_ST_FAILURE;
310bf19064bSHeinrich Schuchardt 		}
3115be9744aSHeinrich Schuchardt 		/*
3125be9744aSHeinrich Schuchardt 		 * CloseProtocol cannot be called without agent handle.
3135be9744aSHeinrich Schuchardt 		 * There is no need to close the device path protocol.
3145be9744aSHeinrich Schuchardt 		 */
315bf19064bSHeinrich Schuchardt 	}
316bf19064bSHeinrich Schuchardt 	ret = boottime->free_pool(handles);
317bf19064bSHeinrich Schuchardt 	if (ret != EFI_SUCCESS) {
318bf19064bSHeinrich Schuchardt 		efi_st_error("FreePool failed\n");
319bf19064bSHeinrich Schuchardt 		return EFI_ST_FAILURE;
320bf19064bSHeinrich Schuchardt 	}
321bf19064bSHeinrich Schuchardt 
322bf19064bSHeinrich Schuchardt 	/* Test ConvertDevicePathToText */
323bf19064bSHeinrich Schuchardt 	string = device_path_to_text->convert_device_path_to_text(
324bf19064bSHeinrich Schuchardt 			(struct efi_device_path *)dp2, true, false);
325bf19064bSHeinrich Schuchardt 	if (!string) {
326bf19064bSHeinrich Schuchardt 		efi_st_error("ConvertDevicePathToText failed\n");
327bf19064bSHeinrich Schuchardt 		return EFI_ST_FAILURE;
328bf19064bSHeinrich Schuchardt 	}
329bf19064bSHeinrich Schuchardt 	if (efi_st_strcmp_16_8(
330bf19064bSHeinrich Schuchardt 		string,
331bf19064bSHeinrich Schuchardt 		"/VenHw(dbca4c98-6cb0-694d-0872-819c650cbbb1)/VenHw(dbca4c98-6cb0-694d-0872-819c650cbba2)")
332bf19064bSHeinrich Schuchardt 	    ) {
333003876d4SHeinrich Schuchardt 		efi_st_printf("dp2: %ps\n", string);
334bf19064bSHeinrich Schuchardt 		efi_st_error("Incorrect text from ConvertDevicePathToText\n");
335bf19064bSHeinrich Schuchardt 		return EFI_ST_FAILURE;
336bf19064bSHeinrich Schuchardt 	}
337bf19064bSHeinrich Schuchardt 	ret = boottime->free_pool(string);
338bf19064bSHeinrich Schuchardt 	if (ret != EFI_SUCCESS) {
339bf19064bSHeinrich Schuchardt 		efi_st_error("FreePool failed\n");
340bf19064bSHeinrich Schuchardt 		return EFI_ST_FAILURE;
341bf19064bSHeinrich Schuchardt 	}
342bf19064bSHeinrich Schuchardt 
343bf19064bSHeinrich Schuchardt 	/* Test ConvertDeviceNodeToText */
344bf19064bSHeinrich Schuchardt 	string = device_path_to_text->convert_device_node_to_text(
345bf19064bSHeinrich Schuchardt 			(struct efi_device_path *)&dp_node, true, false);
346bf19064bSHeinrich Schuchardt 	if (!string) {
347bf19064bSHeinrich Schuchardt 		efi_st_error("ConvertDeviceNodeToText failed\n");
348bf19064bSHeinrich Schuchardt 		return EFI_ST_FAILURE;
349bf19064bSHeinrich Schuchardt 	}
350003876d4SHeinrich Schuchardt 	if (efi_st_strcmp_16_8(string, "u-boot")) {
351bf19064bSHeinrich Schuchardt 		efi_st_printf("dp_node: %ps\n", string);
352003876d4SHeinrich Schuchardt 		efi_st_error(
353003876d4SHeinrich Schuchardt 			"Incorrect conversion by ConvertDeviceNodeToText\n");
354003876d4SHeinrich Schuchardt 		return EFI_ST_FAILURE;
355003876d4SHeinrich Schuchardt 	}
356bf19064bSHeinrich Schuchardt 	ret = boottime->free_pool(string);
357bf19064bSHeinrich Schuchardt 	if (ret != EFI_SUCCESS) {
358bf19064bSHeinrich Schuchardt 		efi_st_error("FreePool failed\n");
359bf19064bSHeinrich Schuchardt 		return EFI_ST_FAILURE;
360bf19064bSHeinrich Schuchardt 	}
361bf19064bSHeinrich Schuchardt 
362bf19064bSHeinrich Schuchardt 	/* Test LocateDevicePath */
363bf19064bSHeinrich Schuchardt 	remaining_dp = (struct efi_device_path *)dp3;
364bf19064bSHeinrich Schuchardt 	ret = boottime->locate_device_path(&guid_protocol, &remaining_dp,
365bf19064bSHeinrich Schuchardt 					   &handle);
366bf19064bSHeinrich Schuchardt 	if (ret != EFI_SUCCESS) {
367bf19064bSHeinrich Schuchardt 		efi_st_error("LocateDevicePath failed\n");
368bf19064bSHeinrich Schuchardt 		return EFI_ST_FAILURE;
369bf19064bSHeinrich Schuchardt 	}
370bf19064bSHeinrich Schuchardt 	if (handle != handle2) {
371bf19064bSHeinrich Schuchardt 		efi_st_error("LocateDevicePath returned wrong handle\n");
372bf19064bSHeinrich Schuchardt 		return EFI_ST_FAILURE;
373bf19064bSHeinrich Schuchardt 	}
374bf19064bSHeinrich Schuchardt 	string = device_path_to_text->convert_device_path_to_text(remaining_dp,
375bf19064bSHeinrich Schuchardt 								  true, false);
376bf19064bSHeinrich Schuchardt 	if (!string) {
377bf19064bSHeinrich Schuchardt 		efi_st_error("ConvertDevicePathToText failed\n");
378bf19064bSHeinrich Schuchardt 		return EFI_ST_FAILURE;
379bf19064bSHeinrich Schuchardt 	}
380bf19064bSHeinrich Schuchardt 	if (efi_st_strcmp_16_8(string,
381bf19064bSHeinrich Schuchardt 			       "/VenHw(dbca4c98-6cb0-694d-0872-819c650cbbc3)")
382bf19064bSHeinrich Schuchardt 	    ) {
383003876d4SHeinrich Schuchardt 		efi_st_printf("remaining device path: %ps\n", string);
384bf19064bSHeinrich Schuchardt 		efi_st_error("LocateDevicePath: wrong remaining device path\n");
385bf19064bSHeinrich Schuchardt 		return EFI_ST_FAILURE;
386bf19064bSHeinrich Schuchardt 	}
387003876d4SHeinrich Schuchardt 	ret = boottime->free_pool(string);
388003876d4SHeinrich Schuchardt 	if (ret != EFI_SUCCESS) {
389003876d4SHeinrich Schuchardt 		efi_st_error("FreePool failed\n");
390003876d4SHeinrich Schuchardt 		return EFI_ST_FAILURE;
391003876d4SHeinrich Schuchardt 	}
392bf19064bSHeinrich Schuchardt 
393bf19064bSHeinrich Schuchardt 	return EFI_ST_SUCCESS;
394bf19064bSHeinrich Schuchardt }
395bf19064bSHeinrich Schuchardt 
396bf19064bSHeinrich Schuchardt EFI_UNIT_TEST(devicepath) = {
397bf19064bSHeinrich Schuchardt 	.name = "device path",
398bf19064bSHeinrich Schuchardt 	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
399bf19064bSHeinrich Schuchardt 	.setup = setup,
400bf19064bSHeinrich Schuchardt 	.execute = execute,
401bf19064bSHeinrich Schuchardt 	.teardown = teardown,
402bf19064bSHeinrich Schuchardt };
403