efidebug.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * UEFI Shell-like command
  4. *
  5. * Copyright (c) 2018 AKASHI Takahiro, Linaro Limited
  6. */
  7. #include <charset.h>
  8. #include <common.h>
  9. #include <command.h>
  10. #include <efi_loader.h>
  11. #include <exports.h>
  12. #include <hexdump.h>
  13. #include <malloc.h>
  14. #include <mapmem.h>
  15. #include <search.h>
  16. #include <linux/ctype.h>
  17. #define BS systab.boottime
  18. /**
  19. * efi_get_device_handle_info() - get information of UEFI device
  20. *
  21. * @handle: Handle of UEFI device
  22. * @dev_path_text: Pointer to text of device path
  23. * Return: 0 on success, -1 on failure
  24. *
  25. * Currently return a formatted text of device path.
  26. */
  27. static int efi_get_device_handle_info(efi_handle_t handle, u16 **dev_path_text)
  28. {
  29. struct efi_device_path *dp;
  30. efi_status_t ret;
  31. ret = EFI_CALL(BS->open_protocol(handle, &efi_guid_device_path,
  32. (void **)&dp, NULL /* FIXME */, NULL,
  33. EFI_OPEN_PROTOCOL_GET_PROTOCOL));
  34. if (ret == EFI_SUCCESS) {
  35. *dev_path_text = efi_dp_str(dp);
  36. return 0;
  37. } else {
  38. return -1;
  39. }
  40. }
  41. #define EFI_HANDLE_WIDTH ((int)sizeof(efi_handle_t) * 2)
  42. static const char spc[] = " ";
  43. static const char sep[] = "================";
  44. /**
  45. * do_efi_show_devices() - show UEFI devices
  46. *
  47. * @cmdtp: Command table
  48. * @flag: Command flag
  49. * @argc: Number of arguments
  50. * @argv: Argument array
  51. * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
  52. *
  53. * Implement efidebug "devices" sub-command.
  54. * Show all UEFI devices and their information.
  55. */
  56. static int do_efi_show_devices(cmd_tbl_t *cmdtp, int flag,
  57. int argc, char * const argv[])
  58. {
  59. efi_handle_t *handles;
  60. efi_uintn_t num, i;
  61. u16 *dev_path_text;
  62. efi_status_t ret;
  63. ret = EFI_CALL(efi_locate_handle_buffer(ALL_HANDLES, NULL, NULL,
  64. &num, &handles));
  65. if (ret != EFI_SUCCESS)
  66. return CMD_RET_FAILURE;
  67. if (!num)
  68. return CMD_RET_SUCCESS;
  69. printf("Device%.*s Device Path\n", EFI_HANDLE_WIDTH - 6, spc);
  70. printf("%.*s ====================\n", EFI_HANDLE_WIDTH, sep);
  71. for (i = 0; i < num; i++) {
  72. if (!efi_get_device_handle_info(handles[i], &dev_path_text)) {
  73. printf("%p %ls\n", handles[i], dev_path_text);
  74. efi_free_pool(dev_path_text);
  75. }
  76. }
  77. efi_free_pool(handles);
  78. return CMD_RET_SUCCESS;
  79. }
  80. /**
  81. * efi_get_driver_handle_info() - get information of UEFI driver
  82. *
  83. * @handle: Handle of UEFI device
  84. * @driver_name: Driver name
  85. * @image_path: Pointer to text of device path
  86. * Return: 0 on success, -1 on failure
  87. *
  88. * Currently return no useful information as all UEFI drivers are
  89. * built-in..
  90. */
  91. static int efi_get_driver_handle_info(efi_handle_t handle, u16 **driver_name,
  92. u16 **image_path)
  93. {
  94. struct efi_handler *handler;
  95. struct efi_loaded_image *image;
  96. efi_status_t ret;
  97. /*
  98. * driver name
  99. * TODO: support EFI_COMPONENT_NAME2_PROTOCOL
  100. */
  101. *driver_name = NULL;
  102. /* image name */
  103. ret = efi_search_protocol(handle, &efi_guid_loaded_image, &handler);
  104. if (ret != EFI_SUCCESS) {
  105. *image_path = NULL;
  106. return 0;
  107. }
  108. image = handler->protocol_interface;
  109. *image_path = efi_dp_str(image->file_path);
  110. return 0;
  111. }
  112. /**
  113. * do_efi_show_drivers() - show UEFI drivers
  114. *
  115. * @cmdtp: Command table
  116. * @flag: Command flag
  117. * @argc: Number of arguments
  118. * @argv: Argument array
  119. * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
  120. *
  121. * Implement efidebug "drivers" sub-command.
  122. * Show all UEFI drivers and their information.
  123. */
  124. static int do_efi_show_drivers(cmd_tbl_t *cmdtp, int flag,
  125. int argc, char * const argv[])
  126. {
  127. efi_handle_t *handles;
  128. efi_uintn_t num, i;
  129. u16 *driver_name, *image_path_text;
  130. efi_status_t ret;
  131. ret = EFI_CALL(efi_locate_handle_buffer(
  132. BY_PROTOCOL, &efi_guid_driver_binding_protocol,
  133. NULL, &num, &handles));
  134. if (ret != EFI_SUCCESS)
  135. return CMD_RET_FAILURE;
  136. if (!num)
  137. return CMD_RET_SUCCESS;
  138. printf("Driver%.*s Name Image Path\n",
  139. EFI_HANDLE_WIDTH - 6, spc);
  140. printf("%.*s ==================== ====================\n",
  141. EFI_HANDLE_WIDTH, sep);
  142. for (i = 0; i < num; i++) {
  143. if (!efi_get_driver_handle_info(handles[i], &driver_name,
  144. &image_path_text)) {
  145. if (image_path_text)
  146. printf("%p %-20ls %ls\n", handles[i],
  147. driver_name, image_path_text);
  148. else
  149. printf("%p %-20ls <built-in>\n",
  150. handles[i], driver_name);
  151. efi_free_pool(driver_name);
  152. efi_free_pool(image_path_text);
  153. }
  154. }
  155. efi_free_pool(handles);
  156. return CMD_RET_SUCCESS;
  157. }
  158. static const struct {
  159. const char *text;
  160. const efi_guid_t guid;
  161. } guid_list[] = {
  162. {
  163. "Device Path",
  164. EFI_DEVICE_PATH_PROTOCOL_GUID,
  165. },
  166. {
  167. "Device Path To Text",
  168. EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID,
  169. },
  170. {
  171. "Device Path Utilities",
  172. EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID,
  173. },
  174. {
  175. "Unicode Collation 2",
  176. EFI_UNICODE_COLLATION_PROTOCOL2_GUID,
  177. },
  178. {
  179. "Driver Binding",
  180. EFI_DRIVER_BINDING_PROTOCOL_GUID,
  181. },
  182. {
  183. "Simple Text Input",
  184. EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID,
  185. },
  186. {
  187. "Simple Text Input Ex",
  188. EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID,
  189. },
  190. {
  191. "Simple Text Output",
  192. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID,
  193. },
  194. {
  195. "Block IO",
  196. EFI_BLOCK_IO_PROTOCOL_GUID,
  197. },
  198. {
  199. "Simple File System",
  200. EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID,
  201. },
  202. {
  203. "Loaded Image",
  204. EFI_LOADED_IMAGE_PROTOCOL_GUID,
  205. },
  206. {
  207. "Graphics Output",
  208. EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID,
  209. },
  210. {
  211. "HII String",
  212. EFI_HII_STRING_PROTOCOL_GUID,
  213. },
  214. {
  215. "HII Database",
  216. EFI_HII_DATABASE_PROTOCOL_GUID,
  217. },
  218. {
  219. "HII Config Routing",
  220. EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID,
  221. },
  222. {
  223. "Load File2",
  224. EFI_LOAD_FILE2_PROTOCOL_GUID,
  225. },
  226. {
  227. "Simple Network",
  228. EFI_SIMPLE_NETWORK_PROTOCOL_GUID,
  229. },
  230. {
  231. "PXE Base Code",
  232. EFI_PXE_BASE_CODE_PROTOCOL_GUID,
  233. },
  234. /* Configuration table GUIDs */
  235. {
  236. "ACPI table",
  237. EFI_ACPI_TABLE_GUID,
  238. },
  239. {
  240. "device tree",
  241. EFI_FDT_GUID,
  242. },
  243. {
  244. "SMBIOS table",
  245. SMBIOS_TABLE_GUID,
  246. },
  247. {
  248. "Runtime properties",
  249. EFI_RT_PROPERTIES_TABLE_GUID,
  250. },
  251. };
  252. /**
  253. * get_guid_text - get string of GUID
  254. *
  255. * Return description of GUID.
  256. *
  257. * @guid: GUID
  258. * Return: description of GUID or NULL
  259. */
  260. static const char *get_guid_text(const void *guid)
  261. {
  262. int i;
  263. for (i = 0; i < ARRAY_SIZE(guid_list); i++) {
  264. /*
  265. * As guidcmp uses memcmp() we can safely accept unaligned
  266. * GUIDs.
  267. */
  268. if (!guidcmp(&guid_list[i].guid, guid))
  269. return guid_list[i].text;
  270. }
  271. return NULL;
  272. }
  273. /**
  274. * do_efi_show_handles() - show UEFI handles
  275. *
  276. * @cmdtp: Command table
  277. * @flag: Command flag
  278. * @argc: Number of arguments
  279. * @argv: Argument array
  280. * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
  281. *
  282. * Implement efidebug "dh" sub-command.
  283. * Show all UEFI handles and their information, currently all protocols
  284. * added to handle.
  285. */
  286. static int do_efi_show_handles(cmd_tbl_t *cmdtp, int flag,
  287. int argc, char * const argv[])
  288. {
  289. efi_handle_t *handles;
  290. efi_guid_t **guid;
  291. efi_uintn_t num, count, i, j;
  292. const char *guid_text;
  293. efi_status_t ret;
  294. ret = EFI_CALL(efi_locate_handle_buffer(ALL_HANDLES, NULL, NULL,
  295. &num, &handles));
  296. if (ret != EFI_SUCCESS)
  297. return CMD_RET_FAILURE;
  298. if (!num)
  299. return CMD_RET_SUCCESS;
  300. printf("Handle%.*s Protocols\n", EFI_HANDLE_WIDTH - 6, spc);
  301. printf("%.*s ====================\n", EFI_HANDLE_WIDTH, sep);
  302. for (i = 0; i < num; i++) {
  303. printf("%p", handles[i]);
  304. ret = EFI_CALL(BS->protocols_per_handle(handles[i], &guid,
  305. &count));
  306. if (ret || !count) {
  307. putc('\n');
  308. continue;
  309. }
  310. for (j = 0; j < count; j++) {
  311. if (j)
  312. printf(", ");
  313. else
  314. putc(' ');
  315. guid_text = get_guid_text(guid[j]);
  316. if (guid_text)
  317. puts(guid_text);
  318. else
  319. printf("%pUl", guid[j]);
  320. }
  321. putc('\n');
  322. }
  323. efi_free_pool(handles);
  324. return CMD_RET_SUCCESS;
  325. }
  326. /**
  327. * do_efi_show_images() - show UEFI images
  328. *
  329. * @cmdtp: Command table
  330. * @flag: Command flag
  331. * @argc: Number of arguments
  332. * @argv: Argument array
  333. * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
  334. *
  335. * Implement efidebug "images" sub-command.
  336. * Show all UEFI loaded images and their information.
  337. */
  338. static int do_efi_show_images(cmd_tbl_t *cmdtp, int flag,
  339. int argc, char * const argv[])
  340. {
  341. efi_print_image_infos(NULL);
  342. return CMD_RET_SUCCESS;
  343. }
  344. static const char * const efi_mem_type_string[] = {
  345. [EFI_RESERVED_MEMORY_TYPE] = "RESERVED",
  346. [EFI_LOADER_CODE] = "LOADER CODE",
  347. [EFI_LOADER_DATA] = "LOADER DATA",
  348. [EFI_BOOT_SERVICES_CODE] = "BOOT CODE",
  349. [EFI_BOOT_SERVICES_DATA] = "BOOT DATA",
  350. [EFI_RUNTIME_SERVICES_CODE] = "RUNTIME CODE",
  351. [EFI_RUNTIME_SERVICES_DATA] = "RUNTIME DATA",
  352. [EFI_CONVENTIONAL_MEMORY] = "CONVENTIONAL",
  353. [EFI_UNUSABLE_MEMORY] = "UNUSABLE MEM",
  354. [EFI_ACPI_RECLAIM_MEMORY] = "ACPI RECLAIM MEM",
  355. [EFI_ACPI_MEMORY_NVS] = "ACPI NVS",
  356. [EFI_MMAP_IO] = "IO",
  357. [EFI_MMAP_IO_PORT] = "IO PORT",
  358. [EFI_PAL_CODE] = "PAL",
  359. [EFI_PERSISTENT_MEMORY_TYPE] = "PERSISTENT",
  360. };
  361. static const struct efi_mem_attrs {
  362. const u64 bit;
  363. const char *text;
  364. } efi_mem_attrs[] = {
  365. {EFI_MEMORY_UC, "UC"},
  366. {EFI_MEMORY_UC, "UC"},
  367. {EFI_MEMORY_WC, "WC"},
  368. {EFI_MEMORY_WT, "WT"},
  369. {EFI_MEMORY_WB, "WB"},
  370. {EFI_MEMORY_UCE, "UCE"},
  371. {EFI_MEMORY_WP, "WP"},
  372. {EFI_MEMORY_RP, "RP"},
  373. {EFI_MEMORY_XP, "WP"},
  374. {EFI_MEMORY_NV, "NV"},
  375. {EFI_MEMORY_MORE_RELIABLE, "REL"},
  376. {EFI_MEMORY_RO, "RO"},
  377. {EFI_MEMORY_RUNTIME, "RT"},
  378. };
  379. /**
  380. * print_memory_attributes() - print memory map attributes
  381. *
  382. * @attributes: Attribute value
  383. *
  384. * Print memory map attributes
  385. */
  386. static void print_memory_attributes(u64 attributes)
  387. {
  388. int sep, i;
  389. for (sep = 0, i = 0; i < ARRAY_SIZE(efi_mem_attrs); i++)
  390. if (attributes & efi_mem_attrs[i].bit) {
  391. if (sep) {
  392. putc('|');
  393. } else {
  394. putc(' ');
  395. sep = 1;
  396. }
  397. puts(efi_mem_attrs[i].text);
  398. }
  399. }
  400. #define EFI_PHYS_ADDR_WIDTH (int)(sizeof(efi_physical_addr_t) * 2)
  401. /**
  402. * do_efi_show_memmap() - show UEFI memory map
  403. *
  404. * @cmdtp: Command table
  405. * @flag: Command flag
  406. * @argc: Number of arguments
  407. * @argv: Argument array
  408. * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
  409. *
  410. * Implement efidebug "memmap" sub-command.
  411. * Show UEFI memory map.
  412. */
  413. static int do_efi_show_memmap(cmd_tbl_t *cmdtp, int flag,
  414. int argc, char * const argv[])
  415. {
  416. struct efi_mem_desc *memmap = NULL, *map;
  417. efi_uintn_t map_size = 0;
  418. const char *type;
  419. int i;
  420. efi_status_t ret;
  421. ret = efi_get_memory_map(&map_size, memmap, NULL, NULL, NULL);
  422. if (ret == EFI_BUFFER_TOO_SMALL) {
  423. map_size += sizeof(struct efi_mem_desc); /* for my own */
  424. ret = efi_allocate_pool(EFI_LOADER_DATA, map_size,
  425. (void *)&memmap);
  426. if (ret != EFI_SUCCESS)
  427. return CMD_RET_FAILURE;
  428. ret = efi_get_memory_map(&map_size, memmap, NULL, NULL, NULL);
  429. }
  430. if (ret != EFI_SUCCESS) {
  431. efi_free_pool(memmap);
  432. return CMD_RET_FAILURE;
  433. }
  434. printf("Type Start%.*s End%.*s Attributes\n",
  435. EFI_PHYS_ADDR_WIDTH - 5, spc, EFI_PHYS_ADDR_WIDTH - 3, spc);
  436. printf("================ %.*s %.*s ==========\n",
  437. EFI_PHYS_ADDR_WIDTH, sep, EFI_PHYS_ADDR_WIDTH, sep);
  438. /*
  439. * Coverity check: dereferencing null pointer "map."
  440. * This is a false positive as memmap will always be
  441. * populated by allocate_pool() above.
  442. */
  443. for (i = 0, map = memmap; i < map_size / sizeof(*map); map++, i++) {
  444. if (map->type < ARRAY_SIZE(efi_mem_type_string))
  445. type = efi_mem_type_string[map->type];
  446. else
  447. type = "(unknown)";
  448. printf("%-16s %.*llx-%.*llx", type,
  449. EFI_PHYS_ADDR_WIDTH,
  450. (u64)map_to_sysmem((void *)(uintptr_t)
  451. map->physical_start),
  452. EFI_PHYS_ADDR_WIDTH,
  453. (u64)map_to_sysmem((void *)(uintptr_t)
  454. (map->physical_start +
  455. map->num_pages * EFI_PAGE_SIZE)));
  456. print_memory_attributes(map->attribute);
  457. putc('\n');
  458. }
  459. efi_free_pool(memmap);
  460. return CMD_RET_SUCCESS;
  461. }
  462. /**
  463. * do_efi_show_tables() - show UEFI configuration tables
  464. *
  465. * @cmdtp: Command table
  466. * @flag: Command flag
  467. * @argc: Number of arguments
  468. * @argv: Argument array
  469. * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
  470. *
  471. * Implement efidebug "tables" sub-command.
  472. * Show UEFI configuration tables.
  473. */
  474. static int do_efi_show_tables(cmd_tbl_t *cmdtp, int flag,
  475. int argc, char * const argv[])
  476. {
  477. efi_uintn_t i;
  478. const char *guid_str;
  479. for (i = 0; i < systab.nr_tables; ++i) {
  480. guid_str = get_guid_text(&systab.tables[i].guid);
  481. if (!guid_str)
  482. guid_str = "";
  483. printf("%pUl %s\n", &systab.tables[i].guid, guid_str);
  484. }
  485. return CMD_RET_SUCCESS;
  486. }
  487. /**
  488. * do_efi_boot_add() - set UEFI load option
  489. *
  490. * @cmdtp: Command table
  491. * @flag: Command flag
  492. * @argc: Number of arguments
  493. * @argv: Argument array
  494. * Return: CMD_RET_SUCCESS on success,
  495. * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
  496. *
  497. * Implement efidebug "boot add" sub-command. Create or change UEFI load option.
  498. *
  499. * efidebug boot add <id> <label> <interface> <devnum>[:<part>] <file> <options>
  500. */
  501. static int do_efi_boot_add(cmd_tbl_t *cmdtp, int flag,
  502. int argc, char * const argv[])
  503. {
  504. int id;
  505. char *endp;
  506. char var_name[9];
  507. u16 var_name16[9], *p;
  508. efi_guid_t guid;
  509. size_t label_len, label_len16;
  510. u16 *label;
  511. struct efi_device_path *device_path = NULL, *file_path = NULL;
  512. struct efi_load_option lo;
  513. void *data = NULL;
  514. efi_uintn_t size;
  515. efi_status_t ret;
  516. int r = CMD_RET_SUCCESS;
  517. if (argc < 6 || argc > 7)
  518. return CMD_RET_USAGE;
  519. id = (int)simple_strtoul(argv[1], &endp, 16);
  520. if (*endp != '\0' || id > 0xffff)
  521. return CMD_RET_USAGE;
  522. sprintf(var_name, "Boot%04X", id);
  523. p = var_name16;
  524. utf8_utf16_strncpy(&p, var_name, 9);
  525. guid = efi_global_variable_guid;
  526. /* attributes */
  527. lo.attributes = LOAD_OPTION_ACTIVE; /* always ACTIVE */
  528. /* label */
  529. label_len = strlen(argv[2]);
  530. label_len16 = utf8_utf16_strnlen(argv[2], label_len);
  531. label = malloc((label_len16 + 1) * sizeof(u16));
  532. if (!label)
  533. return CMD_RET_FAILURE;
  534. lo.label = label; /* label will be changed below */
  535. utf8_utf16_strncpy(&label, argv[2], label_len);
  536. /* file path */
  537. ret = efi_dp_from_name(argv[3], argv[4], argv[5], &device_path,
  538. &file_path);
  539. if (ret != EFI_SUCCESS) {
  540. printf("Cannot create device path for \"%s %s\"\n",
  541. argv[3], argv[4]);
  542. r = CMD_RET_FAILURE;
  543. goto out;
  544. }
  545. lo.file_path = file_path;
  546. lo.file_path_length = efi_dp_size(file_path)
  547. + sizeof(struct efi_device_path); /* for END */
  548. /* optional data */
  549. if (argc == 6)
  550. lo.optional_data = NULL;
  551. else
  552. lo.optional_data = (const u8 *)argv[6];
  553. size = efi_serialize_load_option(&lo, (u8 **)&data);
  554. if (!size) {
  555. r = CMD_RET_FAILURE;
  556. goto out;
  557. }
  558. ret = EFI_CALL(efi_set_variable(var_name16, &guid,
  559. EFI_VARIABLE_NON_VOLATILE |
  560. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  561. EFI_VARIABLE_RUNTIME_ACCESS,
  562. size, data));
  563. if (ret != EFI_SUCCESS) {
  564. printf("Cannot set %ls\n", var_name16);
  565. r = CMD_RET_FAILURE;
  566. }
  567. out:
  568. free(data);
  569. efi_free_pool(device_path);
  570. efi_free_pool(file_path);
  571. free(lo.label);
  572. return r;
  573. }
  574. /**
  575. * do_efi_boot_rm() - delete UEFI load options
  576. *
  577. * @cmdtp: Command table
  578. * @flag: Command flag
  579. * @argc: Number of arguments
  580. * @argv: Argument array
  581. * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
  582. *
  583. * Implement efidebug "boot rm" sub-command.
  584. * Delete UEFI load options.
  585. *
  586. * efidebug boot rm <id> ...
  587. */
  588. static int do_efi_boot_rm(cmd_tbl_t *cmdtp, int flag,
  589. int argc, char * const argv[])
  590. {
  591. efi_guid_t guid;
  592. int id, i;
  593. char *endp;
  594. char var_name[9];
  595. u16 var_name16[9], *p;
  596. efi_status_t ret;
  597. if (argc == 1)
  598. return CMD_RET_USAGE;
  599. guid = efi_global_variable_guid;
  600. for (i = 1; i < argc; i++, argv++) {
  601. id = (int)simple_strtoul(argv[1], &endp, 16);
  602. if (*endp != '\0' || id > 0xffff)
  603. return CMD_RET_FAILURE;
  604. sprintf(var_name, "Boot%04X", id);
  605. p = var_name16;
  606. utf8_utf16_strncpy(&p, var_name, 9);
  607. ret = EFI_CALL(efi_set_variable(var_name16, &guid, 0, 0, NULL));
  608. if (ret) {
  609. printf("Cannot remove %ls\n", var_name16);
  610. return CMD_RET_FAILURE;
  611. }
  612. }
  613. return CMD_RET_SUCCESS;
  614. }
  615. /**
  616. * show_efi_boot_opt_data() - dump UEFI load option
  617. *
  618. * @varname16: variable name
  619. * @data: value of UEFI load option variable
  620. * @size: size of the boot option
  621. *
  622. * Decode the value of UEFI load option variable and print information.
  623. */
  624. static void show_efi_boot_opt_data(u16 *varname16, void *data, size_t size)
  625. {
  626. struct efi_load_option lo;
  627. char *label, *p;
  628. size_t label_len16, label_len;
  629. u16 *dp_str;
  630. efi_deserialize_load_option(&lo, data);
  631. label_len16 = u16_strlen(lo.label);
  632. label_len = utf16_utf8_strnlen(lo.label, label_len16);
  633. label = malloc(label_len + 1);
  634. if (!label)
  635. return;
  636. p = label;
  637. utf16_utf8_strncpy(&p, lo.label, label_len16);
  638. printf("%ls:\nattributes: %c%c%c (0x%08x)\n",
  639. varname16,
  640. /* ACTIVE */
  641. lo.attributes & LOAD_OPTION_ACTIVE ? 'A' : '-',
  642. /* FORCE RECONNECT */
  643. lo.attributes & LOAD_OPTION_FORCE_RECONNECT ? 'R' : '-',
  644. /* HIDDEN */
  645. lo.attributes & LOAD_OPTION_HIDDEN ? 'H' : '-',
  646. lo.attributes);
  647. printf(" label: %s\n", label);
  648. dp_str = efi_dp_str(lo.file_path);
  649. printf(" file_path: %ls\n", dp_str);
  650. efi_free_pool(dp_str);
  651. printf(" data:\n");
  652. print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1,
  653. lo.optional_data, size + (u8 *)data -
  654. (u8 *)lo.optional_data, true);
  655. free(label);
  656. }
  657. /**
  658. * show_efi_boot_opt() - dump UEFI load option
  659. *
  660. * @varname16: variable name
  661. *
  662. * Dump information defined by UEFI load option.
  663. */
  664. static void show_efi_boot_opt(u16 *varname16)
  665. {
  666. void *data;
  667. efi_uintn_t size;
  668. efi_status_t ret;
  669. size = 0;
  670. ret = EFI_CALL(efi_get_variable(varname16, &efi_global_variable_guid,
  671. NULL, &size, NULL));
  672. if (ret == EFI_BUFFER_TOO_SMALL) {
  673. data = malloc(size);
  674. if (!data) {
  675. printf("ERROR: Out of memory\n");
  676. return;
  677. }
  678. ret = EFI_CALL(efi_get_variable(varname16,
  679. &efi_global_variable_guid,
  680. NULL, &size, data));
  681. if (ret == EFI_SUCCESS)
  682. show_efi_boot_opt_data(varname16, data, size);
  683. free(data);
  684. }
  685. }
  686. static int u16_tohex(u16 c)
  687. {
  688. if (c >= '0' && c <= '9')
  689. return c - '0';
  690. if (c >= 'A' && c <= 'F')
  691. return c - 'A' + 10;
  692. /* not hexadecimal */
  693. return -1;
  694. }
  695. /**
  696. * show_efi_boot_dump() - dump all UEFI load options
  697. *
  698. * @cmdtp: Command table
  699. * @flag: Command flag
  700. * @argc: Number of arguments
  701. * @argv: Argument array
  702. * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
  703. *
  704. * Implement efidebug "boot dump" sub-command.
  705. * Dump information of all UEFI load options defined.
  706. *
  707. * efidebug boot dump
  708. */
  709. static int do_efi_boot_dump(cmd_tbl_t *cmdtp, int flag,
  710. int argc, char * const argv[])
  711. {
  712. u16 *var_name16, *p;
  713. efi_uintn_t buf_size, size;
  714. efi_guid_t guid;
  715. int id, i, digit;
  716. efi_status_t ret;
  717. if (argc > 1)
  718. return CMD_RET_USAGE;
  719. buf_size = 128;
  720. var_name16 = malloc(buf_size);
  721. if (!var_name16)
  722. return CMD_RET_FAILURE;
  723. var_name16[0] = 0;
  724. for (;;) {
  725. size = buf_size;
  726. ret = EFI_CALL(efi_get_next_variable_name(&size, var_name16,
  727. &guid));
  728. if (ret == EFI_NOT_FOUND)
  729. break;
  730. if (ret == EFI_BUFFER_TOO_SMALL) {
  731. buf_size = size;
  732. p = realloc(var_name16, buf_size);
  733. if (!p) {
  734. free(var_name16);
  735. return CMD_RET_FAILURE;
  736. }
  737. var_name16 = p;
  738. ret = EFI_CALL(efi_get_next_variable_name(&size,
  739. var_name16,
  740. &guid));
  741. }
  742. if (ret != EFI_SUCCESS) {
  743. free(var_name16);
  744. return CMD_RET_FAILURE;
  745. }
  746. if (memcmp(var_name16, L"Boot", 8))
  747. continue;
  748. for (id = 0, i = 0; i < 4; i++) {
  749. digit = u16_tohex(var_name16[4 + i]);
  750. if (digit < 0)
  751. break;
  752. id = (id << 4) + digit;
  753. }
  754. if (i == 4 && !var_name16[8])
  755. show_efi_boot_opt(var_name16);
  756. }
  757. free(var_name16);
  758. return CMD_RET_SUCCESS;
  759. }
  760. /**
  761. * show_efi_boot_order() - show order of UEFI load options
  762. *
  763. * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
  764. *
  765. * Show order of UEFI load options defined by BootOrder variable.
  766. */
  767. static int show_efi_boot_order(void)
  768. {
  769. u16 *bootorder;
  770. efi_uintn_t size;
  771. int num, i;
  772. char var_name[9];
  773. u16 var_name16[9], *p16;
  774. void *data;
  775. struct efi_load_option lo;
  776. char *label, *p;
  777. size_t label_len16, label_len;
  778. efi_status_t ret;
  779. size = 0;
  780. ret = EFI_CALL(efi_get_variable(L"BootOrder", &efi_global_variable_guid,
  781. NULL, &size, NULL));
  782. if (ret != EFI_BUFFER_TOO_SMALL) {
  783. if (ret == EFI_NOT_FOUND) {
  784. printf("BootOrder not defined\n");
  785. return CMD_RET_SUCCESS;
  786. } else {
  787. return CMD_RET_FAILURE;
  788. }
  789. }
  790. bootorder = malloc(size);
  791. if (!bootorder) {
  792. printf("ERROR: Out of memory\n");
  793. return CMD_RET_FAILURE;
  794. }
  795. ret = EFI_CALL(efi_get_variable(L"BootOrder", &efi_global_variable_guid,
  796. NULL, &size, bootorder));
  797. if (ret != EFI_SUCCESS) {
  798. ret = CMD_RET_FAILURE;
  799. goto out;
  800. }
  801. num = size / sizeof(u16);
  802. for (i = 0; i < num; i++) {
  803. sprintf(var_name, "Boot%04X", bootorder[i]);
  804. p16 = var_name16;
  805. utf8_utf16_strncpy(&p16, var_name, 9);
  806. size = 0;
  807. ret = EFI_CALL(efi_get_variable(var_name16,
  808. &efi_global_variable_guid, NULL,
  809. &size, NULL));
  810. if (ret != EFI_BUFFER_TOO_SMALL) {
  811. printf("%2d: %s: (not defined)\n", i + 1, var_name);
  812. continue;
  813. }
  814. data = malloc(size);
  815. if (!data) {
  816. ret = CMD_RET_FAILURE;
  817. goto out;
  818. }
  819. ret = EFI_CALL(efi_get_variable(var_name16,
  820. &efi_global_variable_guid, NULL,
  821. &size, data));
  822. if (ret != EFI_SUCCESS) {
  823. free(data);
  824. ret = CMD_RET_FAILURE;
  825. goto out;
  826. }
  827. efi_deserialize_load_option(&lo, data);
  828. label_len16 = u16_strlen(lo.label);
  829. label_len = utf16_utf8_strnlen(lo.label, label_len16);
  830. label = malloc(label_len + 1);
  831. if (!label) {
  832. free(data);
  833. ret = CMD_RET_FAILURE;
  834. goto out;
  835. }
  836. p = label;
  837. utf16_utf8_strncpy(&p, lo.label, label_len16);
  838. printf("%2d: %s: %s\n", i + 1, var_name, label);
  839. free(label);
  840. free(data);
  841. }
  842. out:
  843. free(bootorder);
  844. return ret;
  845. }
  846. /**
  847. * do_efi_boot_next() - manage UEFI BootNext variable
  848. *
  849. * @cmdtp: Command table
  850. * @flag: Command flag
  851. * @argc: Number of arguments
  852. * @argv: Argument array
  853. * Return: CMD_RET_SUCCESS on success,
  854. * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
  855. *
  856. * Implement efidebug "boot next" sub-command.
  857. * Set BootNext variable.
  858. *
  859. * efidebug boot next <id>
  860. */
  861. static int do_efi_boot_next(cmd_tbl_t *cmdtp, int flag,
  862. int argc, char * const argv[])
  863. {
  864. u16 bootnext;
  865. efi_uintn_t size;
  866. char *endp;
  867. efi_guid_t guid;
  868. efi_status_t ret;
  869. int r = CMD_RET_SUCCESS;
  870. if (argc != 2)
  871. return CMD_RET_USAGE;
  872. bootnext = (u16)simple_strtoul(argv[1], &endp, 16);
  873. if (*endp) {
  874. printf("invalid value: %s\n", argv[1]);
  875. r = CMD_RET_FAILURE;
  876. goto out;
  877. }
  878. guid = efi_global_variable_guid;
  879. size = sizeof(u16);
  880. ret = EFI_CALL(efi_set_variable(L"BootNext", &guid,
  881. EFI_VARIABLE_NON_VOLATILE |
  882. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  883. EFI_VARIABLE_RUNTIME_ACCESS,
  884. size, &bootnext));
  885. if (ret != EFI_SUCCESS) {
  886. printf("Cannot set BootNext\n");
  887. r = CMD_RET_FAILURE;
  888. }
  889. out:
  890. return r;
  891. }
  892. /**
  893. * do_efi_boot_order() - manage UEFI BootOrder variable
  894. *
  895. * @cmdtp: Command table
  896. * @flag: Command flag
  897. * @argc: Number of arguments
  898. * @argv: Argument array
  899. * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
  900. *
  901. * Implement efidebug "boot order" sub-command.
  902. * Show order of UEFI load options, or change it in BootOrder variable.
  903. *
  904. * efidebug boot order [<id> ...]
  905. */
  906. static int do_efi_boot_order(cmd_tbl_t *cmdtp, int flag,
  907. int argc, char * const argv[])
  908. {
  909. u16 *bootorder = NULL;
  910. efi_uintn_t size;
  911. int id, i;
  912. char *endp;
  913. efi_guid_t guid;
  914. efi_status_t ret;
  915. int r = CMD_RET_SUCCESS;
  916. if (argc == 1)
  917. return show_efi_boot_order();
  918. argc--;
  919. argv++;
  920. size = argc * sizeof(u16);
  921. bootorder = malloc(size);
  922. if (!bootorder)
  923. return CMD_RET_FAILURE;
  924. for (i = 0; i < argc; i++) {
  925. id = (int)simple_strtoul(argv[i], &endp, 16);
  926. if (*endp != '\0' || id > 0xffff) {
  927. printf("invalid value: %s\n", argv[i]);
  928. r = CMD_RET_FAILURE;
  929. goto out;
  930. }
  931. bootorder[i] = (u16)id;
  932. }
  933. guid = efi_global_variable_guid;
  934. ret = EFI_CALL(efi_set_variable(L"BootOrder", &guid,
  935. EFI_VARIABLE_NON_VOLATILE |
  936. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  937. EFI_VARIABLE_RUNTIME_ACCESS,
  938. size, bootorder));
  939. if (ret != EFI_SUCCESS) {
  940. printf("Cannot set BootOrder\n");
  941. r = CMD_RET_FAILURE;
  942. }
  943. out:
  944. free(bootorder);
  945. return r;
  946. }
  947. static cmd_tbl_t cmd_efidebug_boot_sub[] = {
  948. U_BOOT_CMD_MKENT(add, CONFIG_SYS_MAXARGS, 1, do_efi_boot_add, "", ""),
  949. U_BOOT_CMD_MKENT(rm, CONFIG_SYS_MAXARGS, 1, do_efi_boot_rm, "", ""),
  950. U_BOOT_CMD_MKENT(dump, CONFIG_SYS_MAXARGS, 1, do_efi_boot_dump, "", ""),
  951. U_BOOT_CMD_MKENT(next, CONFIG_SYS_MAXARGS, 1, do_efi_boot_next, "", ""),
  952. U_BOOT_CMD_MKENT(order, CONFIG_SYS_MAXARGS, 1, do_efi_boot_order,
  953. "", ""),
  954. };
  955. /**
  956. * do_efi_boot_opt() - manage UEFI load options
  957. *
  958. * @cmdtp: Command table
  959. * @flag: Command flag
  960. * @argc: Number of arguments
  961. * @argv: Argument array
  962. * Return: CMD_RET_SUCCESS on success,
  963. * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
  964. *
  965. * Implement efidebug "boot" sub-command.
  966. */
  967. static int do_efi_boot_opt(cmd_tbl_t *cmdtp, int flag,
  968. int argc, char * const argv[])
  969. {
  970. cmd_tbl_t *cp;
  971. if (argc < 2)
  972. return CMD_RET_USAGE;
  973. argc--; argv++;
  974. cp = find_cmd_tbl(argv[0], cmd_efidebug_boot_sub,
  975. ARRAY_SIZE(cmd_efidebug_boot_sub));
  976. if (!cp)
  977. return CMD_RET_USAGE;
  978. return cp->cmd(cmdtp, flag, argc, argv);
  979. }
  980. /**
  981. * do_efi_test_bootmgr() - run simple bootmgr for test
  982. *
  983. * @cmdtp: Command table
  984. * @flag: Command flag
  985. * @argc: Number of arguments
  986. * @argv: Argument array
  987. * Return: CMD_RET_SUCCESS on success,
  988. * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
  989. *
  990. * Implement efidebug "test bootmgr" sub-command.
  991. * Run simple bootmgr for test.
  992. *
  993. * efidebug test bootmgr
  994. */
  995. static int do_efi_test_bootmgr(cmd_tbl_t *cmdtp, int flag,
  996. int argc, char * const argv[])
  997. {
  998. efi_handle_t image;
  999. efi_uintn_t exit_data_size = 0;
  1000. u16 *exit_data = NULL;
  1001. efi_status_t ret;
  1002. ret = efi_bootmgr_load(&image);
  1003. printf("efi_bootmgr_load() returned: %ld\n", ret & ~EFI_ERROR_MASK);
  1004. /* We call efi_start_image() even if error for test purpose. */
  1005. ret = EFI_CALL(efi_start_image(image, &exit_data_size, &exit_data));
  1006. printf("efi_start_image() returned: %ld\n", ret & ~EFI_ERROR_MASK);
  1007. if (ret && exit_data)
  1008. efi_free_pool(exit_data);
  1009. efi_restore_gd();
  1010. return CMD_RET_SUCCESS;
  1011. }
  1012. static cmd_tbl_t cmd_efidebug_test_sub[] = {
  1013. U_BOOT_CMD_MKENT(bootmgr, CONFIG_SYS_MAXARGS, 1, do_efi_test_bootmgr,
  1014. "", ""),
  1015. };
  1016. /**
  1017. * do_efi_test() - manage UEFI load options
  1018. *
  1019. * @cmdtp: Command table
  1020. * @flag: Command flag
  1021. * @argc: Number of arguments
  1022. * @argv: Argument array
  1023. * Return: CMD_RET_SUCCESS on success,
  1024. * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
  1025. *
  1026. * Implement efidebug "test" sub-command.
  1027. */
  1028. static int do_efi_test(cmd_tbl_t *cmdtp, int flag,
  1029. int argc, char * const argv[])
  1030. {
  1031. cmd_tbl_t *cp;
  1032. if (argc < 2)
  1033. return CMD_RET_USAGE;
  1034. argc--; argv++;
  1035. cp = find_cmd_tbl(argv[0], cmd_efidebug_test_sub,
  1036. ARRAY_SIZE(cmd_efidebug_test_sub));
  1037. if (!cp)
  1038. return CMD_RET_USAGE;
  1039. return cp->cmd(cmdtp, flag, argc, argv);
  1040. }
  1041. /**
  1042. * do_efi_query_info() - QueryVariableInfo EFI service
  1043. *
  1044. * @cmdtp: Command table
  1045. * @flag: Command flag
  1046. * @argc: Number of arguments
  1047. * @argv: Argument array
  1048. * Return: CMD_RET_SUCCESS on success,
  1049. * CMD_RET_USAGE or CMD_RET_FAILURE on failure
  1050. *
  1051. * Implement efidebug "test" sub-command.
  1052. */
  1053. static int do_efi_query_info(cmd_tbl_t *cmdtp, int flag,
  1054. int argc, char * const argv[])
  1055. {
  1056. efi_status_t ret;
  1057. u32 attr = 0;
  1058. u64 max_variable_storage_size;
  1059. u64 remain_variable_storage_size;
  1060. u64 max_variable_size;
  1061. int i;
  1062. for (i = 1; i < argc; i++) {
  1063. if (!strcmp(argv[i], "-bs"))
  1064. attr |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
  1065. else if (!strcmp(argv[i], "-rt"))
  1066. attr |= EFI_VARIABLE_RUNTIME_ACCESS;
  1067. else if (!strcmp(argv[i], "-nv"))
  1068. attr |= EFI_VARIABLE_NON_VOLATILE;
  1069. else if (!strcmp(argv[i], "-at"))
  1070. attr |=
  1071. EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
  1072. }
  1073. ret = EFI_CALL(efi_query_variable_info(attr,
  1074. &max_variable_storage_size,
  1075. &remain_variable_storage_size,
  1076. &max_variable_size));
  1077. if (ret != EFI_SUCCESS) {
  1078. printf("Error: Cannot query UEFI variables, r = %lu\n",
  1079. ret & ~EFI_ERROR_MASK);
  1080. return CMD_RET_FAILURE;
  1081. }
  1082. printf("Max storage size %llu\n", max_variable_storage_size);
  1083. printf("Remaining storage size %llu\n", remain_variable_storage_size);
  1084. printf("Max variable size %llu\n", max_variable_size);
  1085. return CMD_RET_SUCCESS;
  1086. }
  1087. static cmd_tbl_t cmd_efidebug_sub[] = {
  1088. U_BOOT_CMD_MKENT(boot, CONFIG_SYS_MAXARGS, 1, do_efi_boot_opt, "", ""),
  1089. U_BOOT_CMD_MKENT(devices, CONFIG_SYS_MAXARGS, 1, do_efi_show_devices,
  1090. "", ""),
  1091. U_BOOT_CMD_MKENT(drivers, CONFIG_SYS_MAXARGS, 1, do_efi_show_drivers,
  1092. "", ""),
  1093. U_BOOT_CMD_MKENT(dh, CONFIG_SYS_MAXARGS, 1, do_efi_show_handles,
  1094. "", ""),
  1095. U_BOOT_CMD_MKENT(images, CONFIG_SYS_MAXARGS, 1, do_efi_show_images,
  1096. "", ""),
  1097. U_BOOT_CMD_MKENT(memmap, CONFIG_SYS_MAXARGS, 1, do_efi_show_memmap,
  1098. "", ""),
  1099. U_BOOT_CMD_MKENT(tables, CONFIG_SYS_MAXARGS, 1, do_efi_show_tables,
  1100. "", ""),
  1101. U_BOOT_CMD_MKENT(test, CONFIG_SYS_MAXARGS, 1, do_efi_test,
  1102. "", ""),
  1103. U_BOOT_CMD_MKENT(query, CONFIG_SYS_MAXARGS, 1, do_efi_query_info,
  1104. "", ""),
  1105. };
  1106. /**
  1107. * do_efidebug() - display and configure UEFI environment
  1108. *
  1109. * @cmdtp: Command table
  1110. * @flag: Command flag
  1111. * @argc: Number of arguments
  1112. * @argv: Argument array
  1113. * Return: CMD_RET_SUCCESS on success,
  1114. * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
  1115. *
  1116. * Implement efidebug command which allows us to display and
  1117. * configure UEFI environment.
  1118. */
  1119. static int do_efidebug(cmd_tbl_t *cmdtp, int flag,
  1120. int argc, char * const argv[])
  1121. {
  1122. cmd_tbl_t *cp;
  1123. efi_status_t r;
  1124. if (argc < 2)
  1125. return CMD_RET_USAGE;
  1126. argc--; argv++;
  1127. /* Initialize UEFI drivers */
  1128. r = efi_init_obj_list();
  1129. if (r != EFI_SUCCESS) {
  1130. printf("Error: Cannot initialize UEFI sub-system, r = %lu\n",
  1131. r & ~EFI_ERROR_MASK);
  1132. return CMD_RET_FAILURE;
  1133. }
  1134. cp = find_cmd_tbl(argv[0], cmd_efidebug_sub,
  1135. ARRAY_SIZE(cmd_efidebug_sub));
  1136. if (!cp)
  1137. return CMD_RET_USAGE;
  1138. return cp->cmd(cmdtp, flag, argc, argv);
  1139. }
  1140. #ifdef CONFIG_SYS_LONGHELP
  1141. static char efidebug_help_text[] =
  1142. " - UEFI Shell-like interface to configure UEFI environment\n"
  1143. "\n"
  1144. "efidebug boot add <bootid> <label> <interface> <devnum>[:<part>] <file path> [<load options>]\n"
  1145. " - set UEFI BootXXXX variable\n"
  1146. " <load options> will be passed to UEFI application\n"
  1147. "efidebug boot rm <bootid#1> [<bootid#2> [<bootid#3> [...]]]\n"
  1148. " - delete UEFI BootXXXX variables\n"
  1149. "efidebug boot dump\n"
  1150. " - dump all UEFI BootXXXX variables\n"
  1151. "efidebug boot next <bootid>\n"
  1152. " - set UEFI BootNext variable\n"
  1153. "efidebug boot order [<bootid#1> [<bootid#2> [<bootid#3> [...]]]]\n"
  1154. " - set/show UEFI boot order\n"
  1155. "\n"
  1156. "efidebug devices\n"
  1157. " - show UEFI devices\n"
  1158. "efidebug drivers\n"
  1159. " - show UEFI drivers\n"
  1160. "efidebug dh\n"
  1161. " - show UEFI handles\n"
  1162. "efidebug images\n"
  1163. " - show loaded images\n"
  1164. "efidebug memmap\n"
  1165. " - show UEFI memory map\n"
  1166. "efidebug tables\n"
  1167. " - show UEFI configuration tables\n"
  1168. "efidebug test bootmgr\n"
  1169. " - run simple bootmgr for test\n"
  1170. "efidebug query [-nv][-bs][-rt][-at]\n"
  1171. " - show size of UEFI variables store\n";
  1172. #endif
  1173. U_BOOT_CMD(
  1174. efidebug, 10, 0, do_efidebug,
  1175. "Configure UEFI environment",
  1176. efidebug_help_text
  1177. );