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 */ 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 */ 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 /** 94*66eaf566SAKASHI Takahiro * efi_get_driver_handle_info() - get information of UEFI driver 95*66eaf566SAKASHI Takahiro * 96*66eaf566SAKASHI Takahiro * @handle: Handle of UEFI device 97*66eaf566SAKASHI Takahiro * @driver_name: Driver name 98*66eaf566SAKASHI Takahiro * @image_path: Pointer to text of device path 99*66eaf566SAKASHI Takahiro * Return: 0 on success, -1 on failure 100*66eaf566SAKASHI Takahiro * 101*66eaf566SAKASHI Takahiro * Currently return no useful information as all UEFI drivers are 102*66eaf566SAKASHI Takahiro * built-in.. 103*66eaf566SAKASHI Takahiro */ 104*66eaf566SAKASHI Takahiro static int efi_get_driver_handle_info(efi_handle_t handle, u16 **driver_name, 105*66eaf566SAKASHI Takahiro u16 **image_path) 106*66eaf566SAKASHI Takahiro { 107*66eaf566SAKASHI Takahiro struct efi_handler *handler; 108*66eaf566SAKASHI Takahiro struct efi_loaded_image *image; 109*66eaf566SAKASHI Takahiro efi_status_t ret; 110*66eaf566SAKASHI Takahiro 111*66eaf566SAKASHI Takahiro /* 112*66eaf566SAKASHI Takahiro * driver name 113*66eaf566SAKASHI Takahiro * TODO: support EFI_COMPONENT_NAME2_PROTOCOL 114*66eaf566SAKASHI Takahiro */ 115*66eaf566SAKASHI Takahiro *driver_name = NULL; 116*66eaf566SAKASHI Takahiro 117*66eaf566SAKASHI Takahiro /* image name */ 118*66eaf566SAKASHI Takahiro ret = efi_search_protocol(handle, &efi_guid_loaded_image, &handler); 119*66eaf566SAKASHI Takahiro if (ret != EFI_SUCCESS) { 120*66eaf566SAKASHI Takahiro *image_path = NULL; 121*66eaf566SAKASHI Takahiro return 0; 122*66eaf566SAKASHI Takahiro } 123*66eaf566SAKASHI Takahiro 124*66eaf566SAKASHI Takahiro image = handler->protocol_interface; 125*66eaf566SAKASHI Takahiro *image_path = efi_dp_str(image->file_path); 126*66eaf566SAKASHI Takahiro 127*66eaf566SAKASHI Takahiro return 0; 128*66eaf566SAKASHI Takahiro } 129*66eaf566SAKASHI Takahiro 130*66eaf566SAKASHI Takahiro /** 131*66eaf566SAKASHI Takahiro * do_efi_show_drivers() - show UEFI drivers 132*66eaf566SAKASHI Takahiro * 133*66eaf566SAKASHI Takahiro * @cmdtp: Command table 134*66eaf566SAKASHI Takahiro * @flag: Command flag 135*66eaf566SAKASHI Takahiro * @argc: Number of arguments 136*66eaf566SAKASHI Takahiro * @argv: Argument array 137*66eaf566SAKASHI Takahiro * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure 138*66eaf566SAKASHI Takahiro * 139*66eaf566SAKASHI Takahiro * Implement efidebug "drivers" sub-command. 140*66eaf566SAKASHI Takahiro * Show all UEFI drivers and their information. 141*66eaf566SAKASHI Takahiro */ 142*66eaf566SAKASHI Takahiro static int do_efi_show_drivers(cmd_tbl_t *cmdtp, int flag, 143*66eaf566SAKASHI Takahiro int argc, char * const argv[]) 144*66eaf566SAKASHI Takahiro { 145*66eaf566SAKASHI Takahiro efi_handle_t *handles; 146*66eaf566SAKASHI Takahiro efi_uintn_t num, i; 147*66eaf566SAKASHI Takahiro u16 *driver_name, *image_path_text; 148*66eaf566SAKASHI Takahiro efi_status_t ret; 149*66eaf566SAKASHI Takahiro 150*66eaf566SAKASHI Takahiro ret = EFI_CALL(BS->locate_handle_buffer( 151*66eaf566SAKASHI Takahiro BY_PROTOCOL, &efi_guid_driver_binding_protocol, 152*66eaf566SAKASHI Takahiro NULL, &num, &handles)); 153*66eaf566SAKASHI Takahiro if (ret != EFI_SUCCESS) 154*66eaf566SAKASHI Takahiro return CMD_RET_FAILURE; 155*66eaf566SAKASHI Takahiro 156*66eaf566SAKASHI Takahiro if (!num) 157*66eaf566SAKASHI Takahiro return CMD_RET_SUCCESS; 158*66eaf566SAKASHI Takahiro 159*66eaf566SAKASHI Takahiro printf("Driver%.*s Name Image Path\n", 160*66eaf566SAKASHI Takahiro EFI_HANDLE_WIDTH - 6, spc); 161*66eaf566SAKASHI Takahiro printf("%.*s ==================== ====================\n", 162*66eaf566SAKASHI Takahiro EFI_HANDLE_WIDTH, sep); 163*66eaf566SAKASHI Takahiro for (i = 0; i < num; i++) { 164*66eaf566SAKASHI Takahiro if (!efi_get_driver_handle_info(handles[i], &driver_name, 165*66eaf566SAKASHI Takahiro &image_path_text)) { 166*66eaf566SAKASHI Takahiro if (image_path_text) 167*66eaf566SAKASHI Takahiro printf("%p %-20ls %ls\n", handles[i], 168*66eaf566SAKASHI Takahiro driver_name, image_path_text); 169*66eaf566SAKASHI Takahiro else 170*66eaf566SAKASHI Takahiro printf("%p %-20ls <built-in>\n", 171*66eaf566SAKASHI Takahiro handles[i], driver_name); 172*66eaf566SAKASHI Takahiro EFI_CALL(BS->free_pool(driver_name)); 173*66eaf566SAKASHI Takahiro EFI_CALL(BS->free_pool(image_path_text)); 174*66eaf566SAKASHI Takahiro } 175*66eaf566SAKASHI Takahiro } 176*66eaf566SAKASHI Takahiro 177*66eaf566SAKASHI Takahiro EFI_CALL(BS->free_pool(handles)); 178*66eaf566SAKASHI Takahiro 179*66eaf566SAKASHI Takahiro return CMD_RET_SUCCESS; 180*66eaf566SAKASHI Takahiro } 181*66eaf566SAKASHI Takahiro 182*66eaf566SAKASHI Takahiro /** 18359df7e7eSAKASHI Takahiro * do_efi_boot_add() - set UEFI load option 18459df7e7eSAKASHI Takahiro * 18559df7e7eSAKASHI Takahiro * @cmdtp: Command table 18659df7e7eSAKASHI Takahiro * @flag: Command flag 18759df7e7eSAKASHI Takahiro * @argc: Number of arguments 18859df7e7eSAKASHI Takahiro * @argv: Argument array 18959df7e7eSAKASHI Takahiro * Return: CMD_RET_SUCCESS on success, 19059df7e7eSAKASHI Takahiro * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure 19159df7e7eSAKASHI Takahiro * 19259df7e7eSAKASHI Takahiro * Implement efidebug "boot add" sub-command. 19359df7e7eSAKASHI Takahiro * Create or change UEFI load option. 19459df7e7eSAKASHI Takahiro * - boot add <id> <label> <interface> <devnum>[:<part>] <file> <options> 19559df7e7eSAKASHI Takahiro */ 19659df7e7eSAKASHI Takahiro static int do_efi_boot_add(cmd_tbl_t *cmdtp, int flag, 19759df7e7eSAKASHI Takahiro int argc, char * const argv[]) 19859df7e7eSAKASHI Takahiro { 19959df7e7eSAKASHI Takahiro int id; 20059df7e7eSAKASHI Takahiro char *endp; 20159df7e7eSAKASHI Takahiro char var_name[9]; 20259df7e7eSAKASHI Takahiro u16 var_name16[9], *p; 20359df7e7eSAKASHI Takahiro efi_guid_t guid; 20459df7e7eSAKASHI Takahiro size_t label_len, label_len16; 20559df7e7eSAKASHI Takahiro u16 *label; 20659df7e7eSAKASHI Takahiro struct efi_device_path *device_path = NULL, *file_path = NULL; 20759df7e7eSAKASHI Takahiro struct efi_load_option lo; 20859df7e7eSAKASHI Takahiro void *data = NULL; 20959df7e7eSAKASHI Takahiro efi_uintn_t size; 21059df7e7eSAKASHI Takahiro int ret; 21159df7e7eSAKASHI Takahiro 21259df7e7eSAKASHI Takahiro if (argc < 6 || argc > 7) 21359df7e7eSAKASHI Takahiro return CMD_RET_USAGE; 21459df7e7eSAKASHI Takahiro 21559df7e7eSAKASHI Takahiro id = (int)simple_strtoul(argv[1], &endp, 16); 21659df7e7eSAKASHI Takahiro if (*endp != '\0' || id > 0xffff) 21759df7e7eSAKASHI Takahiro return CMD_RET_FAILURE; 21859df7e7eSAKASHI Takahiro 21959df7e7eSAKASHI Takahiro sprintf(var_name, "Boot%04X", id); 22059df7e7eSAKASHI Takahiro p = var_name16; 22159df7e7eSAKASHI Takahiro utf8_utf16_strncpy(&p, var_name, 9); 22259df7e7eSAKASHI Takahiro 22359df7e7eSAKASHI Takahiro guid = efi_global_variable_guid; 22459df7e7eSAKASHI Takahiro 22559df7e7eSAKASHI Takahiro /* attributes */ 22659df7e7eSAKASHI Takahiro lo.attributes = LOAD_OPTION_ACTIVE; /* always ACTIVE */ 22759df7e7eSAKASHI Takahiro 22859df7e7eSAKASHI Takahiro /* label */ 22959df7e7eSAKASHI Takahiro label_len = strlen(argv[2]); 23059df7e7eSAKASHI Takahiro label_len16 = utf8_utf16_strnlen(argv[2], label_len); 23159df7e7eSAKASHI Takahiro label = malloc((label_len16 + 1) * sizeof(u16)); 23259df7e7eSAKASHI Takahiro if (!label) 23359df7e7eSAKASHI Takahiro return CMD_RET_FAILURE; 23459df7e7eSAKASHI Takahiro lo.label = label; /* label will be changed below */ 23559df7e7eSAKASHI Takahiro utf8_utf16_strncpy(&label, argv[2], label_len); 23659df7e7eSAKASHI Takahiro 23759df7e7eSAKASHI Takahiro /* file path */ 23859df7e7eSAKASHI Takahiro ret = efi_dp_from_name(argv[3], argv[4], argv[5], &device_path, 23959df7e7eSAKASHI Takahiro &file_path); 24059df7e7eSAKASHI Takahiro if (ret != EFI_SUCCESS) { 24159df7e7eSAKASHI Takahiro printf("Cannot create device path for \"%s %s\"\n", 24259df7e7eSAKASHI Takahiro argv[3], argv[4]); 24359df7e7eSAKASHI Takahiro ret = CMD_RET_FAILURE; 24459df7e7eSAKASHI Takahiro goto out; 24559df7e7eSAKASHI Takahiro } 24659df7e7eSAKASHI Takahiro lo.file_path = file_path; 24759df7e7eSAKASHI Takahiro lo.file_path_length = efi_dp_size(file_path) 24859df7e7eSAKASHI Takahiro + sizeof(struct efi_device_path); /* for END */ 24959df7e7eSAKASHI Takahiro 25059df7e7eSAKASHI Takahiro /* optional data */ 25159df7e7eSAKASHI Takahiro lo.optional_data = (u8 *)(argc == 6 ? "" : argv[6]); 25259df7e7eSAKASHI Takahiro 25359df7e7eSAKASHI Takahiro size = efi_serialize_load_option(&lo, (u8 **)&data); 25459df7e7eSAKASHI Takahiro if (!size) { 25559df7e7eSAKASHI Takahiro ret = CMD_RET_FAILURE; 25659df7e7eSAKASHI Takahiro goto out; 25759df7e7eSAKASHI Takahiro } 25859df7e7eSAKASHI Takahiro 25959df7e7eSAKASHI Takahiro ret = EFI_CALL(RT->set_variable(var_name16, &guid, 26059df7e7eSAKASHI Takahiro EFI_VARIABLE_BOOTSERVICE_ACCESS | 26159df7e7eSAKASHI Takahiro EFI_VARIABLE_RUNTIME_ACCESS, 26259df7e7eSAKASHI Takahiro size, data)); 26359df7e7eSAKASHI Takahiro ret = (ret == EFI_SUCCESS ? CMD_RET_SUCCESS : CMD_RET_FAILURE); 26459df7e7eSAKASHI Takahiro out: 26559df7e7eSAKASHI Takahiro free(data); 26659df7e7eSAKASHI Takahiro efi_free_pool(device_path); 26759df7e7eSAKASHI Takahiro efi_free_pool(file_path); 26859df7e7eSAKASHI Takahiro free(lo.label); 26959df7e7eSAKASHI Takahiro 27059df7e7eSAKASHI Takahiro return ret; 27159df7e7eSAKASHI Takahiro } 27259df7e7eSAKASHI Takahiro 27359df7e7eSAKASHI Takahiro /** 27459df7e7eSAKASHI Takahiro * do_efi_boot_rm() - delete UEFI load options 27559df7e7eSAKASHI Takahiro * 27659df7e7eSAKASHI Takahiro * @cmdtp: Command table 27759df7e7eSAKASHI Takahiro * @flag: Command flag 27859df7e7eSAKASHI Takahiro * @argc: Number of arguments 27959df7e7eSAKASHI Takahiro * @argv: Argument array 28059df7e7eSAKASHI Takahiro * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure 28159df7e7eSAKASHI Takahiro * 28259df7e7eSAKASHI Takahiro * Implement efidebug "boot rm" sub-command. 28359df7e7eSAKASHI Takahiro * Delete UEFI load options. 28459df7e7eSAKASHI Takahiro * - boot rm <id> ... 28559df7e7eSAKASHI Takahiro */ 28659df7e7eSAKASHI Takahiro static int do_efi_boot_rm(cmd_tbl_t *cmdtp, int flag, 28759df7e7eSAKASHI Takahiro int argc, char * const argv[]) 28859df7e7eSAKASHI Takahiro { 28959df7e7eSAKASHI Takahiro efi_guid_t guid; 29059df7e7eSAKASHI Takahiro int id, i; 29159df7e7eSAKASHI Takahiro char *endp; 29259df7e7eSAKASHI Takahiro char var_name[9]; 29359df7e7eSAKASHI Takahiro u16 var_name16[9]; 29459df7e7eSAKASHI Takahiro efi_status_t ret; 29559df7e7eSAKASHI Takahiro 29659df7e7eSAKASHI Takahiro if (argc == 1) 29759df7e7eSAKASHI Takahiro return CMD_RET_USAGE; 29859df7e7eSAKASHI Takahiro 29959df7e7eSAKASHI Takahiro guid = efi_global_variable_guid; 30059df7e7eSAKASHI Takahiro for (i = 1; i < argc; i++, argv++) { 30159df7e7eSAKASHI Takahiro id = (int)simple_strtoul(argv[1], &endp, 16); 30259df7e7eSAKASHI Takahiro if (*endp != '\0' || id > 0xffff) 30359df7e7eSAKASHI Takahiro return CMD_RET_FAILURE; 30459df7e7eSAKASHI Takahiro 30559df7e7eSAKASHI Takahiro sprintf(var_name, "Boot%04X", id); 30659df7e7eSAKASHI Takahiro utf8_utf16_strncpy((u16 **)&var_name16, var_name, 9); 30759df7e7eSAKASHI Takahiro 30859df7e7eSAKASHI Takahiro ret = EFI_CALL(RT->set_variable(var_name16, &guid, 0, 0, NULL)); 30959df7e7eSAKASHI Takahiro if (ret) { 31059df7e7eSAKASHI Takahiro printf("cannot remove Boot%04X", id); 31159df7e7eSAKASHI Takahiro return CMD_RET_FAILURE; 31259df7e7eSAKASHI Takahiro } 31359df7e7eSAKASHI Takahiro } 31459df7e7eSAKASHI Takahiro 31559df7e7eSAKASHI Takahiro return CMD_RET_SUCCESS; 31659df7e7eSAKASHI Takahiro } 31759df7e7eSAKASHI Takahiro 31859df7e7eSAKASHI Takahiro /** 31959df7e7eSAKASHI Takahiro * show_efi_boot_opt_data() - dump UEFI load option 32059df7e7eSAKASHI Takahiro * 32159df7e7eSAKASHI Takahiro * @id: Load option number 32259df7e7eSAKASHI Takahiro * @data: Value of UEFI load option variable 32359df7e7eSAKASHI Takahiro * 32459df7e7eSAKASHI Takahiro * Decode the value of UEFI load option variable and print information. 32559df7e7eSAKASHI Takahiro */ 32659df7e7eSAKASHI Takahiro static void show_efi_boot_opt_data(int id, void *data) 32759df7e7eSAKASHI Takahiro { 32859df7e7eSAKASHI Takahiro struct efi_load_option lo; 32959df7e7eSAKASHI Takahiro char *label, *p; 33059df7e7eSAKASHI Takahiro size_t label_len16, label_len; 33159df7e7eSAKASHI Takahiro u16 *dp_str; 33259df7e7eSAKASHI Takahiro 33359df7e7eSAKASHI Takahiro efi_deserialize_load_option(&lo, data); 33459df7e7eSAKASHI Takahiro 33559df7e7eSAKASHI Takahiro label_len16 = u16_strlen(lo.label); 33659df7e7eSAKASHI Takahiro label_len = utf16_utf8_strnlen(lo.label, label_len16); 33759df7e7eSAKASHI Takahiro label = malloc(label_len + 1); 33859df7e7eSAKASHI Takahiro if (!label) 33959df7e7eSAKASHI Takahiro return; 34059df7e7eSAKASHI Takahiro p = label; 34159df7e7eSAKASHI Takahiro utf16_utf8_strncpy(&p, lo.label, label_len16); 34259df7e7eSAKASHI Takahiro 34359df7e7eSAKASHI Takahiro printf("Boot%04X:\n", id); 34459df7e7eSAKASHI Takahiro printf("\tattributes: %c%c%c (0x%08x)\n", 34559df7e7eSAKASHI Takahiro /* ACTIVE */ 34659df7e7eSAKASHI Takahiro lo.attributes & LOAD_OPTION_ACTIVE ? 'A' : '-', 34759df7e7eSAKASHI Takahiro /* FORCE RECONNECT */ 34859df7e7eSAKASHI Takahiro lo.attributes & LOAD_OPTION_FORCE_RECONNECT ? 'R' : '-', 34959df7e7eSAKASHI Takahiro /* HIDDEN */ 35059df7e7eSAKASHI Takahiro lo.attributes & LOAD_OPTION_HIDDEN ? 'H' : '-', 35159df7e7eSAKASHI Takahiro lo.attributes); 35259df7e7eSAKASHI Takahiro printf("\tlabel: %s\n", label); 35359df7e7eSAKASHI Takahiro 35459df7e7eSAKASHI Takahiro dp_str = efi_dp_str(lo.file_path); 35559df7e7eSAKASHI Takahiro printf("\tfile_path: %ls\n", dp_str); 35659df7e7eSAKASHI Takahiro efi_free_pool(dp_str); 35759df7e7eSAKASHI Takahiro 35859df7e7eSAKASHI Takahiro printf("\tdata: %s\n", lo.optional_data); 35959df7e7eSAKASHI Takahiro 36059df7e7eSAKASHI Takahiro free(label); 36159df7e7eSAKASHI Takahiro } 36259df7e7eSAKASHI Takahiro 36359df7e7eSAKASHI Takahiro /** 36459df7e7eSAKASHI Takahiro * show_efi_boot_opt() - dump UEFI load option 36559df7e7eSAKASHI Takahiro * 36659df7e7eSAKASHI Takahiro * @id: Load option number 36759df7e7eSAKASHI Takahiro * 36859df7e7eSAKASHI Takahiro * Dump information defined by UEFI load option. 36959df7e7eSAKASHI Takahiro */ 37059df7e7eSAKASHI Takahiro static void show_efi_boot_opt(int id) 37159df7e7eSAKASHI Takahiro { 37259df7e7eSAKASHI Takahiro char var_name[9]; 37359df7e7eSAKASHI Takahiro u16 var_name16[9], *p; 37459df7e7eSAKASHI Takahiro efi_guid_t guid; 37559df7e7eSAKASHI Takahiro void *data = NULL; 37659df7e7eSAKASHI Takahiro efi_uintn_t size; 37759df7e7eSAKASHI Takahiro int ret; 37859df7e7eSAKASHI Takahiro 37959df7e7eSAKASHI Takahiro sprintf(var_name, "Boot%04X", id); 38059df7e7eSAKASHI Takahiro p = var_name16; 38159df7e7eSAKASHI Takahiro utf8_utf16_strncpy(&p, var_name, 9); 38259df7e7eSAKASHI Takahiro guid = efi_global_variable_guid; 38359df7e7eSAKASHI Takahiro 38459df7e7eSAKASHI Takahiro size = 0; 38559df7e7eSAKASHI Takahiro ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size, NULL)); 38659df7e7eSAKASHI Takahiro if (ret == (int)EFI_BUFFER_TOO_SMALL) { 38759df7e7eSAKASHI Takahiro data = malloc(size); 38859df7e7eSAKASHI Takahiro ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size, 38959df7e7eSAKASHI Takahiro data)); 39059df7e7eSAKASHI Takahiro } 39159df7e7eSAKASHI Takahiro if (ret == EFI_SUCCESS) 39259df7e7eSAKASHI Takahiro show_efi_boot_opt_data(id, data); 39359df7e7eSAKASHI Takahiro else if (ret == EFI_NOT_FOUND) 39459df7e7eSAKASHI Takahiro printf("Boot%04X: not found\n", id); 39559df7e7eSAKASHI Takahiro 39659df7e7eSAKASHI Takahiro free(data); 39759df7e7eSAKASHI Takahiro } 39859df7e7eSAKASHI Takahiro 39959df7e7eSAKASHI Takahiro /** 40059df7e7eSAKASHI Takahiro * show_efi_boot_dump() - dump all UEFI load options 40159df7e7eSAKASHI Takahiro * 40259df7e7eSAKASHI Takahiro * @cmdtp: Command table 40359df7e7eSAKASHI Takahiro * @flag: Command flag 40459df7e7eSAKASHI Takahiro * @argc: Number of arguments 40559df7e7eSAKASHI Takahiro * @argv: Argument array 40659df7e7eSAKASHI Takahiro * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure 40759df7e7eSAKASHI Takahiro * 40859df7e7eSAKASHI Takahiro * Implement efidebug "boot dump" sub-command. 40959df7e7eSAKASHI Takahiro * Dump information of all UEFI load options defined. 41059df7e7eSAKASHI Takahiro * - boot dump 41159df7e7eSAKASHI Takahiro */ 41259df7e7eSAKASHI Takahiro static int do_efi_boot_dump(cmd_tbl_t *cmdtp, int flag, 41359df7e7eSAKASHI Takahiro int argc, char * const argv[]) 41459df7e7eSAKASHI Takahiro { 41559df7e7eSAKASHI Takahiro char regex[256]; 41659df7e7eSAKASHI Takahiro char * const regexlist[] = {regex}; 41759df7e7eSAKASHI Takahiro char *variables = NULL, *boot, *value; 41859df7e7eSAKASHI Takahiro int len; 41959df7e7eSAKASHI Takahiro int id; 42059df7e7eSAKASHI Takahiro 42159df7e7eSAKASHI Takahiro if (argc > 1) 42259df7e7eSAKASHI Takahiro return CMD_RET_USAGE; 42359df7e7eSAKASHI Takahiro 42459df7e7eSAKASHI Takahiro snprintf(regex, 256, "efi_.*-.*-.*-.*-.*_Boot[0-9A-F]+"); 42559df7e7eSAKASHI Takahiro 42659df7e7eSAKASHI Takahiro /* TODO: use GetNextVariableName? */ 42759df7e7eSAKASHI Takahiro len = hexport_r(&env_htab, '\n', H_MATCH_REGEX | H_MATCH_KEY, 42859df7e7eSAKASHI Takahiro &variables, 0, 1, regexlist); 42959df7e7eSAKASHI Takahiro 43059df7e7eSAKASHI Takahiro if (!len) 43159df7e7eSAKASHI Takahiro return CMD_RET_SUCCESS; 43259df7e7eSAKASHI Takahiro 43359df7e7eSAKASHI Takahiro if (len < 0) 43459df7e7eSAKASHI Takahiro return CMD_RET_FAILURE; 43559df7e7eSAKASHI Takahiro 43659df7e7eSAKASHI Takahiro boot = variables; 43759df7e7eSAKASHI Takahiro while (*boot) { 43859df7e7eSAKASHI Takahiro value = strstr(boot, "Boot") + 4; 43959df7e7eSAKASHI Takahiro id = (int)simple_strtoul(value, NULL, 16); 44059df7e7eSAKASHI Takahiro show_efi_boot_opt(id); 44159df7e7eSAKASHI Takahiro boot = strchr(boot, '\n'); 44259df7e7eSAKASHI Takahiro if (!*boot) 44359df7e7eSAKASHI Takahiro break; 44459df7e7eSAKASHI Takahiro boot++; 44559df7e7eSAKASHI Takahiro } 44659df7e7eSAKASHI Takahiro free(variables); 44759df7e7eSAKASHI Takahiro 44859df7e7eSAKASHI Takahiro return CMD_RET_SUCCESS; 44959df7e7eSAKASHI Takahiro } 45059df7e7eSAKASHI Takahiro 45159df7e7eSAKASHI Takahiro /** 45259df7e7eSAKASHI Takahiro * show_efi_boot_order() - show order of UEFI load options 45359df7e7eSAKASHI Takahiro * 45459df7e7eSAKASHI Takahiro * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure 45559df7e7eSAKASHI Takahiro * 45659df7e7eSAKASHI Takahiro * Show order of UEFI load options defined by BootOrder variable. 45759df7e7eSAKASHI Takahiro */ 45859df7e7eSAKASHI Takahiro static int show_efi_boot_order(void) 45959df7e7eSAKASHI Takahiro { 46059df7e7eSAKASHI Takahiro efi_guid_t guid; 46159df7e7eSAKASHI Takahiro u16 *bootorder = NULL; 46259df7e7eSAKASHI Takahiro efi_uintn_t size; 46359df7e7eSAKASHI Takahiro int num, i; 46459df7e7eSAKASHI Takahiro char var_name[9]; 46559df7e7eSAKASHI Takahiro u16 var_name16[9], *p16; 46659df7e7eSAKASHI Takahiro void *data; 46759df7e7eSAKASHI Takahiro struct efi_load_option lo; 46859df7e7eSAKASHI Takahiro char *label, *p; 46959df7e7eSAKASHI Takahiro size_t label_len16, label_len; 47059df7e7eSAKASHI Takahiro efi_status_t ret; 47159df7e7eSAKASHI Takahiro 47259df7e7eSAKASHI Takahiro guid = efi_global_variable_guid; 47359df7e7eSAKASHI Takahiro size = 0; 47459df7e7eSAKASHI Takahiro ret = EFI_CALL(RT->get_variable(L"BootOrder", &guid, NULL, &size, 47559df7e7eSAKASHI Takahiro NULL)); 47659df7e7eSAKASHI Takahiro if (ret == EFI_BUFFER_TOO_SMALL) { 47759df7e7eSAKASHI Takahiro bootorder = malloc(size); 47859df7e7eSAKASHI Takahiro ret = EFI_CALL(RT->get_variable(L"BootOrder", &guid, NULL, 47959df7e7eSAKASHI Takahiro &size, bootorder)); 48059df7e7eSAKASHI Takahiro } 48159df7e7eSAKASHI Takahiro if (ret == EFI_NOT_FOUND) { 48259df7e7eSAKASHI Takahiro printf("BootOrder not defined\n"); 48359df7e7eSAKASHI Takahiro ret = CMD_RET_SUCCESS; 48459df7e7eSAKASHI Takahiro goto out; 48559df7e7eSAKASHI Takahiro } else if (ret != EFI_SUCCESS) { 48659df7e7eSAKASHI Takahiro ret = CMD_RET_FAILURE; 48759df7e7eSAKASHI Takahiro goto out; 48859df7e7eSAKASHI Takahiro } 48959df7e7eSAKASHI Takahiro 49059df7e7eSAKASHI Takahiro num = size / sizeof(u16); 49159df7e7eSAKASHI Takahiro for (i = 0; i < num; i++) { 49259df7e7eSAKASHI Takahiro sprintf(var_name, "Boot%04X", bootorder[i]); 49359df7e7eSAKASHI Takahiro p16 = var_name16; 49459df7e7eSAKASHI Takahiro utf8_utf16_strncpy(&p16, var_name, 9); 49559df7e7eSAKASHI Takahiro 49659df7e7eSAKASHI Takahiro size = 0; 49759df7e7eSAKASHI Takahiro ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size, 49859df7e7eSAKASHI Takahiro NULL)); 49959df7e7eSAKASHI Takahiro if (ret != EFI_BUFFER_TOO_SMALL) { 50059df7e7eSAKASHI Takahiro printf("%2d: Boot%04X: (not defined)\n", 50159df7e7eSAKASHI Takahiro i + 1, bootorder[i]); 50259df7e7eSAKASHI Takahiro continue; 50359df7e7eSAKASHI Takahiro } 50459df7e7eSAKASHI Takahiro 50559df7e7eSAKASHI Takahiro data = malloc(size); 50659df7e7eSAKASHI Takahiro if (!data) { 50759df7e7eSAKASHI Takahiro ret = CMD_RET_FAILURE; 50859df7e7eSAKASHI Takahiro goto out; 50959df7e7eSAKASHI Takahiro } 51059df7e7eSAKASHI Takahiro ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size, 51159df7e7eSAKASHI Takahiro data)); 51259df7e7eSAKASHI Takahiro if (ret != EFI_SUCCESS) { 51359df7e7eSAKASHI Takahiro free(data); 51459df7e7eSAKASHI Takahiro ret = CMD_RET_FAILURE; 51559df7e7eSAKASHI Takahiro goto out; 51659df7e7eSAKASHI Takahiro } 51759df7e7eSAKASHI Takahiro 51859df7e7eSAKASHI Takahiro efi_deserialize_load_option(&lo, data); 51959df7e7eSAKASHI Takahiro 52059df7e7eSAKASHI Takahiro label_len16 = u16_strlen(lo.label); 52159df7e7eSAKASHI Takahiro label_len = utf16_utf8_strnlen(lo.label, label_len16); 52259df7e7eSAKASHI Takahiro label = malloc(label_len + 1); 52359df7e7eSAKASHI Takahiro if (!label) { 52459df7e7eSAKASHI Takahiro free(data); 52559df7e7eSAKASHI Takahiro ret = CMD_RET_FAILURE; 52659df7e7eSAKASHI Takahiro goto out; 52759df7e7eSAKASHI Takahiro } 52859df7e7eSAKASHI Takahiro p = label; 52959df7e7eSAKASHI Takahiro utf16_utf8_strncpy(&p, lo.label, label_len16); 53059df7e7eSAKASHI Takahiro printf("%2d: Boot%04X: %s\n", i + 1, bootorder[i], label); 53159df7e7eSAKASHI Takahiro free(label); 53259df7e7eSAKASHI Takahiro 53359df7e7eSAKASHI Takahiro free(data); 53459df7e7eSAKASHI Takahiro } 53559df7e7eSAKASHI Takahiro out: 53659df7e7eSAKASHI Takahiro free(bootorder); 53759df7e7eSAKASHI Takahiro 53859df7e7eSAKASHI Takahiro return ret; 53959df7e7eSAKASHI Takahiro } 54059df7e7eSAKASHI Takahiro 54159df7e7eSAKASHI Takahiro /** 54259df7e7eSAKASHI Takahiro * do_efi_boot_next() - manage UEFI BootNext variable 54359df7e7eSAKASHI Takahiro * 54459df7e7eSAKASHI Takahiro * @cmdtp: Command table 54559df7e7eSAKASHI Takahiro * @flag: Command flag 54659df7e7eSAKASHI Takahiro * @argc: Number of arguments 54759df7e7eSAKASHI Takahiro * @argv: Argument array 54859df7e7eSAKASHI Takahiro * Return: CMD_RET_SUCCESS on success, 54959df7e7eSAKASHI Takahiro * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure 55059df7e7eSAKASHI Takahiro * 55159df7e7eSAKASHI Takahiro * Implement efidebug "boot next" sub-command. 55259df7e7eSAKASHI Takahiro * Set BootNext variable. 55359df7e7eSAKASHI Takahiro * - boot next <id> 55459df7e7eSAKASHI Takahiro */ 55559df7e7eSAKASHI Takahiro static int do_efi_boot_next(cmd_tbl_t *cmdtp, int flag, 55659df7e7eSAKASHI Takahiro int argc, char * const argv[]) 55759df7e7eSAKASHI Takahiro { 55859df7e7eSAKASHI Takahiro u16 bootnext; 55959df7e7eSAKASHI Takahiro efi_uintn_t size; 56059df7e7eSAKASHI Takahiro char *endp; 56159df7e7eSAKASHI Takahiro efi_guid_t guid; 56259df7e7eSAKASHI Takahiro efi_status_t ret; 56359df7e7eSAKASHI Takahiro 56459df7e7eSAKASHI Takahiro if (argc != 2) 56559df7e7eSAKASHI Takahiro return CMD_RET_USAGE; 56659df7e7eSAKASHI Takahiro 56759df7e7eSAKASHI Takahiro bootnext = (u16)simple_strtoul(argv[1], &endp, 16); 56859df7e7eSAKASHI Takahiro if (*endp != '\0' || bootnext > 0xffff) { 56959df7e7eSAKASHI Takahiro printf("invalid value: %s\n", argv[1]); 57059df7e7eSAKASHI Takahiro ret = CMD_RET_FAILURE; 57159df7e7eSAKASHI Takahiro goto out; 57259df7e7eSAKASHI Takahiro } 57359df7e7eSAKASHI Takahiro 57459df7e7eSAKASHI Takahiro guid = efi_global_variable_guid; 57559df7e7eSAKASHI Takahiro size = sizeof(u16); 57659df7e7eSAKASHI Takahiro ret = EFI_CALL(RT->set_variable(L"BootNext", &guid, 57759df7e7eSAKASHI Takahiro EFI_VARIABLE_BOOTSERVICE_ACCESS | 57859df7e7eSAKASHI Takahiro EFI_VARIABLE_RUNTIME_ACCESS, 57959df7e7eSAKASHI Takahiro size, &bootnext)); 58059df7e7eSAKASHI Takahiro ret = (ret == EFI_SUCCESS ? CMD_RET_SUCCESS : CMD_RET_FAILURE); 58159df7e7eSAKASHI Takahiro out: 58259df7e7eSAKASHI Takahiro return ret; 58359df7e7eSAKASHI Takahiro } 58459df7e7eSAKASHI Takahiro 58559df7e7eSAKASHI Takahiro /** 58659df7e7eSAKASHI Takahiro * do_efi_boot_order() - manage UEFI BootOrder variable 58759df7e7eSAKASHI Takahiro * 58859df7e7eSAKASHI Takahiro * @cmdtp: Command table 58959df7e7eSAKASHI Takahiro * @flag: Command flag 59059df7e7eSAKASHI Takahiro * @argc: Number of arguments 59159df7e7eSAKASHI Takahiro * @argv: Argument array 59259df7e7eSAKASHI Takahiro * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure 59359df7e7eSAKASHI Takahiro * 59459df7e7eSAKASHI Takahiro * Implement efidebug "boot order" sub-command. 59559df7e7eSAKASHI Takahiro * Show order of UEFI load options, or change it in BootOrder variable. 59659df7e7eSAKASHI Takahiro * - boot order [<id> ...] 59759df7e7eSAKASHI Takahiro */ 59859df7e7eSAKASHI Takahiro static int do_efi_boot_order(cmd_tbl_t *cmdtp, int flag, 59959df7e7eSAKASHI Takahiro int argc, char * const argv[]) 60059df7e7eSAKASHI Takahiro { 60159df7e7eSAKASHI Takahiro u16 *bootorder = NULL; 60259df7e7eSAKASHI Takahiro efi_uintn_t size; 60359df7e7eSAKASHI Takahiro int id, i; 60459df7e7eSAKASHI Takahiro char *endp; 60559df7e7eSAKASHI Takahiro efi_guid_t guid; 60659df7e7eSAKASHI Takahiro efi_status_t ret; 60759df7e7eSAKASHI Takahiro 60859df7e7eSAKASHI Takahiro if (argc == 1) 60959df7e7eSAKASHI Takahiro return show_efi_boot_order(); 61059df7e7eSAKASHI Takahiro 61159df7e7eSAKASHI Takahiro argc--; 61259df7e7eSAKASHI Takahiro argv++; 61359df7e7eSAKASHI Takahiro 61459df7e7eSAKASHI Takahiro size = argc * sizeof(u16); 61559df7e7eSAKASHI Takahiro bootorder = malloc(size); 61659df7e7eSAKASHI Takahiro if (!bootorder) 61759df7e7eSAKASHI Takahiro return CMD_RET_FAILURE; 61859df7e7eSAKASHI Takahiro 61959df7e7eSAKASHI Takahiro for (i = 0; i < argc; i++) { 62059df7e7eSAKASHI Takahiro id = (int)simple_strtoul(argv[i], &endp, 16); 62159df7e7eSAKASHI Takahiro if (*endp != '\0' || id > 0xffff) { 62259df7e7eSAKASHI Takahiro printf("invalid value: %s\n", argv[i]); 62359df7e7eSAKASHI Takahiro ret = CMD_RET_FAILURE; 62459df7e7eSAKASHI Takahiro goto out; 62559df7e7eSAKASHI Takahiro } 62659df7e7eSAKASHI Takahiro 62759df7e7eSAKASHI Takahiro bootorder[i] = (u16)id; 62859df7e7eSAKASHI Takahiro } 62959df7e7eSAKASHI Takahiro 63059df7e7eSAKASHI Takahiro guid = efi_global_variable_guid; 63159df7e7eSAKASHI Takahiro ret = EFI_CALL(RT->set_variable(L"BootOrder", &guid, 63259df7e7eSAKASHI Takahiro EFI_VARIABLE_BOOTSERVICE_ACCESS | 63359df7e7eSAKASHI Takahiro EFI_VARIABLE_RUNTIME_ACCESS, 63459df7e7eSAKASHI Takahiro size, bootorder)); 63559df7e7eSAKASHI Takahiro ret = (ret == EFI_SUCCESS ? CMD_RET_SUCCESS : CMD_RET_FAILURE); 63659df7e7eSAKASHI Takahiro out: 63759df7e7eSAKASHI Takahiro free(bootorder); 63859df7e7eSAKASHI Takahiro 63959df7e7eSAKASHI Takahiro return ret; 64059df7e7eSAKASHI Takahiro } 64159df7e7eSAKASHI Takahiro 64259df7e7eSAKASHI Takahiro static cmd_tbl_t cmd_efidebug_boot_sub[] = { 64359df7e7eSAKASHI Takahiro U_BOOT_CMD_MKENT(add, CONFIG_SYS_MAXARGS, 1, do_efi_boot_add, "", ""), 64459df7e7eSAKASHI Takahiro U_BOOT_CMD_MKENT(rm, CONFIG_SYS_MAXARGS, 1, do_efi_boot_rm, "", ""), 64559df7e7eSAKASHI Takahiro U_BOOT_CMD_MKENT(dump, CONFIG_SYS_MAXARGS, 1, do_efi_boot_dump, "", ""), 64659df7e7eSAKASHI Takahiro U_BOOT_CMD_MKENT(next, CONFIG_SYS_MAXARGS, 1, do_efi_boot_next, "", ""), 64759df7e7eSAKASHI Takahiro U_BOOT_CMD_MKENT(order, CONFIG_SYS_MAXARGS, 1, do_efi_boot_order, 64859df7e7eSAKASHI Takahiro "", ""), 64959df7e7eSAKASHI Takahiro }; 65059df7e7eSAKASHI Takahiro 65159df7e7eSAKASHI Takahiro /** 65259df7e7eSAKASHI Takahiro * do_efi_boot_opt() - manage UEFI load options 65359df7e7eSAKASHI Takahiro * 65459df7e7eSAKASHI Takahiro * @cmdtp: Command table 65559df7e7eSAKASHI Takahiro * @flag: Command flag 65659df7e7eSAKASHI Takahiro * @argc: Number of arguments 65759df7e7eSAKASHI Takahiro * @argv: Argument array 65859df7e7eSAKASHI Takahiro * Return: CMD_RET_SUCCESS on success, 65959df7e7eSAKASHI Takahiro * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure 66059df7e7eSAKASHI Takahiro * 66159df7e7eSAKASHI Takahiro * Implement efidebug "boot" sub-command. 66259df7e7eSAKASHI Takahiro * See above for details of sub-commands. 66359df7e7eSAKASHI Takahiro */ 66459df7e7eSAKASHI Takahiro static int do_efi_boot_opt(cmd_tbl_t *cmdtp, int flag, 66559df7e7eSAKASHI Takahiro int argc, char * const argv[]) 66659df7e7eSAKASHI Takahiro { 66759df7e7eSAKASHI Takahiro cmd_tbl_t *cp; 66859df7e7eSAKASHI Takahiro 66959df7e7eSAKASHI Takahiro if (argc < 2) 67059df7e7eSAKASHI Takahiro return CMD_RET_USAGE; 67159df7e7eSAKASHI Takahiro 67259df7e7eSAKASHI Takahiro argc--; argv++; 67359df7e7eSAKASHI Takahiro 67459df7e7eSAKASHI Takahiro cp = find_cmd_tbl(argv[0], cmd_efidebug_boot_sub, 67559df7e7eSAKASHI Takahiro ARRAY_SIZE(cmd_efidebug_boot_sub)); 67659df7e7eSAKASHI Takahiro if (!cp) 67759df7e7eSAKASHI Takahiro return CMD_RET_USAGE; 67859df7e7eSAKASHI Takahiro 67959df7e7eSAKASHI Takahiro return cp->cmd(cmdtp, flag, argc, argv); 68059df7e7eSAKASHI Takahiro } 68159df7e7eSAKASHI Takahiro 68259df7e7eSAKASHI Takahiro static cmd_tbl_t cmd_efidebug_sub[] = { 68359df7e7eSAKASHI Takahiro U_BOOT_CMD_MKENT(boot, CONFIG_SYS_MAXARGS, 1, do_efi_boot_opt, "", ""), 684355cdb5aSAKASHI Takahiro U_BOOT_CMD_MKENT(devices, CONFIG_SYS_MAXARGS, 1, do_efi_show_devices, 685355cdb5aSAKASHI Takahiro "", ""), 686*66eaf566SAKASHI Takahiro U_BOOT_CMD_MKENT(drivers, CONFIG_SYS_MAXARGS, 1, do_efi_show_drivers, 687*66eaf566SAKASHI Takahiro "", ""), 68859df7e7eSAKASHI Takahiro }; 68959df7e7eSAKASHI Takahiro 69059df7e7eSAKASHI Takahiro /** 69159df7e7eSAKASHI Takahiro * do_efidebug() - display and configure UEFI environment 69259df7e7eSAKASHI Takahiro * 69359df7e7eSAKASHI Takahiro * @cmdtp: Command table 69459df7e7eSAKASHI Takahiro * @flag: Command flag 69559df7e7eSAKASHI Takahiro * @argc: Number of arguments 69659df7e7eSAKASHI Takahiro * @argv: Argument array 69759df7e7eSAKASHI Takahiro * Return: CMD_RET_SUCCESS on success, 69859df7e7eSAKASHI Takahiro * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure 69959df7e7eSAKASHI Takahiro * 70059df7e7eSAKASHI Takahiro * Implement efidebug command which allows us to display and 70159df7e7eSAKASHI Takahiro * configure UEFI environment. 70259df7e7eSAKASHI Takahiro * See above for details of sub-commands. 70359df7e7eSAKASHI Takahiro */ 70459df7e7eSAKASHI Takahiro static int do_efidebug(cmd_tbl_t *cmdtp, int flag, 70559df7e7eSAKASHI Takahiro int argc, char * const argv[]) 70659df7e7eSAKASHI Takahiro { 70759df7e7eSAKASHI Takahiro cmd_tbl_t *cp; 70859df7e7eSAKASHI Takahiro efi_status_t r; 70959df7e7eSAKASHI Takahiro 71059df7e7eSAKASHI Takahiro if (argc < 2) 71159df7e7eSAKASHI Takahiro return CMD_RET_USAGE; 71259df7e7eSAKASHI Takahiro 71359df7e7eSAKASHI Takahiro argc--; argv++; 71459df7e7eSAKASHI Takahiro 71559df7e7eSAKASHI Takahiro /* Initialize UEFI drivers */ 71659df7e7eSAKASHI Takahiro r = efi_init_obj_list(); 71759df7e7eSAKASHI Takahiro if (r != EFI_SUCCESS) { 71859df7e7eSAKASHI Takahiro printf("Error: Cannot initialize UEFI sub-system, r = %lu\n", 71959df7e7eSAKASHI Takahiro r & ~EFI_ERROR_MASK); 72059df7e7eSAKASHI Takahiro return CMD_RET_FAILURE; 72159df7e7eSAKASHI Takahiro } 72259df7e7eSAKASHI Takahiro 72359df7e7eSAKASHI Takahiro cp = find_cmd_tbl(argv[0], cmd_efidebug_sub, 72459df7e7eSAKASHI Takahiro ARRAY_SIZE(cmd_efidebug_sub)); 72559df7e7eSAKASHI Takahiro if (!cp) 72659df7e7eSAKASHI Takahiro return CMD_RET_USAGE; 72759df7e7eSAKASHI Takahiro 72859df7e7eSAKASHI Takahiro return cp->cmd(cmdtp, flag, argc, argv); 72959df7e7eSAKASHI Takahiro } 73059df7e7eSAKASHI Takahiro 73159df7e7eSAKASHI Takahiro #ifdef CONFIG_SYS_LONGHELP 73259df7e7eSAKASHI Takahiro static char efidebug_help_text[] = 73359df7e7eSAKASHI Takahiro " - UEFI Shell-like interface to configure UEFI environment\n" 73459df7e7eSAKASHI Takahiro "\n" 73559df7e7eSAKASHI Takahiro "efidebug boot add <bootid> <label> <interface> <devnum>[:<part>] <file path> [<load options>]\n" 73659df7e7eSAKASHI Takahiro " - set UEFI BootXXXX variable\n" 73759df7e7eSAKASHI Takahiro " <load options> will be passed to UEFI application\n" 73859df7e7eSAKASHI Takahiro "efidebug boot rm <bootid#1> [<bootid#2> [<bootid#3> [...]]]\n" 73959df7e7eSAKASHI Takahiro " - delete UEFI BootXXXX variables\n" 74059df7e7eSAKASHI Takahiro "efidebug boot dump\n" 74159df7e7eSAKASHI Takahiro " - dump all UEFI BootXXXX variables\n" 74259df7e7eSAKASHI Takahiro "efidebug boot next <bootid>\n" 74359df7e7eSAKASHI Takahiro " - set UEFI BootNext variable\n" 74459df7e7eSAKASHI Takahiro "efidebug boot order [<bootid#1> [<bootid#2> [<bootid#3> [...]]]]\n" 74559df7e7eSAKASHI Takahiro " - set/show UEFI boot order\n" 746355cdb5aSAKASHI Takahiro "\n" 747355cdb5aSAKASHI Takahiro "efidebug devices\n" 748*66eaf566SAKASHI Takahiro " - show uefi devices\n" 749*66eaf566SAKASHI Takahiro "efidebug drivers\n" 750*66eaf566SAKASHI Takahiro " - show uefi drivers\n"; 75159df7e7eSAKASHI Takahiro #endif 75259df7e7eSAKASHI Takahiro 75359df7e7eSAKASHI Takahiro U_BOOT_CMD( 75459df7e7eSAKASHI Takahiro efidebug, 10, 0, do_efidebug, 75559df7e7eSAKASHI Takahiro "Configure UEFI environment", 75659df7e7eSAKASHI Takahiro efidebug_help_text 75759df7e7eSAKASHI Takahiro ); 758