summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Kconfig95
-rw-r--r--common/bloblist.c119
-rw-r--r--common/board_f.c2
-rw-r--r--common/spl/spl.c4
4 files changed, 163 insertions, 57 deletions
diff --git a/common/Kconfig b/common/Kconfig
index 0892d9be362..82cd864baf9 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -717,7 +717,7 @@ config BLOBLIST
from TPL to SPL to U-Boot proper (and potentially to Linux). The
blob list supports multiple binary blobs of data, each with a tag,
so that different U-Boot components can store data which can survive
- through to the next stage of the boot.
+ through to the next phase of the boot.
config SPL_BLOBLIST
bool "Support for a bloblist in SPL"
@@ -738,15 +738,17 @@ config TPL_BLOBLIST
if BLOBLIST
-config BLOBLIST_SIZE
- hex "Size of bloblist"
- depends on BLOBLIST
- default 0x400
+choice
+ prompt "Bloblist location"
help
- Sets the size of the bloblist in bytes. This must include all
- overhead (alignment, bloblist header, record header). The bloblist
- is set up in the first part of U-Boot to run (TPL, SPL or U-Boot
- proper), and this sane bloblist is used for subsequent stages.
+ Select the location of the bloblist, via various means.
+
+config BLOBLIST_FIXED
+ bool "Place bloblist at a fixed address in memory"
+ help
+ Select this to used a fixed memory address for the bloblist. If the
+ bloblist exists at this address from a previous phase, it used as is.
+ If not it is created at this address in U-Boot.
config BLOBLIST_ALLOC
bool "Allocate bloblist"
@@ -755,18 +757,31 @@ config BLOBLIST_ALLOC
specify a fixed address on systems where this is unknown or can
change at runtime.
+endchoice
+
config BLOBLIST_ADDR
hex "Address of bloblist"
default 0xc000 if SANDBOX
+ depends on BLOBLIST_FIXED
help
Sets the address of the bloblist, set up by the first part of U-Boot
- which runs. Subsequent U-Boot stages typically use the same address.
+ which runs. Subsequent U-Boot phases typically use the same address.
This is not used if BLOBLIST_ALLOC is selected.
+config BLOBLIST_SIZE
+ hex "Size of bloblist"
+ default 0x400
+ help
+ Sets the size of the bloblist in bytes. This must include all
+ overhead (alignment, bloblist header, record header). The bloblist
+ is set up in the first part of U-Boot to run (TPL, SPL or U-Boot
+ proper), and this sane bloblist is used for subsequent phases.
+
config BLOBLIST_SIZE_RELOC
hex "Size of bloblist after relocation"
- default BLOBLIST_SIZE
+ default BLOBLIST_SIZE if BLOBLIST_FIXED || BLOBLIST_ALLOC
+ default 0 if BLOBLIST_PASSAGE
help
Sets the size of the bloblist in bytes after relocation. Since U-Boot
has a lot more memory available then, it is possible to use a larger
@@ -775,6 +790,64 @@ config BLOBLIST_SIZE_RELOC
endif # BLOBLIST
+if SPL_BLOBLIST
+
+choice
+ prompt "Bloblist location in SPL"
+ help
+ Select the location of the bloblist, via various means. Typically
+ you should use the same value for SPL as for U-Boot, since they need
+ to look in the same place. But if BLOBLIST_ALLOC is used, then a
+ fresh bloblist will be created each time, since there is no shared
+ address (between phases) for the bloblist.
+
+config SPL_BLOBLIST_FIXED
+ bool "Place bloblist at a fixed address in memory"
+ help
+ Select this to used a fixed memory address for the bloblist. If the
+ bloblist exists at this address from a previous phase, it used as is.
+ If not it is created at this address in SPL.
+
+config SPL_BLOBLIST_ALLOC
+ bool "Allocate bloblist"
+ help
+ Allocate the bloblist using malloc(). This avoids the need to
+ specify a fixed address on systems where this is unknown or can
+ change at runtime.
+
+endchoice
+
+endif # SPL_BLOBLIST
+
+if TPL_BLOBLIST
+
+choice
+ prompt "Bloblist location in TPL"
+ help
+ Select the location of the bloblist, via various means. Typically
+ you should use the same value for SPL as for U-Boot, since they need
+ to look in the same place. But if BLOBLIST_ALLOC is used, then a
+ fresh bloblist will be created each time, since there is no shared
+ address (between phases) for the bloblist.
+
+config TPL_BLOBLIST_FIXED
+ bool "Place bloblist at a fixed address in memory"
+ help
+ Select this to used a fixed memory address for the bloblist. If the
+ bloblist exists at this address from a previous phase, it used as is.
+ If not it is created at this address in TPL.
+
+config TPL_BLOBLIST_ALLOC
+ bool "Allocate bloblist"
+ help
+ Allocate the bloblist using malloc(). This avoids the need to
+ specify a fixed address on systems where this is unknown or can
+ change at runtime.
+
+endchoice
+
+endif # TPL_BLOBLIST
+
endmenu
source "common/spl/Kconfig"
diff --git a/common/bloblist.c b/common/bloblist.c
index 01b04103d91..056b50c2cb6 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -1,9 +1,12 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause
/*
* Copyright 2018 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*/
+#define LOG_DEBUG
+#define LOG_CATEGORY LOGC_BLOBLIST
+
#include <common.h>
#include <bloblist.h>
#include <log.h>
@@ -29,26 +32,39 @@
DECLARE_GLOBAL_DATA_PTR;
-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",
- [BLOBLISTT_ACPI_GNVS] = "ACPI GNVS",
- [BLOBLISTT_INTEL_VBT] = "Intel Video-BIOS table",
- [BLOBLISTT_TPM2_TCG_LOG] = "TPM v2 log space",
- [BLOBLISTT_TCPA_LOG] = "TPM log space",
- [BLOBLISTT_ACPI_TABLES] = "ACPI tables for x86",
- [BLOBLISTT_SMBIOS_TABLES] = "SMBIOS tables for x86",
+static struct tag_name {
+ enum bloblist_tag_t tag;
+ const char *name;
+} tag_name[] = {
+ { BLOBLISTT_NONE, "(none)" },
+
+ /* BLOBLISTT_AREA_FIRMWARE_TOP */
+
+ /* BLOBLISTT_AREA_FIRMWARE */
+ { BLOBLISTT_ACPI_GNVS, "ACPI GNVS" },
+ { BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" },
+ { BLOBLISTT_TPM2_TCG_LOG, "TPM v2 log space" },
+ { BLOBLISTT_TCPA_LOG, "TPM log space" },
+ { BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
+ { BLOBLISTT_SMBIOS_TABLES, "SMBIOS tables for x86" },
+ { BLOBLISTT_VBOOT_CTX, "Chrome OS vboot context" },
+
+ /* BLOBLISTT_PROJECT_AREA */
+ { BLOBLISTT_U_BOOT_SPL_HANDOFF, "SPL hand-off" },
+
+ /* BLOBLISTT_VENDOR_AREA */
};
const char *bloblist_tag_name(enum bloblist_tag_t tag)
{
- if (tag < 0 || tag >= BLOBLISTT_COUNT)
- return "invalid";
+ int i;
- return tag_name[tag];
+ for (i = 0; i < ARRAY_SIZE(tag_name); i++) {
+ if (tag_name[i].tag == tag)
+ return tag_name[i].name;
+ }
+
+ return "invalid";
}
static struct bloblist_rec *bloblist_first_blob(struct bloblist_hdr *hdr)
@@ -120,9 +136,8 @@ static int bloblist_addrec(uint tag, int size, int align,
new_alloced = data_start + ALIGN(size, align);
if (new_alloced > hdr->size) {
- log(LOGC_BLOBLIST, LOGL_ERR,
- "Failed to allocate %x bytes size=%x, need size=%x\n",
- size, hdr->size, new_alloced);
+ log_err("Failed to allocate %x bytes size=%x, need size=%x\n",
+ size, hdr->size, new_alloced);
return log_msg_ret("bloblist add", -ENOSPC);
}
rec = (void *)hdr + hdr->alloced;
@@ -236,14 +251,13 @@ static int bloblist_resize_rec(struct bloblist_hdr *hdr,
expand_by = ALIGN(new_size - rec->size, BLOBLIST_ALIGN);
new_alloced = ALIGN(hdr->alloced + expand_by, BLOBLIST_ALIGN);
if (new_size < 0) {
- log(LOGC_BLOBLIST, LOGL_DEBUG,
- "Attempt to shrink blob size below 0 (%x)\n", new_size);
+ log_debug("Attempt to shrink blob size below 0 (%x)\n",
+ new_size);
return log_msg_ret("size", -EINVAL);
}
if (new_alloced > hdr->size) {
- log(LOGC_BLOBLIST, LOGL_ERR,
- "Failed to allocate %x bytes size=%x, need size=%x\n",
- new_size, hdr->size, new_alloced);
+ log_err("Failed to allocate %x bytes size=%x, need size=%x\n",
+ new_size, hdr->size, new_alloced);
return log_msg_ret("alloc", -ENOSPC);
}
@@ -334,8 +348,7 @@ int bloblist_check(ulong addr, uint size)
return log_msg_ret("Bad size", -EFBIG);
chksum = bloblist_calc_chksum(hdr);
if (hdr->chksum != chksum) {
- log(LOGC_BLOBLIST, LOGL_ERR, "Checksum %x != %x\n", hdr->chksum,
- chksum);
+ log_err("Checksum %x != %x\n", hdr->chksum, chksum);
return log_msg_ret("Bad checksum", -EIO);
}
gd->bloblist = hdr;
@@ -348,10 +361,24 @@ int bloblist_finish(void)
struct bloblist_hdr *hdr = gd->bloblist;
hdr->chksum = bloblist_calc_chksum(hdr);
+ log_debug("Finished bloblist size %lx at %lx\n", (ulong)hdr->size,
+ (ulong)map_to_sysmem(hdr));
return 0;
}
+ulong bloblist_get_base(void)
+{
+ return map_to_sysmem(gd->bloblist);
+}
+
+ulong bloblist_get_size(void)
+{
+ struct bloblist_hdr *hdr = gd->bloblist;
+
+ return hdr->size;
+}
+
void bloblist_get_stats(ulong *basep, ulong *sizep, ulong *allocedp)
{
struct bloblist_hdr *hdr = gd->bloblist;
@@ -383,10 +410,10 @@ void bloblist_show_list(void)
struct bloblist_hdr *hdr = gd->bloblist;
struct bloblist_rec *rec;
- printf("%-8s %8s Tag Name\n", "Address", "Size");
+ 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",
+ printf("%08lx %8x %4x %s\n",
(ulong)map_to_sysmem((void *)rec + rec->hdr_size),
rec->size, rec->tag, bloblist_tag_name(rec->tag));
}
@@ -403,8 +430,9 @@ void bloblist_reloc(void *to, uint to_size, void *from, uint from_size)
int bloblist_init(void)
{
- bool expected;
int ret = -ENOENT;
+ ulong addr, size;
+ bool expected;
/**
* Wed expect to find an existing bloblist in the first phase of U-Boot
@@ -413,27 +441,32 @@ int bloblist_init(void)
expected = !u_boot_first_phase();
if (spl_prev_phase() == PHASE_TPL && !IS_ENABLED(CONFIG_TPL_BLOBLIST))
expected = false;
- if (expected)
- ret = bloblist_check(CONFIG_BLOBLIST_ADDR,
- CONFIG_BLOBLIST_SIZE);
+ addr = bloblist_addr();
+ size = CONFIG_BLOBLIST_SIZE;
+ if (expected) {
+ ret = bloblist_check(addr, size);
+ if (ret) {
+ log_warning("Expected bloblist at %lx not found (err=%d)\n",
+ addr, ret);
+ } else {
+ /* Get the real size, if it is not what we expected */
+ size = gd->bloblist->size;
+ }
+ }
if (ret) {
- ulong addr;
-
- log(LOGC_BLOBLIST, expected ? LOGL_WARNING : LOGL_DEBUG,
- "Existing bloblist not found: creating new bloblist\n");
- if (IS_ENABLED(CONFIG_BLOBLIST_ALLOC)) {
- void *ptr = memalign(BLOBLIST_ALIGN,
- CONFIG_BLOBLIST_SIZE);
+ if (CONFIG_IS_ENABLED(BLOBLIST_ALLOC)) {
+ void *ptr = memalign(BLOBLIST_ALIGN, size);
if (!ptr)
return log_msg_ret("alloc", -ENOMEM);
addr = map_to_sysmem(ptr);
- } else {
- addr = CONFIG_BLOBLIST_ADDR;
}
- ret = bloblist_new(addr, CONFIG_BLOBLIST_SIZE, 0);
+ log_debug("Creating new bloblist size %lx at %lx\n", size,
+ addr);
+ ret = bloblist_new(addr, size, 0);
} else {
- log(LOGC_BLOBLIST, LOGL_DEBUG, "Found existing bloblist\n");
+ log_debug("Found existing bloblist size %lx at %lx\n", size,
+ addr);
}
return ret;
diff --git a/common/board_f.c b/common/board_f.c
index dd69c3b6b77..a68760092ac 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -283,7 +283,7 @@ static int setup_mon_len(void)
static int setup_spl_handoff(void)
{
#if CONFIG_IS_ENABLED(HANDOFF)
- gd->spl_handoff = bloblist_find(BLOBLISTT_SPL_HANDOFF,
+ gd->spl_handoff = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF,
sizeof(struct spl_handoff));
debug("Found SPL hand-off info %p\n", gd->spl_handoff);
#endif
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 4c101ec5d34..f51d1f32052 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -408,7 +408,7 @@ static int setup_spl_handoff(void)
{
struct spl_handoff *ho;
- ho = bloblist_ensure(BLOBLISTT_SPL_HANDOFF, sizeof(struct spl_handoff));
+ ho = bloblist_ensure(BLOBLISTT_U_BOOT_SPL_HANDOFF, sizeof(struct spl_handoff));
if (!ho)
return -ENOENT;
@@ -425,7 +425,7 @@ static int write_spl_handoff(void)
struct spl_handoff *ho;
int ret;
- ho = bloblist_find(BLOBLISTT_SPL_HANDOFF, sizeof(struct spl_handoff));
+ ho = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF, sizeof(struct spl_handoff));
if (!ho)
return -ENOENT;
handoff_save_dram(ho);