efidebug.c 31 KB

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