xref: /openbmc/u-boot/cmd/efidebug.c (revision 606b239a)
159df7e7eSAKASHI Takahiro // SPDX-License-Identifier: GPL-2.0+
259df7e7eSAKASHI Takahiro /*
359df7e7eSAKASHI Takahiro  *  UEFI Shell-like command
459df7e7eSAKASHI Takahiro  *
559df7e7eSAKASHI Takahiro  *  Copyright (c) 2018 AKASHI Takahiro, Linaro Limited
659df7e7eSAKASHI Takahiro  */
759df7e7eSAKASHI Takahiro 
859df7e7eSAKASHI Takahiro #include <charset.h>
959df7e7eSAKASHI Takahiro #include <common.h>
1059df7e7eSAKASHI Takahiro #include <command.h>
1159df7e7eSAKASHI Takahiro #include <efi_loader.h>
1259df7e7eSAKASHI Takahiro #include <environment.h>
1359df7e7eSAKASHI Takahiro #include <exports.h>
1459df7e7eSAKASHI Takahiro #include <malloc.h>
1559df7e7eSAKASHI Takahiro #include <search.h>
1659df7e7eSAKASHI Takahiro #include <linux/ctype.h>
1759df7e7eSAKASHI Takahiro 
18355cdb5aSAKASHI Takahiro #define BS systab.boottime
1959df7e7eSAKASHI Takahiro #define RT systab.runtime
2059df7e7eSAKASHI Takahiro 
2159df7e7eSAKASHI Takahiro /**
22355cdb5aSAKASHI Takahiro  * efi_get_device_handle_info() - get information of UEFI device
23355cdb5aSAKASHI Takahiro  *
24355cdb5aSAKASHI Takahiro  * @handle:		Handle of UEFI device
25355cdb5aSAKASHI Takahiro  * @dev_path_text:	Pointer to text of device path
26355cdb5aSAKASHI Takahiro  * Return:		0 on success, -1 on failure
27355cdb5aSAKASHI Takahiro  *
28355cdb5aSAKASHI Takahiro  * Currently return a formatted text of device path.
29355cdb5aSAKASHI Takahiro  */
efi_get_device_handle_info(efi_handle_t handle,u16 ** dev_path_text)30355cdb5aSAKASHI Takahiro static int efi_get_device_handle_info(efi_handle_t handle, u16 **dev_path_text)
31355cdb5aSAKASHI Takahiro {
32355cdb5aSAKASHI Takahiro 	struct efi_device_path *dp;
33355cdb5aSAKASHI Takahiro 	efi_status_t ret;
34355cdb5aSAKASHI Takahiro 
35355cdb5aSAKASHI Takahiro 	ret = EFI_CALL(BS->open_protocol(handle, &efi_guid_device_path,
36355cdb5aSAKASHI Takahiro 					 (void **)&dp, NULL /* FIXME */, NULL,
37355cdb5aSAKASHI Takahiro 					 EFI_OPEN_PROTOCOL_GET_PROTOCOL));
38355cdb5aSAKASHI Takahiro 	if (ret == EFI_SUCCESS) {
39355cdb5aSAKASHI Takahiro 		*dev_path_text = efi_dp_str(dp);
40355cdb5aSAKASHI Takahiro 		return 0;
41355cdb5aSAKASHI Takahiro 	} else {
42355cdb5aSAKASHI Takahiro 		return -1;
43355cdb5aSAKASHI Takahiro 	}
44355cdb5aSAKASHI Takahiro }
45355cdb5aSAKASHI Takahiro 
46355cdb5aSAKASHI Takahiro #define EFI_HANDLE_WIDTH ((int)sizeof(efi_handle_t) * 2)
47355cdb5aSAKASHI Takahiro 
48355cdb5aSAKASHI Takahiro static const char spc[] = "                ";
49355cdb5aSAKASHI Takahiro static const char sep[] = "================";
50355cdb5aSAKASHI Takahiro 
51355cdb5aSAKASHI Takahiro /**
52355cdb5aSAKASHI Takahiro  * do_efi_show_devices() - show UEFI devices
53355cdb5aSAKASHI Takahiro  *
54355cdb5aSAKASHI Takahiro  * @cmdtp:	Command table
55355cdb5aSAKASHI Takahiro  * @flag:	Command flag
56355cdb5aSAKASHI Takahiro  * @argc:	Number of arguments
57355cdb5aSAKASHI Takahiro  * @argv:	Argument array
58355cdb5aSAKASHI Takahiro  * Return:	CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
59355cdb5aSAKASHI Takahiro  *
60355cdb5aSAKASHI Takahiro  * Implement efidebug "devices" sub-command.
61355cdb5aSAKASHI Takahiro  * Show all UEFI devices and their information.
62355cdb5aSAKASHI Takahiro  */
do_efi_show_devices(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])63355cdb5aSAKASHI Takahiro static int do_efi_show_devices(cmd_tbl_t *cmdtp, int flag,
64355cdb5aSAKASHI Takahiro 			       int argc, char * const argv[])
65355cdb5aSAKASHI Takahiro {
66355cdb5aSAKASHI Takahiro 	efi_handle_t *handles;
67355cdb5aSAKASHI Takahiro 	efi_uintn_t num, i;
68355cdb5aSAKASHI Takahiro 	u16 *dev_path_text;
69355cdb5aSAKASHI Takahiro 	efi_status_t ret;
70355cdb5aSAKASHI Takahiro 
71355cdb5aSAKASHI Takahiro 	ret = EFI_CALL(BS->locate_handle_buffer(ALL_HANDLES, NULL, NULL,
72355cdb5aSAKASHI Takahiro 						&num, &handles));
73355cdb5aSAKASHI Takahiro 	if (ret != EFI_SUCCESS)
74355cdb5aSAKASHI Takahiro 		return CMD_RET_FAILURE;
75355cdb5aSAKASHI Takahiro 
76355cdb5aSAKASHI Takahiro 	if (!num)
77355cdb5aSAKASHI Takahiro 		return CMD_RET_SUCCESS;
78355cdb5aSAKASHI Takahiro 
79355cdb5aSAKASHI Takahiro 	printf("Device%.*s Device Path\n", EFI_HANDLE_WIDTH - 6, spc);
80355cdb5aSAKASHI Takahiro 	printf("%.*s ====================\n", EFI_HANDLE_WIDTH, sep);
81355cdb5aSAKASHI Takahiro 	for (i = 0; i < num; i++) {
82355cdb5aSAKASHI Takahiro 		if (!efi_get_device_handle_info(handles[i], &dev_path_text)) {
83355cdb5aSAKASHI Takahiro 			printf("%p %ls\n", handles[i], dev_path_text);
84355cdb5aSAKASHI Takahiro 			efi_free_pool(dev_path_text);
85355cdb5aSAKASHI Takahiro 		}
86355cdb5aSAKASHI Takahiro 	}
87355cdb5aSAKASHI Takahiro 
88355cdb5aSAKASHI Takahiro 	EFI_CALL(BS->free_pool(handles));
89355cdb5aSAKASHI Takahiro 
90355cdb5aSAKASHI Takahiro 	return CMD_RET_SUCCESS;
91355cdb5aSAKASHI Takahiro }
92355cdb5aSAKASHI Takahiro 
93355cdb5aSAKASHI Takahiro /**
9466eaf566SAKASHI Takahiro  * efi_get_driver_handle_info() - get information of UEFI driver
9566eaf566SAKASHI Takahiro  *
9666eaf566SAKASHI Takahiro  * @handle:		Handle of UEFI device
9766eaf566SAKASHI Takahiro  * @driver_name:	Driver name
9866eaf566SAKASHI Takahiro  * @image_path:		Pointer to text of device path
9966eaf566SAKASHI Takahiro  * Return:		0 on success, -1 on failure
10066eaf566SAKASHI Takahiro  *
10166eaf566SAKASHI Takahiro  * Currently return no useful information as all UEFI drivers are
10266eaf566SAKASHI Takahiro  * built-in..
10366eaf566SAKASHI Takahiro  */
efi_get_driver_handle_info(efi_handle_t handle,u16 ** driver_name,u16 ** image_path)10466eaf566SAKASHI Takahiro static int efi_get_driver_handle_info(efi_handle_t handle, u16 **driver_name,
10566eaf566SAKASHI Takahiro 				      u16 **image_path)
10666eaf566SAKASHI Takahiro {
10766eaf566SAKASHI Takahiro 	struct efi_handler *handler;
10866eaf566SAKASHI Takahiro 	struct efi_loaded_image *image;
10966eaf566SAKASHI Takahiro 	efi_status_t ret;
11066eaf566SAKASHI Takahiro 
11166eaf566SAKASHI Takahiro 	/*
11266eaf566SAKASHI Takahiro 	 * driver name
11366eaf566SAKASHI Takahiro 	 * TODO: support EFI_COMPONENT_NAME2_PROTOCOL
11466eaf566SAKASHI Takahiro 	 */
11566eaf566SAKASHI Takahiro 	*driver_name = NULL;
11666eaf566SAKASHI Takahiro 
11766eaf566SAKASHI Takahiro 	/* image name */
11866eaf566SAKASHI Takahiro 	ret = efi_search_protocol(handle, &efi_guid_loaded_image, &handler);
11966eaf566SAKASHI Takahiro 	if (ret != EFI_SUCCESS) {
12066eaf566SAKASHI Takahiro 		*image_path = NULL;
12166eaf566SAKASHI Takahiro 		return 0;
12266eaf566SAKASHI Takahiro 	}
12366eaf566SAKASHI Takahiro 
12466eaf566SAKASHI Takahiro 	image = handler->protocol_interface;
12566eaf566SAKASHI Takahiro 	*image_path = efi_dp_str(image->file_path);
12666eaf566SAKASHI Takahiro 
12766eaf566SAKASHI Takahiro 	return 0;
12866eaf566SAKASHI Takahiro }
12966eaf566SAKASHI Takahiro 
13066eaf566SAKASHI Takahiro /**
13166eaf566SAKASHI Takahiro  * do_efi_show_drivers() - show UEFI drivers
13266eaf566SAKASHI Takahiro  *
13366eaf566SAKASHI Takahiro  * @cmdtp:	Command table
13466eaf566SAKASHI Takahiro  * @flag:	Command flag
13566eaf566SAKASHI Takahiro  * @argc:	Number of arguments
13666eaf566SAKASHI Takahiro  * @argv:	Argument array
13766eaf566SAKASHI Takahiro  * Return:	CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
13866eaf566SAKASHI Takahiro  *
13966eaf566SAKASHI Takahiro  * Implement efidebug "drivers" sub-command.
14066eaf566SAKASHI Takahiro  * Show all UEFI drivers and their information.
14166eaf566SAKASHI Takahiro  */
do_efi_show_drivers(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])14266eaf566SAKASHI Takahiro static int do_efi_show_drivers(cmd_tbl_t *cmdtp, int flag,
14366eaf566SAKASHI Takahiro 			       int argc, char * const argv[])
14466eaf566SAKASHI Takahiro {
14566eaf566SAKASHI Takahiro 	efi_handle_t *handles;
14666eaf566SAKASHI Takahiro 	efi_uintn_t num, i;
14766eaf566SAKASHI Takahiro 	u16 *driver_name, *image_path_text;
14866eaf566SAKASHI Takahiro 	efi_status_t ret;
14966eaf566SAKASHI Takahiro 
15066eaf566SAKASHI Takahiro 	ret = EFI_CALL(BS->locate_handle_buffer(
15166eaf566SAKASHI Takahiro 				BY_PROTOCOL, &efi_guid_driver_binding_protocol,
15266eaf566SAKASHI Takahiro 				NULL, &num, &handles));
15366eaf566SAKASHI Takahiro 	if (ret != EFI_SUCCESS)
15466eaf566SAKASHI Takahiro 		return CMD_RET_FAILURE;
15566eaf566SAKASHI Takahiro 
15666eaf566SAKASHI Takahiro 	if (!num)
15766eaf566SAKASHI Takahiro 		return CMD_RET_SUCCESS;
15866eaf566SAKASHI Takahiro 
15966eaf566SAKASHI Takahiro 	printf("Driver%.*s Name                 Image Path\n",
16066eaf566SAKASHI Takahiro 	       EFI_HANDLE_WIDTH - 6, spc);
16166eaf566SAKASHI Takahiro 	printf("%.*s ==================== ====================\n",
16266eaf566SAKASHI Takahiro 	       EFI_HANDLE_WIDTH, sep);
16366eaf566SAKASHI Takahiro 	for (i = 0; i < num; i++) {
16466eaf566SAKASHI Takahiro 		if (!efi_get_driver_handle_info(handles[i], &driver_name,
16566eaf566SAKASHI Takahiro 						&image_path_text)) {
16666eaf566SAKASHI Takahiro 			if (image_path_text)
16766eaf566SAKASHI Takahiro 				printf("%p %-20ls %ls\n", handles[i],
16866eaf566SAKASHI Takahiro 				       driver_name, image_path_text);
16966eaf566SAKASHI Takahiro 			else
17066eaf566SAKASHI Takahiro 				printf("%p %-20ls <built-in>\n",
17166eaf566SAKASHI Takahiro 				       handles[i], driver_name);
17266eaf566SAKASHI Takahiro 			EFI_CALL(BS->free_pool(driver_name));
17366eaf566SAKASHI Takahiro 			EFI_CALL(BS->free_pool(image_path_text));
17466eaf566SAKASHI Takahiro 		}
17566eaf566SAKASHI Takahiro 	}
17666eaf566SAKASHI Takahiro 
17766eaf566SAKASHI Takahiro 	EFI_CALL(BS->free_pool(handles));
17866eaf566SAKASHI Takahiro 
17966eaf566SAKASHI Takahiro 	return CMD_RET_SUCCESS;
18066eaf566SAKASHI Takahiro }
18166eaf566SAKASHI Takahiro 
182a8014620SAKASHI Takahiro static const struct {
183a8014620SAKASHI Takahiro 	const char *text;
184a8014620SAKASHI Takahiro 	const efi_guid_t guid;
185a8014620SAKASHI Takahiro } guid_list[] = {
186a8014620SAKASHI Takahiro 	{
187a8014620SAKASHI Takahiro 		"Device Path",
188a8014620SAKASHI Takahiro 		DEVICE_PATH_GUID,
189a8014620SAKASHI Takahiro 	},
190a8014620SAKASHI Takahiro 	{
191a8014620SAKASHI Takahiro 		"Device Path To Text",
192a8014620SAKASHI Takahiro 		EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID,
193a8014620SAKASHI Takahiro 	},
194a8014620SAKASHI Takahiro 	{
195a8014620SAKASHI Takahiro 		"Device Path Utilities",
196a8014620SAKASHI Takahiro 		EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID,
197a8014620SAKASHI Takahiro 	},
198a8014620SAKASHI Takahiro 	{
199a8014620SAKASHI Takahiro 		"Unicode Collation 2",
200a8014620SAKASHI Takahiro 		EFI_UNICODE_COLLATION_PROTOCOL2_GUID,
201a8014620SAKASHI Takahiro 	},
202a8014620SAKASHI Takahiro 	{
203a8014620SAKASHI Takahiro 		"Driver Binding",
204a8014620SAKASHI Takahiro 		EFI_DRIVER_BINDING_PROTOCOL_GUID,
205a8014620SAKASHI Takahiro 	},
206a8014620SAKASHI Takahiro 	{
207a8014620SAKASHI Takahiro 		"Simple Text Input",
208a8014620SAKASHI Takahiro 		EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID,
209a8014620SAKASHI Takahiro 	},
210a8014620SAKASHI Takahiro 	{
211a8014620SAKASHI Takahiro 		"Simple Text Input Ex",
212a8014620SAKASHI Takahiro 		EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID,
213a8014620SAKASHI Takahiro 	},
214a8014620SAKASHI Takahiro 	{
215a8014620SAKASHI Takahiro 		"Simple Text Output",
216a8014620SAKASHI Takahiro 		EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID,
217a8014620SAKASHI Takahiro 	},
218a8014620SAKASHI Takahiro 	{
219a8014620SAKASHI Takahiro 		"Block IO",
220a8014620SAKASHI Takahiro 		BLOCK_IO_GUID,
221a8014620SAKASHI Takahiro 	},
222a8014620SAKASHI Takahiro 	{
223a8014620SAKASHI Takahiro 		"Simple File System",
224a8014620SAKASHI Takahiro 		EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID,
225a8014620SAKASHI Takahiro 	},
226a8014620SAKASHI Takahiro 	{
227a8014620SAKASHI Takahiro 		"Loaded Image",
228a8014620SAKASHI Takahiro 		LOADED_IMAGE_PROTOCOL_GUID,
229a8014620SAKASHI Takahiro 	},
230a8014620SAKASHI Takahiro 	{
231a8014620SAKASHI Takahiro 		"GOP",
232a8014620SAKASHI Takahiro 		EFI_GOP_GUID,
233a8014620SAKASHI Takahiro 	},
234a8014620SAKASHI Takahiro };
235a8014620SAKASHI Takahiro 
236a8014620SAKASHI Takahiro /**
237a8014620SAKASHI Takahiro  * get_guid_text - get string of protocol guid
238a8014620SAKASHI Takahiro  * @guid:	Protocol guid
239a8014620SAKASHI Takahiro  * Return:	String
240a8014620SAKASHI Takahiro  *
241a8014620SAKASHI Takahiro  * Return string for display to represent the protocol.
242a8014620SAKASHI Takahiro  */
get_guid_text(const efi_guid_t * guid)243a8014620SAKASHI Takahiro static const char *get_guid_text(const efi_guid_t *guid)
244a8014620SAKASHI Takahiro {
245a8014620SAKASHI Takahiro 	int i;
246a8014620SAKASHI Takahiro 
247a8014620SAKASHI Takahiro 	for (i = 0; i < ARRAY_SIZE(guid_list); i++)
248a8014620SAKASHI Takahiro 		if (!guidcmp(&guid_list[i].guid, guid))
249a8014620SAKASHI Takahiro 			break;
250a8014620SAKASHI Takahiro 
251a8014620SAKASHI Takahiro 	if (i != ARRAY_SIZE(guid_list))
252a8014620SAKASHI Takahiro 		return guid_list[i].text;
253a8014620SAKASHI Takahiro 	else
254a8014620SAKASHI Takahiro 		return NULL;
255a8014620SAKASHI Takahiro }
256a8014620SAKASHI Takahiro 
257a8014620SAKASHI Takahiro /**
258a8014620SAKASHI Takahiro  * do_efi_show_handles() - show UEFI handles
259a8014620SAKASHI Takahiro  *
260a8014620SAKASHI Takahiro  * @cmdtp:	Command table
261a8014620SAKASHI Takahiro  * @flag:	Command flag
262a8014620SAKASHI Takahiro  * @argc:	Number of arguments
263a8014620SAKASHI Takahiro  * @argv:	Argument array
264a8014620SAKASHI Takahiro  * Return:	CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
265a8014620SAKASHI Takahiro  *
266a8014620SAKASHI Takahiro  * Implement efidebug "dh" sub-command.
267a8014620SAKASHI Takahiro  * Show all UEFI handles and their information, currently all protocols
268a8014620SAKASHI Takahiro  * added to handle.
269a8014620SAKASHI Takahiro  */
do_efi_show_handles(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])270a8014620SAKASHI Takahiro static int do_efi_show_handles(cmd_tbl_t *cmdtp, int flag,
271a8014620SAKASHI Takahiro 			       int argc, char * const argv[])
272a8014620SAKASHI Takahiro {
273a8014620SAKASHI Takahiro 	efi_handle_t *handles;
274a8014620SAKASHI Takahiro 	efi_guid_t **guid;
275a8014620SAKASHI Takahiro 	efi_uintn_t num, count, i, j;
276a8014620SAKASHI Takahiro 	const char *guid_text;
277a8014620SAKASHI Takahiro 	efi_status_t ret;
278a8014620SAKASHI Takahiro 
279a8014620SAKASHI Takahiro 	ret = EFI_CALL(BS->locate_handle_buffer(ALL_HANDLES, NULL, NULL,
280a8014620SAKASHI Takahiro 						&num, &handles));
281a8014620SAKASHI Takahiro 	if (ret != EFI_SUCCESS)
282a8014620SAKASHI Takahiro 		return CMD_RET_FAILURE;
283a8014620SAKASHI Takahiro 
284a8014620SAKASHI Takahiro 	if (!num)
285a8014620SAKASHI Takahiro 		return CMD_RET_SUCCESS;
286a8014620SAKASHI Takahiro 
287a8014620SAKASHI Takahiro 	printf("Handle%.*s Protocols\n", EFI_HANDLE_WIDTH - 6, spc);
288a8014620SAKASHI Takahiro 	printf("%.*s ====================\n", EFI_HANDLE_WIDTH, sep);
289a8014620SAKASHI Takahiro 	for (i = 0; i < num; i++) {
290a8014620SAKASHI Takahiro 		printf("%p", handles[i]);
291a8014620SAKASHI Takahiro 		ret = EFI_CALL(BS->protocols_per_handle(handles[i], &guid,
292a8014620SAKASHI Takahiro 							&count));
293a8014620SAKASHI Takahiro 		if (ret || !count) {
294a8014620SAKASHI Takahiro 			putc('\n');
295a8014620SAKASHI Takahiro 			continue;
296a8014620SAKASHI Takahiro 		}
297a8014620SAKASHI Takahiro 
298a8014620SAKASHI Takahiro 		for (j = 0; j < count; j++) {
299a8014620SAKASHI Takahiro 			if (j)
300a8014620SAKASHI Takahiro 				printf(", ");
301a8014620SAKASHI Takahiro 			else
302a8014620SAKASHI Takahiro 				putc(' ');
303a8014620SAKASHI Takahiro 
304a8014620SAKASHI Takahiro 			guid_text = get_guid_text(guid[j]);
305a8014620SAKASHI Takahiro 			if (guid_text)
306a8014620SAKASHI Takahiro 				puts(guid_text);
307a8014620SAKASHI Takahiro 			else
308a8014620SAKASHI Takahiro 				printf("%pUl", guid[j]);
309a8014620SAKASHI Takahiro 		}
310a8014620SAKASHI Takahiro 		putc('\n');
311a8014620SAKASHI Takahiro 	}
312a8014620SAKASHI Takahiro 
313a8014620SAKASHI Takahiro 	EFI_CALL(BS->free_pool(handles));
314a8014620SAKASHI Takahiro 
315a8014620SAKASHI Takahiro 	return CMD_RET_SUCCESS;
316a8014620SAKASHI Takahiro }
317a8014620SAKASHI Takahiro 
31866eaf566SAKASHI Takahiro /**
319fa536734SAKASHI Takahiro  * do_efi_show_images() - show UEFI images
320fa536734SAKASHI Takahiro  *
321fa536734SAKASHI Takahiro  * @cmdtp:	Command table
322fa536734SAKASHI Takahiro  * @flag:	Command flag
323fa536734SAKASHI Takahiro  * @argc:	Number of arguments
324fa536734SAKASHI Takahiro  * @argv:	Argument array
325fa536734SAKASHI Takahiro  * Return:	CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
326fa536734SAKASHI Takahiro  *
327fa536734SAKASHI Takahiro  * Implement efidebug "images" sub-command.
328fa536734SAKASHI Takahiro  * Show all UEFI loaded images and their information.
329fa536734SAKASHI Takahiro  */
do_efi_show_images(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])330fa536734SAKASHI Takahiro static int do_efi_show_images(cmd_tbl_t *cmdtp, int flag,
331fa536734SAKASHI Takahiro 			      int argc, char * const argv[])
332fa536734SAKASHI Takahiro {
333fa536734SAKASHI Takahiro 	efi_print_image_infos(NULL);
334fa536734SAKASHI Takahiro 
335fa536734SAKASHI Takahiro 	return CMD_RET_SUCCESS;
336fa536734SAKASHI Takahiro }
337fa536734SAKASHI Takahiro 
33800358bb8SAKASHI Takahiro static const char * const efi_mem_type_string[] = {
33900358bb8SAKASHI Takahiro 	[EFI_RESERVED_MEMORY_TYPE] = "RESERVED",
34000358bb8SAKASHI Takahiro 	[EFI_LOADER_CODE] = "LOADER CODE",
34100358bb8SAKASHI Takahiro 	[EFI_LOADER_DATA] = "LOADER DATA",
34200358bb8SAKASHI Takahiro 	[EFI_BOOT_SERVICES_CODE] = "BOOT CODE",
34300358bb8SAKASHI Takahiro 	[EFI_BOOT_SERVICES_DATA] = "BOOT DATA",
34400358bb8SAKASHI Takahiro 	[EFI_RUNTIME_SERVICES_CODE] = "RUNTIME CODE",
34500358bb8SAKASHI Takahiro 	[EFI_RUNTIME_SERVICES_DATA] = "RUNTIME DATA",
34600358bb8SAKASHI Takahiro 	[EFI_CONVENTIONAL_MEMORY] = "CONVENTIONAL",
34700358bb8SAKASHI Takahiro 	[EFI_UNUSABLE_MEMORY] = "UNUSABLE MEM",
34800358bb8SAKASHI Takahiro 	[EFI_ACPI_RECLAIM_MEMORY] = "ACPI RECLAIM MEM",
34900358bb8SAKASHI Takahiro 	[EFI_ACPI_MEMORY_NVS] = "ACPI NVS",
35000358bb8SAKASHI Takahiro 	[EFI_MMAP_IO] = "IO",
35100358bb8SAKASHI Takahiro 	[EFI_MMAP_IO_PORT] = "IO PORT",
35200358bb8SAKASHI Takahiro 	[EFI_PAL_CODE] = "PAL",
35300358bb8SAKASHI Takahiro };
35400358bb8SAKASHI Takahiro 
35500358bb8SAKASHI Takahiro static const struct efi_mem_attrs {
35600358bb8SAKASHI Takahiro 	const u64 bit;
35700358bb8SAKASHI Takahiro 	const char *text;
35800358bb8SAKASHI Takahiro } efi_mem_attrs[] = {
35900358bb8SAKASHI Takahiro 	{EFI_MEMORY_UC, "UC"},
36000358bb8SAKASHI Takahiro 	{EFI_MEMORY_UC, "UC"},
36100358bb8SAKASHI Takahiro 	{EFI_MEMORY_WC, "WC"},
36200358bb8SAKASHI Takahiro 	{EFI_MEMORY_WT, "WT"},
36300358bb8SAKASHI Takahiro 	{EFI_MEMORY_WB, "WB"},
36400358bb8SAKASHI Takahiro 	{EFI_MEMORY_UCE, "UCE"},
36500358bb8SAKASHI Takahiro 	{EFI_MEMORY_WP, "WP"},
36600358bb8SAKASHI Takahiro 	{EFI_MEMORY_RP, "RP"},
36700358bb8SAKASHI Takahiro 	{EFI_MEMORY_XP, "WP"},
36800358bb8SAKASHI Takahiro 	{EFI_MEMORY_NV, "NV"},
36900358bb8SAKASHI Takahiro 	{EFI_MEMORY_MORE_RELIABLE, "REL"},
37000358bb8SAKASHI Takahiro 	{EFI_MEMORY_RO, "RO"},
37100358bb8SAKASHI Takahiro 	{EFI_MEMORY_RUNTIME, "RT"},
37200358bb8SAKASHI Takahiro };
37300358bb8SAKASHI Takahiro 
37400358bb8SAKASHI Takahiro /**
37500358bb8SAKASHI Takahiro  * print_memory_attributes() - print memory map attributes
37600358bb8SAKASHI Takahiro  * @attributes:	Attribute value
37700358bb8SAKASHI Takahiro  *
37800358bb8SAKASHI Takahiro  * Print memory map attributes
37900358bb8SAKASHI Takahiro  */
print_memory_attributes(u64 attributes)38000358bb8SAKASHI Takahiro static void print_memory_attributes(u64 attributes)
38100358bb8SAKASHI Takahiro {
38200358bb8SAKASHI Takahiro 	int sep, i;
38300358bb8SAKASHI Takahiro 
38400358bb8SAKASHI Takahiro 	for (sep = 0, i = 0; i < ARRAY_SIZE(efi_mem_attrs); i++)
38500358bb8SAKASHI Takahiro 		if (attributes & efi_mem_attrs[i].bit) {
38600358bb8SAKASHI Takahiro 			if (sep) {
38700358bb8SAKASHI Takahiro 				putc('|');
38800358bb8SAKASHI Takahiro 			} else {
38900358bb8SAKASHI Takahiro 				putc(' ');
39000358bb8SAKASHI Takahiro 				sep = 1;
39100358bb8SAKASHI Takahiro 			}
39200358bb8SAKASHI Takahiro 			puts(efi_mem_attrs[i].text);
39300358bb8SAKASHI Takahiro 		}
39400358bb8SAKASHI Takahiro }
39500358bb8SAKASHI Takahiro 
39600358bb8SAKASHI Takahiro #define EFI_PHYS_ADDR_WIDTH (int)(sizeof(efi_physical_addr_t) * 2)
39700358bb8SAKASHI Takahiro 
39800358bb8SAKASHI Takahiro /**
39900358bb8SAKASHI Takahiro  * do_efi_show_memmap() - show UEFI memory map
40000358bb8SAKASHI Takahiro  *
40100358bb8SAKASHI Takahiro  * @cmdtp:	Command table
40200358bb8SAKASHI Takahiro  * @flag:	Command flag
40300358bb8SAKASHI Takahiro  * @argc:	Number of arguments
40400358bb8SAKASHI Takahiro  * @argv:	Argument array
40500358bb8SAKASHI Takahiro  * Return:	CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
40600358bb8SAKASHI Takahiro  *
40700358bb8SAKASHI Takahiro  * Implement efidebug "memmap" sub-command.
40800358bb8SAKASHI Takahiro  * Show UEFI memory map.
40900358bb8SAKASHI Takahiro  */
do_efi_show_memmap(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])41000358bb8SAKASHI Takahiro static int do_efi_show_memmap(cmd_tbl_t *cmdtp, int flag,
41100358bb8SAKASHI Takahiro 			      int argc, char * const argv[])
41200358bb8SAKASHI Takahiro {
41300358bb8SAKASHI Takahiro 	struct efi_mem_desc *memmap = NULL, *map;
41400358bb8SAKASHI Takahiro 	efi_uintn_t map_size = 0;
41500358bb8SAKASHI Takahiro 	const char *type;
41600358bb8SAKASHI Takahiro 	int i;
41700358bb8SAKASHI Takahiro 	efi_status_t ret;
41800358bb8SAKASHI Takahiro 
41900358bb8SAKASHI Takahiro 	ret = EFI_CALL(BS->get_memory_map(&map_size, memmap, NULL, NULL, NULL));
42000358bb8SAKASHI Takahiro 	if (ret == EFI_BUFFER_TOO_SMALL) {
42100358bb8SAKASHI Takahiro 		map_size += sizeof(struct efi_mem_desc); /* for my own */
42200358bb8SAKASHI Takahiro 		ret = EFI_CALL(BS->allocate_pool(EFI_LOADER_DATA,
42300358bb8SAKASHI Takahiro 						 map_size, (void *)&memmap));
42400358bb8SAKASHI Takahiro 		if (ret != EFI_SUCCESS)
42500358bb8SAKASHI Takahiro 			return CMD_RET_FAILURE;
42600358bb8SAKASHI Takahiro 		ret = EFI_CALL(BS->get_memory_map(&map_size, memmap,
42700358bb8SAKASHI Takahiro 						  NULL, NULL, NULL));
42800358bb8SAKASHI Takahiro 	}
42900358bb8SAKASHI Takahiro 	if (ret != EFI_SUCCESS) {
43000358bb8SAKASHI Takahiro 		EFI_CALL(BS->free_pool(memmap));
43100358bb8SAKASHI Takahiro 		return CMD_RET_FAILURE;
43200358bb8SAKASHI Takahiro 	}
43300358bb8SAKASHI Takahiro 
43400358bb8SAKASHI Takahiro 	printf("Type             Start%.*s End%.*s Attributes\n",
43500358bb8SAKASHI Takahiro 	       EFI_PHYS_ADDR_WIDTH - 5, spc, EFI_PHYS_ADDR_WIDTH - 3, spc);
43600358bb8SAKASHI Takahiro 	printf("================ %.*s %.*s ==========\n",
43700358bb8SAKASHI Takahiro 	       EFI_PHYS_ADDR_WIDTH, sep, EFI_PHYS_ADDR_WIDTH, sep);
43800358bb8SAKASHI Takahiro 	for (i = 0, map = memmap; i < map_size / sizeof(*map); map++, i++) {
43900358bb8SAKASHI Takahiro 		if (map->type < EFI_MAX_MEMORY_TYPE)
44000358bb8SAKASHI Takahiro 			type = efi_mem_type_string[map->type];
44100358bb8SAKASHI Takahiro 		else
44200358bb8SAKASHI Takahiro 			type = "(unknown)";
44300358bb8SAKASHI Takahiro 
44400358bb8SAKASHI Takahiro 		printf("%-16s %.*llx-%.*llx", type,
44500358bb8SAKASHI Takahiro 		       EFI_PHYS_ADDR_WIDTH,
44600358bb8SAKASHI Takahiro 		       map->physical_start,
44700358bb8SAKASHI Takahiro 		       EFI_PHYS_ADDR_WIDTH,
44800358bb8SAKASHI Takahiro 		       map->physical_start + map->num_pages * EFI_PAGE_SIZE);
44900358bb8SAKASHI Takahiro 
45000358bb8SAKASHI Takahiro 		print_memory_attributes(map->attribute);
45100358bb8SAKASHI Takahiro 		putc('\n');
45200358bb8SAKASHI Takahiro 	}
45300358bb8SAKASHI Takahiro 
45400358bb8SAKASHI Takahiro 	EFI_CALL(BS->free_pool(memmap));
45500358bb8SAKASHI Takahiro 
45600358bb8SAKASHI Takahiro 	return CMD_RET_SUCCESS;
45700358bb8SAKASHI Takahiro }
45800358bb8SAKASHI Takahiro 
459fa536734SAKASHI Takahiro /**
46059df7e7eSAKASHI Takahiro  * do_efi_boot_add() - set UEFI load option
46159df7e7eSAKASHI Takahiro  *
46259df7e7eSAKASHI Takahiro  * @cmdtp:	Command table
46359df7e7eSAKASHI Takahiro  * @flag:	Command flag
46459df7e7eSAKASHI Takahiro  * @argc:	Number of arguments
46559df7e7eSAKASHI Takahiro  * @argv:	Argument array
46659df7e7eSAKASHI Takahiro  * Return:	CMD_RET_SUCCESS on success,
46759df7e7eSAKASHI Takahiro  *		CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
46859df7e7eSAKASHI Takahiro  *
46959df7e7eSAKASHI Takahiro  * Implement efidebug "boot add" sub-command.
47059df7e7eSAKASHI Takahiro  * Create or change UEFI load option.
47159df7e7eSAKASHI Takahiro  *   - boot add <id> <label> <interface> <devnum>[:<part>] <file> <options>
47259df7e7eSAKASHI Takahiro  */
do_efi_boot_add(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])47359df7e7eSAKASHI Takahiro static int do_efi_boot_add(cmd_tbl_t *cmdtp, int flag,
47459df7e7eSAKASHI Takahiro 			   int argc, char * const argv[])
47559df7e7eSAKASHI Takahiro {
47659df7e7eSAKASHI Takahiro 	int id;
47759df7e7eSAKASHI Takahiro 	char *endp;
47859df7e7eSAKASHI Takahiro 	char var_name[9];
47959df7e7eSAKASHI Takahiro 	u16 var_name16[9], *p;
48059df7e7eSAKASHI Takahiro 	efi_guid_t guid;
48159df7e7eSAKASHI Takahiro 	size_t label_len, label_len16;
48259df7e7eSAKASHI Takahiro 	u16 *label;
48359df7e7eSAKASHI Takahiro 	struct efi_device_path *device_path = NULL, *file_path = NULL;
48459df7e7eSAKASHI Takahiro 	struct efi_load_option lo;
48559df7e7eSAKASHI Takahiro 	void *data = NULL;
48659df7e7eSAKASHI Takahiro 	efi_uintn_t size;
48759df7e7eSAKASHI Takahiro 	int ret;
48859df7e7eSAKASHI Takahiro 
48959df7e7eSAKASHI Takahiro 	if (argc < 6 || argc > 7)
49059df7e7eSAKASHI Takahiro 		return CMD_RET_USAGE;
49159df7e7eSAKASHI Takahiro 
49259df7e7eSAKASHI Takahiro 	id = (int)simple_strtoul(argv[1], &endp, 16);
49359df7e7eSAKASHI Takahiro 	if (*endp != '\0' || id > 0xffff)
494*1fa442edSHeinrich Schuchardt 		return CMD_RET_USAGE;
49559df7e7eSAKASHI Takahiro 
49659df7e7eSAKASHI Takahiro 	sprintf(var_name, "Boot%04X", id);
49759df7e7eSAKASHI Takahiro 	p = var_name16;
49859df7e7eSAKASHI Takahiro 	utf8_utf16_strncpy(&p, var_name, 9);
49959df7e7eSAKASHI Takahiro 
50059df7e7eSAKASHI Takahiro 	guid = efi_global_variable_guid;
50159df7e7eSAKASHI Takahiro 
50259df7e7eSAKASHI Takahiro 	/* attributes */
50359df7e7eSAKASHI Takahiro 	lo.attributes = LOAD_OPTION_ACTIVE; /* always ACTIVE */
50459df7e7eSAKASHI Takahiro 
50559df7e7eSAKASHI Takahiro 	/* label */
50659df7e7eSAKASHI Takahiro 	label_len = strlen(argv[2]);
50759df7e7eSAKASHI Takahiro 	label_len16 = utf8_utf16_strnlen(argv[2], label_len);
50859df7e7eSAKASHI Takahiro 	label = malloc((label_len16 + 1) * sizeof(u16));
50959df7e7eSAKASHI Takahiro 	if (!label)
51059df7e7eSAKASHI Takahiro 		return CMD_RET_FAILURE;
51159df7e7eSAKASHI Takahiro 	lo.label = label; /* label will be changed below */
51259df7e7eSAKASHI Takahiro 	utf8_utf16_strncpy(&label, argv[2], label_len);
51359df7e7eSAKASHI Takahiro 
51459df7e7eSAKASHI Takahiro 	/* file path */
51559df7e7eSAKASHI Takahiro 	ret = efi_dp_from_name(argv[3], argv[4], argv[5], &device_path,
51659df7e7eSAKASHI Takahiro 			       &file_path);
51759df7e7eSAKASHI Takahiro 	if (ret != EFI_SUCCESS) {
51859df7e7eSAKASHI Takahiro 		printf("Cannot create device path for \"%s %s\"\n",
51959df7e7eSAKASHI Takahiro 		       argv[3], argv[4]);
52059df7e7eSAKASHI Takahiro 		ret = CMD_RET_FAILURE;
52159df7e7eSAKASHI Takahiro 		goto out;
52259df7e7eSAKASHI Takahiro 	}
52359df7e7eSAKASHI Takahiro 	lo.file_path = file_path;
52459df7e7eSAKASHI Takahiro 	lo.file_path_length = efi_dp_size(file_path)
52559df7e7eSAKASHI Takahiro 				+ sizeof(struct efi_device_path); /* for END */
52659df7e7eSAKASHI Takahiro 
52759df7e7eSAKASHI Takahiro 	/* optional data */
52859df7e7eSAKASHI Takahiro 	lo.optional_data = (u8 *)(argc == 6 ? "" : argv[6]);
52959df7e7eSAKASHI Takahiro 
53059df7e7eSAKASHI Takahiro 	size = efi_serialize_load_option(&lo, (u8 **)&data);
53159df7e7eSAKASHI Takahiro 	if (!size) {
53259df7e7eSAKASHI Takahiro 		ret = CMD_RET_FAILURE;
53359df7e7eSAKASHI Takahiro 		goto out;
53459df7e7eSAKASHI Takahiro 	}
53559df7e7eSAKASHI Takahiro 
53659df7e7eSAKASHI Takahiro 	ret = EFI_CALL(RT->set_variable(var_name16, &guid,
53759df7e7eSAKASHI Takahiro 					EFI_VARIABLE_BOOTSERVICE_ACCESS |
53859df7e7eSAKASHI Takahiro 					EFI_VARIABLE_RUNTIME_ACCESS,
53959df7e7eSAKASHI Takahiro 					size, data));
54059df7e7eSAKASHI Takahiro 	ret = (ret == EFI_SUCCESS ? CMD_RET_SUCCESS : CMD_RET_FAILURE);
54159df7e7eSAKASHI Takahiro out:
54259df7e7eSAKASHI Takahiro 	free(data);
54359df7e7eSAKASHI Takahiro 	efi_free_pool(device_path);
54459df7e7eSAKASHI Takahiro 	efi_free_pool(file_path);
54559df7e7eSAKASHI Takahiro 	free(lo.label);
54659df7e7eSAKASHI Takahiro 
54759df7e7eSAKASHI Takahiro 	return ret;
54859df7e7eSAKASHI Takahiro }
54959df7e7eSAKASHI Takahiro 
55059df7e7eSAKASHI Takahiro /**
55159df7e7eSAKASHI Takahiro  * do_efi_boot_rm() - delete UEFI load options
55259df7e7eSAKASHI Takahiro  *
55359df7e7eSAKASHI Takahiro  * @cmdtp:	Command table
55459df7e7eSAKASHI Takahiro  * @flag:	Command flag
55559df7e7eSAKASHI Takahiro  * @argc:	Number of arguments
55659df7e7eSAKASHI Takahiro  * @argv:	Argument array
55759df7e7eSAKASHI Takahiro  * Return:	CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
55859df7e7eSAKASHI Takahiro  *
55959df7e7eSAKASHI Takahiro  * Implement efidebug "boot rm" sub-command.
56059df7e7eSAKASHI Takahiro  * Delete UEFI load options.
56159df7e7eSAKASHI Takahiro  *   - boot rm <id> ...
56259df7e7eSAKASHI Takahiro  */
do_efi_boot_rm(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])56359df7e7eSAKASHI Takahiro static int do_efi_boot_rm(cmd_tbl_t *cmdtp, int flag,
56459df7e7eSAKASHI Takahiro 			  int argc, char * const argv[])
56559df7e7eSAKASHI Takahiro {
56659df7e7eSAKASHI Takahiro 	efi_guid_t guid;
56759df7e7eSAKASHI Takahiro 	int id, i;
56859df7e7eSAKASHI Takahiro 	char *endp;
56959df7e7eSAKASHI Takahiro 	char var_name[9];
57059df7e7eSAKASHI Takahiro 	u16 var_name16[9];
57159df7e7eSAKASHI Takahiro 	efi_status_t ret;
57259df7e7eSAKASHI Takahiro 
57359df7e7eSAKASHI Takahiro 	if (argc == 1)
57459df7e7eSAKASHI Takahiro 		return CMD_RET_USAGE;
57559df7e7eSAKASHI Takahiro 
57659df7e7eSAKASHI Takahiro 	guid = efi_global_variable_guid;
57759df7e7eSAKASHI Takahiro 	for (i = 1; i < argc; i++, argv++) {
57859df7e7eSAKASHI Takahiro 		id = (int)simple_strtoul(argv[1], &endp, 16);
57959df7e7eSAKASHI Takahiro 		if (*endp != '\0' || id > 0xffff)
58059df7e7eSAKASHI Takahiro 			return CMD_RET_FAILURE;
58159df7e7eSAKASHI Takahiro 
58259df7e7eSAKASHI Takahiro 		sprintf(var_name, "Boot%04X", id);
58359df7e7eSAKASHI Takahiro 		utf8_utf16_strncpy((u16 **)&var_name16, var_name, 9);
58459df7e7eSAKASHI Takahiro 
58559df7e7eSAKASHI Takahiro 		ret = EFI_CALL(RT->set_variable(var_name16, &guid, 0, 0, NULL));
58659df7e7eSAKASHI Takahiro 		if (ret) {
58759df7e7eSAKASHI Takahiro 			printf("cannot remove Boot%04X", id);
58859df7e7eSAKASHI Takahiro 			return CMD_RET_FAILURE;
58959df7e7eSAKASHI Takahiro 		}
59059df7e7eSAKASHI Takahiro 	}
59159df7e7eSAKASHI Takahiro 
59259df7e7eSAKASHI Takahiro 	return CMD_RET_SUCCESS;
59359df7e7eSAKASHI Takahiro }
59459df7e7eSAKASHI Takahiro 
59559df7e7eSAKASHI Takahiro /**
59659df7e7eSAKASHI Takahiro  * show_efi_boot_opt_data() - dump UEFI load option
59759df7e7eSAKASHI Takahiro  *
59859df7e7eSAKASHI Takahiro  * @id:		Load option number
59959df7e7eSAKASHI Takahiro  * @data:	Value of UEFI load option variable
60059df7e7eSAKASHI Takahiro  *
60159df7e7eSAKASHI Takahiro  * Decode the value of UEFI load option variable and print information.
60259df7e7eSAKASHI Takahiro  */
show_efi_boot_opt_data(int id,void * data)60359df7e7eSAKASHI Takahiro static void show_efi_boot_opt_data(int id, void *data)
60459df7e7eSAKASHI Takahiro {
60559df7e7eSAKASHI Takahiro 	struct efi_load_option lo;
60659df7e7eSAKASHI Takahiro 	char *label, *p;
60759df7e7eSAKASHI Takahiro 	size_t label_len16, label_len;
60859df7e7eSAKASHI Takahiro 	u16 *dp_str;
60959df7e7eSAKASHI Takahiro 
61059df7e7eSAKASHI Takahiro 	efi_deserialize_load_option(&lo, data);
61159df7e7eSAKASHI Takahiro 
61259df7e7eSAKASHI Takahiro 	label_len16 = u16_strlen(lo.label);
61359df7e7eSAKASHI Takahiro 	label_len = utf16_utf8_strnlen(lo.label, label_len16);
61459df7e7eSAKASHI Takahiro 	label = malloc(label_len + 1);
61559df7e7eSAKASHI Takahiro 	if (!label)
61659df7e7eSAKASHI Takahiro 		return;
61759df7e7eSAKASHI Takahiro 	p = label;
61859df7e7eSAKASHI Takahiro 	utf16_utf8_strncpy(&p, lo.label, label_len16);
61959df7e7eSAKASHI Takahiro 
62059df7e7eSAKASHI Takahiro 	printf("Boot%04X:\n", id);
62159df7e7eSAKASHI Takahiro 	printf("\tattributes: %c%c%c (0x%08x)\n",
62259df7e7eSAKASHI Takahiro 	       /* ACTIVE */
62359df7e7eSAKASHI Takahiro 	       lo.attributes & LOAD_OPTION_ACTIVE ? 'A' : '-',
62459df7e7eSAKASHI Takahiro 	       /* FORCE RECONNECT */
62559df7e7eSAKASHI Takahiro 	       lo.attributes & LOAD_OPTION_FORCE_RECONNECT ? 'R' : '-',
62659df7e7eSAKASHI Takahiro 	       /* HIDDEN */
62759df7e7eSAKASHI Takahiro 	       lo.attributes & LOAD_OPTION_HIDDEN ? 'H' : '-',
62859df7e7eSAKASHI Takahiro 	       lo.attributes);
62959df7e7eSAKASHI Takahiro 	printf("\tlabel: %s\n", label);
63059df7e7eSAKASHI Takahiro 
63159df7e7eSAKASHI Takahiro 	dp_str = efi_dp_str(lo.file_path);
63259df7e7eSAKASHI Takahiro 	printf("\tfile_path: %ls\n", dp_str);
63359df7e7eSAKASHI Takahiro 	efi_free_pool(dp_str);
63459df7e7eSAKASHI Takahiro 
63559df7e7eSAKASHI Takahiro 	printf("\tdata: %s\n", lo.optional_data);
63659df7e7eSAKASHI Takahiro 
63759df7e7eSAKASHI Takahiro 	free(label);
63859df7e7eSAKASHI Takahiro }
63959df7e7eSAKASHI Takahiro 
64059df7e7eSAKASHI Takahiro /**
64159df7e7eSAKASHI Takahiro  * show_efi_boot_opt() - dump UEFI load option
64259df7e7eSAKASHI Takahiro  *
64359df7e7eSAKASHI Takahiro  * @id:		Load option number
64459df7e7eSAKASHI Takahiro  *
64559df7e7eSAKASHI Takahiro  * Dump information defined by UEFI load option.
64659df7e7eSAKASHI Takahiro  */
show_efi_boot_opt(int id)64759df7e7eSAKASHI Takahiro static void show_efi_boot_opt(int id)
64859df7e7eSAKASHI Takahiro {
64959df7e7eSAKASHI Takahiro 	char var_name[9];
65059df7e7eSAKASHI Takahiro 	u16 var_name16[9], *p;
65159df7e7eSAKASHI Takahiro 	efi_guid_t guid;
65259df7e7eSAKASHI Takahiro 	void *data = NULL;
65359df7e7eSAKASHI Takahiro 	efi_uintn_t size;
65459df7e7eSAKASHI Takahiro 	int ret;
65559df7e7eSAKASHI Takahiro 
65659df7e7eSAKASHI Takahiro 	sprintf(var_name, "Boot%04X", id);
65759df7e7eSAKASHI Takahiro 	p = var_name16;
65859df7e7eSAKASHI Takahiro 	utf8_utf16_strncpy(&p, var_name, 9);
65959df7e7eSAKASHI Takahiro 	guid = efi_global_variable_guid;
66059df7e7eSAKASHI Takahiro 
66159df7e7eSAKASHI Takahiro 	size = 0;
66259df7e7eSAKASHI Takahiro 	ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size, NULL));
66359df7e7eSAKASHI Takahiro 	if (ret == (int)EFI_BUFFER_TOO_SMALL) {
66459df7e7eSAKASHI Takahiro 		data = malloc(size);
66559df7e7eSAKASHI Takahiro 		ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size,
66659df7e7eSAKASHI Takahiro 						data));
66759df7e7eSAKASHI Takahiro 	}
66859df7e7eSAKASHI Takahiro 	if (ret == EFI_SUCCESS)
66959df7e7eSAKASHI Takahiro 		show_efi_boot_opt_data(id, data);
67059df7e7eSAKASHI Takahiro 	else if (ret == EFI_NOT_FOUND)
67159df7e7eSAKASHI Takahiro 		printf("Boot%04X: not found\n", id);
67259df7e7eSAKASHI Takahiro 
67359df7e7eSAKASHI Takahiro 	free(data);
67459df7e7eSAKASHI Takahiro }
67559df7e7eSAKASHI Takahiro 
67659df7e7eSAKASHI Takahiro /**
67759df7e7eSAKASHI Takahiro  * show_efi_boot_dump() - dump all UEFI load options
67859df7e7eSAKASHI Takahiro  *
67959df7e7eSAKASHI Takahiro  * @cmdtp:	Command table
68059df7e7eSAKASHI Takahiro  * @flag:	Command flag
68159df7e7eSAKASHI Takahiro  * @argc:	Number of arguments
68259df7e7eSAKASHI Takahiro  * @argv:	Argument array
68359df7e7eSAKASHI Takahiro  * Return:	CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
68459df7e7eSAKASHI Takahiro  *
68559df7e7eSAKASHI Takahiro  * Implement efidebug "boot dump" sub-command.
68659df7e7eSAKASHI Takahiro  * Dump information of all UEFI load options defined.
68759df7e7eSAKASHI Takahiro  *   - boot dump
68859df7e7eSAKASHI Takahiro  */
do_efi_boot_dump(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])68959df7e7eSAKASHI Takahiro static int do_efi_boot_dump(cmd_tbl_t *cmdtp, int flag,
69059df7e7eSAKASHI Takahiro 			    int argc, char * const argv[])
69159df7e7eSAKASHI Takahiro {
69259df7e7eSAKASHI Takahiro 	char regex[256];
69359df7e7eSAKASHI Takahiro 	char * const regexlist[] = {regex};
69459df7e7eSAKASHI Takahiro 	char *variables = NULL, *boot, *value;
69559df7e7eSAKASHI Takahiro 	int len;
69659df7e7eSAKASHI Takahiro 	int id;
69759df7e7eSAKASHI Takahiro 
69859df7e7eSAKASHI Takahiro 	if (argc > 1)
69959df7e7eSAKASHI Takahiro 		return CMD_RET_USAGE;
70059df7e7eSAKASHI Takahiro 
70159df7e7eSAKASHI Takahiro 	snprintf(regex, 256, "efi_.*-.*-.*-.*-.*_Boot[0-9A-F]+");
70259df7e7eSAKASHI Takahiro 
70359df7e7eSAKASHI Takahiro 	/* TODO: use GetNextVariableName? */
70459df7e7eSAKASHI Takahiro 	len = hexport_r(&env_htab, '\n', H_MATCH_REGEX | H_MATCH_KEY,
70559df7e7eSAKASHI Takahiro 			&variables, 0, 1, regexlist);
70659df7e7eSAKASHI Takahiro 
70759df7e7eSAKASHI Takahiro 	if (!len)
70859df7e7eSAKASHI Takahiro 		return CMD_RET_SUCCESS;
70959df7e7eSAKASHI Takahiro 
71059df7e7eSAKASHI Takahiro 	if (len < 0)
71159df7e7eSAKASHI Takahiro 		return CMD_RET_FAILURE;
71259df7e7eSAKASHI Takahiro 
71359df7e7eSAKASHI Takahiro 	boot = variables;
71459df7e7eSAKASHI Takahiro 	while (*boot) {
71559df7e7eSAKASHI Takahiro 		value = strstr(boot, "Boot") + 4;
71659df7e7eSAKASHI Takahiro 		id = (int)simple_strtoul(value, NULL, 16);
71759df7e7eSAKASHI Takahiro 		show_efi_boot_opt(id);
71859df7e7eSAKASHI Takahiro 		boot = strchr(boot, '\n');
71959df7e7eSAKASHI Takahiro 		if (!*boot)
72059df7e7eSAKASHI Takahiro 			break;
72159df7e7eSAKASHI Takahiro 		boot++;
72259df7e7eSAKASHI Takahiro 	}
72359df7e7eSAKASHI Takahiro 	free(variables);
72459df7e7eSAKASHI Takahiro 
72559df7e7eSAKASHI Takahiro 	return CMD_RET_SUCCESS;
72659df7e7eSAKASHI Takahiro }
72759df7e7eSAKASHI Takahiro 
72859df7e7eSAKASHI Takahiro /**
72959df7e7eSAKASHI Takahiro  * show_efi_boot_order() - show order of UEFI load options
73059df7e7eSAKASHI Takahiro  *
73159df7e7eSAKASHI Takahiro  * Return:	CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
73259df7e7eSAKASHI Takahiro  *
73359df7e7eSAKASHI Takahiro  * Show order of UEFI load options defined by BootOrder variable.
73459df7e7eSAKASHI Takahiro  */
show_efi_boot_order(void)73559df7e7eSAKASHI Takahiro static int show_efi_boot_order(void)
73659df7e7eSAKASHI Takahiro {
73759df7e7eSAKASHI Takahiro 	efi_guid_t guid;
73859df7e7eSAKASHI Takahiro 	u16 *bootorder = NULL;
73959df7e7eSAKASHI Takahiro 	efi_uintn_t size;
74059df7e7eSAKASHI Takahiro 	int num, i;
74159df7e7eSAKASHI Takahiro 	char var_name[9];
74259df7e7eSAKASHI Takahiro 	u16 var_name16[9], *p16;
74359df7e7eSAKASHI Takahiro 	void *data;
74459df7e7eSAKASHI Takahiro 	struct efi_load_option lo;
74559df7e7eSAKASHI Takahiro 	char *label, *p;
74659df7e7eSAKASHI Takahiro 	size_t label_len16, label_len;
74759df7e7eSAKASHI Takahiro 	efi_status_t ret;
74859df7e7eSAKASHI Takahiro 
74959df7e7eSAKASHI Takahiro 	guid = efi_global_variable_guid;
75059df7e7eSAKASHI Takahiro 	size = 0;
75159df7e7eSAKASHI Takahiro 	ret = EFI_CALL(RT->get_variable(L"BootOrder", &guid, NULL, &size,
75259df7e7eSAKASHI Takahiro 					NULL));
75359df7e7eSAKASHI Takahiro 	if (ret == EFI_BUFFER_TOO_SMALL) {
75459df7e7eSAKASHI Takahiro 		bootorder = malloc(size);
75559df7e7eSAKASHI Takahiro 		ret = EFI_CALL(RT->get_variable(L"BootOrder", &guid, NULL,
75659df7e7eSAKASHI Takahiro 						&size, bootorder));
75759df7e7eSAKASHI Takahiro 	}
75859df7e7eSAKASHI Takahiro 	if (ret == EFI_NOT_FOUND) {
75959df7e7eSAKASHI Takahiro 		printf("BootOrder not defined\n");
76059df7e7eSAKASHI Takahiro 		ret = CMD_RET_SUCCESS;
76159df7e7eSAKASHI Takahiro 		goto out;
76259df7e7eSAKASHI Takahiro 	} else if (ret != EFI_SUCCESS) {
76359df7e7eSAKASHI Takahiro 		ret = CMD_RET_FAILURE;
76459df7e7eSAKASHI Takahiro 		goto out;
76559df7e7eSAKASHI Takahiro 	}
76659df7e7eSAKASHI Takahiro 
76759df7e7eSAKASHI Takahiro 	num = size / sizeof(u16);
76859df7e7eSAKASHI Takahiro 	for (i = 0; i < num; i++) {
76959df7e7eSAKASHI Takahiro 		sprintf(var_name, "Boot%04X", bootorder[i]);
77059df7e7eSAKASHI Takahiro 		p16 = var_name16;
77159df7e7eSAKASHI Takahiro 		utf8_utf16_strncpy(&p16, var_name, 9);
77259df7e7eSAKASHI Takahiro 
77359df7e7eSAKASHI Takahiro 		size = 0;
77459df7e7eSAKASHI Takahiro 		ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size,
77559df7e7eSAKASHI Takahiro 						NULL));
77659df7e7eSAKASHI Takahiro 		if (ret != EFI_BUFFER_TOO_SMALL) {
77759df7e7eSAKASHI Takahiro 			printf("%2d: Boot%04X: (not defined)\n",
77859df7e7eSAKASHI Takahiro 			       i + 1, bootorder[i]);
77959df7e7eSAKASHI Takahiro 			continue;
78059df7e7eSAKASHI Takahiro 		}
78159df7e7eSAKASHI Takahiro 
78259df7e7eSAKASHI Takahiro 		data = malloc(size);
78359df7e7eSAKASHI Takahiro 		if (!data) {
78459df7e7eSAKASHI Takahiro 			ret = CMD_RET_FAILURE;
78559df7e7eSAKASHI Takahiro 			goto out;
78659df7e7eSAKASHI Takahiro 		}
78759df7e7eSAKASHI Takahiro 		ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size,
78859df7e7eSAKASHI Takahiro 						data));
78959df7e7eSAKASHI Takahiro 		if (ret != EFI_SUCCESS) {
79059df7e7eSAKASHI Takahiro 			free(data);
79159df7e7eSAKASHI Takahiro 			ret = CMD_RET_FAILURE;
79259df7e7eSAKASHI Takahiro 			goto out;
79359df7e7eSAKASHI Takahiro 		}
79459df7e7eSAKASHI Takahiro 
79559df7e7eSAKASHI Takahiro 		efi_deserialize_load_option(&lo, data);
79659df7e7eSAKASHI Takahiro 
79759df7e7eSAKASHI Takahiro 		label_len16 = u16_strlen(lo.label);
79859df7e7eSAKASHI Takahiro 		label_len = utf16_utf8_strnlen(lo.label, label_len16);
79959df7e7eSAKASHI Takahiro 		label = malloc(label_len + 1);
80059df7e7eSAKASHI Takahiro 		if (!label) {
80159df7e7eSAKASHI Takahiro 			free(data);
80259df7e7eSAKASHI Takahiro 			ret = CMD_RET_FAILURE;
80359df7e7eSAKASHI Takahiro 			goto out;
80459df7e7eSAKASHI Takahiro 		}
80559df7e7eSAKASHI Takahiro 		p = label;
80659df7e7eSAKASHI Takahiro 		utf16_utf8_strncpy(&p, lo.label, label_len16);
80759df7e7eSAKASHI Takahiro 		printf("%2d: Boot%04X: %s\n", i + 1, bootorder[i], label);
80859df7e7eSAKASHI Takahiro 		free(label);
80959df7e7eSAKASHI Takahiro 
81059df7e7eSAKASHI Takahiro 		free(data);
81159df7e7eSAKASHI Takahiro 	}
81259df7e7eSAKASHI Takahiro out:
81359df7e7eSAKASHI Takahiro 	free(bootorder);
81459df7e7eSAKASHI Takahiro 
81559df7e7eSAKASHI Takahiro 	return ret;
81659df7e7eSAKASHI Takahiro }
81759df7e7eSAKASHI Takahiro 
81859df7e7eSAKASHI Takahiro /**
81959df7e7eSAKASHI Takahiro  * do_efi_boot_next() - manage UEFI BootNext variable
82059df7e7eSAKASHI Takahiro  *
82159df7e7eSAKASHI Takahiro  * @cmdtp:	Command table
82259df7e7eSAKASHI Takahiro  * @flag:	Command flag
82359df7e7eSAKASHI Takahiro  * @argc:	Number of arguments
82459df7e7eSAKASHI Takahiro  * @argv:	Argument array
82559df7e7eSAKASHI Takahiro  * Return:	CMD_RET_SUCCESS on success,
82659df7e7eSAKASHI Takahiro  *		CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
82759df7e7eSAKASHI Takahiro  *
82859df7e7eSAKASHI Takahiro  * Implement efidebug "boot next" sub-command.
82959df7e7eSAKASHI Takahiro  * Set BootNext variable.
83059df7e7eSAKASHI Takahiro  *   - boot next <id>
83159df7e7eSAKASHI Takahiro  */
do_efi_boot_next(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])83259df7e7eSAKASHI Takahiro static int do_efi_boot_next(cmd_tbl_t *cmdtp, int flag,
83359df7e7eSAKASHI Takahiro 			    int argc, char * const argv[])
83459df7e7eSAKASHI Takahiro {
83559df7e7eSAKASHI Takahiro 	u16 bootnext;
83659df7e7eSAKASHI Takahiro 	efi_uintn_t size;
83759df7e7eSAKASHI Takahiro 	char *endp;
83859df7e7eSAKASHI Takahiro 	efi_guid_t guid;
83959df7e7eSAKASHI Takahiro 	efi_status_t ret;
84059df7e7eSAKASHI Takahiro 
84159df7e7eSAKASHI Takahiro 	if (argc != 2)
84259df7e7eSAKASHI Takahiro 		return CMD_RET_USAGE;
84359df7e7eSAKASHI Takahiro 
84459df7e7eSAKASHI Takahiro 	bootnext = (u16)simple_strtoul(argv[1], &endp, 16);
84559df7e7eSAKASHI Takahiro 	if (*endp != '\0' || bootnext > 0xffff) {
84659df7e7eSAKASHI Takahiro 		printf("invalid value: %s\n", argv[1]);
84759df7e7eSAKASHI Takahiro 		ret = CMD_RET_FAILURE;
84859df7e7eSAKASHI Takahiro 		goto out;
84959df7e7eSAKASHI Takahiro 	}
85059df7e7eSAKASHI Takahiro 
85159df7e7eSAKASHI Takahiro 	guid = efi_global_variable_guid;
85259df7e7eSAKASHI Takahiro 	size = sizeof(u16);
85359df7e7eSAKASHI Takahiro 	ret = EFI_CALL(RT->set_variable(L"BootNext", &guid,
85459df7e7eSAKASHI Takahiro 					EFI_VARIABLE_BOOTSERVICE_ACCESS |
85559df7e7eSAKASHI Takahiro 					EFI_VARIABLE_RUNTIME_ACCESS,
85659df7e7eSAKASHI Takahiro 					size, &bootnext));
85759df7e7eSAKASHI Takahiro 	ret = (ret == EFI_SUCCESS ? CMD_RET_SUCCESS : CMD_RET_FAILURE);
85859df7e7eSAKASHI Takahiro out:
85959df7e7eSAKASHI Takahiro 	return ret;
86059df7e7eSAKASHI Takahiro }
86159df7e7eSAKASHI Takahiro 
86259df7e7eSAKASHI Takahiro /**
86359df7e7eSAKASHI Takahiro  * do_efi_boot_order() - manage UEFI BootOrder variable
86459df7e7eSAKASHI Takahiro  *
86559df7e7eSAKASHI Takahiro  * @cmdtp:	Command table
86659df7e7eSAKASHI Takahiro  * @flag:	Command flag
86759df7e7eSAKASHI Takahiro  * @argc:	Number of arguments
86859df7e7eSAKASHI Takahiro  * @argv:	Argument array
86959df7e7eSAKASHI Takahiro  * Return:	CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
87059df7e7eSAKASHI Takahiro  *
87159df7e7eSAKASHI Takahiro  * Implement efidebug "boot order" sub-command.
87259df7e7eSAKASHI Takahiro  * Show order of UEFI load options, or change it in BootOrder variable.
87359df7e7eSAKASHI Takahiro  *   - boot order [<id> ...]
87459df7e7eSAKASHI Takahiro  */
do_efi_boot_order(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])87559df7e7eSAKASHI Takahiro static int do_efi_boot_order(cmd_tbl_t *cmdtp, int flag,
87659df7e7eSAKASHI Takahiro 			     int argc, char * const argv[])
87759df7e7eSAKASHI Takahiro {
87859df7e7eSAKASHI Takahiro 	u16 *bootorder = NULL;
87959df7e7eSAKASHI Takahiro 	efi_uintn_t size;
88059df7e7eSAKASHI Takahiro 	int id, i;
88159df7e7eSAKASHI Takahiro 	char *endp;
88259df7e7eSAKASHI Takahiro 	efi_guid_t guid;
88359df7e7eSAKASHI Takahiro 	efi_status_t ret;
88459df7e7eSAKASHI Takahiro 
88559df7e7eSAKASHI Takahiro 	if (argc == 1)
88659df7e7eSAKASHI Takahiro 		return show_efi_boot_order();
88759df7e7eSAKASHI Takahiro 
88859df7e7eSAKASHI Takahiro 	argc--;
88959df7e7eSAKASHI Takahiro 	argv++;
89059df7e7eSAKASHI Takahiro 
89159df7e7eSAKASHI Takahiro 	size = argc * sizeof(u16);
89259df7e7eSAKASHI Takahiro 	bootorder = malloc(size);
89359df7e7eSAKASHI Takahiro 	if (!bootorder)
89459df7e7eSAKASHI Takahiro 		return CMD_RET_FAILURE;
89559df7e7eSAKASHI Takahiro 
89659df7e7eSAKASHI Takahiro 	for (i = 0; i < argc; i++) {
89759df7e7eSAKASHI Takahiro 		id = (int)simple_strtoul(argv[i], &endp, 16);
89859df7e7eSAKASHI Takahiro 		if (*endp != '\0' || id > 0xffff) {
89959df7e7eSAKASHI Takahiro 			printf("invalid value: %s\n", argv[i]);
90059df7e7eSAKASHI Takahiro 			ret = CMD_RET_FAILURE;
90159df7e7eSAKASHI Takahiro 			goto out;
90259df7e7eSAKASHI Takahiro 		}
90359df7e7eSAKASHI Takahiro 
90459df7e7eSAKASHI Takahiro 		bootorder[i] = (u16)id;
90559df7e7eSAKASHI Takahiro 	}
90659df7e7eSAKASHI Takahiro 
90759df7e7eSAKASHI Takahiro 	guid = efi_global_variable_guid;
90859df7e7eSAKASHI Takahiro 	ret = EFI_CALL(RT->set_variable(L"BootOrder", &guid,
90959df7e7eSAKASHI Takahiro 					EFI_VARIABLE_BOOTSERVICE_ACCESS |
91059df7e7eSAKASHI Takahiro 					EFI_VARIABLE_RUNTIME_ACCESS,
91159df7e7eSAKASHI Takahiro 					size, bootorder));
91259df7e7eSAKASHI Takahiro 	ret = (ret == EFI_SUCCESS ? CMD_RET_SUCCESS : CMD_RET_FAILURE);
91359df7e7eSAKASHI Takahiro out:
91459df7e7eSAKASHI Takahiro 	free(bootorder);
91559df7e7eSAKASHI Takahiro 
91659df7e7eSAKASHI Takahiro 	return ret;
91759df7e7eSAKASHI Takahiro }
91859df7e7eSAKASHI Takahiro 
91959df7e7eSAKASHI Takahiro static cmd_tbl_t cmd_efidebug_boot_sub[] = {
92059df7e7eSAKASHI Takahiro 	U_BOOT_CMD_MKENT(add, CONFIG_SYS_MAXARGS, 1, do_efi_boot_add, "", ""),
92159df7e7eSAKASHI Takahiro 	U_BOOT_CMD_MKENT(rm, CONFIG_SYS_MAXARGS, 1, do_efi_boot_rm, "", ""),
92259df7e7eSAKASHI Takahiro 	U_BOOT_CMD_MKENT(dump, CONFIG_SYS_MAXARGS, 1, do_efi_boot_dump, "", ""),
92359df7e7eSAKASHI Takahiro 	U_BOOT_CMD_MKENT(next, CONFIG_SYS_MAXARGS, 1, do_efi_boot_next, "", ""),
92459df7e7eSAKASHI Takahiro 	U_BOOT_CMD_MKENT(order, CONFIG_SYS_MAXARGS, 1, do_efi_boot_order,
92559df7e7eSAKASHI Takahiro 			 "", ""),
92659df7e7eSAKASHI Takahiro };
92759df7e7eSAKASHI Takahiro 
92859df7e7eSAKASHI Takahiro /**
92959df7e7eSAKASHI Takahiro  * do_efi_boot_opt() - manage UEFI load options
93059df7e7eSAKASHI Takahiro  *
93159df7e7eSAKASHI Takahiro  * @cmdtp:	Command table
93259df7e7eSAKASHI Takahiro  * @flag:	Command flag
93359df7e7eSAKASHI Takahiro  * @argc:	Number of arguments
93459df7e7eSAKASHI Takahiro  * @argv:	Argument array
93559df7e7eSAKASHI Takahiro  * Return:	CMD_RET_SUCCESS on success,
93659df7e7eSAKASHI Takahiro  *		CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
93759df7e7eSAKASHI Takahiro  *
93859df7e7eSAKASHI Takahiro  * Implement efidebug "boot" sub-command.
93959df7e7eSAKASHI Takahiro  * See above for details of sub-commands.
94059df7e7eSAKASHI Takahiro  */
do_efi_boot_opt(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])94159df7e7eSAKASHI Takahiro static int do_efi_boot_opt(cmd_tbl_t *cmdtp, int flag,
94259df7e7eSAKASHI Takahiro 			   int argc, char * const argv[])
94359df7e7eSAKASHI Takahiro {
94459df7e7eSAKASHI Takahiro 	cmd_tbl_t *cp;
94559df7e7eSAKASHI Takahiro 
94659df7e7eSAKASHI Takahiro 	if (argc < 2)
94759df7e7eSAKASHI Takahiro 		return CMD_RET_USAGE;
94859df7e7eSAKASHI Takahiro 
94959df7e7eSAKASHI Takahiro 	argc--; argv++;
95059df7e7eSAKASHI Takahiro 
95159df7e7eSAKASHI Takahiro 	cp = find_cmd_tbl(argv[0], cmd_efidebug_boot_sub,
95259df7e7eSAKASHI Takahiro 			  ARRAY_SIZE(cmd_efidebug_boot_sub));
95359df7e7eSAKASHI Takahiro 	if (!cp)
95459df7e7eSAKASHI Takahiro 		return CMD_RET_USAGE;
95559df7e7eSAKASHI Takahiro 
95659df7e7eSAKASHI Takahiro 	return cp->cmd(cmdtp, flag, argc, argv);
95759df7e7eSAKASHI Takahiro }
95859df7e7eSAKASHI Takahiro 
95959df7e7eSAKASHI Takahiro static cmd_tbl_t cmd_efidebug_sub[] = {
96059df7e7eSAKASHI Takahiro 	U_BOOT_CMD_MKENT(boot, CONFIG_SYS_MAXARGS, 1, do_efi_boot_opt, "", ""),
961355cdb5aSAKASHI Takahiro 	U_BOOT_CMD_MKENT(devices, CONFIG_SYS_MAXARGS, 1, do_efi_show_devices,
962355cdb5aSAKASHI Takahiro 			 "", ""),
96366eaf566SAKASHI Takahiro 	U_BOOT_CMD_MKENT(drivers, CONFIG_SYS_MAXARGS, 1, do_efi_show_drivers,
96466eaf566SAKASHI Takahiro 			 "", ""),
965a8014620SAKASHI Takahiro 	U_BOOT_CMD_MKENT(dh, CONFIG_SYS_MAXARGS, 1, do_efi_show_handles,
966a8014620SAKASHI Takahiro 			 "", ""),
967fa536734SAKASHI Takahiro 	U_BOOT_CMD_MKENT(images, CONFIG_SYS_MAXARGS, 1, do_efi_show_images,
968fa536734SAKASHI Takahiro 			 "", ""),
96900358bb8SAKASHI Takahiro 	U_BOOT_CMD_MKENT(memmap, CONFIG_SYS_MAXARGS, 1, do_efi_show_memmap,
97000358bb8SAKASHI Takahiro 			 "", ""),
97159df7e7eSAKASHI Takahiro };
97259df7e7eSAKASHI Takahiro 
97359df7e7eSAKASHI Takahiro /**
97459df7e7eSAKASHI Takahiro  * do_efidebug() - display and configure UEFI environment
97559df7e7eSAKASHI Takahiro  *
97659df7e7eSAKASHI Takahiro  * @cmdtp:	Command table
97759df7e7eSAKASHI Takahiro  * @flag:	Command flag
97859df7e7eSAKASHI Takahiro  * @argc:	Number of arguments
97959df7e7eSAKASHI Takahiro  * @argv:	Argument array
98059df7e7eSAKASHI Takahiro  * Return:	CMD_RET_SUCCESS on success,
98159df7e7eSAKASHI Takahiro  *		CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
98259df7e7eSAKASHI Takahiro  *
98359df7e7eSAKASHI Takahiro  * Implement efidebug command which allows us to display and
98459df7e7eSAKASHI Takahiro  * configure UEFI environment.
98559df7e7eSAKASHI Takahiro  * See above for details of sub-commands.
98659df7e7eSAKASHI Takahiro  */
do_efidebug(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])98759df7e7eSAKASHI Takahiro static int do_efidebug(cmd_tbl_t *cmdtp, int flag,
98859df7e7eSAKASHI Takahiro 		       int argc, char * const argv[])
98959df7e7eSAKASHI Takahiro {
99059df7e7eSAKASHI Takahiro 	cmd_tbl_t *cp;
99159df7e7eSAKASHI Takahiro 	efi_status_t r;
99259df7e7eSAKASHI Takahiro 
99359df7e7eSAKASHI Takahiro 	if (argc < 2)
99459df7e7eSAKASHI Takahiro 		return CMD_RET_USAGE;
99559df7e7eSAKASHI Takahiro 
99659df7e7eSAKASHI Takahiro 	argc--; argv++;
99759df7e7eSAKASHI Takahiro 
99859df7e7eSAKASHI Takahiro 	/* Initialize UEFI drivers */
99959df7e7eSAKASHI Takahiro 	r = efi_init_obj_list();
100059df7e7eSAKASHI Takahiro 	if (r != EFI_SUCCESS) {
100159df7e7eSAKASHI Takahiro 		printf("Error: Cannot initialize UEFI sub-system, r = %lu\n",
100259df7e7eSAKASHI Takahiro 		       r & ~EFI_ERROR_MASK);
100359df7e7eSAKASHI Takahiro 		return CMD_RET_FAILURE;
100459df7e7eSAKASHI Takahiro 	}
100559df7e7eSAKASHI Takahiro 
100659df7e7eSAKASHI Takahiro 	cp = find_cmd_tbl(argv[0], cmd_efidebug_sub,
100759df7e7eSAKASHI Takahiro 			  ARRAY_SIZE(cmd_efidebug_sub));
100859df7e7eSAKASHI Takahiro 	if (!cp)
100959df7e7eSAKASHI Takahiro 		return CMD_RET_USAGE;
101059df7e7eSAKASHI Takahiro 
101159df7e7eSAKASHI Takahiro 	return cp->cmd(cmdtp, flag, argc, argv);
101259df7e7eSAKASHI Takahiro }
101359df7e7eSAKASHI Takahiro 
101459df7e7eSAKASHI Takahiro #ifdef CONFIG_SYS_LONGHELP
101559df7e7eSAKASHI Takahiro static char efidebug_help_text[] =
101659df7e7eSAKASHI Takahiro 	"  - UEFI Shell-like interface to configure UEFI environment\n"
101759df7e7eSAKASHI Takahiro 	"\n"
101859df7e7eSAKASHI Takahiro 	"efidebug boot add <bootid> <label> <interface> <devnum>[:<part>] <file path> [<load options>]\n"
101959df7e7eSAKASHI Takahiro 	"  - set UEFI BootXXXX variable\n"
102059df7e7eSAKASHI Takahiro 	"    <load options> will be passed to UEFI application\n"
102159df7e7eSAKASHI Takahiro 	"efidebug boot rm <bootid#1> [<bootid#2> [<bootid#3> [...]]]\n"
102259df7e7eSAKASHI Takahiro 	"  - delete UEFI BootXXXX variables\n"
102359df7e7eSAKASHI Takahiro 	"efidebug boot dump\n"
102459df7e7eSAKASHI Takahiro 	"  - dump all UEFI BootXXXX variables\n"
102559df7e7eSAKASHI Takahiro 	"efidebug boot next <bootid>\n"
102659df7e7eSAKASHI Takahiro 	"  - set UEFI BootNext variable\n"
102759df7e7eSAKASHI Takahiro 	"efidebug boot order [<bootid#1> [<bootid#2> [<bootid#3> [...]]]]\n"
102859df7e7eSAKASHI Takahiro 	"  - set/show UEFI boot order\n"
1029355cdb5aSAKASHI Takahiro 	"\n"
1030355cdb5aSAKASHI Takahiro 	"efidebug devices\n"
103166eaf566SAKASHI Takahiro 	"  - show uefi devices\n"
103266eaf566SAKASHI Takahiro 	"efidebug drivers\n"
1033a8014620SAKASHI Takahiro 	"  - show uefi drivers\n"
1034a8014620SAKASHI Takahiro 	"efidebug dh\n"
1035fa536734SAKASHI Takahiro 	"  - show uefi handles\n"
1036fa536734SAKASHI Takahiro 	"efidebug images\n"
103700358bb8SAKASHI Takahiro 	"  - show loaded images\n"
103800358bb8SAKASHI Takahiro 	"efidebug memmap\n"
103900358bb8SAKASHI Takahiro 	"  - show uefi memory map\n";
104059df7e7eSAKASHI Takahiro #endif
104159df7e7eSAKASHI Takahiro 
104259df7e7eSAKASHI Takahiro U_BOOT_CMD(
104359df7e7eSAKASHI Takahiro 	efidebug, 10, 0, do_efidebug,
104459df7e7eSAKASHI Takahiro 	"Configure UEFI environment",
104559df7e7eSAKASHI Takahiro 	efidebug_help_text
104659df7e7eSAKASHI Takahiro );
1047