support propagating supernode properties with bootph schema

align bloblist with v0.9 of Firmware Handoff spec
 -----BEGIN PGP SIGNATURE-----
 
 iQFFBAABCgAvFiEEslwAIq+Gp8wWVbYnfxc6PpAIreYFAmWS9jwRHHNqZ0BjaHJv
 bWl1bS5vcmcACgkQfxc6PpAIreZvYggAnc11fzAPnWZK5Nz7RxqoT1vMl/xAaSMJ
 gKaL8V0vAY7I0s3+jMoEfed29OAIkxs68nfEV0Hu4RKc2ER6gIYjun5VOP8G6B9j
 B1S/IbWgMtz+Vn/TQNy72zbWcU/FeypU2ZICAEN7v1hksjZoM7jbytLa/OkPjSA1
 ONEIZTwYL+pXFSneAcXU1cugQX2RO+L5gYNlZF8yv6Jb5DQj0noOvhbvW1s9XvF3
 VognW1UVDmBr0KPaJVufMm0YGaurwsjeb7SaKzgk/9CUY+j6AqpfqqBaK6+KoPku
 MOjyc7shsxmJsBiLVflzSVE7WAvlTcRN6hLzoJd/4JVs+/fazz9P1A==
 =b5aT
 -----END PGP SIGNATURE-----

Merge tag 'dm-next-1124' of https://source.denx.de/u-boot/custodians/u-boot-dm into next

support propagating supernode properties with bootph schema
align bloblist with v0.9 of Firmware Handoff spec
This commit is contained in:
Tom Rini 2024-01-01 12:38:15 -05:00
commit dffa6d0210
11 changed files with 401 additions and 248 deletions

View file

@ -369,12 +369,14 @@
rw-mrc-cache {
label = "rw-mrc-cache";
reg = <0x008e0000 0x00010000>;
bootph-all;
bootph-some-ram;
bootph-pre-ram;
};
rw-var-mrc-cache {
label = "rw-mrc-cache";
reg = <0x008f0000 0x0001000>;
bootph-all;
bootph-some-ram;
bootph-pre-ram;
};
};
};

View file

@ -16,6 +16,7 @@
#include <asm/mpspec.h>
#include <asm/tables.h>
#include <asm/coreboot_tables.h>
#include <linux/log2.h>
DECLARE_GLOBAL_DATA_PTR;
@ -104,7 +105,7 @@ int write_tables(void)
if (!gd->arch.table_end)
gd->arch.table_end = rom_addr;
rom_addr = (ulong)bloblist_add(table->tag, size,
table->align);
ilog2(table->align));
if (!rom_addr)
return log_msg_ret("bloblist", -ENOBUFS);

View file

@ -13,6 +13,7 @@
#include <malloc.h>
#include <mapmem.h>
#include <spl.h>
#include <tables_csum.h>
#include <asm/global_data.h>
#include <u-boot/crc.h>
@ -26,8 +27,6 @@
* start address of the data in each blob is aligned as required. Note that
* each blob's *data* is aligned to BLOBLIST_ALIGN regardless of the alignment
* of the bloblist itself or the blob header.
*
* So far, only BLOBLIST_ALIGN alignment is supported.
*/
DECLARE_GLOBAL_DATA_PTR;
@ -36,16 +35,26 @@ static struct tag_name {
enum bloblist_tag_t tag;
const char *name;
} tag_name[] = {
{ BLOBLISTT_NONE, "(none)" },
{ BLOBLISTT_VOID, "(void)" },
/* BLOBLISTT_AREA_FIRMWARE_TOP */
{ BLOBLISTT_CONTROL_FDT, "Control FDT" },
{ BLOBLISTT_HOB_BLOCK, "HOB block" },
{ BLOBLISTT_HOB_LIST, "HOB list" },
{ BLOBLISTT_ACPI_TABLES, "ACPI tables for x86" },
{ BLOBLISTT_TPM_EVLOG, "TPM event log defined by TCG EFI" },
{ BLOBLISTT_TPM_CRB_BASE, "TPM Command Response Buffer address" },
/* 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_ACPI_GNVS, "ACPI GNVS" },
/* BLOBLISTT_AREA_TF */
{ BLOBLISTT_OPTEE_PAGABLE_PART, "OP-TEE pagable part" },
/* BLOBLISTT_AREA_OTHER */
{ BLOBLISTT_INTEL_VBT, "Intel Video-BIOS table" },
{ BLOBLISTT_SMBIOS_TABLES, "SMBIOS tables for x86" },
{ BLOBLISTT_VBOOT_CTX, "Chrome OS vboot context" },
@ -71,18 +80,36 @@ const char *bloblist_tag_name(enum bloblist_tag_t tag)
static struct bloblist_rec *bloblist_first_blob(struct bloblist_hdr *hdr)
{
if (hdr->alloced <= hdr->hdr_size)
if (hdr->used_size <= hdr->hdr_size)
return NULL;
return (struct bloblist_rec *)((void *)hdr + hdr->hdr_size);
}
static inline uint rec_hdr_size(struct bloblist_rec *rec)
{
return (rec->tag_and_hdr_size & BLOBLISTR_HDR_SIZE_MASK) >>
BLOBLISTR_HDR_SIZE_SHIFT;
}
static inline uint rec_tag(struct bloblist_rec *rec)
{
return (rec->tag_and_hdr_size & BLOBLISTR_TAG_MASK) >>
BLOBLISTR_TAG_SHIFT;
}
static ulong bloblist_blob_end_ofs(struct bloblist_hdr *hdr,
struct bloblist_rec *rec)
{
ulong offset;
offset = (void *)rec - (void *)hdr;
offset += rec->hdr_size + ALIGN(rec->size, BLOBLIST_ALIGN);
/*
* The data section of next TE should start from an address aligned
* to 1 << hdr->align_log2.
*/
offset += rec_hdr_size(rec) + rec->size;
offset = round_up(offset + rec_hdr_size(rec), 1 << hdr->align_log2);
offset -= rec_hdr_size(rec);
return offset;
}
@ -92,7 +119,7 @@ static struct bloblist_rec *bloblist_next_blob(struct bloblist_hdr *hdr,
{
ulong offset = bloblist_blob_end_ofs(hdr, rec);
if (offset >= hdr->alloced)
if (offset >= hdr->used_size)
return NULL;
return (struct bloblist_rec *)((void *)hdr + offset);
}
@ -111,55 +138,69 @@ static struct bloblist_rec *bloblist_findrec(uint tag)
return NULL;
foreach_rec(rec, hdr) {
if (rec->tag == tag)
if (rec_tag(rec) == tag)
return rec;
}
return NULL;
}
static int bloblist_addrec(uint tag, int size, int align,
static int bloblist_addrec(uint tag, int size, int align_log2,
struct bloblist_rec **recp)
{
struct bloblist_hdr *hdr = gd->bloblist;
struct bloblist_rec *rec;
int data_start, new_alloced;
int data_start, aligned_start, new_alloced;
if (!align)
align = BLOBLIST_ALIGN;
if (!align_log2)
align_log2 = BLOBLIST_BLOB_ALIGN_LOG2;
/* Figure out where the new data will start */
data_start = map_to_sysmem(hdr) + hdr->alloced + sizeof(*rec);
data_start = map_to_sysmem(hdr) + hdr->used_size + sizeof(*rec);
/* Align the address and then calculate the offset from ->alloced */
data_start = ALIGN(data_start, align) - map_to_sysmem(hdr);
/* Align the address and then calculate the offset from used size */
aligned_start = ALIGN(data_start, 1U << align_log2) - data_start;
/* If we need to create a dummy record, create it */
if (aligned_start) {
int void_size = aligned_start - sizeof(*rec);
struct bloblist_rec *vrec;
int ret;
ret = bloblist_addrec(BLOBLISTT_VOID, void_size, 0, &vrec);
if (ret)
return log_msg_ret("void", ret);
/* start the record after that */
data_start = map_to_sysmem(hdr) + hdr->used_size + sizeof(*vrec);
}
/* Calculate the new allocated total */
new_alloced = data_start + ALIGN(size, align);
new_alloced = data_start - map_to_sysmem(hdr) +
ALIGN(size, 1U << align_log2);
if (new_alloced > hdr->size) {
log_err("Failed to allocate %x bytes size=%x, need size=%x\n",
size, hdr->size, new_alloced);
if (new_alloced > hdr->total_size) {
log_err("Failed to allocate %x bytes\n", size);
log_err("Used size=%x, total size=%x\n",
hdr->used_size, hdr->total_size);
return log_msg_ret("bloblist add", -ENOSPC);
}
rec = (void *)hdr + hdr->alloced;
rec = (void *)hdr + hdr->used_size;
rec->tag = tag;
rec->hdr_size = data_start - hdr->alloced;
rec->tag_and_hdr_size = tag | sizeof(*rec) << BLOBLISTR_HDR_SIZE_SHIFT;
rec->size = size;
rec->spare = 0;
/* Zero the record data */
memset((void *)rec + rec->hdr_size, '\0', rec->size);
memset((void *)rec + rec_hdr_size(rec), '\0', rec->size);
hdr->alloced = new_alloced;
hdr->used_size = new_alloced;
*recp = rec;
return 0;
}
static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size,
int align)
int align_log2)
{
struct bloblist_rec *rec;
@ -172,7 +213,7 @@ static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size,
} else {
int ret;
ret = bloblist_addrec(tag, size, align, &rec);
ret = bloblist_addrec(tag, size, align_log2, &rec);
if (ret)
return ret;
}
@ -191,28 +232,28 @@ void *bloblist_find(uint tag, int size)
if (size && size != rec->size)
return NULL;
return (void *)rec + rec->hdr_size;
return (void *)rec + rec_hdr_size(rec);
}
void *bloblist_add(uint tag, int size, int align)
void *bloblist_add(uint tag, int size, int align_log2)
{
struct bloblist_rec *rec;
if (bloblist_addrec(tag, size, align, &rec))
if (bloblist_addrec(tag, size, align_log2, &rec))
return NULL;
return (void *)rec + rec->hdr_size;
return (void *)rec + rec_hdr_size(rec);
}
int bloblist_ensure_size(uint tag, int size, int align, void **blobp)
int bloblist_ensure_size(uint tag, int size, int align_log2, void **blobp)
{
struct bloblist_rec *rec;
int ret;
ret = bloblist_ensurerec(tag, &rec, size, align);
ret = bloblist_ensurerec(tag, &rec, size, align_log2);
if (ret)
return ret;
*blobp = (void *)rec + rec->hdr_size;
*blobp = (void *)rec + rec_hdr_size(rec);
return 0;
}
@ -224,7 +265,7 @@ void *bloblist_ensure(uint tag, int size)
if (bloblist_ensurerec(tag, &rec, size, 0))
return NULL;
return (void *)rec + rec->hdr_size;
return (void *)rec + rec_hdr_size(rec);
}
int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp)
@ -237,7 +278,7 @@ int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp)
*sizep = rec->size;
else if (ret)
return ret;
*blobp = (void *)rec + rec->hdr_size;
*blobp = (void *)rec + rec_hdr_size(rec);
return 0;
}
@ -247,33 +288,34 @@ static int bloblist_resize_rec(struct bloblist_hdr *hdr,
int new_size)
{
int expand_by; /* Number of bytes to expand by (-ve to contract) */
int new_alloced; /* New value for @hdr->alloced */
int new_alloced;
ulong next_ofs; /* Offset of the record after @rec */
expand_by = ALIGN(new_size - rec->size, BLOBLIST_ALIGN);
new_alloced = ALIGN(hdr->alloced + expand_by, BLOBLIST_ALIGN);
expand_by = ALIGN(new_size - rec->size, BLOBLIST_BLOB_ALIGN);
new_alloced = ALIGN(hdr->used_size + expand_by, BLOBLIST_BLOB_ALIGN);
if (new_size < 0) {
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_err("Failed to allocate %x bytes size=%x, need size=%x\n",
new_size, hdr->size, new_alloced);
if (new_alloced > hdr->total_size) {
log_err("Failed to allocate %x bytes\n", new_size);
log_err("Used size=%x, total size=%x\n",
hdr->used_size, hdr->total_size);
return log_msg_ret("alloc", -ENOSPC);
}
/* Move the following blobs up or down, if this is not the last */
next_ofs = bloblist_blob_end_ofs(hdr, rec);
if (next_ofs != hdr->alloced) {
if (next_ofs != hdr->used_size) {
memmove((void *)hdr + next_ofs + expand_by,
(void *)hdr + next_ofs, new_alloced - next_ofs);
}
hdr->alloced = new_alloced;
hdr->used_size = new_alloced;
/* Zero the new part of the blob */
if (expand_by > 0) {
memset((void *)rec + rec->hdr_size + rec->size, '\0',
memset((void *)rec + rec_hdr_size(rec) + rec->size, '\0',
new_size - rec->size);
}
@ -301,20 +343,15 @@ int bloblist_resize(uint tag, int new_size)
static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr)
{
struct bloblist_rec *rec;
u32 chksum;
u8 chksum;
chksum = crc32(0, (unsigned char *)hdr,
offsetof(struct bloblist_hdr, chksum));
foreach_rec(rec, hdr) {
chksum = crc32(chksum, (void *)rec, rec->hdr_size);
chksum = crc32(chksum, (void *)rec + rec->hdr_size, rec->size);
}
chksum = table_compute_checksum(hdr, hdr->used_size);
chksum += hdr->chksum;
return chksum;
}
int bloblist_new(ulong addr, uint size, uint flags)
int bloblist_new(ulong addr, uint size, uint flags, uint align_log2)
{
struct bloblist_hdr *hdr;
@ -328,8 +365,9 @@ int bloblist_new(ulong addr, uint size, uint flags)
hdr->hdr_size = sizeof(*hdr);
hdr->flags = flags;
hdr->magic = BLOBLIST_MAGIC;
hdr->size = size;
hdr->alloced = hdr->hdr_size;
hdr->used_size = hdr->hdr_size;
hdr->total_size = size;
hdr->align_log2 = align_log2 ? align_log2 : BLOBLIST_BLOB_ALIGN_LOG2;
hdr->chksum = 0;
gd->bloblist = hdr;
@ -346,8 +384,13 @@ int bloblist_check(ulong addr, uint size)
return log_msg_ret("Bad magic", -ENOENT);
if (hdr->version != BLOBLIST_VERSION)
return log_msg_ret("Bad version", -EPROTONOSUPPORT);
if (size && hdr->size != size)
return log_msg_ret("Bad size", -EFBIG);
if (!hdr->total_size || (size && hdr->total_size != size))
return log_msg_ret("Bad total size", -EFBIG);
if (hdr->used_size > hdr->total_size)
return log_msg_ret("Bad used size", -ENOENT);
if (hdr->hdr_size != sizeof(struct bloblist_hdr))
return log_msg_ret("Bad header size", -ENOENT);
chksum = bloblist_calc_chksum(hdr);
if (hdr->chksum != chksum) {
log_err("Checksum %x != %x\n", hdr->chksum, chksum);
@ -363,7 +406,7 @@ 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,
log_debug("Finished bloblist size %lx at %lx\n", (ulong)hdr->used_size,
(ulong)map_to_sysmem(hdr));
return 0;
@ -378,33 +421,40 @@ ulong bloblist_get_size(void)
{
struct bloblist_hdr *hdr = gd->bloblist;
return hdr->size;
return hdr->used_size;
}
void bloblist_get_stats(ulong *basep, ulong *sizep, ulong *allocedp)
ulong bloblist_get_total_size(void)
{
struct bloblist_hdr *hdr = gd->bloblist;
return hdr->total_size;
}
void bloblist_get_stats(ulong *basep, ulong *tsizep, ulong *usizep)
{
struct bloblist_hdr *hdr = gd->bloblist;
*basep = map_to_sysmem(gd->bloblist);
*sizep = hdr->size;
*allocedp = hdr->alloced;
*tsizep = hdr->total_size;
*usizep = hdr->used_size;
}
static void show_value(const char *prompt, ulong value)
{
printf("%s:%*s %-5lx ", prompt, 8 - (int)strlen(prompt), "", value);
printf("%s:%*s %-5lx ", prompt, 10 - (int)strlen(prompt), "", value);
print_size(value, "\n");
}
void bloblist_show_stats(void)
{
ulong base, size, alloced;
ulong base, tsize, usize;
bloblist_get_stats(&base, &size, &alloced);
printf("base: %lx\n", base);
show_value("size", size);
show_value("alloced", alloced);
show_value("free", size - alloced);
bloblist_get_stats(&base, &tsize, &usize);
printf("base: %lx\n", base);
show_value("total size", tsize);
show_value("used size", usize);
show_value("free", tsize - usize);
}
void bloblist_show_list(void)
@ -416,8 +466,9 @@ void bloblist_show_list(void)
for (rec = bloblist_first_blob(hdr); rec;
rec = bloblist_next_blob(hdr, rec)) {
printf("%08lx %8x %4x %s\n",
(ulong)map_to_sysmem((void *)rec + rec->hdr_size),
rec->size, rec->tag, bloblist_tag_name(rec->tag));
(ulong)map_to_sysmem((void *)rec + rec_hdr_size(rec)),
rec->size, rec_tag(rec),
bloblist_tag_name(rec_tag(rec)));
}
}
@ -427,7 +478,7 @@ void bloblist_reloc(void *to, uint to_size, void *from, uint from_size)
memcpy(to, from, from_size);
hdr = to;
hdr->size = to_size;
hdr->total_size = to_size;
}
int bloblist_init(void)
@ -457,7 +508,7 @@ int bloblist_init(void)
addr, ret);
} else {
/* Get the real size, if it is not what we expected */
size = gd->bloblist->size;
size = gd->bloblist->total_size;
}
}
if (ret) {
@ -472,7 +523,7 @@ int bloblist_init(void)
}
log_debug("Creating new bloblist size %lx at %lx\n", size,
addr);
ret = bloblist_new(addr, size, 0);
ret = bloblist_new(addr, size, 0, 0);
} else {
log_debug("Found existing bloblist size %lx at %lx\n", size,
addr);

View file

@ -14,6 +14,8 @@ structure defined by the code that owns it.
For the design goals of bloblist, please see the comments at the top of the
`bloblist.h` header file.
Bloblist is an implementation with the `Firmware Handoff`_ protocol.
Passing state through the boot process
--------------------------------------
@ -99,7 +101,7 @@ API documentation
-----------------
.. kernel-doc:: include/bloblist.h
.. _`Firmware Handoff`: https://github.com/FirmwareHandoff/firmware_handoff
Simon Glass
sjg@chromium.org

View file

@ -24,11 +24,11 @@
* which would add to code size. For Thumb-2 the code size needed in SPL is
* approximately 940 bytes (e.g. for chromebook_bob).
*
* 5. Bloblist uses 16-byte alignment internally and is designed to start on a
* 16-byte boundary. Its headers are multiples of 16 bytes. This makes it easier
* to deal with data structures which need this level of alignment, such as ACPI
* tables. For use in SPL and TPL the alignment can be relaxed, since it can be
* relocated to an aligned address in U-Boot proper.
* 5. Bloblist uses 8-byte alignment internally and is designed to start on a
* 8-byte boundary. Its headers are 8 bytes long. It is possible to achieve
* larger alignment (e.g. 16 bytes) by adding a dummy header, For use in SPL and
* TPL the alignment can be relaxed, since it can be relocated to an aligned
* address in U-Boot proper.
*
* 6. Bloblist is designed to be passed to Linux as reserved memory. While linux
* doesn't understand the bloblist header, it can be passed the indivdual blobs.
@ -66,6 +66,7 @@
*
* Copyright 2018 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
* Adjusted July 2023 to match Firmware handoff specification, Release 0.9
*/
#ifndef __BLOBLIST_H
@ -74,14 +75,19 @@
#include <mapmem.h>
enum {
BLOBLIST_VERSION = 0,
BLOBLIST_MAGIC = 0xb00757a3,
BLOBLIST_ALIGN = 16,
BLOBLIST_VERSION = 1,
BLOBLIST_MAGIC = 0x4a0fb10b,
BLOBLIST_BLOB_ALIGN_LOG2 = 3,
BLOBLIST_BLOB_ALIGN = 1 << BLOBLIST_BLOB_ALIGN_LOG2,
BLOBLIST_ALIGN_LOG2 = 3,
BLOBLIST_ALIGN = 1 << BLOBLIST_ALIGN_LOG2,
};
/* Supported tags - add new ones to tag_name in bloblist.c */
enum bloblist_tag_t {
BLOBLISTT_NONE = 0,
BLOBLISTT_VOID = 0,
/*
* Standard area to allocate blobs used across firmware components, for
@ -89,42 +95,36 @@ enum bloblist_tag_t {
* projects.
*/
BLOBLISTT_AREA_FIRMWARE_TOP = 0x1,
/*
* Devicetree for use by firmware. On some platforms this is passed to
* the OS also
*/
BLOBLISTT_CONTROL_FDT = 1,
BLOBLISTT_HOB_BLOCK = 2,
BLOBLISTT_HOB_LIST = 3,
BLOBLISTT_ACPI_TABLES = 4,
BLOBLISTT_TPM_EVLOG = 5,
BLOBLISTT_TPM_CRB_BASE = 6,
/* Standard area to allocate blobs used across firmware components */
BLOBLISTT_AREA_FIRMWARE = 0x100,
BLOBLISTT_AREA_FIRMWARE = 0x10,
BLOBLISTT_TPM2_TCG_LOG = 0x10, /* TPM v2 log space */
BLOBLISTT_TCPA_LOG = 0x11, /* TPM log space */
/*
* Advanced Configuration and Power Interface Global Non-Volatile
* Sleeping table. This forms part of the ACPI tables passed to Linux.
*/
BLOBLISTT_ACPI_GNVS = 0x100,
BLOBLISTT_INTEL_VBT = 0x101, /* Intel Video-BIOS table */
BLOBLISTT_TPM2_TCG_LOG = 0x102, /* TPM v2 log space */
BLOBLISTT_TCPA_LOG = 0x103, /* TPM log space */
BLOBLISTT_ACPI_TABLES = 0x104, /* ACPI tables for x86 */
BLOBLISTT_SMBIOS_TABLES = 0x105, /* SMBIOS tables for x86 */
BLOBLISTT_VBOOT_CTX = 0x106, /* Chromium OS verified boot context */
BLOBLISTT_ACPI_GNVS = 0x12,
/*
* Project-specific tags are permitted here. Projects can be open source
* or not, but the format of the data must be fuily documented in an
* open source project, including all fields, bits, etc. Naming should
* be: BLOBLISTT_<project>_<purpose_here>
*/
BLOBLISTT_PROJECT_AREA = 0x8000,
BLOBLISTT_U_BOOT_SPL_HANDOFF = 0x8000, /* Hand-off info from SPL */
BLOBLISTT_VBE = 0x8001, /* VBE per-phase state */
BLOBLISTT_U_BOOT_VIDEO = 0x8002, /* Video information from SPL */
/* Standard area to allocate blobs used for Trusted Firmware */
BLOBLISTT_AREA_TF = 0x100,
BLOBLISTT_OPTEE_PAGABLE_PART = 0x100,
/*
* Vendor-specific tags are permitted here. Projects can be open source
* or not, but the format of the data must be fuily documented in an
* open source project, including all fields, bits, etc. Naming should
* be BLOBLISTT_<vendor>_<purpose_here>
*/
BLOBLISTT_VENDOR_AREA = 0xc000,
/* Tags after this are not allocated for now */
BLOBLISTT_EXPANSION = 0x10000,
/* Other standard area to allocate blobs */
BLOBLISTT_AREA_OTHER = 0x200,
BLOBLISTT_INTEL_VBT = 0x200, /* Intel Video-BIOS table */
BLOBLISTT_SMBIOS_TABLES = 0x201, /* SMBIOS tables for x86 */
BLOBLISTT_VBOOT_CTX = 0x202, /* Chromium OS verified boot context */
/*
* Tags from here are on reserved for private use within a single
@ -133,9 +133,20 @@ enum bloblist_tag_t {
* implementation, but cannot be used in upstream code. Allocate a
* tag in one of the areas above if you want that.
*
* This area may move in future.
* Project-specific tags are permitted here. Projects can be open source
* or not, but the format of the data must be fuily documented in an
* open source project, including all fields, bits, etc. Naming should
* be: BLOBLISTT_<project>_<purpose_here>
*
* Vendor-specific tags are also permitted. Projects can be open source
* or not, but the format of the data must be fuily documented in an
* open source project, including all fields, bits, etc. Naming should
* be BLOBLISTT_<vendor>_<purpose_here>
*/
BLOBLISTT_PRIVATE_AREA = 0xffff0000,
BLOBLISTT_PRIVATE_AREA = 0xfff000,
BLOBLISTT_U_BOOT_SPL_HANDOFF = 0xfff000, /* Hand-off info from SPL */
BLOBLISTT_VBE = 0xfff001, /* VBE per-phase state */
BLOBLISTT_U_BOOT_VIDEO = 0xfff002, /* Video info from SPL */
};
/**
@ -156,33 +167,33 @@ enum bloblist_tag_t {
* from the last.
*
* @magic: BLOBLIST_MAGIC
* @chksum: checksum for the entire bloblist allocated area. Since any of the
* blobs can be altered after being created, this checksum is only valid
* when the bloblist is finalized before jumping to the next stage of boot.
* This is the value needed to make all checksummed bytes sum to 0
* @version: BLOBLIST_VERSION
* @hdr_size: Size of this header, normally sizeof(struct bloblist_hdr). The
* first bloblist_rec starts at this offset from the start of the header
* @flags: Space for BLOBLISTF... flags (none yet)
* @size: Total size of the bloblist (non-zero if valid) including this header.
* The bloblist extends for this many bytes from the start of this header.
* When adding new records, the bloblist can grow up to this size.
* @alloced: Total size allocated so far for this bloblist. This starts out as
* @align_log2: Power of two of the maximum alignment required by this list
* @used_size: Size allocated so far for this bloblist. This starts out as
* sizeof(bloblist_hdr) since we need at least that much space to store a
* valid bloblist
* @total_size: The number of total bytes that the bloblist can occupy.
* Any blob producer must check if there is sufficient space before adding
* a record to the bloblist.
* @flags: Space for BLOBLISTF... flags (none yet)
* @spare: Spare space (for future use)
* @chksum: CRC32 for the entire bloblist allocated area. Since any of the
* blobs can be altered after being created, this checksum is only valid
* when the bloblist is finalised before jumping to the next stage of boot.
* Note that chksum is last to make it easier to exclude it from the
* checksum calculation.
*/
struct bloblist_hdr {
u32 magic;
u32 version;
u32 hdr_size;
u8 chksum;
u8 version;
u8 hdr_size;
u8 align_log2;
u32 used_size;
u32 total_size;
u32 flags;
u32 size;
u32 alloced;
u32 spare;
u32 chksum;
};
/**
@ -193,18 +204,25 @@ struct bloblist_hdr {
*
* NOTE: Only exported for testing purposes. Do not use this struct.
*
* @tag: Tag indicating what the record contains
* @hdr_size: Size of this header, normally sizeof(struct bloblist_rec). The
* record's data starts at this offset from the start of the record
* @tag_and_hdr_size: Tag indicating what the record contains (bottom 24 bits), and
* size of this header (top 8 bits), normally sizeof(struct bloblist_rec).
* The record's data starts at this offset from the start of the record
* @size: Size of record in bytes, excluding the header size. This does not
* need to be aligned (e.g. 3 is OK).
* @spare: Spare space for other things
*/
struct bloblist_rec {
u32 tag;
u32 hdr_size;
u32 tag_and_hdr_size;
u32 size;
u32 spare;
};
enum {
BLOBLISTR_TAG_SHIFT = 0,
BLOBLISTR_TAG_MASK = 0xffffffU << BLOBLISTR_TAG_SHIFT,
BLOBLISTR_HDR_SIZE_SHIFT = 24,
BLOBLISTR_HDR_SIZE_MASK = 0xffU << BLOBLISTR_HDR_SIZE_SHIFT,
BLOBLIST_HDR_SIZE = sizeof(struct bloblist_hdr),
BLOBLIST_REC_HDR_SIZE = sizeof(struct bloblist_rec),
};
/**
@ -249,11 +267,11 @@ void *bloblist_find(uint tag, int size);
*
* @tag: Tag to add (enum bloblist_tag_t)
* @size: Size of the blob
* @align: Alignment of the blob (in bytes), 0 for default
* @align_log2: Alignment of the blob (in bytes log2), 0 for default
* Return: pointer to the newly added block, or NULL if there is not enough
* space for the blob
*/
void *bloblist_add(uint tag, int size, int align);
void *bloblist_add(uint tag, int size, int align_log2);
/**
* bloblist_ensure_size() - Find or add a blob
@ -263,11 +281,11 @@ void *bloblist_add(uint tag, int size, int align);
* @tag: Tag to add (enum bloblist_tag_t)
* @size: Size of the blob
* @blobp: Returns a pointer to blob on success
* @align: Alignment of the blob (in bytes), 0 for default
* @align_log2: Alignment of the blob (in bytes log2), 0 for default
* Return: 0 if OK, -ENOSPC if it is missing and could not be added due to lack
* of space, or -ESPIPE it exists but has the wrong size
*/
int bloblist_ensure_size(uint tag, int size, int align, void **blobp);
int bloblist_ensure_size(uint tag, int size, int align_log2, void **blobp);
/**
* bloblist_ensure() - Find or add a blob
@ -313,10 +331,11 @@ int bloblist_resize(uint tag, int new_size);
* @addr: Address of bloblist
* @size: Initial size for bloblist
* @flags: Flags to use for bloblist
* @align_log2: Log base 2 of maximum alignment provided by this bloblist
* Return: 0 if OK, -EFAULT if addr is not aligned correctly, -ENOSPC is the
* area is not large enough
*/
int bloblist_new(ulong addr, uint size, uint flags);
int bloblist_new(ulong addr, uint size, uint flags, uint align_log2);
/**
* bloblist_check() - Check if a bloblist exists
@ -347,10 +366,10 @@ int bloblist_finish(void);
* This returns useful information about the bloblist
*
* @basep: Returns base address of bloblist
* @sizep: Returns the number of bytes used in the bloblist
* @allocedp: Returns the total space allocated to the bloblist
* @tsizep: Returns the total number of bytes of the bloblist
* @usizep: Returns the number of used bytes of the bloblist
*/
void bloblist_get_stats(ulong *basep, ulong *sizep, ulong *allocedp);
void bloblist_get_stats(ulong *basep, ulong *tsizep, ulong *usizep);
/**
* bloblist_get_base() - Get the base address of the bloblist
@ -366,6 +385,13 @@ ulong bloblist_get_base(void);
*/
ulong bloblist_get_size(void);
/**
* bloblist_get_total_size() - Get the total size of the bloblist
*
* Return: the size in bytes
*/
ulong bloblist_get_total_size(void);
/**
* bloblist_show_stats() - Show information about the bloblist
*

View file

@ -635,8 +635,19 @@ else
fdtgrep_props := -b bootph-all -b bootph-pre-ram $(migrate_spl)
endif
endif
# This rule produces the .dtb for an SPL build.
#
# The first fdtgrep keeps nodes with the above properties (with -u ensuring that
# the properties are implied in all parents of a matching node). The root node
# is always included, along with /chosen and /config nodes. Referenced aliases
# (i.e. properties in /aliases which point to an incldued node) are also
# included.
#
# The second fdtgrep removes all bootph properties along with unused strings
# and any properties in CONFIG_OF_SPL_REMOVE_PROPS
quiet_cmd_fdtgrep = FDTGREP $@
cmd_fdtgrep = $(objtree)/tools/fdtgrep $(fdtgrep_props) -RT $< \
cmd_fdtgrep = $(objtree)/tools/fdtgrep $(fdtgrep_props) -u -RT $< \
-n /chosen -n /config -O dtb | \
$(objtree)/tools/fdtgrep -r -O dtb - -o $@ \
-P bootph-all -P bootph-pre-ram -P bootph-pre-sram \

View file

@ -314,7 +314,7 @@ endif
# - we have either OF_SEPARATE or OF_HOSTFILE
build_dtb :=
ifneq ($(CONFIG_$(SPL_TPL_)OF_REAL),)
ifeq ($(CONFIG_OF_SEPARATE)$(CONFIG_SANDBOX),y)
ifneq ($(CONFIG_OF_SEPARATE)$(CONFIG_SANDBOX),)
build_dtb := y
endif
endif

View file

@ -72,15 +72,15 @@ static int bloblist_test_init(struct unit_test_state *uts)
hdr = clear_bloblist();
ut_asserteq(-ENOENT, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
ut_asserteq_ptr(NULL, bloblist_check_magic(TEST_ADDR));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
ut_asserteq_ptr(hdr, bloblist_check_magic(TEST_ADDR));
hdr->version++;
ut_asserteq(-EPROTONOSUPPORT, bloblist_check(TEST_ADDR,
TEST_BLOBLIST_SIZE));
ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0x10, 0));
ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_asserteq(-ENOSPC, bloblist_new(TEST_ADDR, 0xc, 0, 0));
ut_asserteq(-EFAULT, bloblist_new(1, TEST_BLOBLIST_SIZE, 0, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
ut_assertok(bloblist_finish());
@ -106,8 +106,9 @@ static int bloblist_test_blob(struct unit_test_state *uts)
/* At the start there should be no records */
hdr = clear_bloblist();
ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_asserteq(TEST_BLOBLIST_SIZE, bloblist_get_size());
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
ut_asserteq(sizeof(struct bloblist_hdr), bloblist_get_size());
ut_asserteq(TEST_BLOBLIST_SIZE, bloblist_get_total_size());
ut_asserteq(TEST_ADDR, bloblist_get_base());
ut_asserteq(map_to_sysmem(hdr), TEST_ADDR);
@ -144,7 +145,7 @@ static int bloblist_test_blob_ensure(struct unit_test_state *uts)
/* At the start there should be no records */
clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
/* Test with an empty bloblist */
size = TEST_SIZE;
@ -176,7 +177,7 @@ static int bloblist_test_bad_blob(struct unit_test_state *uts)
void *data;
hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
data = hdr + 1;
data += sizeof(struct bloblist_rec);
ut_asserteq_addr(data, bloblist_ensure(TEST_TAG, TEST_SIZE));
@ -192,7 +193,7 @@ static int bloblist_test_checksum(struct unit_test_state *uts)
char *data, *data2;
hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
ut_assertok(bloblist_finish());
ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
@ -205,9 +206,9 @@ static int bloblist_test_checksum(struct unit_test_state *uts)
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
hdr->flags++;
hdr->size--;
hdr->total_size--;
ut_asserteq(-EFBIG, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
hdr->size++;
hdr->total_size++;
hdr->spare++;
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
@ -217,6 +218,10 @@ static int bloblist_test_checksum(struct unit_test_state *uts)
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
hdr->chksum--;
hdr->align_log2++;
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
hdr->align_log2--;
/* Make sure the checksum changes when we add blobs */
data = bloblist_add(TEST_TAG, TEST_SIZE, 0);
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
@ -237,12 +242,18 @@ static int bloblist_test_checksum(struct unit_test_state *uts)
*data2 -= 1;
/*
* Changing data outside the range of valid data should not affect
* the checksum.
* Changing data outside the range of valid data should affect the
* checksum.
*/
ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
data[TEST_SIZE]++;
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
data[TEST_SIZE]--;
ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
data2[TEST_SIZE2]++;
ut_asserteq(-EIO, bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
data[TEST_SIZE]--;
ut_assertok(bloblist_check(TEST_ADDR, TEST_BLOBLIST_SIZE));
return 0;
@ -256,7 +267,7 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts)
char *data, *data2;
hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
data = bloblist_ensure(TEST_TAG, TEST_SIZE);
data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
@ -264,10 +275,10 @@ static int bloblist_test_cmd_info(struct unit_test_state *uts)
ut_silence_console(uts);
console_record_reset();
run_command("bloblist info", 0);
ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr));
ut_assert_nextline("size: 400 1 KiB");
ut_assert_nextline("alloced: 70 112 Bytes");
ut_assert_nextline("free: 390 912 Bytes");
ut_assert_nextline("base: %lx", (ulong)map_to_sysmem(hdr));
ut_assert_nextline("total size: 400 1 KiB");
ut_assert_nextline("used size: 50 80 Bytes");
ut_assert_nextline("free: 3b0 944 Bytes");
ut_assert_console_end();
ut_unsilence_console(uts);
@ -282,7 +293,7 @@ static int bloblist_test_cmd_list(struct unit_test_state *uts)
char *data, *data2;
hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
data = bloblist_ensure(TEST_TAG, TEST_SIZE);
data2 = bloblist_ensure(TEST_TAG2, TEST_SIZE2);
@ -291,9 +302,9 @@ static int bloblist_test_cmd_list(struct unit_test_state *uts)
console_record_reset();
run_command("bloblist list", 0);
ut_assert_nextline("Address Size Tag Name");
ut_assert_nextline("%08lx %8x 8000 SPL hand-off",
ut_assert_nextline("%08lx %8x fff000 SPL hand-off",
(ulong)map_to_sysmem(data), TEST_SIZE);
ut_assert_nextline("%08lx %8x 106 Chrome OS vboot context",
ut_assert_nextline("%08lx %8x 202 Chrome OS vboot context",
(ulong)map_to_sysmem(data2), TEST_SIZE2);
ut_assert_console_end();
ut_unsilence_console(uts);
@ -312,7 +323,7 @@ static int bloblist_test_align(struct unit_test_state *uts)
/* At the start there should be no records */
hdr = clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE));
/* Check the default alignment */
@ -325,18 +336,18 @@ static int bloblist_test_align(struct unit_test_state *uts)
data = bloblist_add(i, size, 0);
ut_assertnonnull(data);
addr = map_to_sysmem(data);
ut_asserteq(0, addr & (BLOBLIST_ALIGN - 1));
ut_asserteq(0, addr & (BLOBLIST_BLOB_ALIGN - 1));
/* Only the bytes in the blob data should be zeroed */
for (j = 0; j < size; j++)
ut_asserteq(0, data[j]);
for (; j < BLOBLIST_ALIGN; j++)
for (; j < BLOBLIST_BLOB_ALIGN; j++)
ut_asserteq(ERASE_BYTE, data[j]);
}
/* Check larger alignment */
for (i = 0; i < 3; i++) {
int align = 32 << i;
int align = 5 - i;
data = bloblist_add(3 + i, i * 4, align);
ut_assertnonnull(data);
@ -345,16 +356,16 @@ static int bloblist_test_align(struct unit_test_state *uts)
}
/* Check alignment with an bloblist starting on a smaller alignment */
hdr = map_sysmem(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE);
hdr = map_sysmem(TEST_ADDR + BLOBLIST_BLOB_ALIGN, TEST_BLOBLIST_SIZE);
memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE);
memset(hdr, '\0', sizeof(*hdr));
ut_assertok(bloblist_new(TEST_ADDR + BLOBLIST_ALIGN, TEST_BLOBLIST_SIZE,
0));
0, 0));
data = bloblist_add(1, 5, BLOBLIST_ALIGN * 2);
data = bloblist_add(1, 5, BLOBLIST_ALIGN_LOG2 + 1);
ut_assertnonnull(data);
addr = map_to_sysmem(data);
ut_asserteq(0, addr & (BLOBLIST_ALIGN * 2 - 1));
ut_asserteq(0, addr & (BLOBLIST_BLOB_ALIGN * 2 - 1));
return 0;
}
@ -370,7 +381,7 @@ static int bloblist_test_reloc(struct unit_test_state *uts)
ulong new_addr;
ulong new_size;
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
old_ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
/* Add one blob and then one that won't fit */
@ -409,7 +420,7 @@ static int bloblist_test_grow(struct unit_test_state *uts)
memset(hdr, ERASE_BYTE, TEST_BLOBLIST_SIZE);
/* Create two blobs */
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
blob1 = bloblist_add(TEST_TAG, small_size, 0);
ut_assertnonnull(blob1);
ut_assertok(check_zero(blob1, small_size));
@ -421,7 +432,7 @@ static int bloblist_test_grow(struct unit_test_state *uts)
ut_asserteq(sizeof(struct bloblist_hdr) +
sizeof(struct bloblist_rec) * 2 + small_size * 2,
hdr->alloced);
hdr->used_size);
/* Resize the first one */
ut_assertok(bloblist_resize(TEST_TAG, small_size + 4));
@ -442,8 +453,8 @@ static int bloblist_test_grow(struct unit_test_state *uts)
hdr = ptr;
ut_asserteq(sizeof(struct bloblist_hdr) +
sizeof(struct bloblist_rec) * 2 + small_size * 2 +
BLOBLIST_ALIGN,
hdr->alloced);
BLOBLIST_BLOB_ALIGN,
hdr->used_size);
return 0;
}
@ -461,7 +472,7 @@ static int bloblist_test_shrink(struct unit_test_state *uts)
ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
/* Create two blobs */
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
blob1 = bloblist_add(TEST_TAG, small_size, 0);
ut_assertnonnull(blob1);
strcpy(blob1, test1_str);
@ -473,7 +484,7 @@ static int bloblist_test_shrink(struct unit_test_state *uts)
hdr = ptr;
ut_asserteq(sizeof(struct bloblist_hdr) +
sizeof(struct bloblist_rec) * 2 + small_size * 2,
hdr->alloced);
hdr->used_size);
/* Resize the first one */
new_size = small_size - BLOBLIST_ALIGN - 4;
@ -493,7 +504,7 @@ static int bloblist_test_shrink(struct unit_test_state *uts)
ut_asserteq(sizeof(struct bloblist_hdr) +
sizeof(struct bloblist_rec) * 2 + small_size * 2 -
BLOBLIST_ALIGN,
hdr->alloced);
hdr->used_size);
return 0;
}
@ -511,7 +522,7 @@ static int bloblist_test_resize_fail(struct unit_test_state *uts)
ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
/* Create two blobs */
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
blob1 = bloblist_add(TEST_TAG, small_size, 0);
ut_assertnonnull(blob1);
@ -521,12 +532,12 @@ static int bloblist_test_resize_fail(struct unit_test_state *uts)
hdr = ptr;
ut_asserteq(sizeof(struct bloblist_hdr) +
sizeof(struct bloblist_rec) * 2 + small_size * 2,
hdr->alloced);
hdr->used_size);
/* Resize the first one, to check the boundary conditions */
ut_asserteq(-EINVAL, bloblist_resize(TEST_TAG, -1));
new_size = small_size + (hdr->size - hdr->alloced);
new_size = small_size + (hdr->total_size - hdr->used_size);
ut_asserteq(-ENOSPC, bloblist_resize(TEST_TAG, new_size + 1));
ut_assertok(bloblist_resize(TEST_TAG, new_size));
@ -548,7 +559,7 @@ static int bloblist_test_resize_last(struct unit_test_state *uts)
hdr = ptr;
/* Create two blobs */
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
blob1 = bloblist_add(TEST_TAG, small_size, 0);
ut_assertnonnull(blob1);
@ -558,9 +569,9 @@ static int bloblist_test_resize_last(struct unit_test_state *uts)
/* Check the byte after the last blob */
alloced_val = sizeof(struct bloblist_hdr) +
sizeof(struct bloblist_rec) * 2 + small_size * 2;
ut_asserteq(alloced_val, hdr->alloced);
ut_asserteq(alloced_val, hdr->used_size);
ut_asserteq_ptr((void *)hdr + alloced_val, blob2 + small_size);
ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->alloced));
ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->used_size));
/* Resize the second one, checking nothing changes */
ut_asserteq(0, bloblist_resize(TEST_TAG2, small_size + 4));
@ -577,9 +588,9 @@ static int bloblist_test_resize_last(struct unit_test_state *uts)
ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + alloced_val + 4));
/* Check that the new top of the allocated blobs has not been touched */
alloced_val += BLOBLIST_ALIGN;
ut_asserteq(alloced_val, hdr->alloced);
ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->alloced));
alloced_val += BLOBLIST_BLOB_ALIGN;
ut_asserteq(alloced_val, hdr->used_size);
ut_asserteq((u8)ERASE_BYTE, *((u8 *)hdr + hdr->used_size));
return 0;
}
@ -593,7 +604,7 @@ static int bloblist_test_blob_maxsize(struct unit_test_state *uts)
/* At the start there should be no records */
clear_bloblist();
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0));
/* Add a blob that takes up all space */
size = TEST_BLOBLIST_SIZE - sizeof(struct bloblist_hdr) -

View file

@ -2842,12 +2842,14 @@ class TestFunctional(unittest.TestCase):
fdt_size = entries['section'].GetEntries()['u-boot-dtb'].size
fdtmap_offset = entries['fdtmap'].offset
tmpdir = None
try:
tmpdir, updated_fname = self._SetupImageInTmpdir()
with test_util.capture_sys_output() as (stdout, stderr):
self._DoBinman('ls', '-i', updated_fname)
finally:
shutil.rmtree(tmpdir)
if tmpdir:
shutil.rmtree(tmpdir)
lines = stdout.getvalue().splitlines()
expected = [
'Name Image-pos Size Entry-type Offset Uncomp-size',
@ -2868,12 +2870,14 @@ class TestFunctional(unittest.TestCase):
def testListCmdFail(self):
"""Test failing to list an image"""
self._DoReadFile('005_simple.dts')
tmpdir = None
try:
tmpdir, updated_fname = self._SetupImageInTmpdir()
with self.assertRaises(ValueError) as e:
self._DoBinman('ls', '-i', updated_fname)
finally:
shutil.rmtree(tmpdir)
if tmpdir:
shutil.rmtree(tmpdir)
self.assertIn("Cannot find FDT map in image", str(e.exception))
def _RunListCmd(self, paths, expected):
@ -3002,13 +3006,15 @@ class TestFunctional(unittest.TestCase):
self._CheckLz4()
self._DoReadFileRealDtb('130_list_fdtmap.dts')
fname = os.path.join(self._indir, 'output.extact')
tmpdir = None
try:
tmpdir, updated_fname = self._SetupImageInTmpdir()
with test_util.capture_sys_output() as (stdout, stderr):
self._DoBinman('extract', '-i', updated_fname, 'u-boot',
'-f', fname)
finally:
shutil.rmtree(tmpdir)
if tmpdir:
shutil.rmtree(tmpdir)
data = tools.read_file(fname)
self.assertEqual(U_BOOT_DATA, data)
@ -5185,12 +5191,14 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
data = self._DoReadFileRealDtb('207_fip_ls.dts')
hdr, fents = fip_util.decode_fip(data)
tmpdir = None
try:
tmpdir, updated_fname = self._SetupImageInTmpdir()
with test_util.capture_sys_output() as (stdout, stderr):
self._DoBinman('ls', '-i', updated_fname)
finally:
shutil.rmtree(tmpdir)
if tmpdir:
shutil.rmtree(tmpdir)
lines = stdout.getvalue().splitlines()
expected = [
'Name Image-pos Size Entry-type Offset Uncomp-size',
@ -5395,12 +5403,14 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
use_real_dtb=True,
extra_indirs=[os.path.join(self._indir, TEST_FDT_SUBDIR)])
tmpdir = None
try:
tmpdir, updated_fname = self._SetupImageInTmpdir()
with test_util.capture_sys_output() as (stdout, stderr):
self._RunBinman('ls', '-i', updated_fname)
finally:
shutil.rmtree(tmpdir)
if tmpdir:
shutil.rmtree(tmpdir)
def testFitSubentryUsesBintool(self):
"""Test that binman FIT subentries can use bintools"""

View file

@ -119,7 +119,7 @@ class Expr:
"""Set up a new Expr object.
Args:
expr (str): String cotaining regular expression to store
expr (str): String containing regular expression to store
"""
self._expr = expr
self._re = re.compile(expr)

View file

@ -63,6 +63,7 @@ struct display_info {
int types_inc; /* Mask of types that we include (FDT_IS...) */
int types_exc; /* Mask of types that we exclude (FDT_IS...) */
int invert; /* Invert polarity of match */
int props_up; /* Imply properties up to supernodes */
struct value_node *value_head; /* List of values to match */
const char *output_fname; /* Output filename */
FILE *fout; /* File to write dts/dtb output */
@ -375,8 +376,9 @@ static int display_fdt_by_regions(struct display_info *disp, const void *blob,
const char *str;
int str_base = fdt_off_dt_strings(blob);
for (offset = 0; offset < fdt_size_dt_strings(blob);
offset += strlen(str) + 1) {
for (offset = 0;
offset < (int)fdt_size_dt_strings(blob);
offset += strlen(str) + 1) {
str = fdt_string(blob, offset);
int len = strlen(str) + 1;
int show;
@ -431,7 +433,7 @@ static int dump_fdt_regions(struct display_info *disp, const void *blob,
{
struct fdt_header *fdt;
int size, struct_start;
int ptr;
unsigned int ptr;
int i;
/* Set up a basic header (even if we don't actually write it) */
@ -575,15 +577,65 @@ static int check_type_include(void *priv, int type, const char *data, int size)
}
/**
* h_include() - Include handler function for fdt_find_regions()
* check_props() - Check if a node has properties that we want to include
*
* Calls check_type_include() for each property in the nodn, returning 1 if
* that function returns 1 for any of them
*
* @disp: Display structure, holding info about our options
* @fdt: Devicetree blob to check
* @node: Node offset to check
* @inc: Current value of the 'include' variable (see h_include())
* Return: 0 to exclude, 1 to include, -1 if no information is available
*/
static int check_props(struct display_info *disp, const void *fdt, int node,
int inc)
{
int offset;
for (offset = fdt_first_property_offset(fdt, node);
offset > 0 && inc != 1;
offset = fdt_next_property_offset(fdt, offset)) {
const struct fdt_property *prop;
const char *str;
prop = fdt_get_property_by_offset(fdt, offset, NULL);
if (!prop)
continue;
str = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
inc = check_type_include(disp, FDT_NODE_HAS_PROP, str,
strlen(str));
}
/* if requested, check all subnodes for this property too */
if (inc != 1 && disp->props_up) {
int subnode;
for (subnode = fdt_first_subnode(fdt, node);
subnode > 0 && inc != 1;
subnode = fdt_next_subnode(fdt, subnode))
inc = check_props(disp, fdt, subnode, inc);
}
return inc;
}
/**
* h_include() - Include handler function for fdt_first_region()
*
* This function decides whether to include or exclude a node, property or
* compatible string. The function is defined by fdt_find_regions().
* compatible string. The function is defined by fdt_first_region().
*
* The algorithm is documented in the code - disp->invert is 0 for normal
* operation, and 1 to invert the sense of all matches.
*
* See
* @priv: Private pointer as passed to fdtgrep_find_regions()
* @fdt: Pointer to FDT blob
* @offset: Offset of this node / property
* @type: Type of this part, FDT_IS_...
* @data: Pointer to data (node name, property name, compatible string)
* @size: Size of data, or 0 if none
* Return: 0 to exclude, 1 to include, -1 if no information is available
*/
static int h_include(void *priv, const void *fdt, int offset, int type,
const char *data, int size)
@ -610,31 +662,13 @@ static int h_include(void *priv, const void *fdt, int offset, int type,
(disp->types_inc & FDT_NODE_HAS_PROP)) {
debug(" - checking node '%s'\n",
fdt_get_name(fdt, offset, NULL));
for (offset = fdt_first_property_offset(fdt, offset);
offset > 0 && inc != 1;
offset = fdt_next_property_offset(fdt, offset)) {
const struct fdt_property *prop;
const char *str;
prop = fdt_get_property_by_offset(fdt, offset, NULL);
if (!prop)
continue;
str = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
inc = check_type_include(priv, FDT_NODE_HAS_PROP, str,
strlen(str));
}
inc = check_props(disp, fdt, offset, inc);
if (inc == -1)
inc = 0;
}
switch (inc) {
case 1:
inc = !disp->invert;
break;
case 0:
inc = disp->invert;
break;
}
if (inc != -1 && disp->invert)
inc = !inc;
debug(" - returning %d\n", inc);
return inc;
@ -683,10 +717,10 @@ static int fdtgrep_find_regions(const void *fdt,
return new_count;
} else if (new_count <= max_regions) {
/*
* The alias regions will now be at the end of the list.
* Sort the regions by offset to get things into the
* right order
*/
* The alias regions will now be at the end of the list.
* Sort the regions by offset to get things into the
* right order
*/
count = new_count;
qsort(region, count, sizeof(struct fdt_region),
h_cmp_region);
@ -821,7 +855,7 @@ static int do_fdtgrep(struct display_info *disp, const char *filename)
region, max_regions, path, sizeof(path),
disp->flags);
if (count < 0) {
report_error("fdt_find_regions", count);
report_error("fdtgrep_find_regions", count);
free(region);
return -1;
}
@ -880,7 +914,7 @@ static int do_fdtgrep(struct display_info *disp, const char *filename)
size = fdt_totalsize(fdt);
}
if (size != fwrite(fdt, 1, size, disp->fout)) {
if ((size_t)size != fwrite(fdt, 1, size, disp->fout)) {
fprintf(stderr, "Write failure, %d bytes\n", size);
free(fdt);
ret = 1;
@ -932,9 +966,9 @@ static const char usage_synopsis[] =
case '?': usage("unknown option");
static const char usage_short_opts[] =
"haAc:b:C:defg:G:HIlLmn:N:o:O:p:P:rRsStTv"
"haAc:b:C:defg:G:HIlLmn:N:o:O:p:P:rRsStTuv"
USAGE_COMMON_SHORT_OPTS;
static struct option const usage_long_opts[] = {
static const struct option usage_long_opts[] = {
{"show-address", no_argument, NULL, 'a'},
{"colour", no_argument, NULL, 'A'},
{"include-node-with-prop", a_argument, NULL, 'b'},
@ -952,6 +986,8 @@ static struct option const usage_long_opts[] = {
{"include-mem", no_argument, NULL, 'm'},
{"include-node", a_argument, NULL, 'n'},
{"exclude-node", a_argument, NULL, 'N'},
{"out", a_argument, NULL, 'o'},
{"out-format", a_argument, NULL, 'O'},
{"include-prop", a_argument, NULL, 'p'},
{"exclude-prop", a_argument, NULL, 'P'},
{"remove-strings", no_argument, NULL, 'r'},
@ -960,8 +996,7 @@ static struct option const usage_long_opts[] = {
{"skip-supernodes", no_argument, NULL, 'S'},
{"show-stringtab", no_argument, NULL, 't'},
{"show-aliases", no_argument, NULL, 'T'},
{"out", a_argument, NULL, 'o'},
{"out-format", a_argument, NULL, 'O'},
{"props-up-to-supernode", no_argument, NULL, 'u'},
{"invert-match", no_argument, NULL, 'v'},
USAGE_COMMON_LONG_OPTS,
};
@ -983,6 +1018,8 @@ static const char * const usage_opts_help[] = {
"Include mem_rsvmap section in binary output",
"Node to include in grep",
"Node to exclude in grep",
"-o <output file>",
"-O <output format>",
"Property to include in grep",
"Property to exclude in grep",
"Remove unused strings from string table",
@ -991,8 +1028,7 @@ static const char * const usage_opts_help[] = {
"Don't include supernodes of matching nodes",
"Include string table in binary output",
"Include matching aliases in output",
"-o <output file>",
"-O <output format>",
"Add -p properties to supernodes too",
"Invert the sense of matching (select non-matching lines)",
USAGE_COMMON_OPTS_HELP
};
@ -1124,6 +1160,9 @@ static void scan_args(struct display_info *disp, int argc, char *argv[])
case 'H':
disp->header = 1;
break;
case 'I':
disp->show_dts_version = 1;
break;
case 'l':
disp->region_list = 1;
break;
@ -1176,12 +1215,12 @@ static void scan_args(struct display_info *disp, int argc, char *argv[])
case 'T':
disp->add_aliases = 1;
break;
case 'u':
disp->props_up = 1;
break;
case 'v':
disp->invert = 1;
break;
case 'I':
disp->show_dts_version = 1;
break;
}
if (type && value_add(disp, &disp->value_head, type, inc,