From 4aed22762303755f8f26d14f0ad2608d63550e72 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 19 Sep 2020 18:49:26 -0600 Subject: [PATCH] bloblist: Add a command 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 --- 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 999b6cf..b25d2b0 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 c7a08ed..015b837 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 0000000..bb2e682 --- /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 + */ + +#include +#include +#include + +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 9950195..c86ea02 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 5784c22..6c37cd2 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, @@ -35,6 +36,8 @@ enum bloblist_tag_t { BLOBLISTT_INTEL_VBT, /* Intel Video-BIOS table */ BLOBLISTT_TPM2_TCG_LOG, /* TPM v2 log space */ BLOBLISTT_TCPA_LOG, /* TPM log space */ + + BLOBLISTT_COUNT }; /** @@ -207,6 +210,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 * * This uses CONFIG_BLOBLIST_ADDR and CONFIG_BLOBLIST_SIZE to set up a bloblist diff --git a/test/bloblist.c b/test/bloblist.c index 4e537ee..cbdc9db 100644 --- a/test/bloblist.c +++ b/test/bloblist.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -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.7.4