Skip to content
Snippets Groups Projects
Commit 4aed2276 authored by Simon Glass's avatar Simon Glass
Browse files

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's avatarSimon Glass <sjg@chromium.org>
parent 9c22adb8
No related branches found
No related tags found
No related merge requests found
...@@ -631,6 +631,15 @@ config CMD_BINOP ...@@ -631,6 +631,15 @@ config CMD_BINOP
Compute binary operations (xor, or, and) of byte arrays of arbitrary Compute binary operations (xor, or, and) of byte arrays of arbitrary
size from memory and store the result in memory or the environment. 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 config CMD_CRC32
bool "crc32" bool "crc32"
default y default y
......
...@@ -24,6 +24,7 @@ obj-$(CONFIG_CMD_BDI) += bdinfo.o ...@@ -24,6 +24,7 @@ obj-$(CONFIG_CMD_BDI) += bdinfo.o
obj-$(CONFIG_CMD_BEDBUG) += bedbug.o obj-$(CONFIG_CMD_BEDBUG) += bedbug.o
obj-$(CONFIG_CMD_BIND) += bind.o obj-$(CONFIG_CMD_BIND) += bind.o
obj-$(CONFIG_CMD_BINOP) += binop.o obj-$(CONFIG_CMD_BINOP) += binop.o
obj-$(CONFIG_CMD_BLOBLIST) += bloblist.o
obj-$(CONFIG_CMD_BLOCK_CACHE) += blkcache.o obj-$(CONFIG_CMD_BLOCK_CACHE) += blkcache.o
obj-$(CONFIG_CMD_BMP) += bmp.o obj-$(CONFIG_CMD_BMP) += bmp.o
obj-$(CONFIG_CMD_BOOTCOUNT) += bootcount.o obj-$(CONFIG_CMD_BOOTCOUNT) += bootcount.o
......
// 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));
...@@ -13,15 +13,31 @@ ...@@ -13,15 +13,31 @@
DECLARE_GLOBAL_DATA_PTR; 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) if (hdr->alloced <= hdr->hdr_size)
return NULL; return NULL;
return (struct bloblist_rec *)((void *)hdr + hdr->hdr_size); return (struct bloblist_rec *)((void *)hdr + hdr->hdr_size);
} }
struct bloblist_rec *bloblist_next_blob(struct bloblist_hdr *hdr, static struct bloblist_rec *bloblist_next_blob(struct bloblist_hdr *hdr,
struct bloblist_rec *rec) struct bloblist_rec *rec)
{ {
ulong offset; ulong offset;
...@@ -233,6 +249,46 @@ int bloblist_finish(void) ...@@ -233,6 +249,46 @@ int bloblist_finish(void)
return 0; 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) int bloblist_init(void)
{ {
bool expected; bool expected;
......
...@@ -19,6 +19,7 @@ enum { ...@@ -19,6 +19,7 @@ enum {
BLOBLIST_ALIGN = 16, BLOBLIST_ALIGN = 16,
}; };
/* Supported tags - add new ones to tag_name in bloblist.c */
enum bloblist_tag_t { enum bloblist_tag_t {
BLOBLISTT_NONE = 0, BLOBLISTT_NONE = 0,
...@@ -35,6 +36,8 @@ enum bloblist_tag_t { ...@@ -35,6 +36,8 @@ enum bloblist_tag_t {
BLOBLISTT_INTEL_VBT, /* Intel Video-BIOS table */ BLOBLISTT_INTEL_VBT, /* Intel Video-BIOS table */
BLOBLISTT_TPM2_TCG_LOG, /* TPM v2 log space */ BLOBLISTT_TPM2_TCG_LOG, /* TPM v2 log space */
BLOBLISTT_TCPA_LOG, /* TPM log space */ BLOBLISTT_TCPA_LOG, /* TPM log space */
BLOBLISTT_COUNT
}; };
/** /**
...@@ -206,6 +209,35 @@ int bloblist_check(ulong addr, uint size); ...@@ -206,6 +209,35 @@ int bloblist_check(ulong addr, uint size);
*/ */
int bloblist_finish(void); 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 * bloblist_init() - Init the bloblist system with a single bloblist
* *
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <bloblist.h> #include <bloblist.h>
#include <log.h> #include <log.h>
#include <mapmem.h> #include <mapmem.h>
#include <asm/state.h>
#include <test/suites.h> #include <test/suites.h>
#include <test/test.h> #include <test/test.h>
#include <test/ut.h> #include <test/ut.h>
...@@ -231,9 +232,65 @@ static int bloblist_test_checksum(struct unit_test_state *uts) ...@@ -231,9 +232,65 @@ static int bloblist_test_checksum(struct unit_test_state *uts)
return 0; return 0;
} }
BLOBLIST_TEST(bloblist_test_checksum, 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, int do_ut_bloblist(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[]) char *const argv[])
{ {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment