sandbox: test: Provide an easy way to use the other FDT

Add a test flag which indicates that the 'other' FDT should be set up
ready for use. Handle this by copying in the FDT, unflattening it for
livetree tests. Free the structures when the tests have run.

We cannot use the other FDT unless we are using live tree or
OFNODE_MULTI_TREE is enabled, since only one tree is supported by the
ofnode interface in that case. Add this condition into
ut_run_test_live_flat() and update the comments.

Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/test/test-main.c b/test/test-main.c
index c12027c..1fcbae3 100644
--- a/test/test-main.c
+++ b/test/test-main.c
@@ -9,6 +9,7 @@
 #include <cyclic.h>
 #include <dm.h>
 #include <event.h>
+#include <of_live.h>
 #include <os.h>
 #include <dm/root.h>
 #include <dm/test.h>
@@ -314,6 +315,20 @@
 	    (test->flags & UT_TESTF_SCAN_FDT))
 		ut_assertok(dm_extended_scan(false));
 
+	if (IS_ENABLED(CONFIG_SANDBOX) && (test->flags & UT_TESTF_OTHER_FDT)) {
+		/* make sure the other FDT is available */
+		ut_assertok(test_load_other_fdt(uts));
+
+		/*
+		 * create a new live tree with it for every test, in case a
+		 * test modifies the tree
+		 */
+		if (of_live_active()) {
+			ut_assertok(unflatten_device_tree(uts->other_fdt,
+							  &uts->of_other));
+		}
+	}
+
 	if (test->flags & UT_TESTF_CONSOLE_REC) {
 		int ret = console_record_reset_enable();
 
@@ -342,6 +357,9 @@
 	ut_assertok(cyclic_uninit());
 	ut_assertok(event_uninit());
 
+	free(uts->of_other);
+	uts->of_other = NULL;
+
 	return 0;
 }
 
@@ -412,6 +430,9 @@
 {
 	int runs;
 
+	if ((test->flags & UT_TESTF_OTHER_FDT) && !IS_ENABLED(CONFIG_SANDBOX))
+		return -EAGAIN;
+
 	/* Run with the live tree if possible */
 	runs = 0;
 	if (CONFIG_IS_ENABLED(OF_LIVE)) {
@@ -423,10 +444,20 @@
 	}
 
 	/*
-	 * Run with the flat tree if we couldn't run it with live tree,
-	 * or it is a core test.
+	 * Run with the flat tree if:
+	 * - it is not marked for live tree only
+	 * - it doesn't require the 'other' FDT when OFNODE_MULTI_TREE_MAX is
+	 *   not enabled (since flat tree can only support a single FDT in that
+	 *   case
+	 * - we couldn't run it with live tree,
+	 * - it is a core test (dm tests except video)
+	 * - the FDT is still valid and has not been updated by an earlier test
+	 *   (for sandbox we handle this by copying the tree, but not for other
+	 *    boards)
 	 */
 	if (!(test->flags & UT_TESTF_LIVE_TREE) &&
+	    (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) ||
+	     !(test->flags & UT_TESTF_OTHER_FDT)) &&
 	    (!runs || ut_test_run_on_flattree(test)) &&
 	    !(gd->flags & GD_FLG_FDT_CHANGED)) {
 		uts->of_live = false;
@@ -529,8 +560,10 @@
 	/* Best efforts only...ignore errors */
 	if (has_dm_tests)
 		dm_test_restore(uts.of_root);
-	if (IS_ENABLED(CONFIG_SANDBOX))
+	if (IS_ENABLED(CONFIG_SANDBOX)) {
 		os_free(uts.fdt_copy);
+		os_free(uts.other_fdt);
+	}
 
 	if (ret == -ENOENT)
 		printf("Test '%s' not found\n", select_name);