efidebug.c 38 KB

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