All of lore.kernel.org
 help / color / mirror / Atom feed
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
To: u-boot@lists.denx.de
Subject: [PATCH v2 14/17] cmd: add "efidebug capsule" command
Date: Wed, 17 Jun 2020 11:55:12 +0900	[thread overview]
Message-ID: <20200617025515.23585-15-takahiro.akashi@linaro.org> (raw)
In-Reply-To: <20200617025515.23585-1-takahiro.akashi@linaro.org>

"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>
---
 cmd/efidebug.c | 235 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 235 insertions(+)

diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index 58018f700cd4..29054d09daba 100644
--- a/cmd/efidebug.c
+++ b/cmd/efidebug.c
@@ -18,6 +18,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
@@ -1230,6 +1452,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,
@@ -1304,6 +1530,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"
-- 
2.27.0

  parent reply	other threads:[~2020-06-17  2:55 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-17  2:54 [PATCH v2 00/17] efi_loader: add capsule update support AKASHI Takahiro
2020-06-17  2:54 ` [PATCH v2 01/17] common: update_tftp: remove unnecessary build check AKASHI Takahiro
2020-06-17  2:55 ` [PATCH v2 02/17] dfu: add a hidden reverse-dependency on UPDATE_TFTP AKASHI Takahiro
2020-06-17  2:55 ` [PATCH v2 03/17] dfu: rename dfu_tftp_write() to dfu_write_by_name() AKASHI Takahiro
2020-06-20 18:35   ` Sughosh Ganu
2020-06-21  7:38     ` Lukasz Majewski
2020-06-22  0:41       ` AKASHI Takahiro
2020-06-22  7:19         ` Lukasz Majewski
2020-06-22  0:58     ` AKASHI Takahiro
2020-06-17  2:55 ` [PATCH v2 04/17] common: update: add a generic interface for FIT image AKASHI Takahiro
2020-06-17  2:55 ` [PATCH v2 05/17] dfu: export dfu_list AKASHI Takahiro
2020-06-17  2:55 ` [PATCH v2 06/17] efi_loader: add option to initialise EFI subsystem early AKASHI Takahiro
2020-06-17  2:55 ` [PATCH v2 07/17] efi_loader: define UpdateCapsule api AKASHI Takahiro
2020-06-17  2:55 ` [PATCH v2 08/17] efi_loader: capsule: add capsule_on_disk support AKASHI Takahiro
2020-06-17  2:55 ` [PATCH v2 09/17] efi_loader: capsule: add memory range capsule definitions AKASHI Takahiro
2020-06-17  2:55 ` [PATCH v2 10/17] efi_loader: capsule: support firmware update AKASHI Takahiro
2020-06-17  2:55 ` [PATCH v2 11/17] efi_loader: add firmware management protocol for FIT image AKASHI Takahiro
2020-06-20 18:39   ` Sughosh Ganu
2020-06-22  1:03     ` AKASHI Takahiro
2020-06-20 18:49   ` Sughosh Ganu
2020-06-22  1:09     ` AKASHI Takahiro
2020-06-22  7:58       ` Sughosh Ganu
2020-06-22  8:06         ` AKASHI Takahiro
2020-06-22  8:38           ` Sughosh Ganu
2020-06-17  2:55 ` [PATCH v2 12/17] dfu: add dfu_write_by_alt() AKASHI Takahiro
2020-06-17  2:55 ` [PATCH v2 13/17] efi_loader: add firmware management protocol for raw image AKASHI Takahiro
2020-06-20 18:57   ` Sughosh Ganu
2020-06-22  1:21     ` AKASHI Takahiro
2020-06-22  7:53       ` Sughosh Ganu
2020-06-17  2:55 ` AKASHI Takahiro [this message]
2020-06-17  2:55 ` [PATCH v2 15/17] tools: add mkeficapsule command for UEFI capsule update AKASHI Takahiro
2020-06-17  2:55 ` [PATCH v2 16/17] test/py: add a test for efi firmware update capsule of FIT image AKASHI Takahiro
2020-06-17  2:55 ` [PATCH v2 17/17] test/py: add a test for uefi firmware update capsule of raw image AKASHI Takahiro

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200617025515.23585-15-takahiro.akashi@linaro.org \
    --to=takahiro.akashi@linaro.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.