mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-10-30 19:48:19 +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
					
				| @ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user