blob: f16b643fa3f68de4a1b22c047f4a409ae2dc4eb7 [file] [log] [blame]
Masahiro Yamadab4f2dda2018-04-27 01:02:02 +09001// SPDX-License-Identifier: GPL-2.0+
Simon Glassf912a722022-09-06 20:27:27 -06002/*
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 */
Masahiro Yamadab4f2dda2018-04-27 01:02:02 +090018
Simon Glassebbe90b2023-09-26 08:14:43 -060019#include <abuf.h>
Masahiro Yamadab4f2dda2018-04-27 01:02:02 +090020#include <dm.h>
Simon Glass0f2af882020-05-10 11:40:05 -060021#include <log.h>
Simon Glassef75c592022-07-30 15:52:08 -060022#include <of_live.h>
Simon Glass270a4432022-07-30 15:52:09 -060023#include <dm/device-internal.h>
24#include <dm/lists.h>
Simon Glass699c9ca2018-10-01 12:22:08 -060025#include <dm/of_extra.h>
Simon Glass270a4432022-07-30 15:52:09 -060026#include <dm/root.h>
Masahiro Yamadab4f2dda2018-04-27 01:02:02 +090027#include <dm/test.h>
Simon Glass270a4432022-07-30 15:52:09 -060028#include <dm/uclass-internal.h>
Simon Glassebbe90b2023-09-26 08:14:43 -060029#include <linux/sizes.h>
Simon Glass75c4d412020-07-19 10:15:37 -060030#include <test/test.h>
Masahiro Yamadab4f2dda2018-04-27 01:02:02 +090031#include <test/ut.h>
32
Simon Glassf912a722022-09-06 20:27:27 -060033/**
34 * get_other_oftree() - Convert a flat tree into an oftree object
35 *
36 * @uts: Test state
37 * @return: oftree object for the 'other' FDT (see sandbox' other.dts)
38 */
39oftree get_other_oftree(struct unit_test_state *uts)
40{
41 oftree tree;
42
43 if (of_live_active())
44 tree = oftree_from_np(uts->of_other);
45 else
46 tree = oftree_from_fdt(uts->other_fdt);
47
48 /* An invalid tree may cause failure or crashes */
49 if (!oftree_valid(tree))
Simon Glass1a92f832024-08-22 07:57:48 -060050 ut_reportf("test needs the UTF_OTHER_FDT flag");
Simon Glassf912a722022-09-06 20:27:27 -060051
52 return tree;
53}
54
Simon Glassdad97512022-09-06 20:27:29 -060055/**
56 * get_oftree() - Convert a flat tree into an oftree object
57 *
58 * @uts: Test state
59 * @fdt: Pointer to flat tree
60 * @treep: Returns the tree, on success
61 * Return: 0 if OK, 1 if the tree failed to unflatten, -EOVERFLOW if there are
62 * too many flat trees to allow another one to be registers (see
63 * oftree_ensure())
64 */
65int get_oftree(struct unit_test_state *uts, void *fdt, oftree *treep)
66{
67 oftree tree;
68
69 if (of_live_active()) {
70 struct device_node *root;
71
72 ut_assertok(unflatten_device_tree(fdt, &root));
73 tree = oftree_from_np(root);
74 } else {
75 tree = oftree_from_fdt(fdt);
76 if (!oftree_valid(tree))
77 return -EOVERFLOW;
78 }
79 *treep = tree;
80
81 return 0;
82}
83
84/**
85 * free_oftree() - Free memory used by get_oftree()
86 *
87 * @tree: Tree to free
88 */
89void free_oftree(oftree tree)
90{
91 if (of_live_active())
92 free(tree.np);
93}
94
Simon Glass75b8a872023-09-26 08:14:39 -060095/* test ofnode_device_is_compatible() */
Masahiro Yamadab4f2dda2018-04-27 01:02:02 +090096static int dm_test_ofnode_compatible(struct unit_test_state *uts)
97{
98 ofnode root_node = ofnode_path("/");
99
100 ut_assert(ofnode_valid(root_node));
101 ut_assert(ofnode_device_is_compatible(root_node, "sandbox"));
102
103 return 0;
104}
Simon Glass9e7a42a2022-09-06 20:27:30 -0600105DM_TEST(dm_test_ofnode_compatible,
Simon Glass1a92f832024-08-22 07:57:48 -0600106 UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -0600107
108/* check ofnode_device_is_compatible() with the 'other' FDT */
109static int dm_test_ofnode_compatible_ot(struct unit_test_state *uts)
110{
111 oftree otree = get_other_oftree(uts);
112 ofnode oroot = oftree_root(otree);
113
114 ut_assert(ofnode_valid(oroot));
115 ut_assert(ofnode_device_is_compatible(oroot, "sandbox-other"));
116
117 return 0;
118}
Simon Glass1a92f832024-08-22 07:57:48 -0600119DM_TEST(dm_test_ofnode_compatible_ot, UTF_SCAN_FDT | UTF_OTHER_FDT);
Jens Wiklanderd9fd0ac2018-08-20 11:10:00 +0200120
Patrick Delaunay04fcfe72020-09-24 17:26:20 +0200121static int dm_test_ofnode_get_by_phandle(struct unit_test_state *uts)
122{
123 /* test invalid phandle */
124 ut_assert(!ofnode_valid(ofnode_get_by_phandle(0)));
125 ut_assert(!ofnode_valid(ofnode_get_by_phandle(-1)));
126
127 /* test first valid phandle */
128 ut_assert(ofnode_valid(ofnode_get_by_phandle(1)));
129
130 /* test unknown phandle */
131 ut_assert(!ofnode_valid(ofnode_get_by_phandle(0x1000000)));
132
Simon Glass95fd2092022-09-06 20:27:22 -0600133 ut_assert(ofnode_valid(oftree_get_by_phandle(oftree_default(), 1)));
134
Patrick Delaunay04fcfe72020-09-24 17:26:20 +0200135 return 0;
136}
Simon Glass1a92f832024-08-22 07:57:48 -0600137DM_TEST(dm_test_ofnode_get_by_phandle, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Patrick Delaunay04fcfe72020-09-24 17:26:20 +0200138
Simon Glass75b8a872023-09-26 08:14:39 -0600139/* test oftree_get_by_phandle() with a the 'other' oftree */
Simon Glassf912a722022-09-06 20:27:27 -0600140static int dm_test_ofnode_get_by_phandle_ot(struct unit_test_state *uts)
141{
142 oftree otree = get_other_oftree(uts);
143 ofnode node;
Christian Marangi7d75d202024-11-10 12:50:21 +0100144 u32 idx;
145 int ret;
146
147 node = oftree_path(otree, "/node");
148 ut_assert(ofnode_valid(node));
149
150 ret = ofnode_read_u32(node, "other-phandle", &idx);
151 ut_assertok(ret);
Simon Glassf912a722022-09-06 20:27:27 -0600152
Christian Marangi7d75d202024-11-10 12:50:21 +0100153 node = oftree_get_by_phandle(otree, idx);
Simon Glassf912a722022-09-06 20:27:27 -0600154 ut_assert(ofnode_valid(node));
155 ut_asserteq_str("target", ofnode_get_name(node));
156
157 return 0;
158}
Simon Glassdb6d8722023-09-26 08:14:38 -0600159DM_TEST(dm_test_ofnode_get_by_phandle_ot,
Simon Glass1a92f832024-08-22 07:57:48 -0600160 UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glassf912a722022-09-06 20:27:27 -0600161
Simon Glass9e7a42a2022-09-06 20:27:30 -0600162static int check_prop_values(struct unit_test_state *uts, ofnode start,
163 const char *propname, const char *propval,
164 int expect_count)
Jens Wiklanderd9fd0ac2018-08-20 11:10:00 +0200165{
Simon Glass9e7a42a2022-09-06 20:27:30 -0600166 int proplen = strlen(propval) + 1;
Jens Wiklanderd9fd0ac2018-08-20 11:10:00 +0200167 const char *str;
Simon Glass9e7a42a2022-09-06 20:27:30 -0600168 ofnode node;
169 int count;
Jens Wiklanderd9fd0ac2018-08-20 11:10:00 +0200170
171 /* Find first matching node, there should be at least one */
Simon Glass9e7a42a2022-09-06 20:27:30 -0600172 node = ofnode_by_prop_value(start, propname, propval, proplen);
Jens Wiklanderd9fd0ac2018-08-20 11:10:00 +0200173 ut_assert(ofnode_valid(node));
174 str = ofnode_read_string(node, propname);
175 ut_assert(str && !strcmp(str, propval));
176
177 /* Find the rest of the matching nodes */
Simon Glass9e7a42a2022-09-06 20:27:30 -0600178 count = 1;
Jens Wiklanderd9fd0ac2018-08-20 11:10:00 +0200179 while (true) {
Simon Glass9e7a42a2022-09-06 20:27:30 -0600180 node = ofnode_by_prop_value(node, propname, propval, proplen);
Jens Wiklanderd9fd0ac2018-08-20 11:10:00 +0200181 if (!ofnode_valid(node))
182 break;
183 str = ofnode_read_string(node, propname);
Simon Glass9e7a42a2022-09-06 20:27:30 -0600184 ut_asserteq_str(propval, str);
185 count++;
Jens Wiklanderd9fd0ac2018-08-20 11:10:00 +0200186 }
Simon Glass9e7a42a2022-09-06 20:27:30 -0600187 ut_asserteq(expect_count, count);
188
189 return 0;
190}
191
192static int dm_test_ofnode_by_prop_value(struct unit_test_state *uts)
193{
194 ut_assertok(check_prop_values(uts, ofnode_null(), "compatible",
195 "denx,u-boot-fdt-test", 11));
Jens Wiklanderd9fd0ac2018-08-20 11:10:00 +0200196
197 return 0;
198}
Simon Glass1a92f832024-08-22 07:57:48 -0600199DM_TEST(dm_test_ofnode_by_prop_value, UTF_SCAN_FDT);
Simon Glass699c9ca2018-10-01 12:22:08 -0600200
Simon Glass75b8a872023-09-26 08:14:39 -0600201/* test ofnode_by_prop_value() with a the 'other' oftree */
Simon Glass9e7a42a2022-09-06 20:27:30 -0600202static int dm_test_ofnode_by_prop_value_ot(struct unit_test_state *uts)
203{
204 oftree otree = get_other_oftree(uts);
205
206 ut_assertok(check_prop_values(uts, oftree_root(otree), "str-prop",
207 "other", 2));
208
209 return 0;
210}
Simon Glassdb6d8722023-09-26 08:14:38 -0600211DM_TEST(dm_test_ofnode_by_prop_value_ot,
Simon Glass1a92f832024-08-22 07:57:48 -0600212 UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -0600213
Simon Glass75b8a872023-09-26 08:14:39 -0600214/* test ofnode_read_fmap_entry() */
Simon Glass699c9ca2018-10-01 12:22:08 -0600215static int dm_test_ofnode_fmap(struct unit_test_state *uts)
216{
217 struct fmap_entry entry;
218 ofnode node;
219
220 node = ofnode_path("/cros-ec/flash");
221 ut_assert(ofnode_valid(node));
222 ut_assertok(ofnode_read_fmap_entry(node, &entry));
223 ut_asserteq(0x08000000, entry.offset);
224 ut_asserteq(0x20000, entry.length);
225
226 return 0;
227}
Simon Glass1a92f832024-08-22 07:57:48 -0600228DM_TEST(dm_test_ofnode_fmap, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glassf3455962020-01-27 08:49:43 -0700229
Simon Glass75b8a872023-09-26 08:14:39 -0600230/* test ofnode_read_prop() */
Simon Glass0c2e9802020-01-27 08:49:44 -0700231static int dm_test_ofnode_read(struct unit_test_state *uts)
232{
233 const u32 *val;
234 ofnode node;
235 int size;
236
Simon Glass310487d2023-09-26 08:14:46 -0600237 node = oftree_path(oftree_default(), "/");
238 ut_assert(ofnode_valid(node));
239
Simon Glass0c2e9802020-01-27 08:49:44 -0700240 node = ofnode_path("/a-test");
241 ut_assert(ofnode_valid(node));
242
243 val = ofnode_read_prop(node, "int-value", &size);
244 ut_assertnonnull(val);
245 ut_asserteq(4, size);
246 ut_asserteq(1234, fdt32_to_cpu(val[0]));
247
248 val = ofnode_read_prop(node, "missing", &size);
249 ut_assertnull(val);
250 ut_asserteq(-FDT_ERR_NOTFOUND, size);
251
252 /* Check it works without a size parameter */
253 val = ofnode_read_prop(node, "missing", NULL);
254 ut_assertnull(val);
255
256 return 0;
257}
Simon Glass1a92f832024-08-22 07:57:48 -0600258DM_TEST(dm_test_ofnode_read, UTF_SCAN_FDT);
Simon Glass0c2e9802020-01-27 08:49:44 -0700259
Simon Glass75b8a872023-09-26 08:14:39 -0600260/* test ofnode_read_prop() with the 'other' tree */
Simon Glass9e7a42a2022-09-06 20:27:30 -0600261static int dm_test_ofnode_read_ot(struct unit_test_state *uts)
262{
263 oftree otree = get_other_oftree(uts);
264 const char *val;
265 ofnode node;
266 int size;
267
Simon Glass310487d2023-09-26 08:14:46 -0600268 node = oftree_path(otree, "/");
269 ut_assert(ofnode_valid(node));
270
Simon Glass9e7a42a2022-09-06 20:27:30 -0600271 node = oftree_path(otree, "/node/subnode");
272 ut_assert(ofnode_valid(node));
273
274 val = ofnode_read_prop(node, "str-prop", &size);
275 ut_assertnonnull(val);
276 ut_asserteq_str("other", val);
277 ut_asserteq(6, size);
278
279 return 0;
280}
Simon Glass1a92f832024-08-22 07:57:48 -0600281DM_TEST(dm_test_ofnode_read_ot, UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -0600282
Christian Marangia1a1e0e2024-11-10 12:50:23 +0100283/* test ofnode_count_/parse/_phandle_with_args() */
Patrick Delaunay8cd28012020-09-25 09:41:16 +0200284static int dm_test_ofnode_phandle(struct unit_test_state *uts)
285{
286 struct ofnode_phandle_args args;
Christian Marangia1a1e0e2024-11-10 12:50:23 +0100287 ofnode node, phandle, target;
Patrick Delaunay8cd28012020-09-25 09:41:16 +0200288 int ret;
289 const char prop[] = "test-gpios";
290 const char cell[] = "#gpio-cells";
291 const char prop2[] = "phandle-value";
Christian Marangia1a1e0e2024-11-10 12:50:23 +0100292 const char prop3[] = "phandle-nodes";
Patrick Delaunay8cd28012020-09-25 09:41:16 +0200293
294 node = ofnode_path("/a-test");
295 ut_assert(ofnode_valid(node));
296
297 /* Test ofnode_count_phandle_with_args with cell name */
298 ret = ofnode_count_phandle_with_args(node, "missing", cell, 0);
299 ut_asserteq(-ENOENT, ret);
300 ret = ofnode_count_phandle_with_args(node, prop, "#invalid", 0);
301 ut_asserteq(-EINVAL, ret);
302 ret = ofnode_count_phandle_with_args(node, prop, cell, 0);
303 ut_asserteq(5, ret);
304
305 /* Test ofnode_parse_phandle_with_args with cell name */
306 ret = ofnode_parse_phandle_with_args(node, "missing", cell, 0, 0,
307 &args);
308 ut_asserteq(-ENOENT, ret);
309 ret = ofnode_parse_phandle_with_args(node, prop, "#invalid", 0, 0,
310 &args);
311 ut_asserteq(-EINVAL, ret);
312 ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 0, &args);
313 ut_assertok(ret);
314 ut_asserteq(1, args.args_count);
315 ut_asserteq(1, args.args[0]);
316 ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 1, &args);
317 ut_assertok(ret);
318 ut_asserteq(1, args.args_count);
319 ut_asserteq(4, args.args[0]);
320 ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 2, &args);
321 ut_assertok(ret);
322 ut_asserteq(5, args.args_count);
323 ut_asserteq(5, args.args[0]);
324 ut_asserteq(1, args.args[4]);
325 ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 3, &args);
326 ut_asserteq(-ENOENT, ret);
327 ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 4, &args);
328 ut_assertok(ret);
329 ut_asserteq(1, args.args_count);
330 ut_asserteq(12, args.args[0]);
331 ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 5, &args);
332 ut_asserteq(-ENOENT, ret);
333
334 /* Test ofnode_count_phandle_with_args with cell count */
335 ret = ofnode_count_phandle_with_args(node, "missing", NULL, 2);
336 ut_asserteq(-ENOENT, ret);
337 ret = ofnode_count_phandle_with_args(node, prop2, NULL, 1);
338 ut_asserteq(3, ret);
339
340 /* Test ofnode_parse_phandle_with_args with cell count */
341 ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 0, &args);
342 ut_assertok(ret);
343 ut_asserteq(1, ofnode_valid(args.node));
344 ut_asserteq(1, args.args_count);
345 ut_asserteq(10, args.args[0]);
346 ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 1, &args);
347 ut_asserteq(-EINVAL, ret);
348 ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 2, &args);
349 ut_assertok(ret);
350 ut_asserteq(1, ofnode_valid(args.node));
351 ut_asserteq(1, args.args_count);
352 ut_asserteq(30, args.args[0]);
353 ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 3, &args);
354 ut_asserteq(-ENOENT, ret);
355
Christian Marangia1a1e0e2024-11-10 12:50:23 +0100356 /* Test ofnode_parse_phandle */
357 phandle = ofnode_parse_phandle(node, "missing", 0);
358 ut_assert(ofnode_equal(ofnode_null(), phandle));
359
360 target = ofnode_path("/phandle-node-1");
361 ut_assert(ofnode_valid(target));
362 phandle = ofnode_parse_phandle(node, prop3, 0);
363 ut_assert(ofnode_equal(target, phandle));
364
365 target = ofnode_path("/phandle-node-2");
366 ut_assert(ofnode_valid(target));
367 phandle = ofnode_parse_phandle(node, prop3, 1);
368 ut_assert(ofnode_equal(target, phandle));
369
370 phandle = ofnode_parse_phandle(node, prop3, 3);
371 ut_assert(ofnode_equal(ofnode_null(), phandle));
372
Patrick Delaunay8cd28012020-09-25 09:41:16 +0200373 return 0;
374}
Simon Glass1a92f832024-08-22 07:57:48 -0600375DM_TEST(dm_test_ofnode_phandle, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Patrick Delaunay8cd28012020-09-25 09:41:16 +0200376
Christian Marangia1a1e0e2024-11-10 12:50:23 +0100377/* test oftree_count_/parse/_phandle_with_args() with 'other' tree */
Simon Glassf912a722022-09-06 20:27:27 -0600378static int dm_test_ofnode_phandle_ot(struct unit_test_state *uts)
379{
380 oftree otree = get_other_oftree(uts);
381 struct ofnode_phandle_args args;
Christian Marangia1a1e0e2024-11-10 12:50:23 +0100382 ofnode node, phandle, target;
Simon Glassf912a722022-09-06 20:27:27 -0600383 int ret;
Christian Marangi7d75d202024-11-10 12:50:21 +0100384 const char prop[] = "other-test-gpios";
385 const char cell[] = "#gpio-cells";
386 const char prop2[] = "other-phandle-value";
Christian Marangia1a1e0e2024-11-10 12:50:23 +0100387 const char prop3[] = "other-phandle-nodes";
Simon Glassf912a722022-09-06 20:27:27 -0600388
Christian Marangi7d75d202024-11-10 12:50:21 +0100389 node = oftree_path(otree, "/other-a-test");
390 ut_assert(ofnode_valid(node));
Simon Glassf912a722022-09-06 20:27:27 -0600391
Christian Marangi7d75d202024-11-10 12:50:21 +0100392 /* Test oftree_count_phandle_with_args with cell name */
393 ret = oftree_count_phandle_with_args(otree, node, "missing", cell, 0);
Simon Glassf912a722022-09-06 20:27:27 -0600394 ut_asserteq(-ENOENT, ret);
Christian Marangi7d75d202024-11-10 12:50:21 +0100395 ret = oftree_count_phandle_with_args(otree, node, prop, "#invalid", 0);
Simon Glassf912a722022-09-06 20:27:27 -0600396 ut_asserteq(-EINVAL, ret);
Christian Marangi7d75d202024-11-10 12:50:21 +0100397 ret = oftree_count_phandle_with_args(otree, node, prop, cell, 0);
398 ut_asserteq(5, ret);
Simon Glassf912a722022-09-06 20:27:27 -0600399
Christian Marangi7d75d202024-11-10 12:50:21 +0100400 /* Test oftree_parse_phandle_with_args with cell name */
401 ret = oftree_parse_phandle_with_args(otree, node, "missing", cell, 0, 0,
402 &args);
403 ut_asserteq(-ENOENT, ret);
404 ret = oftree_parse_phandle_with_args(otree, node, prop, "#invalid", 0, 0,
405 &args);
406 ut_asserteq(-EINVAL, ret);
407 ret = oftree_parse_phandle_with_args(otree, node, prop, cell, 0, 0, &args);
Simon Glassf912a722022-09-06 20:27:27 -0600408 ut_assertok(ret);
Christian Marangi7d75d202024-11-10 12:50:21 +0100409 ut_asserteq(1, args.args_count);
410 ut_asserteq(1, args.args[0]);
411 ret = oftree_parse_phandle_with_args(otree, node, prop, cell, 0, 1, &args);
412 ut_assertok(ret);
413 ut_asserteq(1, args.args_count);
414 ut_asserteq(4, args.args[0]);
415 ret = oftree_parse_phandle_with_args(otree, node, prop, cell, 0, 2, &args);
416 ut_assertok(ret);
417 ut_asserteq(5, args.args_count);
418 ut_asserteq(5, args.args[0]);
419 ut_asserteq(1, args.args[4]);
420 ret = oftree_parse_phandle_with_args(otree, node, prop, cell, 0, 3, &args);
421 ut_asserteq(-ENOENT, ret);
422 ret = oftree_parse_phandle_with_args(otree, node, prop, cell, 0, 4, &args);
423 ut_assertok(ret);
424 ut_asserteq(1, args.args_count);
425 ut_asserteq(12, args.args[0]);
426 ret = oftree_parse_phandle_with_args(otree, node, prop, cell, 0, 5, &args);
427 ut_asserteq(-ENOENT, ret);
428
429 /* Test oftree_count_phandle_with_args with cell count */
430 ret = oftree_count_phandle_with_args(otree, node, "missing", NULL, 2);
431 ut_asserteq(-ENOENT, ret);
432 ret = oftree_count_phandle_with_args(otree, node, prop2, NULL, 1);
433 ut_asserteq(3, ret);
434
435 /* Test oftree_parse_phandle_with_args with cell count */
436 ret = oftree_parse_phandle_with_args(otree, node, prop2, NULL, 1, 0, &args);
437 ut_assertok(ret);
438 ut_asserteq(1, ofnode_valid(args.node));
439 ut_asserteq(1, args.args_count);
440 ut_asserteq(10, args.args[0]);
441 ret = oftree_parse_phandle_with_args(otree, node, prop2, NULL, 1, 1, &args);
442 ut_asserteq(-EINVAL, ret);
443 ret = oftree_parse_phandle_with_args(otree, node, prop2, NULL, 1, 2, &args);
444 ut_assertok(ret);
445 ut_asserteq(1, ofnode_valid(args.node));
446 ut_asserteq(1, args.args_count);
447 ut_asserteq(30, args.args[0]);
448 ret = oftree_parse_phandle_with_args(otree, node, prop2, NULL, 1, 3, &args);
449 ut_asserteq(-ENOENT, ret);
Simon Glassf912a722022-09-06 20:27:27 -0600450
Christian Marangia1a1e0e2024-11-10 12:50:23 +0100451 /* Test oftree_parse_phandle */
452 phandle = oftree_parse_phandle(otree, node, "missing", 0);
453 ut_assert(ofnode_equal(ofnode_null(), phandle));
454
455 target = oftree_path(otree, "/other-phandle-node-1");
456 ut_assert(ofnode_valid(target));
457 phandle = oftree_parse_phandle(otree, node, prop3, 0);
458 ut_assert(ofnode_equal(target, phandle));
459
460 target = oftree_path(otree, "/other-phandle-node-2");
461 ut_assert(ofnode_valid(target));
462 phandle = oftree_parse_phandle(otree, node, prop3, 1);
463 ut_assert(ofnode_equal(target, phandle));
464
465 phandle = oftree_parse_phandle(otree, node, prop3, 3);
466 ut_assert(ofnode_equal(ofnode_null(), phandle));
467
Simon Glassf912a722022-09-06 20:27:27 -0600468 return 0;
469}
Simon Glass1a92f832024-08-22 07:57:48 -0600470DM_TEST(dm_test_ofnode_phandle_ot, UTF_OTHER_FDT);
Simon Glassf912a722022-09-06 20:27:27 -0600471
Simon Glass75b8a872023-09-26 08:14:39 -0600472/* test ofnode_read_chosen_string/node/prop() */
Simon Glassf3455962020-01-27 08:49:43 -0700473static int dm_test_ofnode_read_chosen(struct unit_test_state *uts)
474{
475 const char *str;
Simon Glasse09223c2020-01-27 08:49:46 -0700476 const u32 *val;
Simon Glassf3455962020-01-27 08:49:43 -0700477 ofnode node;
Simon Glasse09223c2020-01-27 08:49:46 -0700478 int size;
Simon Glassf3455962020-01-27 08:49:43 -0700479
480 str = ofnode_read_chosen_string("setting");
481 ut_assertnonnull(str);
482 ut_asserteq_str("sunrise ohoka", str);
483 ut_asserteq_ptr(NULL, ofnode_read_chosen_string("no-setting"));
484
485 node = ofnode_get_chosen_node("other-node");
486 ut_assert(ofnode_valid(node));
487 ut_asserteq_str("c-test@5", ofnode_get_name(node));
488
489 node = ofnode_get_chosen_node("setting");
490 ut_assert(!ofnode_valid(node));
491
Simon Glasse09223c2020-01-27 08:49:46 -0700492 val = ofnode_read_chosen_prop("int-values", &size);
493 ut_assertnonnull(val);
494 ut_asserteq(8, size);
495 ut_asserteq(0x1937, fdt32_to_cpu(val[0]));
496 ut_asserteq(72993, fdt32_to_cpu(val[1]));
497
Simon Glassf3455962020-01-27 08:49:43 -0700498 return 0;
499}
Simon Glass1a92f832024-08-22 07:57:48 -0600500DM_TEST(dm_test_ofnode_read_chosen, UTF_SCAN_PDATA | UTF_SCAN_FDT);
developercf8bc132020-05-02 11:35:10 +0200501
Simon Glass75b8a872023-09-26 08:14:39 -0600502/* test ofnode_get_aliases_node/prop() */
Michal Simek92a88622020-07-28 12:51:08 +0200503static int dm_test_ofnode_read_aliases(struct unit_test_state *uts)
504{
505 const void *val;
506 ofnode node;
507 int size;
508
Michael Walle7efcdfd2021-02-25 16:51:11 +0100509 node = ofnode_get_aliases_node("ethernet3");
Michal Simek92a88622020-07-28 12:51:08 +0200510 ut_assert(ofnode_valid(node));
511 ut_asserteq_str("sbe5", ofnode_get_name(node));
512
513 node = ofnode_get_aliases_node("unknown");
514 ut_assert(!ofnode_valid(node));
515
516 val = ofnode_read_aliases_prop("spi0", &size);
517 ut_assertnonnull(val);
518 ut_asserteq(7, size);
519 ut_asserteq_str("/spi@0", (const char *)val);
520
521 return 0;
522}
Simon Glass1a92f832024-08-22 07:57:48 -0600523DM_TEST(dm_test_ofnode_read_aliases, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Michal Simek92a88622020-07-28 12:51:08 +0200524
developercf8bc132020-05-02 11:35:10 +0200525static int dm_test_ofnode_get_child_count(struct unit_test_state *uts)
526{
527 ofnode node, child_node;
528 u32 val;
529
530 node = ofnode_path("/i-test");
531 ut_assert(ofnode_valid(node));
532
533 val = ofnode_get_child_count(node);
534 ut_asserteq(3, val);
535
536 child_node = ofnode_first_subnode(node);
537 ut_assert(ofnode_valid(child_node));
538 val = ofnode_get_child_count(child_node);
539 ut_asserteq(0, val);
540
541 return 0;
542}
543DM_TEST(dm_test_ofnode_get_child_count,
Simon Glass1a92f832024-08-22 07:57:48 -0600544 UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass5de5b3b2020-11-28 17:50:02 -0700545
Simon Glass75b8a872023-09-26 08:14:39 -0600546/* test ofnode_get_child_count() with 'other' tree */
Simon Glass9e7a42a2022-09-06 20:27:30 -0600547static int dm_test_ofnode_get_child_count_ot(struct unit_test_state *uts)
548{
549 oftree otree = get_other_oftree(uts);
550 ofnode node, child_node;
551 u32 val;
552
553 node = oftree_path(otree, "/node");
554 ut_assert(ofnode_valid(node));
555
556 val = ofnode_get_child_count(node);
557 ut_asserteq(2, val);
558
559 child_node = ofnode_first_subnode(node);
560 ut_assert(ofnode_valid(child_node));
561 val = ofnode_get_child_count(child_node);
562 ut_asserteq(0, val);
563
564 return 0;
565}
Simon Glassdb6d8722023-09-26 08:14:38 -0600566DM_TEST(dm_test_ofnode_get_child_count_ot,
Simon Glass1a92f832024-08-22 07:57:48 -0600567 UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -0600568
Simon Glass5de5b3b2020-11-28 17:50:02 -0700569static int dm_test_ofnode_is_enabled(struct unit_test_state *uts)
570{
571 ofnode root_node = ofnode_path("/");
572 ofnode node = ofnode_path("/usb@0");
573
574 ut_assert(ofnode_is_enabled(root_node));
575 ut_assert(!ofnode_is_enabled(node));
576
577 return 0;
578}
Simon Glass1a92f832024-08-22 07:57:48 -0600579DM_TEST(dm_test_ofnode_is_enabled, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Chen Guanqiaobe0512f2021-04-12 14:51:12 +0800580
Simon Glass75b8a872023-09-26 08:14:39 -0600581/* test ofnode_is_enabled() with 'other' tree */
Simon Glass9e7a42a2022-09-06 20:27:30 -0600582static int dm_test_ofnode_is_enabled_ot(struct unit_test_state *uts)
583{
584 oftree otree = get_other_oftree(uts);
585 ofnode root_node = oftree_root(otree);
586 ofnode node = oftree_path(otree, "/target");
587
588 ut_assert(ofnode_is_enabled(root_node));
589 ut_assert(!ofnode_is_enabled(node));
590
591 return 0;
592}
Simon Glass1a92f832024-08-22 07:57:48 -0600593DM_TEST(dm_test_ofnode_is_enabled_ot, UTF_OTHER_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -0600594
Simon Glass75b8a872023-09-26 08:14:39 -0600595/* test ofnode_get_addr/size() */
Chen Guanqiaobe0512f2021-04-12 14:51:12 +0800596static int dm_test_ofnode_get_reg(struct unit_test_state *uts)
597{
598 ofnode node;
599 fdt_addr_t addr;
600 fdt_size_t size;
601
602 node = ofnode_path("/translation-test@8000");
603 ut_assert(ofnode_valid(node));
604 addr = ofnode_get_addr(node);
605 size = ofnode_get_size(node);
606 ut_asserteq(0x8000, addr);
607 ut_asserteq(0x4000, size);
608
609 node = ofnode_path("/translation-test@8000/dev@1,100");
610 ut_assert(ofnode_valid(node));
611 addr = ofnode_get_addr(node);
612 size = ofnode_get_size(node);
613 ut_asserteq(0x9000, addr);
614 ut_asserteq(0x1000, size);
615
616 node = ofnode_path("/emul-mux-controller");
617 ut_assert(ofnode_valid(node));
618 addr = ofnode_get_addr(node);
619 size = ofnode_get_size(node);
Patrice Chotardb4c52112022-01-04 08:42:48 +0100620 ut_asserteq_64(FDT_ADDR_T_NONE, addr);
Chen Guanqiaobe0512f2021-04-12 14:51:12 +0800621 ut_asserteq(FDT_SIZE_T_NONE, size);
622
Marek Behún177ab7f2021-05-26 14:08:17 +0200623 node = ofnode_path("/translation-test@8000/noxlatebus@3,300/dev@42");
624 ut_assert(ofnode_valid(node));
625 addr = ofnode_get_addr_size_index_notrans(node, 0, &size);
626 ut_asserteq_64(0x42, addr);
627
Chen Guanqiaobe0512f2021-04-12 14:51:12 +0800628 return 0;
629}
Simon Glass1a92f832024-08-22 07:57:48 -0600630DM_TEST(dm_test_ofnode_get_reg, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Marek Behúne897e3c2021-05-26 14:08:18 +0200631
Simon Glass75b8a872023-09-26 08:14:39 -0600632/* test ofnode_get_addr() with 'other' tree */
Simon Glass9e7a42a2022-09-06 20:27:30 -0600633static int dm_test_ofnode_get_reg_ot(struct unit_test_state *uts)
634{
635 oftree otree = get_other_oftree(uts);
636 ofnode node = oftree_path(otree, "/target");
637 fdt_addr_t addr;
638
639 addr = ofnode_get_addr(node);
640 ut_asserteq(0x8000, addr);
641
642 return 0;
643}
Simon Glass1a92f832024-08-22 07:57:48 -0600644DM_TEST(dm_test_ofnode_get_reg_ot, UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -0600645
Marek Behúne897e3c2021-05-26 14:08:18 +0200646static int dm_test_ofnode_get_path(struct unit_test_state *uts)
647{
648 const char *path = "/translation-test@8000/noxlatebus@3,300/dev@42";
649 char buf[64];
650 ofnode node;
Marek Behúne897e3c2021-05-26 14:08:18 +0200651
652 node = ofnode_path(path);
653 ut_assert(ofnode_valid(node));
654
Simon Glass9e7a42a2022-09-06 20:27:30 -0600655 ut_assertok(ofnode_get_path(node, buf, sizeof(buf)));
Marek Behúne897e3c2021-05-26 14:08:18 +0200656 ut_asserteq_str(path, buf);
657
Simon Glass9e7a42a2022-09-06 20:27:30 -0600658 ut_asserteq(-ENOSPC, ofnode_get_path(node, buf, 32));
Marek Behúne897e3c2021-05-26 14:08:18 +0200659
Simon Glass9e7a42a2022-09-06 20:27:30 -0600660 ut_assertok(ofnode_get_path(ofnode_root(), buf, 32));
Simon Glasse3be5fc2022-09-06 20:27:18 -0600661 ut_asserteq_str("/", buf);
662
Marek Behúne897e3c2021-05-26 14:08:18 +0200663 return 0;
664}
Simon Glass1a92f832024-08-22 07:57:48 -0600665DM_TEST(dm_test_ofnode_get_path, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass0034d962021-08-07 07:24:01 -0600666
Simon Glass75b8a872023-09-26 08:14:39 -0600667/* test ofnode_get_path() with 'other' tree */
Simon Glass9e7a42a2022-09-06 20:27:30 -0600668static int dm_test_ofnode_get_path_ot(struct unit_test_state *uts)
669{
670 oftree otree = get_other_oftree(uts);
671 const char *path = "/node/subnode";
672 ofnode node = oftree_path(otree, path);
673 char buf[64];
674
675 ut_assert(ofnode_valid(node));
676
677 ut_assertok(ofnode_get_path(node, buf, sizeof(buf)));
678 ut_asserteq_str(path, buf);
679
680 ut_assertok(ofnode_get_path(oftree_root(otree), buf, 32));
681 ut_asserteq_str("/", buf);
682
683 return 0;
684}
Simon Glass1a92f832024-08-22 07:57:48 -0600685DM_TEST(dm_test_ofnode_get_path_ot, UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -0600686
Simon Glass75b8a872023-09-26 08:14:39 -0600687/* test ofnode_conf_read_bool/int/str() */
Simon Glass0034d962021-08-07 07:24:01 -0600688static int dm_test_ofnode_conf(struct unit_test_state *uts)
689{
690 ut_assert(!ofnode_conf_read_bool("missing"));
691 ut_assert(ofnode_conf_read_bool("testing-bool"));
692
693 ut_asserteq(123, ofnode_conf_read_int("testing-int", 0));
694 ut_asserteq(6, ofnode_conf_read_int("missing", 6));
695
696 ut_assertnull(ofnode_conf_read_str("missing"));
697 ut_asserteq_str("testing", ofnode_conf_read_str("testing-str"));
698
699 return 0;
700}
Simon Glass1a92f832024-08-22 07:57:48 -0600701DM_TEST(dm_test_ofnode_conf, UTF_SCAN_FDT);
Michael Wallef1f87402021-10-15 15:15:18 +0200702
Michal Simek43c42bd2023-08-31 08:59:05 +0200703static int dm_test_ofnode_options(struct unit_test_state *uts)
704{
Michal Simek6a7c1ce2023-08-31 09:04:27 +0200705 u64 bootscr_address, bootscr_offset;
706 u64 bootscr_flash_offset, bootscr_flash_size;
Christian Marangi81ce47e2024-11-10 12:50:25 +0100707 ofnode node, phandle_node, target;
708
709 node = ofnode_path("/options/u-boot");
710 ut_assert(ofnode_valid(node));
Michal Simek43c42bd2023-08-31 08:59:05 +0200711
Christian Marangicdc38152024-10-01 14:24:44 +0200712 ut_assert(!ofnode_options_read_bool("missing"));
713 ut_assert(ofnode_options_read_bool("testing-bool"));
714
715 ut_asserteq(123, ofnode_options_read_int("testing-int", 0));
716 ut_asserteq(6, ofnode_options_read_int("missing", 6));
717
718 ut_assertnull(ofnode_options_read_str("missing"));
719 ut_asserteq_str("testing", ofnode_options_read_str("testing-str"));
720
Christian Marangi81ce47e2024-11-10 12:50:25 +0100721 ut_asserteq(-EINVAL, ofnode_options_get_by_phandle("missing", &phandle_node));
722
723 target = ofnode_path("/phandle-node-1");
724 ut_assert(ofnode_valid(target));
725 ut_assertok(ofnode_options_get_by_phandle("testing-phandle", &phandle_node));
726 ut_assert(ofnode_equal(target, phandle_node));
727
Michal Simek43c42bd2023-08-31 08:59:05 +0200728 ut_assertok(ofnode_read_bootscript_address(&bootscr_address,
729 &bootscr_offset));
730 ut_asserteq_64(0, bootscr_address);
731 ut_asserteq_64(0x12345678, bootscr_offset);
732
Michal Simek6a7c1ce2023-08-31 09:04:27 +0200733 ut_assertok(ofnode_read_bootscript_flash(&bootscr_flash_offset,
734 &bootscr_flash_size));
735 ut_asserteq_64(0, bootscr_flash_offset);
736 ut_asserteq_64(0x2000, bootscr_flash_size);
737
Michal Simek43c42bd2023-08-31 08:59:05 +0200738 return 0;
739}
740DM_TEST(dm_test_ofnode_options, 0);
741
Michael Wallef1f87402021-10-15 15:15:18 +0200742static int dm_test_ofnode_for_each_compatible_node(struct unit_test_state *uts)
743{
744 const char compatible[] = "denx,u-boot-fdt-test";
745 bool found = false;
746 ofnode node;
747
748 ofnode_for_each_compatible_node(node, compatible) {
749 ut_assert(ofnode_device_is_compatible(node, compatible));
750 found = true;
751 }
752
753 /* There should be at least one matching node */
754 ut_assert(found);
755
756 return 0;
757}
Simon Glass1a92f832024-08-22 07:57:48 -0600758DM_TEST(dm_test_ofnode_for_each_compatible_node, UTF_SCAN_FDT);
Simon Glass73025392021-10-23 17:26:04 -0600759
Simon Glass75b8a872023-09-26 08:14:39 -0600760/* test dm_test_ofnode_string_count/index/list() */
Simon Glass73025392021-10-23 17:26:04 -0600761static int dm_test_ofnode_string(struct unit_test_state *uts)
762{
Simon Glass9580bfc2021-10-23 17:26:07 -0600763 const char **val;
Simon Glass73025392021-10-23 17:26:04 -0600764 const char *out;
765 ofnode node;
766
767 node = ofnode_path("/a-test");
768 ut_assert(ofnode_valid(node));
769
770 /* single string */
771 ut_asserteq(1, ofnode_read_string_count(node, "str-value"));
772 ut_assertok(ofnode_read_string_index(node, "str-value", 0, &out));
773 ut_asserteq_str("test string", out);
774 ut_asserteq(0, ofnode_stringlist_search(node, "str-value",
775 "test string"));
Simon Glass9580bfc2021-10-23 17:26:07 -0600776 ut_asserteq(1, ofnode_read_string_list(node, "str-value", &val));
777 ut_asserteq_str("test string", val[0]);
778 ut_assertnull(val[1]);
779 free(val);
Simon Glass73025392021-10-23 17:26:04 -0600780
781 /* list of strings */
782 ut_asserteq(5, ofnode_read_string_count(node, "mux-control-names"));
783 ut_assertok(ofnode_read_string_index(node, "mux-control-names", 0,
784 &out));
785 ut_asserteq_str("mux0", out);
786 ut_asserteq(0, ofnode_stringlist_search(node, "mux-control-names",
787 "mux0"));
Simon Glass9580bfc2021-10-23 17:26:07 -0600788 ut_asserteq(5, ofnode_read_string_list(node, "mux-control-names",
789 &val));
790 ut_asserteq_str("mux0", val[0]);
791 ut_asserteq_str("mux1", val[1]);
792 ut_asserteq_str("mux2", val[2]);
793 ut_asserteq_str("mux3", val[3]);
794 ut_asserteq_str("mux4", val[4]);
795 ut_assertnull(val[5]);
796 free(val);
Simon Glass73025392021-10-23 17:26:04 -0600797
798 ut_assertok(ofnode_read_string_index(node, "mux-control-names", 4,
799 &out));
800 ut_asserteq_str("mux4", out);
801 ut_asserteq(4, ofnode_stringlist_search(node, "mux-control-names",
802 "mux4"));
803
804 return 0;
805}
Simon Glass1a92f832024-08-22 07:57:48 -0600806DM_TEST(dm_test_ofnode_string, UTF_SCAN_FDT);
Simon Glass73025392021-10-23 17:26:04 -0600807
Simon Glass75b8a872023-09-26 08:14:39 -0600808/* test error returns from ofnode_read_string_count/index/list() */
Simon Glass73025392021-10-23 17:26:04 -0600809static int dm_test_ofnode_string_err(struct unit_test_state *uts)
810{
Simon Glass9580bfc2021-10-23 17:26:07 -0600811 const char **val;
Simon Glass73025392021-10-23 17:26:04 -0600812 const char *out;
813 ofnode node;
814
815 /*
816 * Test error codes only on livetree, as they are different with
817 * flattree
818 */
819 node = ofnode_path("/a-test");
820 ut_assert(ofnode_valid(node));
821
822 /* non-existent property */
823 ut_asserteq(-EINVAL, ofnode_read_string_count(node, "missing"));
824 ut_asserteq(-EINVAL, ofnode_read_string_index(node, "missing", 0,
825 &out));
Simon Glass9580bfc2021-10-23 17:26:07 -0600826 ut_asserteq(-EINVAL, ofnode_read_string_list(node, "missing", &val));
Simon Glass73025392021-10-23 17:26:04 -0600827
828 /* empty property */
829 ut_asserteq(-ENODATA, ofnode_read_string_count(node, "bool-value"));
830 ut_asserteq(-ENODATA, ofnode_read_string_index(node, "bool-value", 0,
831 &out));
Simon Glass9580bfc2021-10-23 17:26:07 -0600832 ut_asserteq(-ENODATA, ofnode_read_string_list(node, "bool-value",
833 &val));
Simon Glass73025392021-10-23 17:26:04 -0600834
835 /* badly formatted string list */
836 ut_asserteq(-EILSEQ, ofnode_read_string_count(node, "int64-value"));
837 ut_asserteq(-EILSEQ, ofnode_read_string_index(node, "int64-value", 0,
838 &out));
Simon Glass9580bfc2021-10-23 17:26:07 -0600839 ut_asserteq(-EILSEQ, ofnode_read_string_list(node, "int64-value",
840 &val));
Simon Glass73025392021-10-23 17:26:04 -0600841
842 /* out of range / not found */
843 ut_asserteq(-ENODATA, ofnode_read_string_index(node, "str-value", 1,
844 &out));
845 ut_asserteq(-ENODATA, ofnode_stringlist_search(node, "str-value",
846 "other"));
847
848 /* negative value for index is not allowed, so don't test for that */
849
850 ut_asserteq(-ENODATA, ofnode_read_string_index(node,
851 "mux-control-names", 5,
852 &out));
853
854 return 0;
855}
Simon Glass1a92f832024-08-22 07:57:48 -0600856DM_TEST(dm_test_ofnode_string_err, UTF_LIVE_TREE);
Marek Behúnf4f1ddc2022-04-07 00:32:57 +0200857
Simon Glass75b8a872023-09-26 08:14:39 -0600858static int dm_test_ofnode_read_phy_mode(struct unit_test_state *uts)
Marek Behúnf4f1ddc2022-04-07 00:32:57 +0200859{
860 ofnode eth_node, phy_node;
Marek Behúnbc194772022-04-07 00:33:01 +0200861 phy_interface_t mode;
Marek Behúnf4f1ddc2022-04-07 00:32:57 +0200862 u32 reg;
863
864 eth_node = ofnode_path("/phy-test-eth");
865 ut_assert(ofnode_valid(eth_node));
866
Marek Behúnbc194772022-04-07 00:33:01 +0200867 mode = ofnode_read_phy_mode(eth_node);
868 ut_assert(mode == PHY_INTERFACE_MODE_2500BASEX);
869
Marek Behúnf4f1ddc2022-04-07 00:32:57 +0200870 phy_node = ofnode_get_phy_node(eth_node);
871 ut_assert(ofnode_valid(phy_node));
872
873 reg = ofnode_read_u32_default(phy_node, "reg", -1U);
874 ut_asserteq_64(0x1, reg);
875
876 return 0;
877}
Simon Glass1a92f832024-08-22 07:57:48 -0600878DM_TEST(dm_test_ofnode_read_phy_mode, UTF_SCAN_FDT);
Simon Glassef75c592022-07-30 15:52:08 -0600879
880/**
881 * make_ofnode_fdt() - Create an FDT for testing with ofnode
882 *
883 * The size is set to the minimum needed
884 *
885 * @uts: Test state
886 * @fdt: Place to write FDT
887 * @size: Maximum size of space for fdt
Simon Glass9e7a42a2022-09-06 20:27:30 -0600888 * @id: id value to add to the tree ('id' property in root node)
Simon Glassef75c592022-07-30 15:52:08 -0600889 */
Simon Glass9e7a42a2022-09-06 20:27:30 -0600890static int make_ofnode_fdt(struct unit_test_state *uts, void *fdt, int size,
891 int id)
Simon Glassef75c592022-07-30 15:52:08 -0600892{
893 ut_assertok(fdt_create(fdt, size));
894 ut_assertok(fdt_finish_reservemap(fdt));
895 ut_assert(fdt_begin_node(fdt, "") >= 0);
896
Simon Glass9e7a42a2022-09-06 20:27:30 -0600897 ut_assertok(fdt_property_u32(fdt, "id", id));
898
Simon Glassef75c592022-07-30 15:52:08 -0600899 ut_assert(fdt_begin_node(fdt, "aliases") >= 0);
900 ut_assertok(fdt_property_string(fdt, "mmc0", "/new-mmc"));
901 ut_assertok(fdt_end_node(fdt));
902
903 ut_assert(fdt_begin_node(fdt, "new-mmc") >= 0);
904 ut_assertok(fdt_end_node(fdt));
905
906 ut_assertok(fdt_end_node(fdt));
907 ut_assertok(fdt_finish(fdt));
908
909 return 0;
910}
911
Simon Glass75b8a872023-09-26 08:14:39 -0600912/* Check that aliases work on the control FDT */
913static int dm_test_ofnode_aliases(struct unit_test_state *uts)
Simon Glassef75c592022-07-30 15:52:08 -0600914{
Simon Glassef75c592022-07-30 15:52:08 -0600915 ofnode node;
916
Simon Glassef75c592022-07-30 15:52:08 -0600917 node = ofnode_get_aliases_node("ethernet3");
918 ut_assert(ofnode_valid(node));
919 ut_asserteq_str("sbe5", ofnode_get_name(node));
920
Simon Glass2b9b14582022-09-06 20:27:21 -0600921 ut_assert(!oftree_valid(oftree_null()));
922
Simon Glassc7599442022-10-20 18:22:49 -0600923 return 0;
924}
Simon Glass1a92f832024-08-22 07:57:48 -0600925DM_TEST(dm_test_ofnode_aliases, UTF_SCAN_FDT);
Simon Glassdad97512022-09-06 20:27:29 -0600926
Simon Glass75b8a872023-09-26 08:14:39 -0600927/**
928 * dm_test_ofnode_root_mult() - Check aliaes on control and 'other' tree
929 *
930 * Check that aliases work only with the control FDT, not with 'other' tree.
931 * This is not actually the desired behaviour. If aliases are implemented for
932 * any tree, then this test should be changed.
933 */
Simon Glassc7599442022-10-20 18:22:49 -0600934static int dm_test_ofnode_root_mult(struct unit_test_state *uts)
935{
936 char fdt[256];
937 oftree tree;
938 ofnode node;
Simon Glassdad97512022-09-06 20:27:29 -0600939
Simon Glassc7599442022-10-20 18:22:49 -0600940 /* skip this test if multiple FDTs are not supported */
941 if (!IS_ENABLED(CONFIG_OFNODE_MULTI_TREE))
942 return -EAGAIN;
943
944 ut_assertok(make_ofnode_fdt(uts, fdt, sizeof(fdt), 0));
945 ut_assertok(get_oftree(uts, fdt, &tree));
Simon Glass2b9b14582022-09-06 20:27:21 -0600946 ut_assert(oftree_valid(tree));
Simon Glassef75c592022-07-30 15:52:08 -0600947
948 /* Make sure they don't work on this new tree */
Simon Glass45ae59d2022-09-06 20:27:24 -0600949 node = oftree_path(tree, "mmc0");
Simon Glassef75c592022-07-30 15:52:08 -0600950 ut_assert(!ofnode_valid(node));
951
952 /* It should appear in the new tree */
Simon Glass45ae59d2022-09-06 20:27:24 -0600953 node = oftree_path(tree, "/new-mmc");
Simon Glassef75c592022-07-30 15:52:08 -0600954 ut_assert(ofnode_valid(node));
955
956 /* ...and not in the control FDT */
Simon Glass45ae59d2022-09-06 20:27:24 -0600957 node = oftree_path(oftree_default(), "/new-mmc");
Simon Glassef75c592022-07-30 15:52:08 -0600958 ut_assert(!ofnode_valid(node));
959
Simon Glassdad97512022-09-06 20:27:29 -0600960 free_oftree(tree);
Simon Glassef75c592022-07-30 15:52:08 -0600961
962 return 0;
963}
Simon Glass1a92f832024-08-22 07:57:48 -0600964DM_TEST(dm_test_ofnode_root_mult, UTF_SCAN_FDT);
Simon Glass270a4432022-07-30 15:52:09 -0600965
Simon Glass75b8a872023-09-26 08:14:39 -0600966/* test ofnode_set_enabled(), ofnode_write_prop() on a livetree */
Simon Glass270a4432022-07-30 15:52:09 -0600967static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts)
968{
969 struct udevice *dev;
970 ofnode node;
971
Simon Glass270a4432022-07-30 15:52:09 -0600972 /* Test enabling devices */
Simon Glass270a4432022-07-30 15:52:09 -0600973 node = ofnode_path("/usb@2");
974
Simon Glass3ee3d152022-07-30 15:52:13 -0600975 ut_assert(!ofnode_is_enabled(node));
976 ut_assertok(ofnode_set_enabled(node, true));
977 ut_asserteq(true, ofnode_is_enabled(node));
Simon Glass270a4432022-07-30 15:52:09 -0600978
979 device_bind_driver_to_node(dm_root(), "usb_sandbox", "usb@2", node,
980 &dev);
981 ut_assertok(uclass_find_device_by_seq(UCLASS_USB, 2, &dev));
982
983 /* Test string property setting */
Simon Glass270a4432022-07-30 15:52:09 -0600984 ut_assert(device_is_compatible(dev, "sandbox,usb"));
985 ofnode_write_string(node, "compatible", "gdsys,super-usb");
986 ut_assert(device_is_compatible(dev, "gdsys,super-usb"));
987 ofnode_write_string(node, "compatible", "sandbox,usb");
988 ut_assert(device_is_compatible(dev, "sandbox,usb"));
989
990 /* Test setting generic properties */
991
992 /* Non-existent in DTB */
993 ut_asserteq_64(FDT_ADDR_T_NONE, dev_read_addr(dev));
994 /* reg = 0x42, size = 0x100 */
Simon Glass5e2cd5e2022-07-30 15:52:10 -0600995 ut_assertok(ofnode_write_prop(node, "reg",
Simon Glass17abed02022-09-06 20:27:32 -0600996 "\x00\x00\x00\x42\x00\x00\x01\x00", 8,
997 false));
Simon Glass270a4432022-07-30 15:52:09 -0600998 ut_asserteq(0x42, dev_read_addr(dev));
999
1000 /* Test disabling devices */
Simon Glass270a4432022-07-30 15:52:09 -06001001 device_remove(dev, DM_REMOVE_NORMAL);
1002 device_unbind(dev);
1003
Simon Glass3ee3d152022-07-30 15:52:13 -06001004 ut_assert(ofnode_is_enabled(node));
1005 ut_assertok(ofnode_set_enabled(node, false));
1006 ut_assert(!ofnode_is_enabled(node));
Simon Glass270a4432022-07-30 15:52:09 -06001007
1008 return 0;
1009}
Simon Glassb75dc162022-07-30 15:52:11 -06001010DM_TEST(dm_test_ofnode_livetree_writing,
Simon Glass1a92f832024-08-22 07:57:48 -06001011 UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glassd28e31e2022-07-30 15:52:14 -06001012
Simon Glass17abed02022-09-06 20:27:32 -06001013static int check_write_prop(struct unit_test_state *uts, ofnode node)
1014{
1015 char prop[] = "middle-name";
1016 char name[10];
1017 int len;
1018
1019 strcpy(name, "cecil");
1020 len = strlen(name) + 1;
1021 ut_assertok(ofnode_write_prop(node, prop, name, len, false));
1022 ut_asserteq_str(name, ofnode_read_string(node, prop));
1023
1024 /* change the underlying value, this should mess up the live tree */
1025 strcpy(name, "tony");
1026 if (of_live_active()) {
1027 ut_asserteq_str(name, ofnode_read_string(node, prop));
1028 } else {
1029 ut_asserteq_str("cecil", ofnode_read_string(node, prop));
1030 }
1031
1032 /* try again, this time copying the property */
1033 strcpy(name, "mary");
1034 ut_assertok(ofnode_write_prop(node, prop, name, len, true));
1035 ut_asserteq_str(name, ofnode_read_string(node, prop));
1036 strcpy(name, "leah");
1037
1038 /* both flattree and livetree behave the same */
1039 ut_asserteq_str("mary", ofnode_read_string(node, prop));
1040
1041 return 0;
1042}
1043
1044/* writing the tree with and without copying the property */
1045static int dm_test_ofnode_write_copy(struct unit_test_state *uts)
1046{
1047 ofnode node;
1048
1049 node = ofnode_path("/a-test");
1050 ut_assertok(check_write_prop(uts, node));
1051
1052 return 0;
1053}
Simon Glass1a92f832024-08-22 07:57:48 -06001054DM_TEST(dm_test_ofnode_write_copy, UTF_SCAN_FDT);
Simon Glass17abed02022-09-06 20:27:32 -06001055
Simon Glass75b8a872023-09-26 08:14:39 -06001056/* test writing a property to the 'other' tree */
Simon Glass17abed02022-09-06 20:27:32 -06001057static int dm_test_ofnode_write_copy_ot(struct unit_test_state *uts)
1058{
1059 oftree otree = get_other_oftree(uts);
1060 ofnode node, check_node;
1061
1062 node = oftree_path(otree, "/node");
1063 ut_assertok(check_write_prop(uts, node));
1064
1065 /* make sure the control FDT is not touched */
1066 check_node = ofnode_path("/node");
1067 ut_assertnull(ofnode_read_string(check_node, "middle-name"));
1068
1069 return 0;
1070}
Simon Glass1a92f832024-08-22 07:57:48 -06001071DM_TEST(dm_test_ofnode_write_copy_ot, UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glass17abed02022-09-06 20:27:32 -06001072
Simon Glass75b8a872023-09-26 08:14:39 -06001073/* test ofnode_read_u32_index/default() */
Simon Glassd28e31e2022-07-30 15:52:14 -06001074static int dm_test_ofnode_u32(struct unit_test_state *uts)
1075{
1076 ofnode node;
Simon Glasse3be5fc2022-09-06 20:27:18 -06001077 u32 val;
Simon Glassd28e31e2022-07-30 15:52:14 -06001078
1079 node = ofnode_path("/lcd");
1080 ut_assert(ofnode_valid(node));
1081 ut_asserteq(1366, ofnode_read_u32_default(node, "xres", 123));
1082 ut_assertok(ofnode_write_u32(node, "xres", 1367));
1083 ut_asserteq(1367, ofnode_read_u32_default(node, "xres", 123));
1084 ut_assertok(ofnode_write_u32(node, "xres", 1366));
1085
Simon Glasse3be5fc2022-09-06 20:27:18 -06001086 node = ofnode_path("/backlight");
1087 ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 0, &val));
1088 ut_asserteq(0, val);
1089 ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 1, &val));
1090 ut_asserteq(16, val);
1091 ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 8, &val));
1092 ut_asserteq(255, val);
1093 ut_asserteq(-EOVERFLOW,
1094 ofnode_read_u32_index(node, "brightness-levels", 9, &val));
1095 ut_asserteq(-EINVAL, ofnode_read_u32_index(node, "missing", 0, &val));
1096
Simon Glassd28e31e2022-07-30 15:52:14 -06001097 return 0;
1098}
Simon Glass1a92f832024-08-22 07:57:48 -06001099DM_TEST(dm_test_ofnode_u32, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass56bc3322022-09-06 20:27:02 -06001100
Simon Glass75b8a872023-09-26 08:14:39 -06001101/* test ofnode_read_u32_array() */
Simon Glasse3be5fc2022-09-06 20:27:18 -06001102static int dm_test_ofnode_u32_array(struct unit_test_state *uts)
1103{
1104 ofnode node;
1105 u32 val[10];
1106
1107 node = ofnode_path("/a-test");
1108 ut_assert(ofnode_valid(node));
1109 ut_assertok(ofnode_read_u32_array(node, "int-value", val, 1));
1110 ut_asserteq(-EINVAL, ofnode_read_u32_array(node, "missing", val, 1));
1111 ut_asserteq(-EOVERFLOW, ofnode_read_u32_array(node, "bool-value", val,
1112 1));
1113
1114 memset(val, '\0', sizeof(val));
1115 ut_assertok(ofnode_read_u32_array(node, "int-array", val + 1, 3));
1116 ut_asserteq(0, val[0]);
1117 ut_asserteq(5678, val[1]);
1118 ut_asserteq(9123, val[2]);
1119 ut_asserteq(4567, val[3]);
1120 ut_asserteq(0, val[4]);
1121 ut_asserteq(-EOVERFLOW, ofnode_read_u32_array(node, "int-array", val,
1122 4));
1123
1124 return 0;
1125}
Simon Glass1a92f832024-08-22 07:57:48 -06001126DM_TEST(dm_test_ofnode_u32_array, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glasse3be5fc2022-09-06 20:27:18 -06001127
Simon Glassc681e092023-09-26 08:14:45 -06001128/* test ofnode_read_u64() and ofnode_write_u64() */
1129static int dm_test_ofnode_u64(struct unit_test_state *uts)
Simon Glasse3be5fc2022-09-06 20:27:18 -06001130{
1131 ofnode node;
1132 u64 val;
1133
1134 node = ofnode_path("/a-test");
1135 ut_assert(ofnode_valid(node));
1136 ut_assertok(ofnode_read_u64(node, "int64-value", &val));
1137 ut_asserteq_64(0x1111222233334444, val);
Simon Glassc681e092023-09-26 08:14:45 -06001138 ut_assertok(ofnode_write_u64(node, "new-int64-value", 0x9876543210));
1139 ut_assertok(ofnode_read_u64(node, "new-int64-value", &val));
1140 ut_asserteq_64(0x9876543210, val);
1141
Simon Glasse3be5fc2022-09-06 20:27:18 -06001142 ut_asserteq(-EINVAL, ofnode_read_u64(node, "missing", &val));
1143
Michal Simek08a194e2023-08-25 11:37:46 +02001144 ut_assertok(ofnode_read_u64_index(node, "int64-array", 0, &val));
1145 ut_asserteq_64(0x1111222233334444, val);
1146 ut_assertok(ofnode_read_u64_index(node, "int64-array", 1, &val));
1147 ut_asserteq_64(0x4444333322221111, val);
1148 ut_asserteq(-EOVERFLOW,
1149 ofnode_read_u64_index(node, "int64-array", 2, &val));
1150 ut_asserteq(-EINVAL, ofnode_read_u64_index(node, "missing", 0, &val));
1151
Simon Glassc681e092023-09-26 08:14:45 -06001152 ut_assertok(ofnode_write_u64(node, "int64-array", 0x9876543210));
1153 ut_assertok(ofnode_read_u64_index(node, "int64-array", 0, &val));
1154 ut_asserteq_64(0x9876543210, val);
1155 ut_asserteq(-EOVERFLOW,
1156 ofnode_read_u64_index(node, "int64-array", 1, &val));
1157
Simon Glasse3be5fc2022-09-06 20:27:18 -06001158 return 0;
1159}
Simon Glass1a92f832024-08-22 07:57:48 -06001160DM_TEST(dm_test_ofnode_u64, UTF_SCAN_FDT);
Simon Glasse3be5fc2022-09-06 20:27:18 -06001161
Simon Glass56bc3322022-09-06 20:27:02 -06001162static int dm_test_ofnode_add_subnode(struct unit_test_state *uts)
1163{
1164 ofnode node, check, subnode;
1165 char buf[128];
1166
Simon Glass56bc3322022-09-06 20:27:02 -06001167 node = ofnode_path("/lcd");
1168 ut_assert(ofnode_valid(node));
1169 ut_assertok(ofnode_add_subnode(node, "edmund", &subnode));
1170 check = ofnode_path("/lcd/edmund");
1171 ut_asserteq(subnode.of_offset, check.of_offset);
1172 ut_assertok(ofnode_get_path(subnode, buf, sizeof(buf)));
1173 ut_asserteq_str("/lcd/edmund", buf);
1174
1175 if (of_live_active()) {
1176 struct device_node *child;
1177
1178 ut_assertok(of_add_subnode((void *)ofnode_to_np(node), "edmund",
1179 2, &child));
1180 ut_asserteq_str("ed", child->name);
1181 ut_asserteq_str("/lcd/ed", child->full_name);
1182 check = ofnode_path("/lcd/ed");
1183 ut_asserteq_ptr(child, check.np);
1184 ut_assertok(ofnode_get_path(np_to_ofnode(child), buf,
1185 sizeof(buf)));
1186 ut_asserteq_str("/lcd/ed", buf);
1187 }
1188
1189 /* An existing node should be returned with -EEXIST */
1190 ut_asserteq(-EEXIST, ofnode_add_subnode(node, "edmund", &check));
1191 ut_asserteq(subnode.of_offset, check.of_offset);
1192
1193 /* add a root node */
1194 node = ofnode_path("/");
1195 ut_assert(ofnode_valid(node));
1196 ut_assertok(ofnode_add_subnode(node, "lcd2", &subnode));
1197 check = ofnode_path("/lcd2");
1198 ut_asserteq(subnode.of_offset, check.of_offset);
1199 ut_assertok(ofnode_get_path(subnode, buf, sizeof(buf)));
1200 ut_asserteq_str("/lcd2", buf);
1201
1202 if (of_live_active()) {
1203 ulong start;
1204 int i;
1205
1206 /*
1207 * Make sure each of the three malloc()checks in
1208 * of_add_subnode() work
1209 */
1210 for (i = 0; i < 3; i++) {
1211 malloc_enable_testing(i);
1212 start = ut_check_free();
1213 ut_asserteq(-ENOMEM, ofnode_add_subnode(node, "anthony",
1214 &check));
1215 ut_assertok(ut_check_delta(start));
1216 }
1217
1218 /* This should pass since we allow 3 allocations */
1219 malloc_enable_testing(3);
1220 ut_assertok(ofnode_add_subnode(node, "anthony", &check));
1221 malloc_disable_testing();
1222 }
1223
Simon Glass238afb52022-09-06 20:27:03 -06001224 /* write to the empty node */
1225 ut_assertok(ofnode_write_string(subnode, "example", "text"));
1226
Simon Glass56bc3322022-09-06 20:27:02 -06001227 return 0;
1228}
Simon Glass1a92f832024-08-22 07:57:48 -06001229DM_TEST(dm_test_ofnode_add_subnode, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass4caa79a2022-09-06 20:27:16 -06001230
1231static int dm_test_ofnode_for_each_prop(struct unit_test_state *uts)
1232{
1233 ofnode node, subnode;
1234 struct ofprop prop;
1235 int count;
1236
Dzmitry Sankouski54f4c832023-01-22 18:21:23 +03001237 node = ofnode_path("/ofnode-foreach");
Simon Glass4caa79a2022-09-06 20:27:16 -06001238 count = 0;
1239
1240 /* we expect "compatible" for each node */
1241 ofnode_for_each_prop(prop, node)
1242 count++;
1243 ut_asserteq(1, count);
1244
1245 /* there are two nodes, each with 2 properties */
1246 ofnode_for_each_subnode(subnode, node)
1247 ofnode_for_each_prop(prop, subnode)
1248 count++;
1249 ut_asserteq(5, count);
1250
1251 return 0;
1252}
Simon Glass1a92f832024-08-22 07:57:48 -06001253DM_TEST(dm_test_ofnode_for_each_prop, UTF_SCAN_FDT);
Simon Glasse3be5fc2022-09-06 20:27:18 -06001254
1255static int dm_test_ofnode_by_compatible(struct unit_test_state *uts)
1256{
1257 const char *compat = "denx,u-boot-fdt-test";
1258 ofnode node;
1259 int count;
1260
1261 count = 0;
1262 for (node = ofnode_null();
1263 node = ofnode_by_compatible(node, compat), ofnode_valid(node);)
1264 count++;
1265 ut_asserteq(11, count);
1266
1267 return 0;
1268}
Simon Glass1a92f832024-08-22 07:57:48 -06001269DM_TEST(dm_test_ofnode_by_compatible, UTF_SCAN_FDT);
Simon Glasse3be5fc2022-09-06 20:27:18 -06001270
Simon Glass75b8a872023-09-26 08:14:39 -06001271/* check ofnode_by_compatible() on the 'other' tree */
Simon Glass9e7a42a2022-09-06 20:27:30 -06001272static int dm_test_ofnode_by_compatible_ot(struct unit_test_state *uts)
1273{
1274 const char *compat = "sandbox-other2";
1275 oftree otree = get_other_oftree(uts);
1276 ofnode node;
1277 int count;
1278
1279 count = 0;
1280 for (node = oftree_root(otree);
1281 node = ofnode_by_compatible(node, compat), ofnode_valid(node);)
1282 count++;
1283 ut_asserteq(2, count);
1284
1285 return 0;
1286}
Simon Glass1a92f832024-08-22 07:57:48 -06001287DM_TEST(dm_test_ofnode_by_compatible_ot, UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -06001288
Simon Glasse3be5fc2022-09-06 20:27:18 -06001289static int dm_test_ofnode_find_subnode(struct unit_test_state *uts)
1290{
1291 ofnode node, subnode;
1292
1293 node = ofnode_path("/buttons");
1294
1295 subnode = ofnode_find_subnode(node, "btn1");
1296 ut_assert(ofnode_valid(subnode));
1297 ut_asserteq_str("btn1", ofnode_get_name(subnode));
1298
1299 subnode = ofnode_find_subnode(node, "btn");
1300 ut_assert(!ofnode_valid(subnode));
1301
1302 return 0;
1303}
Simon Glass1a92f832024-08-22 07:57:48 -06001304DM_TEST(dm_test_ofnode_find_subnode, UTF_SCAN_FDT);
Simon Glasse3be5fc2022-09-06 20:27:18 -06001305
Simon Glass75b8a872023-09-26 08:14:39 -06001306/* test ofnode_find_subnode() on the 'other' tree */
Simon Glass9e7a42a2022-09-06 20:27:30 -06001307static int dm_test_ofnode_find_subnode_ot(struct unit_test_state *uts)
1308{
1309 oftree otree = get_other_oftree(uts);
1310 ofnode node, subnode;
1311
1312 node = oftree_path(otree, "/node");
1313
1314 subnode = ofnode_find_subnode(node, "subnode");
1315 ut_assert(ofnode_valid(subnode));
1316 ut_asserteq_str("subnode", ofnode_get_name(subnode));
1317
1318 subnode = ofnode_find_subnode(node, "btn");
1319 ut_assert(!ofnode_valid(subnode));
1320
1321 return 0;
1322}
Simon Glass1a92f832024-08-22 07:57:48 -06001323DM_TEST(dm_test_ofnode_find_subnode_ot, UTF_OTHER_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -06001324
Simon Glasse3be5fc2022-09-06 20:27:18 -06001325static int dm_test_ofnode_get_name(struct unit_test_state *uts)
1326{
1327 ofnode node;
1328
1329 node = ofnode_path("/buttons");
1330 ut_assert(ofnode_valid(node));
1331 ut_asserteq_str("buttons", ofnode_get_name(node));
1332 ut_asserteq_str("", ofnode_get_name(ofnode_root()));
1333
1334 return 0;
1335}
Simon Glass1a92f832024-08-22 07:57:48 -06001336DM_TEST(dm_test_ofnode_get_name, UTF_SCAN_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -06001337
1338/* try to access more FDTs than is supported */
1339static int dm_test_ofnode_too_many(struct unit_test_state *uts)
1340{
1341 const int max_trees = CONFIG_IS_ENABLED(OFNODE_MULTI_TREE,
1342 (CONFIG_OFNODE_MULTI_TREE_MAX), (1));
1343 const int fdt_size = 256;
1344 const int num_trees = max_trees + 1;
1345 char fdt[num_trees][fdt_size];
1346 int i;
1347
1348 for (i = 0; i < num_trees; i++) {
1349 oftree tree;
1350 int ret;
1351
1352 ut_assertok(make_ofnode_fdt(uts, fdt[i], fdt_size, i));
1353 ret = get_oftree(uts, fdt[i], &tree);
1354
1355 /*
1356 * With flat tree we have the control FDT using one slot. Live
1357 * tree has no limit since it uses pointers, not integer tree
1358 * IDs
1359 */
1360 if (of_live_active() || i < max_trees - 1) {
1361 ut_assertok(ret);
1362 } else {
1363 /*
1364 * tree should be invalid when we try to register too
1365 * many trees
1366 */
1367 ut_asserteq(-EOVERFLOW, ret);
1368 }
1369 }
1370
1371 return 0;
1372}
Simon Glass1a92f832024-08-22 07:57:48 -06001373DM_TEST(dm_test_ofnode_too_many, UTF_SCAN_FDT);
Simon Glass7a7229a2022-09-06 20:27:33 -06001374
Simon Glass68164892023-09-26 08:14:37 -06001375static int check_copy_props(struct unit_test_state *uts, ofnode dst, ofnode src)
Simon Glass7a7229a2022-09-06 20:27:33 -06001376{
1377 u32 reg[2], val;
1378
Simon Glass68164892023-09-26 08:14:37 -06001379 ut_assertok(ofnode_copy_props(dst, src));
Simon Glass7a7229a2022-09-06 20:27:33 -06001380
1381 ut_assertok(ofnode_read_u32(dst, "ping-expect", &val));
1382 ut_asserteq(3, val);
1383
1384 ut_asserteq_str("denx,u-boot-fdt-test",
1385 ofnode_read_string(dst, "compatible"));
1386
1387 /* check that a property with the same name is overwritten */
1388 ut_assertok(ofnode_read_u32_array(dst, "reg", reg, ARRAY_SIZE(reg)));
1389 ut_asserteq(3, reg[0]);
1390 ut_asserteq(1, reg[1]);
1391
1392 /* reset the compatible so the live tree does not change */
1393 ut_assertok(ofnode_write_string(dst, "compatible", "nothing"));
1394
1395 return 0;
1396}
1397
1398static int dm_test_ofnode_copy_props(struct unit_test_state *uts)
1399{
1400 ofnode src, dst;
1401
1402 /*
1403 * These nodes are chosen so that the src node is before the destination
1404 * node in the tree. This doesn't matter with livetree, but with
1405 * flattree any attempt to insert a property earlier in the tree will
1406 * mess up the offsets after it.
1407 */
1408 src = ofnode_path("/b-test");
1409 dst = ofnode_path("/some-bus");
1410
Simon Glass68164892023-09-26 08:14:37 -06001411 ut_assertok(check_copy_props(uts, dst, src));
Simon Glass7a7229a2022-09-06 20:27:33 -06001412
1413 /* check a property that is in the destination already */
1414 ut_asserteq_str("mux0", ofnode_read_string(dst, "mux-control-names"));
1415
1416 return 0;
1417}
Simon Glass1a92f832024-08-22 07:57:48 -06001418DM_TEST(dm_test_ofnode_copy_props, UTF_SCAN_FDT);
Simon Glass7a7229a2022-09-06 20:27:33 -06001419
Simon Glass75b8a872023-09-26 08:14:39 -06001420/* test ofnode_copy_props() with the 'other' tree */
Simon Glass7a7229a2022-09-06 20:27:33 -06001421static int dm_test_ofnode_copy_props_ot(struct unit_test_state *uts)
1422{
1423 ofnode src, dst;
1424 oftree otree = get_other_oftree(uts);
1425
1426 src = ofnode_path("/b-test");
1427 dst = oftree_path(otree, "/node/subnode2");
Simon Glass68164892023-09-26 08:14:37 -06001428 ut_assertok(check_copy_props(uts, dst, src));
Simon Glass7a7229a2022-09-06 20:27:33 -06001429
1430 return 0;
1431}
Simon Glass1a92f832024-08-22 07:57:48 -06001432DM_TEST(dm_test_ofnode_copy_props_ot, UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glasse88e2fe2023-06-01 10:22:40 -06001433
1434/* check that the livetree is aligned to a structure boundary */
1435static int dm_test_livetree_align(struct unit_test_state *uts)
1436{
1437 const int align = __alignof__(struct unit_test_state);
1438 struct device_node *node;
1439 u32 *sentinel;
1440 ulong start;
1441
1442 start = (ulong)gd_of_root();
1443 ut_asserteq(start, ALIGN(start, align));
1444
1445 node = gd_of_root();
1446 sentinel = (void *)node - sizeof(u32);
1447
1448 /*
1449 * The sentinel should be overwritten with the root node. If it isn't,
1450 * then the root node is not at the very start of the livetree memory
1451 * area, and free(root) will fail to free the memory used by the
1452 * livetree.
1453 */
1454 ut_assert(*sentinel != BAD_OF_ROOT);
1455
1456 return 0;
1457}
Simon Glass1a92f832024-08-22 07:57:48 -06001458DM_TEST(dm_test_livetree_align, UTF_SCAN_FDT | UTF_LIVE_TREE);
Simon Glass722281b2023-06-01 10:22:42 -06001459
1460/* check that it is possible to load an arbitrary livetree */
1461static int dm_test_livetree_ensure(struct unit_test_state *uts)
1462{
1463 oftree tree;
1464 ofnode node;
1465
1466 /* read from other.dtb */
1467 ut_assertok(test_load_other_fdt(uts));
1468 tree = oftree_from_fdt(uts->other_fdt);
1469 ut_assert(oftree_valid(tree));
1470 node = oftree_path(tree, "/node/subnode");
1471 ut_assert(ofnode_valid(node));
1472 ut_asserteq_str("sandbox-other2",
1473 ofnode_read_string(node, "compatible"));
1474
1475 return 0;
1476}
Simon Glass1a92f832024-08-22 07:57:48 -06001477DM_TEST(dm_test_livetree_ensure, UTF_SCAN_FDT);
Simon Glassa869a1b2023-09-26 08:14:40 -06001478
1479static int dm_test_oftree_new(struct unit_test_state *uts)
1480{
1481 ofnode node, subnode, check;
1482 oftree tree;
1483
1484 ut_assertok(oftree_new(&tree));
1485 node = oftree_root(tree);
1486 ut_assert(ofnode_valid(node));
1487 ut_assertok(ofnode_add_subnode(node, "edmund", &subnode));
1488 check = ofnode_find_subnode(node, "edmund");
1489 ut_asserteq(check.of_offset, subnode.of_offset);
1490
1491 return 0;
1492}
Simon Glass1a92f832024-08-22 07:57:48 -06001493DM_TEST(dm_test_oftree_new, UTF_SCAN_FDT);
Simon Glass7c33c962023-09-26 08:14:41 -06001494
1495static int check_copy_node(struct unit_test_state *uts, ofnode dst, ofnode src,
1496 ofnode *nodep)
1497{
1498 u32 reg[2], val;
1499 ofnode node;
1500
1501 ut_assertok(ofnode_copy_node(dst, "copy-test", src, &node));
1502
1503 ut_assertok(ofnode_read_u32(node, "ping-expect", &val));
1504 ut_asserteq(3, val);
1505
1506 ut_asserteq_str("denx,u-boot-fdt-test",
1507 ofnode_read_string(node, "compatible"));
1508
1509 /* check that a property with the same name is overwritten */
1510 ut_assertok(ofnode_read_u32_array(node, "reg", reg, ARRAY_SIZE(reg)));
1511 ut_asserteq(3, reg[0]);
1512 ut_asserteq(1, reg[1]);
1513
1514 /* reset the compatible so the live tree does not change */
1515 ut_assertok(ofnode_write_string(node, "compatible", "nothing"));
1516 *nodep = node;
1517
1518 return 0;
1519}
1520
1521static int dm_test_ofnode_copy_node(struct unit_test_state *uts)
1522{
1523 ofnode src, dst, node, try;
1524
1525 /*
1526 * These nodes are chosen so that the src node is before the destination
1527 * node in the tree. This doesn't matter with livetree, but with
1528 * flattree any attempt to insert a property earlier in the tree will
1529 * mess up the offsets after it.
1530 */
1531 src = ofnode_path("/b-test");
1532 dst = ofnode_path("/some-bus");
1533
1534 ut_assertok(check_copy_node(uts, dst, src, &node));
1535
1536 /* check trying to copy over an existing node */
1537 ut_asserteq(-EEXIST, ofnode_copy_node(dst, "copy-test", src, &try));
1538 ut_asserteq(try.of_offset, node.of_offset);
1539
1540 return 0;
1541}
Simon Glass1a92f832024-08-22 07:57:48 -06001542DM_TEST(dm_test_ofnode_copy_node, UTF_SCAN_FDT);
Simon Glass7c33c962023-09-26 08:14:41 -06001543
1544/* test ofnode_copy_node() with the 'other' tree */
1545static int dm_test_ofnode_copy_node_ot(struct unit_test_state *uts)
1546{
1547 oftree otree = get_other_oftree(uts);
1548 ofnode src, dst, node;
1549
1550 src = ofnode_path("/b-test");
1551 dst = oftree_path(otree, "/node/subnode2");
1552 ut_assertok(check_copy_node(uts, dst, src, &node));
1553
1554 return 0;
1555}
Simon Glass1a92f832024-08-22 07:57:48 -06001556DM_TEST(dm_test_ofnode_copy_node_ot, UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glass45448772023-09-26 08:14:42 -06001557
1558static int dm_test_ofnode_delete(struct unit_test_state *uts)
1559{
1560 ofnode node;
1561
1562 /*
1563 * At present the livetree is not restored after changes made in tests.
1564 * See test_pre_run() for how this is done with the other FDT and
1565 * dm_test_pre_run() where it sets up the root-tree pointer. So use
1566 * nodes which don't matter to other tests.
1567 *
1568 * We could fix this by detecting livetree changes and regenerating it
1569 * before the next test if needed.
1570 */
1571 node = ofnode_path("/leds/iracibble");
1572 ut_assert(ofnode_valid(node));
1573 ut_assertok(ofnode_delete(&node));
1574 ut_assert(!ofnode_valid(node));
1575 ut_assert(!ofnode_valid(ofnode_path("/leds/iracibble")));
1576
1577 node = ofnode_path("/leds/default_on");
1578 ut_assert(ofnode_valid(node));
1579 ut_assertok(ofnode_delete(&node));
1580 ut_assert(!ofnode_valid(node));
1581 ut_assert(!ofnode_valid(ofnode_path("/leds/default_on")));
1582
1583 ut_asserteq(2, ofnode_get_child_count(ofnode_path("/leds")));
1584
1585 return 0;
1586}
Simon Glass1a92f832024-08-22 07:57:48 -06001587DM_TEST(dm_test_ofnode_delete, UTF_SCAN_FDT);
Simon Glassebbe90b2023-09-26 08:14:43 -06001588
1589static int dm_test_oftree_to_fdt(struct unit_test_state *uts)
1590{
1591 oftree tree, check;
1592 struct abuf buf, buf2;
1593
1594 tree = oftree_default();
1595 ut_assertok(oftree_to_fdt(tree, &buf));
1596 ut_assert(abuf_size(&buf) > SZ_16K);
1597
1598 /* convert it back to a tree and see if it looks OK */
1599 check = oftree_from_fdt(abuf_data(&buf));
1600 ut_assert(oftree_valid(check));
1601
1602 ut_assertok(oftree_to_fdt(check, &buf2));
1603 ut_assert(abuf_size(&buf2) > SZ_16K);
1604 ut_asserteq(abuf_size(&buf), abuf_size(&buf2));
1605 ut_asserteq_mem(abuf_data(&buf), abuf_data(&buf2), abuf_size(&buf));
1606
1607 return 0;
1608}
Simon Glass1a92f832024-08-22 07:57:48 -06001609DM_TEST(dm_test_oftree_to_fdt, UTF_SCAN_FDT);
Simon Glass86ef3992023-09-26 08:14:44 -06001610
1611/* test ofnode_read_bool() and ofnode_write_bool() */
1612static int dm_test_bool(struct unit_test_state *uts)
1613{
1614 const char *propname = "missing-bool-value";
1615 ofnode node;
1616
1617 node = ofnode_path("/a-test");
1618 ut_assert(ofnode_read_bool(node, "bool-value"));
1619 ut_assert(!ofnode_read_bool(node, propname));
1620 ut_assert(!ofnode_has_property(node, propname));
1621
1622 ut_assertok(ofnode_write_bool(node, propname, true));
1623 ut_assert(ofnode_read_bool(node, propname));
1624 ut_assert(ofnode_has_property(node, propname));
1625 ut_assert(ofnode_read_bool(node, "bool-value"));
1626
1627 ut_assertok(ofnode_write_bool(node, propname, false));
1628 ut_assert(!ofnode_read_bool(node, propname));
1629 ut_assert(!ofnode_has_property(node, propname));
1630 ut_assert(ofnode_read_bool(node, "bool-value"));
1631
1632 return 0;
1633}
Simon Glass1a92f832024-08-22 07:57:48 -06001634DM_TEST(dm_test_bool, UTF_SCAN_FDT);