mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-03-17 07:16:59 +00:00
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:
commit
dffa6d0210
11 changed files with 401 additions and 248 deletions
|
@ -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;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
105
test/bloblist.c
105
test/bloblist.c
|
@ -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) -
|
||||
|
|
|
@ -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"""
|
||||
|
|
|
@ -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)
|
||||
|
|
123
tools/fdtgrep.c
123
tools/fdtgrep.c
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue