efidebug.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609
  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. {
  454. "Firmware Management",
  455. EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID
  456. },
  457. /* Configuration table GUIDs */
  458. {
  459. "ACPI table",
  460. EFI_ACPI_TABLE_GUID,
  461. },
  462. {
  463. "device tree",
  464. EFI_FDT_GUID,
  465. },
  466. {
  467. "SMBIOS table",
  468. SMBIOS_TABLE_GUID,
  469. },
  470. {
  471. "Runtime properties",
  472. EFI_RT_PROPERTIES_TABLE_GUID,
  473. },
  474. {
  475. "TCG2 Final Events Table",
  476. EFI_TCG2_FINAL_EVENTS_TABLE_GUID,
  477. },
  478. };
  479. /**
  480. * get_guid_text - get string of GUID
  481. *
  482. * Return description of GUID.
  483. *
  484. * @guid: GUID
  485. * Return: description of GUID or NULL
  486. */
  487. static const char *get_guid_text(const void *guid)
  488. {
  489. int i;
  490. for (i = 0; i < ARRAY_SIZE(guid_list); i++) {
  491. /*
  492. * As guidcmp uses memcmp() we can safely accept unaligned
  493. * GUIDs.
  494. */
  495. if (!guidcmp(&guid_list[i].guid, guid))
  496. return guid_list[i].text;
  497. }
  498. return NULL;
  499. }
  500. /**
  501. * do_efi_show_handles() - show UEFI handles
  502. *
  503. * @cmdtp: Command table
  504. * @flag: Command flag
  505. * @argc: Number of arguments
  506. * @argv: Argument array
  507. * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
  508. *
  509. * Implement efidebug "dh" sub-command.
  510. * Show all UEFI handles and their information, currently all protocols
  511. * added to handle.
  512. */
  513. static int do_efi_show_handles(struct cmd_tbl *cmdtp, int flag,
  514. int argc, char *const argv[])
  515. {
  516. efi_handle_t *handles;
  517. efi_guid_t **guid;
  518. efi_uintn_t num, count, i, j;
  519. const char *guid_text;
  520. efi_status_t ret;
  521. ret = EFI_CALL(efi_locate_handle_buffer(ALL_HANDLES, NULL, NULL,
  522. &num, &handles));
  523. if (ret != EFI_SUCCESS)
  524. return CMD_RET_FAILURE;
  525. if (!num)
  526. return CMD_RET_SUCCESS;
  527. printf("Handle%.*s Protocols\n", EFI_HANDLE_WIDTH - 6, spc);
  528. printf("%.*s ====================\n", EFI_HANDLE_WIDTH, sep);
  529. for (i = 0; i < num; i++) {
  530. printf("%p", handles[i]);
  531. ret = EFI_CALL(BS->protocols_per_handle(handles[i], &guid,
  532. &count));
  533. if (ret || !count) {
  534. putc('\n');
  535. continue;
  536. }
  537. for (j = 0; j < count; j++) {
  538. if (j)
  539. printf(", ");
  540. else
  541. putc(' ');
  542. guid_text = get_guid_text(guid[j]);
  543. if (guid_text)
  544. puts(guid_text);
  545. else
  546. printf("%pUl", guid[j]);
  547. }
  548. putc('\n');
  549. }
  550. efi_free_pool(handles);
  551. return CMD_RET_SUCCESS;
  552. }
  553. /**
  554. * do_efi_show_images() - show UEFI images
  555. *
  556. * @cmdtp: Command table
  557. * @flag: Command flag
  558. * @argc: Number of arguments
  559. * @argv: Argument array
  560. * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
  561. *
  562. * Implement efidebug "images" sub-command.
  563. * Show all UEFI loaded images and their information.
  564. */
  565. static int do_efi_show_images(struct cmd_tbl *cmdtp, int flag,
  566. int argc, char *const argv[])
  567. {
  568. efi_print_image_infos(NULL);
  569. return CMD_RET_SUCCESS;
  570. }
  571. static const char * const efi_mem_type_string[] = {
  572. [EFI_RESERVED_MEMORY_TYPE] = "RESERVED",
  573. [EFI_LOADER_CODE] = "LOADER CODE",
  574. [EFI_LOADER_DATA] = "LOADER DATA",
  575. [EFI_BOOT_SERVICES_CODE] = "BOOT CODE",
  576. [EFI_BOOT_SERVICES_DATA] = "BOOT DATA",
  577. [EFI_RUNTIME_SERVICES_CODE] = "RUNTIME CODE",
  578. [EFI_RUNTIME_SERVICES_DATA] = "RUNTIME DATA",
  579. [EFI_CONVENTIONAL_MEMORY] = "CONVENTIONAL",
  580. [EFI_UNUSABLE_MEMORY] = "UNUSABLE MEM",
  581. [EFI_ACPI_RECLAIM_MEMORY] = "ACPI RECLAIM MEM",
  582. [EFI_ACPI_MEMORY_NVS] = "ACPI NVS",
  583. [EFI_MMAP_IO] = "IO",
  584. [EFI_MMAP_IO_PORT] = "IO PORT",
  585. [EFI_PAL_CODE] = "PAL",
  586. [EFI_PERSISTENT_MEMORY_TYPE] = "PERSISTENT",
  587. };
  588. static const struct efi_mem_attrs {
  589. const u64 bit;
  590. const char *text;
  591. } efi_mem_attrs[] = {
  592. {EFI_MEMORY_UC, "UC"},
  593. {EFI_MEMORY_UC, "UC"},
  594. {EFI_MEMORY_WC, "WC"},
  595. {EFI_MEMORY_WT, "WT"},
  596. {EFI_MEMORY_WB, "WB"},
  597. {EFI_MEMORY_UCE, "UCE"},
  598. {EFI_MEMORY_WP, "WP"},
  599. {EFI_MEMORY_RP, "RP"},
  600. {EFI_MEMORY_XP, "WP"},
  601. {EFI_MEMORY_NV, "NV"},
  602. {EFI_MEMORY_MORE_RELIABLE, "REL"},
  603. {EFI_MEMORY_RO, "RO"},
  604. {EFI_MEMORY_SP, "SP"},
  605. {EFI_MEMORY_RUNTIME, "RT"},
  606. };
  607. /**
  608. * print_memory_attributes() - print memory map attributes
  609. *
  610. * @attributes: Attribute value
  611. *
  612. * Print memory map attributes
  613. */
  614. static void print_memory_attributes(u64 attributes)
  615. {
  616. int sep, i;
  617. for (sep = 0, i = 0; i < ARRAY_SIZE(efi_mem_attrs); i++)
  618. if (attributes & efi_mem_attrs[i].bit) {
  619. if (sep) {
  620. putc('|');
  621. } else {
  622. putc(' ');
  623. sep = 1;
  624. }
  625. puts(efi_mem_attrs[i].text);
  626. }
  627. }
  628. #define EFI_PHYS_ADDR_WIDTH (int)(sizeof(efi_physical_addr_t) * 2)
  629. /**
  630. * do_efi_show_memmap() - show UEFI memory map
  631. *
  632. * @cmdtp: Command table
  633. * @flag: Command flag
  634. * @argc: Number of arguments
  635. * @argv: Argument array
  636. * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
  637. *
  638. * Implement efidebug "memmap" sub-command.
  639. * Show UEFI memory map.
  640. */
  641. static int do_efi_show_memmap(struct cmd_tbl *cmdtp, int flag,
  642. int argc, char *const argv[])
  643. {
  644. struct efi_mem_desc *memmap = NULL, *map;
  645. efi_uintn_t map_size = 0;
  646. const char *type;
  647. int i;
  648. efi_status_t ret;
  649. ret = efi_get_memory_map(&map_size, memmap, NULL, NULL, NULL);
  650. if (ret == EFI_BUFFER_TOO_SMALL) {
  651. map_size += sizeof(struct efi_mem_desc); /* for my own */
  652. ret = efi_allocate_pool(EFI_LOADER_DATA, map_size,
  653. (void *)&memmap);
  654. if (ret != EFI_SUCCESS)
  655. return CMD_RET_FAILURE;
  656. ret = efi_get_memory_map(&map_size, memmap, NULL, NULL, NULL);
  657. }
  658. if (ret != EFI_SUCCESS) {
  659. efi_free_pool(memmap);
  660. return CMD_RET_FAILURE;
  661. }
  662. printf("Type Start%.*s End%.*s Attributes\n",
  663. EFI_PHYS_ADDR_WIDTH - 5, spc, EFI_PHYS_ADDR_WIDTH - 3, spc);
  664. printf("================ %.*s %.*s ==========\n",
  665. EFI_PHYS_ADDR_WIDTH, sep, EFI_PHYS_ADDR_WIDTH, sep);
  666. /*
  667. * Coverity check: dereferencing null pointer "map."
  668. * This is a false positive as memmap will always be
  669. * populated by allocate_pool() above.
  670. */
  671. for (i = 0, map = memmap; i < map_size / sizeof(*map); map++, i++) {
  672. if (map->type < ARRAY_SIZE(efi_mem_type_string))
  673. type = efi_mem_type_string[map->type];
  674. else
  675. type = "(unknown)";
  676. printf("%-16s %.*llx-%.*llx", type,
  677. EFI_PHYS_ADDR_WIDTH,
  678. (u64)map_to_sysmem((void *)(uintptr_t)
  679. map->physical_start),
  680. EFI_PHYS_ADDR_WIDTH,
  681. (u64)map_to_sysmem((void *)(uintptr_t)
  682. (map->physical_start +
  683. map->num_pages * EFI_PAGE_SIZE)));
  684. print_memory_attributes(map->attribute);
  685. putc('\n');
  686. }
  687. efi_free_pool(memmap);
  688. return CMD_RET_SUCCESS;
  689. }
  690. /**
  691. * do_efi_show_tables() - show UEFI configuration tables
  692. *
  693. * @cmdtp: Command table
  694. * @flag: Command flag
  695. * @argc: Number of arguments
  696. * @argv: Argument array
  697. * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
  698. *
  699. * Implement efidebug "tables" sub-command.
  700. * Show UEFI configuration tables.
  701. */
  702. static int do_efi_show_tables(struct cmd_tbl *cmdtp, int flag,
  703. int argc, char *const argv[])
  704. {
  705. efi_uintn_t i;
  706. const char *guid_str;
  707. for (i = 0; i < systab.nr_tables; ++i) {
  708. guid_str = get_guid_text(&systab.tables[i].guid);
  709. if (!guid_str)
  710. guid_str = "";
  711. printf("%pUl %s\n", &systab.tables[i].guid, guid_str);
  712. }
  713. return CMD_RET_SUCCESS;
  714. }
  715. /**
  716. * do_efi_boot_add() - set UEFI load option
  717. *
  718. * @cmdtp: Command table
  719. * @flag: Command flag
  720. * @argc: Number of arguments
  721. * @argv: Argument array
  722. * Return: CMD_RET_SUCCESS on success,
  723. * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
  724. *
  725. * Implement efidebug "boot add" sub-command. Create or change UEFI load option.
  726. *
  727. * efidebug boot add <id> <label> <interface> <devnum>[:<part>] <file> <options>
  728. */
  729. static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag,
  730. int argc, char *const argv[])
  731. {
  732. int id;
  733. char *endp;
  734. char var_name[9];
  735. u16 var_name16[9], *p;
  736. efi_guid_t guid;
  737. size_t label_len, label_len16;
  738. u16 *label;
  739. struct efi_device_path *device_path = NULL, *file_path = NULL;
  740. struct efi_load_option lo;
  741. void *data = NULL;
  742. efi_uintn_t size;
  743. efi_status_t ret;
  744. int r = CMD_RET_SUCCESS;
  745. if (argc < 6 || argc > 7)
  746. return CMD_RET_USAGE;
  747. id = (int)simple_strtoul(argv[1], &endp, 16);
  748. if (*endp != '\0' || id > 0xffff)
  749. return CMD_RET_USAGE;
  750. sprintf(var_name, "Boot%04X", id);
  751. p = var_name16;
  752. utf8_utf16_strncpy(&p, var_name, 9);
  753. guid = efi_global_variable_guid;
  754. /* attributes */
  755. lo.attributes = LOAD_OPTION_ACTIVE; /* always ACTIVE */
  756. /* label */
  757. label_len = strlen(argv[2]);
  758. label_len16 = utf8_utf16_strnlen(argv[2], label_len);
  759. label = malloc((label_len16 + 1) * sizeof(u16));
  760. if (!label)
  761. return CMD_RET_FAILURE;
  762. lo.label = label; /* label will be changed below */
  763. utf8_utf16_strncpy(&label, argv[2], label_len);
  764. /* file path */
  765. ret = efi_dp_from_name(argv[3], argv[4], argv[5], &device_path,
  766. &file_path);
  767. if (ret != EFI_SUCCESS) {
  768. printf("Cannot create device path for \"%s %s\"\n",
  769. argv[3], argv[4]);
  770. r = CMD_RET_FAILURE;
  771. goto out;
  772. }
  773. lo.file_path = file_path;
  774. lo.file_path_length = efi_dp_size(file_path)
  775. + sizeof(struct efi_device_path); /* for END */
  776. /* optional data */
  777. if (argc == 6)
  778. lo.optional_data = NULL;
  779. else
  780. lo.optional_data = (const u8 *)argv[6];
  781. size = efi_serialize_load_option(&lo, (u8 **)&data);
  782. if (!size) {
  783. r = CMD_RET_FAILURE;
  784. goto out;
  785. }
  786. ret = EFI_CALL(efi_set_variable(var_name16, &guid,
  787. EFI_VARIABLE_NON_VOLATILE |
  788. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  789. EFI_VARIABLE_RUNTIME_ACCESS,
  790. size, data));
  791. if (ret != EFI_SUCCESS) {
  792. printf("Cannot set %ls\n", var_name16);
  793. r = CMD_RET_FAILURE;
  794. }
  795. out:
  796. free(data);
  797. efi_free_pool(device_path);
  798. efi_free_pool(file_path);
  799. free(lo.label);
  800. return r;
  801. }
  802. /**
  803. * do_efi_boot_rm() - delete UEFI load options
  804. *
  805. * @cmdtp: Command table
  806. * @flag: Command flag
  807. * @argc: Number of arguments
  808. * @argv: Argument array
  809. * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
  810. *
  811. * Implement efidebug "boot rm" sub-command.
  812. * Delete UEFI load options.
  813. *
  814. * efidebug boot rm <id> ...
  815. */
  816. static int do_efi_boot_rm(struct cmd_tbl *cmdtp, int flag,
  817. int argc, char *const argv[])
  818. {
  819. efi_guid_t guid;
  820. int id, i;
  821. char *endp;
  822. char var_name[9];
  823. u16 var_name16[9], *p;
  824. efi_status_t ret;
  825. if (argc == 1)
  826. return CMD_RET_USAGE;
  827. guid = efi_global_variable_guid;
  828. for (i = 1; i < argc; i++, argv++) {
  829. id = (int)simple_strtoul(argv[1], &endp, 16);
  830. if (*endp != '\0' || id > 0xffff)
  831. return CMD_RET_FAILURE;
  832. sprintf(var_name, "Boot%04X", id);
  833. p = var_name16;
  834. utf8_utf16_strncpy(&p, var_name, 9);
  835. ret = EFI_CALL(efi_set_variable(var_name16, &guid, 0, 0, NULL));
  836. if (ret) {
  837. printf("Cannot remove %ls\n", var_name16);
  838. return CMD_RET_FAILURE;
  839. }
  840. }
  841. return CMD_RET_SUCCESS;
  842. }
  843. /**
  844. * show_efi_boot_opt_data() - dump UEFI load option
  845. *
  846. * @varname16: variable name
  847. * @data: value of UEFI load option variable
  848. * @size: size of the boot option
  849. *
  850. * Decode the value of UEFI load option variable and print information.
  851. */
  852. static void show_efi_boot_opt_data(u16 *varname16, void *data, size_t *size)
  853. {
  854. struct efi_load_option lo;
  855. char *label, *p;
  856. size_t label_len16, label_len;
  857. u16 *dp_str;
  858. efi_status_t ret;
  859. ret = efi_deserialize_load_option(&lo, data, size);
  860. if (ret != EFI_SUCCESS) {
  861. printf("%ls: invalid load option\n", varname16);
  862. return;
  863. }
  864. label_len16 = u16_strlen(lo.label);
  865. label_len = utf16_utf8_strnlen(lo.label, label_len16);
  866. label = malloc(label_len + 1);
  867. if (!label)
  868. return;
  869. p = label;
  870. utf16_utf8_strncpy(&p, lo.label, label_len16);
  871. printf("%ls:\nattributes: %c%c%c (0x%08x)\n",
  872. varname16,
  873. /* ACTIVE */
  874. lo.attributes & LOAD_OPTION_ACTIVE ? 'A' : '-',
  875. /* FORCE RECONNECT */
  876. lo.attributes & LOAD_OPTION_FORCE_RECONNECT ? 'R' : '-',
  877. /* HIDDEN */
  878. lo.attributes & LOAD_OPTION_HIDDEN ? 'H' : '-',
  879. lo.attributes);
  880. printf(" label: %s\n", label);
  881. dp_str = efi_dp_str(lo.file_path);
  882. printf(" file_path: %ls\n", dp_str);
  883. efi_free_pool(dp_str);
  884. printf(" data:\n");
  885. print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1,
  886. lo.optional_data, *size, true);
  887. free(label);
  888. }
  889. /**
  890. * show_efi_boot_opt() - dump UEFI load option
  891. *
  892. * @varname16: variable name
  893. *
  894. * Dump information defined by UEFI load option.
  895. */
  896. static void show_efi_boot_opt(u16 *varname16)
  897. {
  898. void *data;
  899. efi_uintn_t size;
  900. efi_status_t ret;
  901. size = 0;
  902. ret = EFI_CALL(efi_get_variable(varname16, &efi_global_variable_guid,
  903. NULL, &size, NULL));
  904. if (ret == EFI_BUFFER_TOO_SMALL) {
  905. data = malloc(size);
  906. if (!data) {
  907. printf("ERROR: Out of memory\n");
  908. return;
  909. }
  910. ret = EFI_CALL(efi_get_variable(varname16,
  911. &efi_global_variable_guid,
  912. NULL, &size, data));
  913. if (ret == EFI_SUCCESS)
  914. show_efi_boot_opt_data(varname16, data, &size);
  915. free(data);
  916. }
  917. }
  918. static int u16_tohex(u16 c)
  919. {
  920. if (c >= '0' && c <= '9')
  921. return c - '0';
  922. if (c >= 'A' && c <= 'F')
  923. return c - 'A' + 10;
  924. /* not hexadecimal */
  925. return -1;
  926. }
  927. /**
  928. * show_efi_boot_dump() - dump all UEFI load options
  929. *
  930. * @cmdtp: Command table
  931. * @flag: Command flag
  932. * @argc: Number of arguments
  933. * @argv: Argument array
  934. * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
  935. *
  936. * Implement efidebug "boot dump" sub-command.
  937. * Dump information of all UEFI load options defined.
  938. *
  939. * efidebug boot dump
  940. */
  941. static int do_efi_boot_dump(struct cmd_tbl *cmdtp, int flag,
  942. int argc, char *const argv[])
  943. {
  944. u16 *var_name16, *p;
  945. efi_uintn_t buf_size, size;
  946. efi_guid_t guid;
  947. int id, i, digit;
  948. efi_status_t ret;
  949. if (argc > 1)
  950. return CMD_RET_USAGE;
  951. buf_size = 128;
  952. var_name16 = malloc(buf_size);
  953. if (!var_name16)
  954. return CMD_RET_FAILURE;
  955. var_name16[0] = 0;
  956. for (;;) {
  957. size = buf_size;
  958. ret = EFI_CALL(efi_get_next_variable_name(&size, var_name16,
  959. &guid));
  960. if (ret == EFI_NOT_FOUND)
  961. break;
  962. if (ret == EFI_BUFFER_TOO_SMALL) {
  963. buf_size = size;
  964. p = realloc(var_name16, buf_size);
  965. if (!p) {
  966. free(var_name16);
  967. return CMD_RET_FAILURE;
  968. }
  969. var_name16 = p;
  970. ret = EFI_CALL(efi_get_next_variable_name(&size,
  971. var_name16,
  972. &guid));
  973. }
  974. if (ret != EFI_SUCCESS) {
  975. free(var_name16);
  976. return CMD_RET_FAILURE;
  977. }
  978. if (memcmp(var_name16, L"Boot", 8))
  979. continue;
  980. for (id = 0, i = 0; i < 4; i++) {
  981. digit = u16_tohex(var_name16[4 + i]);
  982. if (digit < 0)
  983. break;
  984. id = (id << 4) + digit;
  985. }
  986. if (i == 4 && !var_name16[8])
  987. show_efi_boot_opt(var_name16);
  988. }
  989. free(var_name16);
  990. return CMD_RET_SUCCESS;
  991. }
  992. /**
  993. * show_efi_boot_order() - show order of UEFI load options
  994. *
  995. * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
  996. *
  997. * Show order of UEFI load options defined by BootOrder variable.
  998. */
  999. static int show_efi_boot_order(void)
  1000. {
  1001. u16 *bootorder;
  1002. efi_uintn_t size;
  1003. int num, i;
  1004. char var_name[9];
  1005. u16 var_name16[9], *p16;
  1006. void *data;
  1007. struct efi_load_option lo;
  1008. char *label, *p;
  1009. size_t label_len16, label_len;
  1010. efi_status_t ret;
  1011. size = 0;
  1012. ret = EFI_CALL(efi_get_variable(L"BootOrder", &efi_global_variable_guid,
  1013. NULL, &size, NULL));
  1014. if (ret != EFI_BUFFER_TOO_SMALL) {
  1015. if (ret == EFI_NOT_FOUND) {
  1016. printf("BootOrder not defined\n");
  1017. return CMD_RET_SUCCESS;
  1018. } else {
  1019. return CMD_RET_FAILURE;
  1020. }
  1021. }
  1022. bootorder = malloc(size);
  1023. if (!bootorder) {
  1024. printf("ERROR: Out of memory\n");
  1025. return CMD_RET_FAILURE;
  1026. }
  1027. ret = EFI_CALL(efi_get_variable(L"BootOrder", &efi_global_variable_guid,
  1028. NULL, &size, bootorder));
  1029. if (ret != EFI_SUCCESS) {
  1030. ret = CMD_RET_FAILURE;
  1031. goto out;
  1032. }
  1033. num = size / sizeof(u16);
  1034. for (i = 0; i < num; i++) {
  1035. sprintf(var_name, "Boot%04X", bootorder[i]);
  1036. p16 = var_name16;
  1037. utf8_utf16_strncpy(&p16, var_name, 9);
  1038. size = 0;
  1039. ret = EFI_CALL(efi_get_variable(var_name16,
  1040. &efi_global_variable_guid, NULL,
  1041. &size, NULL));
  1042. if (ret != EFI_BUFFER_TOO_SMALL) {
  1043. printf("%2d: %s: (not defined)\n", i + 1, var_name);
  1044. continue;
  1045. }
  1046. data = malloc(size);
  1047. if (!data) {
  1048. ret = CMD_RET_FAILURE;
  1049. goto out;
  1050. }
  1051. ret = EFI_CALL(efi_get_variable(var_name16,
  1052. &efi_global_variable_guid, NULL,
  1053. &size, data));
  1054. if (ret != EFI_SUCCESS) {
  1055. free(data);
  1056. ret = CMD_RET_FAILURE;
  1057. goto out;
  1058. }
  1059. ret = efi_deserialize_load_option(&lo, data, &size);
  1060. if (ret != EFI_SUCCESS) {
  1061. printf("%ls: invalid load option\n", var_name16);
  1062. ret = CMD_RET_FAILURE;
  1063. goto out;
  1064. }
  1065. label_len16 = u16_strlen(lo.label);
  1066. label_len = utf16_utf8_strnlen(lo.label, label_len16);
  1067. label = malloc(label_len + 1);
  1068. if (!label) {
  1069. free(data);
  1070. ret = CMD_RET_FAILURE;
  1071. goto out;
  1072. }
  1073. p = label;
  1074. utf16_utf8_strncpy(&p, lo.label, label_len16);
  1075. printf("%2d: %s: %s\n", i + 1, var_name, label);
  1076. free(label);
  1077. free(data);
  1078. }
  1079. out:
  1080. free(bootorder);
  1081. return ret;
  1082. }
  1083. /**
  1084. * do_efi_boot_next() - manage UEFI BootNext variable
  1085. *
  1086. * @cmdtp: Command table
  1087. * @flag: Command flag
  1088. * @argc: Number of arguments
  1089. * @argv: Argument array
  1090. * Return: CMD_RET_SUCCESS on success,
  1091. * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
  1092. *
  1093. * Implement efidebug "boot next" sub-command.
  1094. * Set BootNext variable.
  1095. *
  1096. * efidebug boot next <id>
  1097. */
  1098. static int do_efi_boot_next(struct cmd_tbl *cmdtp, int flag,
  1099. int argc, char *const argv[])
  1100. {
  1101. u16 bootnext;
  1102. efi_uintn_t size;
  1103. char *endp;
  1104. efi_guid_t guid;
  1105. efi_status_t ret;
  1106. int r = CMD_RET_SUCCESS;
  1107. if (argc != 2)
  1108. return CMD_RET_USAGE;
  1109. bootnext = (u16)simple_strtoul(argv[1], &endp, 16);
  1110. if (*endp) {
  1111. printf("invalid value: %s\n", argv[1]);
  1112. r = CMD_RET_FAILURE;
  1113. goto out;
  1114. }
  1115. guid = efi_global_variable_guid;
  1116. size = sizeof(u16);
  1117. ret = EFI_CALL(efi_set_variable(L"BootNext", &guid,
  1118. EFI_VARIABLE_NON_VOLATILE |
  1119. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  1120. EFI_VARIABLE_RUNTIME_ACCESS,
  1121. size, &bootnext));
  1122. if (ret != EFI_SUCCESS) {
  1123. printf("Cannot set BootNext\n");
  1124. r = CMD_RET_FAILURE;
  1125. }
  1126. out:
  1127. return r;
  1128. }
  1129. /**
  1130. * do_efi_boot_order() - manage UEFI BootOrder variable
  1131. *
  1132. * @cmdtp: Command table
  1133. * @flag: Command flag
  1134. * @argc: Number of arguments
  1135. * @argv: Argument array
  1136. * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
  1137. *
  1138. * Implement efidebug "boot order" sub-command.
  1139. * Show order of UEFI load options, or change it in BootOrder variable.
  1140. *
  1141. * efidebug boot order [<id> ...]
  1142. */
  1143. static int do_efi_boot_order(struct cmd_tbl *cmdtp, int flag,
  1144. int argc, char *const argv[])
  1145. {
  1146. u16 *bootorder = NULL;
  1147. efi_uintn_t size;
  1148. int id, i;
  1149. char *endp;
  1150. efi_guid_t guid;
  1151. efi_status_t ret;
  1152. int r = CMD_RET_SUCCESS;
  1153. if (argc == 1)
  1154. return show_efi_boot_order();
  1155. argc--;
  1156. argv++;
  1157. size = argc * sizeof(u16);
  1158. bootorder = malloc(size);
  1159. if (!bootorder)
  1160. return CMD_RET_FAILURE;
  1161. for (i = 0; i < argc; i++) {
  1162. id = (int)simple_strtoul(argv[i], &endp, 16);
  1163. if (*endp != '\0' || id > 0xffff) {
  1164. printf("invalid value: %s\n", argv[i]);
  1165. r = CMD_RET_FAILURE;
  1166. goto out;
  1167. }
  1168. bootorder[i] = (u16)id;
  1169. }
  1170. guid = efi_global_variable_guid;
  1171. ret = EFI_CALL(efi_set_variable(L"BootOrder", &guid,
  1172. EFI_VARIABLE_NON_VOLATILE |
  1173. EFI_VARIABLE_BOOTSERVICE_ACCESS |
  1174. EFI_VARIABLE_RUNTIME_ACCESS,
  1175. size, bootorder));
  1176. if (ret != EFI_SUCCESS) {
  1177. printf("Cannot set BootOrder\n");
  1178. r = CMD_RET_FAILURE;
  1179. }
  1180. out:
  1181. free(bootorder);
  1182. return r;
  1183. }
  1184. static struct cmd_tbl cmd_efidebug_boot_sub[] = {
  1185. U_BOOT_CMD_MKENT(add, CONFIG_SYS_MAXARGS, 1, do_efi_boot_add, "", ""),
  1186. U_BOOT_CMD_MKENT(rm, CONFIG_SYS_MAXARGS, 1, do_efi_boot_rm, "", ""),
  1187. U_BOOT_CMD_MKENT(dump, CONFIG_SYS_MAXARGS, 1, do_efi_boot_dump, "", ""),
  1188. U_BOOT_CMD_MKENT(next, CONFIG_SYS_MAXARGS, 1, do_efi_boot_next, "", ""),
  1189. U_BOOT_CMD_MKENT(order, CONFIG_SYS_MAXARGS, 1, do_efi_boot_order,
  1190. "", ""),
  1191. };
  1192. /**
  1193. * do_efi_boot_opt() - manage UEFI load options
  1194. *
  1195. * @cmdtp: Command table
  1196. * @flag: Command flag
  1197. * @argc: Number of arguments
  1198. * @argv: Argument array
  1199. * Return: CMD_RET_SUCCESS on success,
  1200. * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
  1201. *
  1202. * Implement efidebug "boot" sub-command.
  1203. */
  1204. static int do_efi_boot_opt(struct cmd_tbl *cmdtp, int flag,
  1205. int argc, char *const argv[])
  1206. {
  1207. struct cmd_tbl *cp;
  1208. if (argc < 2)
  1209. return CMD_RET_USAGE;
  1210. argc--; argv++;
  1211. cp = find_cmd_tbl(argv[0], cmd_efidebug_boot_sub,
  1212. ARRAY_SIZE(cmd_efidebug_boot_sub));
  1213. if (!cp)
  1214. return CMD_RET_USAGE;
  1215. return cp->cmd(cmdtp, flag, argc, argv);
  1216. }
  1217. /**
  1218. * do_efi_test_bootmgr() - run simple bootmgr for test
  1219. *
  1220. * @cmdtp: Command table
  1221. * @flag: Command flag
  1222. * @argc: Number of arguments
  1223. * @argv: Argument array
  1224. * Return: CMD_RET_SUCCESS on success,
  1225. * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
  1226. *
  1227. * Implement efidebug "test bootmgr" sub-command.
  1228. * Run simple bootmgr for test.
  1229. *
  1230. * efidebug test bootmgr
  1231. */
  1232. static __maybe_unused int do_efi_test_bootmgr(struct cmd_tbl *cmdtp, int flag,
  1233. int argc, char * const argv[])
  1234. {
  1235. efi_handle_t image;
  1236. efi_uintn_t exit_data_size = 0;
  1237. u16 *exit_data = NULL;
  1238. efi_status_t ret;
  1239. void *load_options = NULL;
  1240. ret = efi_bootmgr_load(&image, &load_options);
  1241. printf("efi_bootmgr_load() returned: %ld\n", ret & ~EFI_ERROR_MASK);
  1242. /* We call efi_start_image() even if error for test purpose. */
  1243. ret = EFI_CALL(efi_start_image(image, &exit_data_size, &exit_data));
  1244. printf("efi_start_image() returned: %ld\n", ret & ~EFI_ERROR_MASK);
  1245. if (ret && exit_data)
  1246. efi_free_pool(exit_data);
  1247. efi_restore_gd();
  1248. free(load_options);
  1249. return CMD_RET_SUCCESS;
  1250. }
  1251. static struct cmd_tbl cmd_efidebug_test_sub[] = {
  1252. #ifdef CONFIG_CMD_BOOTEFI_BOOTMGR
  1253. U_BOOT_CMD_MKENT(bootmgr, CONFIG_SYS_MAXARGS, 1, do_efi_test_bootmgr,
  1254. "", ""),
  1255. #endif
  1256. };
  1257. /**
  1258. * do_efi_test() - manage UEFI load options
  1259. *
  1260. * @cmdtp: Command table
  1261. * @flag: Command flag
  1262. * @argc: Number of arguments
  1263. * @argv: Argument array
  1264. * Return: CMD_RET_SUCCESS on success,
  1265. * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
  1266. *
  1267. * Implement efidebug "test" sub-command.
  1268. */
  1269. static int do_efi_test(struct cmd_tbl *cmdtp, int flag,
  1270. int argc, char * const argv[])
  1271. {
  1272. struct cmd_tbl *cp;
  1273. if (argc < 2)
  1274. return CMD_RET_USAGE;
  1275. argc--; argv++;
  1276. cp = find_cmd_tbl(argv[0], cmd_efidebug_test_sub,
  1277. ARRAY_SIZE(cmd_efidebug_test_sub));
  1278. if (!cp)
  1279. return CMD_RET_USAGE;
  1280. return cp->cmd(cmdtp, flag, argc, argv);
  1281. }
  1282. /**
  1283. * do_efi_query_info() - QueryVariableInfo EFI service
  1284. *
  1285. * @cmdtp: Command table
  1286. * @flag: Command flag
  1287. * @argc: Number of arguments
  1288. * @argv: Argument array
  1289. * Return: CMD_RET_SUCCESS on success,
  1290. * CMD_RET_USAGE or CMD_RET_FAILURE on failure
  1291. *
  1292. * Implement efidebug "test" sub-command.
  1293. */
  1294. static int do_efi_query_info(struct cmd_tbl *cmdtp, int flag,
  1295. int argc, char * const argv[])
  1296. {
  1297. efi_status_t ret;
  1298. u32 attr = 0;
  1299. u64 max_variable_storage_size;
  1300. u64 remain_variable_storage_size;
  1301. u64 max_variable_size;
  1302. int i;
  1303. for (i = 1; i < argc; i++) {
  1304. if (!strcmp(argv[i], "-bs"))
  1305. attr |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
  1306. else if (!strcmp(argv[i], "-rt"))
  1307. attr |= EFI_VARIABLE_RUNTIME_ACCESS;
  1308. else if (!strcmp(argv[i], "-nv"))
  1309. attr |= EFI_VARIABLE_NON_VOLATILE;
  1310. else if (!strcmp(argv[i], "-at"))
  1311. attr |=
  1312. EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
  1313. }
  1314. ret = EFI_CALL(efi_query_variable_info(attr,
  1315. &max_variable_storage_size,
  1316. &remain_variable_storage_size,
  1317. &max_variable_size));
  1318. if (ret != EFI_SUCCESS) {
  1319. printf("Error: Cannot query UEFI variables, r = %lu\n",
  1320. ret & ~EFI_ERROR_MASK);
  1321. return CMD_RET_FAILURE;
  1322. }
  1323. printf("Max storage size %llu\n", max_variable_storage_size);
  1324. printf("Remaining storage size %llu\n", remain_variable_storage_size);
  1325. printf("Max variable size %llu\n", max_variable_size);
  1326. return CMD_RET_SUCCESS;
  1327. }
  1328. static struct cmd_tbl cmd_efidebug_sub[] = {
  1329. U_BOOT_CMD_MKENT(boot, CONFIG_SYS_MAXARGS, 1, do_efi_boot_opt, "", ""),
  1330. #ifdef CONFIG_EFI_HAVE_CAPSULE_SUPPORT
  1331. U_BOOT_CMD_MKENT(capsule, CONFIG_SYS_MAXARGS, 1, do_efi_capsule,
  1332. "", ""),
  1333. #endif
  1334. U_BOOT_CMD_MKENT(devices, CONFIG_SYS_MAXARGS, 1, do_efi_show_devices,
  1335. "", ""),
  1336. U_BOOT_CMD_MKENT(drivers, CONFIG_SYS_MAXARGS, 1, do_efi_show_drivers,
  1337. "", ""),
  1338. U_BOOT_CMD_MKENT(dh, CONFIG_SYS_MAXARGS, 1, do_efi_show_handles,
  1339. "", ""),
  1340. U_BOOT_CMD_MKENT(images, CONFIG_SYS_MAXARGS, 1, do_efi_show_images,
  1341. "", ""),
  1342. U_BOOT_CMD_MKENT(memmap, CONFIG_SYS_MAXARGS, 1, do_efi_show_memmap,
  1343. "", ""),
  1344. U_BOOT_CMD_MKENT(tables, CONFIG_SYS_MAXARGS, 1, do_efi_show_tables,
  1345. "", ""),
  1346. U_BOOT_CMD_MKENT(test, CONFIG_SYS_MAXARGS, 1, do_efi_test,
  1347. "", ""),
  1348. U_BOOT_CMD_MKENT(query, CONFIG_SYS_MAXARGS, 1, do_efi_query_info,
  1349. "", ""),
  1350. };
  1351. /**
  1352. * do_efidebug() - display and configure UEFI environment
  1353. *
  1354. * @cmdtp: Command table
  1355. * @flag: Command flag
  1356. * @argc: Number of arguments
  1357. * @argv: Argument array
  1358. * Return: CMD_RET_SUCCESS on success,
  1359. * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
  1360. *
  1361. * Implement efidebug command which allows us to display and
  1362. * configure UEFI environment.
  1363. */
  1364. static int do_efidebug(struct cmd_tbl *cmdtp, int flag,
  1365. int argc, char *const argv[])
  1366. {
  1367. struct cmd_tbl *cp;
  1368. efi_status_t r;
  1369. if (argc < 2)
  1370. return CMD_RET_USAGE;
  1371. argc--; argv++;
  1372. /* Initialize UEFI drivers */
  1373. r = efi_init_obj_list();
  1374. if (r != EFI_SUCCESS) {
  1375. printf("Error: Cannot initialize UEFI sub-system, r = %lu\n",
  1376. r & ~EFI_ERROR_MASK);
  1377. return CMD_RET_FAILURE;
  1378. }
  1379. cp = find_cmd_tbl(argv[0], cmd_efidebug_sub,
  1380. ARRAY_SIZE(cmd_efidebug_sub));
  1381. if (!cp)
  1382. return CMD_RET_USAGE;
  1383. return cp->cmd(cmdtp, flag, argc, argv);
  1384. }
  1385. #ifdef CONFIG_SYS_LONGHELP
  1386. static char efidebug_help_text[] =
  1387. " - UEFI Shell-like interface to configure UEFI environment\n"
  1388. "\n"
  1389. "efidebug boot add <bootid> <label> <interface> <devnum>[:<part>] <file path> [<load options>]\n"
  1390. " - set UEFI BootXXXX variable\n"
  1391. " <load options> will be passed to UEFI application\n"
  1392. "efidebug boot rm <bootid#1> [<bootid#2> [<bootid#3> [...]]]\n"
  1393. " - delete UEFI BootXXXX variables\n"
  1394. "efidebug boot dump\n"
  1395. " - dump all UEFI BootXXXX variables\n"
  1396. "efidebug boot next <bootid>\n"
  1397. " - set UEFI BootNext variable\n"
  1398. "efidebug boot order [<bootid#1> [<bootid#2> [<bootid#3> [...]]]]\n"
  1399. " - set/show UEFI boot order\n"
  1400. "\n"
  1401. #ifdef CONFIG_EFI_HAVE_CAPSULE_SUPPORT
  1402. "efidebug capsule update [-v] <capsule address>\n"
  1403. " - process a capsule\n"
  1404. "efidebug capsule disk-update\n"
  1405. " - update a capsule from disk\n"
  1406. "efidebug capsule show <capsule address>\n"
  1407. " - show capsule information\n"
  1408. "efidebug capsule result [<capsule result var>]\n"
  1409. " - show a capsule update result\n"
  1410. "\n"
  1411. #endif
  1412. "efidebug devices\n"
  1413. " - show UEFI devices\n"
  1414. "efidebug drivers\n"
  1415. " - show UEFI drivers\n"
  1416. "efidebug dh\n"
  1417. " - show UEFI handles\n"
  1418. "efidebug images\n"
  1419. " - show loaded images\n"
  1420. "efidebug memmap\n"
  1421. " - show UEFI memory map\n"
  1422. "efidebug tables\n"
  1423. " - show UEFI configuration tables\n"
  1424. #ifdef CONFIG_CMD_BOOTEFI_BOOTMGR
  1425. "efidebug test bootmgr\n"
  1426. " - run simple bootmgr for test\n"
  1427. #endif
  1428. "efidebug query [-nv][-bs][-rt][-at]\n"
  1429. " - show size of UEFI variables store\n";
  1430. #endif
  1431. U_BOOT_CMD(
  1432. efidebug, 10, 0, do_efidebug,
  1433. "Configure UEFI environment",
  1434. efidebug_help_text
  1435. );