summaryrefslogtreecommitdiff
path: root/test/boot
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2026-07-06 18:26:12 -0600
committerTom Rini <trini@konsulko.com>2026-07-06 18:26:12 -0600
commitee5d46b45ec0c63f8f9dd1e816e0dac3452ccc3d (patch)
tree800cd9e204ca027144070101884c0d5d3c00130f /test/boot
parentece349ade2973e220f524ce59e59711cc919263f (diff)
parenta18265f1ccb7a272721ed4286ed3b5a6182ff424 (diff)
downloadu-boot-master.tar.gz
u-boot-master.zip
Merge branch 'next'HEADmasterWIP/06Jul2026
Diffstat (limited to 'test/boot')
-rw-r--r--test/boot/Makefile4
-rw-r--r--test/boot/bootdev.c23
-rw-r--r--test/boot/bootflow.c47
-rw-r--r--test/boot/bootstd_common.h5
-rw-r--r--test/boot/fit_verity.c306
-rw-r--r--test/boot/image_fdt.c83
6 files changed, 456 insertions, 12 deletions
diff --git a/test/boot/Makefile b/test/boot/Makefile
index 89538d4f0a6..e6aa0ab7d3e 100644
--- a/test/boot/Makefile
+++ b/test/boot/Makefile
@@ -14,7 +14,11 @@ endif
ifdef CONFIG_SANDBOX
obj-$(CONFIG_$(PHASE_)CMDLINE) += bootm.o
+ifdef CONFIG_UT_DM
+obj-$(CONFIG_$(PHASE_)OF_LIBFDT) += image_fdt.o
endif
+endif
+obj-$(CONFIG_$(PHASE_)FIT_VERITY) += fit_verity.o
obj-$(CONFIG_MEASURED_BOOT) += measurement.o
ifdef CONFIG_OF_LIVE
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index 0820bf10ee0..c2eaf0b2c55 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -384,19 +384,19 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
ut_assert_nextline(" 2 mmc mmc_bootdev");
ut_assert_nextline(" 4 nvme nvme_bootdev");
ut_assert_nextline(" 4 qfw qfw_bootdev");
+ ut_assert_nextline(" 4 host sandbox_bootdev");
ut_assert_nextline(" 4 scsi scsi_bootdev");
ut_assert_nextline(" 4 spi_flash sf_bootdev");
ut_assert_nextline(" 5 usb usb_bootdev");
ut_assert_nextline(" 4 virtio virtio_bootdev");
- ut_assert_nextline("(total hunters: 9)");
+ ut_assert_nextline("(total hunters: 10)");
ut_assert_console_end();
ut_assertok(bootdev_hunt("usb1", false));
ut_assert_skip_to_line("Bus usb@1: 5 USB Device(s) found");
ut_assert_console_end();
- /* USB is 8th in the list, so bit 7 */
- ut_asserteq(BIT(7), std->hunters_used);
+ ut_asserteq(BIT(USB_HUNTER), std->hunters_used);
return 0;
}
@@ -417,7 +417,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
ut_assert_nextline("Prio Used Uclass Hunter");
ut_assert_nextlinen("----");
ut_assert_nextline(" 6 ethernet eth_bootdev");
- ut_assert_skip_to_line("(total hunters: 9)");
+ ut_assert_skip_to_line("(total hunters: 10)");
ut_assert_console_end();
/* Use the MMC hunter and see that it updates */
@@ -425,7 +425,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
ut_assertok(run_command("bootdev hunt -l", 0));
ut_assert_skip_to_line(" 5 ide ide_bootdev");
ut_assert_nextline(" 2 * mmc mmc_bootdev");
- ut_assert_skip_to_line("(total hunters: 9)");
+ ut_assert_skip_to_line("(total hunters: 10)");
ut_assert_console_end();
/* Scan all hunters */
@@ -441,6 +441,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
ut_assert_nextline("Hunting with: nvme");
ut_assert_nextline("Hunting with: qfw");
+ ut_assert_nextline("Hunting with: host");
ut_assert_nextline("Hunting with: scsi");
ut_assert_nextline("scanning bus for devices...");
ut_assert_skip_to_line("Hunting with: spi_flash");
@@ -458,11 +459,12 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
ut_assert_nextline(" 2 * mmc mmc_bootdev");
ut_assert_nextline(" 4 * nvme nvme_bootdev");
ut_assert_nextline(" 4 * qfw qfw_bootdev");
+ ut_assert_nextline(" 4 * host sandbox_bootdev");
ut_assert_nextline(" 4 * scsi scsi_bootdev");
ut_assert_nextline(" 4 * spi_flash sf_bootdev");
ut_assert_nextline(" 5 * usb usb_bootdev");
ut_assert_nextline(" 4 * virtio virtio_bootdev");
- ut_assert_nextline("(total hunters: 9)");
+ ut_assert_nextline("(total hunters: 10)");
ut_assert_console_end();
ut_asserteq(GENMASK(MAX_HUNTER, 0), std->hunters_used);
@@ -646,8 +648,7 @@ static int bootdev_test_next_label(struct unit_test_state *uts)
ut_asserteq_str("scsi.id0lun0.bootdev", dev->name);
ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS, mflags);
- /* SCSI is 6th in the list, so bit 5 */
- ut_asserteq(BIT(MMC_HUNTER) | BIT(5), std->hunters_used);
+ ut_asserteq(BIT(MMC_HUNTER) | BIT(SCSI_HUNTER), std->hunters_used);
ut_assertok(bootdev_next_label(&iter, &dev, &mflags));
ut_assert_console_end();
@@ -657,7 +658,7 @@ static int bootdev_test_next_label(struct unit_test_state *uts)
mflags);
/* dhcp: Ethernet is first so bit 0 */
- ut_asserteq(BIT(MMC_HUNTER) | BIT(5) | BIT(0), std->hunters_used);
+ ut_asserteq(BIT(MMC_HUNTER) | BIT(SCSI_HUNTER) | BIT(0), std->hunters_used);
ut_assertok(bootdev_next_label(&iter, &dev, &mflags));
ut_assert_console_end();
@@ -667,7 +668,7 @@ static int bootdev_test_next_label(struct unit_test_state *uts)
mflags);
/* pxe: Ethernet is first so bit 0 */
- ut_asserteq(BIT(MMC_HUNTER) | BIT(5) | BIT(0), std->hunters_used);
+ ut_asserteq(BIT(MMC_HUNTER) | BIT(SCSI_HUNTER) | BIT(0), std->hunters_used);
mflags = 123;
ut_asserteq(-ENODEV, bootdev_next_label(&iter, &dev, &mflags));
@@ -675,7 +676,7 @@ static int bootdev_test_next_label(struct unit_test_state *uts)
ut_assert_console_end();
/* no change */
- ut_asserteq(BIT(MMC_HUNTER) | BIT(5) | BIT(0), std->hunters_used);
+ ut_asserteq(BIT(MMC_HUNTER) | BIT(SCSI_HUNTER) | BIT(0), std->hunters_used);
return 0;
}
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index 56ee1952357..1cc137c9700 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -19,6 +19,8 @@
#include <mapmem.h>
#ifdef CONFIG_SANDBOX
#include <asm/test.h>
+#include <sandbox_host.h>
+#include <os.h>
#endif
#include <dm/device-internal.h>
#include <dm/lists.h>
@@ -1532,3 +1534,48 @@ static int bootstd_images(struct unit_test_state *uts)
return 0;
}
BOOTSTD_TEST(bootstd_images, UTF_CONSOLE);
+
+#if defined(CONFIG_SANDBOX) && defined(CONFIG_BOOTMETH_GLOBAL)
+/*
+ * Check that bootdev scanning does not stop if higher-priority bootdevs
+ * are failed to be hunted.
+ */
+static int bootdev_hunt_fallthrough(struct unit_test_state *uts)
+{
+ struct bootstd_priv *std;
+ struct udevice *dev;
+
+ ut_assertok(bootstd_get_priv(&std));
+ bootstd_test_drop_bootdev_order(uts);
+ test_set_skip_delays(true);
+ bootstd_reset_usb();
+ console_record_reset_enable();
+
+ /*
+ * Create a sandbox block device (BOOTDEVP_4_SCAN_FAST) and mark it as
+ * broken so that bootdev_hunt_prio() returns an error.
+ */
+ ut_asserteq(0, uclass_id_count(UCLASS_HOST));
+ ut_assertok(host_create_device("test", true, DEFAULT_BLKSZ, &dev));
+ ut_assertok(host_set_flags_by_label("test", HOST_FLAG_BROKEN));
+ ut_asserteq(1, uclass_id_count(UCLASS_HOST));
+
+ /*
+ * Scan with hunting.
+ * The sandbox hunter at priority 4 must fail, but the USB hunter at
+ * priority 5 must still be reached.
+ */
+ ut_assertok(run_command("bootflow scan -l", 0));
+
+ ut_assert(!(std->hunters_used & BIT(HOST_HUNTER)));
+ ut_assert_skip_to_line("Hunting with: host");
+
+ /* USB was hunted despite the sandbox hunter failure */
+ ut_assert(std->hunters_used & BIT(USB_HUNTER));
+ ut_assert_skip_to_line("Bus usb@1: 5 USB Device(s) found");
+
+ return 0;
+}
+BOOTSTD_TEST(bootdev_hunt_fallthrough,
+ UTF_DM | UTF_SCAN_FDT | UTF_SF_BOOTDEV | UTF_CONSOLE);
+#endif /* CONFIG_SANDBOX */
diff --git a/test/boot/bootstd_common.h b/test/boot/bootstd_common.h
index dd769313a84..672917454a3 100644
--- a/test/boot/bootstd_common.h
+++ b/test/boot/bootstd_common.h
@@ -21,8 +21,11 @@
#define TEST_VERNUM 0x00010002
enum {
- MAX_HUNTER = 8,
MMC_HUNTER = 2, /* ID of MMC hunter */
+ HOST_HUNTER = 5,
+ SCSI_HUNTER = 6,
+ USB_HUNTER = 8,
+ MAX_HUNTER = 9,
};
struct unit_test_state;
diff --git a/test/boot/fit_verity.c b/test/boot/fit_verity.c
new file mode 100644
index 00000000000..7459a9d6f81
--- /dev/null
+++ b/test/boot/fit_verity.c
@@ -0,0 +1,306 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Tests for FIT dm-verity cmdline generation
+ *
+ * Copyright 2026 Daniel Golle <daniel@makrotopia.org>
+ */
+
+#include <image.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+#define FIT_VERITY_TEST(_name, _flags) UNIT_TEST(_name, _flags, fit_verity)
+
+/* FIT blob buffer size — generous to avoid FDT_ERR_NOSPACE */
+#define FIT_BUF_SIZE 4096
+
+/* Test digest (32 bytes = sha256) */
+static const u8 test_digest[32] = {
+ 0x8e, 0x67, 0x91, 0x63, 0x7f, 0x93, 0xcb, 0xb8,
+ 0x1f, 0xc4, 0x52, 0x99, 0xe2, 0x03, 0xcb, 0xe8,
+ 0x5c, 0xa2, 0xe4, 0x7a, 0x38, 0xf5, 0x05, 0x1b,
+ 0xdd, 0xee, 0xce, 0x92, 0xd7, 0xb1, 0xc9, 0xf9,
+};
+
+/* Test salt (32 bytes) */
+static const u8 test_salt[32] = {
+ 0xaa, 0x7b, 0x11, 0xf8, 0xdb, 0x8f, 0xe2, 0xe5,
+ 0xbf, 0xd4, 0xec, 0xa1, 0xd1, 0x8a, 0x22, 0xb5,
+ 0xde, 0x7e, 0xa3, 0x9d, 0x2e, 0x1b, 0x93, 0xbb,
+ 0x72, 0x72, 0xce, 0x0c, 0x6c, 0xa3, 0xcc, 0x8e,
+};
+
+/**
+ * build_verity_fit() - construct a minimal FIT blob with dm-verity metadata
+ * @buf: output buffer (at least FIT_BUF_SIZE bytes)
+ * @num_loadables: number of filesystem loadables to create (1 or 2)
+ *
+ * Builds a FIT blob containing:
+ * - /images/rootfsN with type="filesystem" and a dm-verity subnode
+ * - /configurations/conf-1 referencing the loadable(s)
+ *
+ * Return: configuration node offset, or -ve on error
+ */
+static int build_verity_fit(void *buf, int num_loadables)
+{
+ int images_node, conf_node, confs_node, img_node, verity_node;
+ fdt32_t val;
+ int ret, i;
+ char name[32];
+ /*
+ * Build the loadables string list. FDT stringlists are concatenated
+ * NUL-terminated strings. E.g. "rootfs0\0rootfs1\0"
+ */
+ char loadables[128];
+ int loadables_len = 0;
+
+ ret = fdt_create_empty_tree(buf, FIT_BUF_SIZE);
+ if (ret)
+ return ret;
+
+ /* /images */
+ images_node = fdt_add_subnode(buf, 0, "images");
+ if (images_node < 0)
+ return images_node;
+
+ for (i = 0; i < num_loadables; i++) {
+ snprintf(name, sizeof(name), "rootfs%d", i);
+
+ img_node = fdt_add_subnode(buf, images_node, name);
+ if (img_node < 0)
+ return img_node;
+
+ ret = fdt_setprop_string(buf, img_node, FIT_TYPE_PROP,
+ "filesystem");
+ if (ret)
+ return ret;
+
+ verity_node = fdt_add_subnode(buf, img_node,
+ FIT_VERITY_NODENAME);
+ if (verity_node < 0)
+ return verity_node;
+
+ ret = fdt_setprop_string(buf, verity_node,
+ FIT_VERITY_ALGO_PROP, "sha256");
+ if (ret)
+ return ret;
+
+ val = cpu_to_fdt32(4096);
+ ret = fdt_setprop(buf, verity_node, FIT_VERITY_DBS_PROP,
+ &val, sizeof(val));
+ if (ret)
+ return ret;
+
+ ret = fdt_setprop(buf, verity_node, FIT_VERITY_HBS_PROP,
+ &val, sizeof(val));
+ if (ret)
+ return ret;
+
+ val = cpu_to_fdt32(100);
+ ret = fdt_setprop(buf, verity_node, FIT_VERITY_NBLK_PROP,
+ &val, sizeof(val));
+ if (ret)
+ return ret;
+
+ val = cpu_to_fdt32(100);
+ ret = fdt_setprop(buf, verity_node, FIT_VERITY_HBLK_PROP,
+ &val, sizeof(val));
+ if (ret)
+ return ret;
+
+ ret = fdt_setprop(buf, verity_node, FIT_VERITY_DIGEST_PROP,
+ test_digest, sizeof(test_digest));
+ if (ret)
+ return ret;
+
+ ret = fdt_setprop(buf, verity_node, FIT_VERITY_SALT_PROP,
+ test_salt, sizeof(test_salt));
+ if (ret)
+ return ret;
+
+ /* Append to loadables stringlist */
+ loadables_len += snprintf(loadables + loadables_len,
+ sizeof(loadables) - loadables_len,
+ "%s", name) + 1;
+ }
+
+ /* /configurations/conf-1 */
+ confs_node = fdt_add_subnode(buf, 0, "configurations");
+ if (confs_node < 0)
+ return confs_node;
+
+ conf_node = fdt_add_subnode(buf, confs_node, "conf-1");
+ if (conf_node < 0)
+ return conf_node;
+
+ ret = fdt_setprop(buf, conf_node, FIT_LOADABLE_PROP,
+ loadables, loadables_len);
+ if (ret)
+ return ret;
+
+ return conf_node;
+}
+
+/* Test: single dm-verity loadable produces correct cmdline fragments */
+static int fit_verity_test_single(struct unit_test_state *uts)
+{
+ char buf[FIT_BUF_SIZE];
+ struct bootm_headers images;
+ int conf_noffset;
+
+ conf_noffset = build_verity_fit(buf, 1);
+ ut_assert(conf_noffset >= 0);
+
+ memset(&images, 0, sizeof(images));
+ ut_assertok(fit_verity_build_cmdline(buf, conf_noffset, &images));
+
+ /* dm_mod_create should contain the target spec for rootfs0 */
+ ut_assertnonnull(images.dm_mod_create);
+ ut_assert(strstr(images.dm_mod_create, "rootfs0,,,"));
+ ut_assert(strstr(images.dm_mod_create, "verity 1"));
+ ut_assert(strstr(images.dm_mod_create, "/dev/fit0"));
+ ut_assert(strstr(images.dm_mod_create, "4096 4096 100 100"));
+ ut_assert(strstr(images.dm_mod_create, "sha256"));
+ /* Check hex-encoded digest prefix */
+ ut_assert(strstr(images.dm_mod_create, "8e6791637f93cbb8"));
+ /* Check hex-encoded salt prefix */
+ ut_assert(strstr(images.dm_mod_create, "aa7b11f8db8fe2e5"));
+
+ /* dm_mod_waitfor should reference /dev/fit0 */
+ ut_assertnonnull(images.dm_mod_waitfor);
+ ut_asserteq_str("/dev/fit0", images.dm_mod_waitfor);
+
+ fit_verity_free(&images);
+ ut_assertnull(images.dm_mod_create);
+ ut_assertnull(images.dm_mod_waitfor);
+
+ return 0;
+}
+FIT_VERITY_TEST(fit_verity_test_single, 0);
+
+/* Test: FIT with no dm-verity subnode returns 0, pointers stay NULL */
+static int fit_verity_test_no_verity(struct unit_test_state *uts)
+{
+ char buf[FIT_BUF_SIZE];
+ struct bootm_headers images;
+ int conf_node, images_node, img_node, confs_node;
+ int ret;
+
+ ret = fdt_create_empty_tree(buf, FIT_BUF_SIZE);
+ ut_assertok(ret);
+
+ images_node = fdt_add_subnode(buf, 0, "images");
+ ut_assert(images_node >= 0);
+
+ img_node = fdt_add_subnode(buf, images_node, "rootfs");
+ ut_assert(img_node >= 0);
+ ut_assertok(fdt_setprop_string(buf, img_node, FIT_TYPE_PROP,
+ "filesystem"));
+ /* No dm-verity subnode */
+
+ confs_node = fdt_add_subnode(buf, 0, "configurations");
+ ut_assert(confs_node >= 0);
+ conf_node = fdt_add_subnode(buf, confs_node, "conf-1");
+ ut_assert(conf_node >= 0);
+ ut_assertok(fdt_setprop_string(buf, conf_node, FIT_LOADABLE_PROP,
+ "rootfs"));
+
+ memset(&images, 0, sizeof(images));
+ ut_asserteq(0, fit_verity_build_cmdline(buf, conf_node, &images));
+ ut_assertnull(images.dm_mod_create);
+ ut_assertnull(images.dm_mod_waitfor);
+
+ return 0;
+}
+FIT_VERITY_TEST(fit_verity_test_no_verity, 0);
+
+/* Test: two dm-verity loadables produce combined cmdline */
+static int fit_verity_test_two_loadables(struct unit_test_state *uts)
+{
+ char buf[FIT_BUF_SIZE];
+ struct bootm_headers images;
+ int conf_noffset;
+
+ conf_noffset = build_verity_fit(buf, 2);
+ ut_assert(conf_noffset >= 0);
+
+ memset(&images, 0, sizeof(images));
+ ut_assertok(fit_verity_build_cmdline(buf, conf_noffset, &images));
+
+ /* Both targets should appear, separated by ";" */
+ ut_assertnonnull(images.dm_mod_create);
+ ut_assert(strstr(images.dm_mod_create, "rootfs0,,,"));
+ ut_assert(strstr(images.dm_mod_create, ";rootfs1,,,"));
+ ut_assert(strstr(images.dm_mod_create, "/dev/fit0"));
+ ut_assert(strstr(images.dm_mod_create, "/dev/fit1"));
+
+ /* dm_mod_waitfor should list both devices */
+ ut_assertnonnull(images.dm_mod_waitfor);
+ ut_assert(strstr(images.dm_mod_waitfor, "/dev/fit0"));
+ ut_assert(strstr(images.dm_mod_waitfor, "/dev/fit1"));
+
+ fit_verity_free(&images);
+ return 0;
+}
+FIT_VERITY_TEST(fit_verity_test_two_loadables, 0);
+
+/* Test: invalid block size (not power of two) returns -EINVAL */
+static int fit_verity_test_bad_blocksize(struct unit_test_state *uts)
+{
+ char buf[FIT_BUF_SIZE];
+ struct bootm_headers images;
+ int images_node, conf_node, confs_node, img_node, verity_node;
+ fdt32_t val;
+ int ret;
+
+ ret = fdt_create_empty_tree(buf, FIT_BUF_SIZE);
+ ut_assertok(ret);
+
+ images_node = fdt_add_subnode(buf, 0, "images");
+ ut_assert(images_node >= 0);
+
+ img_node = fdt_add_subnode(buf, images_node, "rootfs");
+ ut_assert(img_node >= 0);
+ ut_assertok(fdt_setprop_string(buf, img_node, FIT_TYPE_PROP,
+ "filesystem"));
+
+ verity_node = fdt_add_subnode(buf, img_node, FIT_VERITY_NODENAME);
+ ut_assert(verity_node >= 0);
+
+ ut_assertok(fdt_setprop_string(buf, verity_node,
+ FIT_VERITY_ALGO_PROP, "sha256"));
+
+ /* 3000 is not a power of two */
+ val = cpu_to_fdt32(3000);
+ ut_assertok(fdt_setprop(buf, verity_node, FIT_VERITY_DBS_PROP,
+ &val, sizeof(val)));
+ val = cpu_to_fdt32(4096);
+ ut_assertok(fdt_setprop(buf, verity_node, FIT_VERITY_HBS_PROP,
+ &val, sizeof(val)));
+
+ val = cpu_to_fdt32(100);
+ ut_assertok(fdt_setprop(buf, verity_node, FIT_VERITY_NBLK_PROP,
+ &val, sizeof(val)));
+ ut_assertok(fdt_setprop(buf, verity_node, FIT_VERITY_HBLK_PROP,
+ &val, sizeof(val)));
+
+ ut_assertok(fdt_setprop(buf, verity_node, FIT_VERITY_DIGEST_PROP,
+ test_digest, sizeof(test_digest)));
+ ut_assertok(fdt_setprop(buf, verity_node, FIT_VERITY_SALT_PROP,
+ test_salt, sizeof(test_salt)));
+
+ confs_node = fdt_add_subnode(buf, 0, "configurations");
+ ut_assert(confs_node >= 0);
+ conf_node = fdt_add_subnode(buf, confs_node, "conf-1");
+ ut_assert(conf_node >= 0);
+ ut_assertok(fdt_setprop_string(buf, conf_node, FIT_LOADABLE_PROP,
+ "rootfs"));
+
+ memset(&images, 0, sizeof(images));
+ ut_asserteq(-EINVAL, fit_verity_build_cmdline(buf, conf_node, &images));
+ ut_assertnull(images.dm_mod_create);
+ ut_assertnull(images.dm_mod_waitfor);
+
+ return 0;
+}
+FIT_VERITY_TEST(fit_verity_test_bad_blocksize, 0);
diff --git a/test/boot/image_fdt.c b/test/boot/image_fdt.c
new file mode 100644
index 00000000000..5417689a683
--- /dev/null
+++ b/test/boot/image_fdt.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include <config.h>
+
+#include <fdt_support.h>
+#include <image.h>
+#include <lmb.h>
+#include <malloc.h>
+
+#include <asm/global_data.h>
+
+#include <test/test.h>
+#include <test/ut.h>
+
+#define IMAGE_FDT_TEST(_name, _flags) UNIT_TEST(_name, _flags, image_fdt)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * test_boot_fdt_add_mem_rsv_regions - Make sure dt reservations are created and
+ * destroyed correctly
+ * @uts: Test state
+ *
+ * This test depends on the UT_DM device tree and ensures the following
+ * statements hold true: The default reservation in test.dtb exists.
+ * Re-reserving that region will result in an error. Loading a new device tree
+ * will remove old reservations.
+ */
+static int test_boot_fdt_add_mem_rsv_regions(struct unit_test_state *uts)
+{
+ phys_addr_t start = CFG_SYS_SDRAM_BASE + 0x100000;
+ const void *old_blob = gd->fdt_blob;
+ int ret = CMD_RET_FAILURE;
+ ulong fdt_sz;
+ int nodeoffset;
+ void *new_blob;
+
+ /* Default reservation should exist */
+ ut_asserteq(1, lmb_is_reserved_flags(start, LMB_NOMAP));
+
+ /* Attempting to re-reserve should warn the user */
+ boot_fdt_add_mem_rsv_regions(gd->fdt_blob);
+ ut_assert_nextlinen("ERROR: reserving");
+ ut_assert_console_end();
+
+ /* Loading a new_blob device tree should be allowed */
+ fdt_sz = fdt_totalsize(gd->fdt_blob);
+ new_blob = malloc(fdt_sz);
+ ut_assertnonnull(new_blob);
+ memcpy(new_blob, gd->fdt_blob, fdt_sz);
+
+ nodeoffset = fdt_path_offset(new_blob, "/reserved-memory");
+ if (nodeoffset < 0)
+ goto free_blob;
+
+ if (fdt_del_node(new_blob, nodeoffset))
+ goto free_blob;
+
+ boot_fdt_add_mem_rsv_regions(new_blob);
+ gd->fdt_blob = new_blob;
+
+ if (ut_check_console_end(uts)) {
+ ut_failf(uts, __FILE__, __LINE__, __func__, "console",
+ "Expected no more output, got '%s'", uts->actual_str);
+ goto switch_fdt;
+ }
+
+ /* Reservation should not exist now */
+ if (!lmb_is_reserved_flags(start, LMB_NOMAP))
+ ret = 0;
+
+ /* Cleanup */
+switch_fdt:
+ boot_fdt_add_mem_rsv_regions(old_blob);
+ gd->fdt_blob = old_blob;
+free_blob:
+ free(new_blob);
+ return ret;
+}
+IMAGE_FDT_TEST(test_boot_fdt_add_mem_rsv_regions, UTF_CONSOLE);