efidebug.c 31 KB

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