mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-16 09:54:35 +00:00
cmd: add "efidebug capsule" command
"efidebug capsule" is more or less a debugging utility. efidebug capsule update: invoke UpdateCapsule against data on memory efidebug capsule show: show a capsule header efidebug capsule result: dump a capsule result variable Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
This commit is contained in:
parent
bb7e71d33c
commit
7f35cedfd9
1 changed files with 235 additions and 0 deletions
235
cmd/efidebug.c
235
cmd/efidebug.c
|
@ -19,6 +19,228 @@
|
|||
#include <linux/ctype.h>
|
||||
|
||||
#define BS systab.boottime
|
||||
#define RT systab.runtime
|
||||
|
||||
#ifdef CONFIG_EFI_HAVE_CAPSULE_SUPPORT
|
||||
/**
|
||||
* do_efi_capsule_update() - process a capsule update
|
||||
*
|
||||
* @cmdtp: Command table
|
||||
* @flag: Command flag
|
||||
* @argc: Number of arguments
|
||||
* @argv: Argument array
|
||||
* Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
|
||||
*
|
||||
* Implement efidebug "capsule update" sub-command.
|
||||
* process a capsule update.
|
||||
*
|
||||
* efidebug capsule update [-v] <capsule address>
|
||||
*/
|
||||
static int do_efi_capsule_update(struct cmd_tbl *cmdtp, int flag,
|
||||
int argc, char * const argv[])
|
||||
{
|
||||
struct efi_capsule_header *capsule;
|
||||
int verbose = 0;
|
||||
char *endp;
|
||||
efi_status_t ret;
|
||||
|
||||
if (argc != 2 && argc != 3)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
if (argc == 3) {
|
||||
if (strcmp(argv[1], "-v"))
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
verbose = 1;
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
capsule = (typeof(capsule))simple_strtoul(argv[1], &endp, 16);
|
||||
if (endp == argv[1]) {
|
||||
printf("Invalid address: %s", argv[1]);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
printf("Capsule guid: %pUl\n", &capsule->capsule_guid);
|
||||
printf("Capsule flags: 0x%x\n", capsule->flags);
|
||||
printf("Capsule header size: 0x%x\n", capsule->header_size);
|
||||
printf("Capsule image size: 0x%x\n",
|
||||
capsule->capsule_image_size);
|
||||
}
|
||||
|
||||
ret = EFI_CALL(RT->update_capsule(&capsule, 1, (u64)NULL));
|
||||
if (ret) {
|
||||
printf("Cannot handle a capsule at %p", capsule);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* do_efi_capsule_show() - show capsule information
|
||||
*
|
||||
* @cmdtp: Command table
|
||||
* @flag: Command flag
|
||||
* @argc: Number of arguments
|
||||
* @argv: Argument array
|
||||
* Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
|
||||
*
|
||||
* Implement efidebug "capsule show" sub-command.
|
||||
* show capsule information.
|
||||
*
|
||||
* efidebug capsule show <capsule address>
|
||||
*/
|
||||
static int do_efi_capsule_show(struct cmd_tbl *cmdtp, int flag,
|
||||
int argc, char * const argv[])
|
||||
{
|
||||
struct efi_capsule_header *capsule;
|
||||
char *endp;
|
||||
|
||||
if (argc != 2)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
capsule = (typeof(capsule))simple_strtoul(argv[1], &endp, 16);
|
||||
if (endp == argv[1]) {
|
||||
printf("Invalid address: %s", argv[1]);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
printf("Capsule guid: %pUl\n", &capsule->capsule_guid);
|
||||
printf("Capsule flags: 0x%x\n", capsule->flags);
|
||||
printf("Capsule header size: 0x%x\n", capsule->header_size);
|
||||
printf("Capsule image size: 0x%x\n",
|
||||
capsule->capsule_image_size);
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* do_efi_capsule_res() - show a capsule update result
|
||||
*
|
||||
* @cmdtp: Command table
|
||||
* @flag: Command flag
|
||||
* @argc: Number of arguments
|
||||
* @argv: Argument array
|
||||
* Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure
|
||||
*
|
||||
* Implement efidebug "capsule result" sub-command.
|
||||
* show a capsule update result.
|
||||
* If result number is not specified, CapsuleLast will be shown.
|
||||
*
|
||||
* efidebug capsule result [<capsule result number>]
|
||||
*/
|
||||
static int do_efi_capsule_res(struct cmd_tbl *cmdtp, int flag,
|
||||
int argc, char * const argv[])
|
||||
{
|
||||
int capsule_id;
|
||||
char *endp;
|
||||
char var_name[12];
|
||||
u16 var_name16[12], *p;
|
||||
efi_guid_t guid;
|
||||
struct efi_capsule_result_variable_header *result = NULL;
|
||||
efi_uintn_t size;
|
||||
efi_status_t ret;
|
||||
|
||||
if (argc != 1 && argc != 2)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
guid = efi_guid_capsule_report;
|
||||
if (argc == 1) {
|
||||
size = sizeof(var_name16);
|
||||
ret = EFI_CALL(RT->get_variable(L"CapsuleLast", &guid, NULL,
|
||||
&size, var_name16));
|
||||
if (ret != EFI_SUCCESS) {
|
||||
if (ret == EFI_NOT_FOUND)
|
||||
printf("CapsuleLast doesn't exist\n");
|
||||
else
|
||||
printf("Failed to get CapsuleLast\n");
|
||||
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
printf("CapsuleLast is %ls\n", var_name16);
|
||||
} else {
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
capsule_id = simple_strtoul(argv[0], &endp, 16);
|
||||
if (capsule_id < 0 || capsule_id > 0xffff)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
sprintf(var_name, "Capsule%04X", capsule_id);
|
||||
p = var_name16;
|
||||
utf8_utf16_strncpy(&p, var_name, 9);
|
||||
}
|
||||
|
||||
size = 0;
|
||||
ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size, NULL));
|
||||
if (ret == EFI_BUFFER_TOO_SMALL) {
|
||||
result = malloc(size);
|
||||
ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size,
|
||||
result));
|
||||
if (ret != EFI_SUCCESS) {
|
||||
free(result);
|
||||
printf("Failed to get %ls\n", var_name16);
|
||||
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Result total size: 0x%x\n", result->variable_total_size);
|
||||
printf("Capsule guid: %pUl\n", &result->capsule_guid);
|
||||
printf("Time processed: %04d-%02d-%02d %02d:%02d:%02d\n",
|
||||
result->capsule_processed.year, result->capsule_processed.month,
|
||||
result->capsule_processed.day, result->capsule_processed.hour,
|
||||
result->capsule_processed.minute,
|
||||
result->capsule_processed.second);
|
||||
printf("Capsule status: 0x%lx\n", result->capsule_status);
|
||||
|
||||
free(result);
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
static struct cmd_tbl cmd_efidebug_capsule_sub[] = {
|
||||
U_BOOT_CMD_MKENT(update, CONFIG_SYS_MAXARGS, 1, do_efi_capsule_update,
|
||||
"", ""),
|
||||
U_BOOT_CMD_MKENT(show, CONFIG_SYS_MAXARGS, 1, do_efi_capsule_show,
|
||||
"", ""),
|
||||
U_BOOT_CMD_MKENT(result, CONFIG_SYS_MAXARGS, 1, do_efi_capsule_res,
|
||||
"", ""),
|
||||
};
|
||||
|
||||
/**
|
||||
* do_efi_capsule() - manage UEFI capsules
|
||||
*
|
||||
* @cmdtp: Command table
|
||||
* @flag: Command flag
|
||||
* @argc: Number of arguments
|
||||
* @argv: Argument array
|
||||
* Return: CMD_RET_SUCCESS on success,
|
||||
* CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure
|
||||
*
|
||||
* Implement efidebug "capsule" sub-command.
|
||||
*/
|
||||
static int do_efi_capsule(struct cmd_tbl *cmdtp, int flag,
|
||||
int argc, char * const argv[])
|
||||
{
|
||||
struct cmd_tbl *cp;
|
||||
|
||||
if (argc < 2)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
argc--; argv++;
|
||||
|
||||
cp = find_cmd_tbl(argv[0], cmd_efidebug_capsule_sub,
|
||||
ARRAY_SIZE(cmd_efidebug_capsule_sub));
|
||||
if (!cp)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
return cp->cmd(cmdtp, flag, argc, argv);
|
||||
}
|
||||
#endif /* CONFIG_EFI_HAVE_CAPSULE_SUPPORT */
|
||||
|
||||
/**
|
||||
* efi_get_device_handle_info() - get information of UEFI device
|
||||
|
@ -1241,6 +1463,10 @@ static int do_efi_query_info(struct cmd_tbl *cmdtp, int flag,
|
|||
|
||||
static struct cmd_tbl cmd_efidebug_sub[] = {
|
||||
U_BOOT_CMD_MKENT(boot, CONFIG_SYS_MAXARGS, 1, do_efi_boot_opt, "", ""),
|
||||
#ifdef CONFIG_EFI_HAVE_CAPSULE_SUPPORT
|
||||
U_BOOT_CMD_MKENT(capsule, CONFIG_SYS_MAXARGS, 1, do_efi_capsule,
|
||||
"", ""),
|
||||
#endif
|
||||
U_BOOT_CMD_MKENT(devices, CONFIG_SYS_MAXARGS, 1, do_efi_show_devices,
|
||||
"", ""),
|
||||
U_BOOT_CMD_MKENT(drivers, CONFIG_SYS_MAXARGS, 1, do_efi_show_drivers,
|
||||
|
@ -1315,6 +1541,15 @@ static char efidebug_help_text[] =
|
|||
"efidebug boot order [<bootid#1> [<bootid#2> [<bootid#3> [...]]]]\n"
|
||||
" - set/show UEFI boot order\n"
|
||||
"\n"
|
||||
#ifdef CONFIG_EFI_HAVE_CAPSULE_SUPPORT
|
||||
"efidebug capsule update [-v] <capsule address>\n"
|
||||
" - process a capsule\n"
|
||||
"efidebug capsule show <capsule address>\n"
|
||||
" - show capsule information\n"
|
||||
"efidebug capsule result [<capsule result var>]\n"
|
||||
" - show a capsule update result\n"
|
||||
"\n"
|
||||
#endif
|
||||
"efidebug devices\n"
|
||||
" - show UEFI devices\n"
|
||||
"efidebug drivers\n"
|
||||
|
|
Loading…
Add table
Reference in a new issue