[PATCH 5/5] spl: fit: Add test to check loadables

Nikita Shubin <[email protected]>
Newsgroups gmane.comp.boot-loaders.u-boot
Message-ID <20260807-riscv-full-fit-support-v1-5-21a34f79c350__41663.1679445104$1786090461$gmane$org@maquefel.me>
Add spl_test_firmware_image() to check lodables correctly provided by
spl_load_fit_image().

We create special image with U-Boot, firmware and empty dtb. Then invoke
spl_load_fit_image(), check everything (including dtb) loaded correctly
and then check if loaded dtb contains "/fit-images/u-boot".

Signed-off-by: Nikita Shubin <[email protected]>
---
 test/image/spl_load.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 195 insertions(+)

diff --git a/test/image/spl_load.c b/test/image/spl_load.c
index c43c977f784..314795e2506 100644
--- a/test/image/spl_load.c
+++ b/test/image/spl_load.c
@@ -275,6 +275,201 @@ size_t create_image(void *dst, enum spl_test_image type,
 	return 0;
 }
 
+static size_t create_firmware_fit(void *dst, struct spl_image_info *uboot_image,
+							struct spl_image_info *opensbi_image, ulong fdt_load_addr,
+							size_t *data_offset)
+{
+	size_t prop_size = 1168;
+	size_t total_size = prop_size + uboot_image->size + opensbi_image->size;
+	size_t size = prop_size;
+	size_t fdt_size;
+	char tmp[256];
+	void *fdt;
+
+	if (data_offset)
+		*data_offset = size;
+
+	if (!dst)
+		goto out;
+
+	if (fdt_create(dst, size))
+		return 0;
+	if (fdt_finish_reservemap(dst))
+		return 0;
+	if (fdt_begin_node(dst, ""))
+		return 0;
+	if (fdt_property_u32(dst, FIT_TIMESTAMP_PROP, 0))
+		return 0;
+	if (fdt_property_u32(dst, "#address-cells", 2))
+		return 0;
+	if (fdt_property_string(dst, FIT_DESC_PROP, ""))
+		return 0;
+	if (fdt_begin_node(dst, "images"))
+		return 0;
+
+	/* u-boot image node */
+	if (fdt_begin_node(dst, "u-boot"))
+		return 0;
+	if (fdt_property_u32(dst, FIT_DATA_OFFSET_PROP, 0))
+		return 0;
+	if (fdt_property_string(dst, FIT_DESC_PROP, uboot_image->name))
+		return 0;
+	if (fdt_property_string(dst, FIT_TYPE_PROP, "standalone"))
+		return 0;
+	if (fdt_property_string(dst, FIT_COMP_PROP, "none"))
+		return 0;
+	if (fdt_property_u32(dst, FIT_DATA_SIZE_PROP, uboot_image->size))
+		return 0;
+	if (fdt_property_string(dst, FIT_OS_PROP,
+				genimg_get_os_short_name(uboot_image->os)))
+		return 0;
+	if (fdt_property_string(dst, FIT_ARCH_PROP,
+				genimg_get_arch_short_name(IH_ARCH_DEFAULT)))
+		return 0;
+	if (fdt_property_u64(dst, FIT_ENTRY_PROP, uboot_image->entry_point))
+		return 0;
+	if (fdt_property_u64(dst, FIT_LOAD_PROP, uboot_image->load_addr))
+		return 0;
+	if (fdt_end_node(dst))
+		return 0;
+
+	/* opensbi image node */
+	if (fdt_begin_node(dst, "opensbi"))
+		return 0;
+	if (fdt_property_u32(dst, FIT_DATA_OFFSET_PROP, uboot_image->size))
+		return 0;
+	if (fdt_property_string(dst, FIT_DESC_PROP, opensbi_image->name))
+		return 0;
+	if (fdt_property_string(dst, FIT_TYPE_PROP, "firmware"))
+		return 0;
+	if (fdt_property_string(dst, FIT_COMP_PROP, "none"))
+		return 0;
+	if (fdt_property_u32(dst, FIT_DATA_SIZE_PROP, opensbi_image->size))
+		return 0;
+	if (fdt_property_string(dst, FIT_OS_PROP,
+				genimg_get_os_short_name(opensbi_image->os)))
+		return 0;
+	if (fdt_property_string(dst, FIT_ARCH_PROP,
+				genimg_get_arch_short_name(IH_ARCH_DEFAULT)))
+		return 0;
+	if (fdt_property_u64(dst, FIT_ENTRY_PROP, opensbi_image->entry_point))
+		return 0;
+	if (fdt_property_u64(dst, FIT_LOAD_PROP, opensbi_image->load_addr))
+		return 0;
+	if (fdt_end_node(dst)) /* opensbi */
+		return 0;
+
+	/* generate empty dtb */
+
+	if (fdt_create_empty_tree(&tmp, sizeof(tmp)))
+		return 0;
+	fdt_size = fdt_totalsize(tmp);
+
+	/* empty fdt node */
+	if (fdt_begin_node(dst, "fdt-1"))
+		return 0;
+	if (fdt_property_string(dst, FIT_TYPE_PROP, "flat_dt"))
+		return 0;
+	if (fdt_property_string(dst, FIT_COMP_PROP, "none"))
+		return 0;
+
+	if (fdt_property_u64(dst, FIT_LOAD_PROP, fdt_load_addr))
+		return 0;
+
+	if (fdt_property_placeholder(dst, FIT_DATA_PROP, fdt_size, &fdt))
+		return 0;
+
+	memcpy(fdt, tmp, fdt_size);
+	if (fdt_end_node(dst)) /* fdt-1 */
+		return 0;
+
+	if (fdt_end_node(dst)) /* images */
+		return 0;
+
+	/* configurations node */
+	if (fdt_begin_node(dst, "configurations"))
+		return 0;
+	if (fdt_property_string(dst, FIT_DEFAULT_PROP, "config-1"))
+		return 0;
+	if (fdt_begin_node(dst, "config-1"))
+		return 0;
+	if (fdt_property_string(dst, FIT_DESC_PROP, opensbi_image->name))
+		return 0;
+	if (fdt_property_string(dst, FIT_FIRMWARE_PROP, "opensbi"))
+		return 0;
+	if (fdt_property_string(dst, FIT_LOADABLE_PROP, "u-boot"))
+		return 0;
+	if (fdt_property_string(dst, FIT_FDT_PROP, "fdt-1"))
+		return 0;
+	if (fdt_end_node(dst)) /* config-1 */
+		return 0;
+	if (fdt_end_node(dst)) /* configurations */
+		return 0;
+	if (fdt_end_node(dst)) /* root */
+		return 0;
+	if (fdt_finish(dst))
+		return 0;
+
+out:
+	return total_size;
+}
+
+static int spl_test_firmware_image(struct unit_test_state *uts)
+{
+	size_t img_size, img_data, data_size = SPL_TEST_DATA_SIZE;
+	ulong uboot_load_addr = CONFIG_TEXT_BASE;
+	ulong firmware_load_addr = ALIGN(uboot_load_addr + data_size, 4096);
+	ulong fdt_load_addr = ALIGN(firmware_load_addr + data_size, 8);
+	struct spl_image_info info_uboot = {
+		.name = "U-Boot",
+		.os = IH_OS_U_BOOT,
+		.size = data_size,
+		.load_addr = CONFIG_TEXT_BASE,
+	}, info_firmware = {
+		.name = "RISC-V OpenSBI",
+		.os = IH_OS_OPENSBI,
+		.size = data_size,
+		.load_addr = firmware_load_addr,
+		.entry_point = firmware_load_addr,
+		.flags = SPL_FIT_FOUND,
+	}, info_read = { };
+	char *data_uboot, *data_firmware;
+	const char *uname;
+	ulong check_addr;
+	char str[100];
+	int noffset;
+	void *img;
+
+	img_size = create_firmware_fit(NULL, &info_uboot, &info_firmware, fdt_load_addr,
+								   &img_data);
+	ut_assert(img_size);
+	img = calloc(img_size, 1);
+	ut_assertnonnull(img);
+
+	data_uboot = img + img_data;
+	generate_data(data_uboot, data_size, "uboot_image");
+	data_firmware = data_uboot + info_uboot.size;
+	generate_data(data_firmware, info_firmware.size, "firmware_image");
+	ut_asserteq(img_size, create_firmware_fit(img, &info_uboot, &info_firmware, fdt_load_addr,
+				NULL));
+	ut_assertok(spl_load_fit_image(&info_read, img));
+	if (check_image_info(uts, &info_firmware, &info_read))
+		return CMD_RET_FAILURE;
+	ut_asserteq_mem(data_uboot, phys_to_virt(info_uboot.load_addr), info_uboot.size);
+	ut_asserteq_mem(data_firmware, phys_to_virt(info_read.load_addr), info_read.size);
+
+	/* check loadable and load address recorded successfully in empty dtb */
+	noffset = fdt_path_offset(phys_to_virt(fdt_load_addr), "/fit-images/u-boot");
+	ut_assert(noffset);
+
+	ut_assertok(fit_image_get_load(phys_to_virt(fdt_load_addr), noffset, &check_addr));
+	ut_asserteq(uboot_load_addr, check_addr);
+
+	free(img);
+	return 0;
+}
+SPL_TEST(spl_test_firmware_image, 0);
+
 int check_image_info(struct unit_test_state *uts, struct spl_image_info *info1,
 		     struct spl_image_info *info2)
 {

-- 
2.52.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.