efidebug.c 38 KB

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