1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2022 Google LLC
4 *
5 * There are two types of tests in this file:
6 * - normal ones which act on the control FDT (gd->fdt_blob or gd->of_root)
7 * - 'other' ones which act on the 'other' FDT (other.dts)
8 *
9 * The 'other' ones have an _ot suffix.
10 *
11 * The latter are used to check behaviour with multiple device trees,
12 * particularly with flat tree, where a tree ID is included in ofnode as part of
13 * the node offset. These tests are typically just for making sure that the
14 * offset makes it to libfdt correctly and that the resulting return value is
15 * correctly turned into an ofnode. The 'other' tests do not fully check the
16 * behaviour of each ofnode function, since that is done by the normal ones.
17 */
18
19#include <common.h>
20#include <abuf.h>
21#include <dm.h>
22#include <log.h>
23#include <of_live.h>
24#include <dm/device-internal.h>
25#include <dm/lists.h>
26#include <dm/of_extra.h>
27#include <dm/root.h>
28#include <dm/test.h>
29#include <dm/uclass-internal.h>
30#include <linux/sizes.h>
31#include <test/test.h>
32#include <test/ut.h>
33
34/**
35 * get_other_oftree() - Convert a flat tree into an oftree object
36 *
37 * @uts: Test state
38 * @return: oftree object for the 'other' FDT (see sandbox' other.dts)
39 */
40oftree get_other_oftree(struct unit_test_state *uts)
41{
42	oftree tree;
43
44	if (of_live_active())
45		tree = oftree_from_np(uts->of_other);
46	else
47		tree = oftree_from_fdt(uts->other_fdt);
48
49	/* An invalid tree may cause failure or crashes */
50	if (!oftree_valid(tree))
51		ut_reportf("test needs the UT_TESTF_OTHER_FDT flag");
52
53	return tree;
54}
55
56/**
57 * get_oftree() - Convert a flat tree into an oftree object
58 *
59 * @uts: Test state
60 * @fdt: Pointer to flat tree
61 * @treep: Returns the tree, on success
62 * Return: 0 if OK, 1 if the tree failed to unflatten, -EOVERFLOW if there are
63 * too many flat trees to allow another one to be registers (see
64 * oftree_ensure())
65 */
66int get_oftree(struct unit_test_state *uts, void *fdt, oftree *treep)
67{
68	oftree tree;
69
70	if (of_live_active()) {
71		struct device_node *root;
72
73		ut_assertok(unflatten_device_tree(fdt, &root));
74		tree = oftree_from_np(root);
75	} else {
76		tree = oftree_from_fdt(fdt);
77		if (!oftree_valid(tree))
78			return -EOVERFLOW;
79	}
80	*treep = tree;
81
82	return 0;
83}
84
85/**
86 * free_oftree() - Free memory used by get_oftree()
87 *
88 * @tree: Tree to free
89 */
90void free_oftree(oftree tree)
91{
92	if (of_live_active())
93		free(tree.np);
94}
95
96/* test ofnode_device_is_compatible() */
97static int dm_test_ofnode_compatible(struct unit_test_state *uts)
98{
99	ofnode root_node = ofnode_path("/");
100
101	ut_assert(ofnode_valid(root_node));
102	ut_assert(ofnode_device_is_compatible(root_node, "sandbox"));
103
104	return 0;
105}
106DM_TEST(dm_test_ofnode_compatible,
107	UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
108
109/* check ofnode_device_is_compatible() with the 'other' FDT */
110static int dm_test_ofnode_compatible_ot(struct unit_test_state *uts)
111{
112	oftree otree = get_other_oftree(uts);
113	ofnode oroot = oftree_root(otree);
114
115	ut_assert(ofnode_valid(oroot));
116	ut_assert(ofnode_device_is_compatible(oroot, "sandbox-other"));
117
118	return 0;
119}
120DM_TEST(dm_test_ofnode_compatible_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT);
121
122static int dm_test_ofnode_get_by_phandle(struct unit_test_state *uts)
123{
124	/* test invalid phandle */
125	ut_assert(!ofnode_valid(ofnode_get_by_phandle(0)));
126	ut_assert(!ofnode_valid(ofnode_get_by_phandle(-1)));
127
128	/* test first valid phandle */
129	ut_assert(ofnode_valid(ofnode_get_by_phandle(1)));
130
131	/* test unknown phandle */
132	ut_assert(!ofnode_valid(ofnode_get_by_phandle(0x1000000)));
133
134	ut_assert(ofnode_valid(oftree_get_by_phandle(oftree_default(), 1)));
135
136	return 0;
137}
138DM_TEST(dm_test_ofnode_get_by_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
139
140/* test oftree_get_by_phandle() with a the 'other' oftree */
141static int dm_test_ofnode_get_by_phandle_ot(struct unit_test_state *uts)
142{
143	oftree otree = get_other_oftree(uts);
144	ofnode node;
145
146	ut_assert(ofnode_valid(oftree_get_by_phandle(oftree_default(), 1)));
147	node = oftree_get_by_phandle(otree, 1);
148	ut_assert(ofnode_valid(node));
149	ut_asserteq_str("target", ofnode_get_name(node));
150
151	return 0;
152}
153DM_TEST(dm_test_ofnode_get_by_phandle_ot,
154	UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT);
155
156static int check_prop_values(struct unit_test_state *uts, ofnode start,
157			     const char *propname, const char *propval,
158			     int expect_count)
159{
160	int proplen = strlen(propval) + 1;
161	const char *str;
162	ofnode node;
163	int count;
164
165	/* Find first matching node, there should be at least one */
166	node = ofnode_by_prop_value(start, propname, propval, proplen);
167	ut_assert(ofnode_valid(node));
168	str = ofnode_read_string(node, propname);
169	ut_assert(str && !strcmp(str, propval));
170
171	/* Find the rest of the matching nodes */
172	count = 1;
173	while (true) {
174		node = ofnode_by_prop_value(node, propname, propval, proplen);
175		if (!ofnode_valid(node))
176			break;
177		str = ofnode_read_string(node, propname);
178		ut_asserteq_str(propval, str);
179		count++;
180	}
181	ut_asserteq(expect_count, count);
182
183	return 0;
184}
185
186static int dm_test_ofnode_by_prop_value(struct unit_test_state *uts)
187{
188	ut_assertok(check_prop_values(uts, ofnode_null(), "compatible",
189				      "denx,u-boot-fdt-test", 11));
190
191	return 0;
192}
193DM_TEST(dm_test_ofnode_by_prop_value, UT_TESTF_SCAN_FDT);
194
195/* test ofnode_by_prop_value() with a the 'other' oftree */
196static int dm_test_ofnode_by_prop_value_ot(struct unit_test_state *uts)
197{
198	oftree otree = get_other_oftree(uts);
199
200	ut_assertok(check_prop_values(uts, oftree_root(otree), "str-prop",
201				      "other", 2));
202
203	return 0;
204}
205DM_TEST(dm_test_ofnode_by_prop_value_ot,
206	UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT);
207
208/* test ofnode_read_fmap_entry() */
209static int dm_test_ofnode_fmap(struct unit_test_state *uts)
210{
211	struct fmap_entry entry;
212	ofnode node;
213
214	node = ofnode_path("/cros-ec/flash");
215	ut_assert(ofnode_valid(node));
216	ut_assertok(ofnode_read_fmap_entry(node, &entry));
217	ut_asserteq(0x08000000, entry.offset);
218	ut_asserteq(0x20000, entry.length);
219
220	return 0;
221}
222DM_TEST(dm_test_ofnode_fmap, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
223
224/* test ofnode_read_prop() */
225static int dm_test_ofnode_read(struct unit_test_state *uts)
226{
227	const u32 *val;
228	ofnode node;
229	int size;
230
231	node = oftree_path(oftree_default(), "/");
232	ut_assert(ofnode_valid(node));
233
234	node = ofnode_path("/a-test");
235	ut_assert(ofnode_valid(node));
236
237	val = ofnode_read_prop(node, "int-value", &size);
238	ut_assertnonnull(val);
239	ut_asserteq(4, size);
240	ut_asserteq(1234, fdt32_to_cpu(val[0]));
241
242	val = ofnode_read_prop(node, "missing", &size);
243	ut_assertnull(val);
244	ut_asserteq(-FDT_ERR_NOTFOUND, size);
245
246	/* Check it works without a size parameter */
247	val = ofnode_read_prop(node, "missing", NULL);
248	ut_assertnull(val);
249
250	return 0;
251}
252DM_TEST(dm_test_ofnode_read, UT_TESTF_SCAN_FDT);
253
254/* test ofnode_read_prop() with the 'other' tree */
255static int dm_test_ofnode_read_ot(struct unit_test_state *uts)
256{
257	oftree otree = get_other_oftree(uts);
258	const char *val;
259	ofnode node;
260	int size;
261
262	node = oftree_path(otree, "/");
263	ut_assert(ofnode_valid(node));
264
265	node = oftree_path(otree, "/node/subnode");
266	ut_assert(ofnode_valid(node));
267
268	val = ofnode_read_prop(node, "str-prop", &size);
269	ut_assertnonnull(val);
270	ut_asserteq_str("other", val);
271	ut_asserteq(6, size);
272
273	return 0;
274}
275DM_TEST(dm_test_ofnode_read_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT);
276
277/* test ofnode_count_/parse_phandle_with_args() */
278static int dm_test_ofnode_phandle(struct unit_test_state *uts)
279{
280	struct ofnode_phandle_args args;
281	ofnode node;
282	int ret;
283	const char prop[] = "test-gpios";
284	const char cell[] = "#gpio-cells";
285	const char prop2[] = "phandle-value";
286
287	node = ofnode_path("/a-test");
288	ut_assert(ofnode_valid(node));
289
290	/* Test ofnode_count_phandle_with_args with cell name */
291	ret = ofnode_count_phandle_with_args(node, "missing", cell, 0);
292	ut_asserteq(-ENOENT, ret);
293	ret = ofnode_count_phandle_with_args(node, prop, "#invalid", 0);
294	ut_asserteq(-EINVAL, ret);
295	ret = ofnode_count_phandle_with_args(node, prop, cell, 0);
296	ut_asserteq(5, ret);
297
298	/* Test ofnode_parse_phandle_with_args with cell name */
299	ret = ofnode_parse_phandle_with_args(node, "missing", cell, 0, 0,
300					     &args);
301	ut_asserteq(-ENOENT, ret);
302	ret = ofnode_parse_phandle_with_args(node, prop, "#invalid", 0, 0,
303					     &args);
304	ut_asserteq(-EINVAL, ret);
305	ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 0, &args);
306	ut_assertok(ret);
307	ut_asserteq(1, args.args_count);
308	ut_asserteq(1, args.args[0]);
309	ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 1, &args);
310	ut_assertok(ret);
311	ut_asserteq(1, args.args_count);
312	ut_asserteq(4, args.args[0]);
313	ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 2, &args);
314	ut_assertok(ret);
315	ut_asserteq(5, args.args_count);
316	ut_asserteq(5, args.args[0]);
317	ut_asserteq(1, args.args[4]);
318	ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 3, &args);
319	ut_asserteq(-ENOENT, ret);
320	ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 4, &args);
321	ut_assertok(ret);
322	ut_asserteq(1, args.args_count);
323	ut_asserteq(12, args.args[0]);
324	ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 5, &args);
325	ut_asserteq(-ENOENT, ret);
326
327	/* Test ofnode_count_phandle_with_args with cell count */
328	ret = ofnode_count_phandle_with_args(node, "missing", NULL, 2);
329	ut_asserteq(-ENOENT, ret);
330	ret = ofnode_count_phandle_with_args(node, prop2, NULL, 1);
331	ut_asserteq(3, ret);
332
333	/* Test ofnode_parse_phandle_with_args with cell count */
334	ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 0, &args);
335	ut_assertok(ret);
336	ut_asserteq(1, ofnode_valid(args.node));
337	ut_asserteq(1, args.args_count);
338	ut_asserteq(10, args.args[0]);
339	ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 1, &args);
340	ut_asserteq(-EINVAL, ret);
341	ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 2, &args);
342	ut_assertok(ret);
343	ut_asserteq(1, ofnode_valid(args.node));
344	ut_asserteq(1, args.args_count);
345	ut_asserteq(30, args.args[0]);
346	ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 3, &args);
347	ut_asserteq(-ENOENT, ret);
348
349	return 0;
350}
351DM_TEST(dm_test_ofnode_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
352
353/* test ofnode_count_/parse_phandle_with_args() with 'other' tree */
354static int dm_test_ofnode_phandle_ot(struct unit_test_state *uts)
355{
356	oftree otree = get_other_oftree(uts);
357	struct ofnode_phandle_args args;
358	ofnode node;
359	int ret;
360
361	node = oftree_path(otree, "/node");
362
363	/* Test ofnode_count_phandle_with_args with cell name */
364	ret = ofnode_count_phandle_with_args(node, "missing", "#gpio-cells", 0);
365	ut_asserteq(-ENOENT, ret);
366	ret = ofnode_count_phandle_with_args(node, "target", "#invalid", 0);
367	ut_asserteq(-EINVAL, ret);
368	ret = ofnode_count_phandle_with_args(node, "target", "#gpio-cells", 0);
369	ut_asserteq(1, ret);
370
371	ret = ofnode_parse_phandle_with_args(node, "target", "#gpio-cells", 0,
372					     0, &args);
373	ut_assertok(ret);
374	ut_asserteq(2, args.args_count);
375	ut_asserteq(3, args.args[0]);
376	ut_asserteq(4, args.args[1]);
377
378	return 0;
379}
380DM_TEST(dm_test_ofnode_phandle_ot, UT_TESTF_OTHER_FDT);
381
382/* test ofnode_read_chosen_string/node/prop() */
383static int dm_test_ofnode_read_chosen(struct unit_test_state *uts)
384{
385	const char *str;
386	const u32 *val;
387	ofnode node;
388	int size;
389
390	str = ofnode_read_chosen_string("setting");
391	ut_assertnonnull(str);
392	ut_asserteq_str("sunrise ohoka", str);
393	ut_asserteq_ptr(NULL, ofnode_read_chosen_string("no-setting"));
394
395	node = ofnode_get_chosen_node("other-node");
396	ut_assert(ofnode_valid(node));
397	ut_asserteq_str("c-test@5", ofnode_get_name(node));
398
399	node = ofnode_get_chosen_node("setting");
400	ut_assert(!ofnode_valid(node));
401
402	val = ofnode_read_chosen_prop("int-values", &size);
403	ut_assertnonnull(val);
404	ut_asserteq(8, size);
405	ut_asserteq(0x1937, fdt32_to_cpu(val[0]));
406	ut_asserteq(72993, fdt32_to_cpu(val[1]));
407
408	return 0;
409}
410DM_TEST(dm_test_ofnode_read_chosen, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
411
412/* test ofnode_get_aliases_node/prop() */
413static int dm_test_ofnode_read_aliases(struct unit_test_state *uts)
414{
415	const void *val;
416	ofnode node;
417	int size;
418
419	node = ofnode_get_aliases_node("ethernet3");
420	ut_assert(ofnode_valid(node));
421	ut_asserteq_str("sbe5", ofnode_get_name(node));
422
423	node = ofnode_get_aliases_node("unknown");
424	ut_assert(!ofnode_valid(node));
425
426	val = ofnode_read_aliases_prop("spi0", &size);
427	ut_assertnonnull(val);
428	ut_asserteq(7, size);
429	ut_asserteq_str("/spi@0", (const char *)val);
430
431	return 0;
432}
433DM_TEST(dm_test_ofnode_read_aliases, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
434
435static int dm_test_ofnode_get_child_count(struct unit_test_state *uts)
436{
437	ofnode node, child_node;
438	u32 val;
439
440	node = ofnode_path("/i-test");
441	ut_assert(ofnode_valid(node));
442
443	val = ofnode_get_child_count(node);
444	ut_asserteq(3, val);
445
446	child_node = ofnode_first_subnode(node);
447	ut_assert(ofnode_valid(child_node));
448	val = ofnode_get_child_count(child_node);
449	ut_asserteq(0, val);
450
451	return 0;
452}
453DM_TEST(dm_test_ofnode_get_child_count,
454	UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
455
456/* test ofnode_get_child_count() with 'other' tree */
457static int dm_test_ofnode_get_child_count_ot(struct unit_test_state *uts)
458{
459	oftree otree = get_other_oftree(uts);
460	ofnode node, child_node;
461	u32 val;
462
463	node = oftree_path(otree, "/node");
464	ut_assert(ofnode_valid(node));
465
466	val = ofnode_get_child_count(node);
467	ut_asserteq(2, val);
468
469	child_node = ofnode_first_subnode(node);
470	ut_assert(ofnode_valid(child_node));
471	val = ofnode_get_child_count(child_node);
472	ut_asserteq(0, val);
473
474	return 0;
475}
476DM_TEST(dm_test_ofnode_get_child_count_ot,
477	UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT);
478
479static int dm_test_ofnode_is_enabled(struct unit_test_state *uts)
480{
481	ofnode root_node = ofnode_path("/");
482	ofnode node = ofnode_path("/usb@0");
483
484	ut_assert(ofnode_is_enabled(root_node));
485	ut_assert(!ofnode_is_enabled(node));
486
487	return 0;
488}
489DM_TEST(dm_test_ofnode_is_enabled, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
490
491/* test ofnode_is_enabled() with 'other' tree */
492static int dm_test_ofnode_is_enabled_ot(struct unit_test_state *uts)
493{
494	oftree otree = get_other_oftree(uts);
495	ofnode root_node = oftree_root(otree);
496	ofnode node = oftree_path(otree, "/target");
497
498	ut_assert(ofnode_is_enabled(root_node));
499	ut_assert(!ofnode_is_enabled(node));
500
501	return 0;
502}
503DM_TEST(dm_test_ofnode_is_enabled_ot, UT_TESTF_OTHER_FDT);
504
505/* test ofnode_get_addr/size() */
506static int dm_test_ofnode_get_reg(struct unit_test_state *uts)
507{
508	ofnode node;
509	fdt_addr_t addr;
510	fdt_size_t size;
511
512	node = ofnode_path("/translation-test@8000");
513	ut_assert(ofnode_valid(node));
514	addr = ofnode_get_addr(node);
515	size = ofnode_get_size(node);
516	ut_asserteq(0x8000, addr);
517	ut_asserteq(0x4000, size);
518
519	node = ofnode_path("/translation-test@8000/dev@1,100");
520	ut_assert(ofnode_valid(node));
521	addr = ofnode_get_addr(node);
522	size = ofnode_get_size(node);
523	ut_asserteq(0x9000, addr);
524	ut_asserteq(0x1000, size);
525
526	node = ofnode_path("/emul-mux-controller");
527	ut_assert(ofnode_valid(node));
528	addr = ofnode_get_addr(node);
529	size = ofnode_get_size(node);
530	ut_asserteq_64(FDT_ADDR_T_NONE, addr);
531	ut_asserteq(FDT_SIZE_T_NONE, size);
532
533	node = ofnode_path("/translation-test@8000/noxlatebus@3,300/dev@42");
534	ut_assert(ofnode_valid(node));
535	addr = ofnode_get_addr_size_index_notrans(node, 0, &size);
536	ut_asserteq_64(0x42, addr);
537
538	return 0;
539}
540DM_TEST(dm_test_ofnode_get_reg, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
541
542/* test ofnode_get_addr() with 'other' tree */
543static int dm_test_ofnode_get_reg_ot(struct unit_test_state *uts)
544{
545	oftree otree = get_other_oftree(uts);
546	ofnode node = oftree_path(otree, "/target");
547	fdt_addr_t addr;
548
549	addr = ofnode_get_addr(node);
550	ut_asserteq(0x8000, addr);
551
552	return 0;
553}
554DM_TEST(dm_test_ofnode_get_reg_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT);
555
556static int dm_test_ofnode_get_path(struct unit_test_state *uts)
557{
558	const char *path = "/translation-test@8000/noxlatebus@3,300/dev@42";
559	char buf[64];
560	ofnode node;
561
562	node = ofnode_path(path);
563	ut_assert(ofnode_valid(node));
564
565	ut_assertok(ofnode_get_path(node, buf, sizeof(buf)));
566	ut_asserteq_str(path, buf);
567
568	ut_asserteq(-ENOSPC, ofnode_get_path(node, buf, 32));
569
570	ut_assertok(ofnode_get_path(ofnode_root(), buf, 32));
571	ut_asserteq_str("/", buf);
572
573	return 0;
574}
575DM_TEST(dm_test_ofnode_get_path, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
576
577/* test ofnode_get_path() with 'other' tree */
578static int dm_test_ofnode_get_path_ot(struct unit_test_state *uts)
579{
580	oftree otree = get_other_oftree(uts);
581	const char *path = "/node/subnode";
582	ofnode node = oftree_path(otree, path);
583	char buf[64];
584
585	ut_assert(ofnode_valid(node));
586
587	ut_assertok(ofnode_get_path(node, buf, sizeof(buf)));
588	ut_asserteq_str(path, buf);
589
590	ut_assertok(ofnode_get_path(oftree_root(otree), buf, 32));
591	ut_asserteq_str("/", buf);
592
593	return 0;
594}
595DM_TEST(dm_test_ofnode_get_path_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT);
596
597/* test ofnode_conf_read_bool/int/str() */
598static int dm_test_ofnode_conf(struct unit_test_state *uts)
599{
600	ut_assert(!ofnode_conf_read_bool("missing"));
601	ut_assert(ofnode_conf_read_bool("testing-bool"));
602
603	ut_asserteq(123, ofnode_conf_read_int("testing-int", 0));
604	ut_asserteq(6, ofnode_conf_read_int("missing", 6));
605
606	ut_assertnull(ofnode_conf_read_str("missing"));
607	ut_asserteq_str("testing", ofnode_conf_read_str("testing-str"));
608
609	return 0;
610}
611DM_TEST(dm_test_ofnode_conf, UT_TESTF_SCAN_FDT);
612
613static int dm_test_ofnode_options(struct unit_test_state *uts)
614{
615	u64 bootscr_address, bootscr_offset;
616	u64 bootscr_flash_offset, bootscr_flash_size;
617
618	ut_assertok(ofnode_read_bootscript_address(&bootscr_address,
619						   &bootscr_offset));
620	ut_asserteq_64(0, bootscr_address);
621	ut_asserteq_64(0x12345678, bootscr_offset);
622
623	ut_assertok(ofnode_read_bootscript_flash(&bootscr_flash_offset,
624						 &bootscr_flash_size));
625	ut_asserteq_64(0, bootscr_flash_offset);
626	ut_asserteq_64(0x2000, bootscr_flash_size);
627
628	return 0;
629}
630DM_TEST(dm_test_ofnode_options, 0);
631
632static int dm_test_ofnode_for_each_compatible_node(struct unit_test_state *uts)
633{
634	const char compatible[] = "denx,u-boot-fdt-test";
635	bool found = false;
636	ofnode node;
637
638	ofnode_for_each_compatible_node(node, compatible) {
639		ut_assert(ofnode_device_is_compatible(node, compatible));
640		found = true;
641	}
642
643	/* There should be at least one matching node */
644	ut_assert(found);
645
646	return 0;
647}
648DM_TEST(dm_test_ofnode_for_each_compatible_node, UT_TESTF_SCAN_FDT);
649
650/* test dm_test_ofnode_string_count/index/list() */
651static int dm_test_ofnode_string(struct unit_test_state *uts)
652{
653	const char **val;
654	const char *out;
655	ofnode node;
656
657	node = ofnode_path("/a-test");
658	ut_assert(ofnode_valid(node));
659
660	/* single string */
661	ut_asserteq(1, ofnode_read_string_count(node, "str-value"));
662	ut_assertok(ofnode_read_string_index(node, "str-value", 0, &out));
663	ut_asserteq_str("test string", out);
664	ut_asserteq(0, ofnode_stringlist_search(node, "str-value",
665						"test string"));
666	ut_asserteq(1, ofnode_read_string_list(node, "str-value", &val));
667	ut_asserteq_str("test string", val[0]);
668	ut_assertnull(val[1]);
669	free(val);
670
671	/* list of strings */
672	ut_asserteq(5, ofnode_read_string_count(node, "mux-control-names"));
673	ut_assertok(ofnode_read_string_index(node, "mux-control-names", 0,
674					     &out));
675	ut_asserteq_str("mux0", out);
676	ut_asserteq(0, ofnode_stringlist_search(node, "mux-control-names",
677						"mux0"));
678	ut_asserteq(5, ofnode_read_string_list(node, "mux-control-names",
679					       &val));
680	ut_asserteq_str("mux0", val[0]);
681	ut_asserteq_str("mux1", val[1]);
682	ut_asserteq_str("mux2", val[2]);
683	ut_asserteq_str("mux3", val[3]);
684	ut_asserteq_str("mux4", val[4]);
685	ut_assertnull(val[5]);
686	free(val);
687
688	ut_assertok(ofnode_read_string_index(node, "mux-control-names", 4,
689					     &out));
690	ut_asserteq_str("mux4", out);
691	ut_asserteq(4, ofnode_stringlist_search(node, "mux-control-names",
692						"mux4"));
693
694	return 0;
695}
696DM_TEST(dm_test_ofnode_string, UT_TESTF_SCAN_FDT);
697
698/* test error returns from ofnode_read_string_count/index/list() */
699static int dm_test_ofnode_string_err(struct unit_test_state *uts)
700{
701	const char **val;
702	const char *out;
703	ofnode node;
704
705	/*
706	 * Test error codes only on livetree, as they are different with
707	 * flattree
708	 */
709	node = ofnode_path("/a-test");
710	ut_assert(ofnode_valid(node));
711
712	/* non-existent property */
713	ut_asserteq(-EINVAL, ofnode_read_string_count(node, "missing"));
714	ut_asserteq(-EINVAL, ofnode_read_string_index(node, "missing", 0,
715						      &out));
716	ut_asserteq(-EINVAL, ofnode_read_string_list(node, "missing", &val));
717
718	/* empty property */
719	ut_asserteq(-ENODATA, ofnode_read_string_count(node, "bool-value"));
720	ut_asserteq(-ENODATA, ofnode_read_string_index(node, "bool-value", 0,
721						       &out));
722	ut_asserteq(-ENODATA, ofnode_read_string_list(node, "bool-value",
723						     &val));
724
725	/* badly formatted string list */
726	ut_asserteq(-EILSEQ, ofnode_read_string_count(node, "int64-value"));
727	ut_asserteq(-EILSEQ, ofnode_read_string_index(node, "int64-value", 0,
728						       &out));
729	ut_asserteq(-EILSEQ, ofnode_read_string_list(node, "int64-value",
730						     &val));
731
732	/* out of range / not found */
733	ut_asserteq(-ENODATA, ofnode_read_string_index(node, "str-value", 1,
734						       &out));
735	ut_asserteq(-ENODATA, ofnode_stringlist_search(node, "str-value",
736						       "other"));
737
738	/* negative value for index is not allowed, so don't test for that */
739
740	ut_asserteq(-ENODATA, ofnode_read_string_index(node,
741						       "mux-control-names", 5,
742						       &out));
743
744	return 0;
745}
746DM_TEST(dm_test_ofnode_string_err, UT_TESTF_LIVE_TREE);
747
748static int dm_test_ofnode_read_phy_mode(struct unit_test_state *uts)
749{
750	ofnode eth_node, phy_node;
751	phy_interface_t mode;
752	u32 reg;
753
754	eth_node = ofnode_path("/phy-test-eth");
755	ut_assert(ofnode_valid(eth_node));
756
757	mode = ofnode_read_phy_mode(eth_node);
758	ut_assert(mode == PHY_INTERFACE_MODE_2500BASEX);
759
760	phy_node = ofnode_get_phy_node(eth_node);
761	ut_assert(ofnode_valid(phy_node));
762
763	reg = ofnode_read_u32_default(phy_node, "reg", -1U);
764	ut_asserteq_64(0x1, reg);
765
766	return 0;
767}
768DM_TEST(dm_test_ofnode_read_phy_mode, UT_TESTF_SCAN_FDT);
769
770/**
771 * make_ofnode_fdt() - Create an FDT for testing with ofnode
772 *
773 * The size is set to the minimum needed
774 *
775 * @uts: Test state
776 * @fdt: Place to write FDT
777 * @size: Maximum size of space for fdt
778 * @id: id value to add to the tree ('id' property in root node)
779 */
780static int make_ofnode_fdt(struct unit_test_state *uts, void *fdt, int size,
781			   int id)
782{
783	ut_assertok(fdt_create(fdt, size));
784	ut_assertok(fdt_finish_reservemap(fdt));
785	ut_assert(fdt_begin_node(fdt, "") >= 0);
786
787	ut_assertok(fdt_property_u32(fdt, "id", id));
788
789	ut_assert(fdt_begin_node(fdt, "aliases") >= 0);
790	ut_assertok(fdt_property_string(fdt, "mmc0", "/new-mmc"));
791	ut_assertok(fdt_end_node(fdt));
792
793	ut_assert(fdt_begin_node(fdt, "new-mmc") >= 0);
794	ut_assertok(fdt_end_node(fdt));
795
796	ut_assertok(fdt_end_node(fdt));
797	ut_assertok(fdt_finish(fdt));
798
799	return 0;
800}
801
802/* Check that aliases work on the control FDT */
803static int dm_test_ofnode_aliases(struct unit_test_state *uts)
804{
805	ofnode node;
806
807	node = ofnode_get_aliases_node("ethernet3");
808	ut_assert(ofnode_valid(node));
809	ut_asserteq_str("sbe5", ofnode_get_name(node));
810
811	ut_assert(!oftree_valid(oftree_null()));
812
813	return 0;
814}
815DM_TEST(dm_test_ofnode_aliases, UT_TESTF_SCAN_FDT);
816
817/**
818 * dm_test_ofnode_root_mult() - Check aliaes on control and 'other' tree
819 *
820 * Check that aliases work only with the control FDT, not with 'other' tree.
821 * This is not actually the desired behaviour. If aliases are implemented for
822 * any tree, then this test should be changed.
823 */
824static int dm_test_ofnode_root_mult(struct unit_test_state *uts)
825{
826	char fdt[256];
827	oftree tree;
828	ofnode node;
829
830	/* skip this test if multiple FDTs are not supported */
831	if (!IS_ENABLED(CONFIG_OFNODE_MULTI_TREE))
832		return -EAGAIN;
833
834	ut_assertok(make_ofnode_fdt(uts, fdt, sizeof(fdt), 0));
835	ut_assertok(get_oftree(uts, fdt, &tree));
836	ut_assert(oftree_valid(tree));
837
838	/* Make sure they don't work on this new tree */
839	node = oftree_path(tree, "mmc0");
840	ut_assert(!ofnode_valid(node));
841
842	/* It should appear in the new tree */
843	node = oftree_path(tree, "/new-mmc");
844	ut_assert(ofnode_valid(node));
845
846	/* ...and not in the control FDT */
847	node = oftree_path(oftree_default(), "/new-mmc");
848	ut_assert(!ofnode_valid(node));
849
850	free_oftree(tree);
851
852	return 0;
853}
854DM_TEST(dm_test_ofnode_root_mult, UT_TESTF_SCAN_FDT);
855
856/* test ofnode_set_enabled(), ofnode_write_prop() on a livetree */
857static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts)
858{
859	struct udevice *dev;
860	ofnode node;
861
862	/* Test enabling devices */
863	node = ofnode_path("/usb@2");
864
865	ut_assert(!ofnode_is_enabled(node));
866	ut_assertok(ofnode_set_enabled(node, true));
867	ut_asserteq(true, ofnode_is_enabled(node));
868
869	device_bind_driver_to_node(dm_root(), "usb_sandbox", "usb@2", node,
870				   &dev);
871	ut_assertok(uclass_find_device_by_seq(UCLASS_USB, 2, &dev));
872
873	/* Test string property setting */
874	ut_assert(device_is_compatible(dev, "sandbox,usb"));
875	ofnode_write_string(node, "compatible", "gdsys,super-usb");
876	ut_assert(device_is_compatible(dev, "gdsys,super-usb"));
877	ofnode_write_string(node, "compatible", "sandbox,usb");
878	ut_assert(device_is_compatible(dev, "sandbox,usb"));
879
880	/* Test setting generic properties */
881
882	/* Non-existent in DTB */
883	ut_asserteq_64(FDT_ADDR_T_NONE, dev_read_addr(dev));
884	/* reg = 0x42, size = 0x100 */
885	ut_assertok(ofnode_write_prop(node, "reg",
886				      "\x00\x00\x00\x42\x00\x00\x01\x00", 8,
887				      false));
888	ut_asserteq(0x42, dev_read_addr(dev));
889
890	/* Test disabling devices */
891	device_remove(dev, DM_REMOVE_NORMAL);
892	device_unbind(dev);
893
894	ut_assert(ofnode_is_enabled(node));
895	ut_assertok(ofnode_set_enabled(node, false));
896	ut_assert(!ofnode_is_enabled(node));
897
898	return 0;
899}
900DM_TEST(dm_test_ofnode_livetree_writing,
901	UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
902
903static int check_write_prop(struct unit_test_state *uts, ofnode node)
904{
905	char prop[] = "middle-name";
906	char name[10];
907	int len;
908
909	strcpy(name, "cecil");
910	len = strlen(name) + 1;
911	ut_assertok(ofnode_write_prop(node, prop, name, len, false));
912	ut_asserteq_str(name, ofnode_read_string(node, prop));
913
914	/* change the underlying value, this should mess up the live tree */
915	strcpy(name, "tony");
916	if (of_live_active()) {
917		ut_asserteq_str(name, ofnode_read_string(node, prop));
918	} else {
919		ut_asserteq_str("cecil", ofnode_read_string(node, prop));
920	}
921
922	/* try again, this time copying the property */
923	strcpy(name, "mary");
924	ut_assertok(ofnode_write_prop(node, prop, name, len, true));
925	ut_asserteq_str(name, ofnode_read_string(node, prop));
926	strcpy(name, "leah");
927
928	/* both flattree and livetree behave the same */
929	ut_asserteq_str("mary", ofnode_read_string(node, prop));
930
931	return 0;
932}
933
934/* writing the tree with and without copying the property */
935static int dm_test_ofnode_write_copy(struct unit_test_state *uts)
936{
937	ofnode node;
938
939	node = ofnode_path("/a-test");
940	ut_assertok(check_write_prop(uts, node));
941
942	return 0;
943}
944DM_TEST(dm_test_ofnode_write_copy, UT_TESTF_SCAN_FDT);
945
946/* test writing a property to the 'other' tree */
947static int dm_test_ofnode_write_copy_ot(struct unit_test_state *uts)
948{
949	oftree otree = get_other_oftree(uts);
950	ofnode node, check_node;
951
952	node = oftree_path(otree, "/node");
953	ut_assertok(check_write_prop(uts, node));
954
955	/* make sure the control FDT is not touched */
956	check_node = ofnode_path("/node");
957	ut_assertnull(ofnode_read_string(check_node, "middle-name"));
958
959	return 0;
960}
961DM_TEST(dm_test_ofnode_write_copy_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT);
962
963/* test ofnode_read_u32_index/default() */
964static int dm_test_ofnode_u32(struct unit_test_state *uts)
965{
966	ofnode node;
967	u32 val;
968
969	node = ofnode_path("/lcd");
970	ut_assert(ofnode_valid(node));
971	ut_asserteq(1366, ofnode_read_u32_default(node, "xres", 123));
972	ut_assertok(ofnode_write_u32(node, "xres", 1367));
973	ut_asserteq(1367, ofnode_read_u32_default(node, "xres", 123));
974	ut_assertok(ofnode_write_u32(node, "xres", 1366));
975
976	node = ofnode_path("/backlight");
977	ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 0, &val));
978	ut_asserteq(0, val);
979	ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 1, &val));
980	ut_asserteq(16, val);
981	ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 8, &val));
982	ut_asserteq(255, val);
983	ut_asserteq(-EOVERFLOW,
984		    ofnode_read_u32_index(node, "brightness-levels", 9, &val));
985	ut_asserteq(-EINVAL, ofnode_read_u32_index(node, "missing", 0, &val));
986
987	return 0;
988}
989DM_TEST(dm_test_ofnode_u32, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
990
991/* test ofnode_read_u32_array() */
992static int dm_test_ofnode_u32_array(struct unit_test_state *uts)
993{
994	ofnode node;
995	u32 val[10];
996
997	node = ofnode_path("/a-test");
998	ut_assert(ofnode_valid(node));
999	ut_assertok(ofnode_read_u32_array(node, "int-value", val, 1));
1000	ut_asserteq(-EINVAL, ofnode_read_u32_array(node, "missing", val, 1));
1001	ut_asserteq(-EOVERFLOW, ofnode_read_u32_array(node, "bool-value", val,
1002						      1));
1003
1004	memset(val, '\0', sizeof(val));
1005	ut_assertok(ofnode_read_u32_array(node, "int-array", val + 1, 3));
1006	ut_asserteq(0, val[0]);
1007	ut_asserteq(5678, val[1]);
1008	ut_asserteq(9123, val[2]);
1009	ut_asserteq(4567, val[3]);
1010	ut_asserteq(0, val[4]);
1011	ut_asserteq(-EOVERFLOW, ofnode_read_u32_array(node, "int-array", val,
1012						      4));
1013
1014	return 0;
1015}
1016DM_TEST(dm_test_ofnode_u32_array, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
1017
1018/* test ofnode_read_u64() and ofnode_write_u64() */
1019static int dm_test_ofnode_u64(struct unit_test_state *uts)
1020{
1021	ofnode node;
1022	u64 val;
1023
1024	node = ofnode_path("/a-test");
1025	ut_assert(ofnode_valid(node));
1026	ut_assertok(ofnode_read_u64(node, "int64-value", &val));
1027	ut_asserteq_64(0x1111222233334444, val);
1028	ut_assertok(ofnode_write_u64(node, "new-int64-value", 0x9876543210));
1029	ut_assertok(ofnode_read_u64(node, "new-int64-value", &val));
1030	ut_asserteq_64(0x9876543210, val);
1031
1032	ut_asserteq(-EINVAL, ofnode_read_u64(node, "missing", &val));
1033
1034	ut_assertok(ofnode_read_u64_index(node, "int64-array", 0, &val));
1035	ut_asserteq_64(0x1111222233334444, val);
1036	ut_assertok(ofnode_read_u64_index(node, "int64-array", 1, &val));
1037	ut_asserteq_64(0x4444333322221111, val);
1038	ut_asserteq(-EOVERFLOW,
1039		    ofnode_read_u64_index(node, "int64-array", 2, &val));
1040	ut_asserteq(-EINVAL, ofnode_read_u64_index(node, "missing", 0, &val));
1041
1042	ut_assertok(ofnode_write_u64(node, "int64-array", 0x9876543210));
1043	ut_assertok(ofnode_read_u64_index(node, "int64-array", 0, &val));
1044	ut_asserteq_64(0x9876543210, val);
1045	ut_asserteq(-EOVERFLOW,
1046		    ofnode_read_u64_index(node, "int64-array", 1, &val));
1047
1048	return 0;
1049}
1050DM_TEST(dm_test_ofnode_u64, UT_TESTF_SCAN_FDT);
1051
1052static int dm_test_ofnode_add_subnode(struct unit_test_state *uts)
1053{
1054	ofnode node, check, subnode;
1055	char buf[128];
1056
1057	node = ofnode_path("/lcd");
1058	ut_assert(ofnode_valid(node));
1059	ut_assertok(ofnode_add_subnode(node, "edmund", &subnode));
1060	check = ofnode_path("/lcd/edmund");
1061	ut_asserteq(subnode.of_offset, check.of_offset);
1062	ut_assertok(ofnode_get_path(subnode, buf, sizeof(buf)));
1063	ut_asserteq_str("/lcd/edmund", buf);
1064
1065	if (of_live_active()) {
1066		struct device_node *child;
1067
1068		ut_assertok(of_add_subnode((void *)ofnode_to_np(node), "edmund",
1069					   2, &child));
1070		ut_asserteq_str("ed", child->name);
1071		ut_asserteq_str("/lcd/ed", child->full_name);
1072		check = ofnode_path("/lcd/ed");
1073		ut_asserteq_ptr(child, check.np);
1074		ut_assertok(ofnode_get_path(np_to_ofnode(child), buf,
1075					    sizeof(buf)));
1076		ut_asserteq_str("/lcd/ed", buf);
1077	}
1078
1079	/* An existing node should be returned with -EEXIST */
1080	ut_asserteq(-EEXIST, ofnode_add_subnode(node, "edmund", &check));
1081	ut_asserteq(subnode.of_offset, check.of_offset);
1082
1083	/* add a root node */
1084	node = ofnode_path("/");
1085	ut_assert(ofnode_valid(node));
1086	ut_assertok(ofnode_add_subnode(node, "lcd2", &subnode));
1087	check = ofnode_path("/lcd2");
1088	ut_asserteq(subnode.of_offset, check.of_offset);
1089	ut_assertok(ofnode_get_path(subnode, buf, sizeof(buf)));
1090	ut_asserteq_str("/lcd2", buf);
1091
1092	if (of_live_active()) {
1093		ulong start;
1094		int i;
1095
1096		/*
1097		 * Make sure each of the three malloc()checks in
1098		 * of_add_subnode() work
1099		 */
1100		for (i = 0; i < 3; i++) {
1101			malloc_enable_testing(i);
1102			start = ut_check_free();
1103			ut_asserteq(-ENOMEM, ofnode_add_subnode(node, "anthony",
1104								&check));
1105			ut_assertok(ut_check_delta(start));
1106		}
1107
1108		/* This should pass since we allow 3 allocations */
1109		malloc_enable_testing(3);
1110		ut_assertok(ofnode_add_subnode(node, "anthony", &check));
1111		malloc_disable_testing();
1112	}
1113
1114	/* write to the empty node */
1115	ut_assertok(ofnode_write_string(subnode, "example", "text"));
1116
1117	return 0;
1118}
1119DM_TEST(dm_test_ofnode_add_subnode, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
1120
1121static int dm_test_ofnode_for_each_prop(struct unit_test_state *uts)
1122{
1123	ofnode node, subnode;
1124	struct ofprop prop;
1125	int count;
1126
1127	node = ofnode_path("/ofnode-foreach");
1128	count = 0;
1129
1130	/* we expect "compatible" for each node */
1131	ofnode_for_each_prop(prop, node)
1132		count++;
1133	ut_asserteq(1, count);
1134
1135	/* there are two nodes, each with 2 properties */
1136	ofnode_for_each_subnode(subnode, node)
1137		ofnode_for_each_prop(prop, subnode)
1138			count++;
1139	ut_asserteq(5, count);
1140
1141	return 0;
1142}
1143DM_TEST(dm_test_ofnode_for_each_prop, UT_TESTF_SCAN_FDT);
1144
1145static int dm_test_ofnode_by_compatible(struct unit_test_state *uts)
1146{
1147	const char *compat = "denx,u-boot-fdt-test";
1148	ofnode node;
1149	int count;
1150
1151	count = 0;
1152	for (node = ofnode_null();
1153	     node = ofnode_by_compatible(node, compat), ofnode_valid(node);)
1154		count++;
1155	ut_asserteq(11, count);
1156
1157	return 0;
1158}
1159DM_TEST(dm_test_ofnode_by_compatible, UT_TESTF_SCAN_FDT);
1160
1161/* check ofnode_by_compatible() on the 'other' tree */
1162static int dm_test_ofnode_by_compatible_ot(struct unit_test_state *uts)
1163{
1164	const char *compat = "sandbox-other2";
1165	oftree otree = get_other_oftree(uts);
1166	ofnode node;
1167	int count;
1168
1169	count = 0;
1170	for (node = oftree_root(otree);
1171	     node = ofnode_by_compatible(node, compat), ofnode_valid(node);)
1172		count++;
1173	ut_asserteq(2, count);
1174
1175	return 0;
1176}
1177DM_TEST(dm_test_ofnode_by_compatible_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT);
1178
1179static int dm_test_ofnode_find_subnode(struct unit_test_state *uts)
1180{
1181	ofnode node, subnode;
1182
1183	node = ofnode_path("/buttons");
1184
1185	subnode = ofnode_find_subnode(node, "btn1");
1186	ut_assert(ofnode_valid(subnode));
1187	ut_asserteq_str("btn1", ofnode_get_name(subnode));
1188
1189	subnode = ofnode_find_subnode(node, "btn");
1190	ut_assert(!ofnode_valid(subnode));
1191
1192	return 0;
1193}
1194DM_TEST(dm_test_ofnode_find_subnode, UT_TESTF_SCAN_FDT);
1195
1196/* test ofnode_find_subnode() on the 'other' tree */
1197static int dm_test_ofnode_find_subnode_ot(struct unit_test_state *uts)
1198{
1199	oftree otree = get_other_oftree(uts);
1200	ofnode node, subnode;
1201
1202	node = oftree_path(otree, "/node");
1203
1204	subnode = ofnode_find_subnode(node, "subnode");
1205	ut_assert(ofnode_valid(subnode));
1206	ut_asserteq_str("subnode", ofnode_get_name(subnode));
1207
1208	subnode = ofnode_find_subnode(node, "btn");
1209	ut_assert(!ofnode_valid(subnode));
1210
1211	return 0;
1212}
1213DM_TEST(dm_test_ofnode_find_subnode_ot, UT_TESTF_OTHER_FDT);
1214
1215static int dm_test_ofnode_get_name(struct unit_test_state *uts)
1216{
1217	ofnode node;
1218
1219	node = ofnode_path("/buttons");
1220	ut_assert(ofnode_valid(node));
1221	ut_asserteq_str("buttons", ofnode_get_name(node));
1222	ut_asserteq_str("", ofnode_get_name(ofnode_root()));
1223
1224	return 0;
1225}
1226DM_TEST(dm_test_ofnode_get_name, UT_TESTF_SCAN_FDT);
1227
1228/* try to access more FDTs than is supported */
1229static int dm_test_ofnode_too_many(struct unit_test_state *uts)
1230{
1231	const int max_trees = CONFIG_IS_ENABLED(OFNODE_MULTI_TREE,
1232					(CONFIG_OFNODE_MULTI_TREE_MAX), (1));
1233	const int fdt_size = 256;
1234	const int num_trees = max_trees + 1;
1235	char fdt[num_trees][fdt_size];
1236	int i;
1237
1238	for (i = 0; i < num_trees; i++) {
1239		oftree tree;
1240		int ret;
1241
1242		ut_assertok(make_ofnode_fdt(uts, fdt[i], fdt_size, i));
1243		ret = get_oftree(uts, fdt[i], &tree);
1244
1245		/*
1246		 * With flat tree we have the control FDT using one slot. Live
1247		 * tree has no limit since it uses pointers, not integer tree
1248		 * IDs
1249		 */
1250		if (of_live_active() || i < max_trees - 1) {
1251			ut_assertok(ret);
1252		} else {
1253			/*
1254			 * tree should be invalid when we try to register too
1255			 * many trees
1256			 */
1257			ut_asserteq(-EOVERFLOW, ret);
1258		}
1259	}
1260
1261	return 0;
1262}
1263DM_TEST(dm_test_ofnode_too_many, UT_TESTF_SCAN_FDT);
1264
1265static int check_copy_props(struct unit_test_state *uts, ofnode dst, ofnode src)
1266{
1267	u32 reg[2], val;
1268
1269	ut_assertok(ofnode_copy_props(dst, src));
1270
1271	ut_assertok(ofnode_read_u32(dst, "ping-expect", &val));
1272	ut_asserteq(3, val);
1273
1274	ut_asserteq_str("denx,u-boot-fdt-test",
1275			ofnode_read_string(dst, "compatible"));
1276
1277	/* check that a property with the same name is overwritten */
1278	ut_assertok(ofnode_read_u32_array(dst, "reg", reg, ARRAY_SIZE(reg)));
1279	ut_asserteq(3, reg[0]);
1280	ut_asserteq(1, reg[1]);
1281
1282	/* reset the compatible so the live tree does not change */
1283	ut_assertok(ofnode_write_string(dst, "compatible", "nothing"));
1284
1285	return 0;
1286}
1287
1288static int dm_test_ofnode_copy_props(struct unit_test_state *uts)
1289{
1290	ofnode src, dst;
1291
1292	/*
1293	 * These nodes are chosen so that the src node is before the destination
1294	 * node in the tree. This doesn't matter with livetree, but with
1295	 * flattree any attempt to insert a property earlier in the tree will
1296	 * mess up the offsets after it.
1297	 */
1298	src = ofnode_path("/b-test");
1299	dst = ofnode_path("/some-bus");
1300
1301	ut_assertok(check_copy_props(uts, dst, src));
1302
1303	/* check a property that is in the destination already */
1304	ut_asserteq_str("mux0", ofnode_read_string(dst, "mux-control-names"));
1305
1306	return 0;
1307}
1308DM_TEST(dm_test_ofnode_copy_props, UT_TESTF_SCAN_FDT);
1309
1310/* test ofnode_copy_props() with the 'other' tree */
1311static int dm_test_ofnode_copy_props_ot(struct unit_test_state *uts)
1312{
1313	ofnode src, dst;
1314	oftree otree = get_other_oftree(uts);
1315
1316	src = ofnode_path("/b-test");
1317	dst = oftree_path(otree, "/node/subnode2");
1318	ut_assertok(check_copy_props(uts, dst, src));
1319
1320	return 0;
1321}
1322DM_TEST(dm_test_ofnode_copy_props_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT);
1323
1324/* check that the livetree is aligned to a structure boundary */
1325static int dm_test_livetree_align(struct unit_test_state *uts)
1326{
1327	const int align = __alignof__(struct unit_test_state);
1328	struct device_node *node;
1329	u32 *sentinel;
1330	ulong start;
1331
1332	start = (ulong)gd_of_root();
1333	ut_asserteq(start, ALIGN(start, align));
1334
1335	node = gd_of_root();
1336	sentinel = (void *)node - sizeof(u32);
1337
1338	/*
1339	 * The sentinel should be overwritten with the root node. If it isn't,
1340	 * then the root node is not at the very start of the livetree memory
1341	 * area, and free(root) will fail to free the memory used by the
1342	 * livetree.
1343	 */
1344	ut_assert(*sentinel != BAD_OF_ROOT);
1345
1346	return 0;
1347}
1348DM_TEST(dm_test_livetree_align, UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_TREE);
1349
1350/* check that it is possible to load an arbitrary livetree */
1351static int dm_test_livetree_ensure(struct unit_test_state *uts)
1352{
1353	oftree tree;
1354	ofnode node;
1355
1356	/* read from other.dtb */
1357	ut_assertok(test_load_other_fdt(uts));
1358	tree = oftree_from_fdt(uts->other_fdt);
1359	ut_assert(oftree_valid(tree));
1360	node = oftree_path(tree, "/node/subnode");
1361	ut_assert(ofnode_valid(node));
1362	ut_asserteq_str("sandbox-other2",
1363			ofnode_read_string(node, "compatible"));
1364
1365	return 0;
1366}
1367DM_TEST(dm_test_livetree_ensure, UT_TESTF_SCAN_FDT);
1368
1369static int dm_test_oftree_new(struct unit_test_state *uts)
1370{
1371	ofnode node, subnode, check;
1372	oftree tree;
1373
1374	ut_assertok(oftree_new(&tree));
1375	node = oftree_root(tree);
1376	ut_assert(ofnode_valid(node));
1377	ut_assertok(ofnode_add_subnode(node, "edmund", &subnode));
1378	check = ofnode_find_subnode(node, "edmund");
1379	ut_asserteq(check.of_offset, subnode.of_offset);
1380
1381	return 0;
1382}
1383DM_TEST(dm_test_oftree_new, UT_TESTF_SCAN_FDT);
1384
1385static int check_copy_node(struct unit_test_state *uts, ofnode dst, ofnode src,
1386			   ofnode *nodep)
1387{
1388	u32 reg[2], val;
1389	ofnode node;
1390
1391	ut_assertok(ofnode_copy_node(dst, "copy-test", src, &node));
1392
1393	ut_assertok(ofnode_read_u32(node, "ping-expect", &val));
1394	ut_asserteq(3, val);
1395
1396	ut_asserteq_str("denx,u-boot-fdt-test",
1397			ofnode_read_string(node, "compatible"));
1398
1399	/* check that a property with the same name is overwritten */
1400	ut_assertok(ofnode_read_u32_array(node, "reg", reg, ARRAY_SIZE(reg)));
1401	ut_asserteq(3, reg[0]);
1402	ut_asserteq(1, reg[1]);
1403
1404	/* reset the compatible so the live tree does not change */
1405	ut_assertok(ofnode_write_string(node, "compatible", "nothing"));
1406	*nodep = node;
1407
1408	return 0;
1409}
1410
1411static int dm_test_ofnode_copy_node(struct unit_test_state *uts)
1412{
1413	ofnode src, dst, node, try;
1414
1415	/*
1416	 * These nodes are chosen so that the src node is before the destination
1417	 * node in the tree. This doesn't matter with livetree, but with
1418	 * flattree any attempt to insert a property earlier in the tree will
1419	 * mess up the offsets after it.
1420	 */
1421	src = ofnode_path("/b-test");
1422	dst = ofnode_path("/some-bus");
1423
1424	ut_assertok(check_copy_node(uts, dst, src, &node));
1425
1426	/* check trying to copy over an existing node */
1427	ut_asserteq(-EEXIST, ofnode_copy_node(dst, "copy-test", src, &try));
1428	ut_asserteq(try.of_offset, node.of_offset);
1429
1430	return 0;
1431}
1432DM_TEST(dm_test_ofnode_copy_node, UT_TESTF_SCAN_FDT);
1433
1434/* test ofnode_copy_node() with the 'other' tree */
1435static int dm_test_ofnode_copy_node_ot(struct unit_test_state *uts)
1436{
1437	oftree otree = get_other_oftree(uts);
1438	ofnode src, dst, node;
1439
1440	src = ofnode_path("/b-test");
1441	dst = oftree_path(otree, "/node/subnode2");
1442	ut_assertok(check_copy_node(uts, dst, src, &node));
1443
1444	return 0;
1445}
1446DM_TEST(dm_test_ofnode_copy_node_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT);
1447
1448static int dm_test_ofnode_delete(struct unit_test_state *uts)
1449{
1450	ofnode node;
1451
1452	/*
1453	 * At present the livetree is not restored after changes made in tests.
1454	 * See test_pre_run() for how this is done with the other FDT and
1455	 * dm_test_pre_run() where it sets up the root-tree pointer. So use
1456	 * nodes which don't matter to other tests.
1457	 *
1458	 * We could fix this by detecting livetree changes and regenerating it
1459	 * before the next test if needed.
1460	 */
1461	node = ofnode_path("/leds/iracibble");
1462	ut_assert(ofnode_valid(node));
1463	ut_assertok(ofnode_delete(&node));
1464	ut_assert(!ofnode_valid(node));
1465	ut_assert(!ofnode_valid(ofnode_path("/leds/iracibble")));
1466
1467	node = ofnode_path("/leds/default_on");
1468	ut_assert(ofnode_valid(node));
1469	ut_assertok(ofnode_delete(&node));
1470	ut_assert(!ofnode_valid(node));
1471	ut_assert(!ofnode_valid(ofnode_path("/leds/default_on")));
1472
1473	ut_asserteq(2, ofnode_get_child_count(ofnode_path("/leds")));
1474
1475	return 0;
1476}
1477DM_TEST(dm_test_ofnode_delete, UT_TESTF_SCAN_FDT);
1478
1479static int dm_test_oftree_to_fdt(struct unit_test_state *uts)
1480{
1481	oftree tree, check;
1482	struct abuf buf, buf2;
1483
1484	tree = oftree_default();
1485	ut_assertok(oftree_to_fdt(tree, &buf));
1486	ut_assert(abuf_size(&buf) > SZ_16K);
1487
1488	/* convert it back to a tree and see if it looks OK */
1489	check = oftree_from_fdt(abuf_data(&buf));
1490	ut_assert(oftree_valid(check));
1491
1492	ut_assertok(oftree_to_fdt(check, &buf2));
1493	ut_assert(abuf_size(&buf2) > SZ_16K);
1494	ut_asserteq(abuf_size(&buf), abuf_size(&buf2));
1495	ut_asserteq_mem(abuf_data(&buf), abuf_data(&buf2), abuf_size(&buf));
1496
1497	return 0;
1498}
1499DM_TEST(dm_test_oftree_to_fdt, UT_TESTF_SCAN_FDT);
1500
1501/* test ofnode_read_bool() and ofnode_write_bool() */
1502static int dm_test_bool(struct unit_test_state *uts)
1503{
1504	const char *propname = "missing-bool-value";
1505	ofnode node;
1506
1507	node = ofnode_path("/a-test");
1508	ut_assert(ofnode_read_bool(node, "bool-value"));
1509	ut_assert(!ofnode_read_bool(node, propname));
1510	ut_assert(!ofnode_has_property(node, propname));
1511
1512	ut_assertok(ofnode_write_bool(node, propname, true));
1513	ut_assert(ofnode_read_bool(node, propname));
1514	ut_assert(ofnode_has_property(node, propname));
1515	ut_assert(ofnode_read_bool(node, "bool-value"));
1516
1517	ut_assertok(ofnode_write_bool(node, propname, false));
1518	ut_assert(!ofnode_read_bool(node, propname));
1519	ut_assert(!ofnode_has_property(node, propname));
1520	ut_assert(ofnode_read_bool(node, "bool-value"));
1521
1522	return 0;
1523}
1524DM_TEST(dm_test_bool, UT_TESTF_SCAN_FDT);
1525