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
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
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Command-line access to bloblist features
+ *
+ * Copyright 2020 Google LLC
+ * Written by Simon Glass <sjg@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));
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;
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;
BLOBLIST_ALIGN = 16,
};
+/* Supported tags - add new ones to tag_name in bloblist.c */
enum bloblist_tag_t {
BLOBLISTT_NONE = 0,
BLOBLISTT_INTEL_VBT, /* Intel Video-BIOS table */
BLOBLISTT_TPM2_TCG_LOG, /* TPM v2 log space */
BLOBLISTT_TCPA_LOG, /* TPM log space */
+
+ BLOBLISTT_COUNT
};
/**
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
#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>
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[])
{