[PATCH 1/5] bloblist: Add a command

Simon Glass sjg at chromium.org
Sun Sep 20 02:49:26 CEST 2020


It is helpful to be able to see basic statistics about the bloblist and
also to list its contents. Add a 'bloblist' command to handle this.

Put the display functions in the bloblist modules rather than in the
command code itself. That allows showing a list from SPL, where commands
are not available.

Also make bloblist_first/next_blob() static as they are not used outside
this file.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 cmd/Kconfig        |  9 +++++++
 cmd/Makefile       |  1 +
 cmd/bloblist.c     | 37 +++++++++++++++++++++++++++
 common/bloblist.c  | 62 +++++++++++++++++++++++++++++++++++++++++++---
 include/bloblist.h | 32 ++++++++++++++++++++++++
 test/bloblist.c    | 59 ++++++++++++++++++++++++++++++++++++++++++-
 6 files changed, 196 insertions(+), 4 deletions(-)
 create mode 100644 cmd/bloblist.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 0761dbb7460..26be32d2a59 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -631,6 +631,15 @@ config CMD_BINOP
 	  Compute binary operations (xor, or, and) of byte arrays of arbitrary
 	  size from memory and store the result in memory or the environment.
 
+config CMD_BLOBLIST
+	bool "bloblist"
+	default y if BLOBLIST
+	help
+	  Show information about the bloblist, a collection of binary blobs
+	  held in memory that persist between SPL and U-Boot. In the case of
+	  x86 devices the bloblist can be used to hold ACPI tables so that they
+	  remain available in memory.
+
 config CMD_CRC32
 	bool "crc32"
 	default y
diff --git a/cmd/Makefile b/cmd/Makefile
index 3a9c9747c94..2892f0fd803 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_CMD_BDI) += bdinfo.o
 obj-$(CONFIG_CMD_BEDBUG) += bedbug.o
 obj-$(CONFIG_CMD_BIND) += bind.o
 obj-$(CONFIG_CMD_BINOP) += binop.o
+obj-$(CONFIG_CMD_BLOBLIST) += bloblist.o
 obj-$(CONFIG_CMD_BLOCK_CACHE) += blkcache.o
 obj-$(CONFIG_CMD_BMP) += bmp.o
 obj-$(CONFIG_CMD_BOOTCOUNT) += bootcount.o
diff --git a/cmd/bloblist.c b/cmd/bloblist.c
new file mode 100644
index 00000000000..bb2e682ff84
--- /dev/null
+++ b/cmd/bloblist.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Command-line access to bloblist features
+ *
+ * Copyright 2020 Google LLC
+ * Written by Simon Glass <sjg at chromium.org>
+ */
+
+#include <common.h>
+#include <bloblist.h>
+#include <command.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int do_bloblist_info(struct cmd_tbl *cmdtp, int flag, int argc,
+			    char *const argv[])
+{
+	bloblist_show_stats();
+
+	return 0;
+}
+
+static int do_bloblist_list(struct cmd_tbl *cmdtp, int flag, int argc,
+			    char *const argv[])
+{
+	bloblist_show_list();
+
+	return 0;
+}
+
+static char bloblist_help_text[] =
+	"info   - show information about the bloblist\n"
+	"bloblist list   - list blobs in the bloblist";
+
+U_BOOT_CMD_WITH_SUBCMDS(bloblist, "Bloblists", bloblist_help_text,
+	U_BOOT_SUBCMD_MKENT(info, 1, 1, do_bloblist_info),
+	U_BOOT_SUBCMD_MKENT(list, 1, 1, do_bloblist_list));
diff --git a/common/bloblist.c b/common/bloblist.c
index 99501951e0c..c86ea029c8d 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -13,15 +13,31 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-struct bloblist_rec *bloblist_first_blob(struct bloblist_hdr *hdr)
+static const char *const tag_name[] = {
+	[BLOBLISTT_NONE]		= "(none)",
+	[BLOBLISTT_EC_HOSTEVENT]	= "EC host event",
+	[BLOBLISTT_SPL_HANDOFF]		= "SPL hand-off",
+	[BLOBLISTT_VBOOT_CTX]		= "Chrome OS vboot context",
+	[BLOBLISTT_VBOOT_HANDOFF]	= "Chrome OS vboot hand-off",
+};
+
+const char *bloblist_tag_name(enum bloblist_tag_t tag)
+{
+	if (tag < 0 || tag >= BLOBLISTT_COUNT)
+		return "invalid";
+
+	return tag_name[tag];
+}
+
+static struct bloblist_rec *bloblist_first_blob(struct bloblist_hdr *hdr)
 {
 	if (hdr->alloced <= hdr->hdr_size)
 		return NULL;
 	return (struct bloblist_rec *)((void *)hdr + hdr->hdr_size);
 }
 
-struct bloblist_rec *bloblist_next_blob(struct bloblist_hdr *hdr,
-					struct bloblist_rec *rec)
+static struct bloblist_rec *bloblist_next_blob(struct bloblist_hdr *hdr,
+					       struct bloblist_rec *rec)
 {
 	ulong offset;
 
@@ -233,6 +249,46 @@ int bloblist_finish(void)
 	return 0;
 }
 
+void bloblist_get_stats(ulong *basep, ulong *sizep, ulong *allocedp)
+{
+	struct bloblist_hdr *hdr = gd->bloblist;
+
+	*basep = map_to_sysmem(gd->bloblist);
+	*sizep = hdr->size;
+	*allocedp = hdr->alloced;
+}
+
+static void show_value(const char *prompt, ulong value)
+{
+	printf("%s:%*s %-5lx  ", prompt, 8 - (int)strlen(prompt), "", value);
+	print_size(value, "\n");
+}
+
+void bloblist_show_stats(void)
+{
+	ulong base, size, alloced;
+
+	bloblist_get_stats(&base, &size, &alloced);
+	printf("base:     %lx\n", base);
+	show_value("size", size);
+	show_value("alloced", alloced);
+	show_value("free", size - alloced);
+}
+
+void bloblist_show_list(void)
+{
+	struct bloblist_hdr *hdr = gd->bloblist;
+	struct bloblist_rec *rec;
+
+	printf("%-8s  %8s  Tag Name\n", "Address", "Size");
+	for (rec = bloblist_first_blob(hdr); rec;
+	     rec = bloblist_next_blob(hdr, rec)) {
+		printf("%08lx  %8x  %3d %s\n",
+		       (ulong)map_to_sysmem((void *)rec + rec->hdr_size),
+		       rec->size, rec->tag, bloblist_tag_name(rec->tag));
+	}
+}
+
 int bloblist_init(void)
 {
 	bool expected;
diff --git a/include/bloblist.h b/include/bloblist.h
index 609ac421d66..57c0794793b 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -19,6 +19,7 @@ enum {
 	BLOBLIST_ALIGN		= 16,
 };
 
+/* Supported tags - add new ones to tag_name in bloblist.c */
 enum bloblist_tag_t {
 	BLOBLISTT_NONE = 0,
 
@@ -27,6 +28,8 @@ enum bloblist_tag_t {
 	BLOBLISTT_SPL_HANDOFF,		/* Hand-off info from SPL */
 	BLOBLISTT_VBOOT_CTX,		/* Chromium OS verified boot context */
 	BLOBLISTT_VBOOT_HANDOFF,	/* Chromium OS internal handoff info */
+
+	BLOBLISTT_COUNT
 };
 
 /**
@@ -198,6 +201,35 @@ int bloblist_check(ulong addr, uint size);
  */
 int bloblist_finish(void);
 
+/**
+ * bloblist_get_stats() - Get information about the bloblist
+ *
+ * This returns useful information about the bloblist
+ */
+void bloblist_get_stats(ulong *basep, ulong *sizep, ulong *allocedp);
+
+/**
+ * bloblist_show_stats() - Show information about the bloblist
+ *
+ * This shows useful information about the bloblist on the console
+ */
+void bloblist_show_stats(void);
+
+/**
+ * bloblist_show_list() - Show a list of blobs in the bloblist
+ *
+ * This shows a list of blobs, showing their address, size and tag.
+ */
+void bloblist_show_list(void);
+
+/**
+ * bloblist_tag_name() - Get the name for a tag
+ *
+ * @tag: Tag to check
+ * @return name of tag, or "invalid" if an invalid tag is provided
+ */
+const char *bloblist_tag_name(enum bloblist_tag_t tag);
+
 /**
  * bloblist_init() - Init the bloblist system with a single bloblist
  *
diff --git a/test/bloblist.c b/test/bloblist.c
index 4e537ee1b9c..cbdc9db4ecf 100644
--- a/test/bloblist.c
+++ b/test/bloblist.c
@@ -7,6 +7,7 @@
 #include <bloblist.h>
 #include <log.h>
 #include <mapmem.h>
+#include <asm/state.h>
 #include <test/suites.h>
 #include <test/test.h>
 #include <test/ut.h>
@@ -231,9 +232,65 @@ static int bloblist_test_checksum(struct unit_test_state *uts)
 
 	return 0;
 }
-
 BLOBLIST_TEST(bloblist_test_checksum, 0);
 
+/* Test the 'bloblist info' command */
+static int bloblist_test_cmd_info(struct unit_test_state *uts)
+{
+	struct sandbox_state *state = state_get_current();
+	struct bloblist_hdr *hdr;
+	char *data, *data2;
+
+	hdr = clear_bloblist();
+	ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+	data = bloblist_ensure(TEST_TAG, TEST_SIZE);
+	data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
+
+	console_record_reset_enable();
+	if (!state->show_test_output)
+		gd->flags |= GD_FLG_SILENT;
+	console_record_reset();
+	run_command("bloblist info", 0);
+	ut_assert_nextline("base:     %x", map_to_sysmem(hdr));
+	ut_assert_nextline("size:     100    256 Bytes");
+	ut_assert_nextline("alloced:  70     112 Bytes");
+	ut_assert_nextline("free:     90     144 Bytes");
+	ut_assert_console_end();
+	gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
+
+	return 0;
+}
+BLOBLIST_TEST(bloblist_test_cmd_info, 0);
+
+/* Test the 'bloblist list' command */
+static int bloblist_test_cmd_list(struct unit_test_state *uts)
+{
+	struct sandbox_state *state = state_get_current();
+	struct bloblist_hdr *hdr;
+	char *data, *data2;
+
+	hdr = clear_bloblist();
+	ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+	data = bloblist_ensure(TEST_TAG, TEST_SIZE);
+	data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
+
+	console_record_reset_enable();
+	if (!state->show_test_output)
+		gd->flags |= GD_FLG_SILENT;
+	console_record_reset();
+	run_command("bloblist list", 0);
+	ut_assert_nextline("Address       Size  Tag Name");
+	ut_assert_nextline("%08x  %8x    1 EC host event", map_to_sysmem(data),
+			   TEST_SIZE);
+	ut_assert_nextline("%08x  %8x    2 SPL hand-off", map_to_sysmem(data2),
+			   TEST_SIZE2);
+	ut_assert_console_end();
+	gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
+
+	return 0;
+}
+BLOBLIST_TEST(bloblist_test_cmd_list, 0);
+
 int do_ut_bloblist(struct cmd_tbl *cmdtp, int flag, int argc,
 		   char *const argv[])
 {
-- 
2.28.0.681.g6f77f65b4e-goog



More information about the U-Boot mailing list