blob: 0f60c2a6281fa7ce845ffdea0aca7766107a5e17 [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>
Svyatoslav Ryhel1f5298f2025-02-16 13:14:40 +020026#include <dm/ofnode_graph.h>
Simon Glass270a4432022-07-30 15:52:09 -060027#include <dm/root.h>
Masahiro Yamadab4f2dda2018-04-27 01:02:02 +090028#include <dm/test.h>
Simon Glass270a4432022-07-30 15:52:09 -060029#include <dm/uclass-internal.h>
Simon Glassebbe90b2023-09-26 08:14:43 -060030#include <linux/sizes.h>
Simon Glass75c4d412020-07-19 10:15:37 -060031#include <test/test.h>
Masahiro Yamadab4f2dda2018-04-27 01:02:02 +090032#include <test/ut.h>
33
Simon Glassf912a722022-09-06 20:27:27 -060034/**
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))
Simon Glass1a92f832024-08-22 07:57:48 -060051 ut_reportf("test needs the UTF_OTHER_FDT flag");
Simon Glassf912a722022-09-06 20:27:27 -060052
53 return tree;
54}
55
Simon Glassdad97512022-09-06 20:27:29 -060056/**
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
Simon Glass75b8a872023-09-26 08:14:39 -060096/* test ofnode_device_is_compatible() */
Masahiro Yamadab4f2dda2018-04-27 01:02:02 +090097static 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}
Simon Glass9e7a42a2022-09-06 20:27:30 -0600106DM_TEST(dm_test_ofnode_compatible,
Simon Glass1a92f832024-08-22 07:57:48 -0600107 UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -0600108
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}
Simon Glass1a92f832024-08-22 07:57:48 -0600120DM_TEST(dm_test_ofnode_compatible_ot, UTF_SCAN_FDT | UTF_OTHER_FDT);
Jens Wiklanderd9fd0ac2018-08-20 11:10:00 +0200121
Patrick Delaunay04fcfe72020-09-24 17:26:20 +0200122static 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
Simon Glass95fd2092022-09-06 20:27:22 -0600134 ut_assert(ofnode_valid(oftree_get_by_phandle(oftree_default(), 1)));
135
Patrick Delaunay04fcfe72020-09-24 17:26:20 +0200136 return 0;
137}
Simon Glass1a92f832024-08-22 07:57:48 -0600138DM_TEST(dm_test_ofnode_get_by_phandle, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Patrick Delaunay04fcfe72020-09-24 17:26:20 +0200139
Simon Glass75b8a872023-09-26 08:14:39 -0600140/* test oftree_get_by_phandle() with a the 'other' oftree */
Simon Glassf912a722022-09-06 20:27:27 -0600141static int dm_test_ofnode_get_by_phandle_ot(struct unit_test_state *uts)
142{
143 oftree otree = get_other_oftree(uts);
144 ofnode node;
Christian Marangi7d75d202024-11-10 12:50:21 +0100145 u32 idx;
146 int ret;
147
148 node = oftree_path(otree, "/node");
149 ut_assert(ofnode_valid(node));
150
151 ret = ofnode_read_u32(node, "other-phandle", &idx);
152 ut_assertok(ret);
Simon Glassf912a722022-09-06 20:27:27 -0600153
Christian Marangi7d75d202024-11-10 12:50:21 +0100154 node = oftree_get_by_phandle(otree, idx);
Simon Glassf912a722022-09-06 20:27:27 -0600155 ut_assert(ofnode_valid(node));
156 ut_asserteq_str("target", ofnode_get_name(node));
157
158 return 0;
159}
Simon Glassdb6d8722023-09-26 08:14:38 -0600160DM_TEST(dm_test_ofnode_get_by_phandle_ot,
Simon Glass1a92f832024-08-22 07:57:48 -0600161 UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glassf912a722022-09-06 20:27:27 -0600162
Simon Glass9e7a42a2022-09-06 20:27:30 -0600163static int check_prop_values(struct unit_test_state *uts, ofnode start,
164 const char *propname, const char *propval,
165 int expect_count)
Jens Wiklanderd9fd0ac2018-08-20 11:10:00 +0200166{
Simon Glass9e7a42a2022-09-06 20:27:30 -0600167 int proplen = strlen(propval) + 1;
Jens Wiklanderd9fd0ac2018-08-20 11:10:00 +0200168 const char *str;
Simon Glass9e7a42a2022-09-06 20:27:30 -0600169 ofnode node;
170 int count;
Jens Wiklanderd9fd0ac2018-08-20 11:10:00 +0200171
172 /* Find first matching node, there should be at least one */
Simon Glass9e7a42a2022-09-06 20:27:30 -0600173 node = ofnode_by_prop_value(start, propname, propval, proplen);
Jens Wiklanderd9fd0ac2018-08-20 11:10:00 +0200174 ut_assert(ofnode_valid(node));
175 str = ofnode_read_string(node, propname);
176 ut_assert(str && !strcmp(str, propval));
177
178 /* Find the rest of the matching nodes */
Simon Glass9e7a42a2022-09-06 20:27:30 -0600179 count = 1;
Jens Wiklanderd9fd0ac2018-08-20 11:10:00 +0200180 while (true) {
Simon Glass9e7a42a2022-09-06 20:27:30 -0600181 node = ofnode_by_prop_value(node, propname, propval, proplen);
Jens Wiklanderd9fd0ac2018-08-20 11:10:00 +0200182 if (!ofnode_valid(node))
183 break;
184 str = ofnode_read_string(node, propname);
Simon Glass9e7a42a2022-09-06 20:27:30 -0600185 ut_asserteq_str(propval, str);
186 count++;
Jens Wiklanderd9fd0ac2018-08-20 11:10:00 +0200187 }
Simon Glass9e7a42a2022-09-06 20:27:30 -0600188 ut_asserteq(expect_count, count);
189
190 return 0;
191}
192
193static int dm_test_ofnode_by_prop_value(struct unit_test_state *uts)
194{
195 ut_assertok(check_prop_values(uts, ofnode_null(), "compatible",
196 "denx,u-boot-fdt-test", 11));
Jens Wiklanderd9fd0ac2018-08-20 11:10:00 +0200197
198 return 0;
199}
Simon Glass1a92f832024-08-22 07:57:48 -0600200DM_TEST(dm_test_ofnode_by_prop_value, UTF_SCAN_FDT);
Simon Glass699c9ca2018-10-01 12:22:08 -0600201
Simon Glass75b8a872023-09-26 08:14:39 -0600202/* test ofnode_by_prop_value() with a the 'other' oftree */
Simon Glass9e7a42a2022-09-06 20:27:30 -0600203static int dm_test_ofnode_by_prop_value_ot(struct unit_test_state *uts)
204{
205 oftree otree = get_other_oftree(uts);
206
207 ut_assertok(check_prop_values(uts, oftree_root(otree), "str-prop",
208 "other", 2));
209
210 return 0;
211}
Simon Glassdb6d8722023-09-26 08:14:38 -0600212DM_TEST(dm_test_ofnode_by_prop_value_ot,
Simon Glass1a92f832024-08-22 07:57:48 -0600213 UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -0600214
Simon Glass75b8a872023-09-26 08:14:39 -0600215/* test ofnode_read_fmap_entry() */
Simon Glass699c9ca2018-10-01 12:22:08 -0600216static int dm_test_ofnode_fmap(struct unit_test_state *uts)
217{
218 struct fmap_entry entry;
219 ofnode node;
220
221 node = ofnode_path("/cros-ec/flash");
222 ut_assert(ofnode_valid(node));
223 ut_assertok(ofnode_read_fmap_entry(node, &entry));
224 ut_asserteq(0x08000000, entry.offset);
225 ut_asserteq(0x20000, entry.length);
226
227 return 0;
228}
Simon Glass1a92f832024-08-22 07:57:48 -0600229DM_TEST(dm_test_ofnode_fmap, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glassf3455962020-01-27 08:49:43 -0700230
Simon Glass75b8a872023-09-26 08:14:39 -0600231/* test ofnode_read_prop() */
Simon Glass0c2e9802020-01-27 08:49:44 -0700232static int dm_test_ofnode_read(struct unit_test_state *uts)
233{
234 const u32 *val;
235 ofnode node;
236 int size;
237
Simon Glass310487d2023-09-26 08:14:46 -0600238 node = oftree_path(oftree_default(), "/");
239 ut_assert(ofnode_valid(node));
240
Simon Glass0c2e9802020-01-27 08:49:44 -0700241 node = ofnode_path("/a-test");
242 ut_assert(ofnode_valid(node));
243
244 val = ofnode_read_prop(node, "int-value", &size);
245 ut_assertnonnull(val);
246 ut_asserteq(4, size);
247 ut_asserteq(1234, fdt32_to_cpu(val[0]));
248
249 val = ofnode_read_prop(node, "missing", &size);
250 ut_assertnull(val);
251 ut_asserteq(-FDT_ERR_NOTFOUND, size);
252
253 /* Check it works without a size parameter */
254 val = ofnode_read_prop(node, "missing", NULL);
255 ut_assertnull(val);
256
257 return 0;
258}
Simon Glass1a92f832024-08-22 07:57:48 -0600259DM_TEST(dm_test_ofnode_read, UTF_SCAN_FDT);
Simon Glass0c2e9802020-01-27 08:49:44 -0700260
Simon Glass75b8a872023-09-26 08:14:39 -0600261/* test ofnode_read_prop() with the 'other' tree */
Simon Glass9e7a42a2022-09-06 20:27:30 -0600262static int dm_test_ofnode_read_ot(struct unit_test_state *uts)
263{
264 oftree otree = get_other_oftree(uts);
265 const char *val;
266 ofnode node;
267 int size;
268
Simon Glass310487d2023-09-26 08:14:46 -0600269 node = oftree_path(otree, "/");
270 ut_assert(ofnode_valid(node));
271
Simon Glass9e7a42a2022-09-06 20:27:30 -0600272 node = oftree_path(otree, "/node/subnode");
273 ut_assert(ofnode_valid(node));
274
275 val = ofnode_read_prop(node, "str-prop", &size);
276 ut_assertnonnull(val);
277 ut_asserteq_str("other", val);
278 ut_asserteq(6, size);
279
280 return 0;
281}
Simon Glass1a92f832024-08-22 07:57:48 -0600282DM_TEST(dm_test_ofnode_read_ot, UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -0600283
Christian Marangia1a1e0e2024-11-10 12:50:23 +0100284/* test ofnode_count_/parse/_phandle_with_args() */
Patrick Delaunay8cd28012020-09-25 09:41:16 +0200285static int dm_test_ofnode_phandle(struct unit_test_state *uts)
286{
287 struct ofnode_phandle_args args;
Christian Marangia1a1e0e2024-11-10 12:50:23 +0100288 ofnode node, phandle, target;
Patrick Delaunay8cd28012020-09-25 09:41:16 +0200289 int ret;
290 const char prop[] = "test-gpios";
291 const char cell[] = "#gpio-cells";
292 const char prop2[] = "phandle-value";
Christian Marangia1a1e0e2024-11-10 12:50:23 +0100293 const char prop3[] = "phandle-nodes";
Patrick Delaunay8cd28012020-09-25 09:41:16 +0200294
295 node = ofnode_path("/a-test");
296 ut_assert(ofnode_valid(node));
297
298 /* Test ofnode_count_phandle_with_args with cell name */
299 ret = ofnode_count_phandle_with_args(node, "missing", cell, 0);
300 ut_asserteq(-ENOENT, ret);
301 ret = ofnode_count_phandle_with_args(node, prop, "#invalid", 0);
302 ut_asserteq(-EINVAL, ret);
303 ret = ofnode_count_phandle_with_args(node, prop, cell, 0);
304 ut_asserteq(5, ret);
305
306 /* Test ofnode_parse_phandle_with_args with cell name */
307 ret = ofnode_parse_phandle_with_args(node, "missing", cell, 0, 0,
308 &args);
309 ut_asserteq(-ENOENT, ret);
310 ret = ofnode_parse_phandle_with_args(node, prop, "#invalid", 0, 0,
311 &args);
312 ut_asserteq(-EINVAL, ret);
313 ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 0, &args);
314 ut_assertok(ret);
315 ut_asserteq(1, args.args_count);
316 ut_asserteq(1, args.args[0]);
317 ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 1, &args);
318 ut_assertok(ret);
319 ut_asserteq(1, args.args_count);
320 ut_asserteq(4, args.args[0]);
321 ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 2, &args);
322 ut_assertok(ret);
323 ut_asserteq(5, args.args_count);
324 ut_asserteq(5, args.args[0]);
325 ut_asserteq(1, args.args[4]);
326 ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 3, &args);
327 ut_asserteq(-ENOENT, ret);
328 ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 4, &args);
329 ut_assertok(ret);
330 ut_asserteq(1, args.args_count);
331 ut_asserteq(12, args.args[0]);
332 ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 5, &args);
333 ut_asserteq(-ENOENT, ret);
334
335 /* Test ofnode_count_phandle_with_args with cell count */
336 ret = ofnode_count_phandle_with_args(node, "missing", NULL, 2);
337 ut_asserteq(-ENOENT, ret);
338 ret = ofnode_count_phandle_with_args(node, prop2, NULL, 1);
339 ut_asserteq(3, ret);
340
341 /* Test ofnode_parse_phandle_with_args with cell count */
342 ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 0, &args);
343 ut_assertok(ret);
344 ut_asserteq(1, ofnode_valid(args.node));
345 ut_asserteq(1, args.args_count);
346 ut_asserteq(10, args.args[0]);
347 ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 1, &args);
348 ut_asserteq(-EINVAL, ret);
349 ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 2, &args);
350 ut_assertok(ret);
351 ut_asserteq(1, ofnode_valid(args.node));
352 ut_asserteq(1, args.args_count);
353 ut_asserteq(30, args.args[0]);
354 ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 3, &args);
355 ut_asserteq(-ENOENT, ret);
356
Christian Marangia1a1e0e2024-11-10 12:50:23 +0100357 /* Test ofnode_parse_phandle */
358 phandle = ofnode_parse_phandle(node, "missing", 0);
359 ut_assert(ofnode_equal(ofnode_null(), phandle));
360
361 target = ofnode_path("/phandle-node-1");
362 ut_assert(ofnode_valid(target));
363 phandle = ofnode_parse_phandle(node, prop3, 0);
364 ut_assert(ofnode_equal(target, phandle));
365
366 target = ofnode_path("/phandle-node-2");
367 ut_assert(ofnode_valid(target));
368 phandle = ofnode_parse_phandle(node, prop3, 1);
369 ut_assert(ofnode_equal(target, phandle));
370
371 phandle = ofnode_parse_phandle(node, prop3, 3);
372 ut_assert(ofnode_equal(ofnode_null(), phandle));
373
Patrick Delaunay8cd28012020-09-25 09:41:16 +0200374 return 0;
375}
Simon Glass1a92f832024-08-22 07:57:48 -0600376DM_TEST(dm_test_ofnode_phandle, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Patrick Delaunay8cd28012020-09-25 09:41:16 +0200377
Christian Marangia1a1e0e2024-11-10 12:50:23 +0100378/* test oftree_count_/parse/_phandle_with_args() with 'other' tree */
Simon Glassf912a722022-09-06 20:27:27 -0600379static int dm_test_ofnode_phandle_ot(struct unit_test_state *uts)
380{
381 oftree otree = get_other_oftree(uts);
382 struct ofnode_phandle_args args;
Christian Marangia1a1e0e2024-11-10 12:50:23 +0100383 ofnode node, phandle, target;
Simon Glassf912a722022-09-06 20:27:27 -0600384 int ret;
Christian Marangi7d75d202024-11-10 12:50:21 +0100385 const char prop[] = "other-test-gpios";
386 const char cell[] = "#gpio-cells";
387 const char prop2[] = "other-phandle-value";
Christian Marangia1a1e0e2024-11-10 12:50:23 +0100388 const char prop3[] = "other-phandle-nodes";
Simon Glassf912a722022-09-06 20:27:27 -0600389
Christian Marangi7d75d202024-11-10 12:50:21 +0100390 node = oftree_path(otree, "/other-a-test");
391 ut_assert(ofnode_valid(node));
Simon Glassf912a722022-09-06 20:27:27 -0600392
Christian Marangi7d75d202024-11-10 12:50:21 +0100393 /* Test oftree_count_phandle_with_args with cell name */
394 ret = oftree_count_phandle_with_args(otree, node, "missing", cell, 0);
Simon Glassf912a722022-09-06 20:27:27 -0600395 ut_asserteq(-ENOENT, ret);
Christian Marangi7d75d202024-11-10 12:50:21 +0100396 ret = oftree_count_phandle_with_args(otree, node, prop, "#invalid", 0);
Simon Glassf912a722022-09-06 20:27:27 -0600397 ut_asserteq(-EINVAL, ret);
Christian Marangi7d75d202024-11-10 12:50:21 +0100398 ret = oftree_count_phandle_with_args(otree, node, prop, cell, 0);
399 ut_asserteq(5, ret);
Simon Glassf912a722022-09-06 20:27:27 -0600400
Christian Marangi7d75d202024-11-10 12:50:21 +0100401 /* Test oftree_parse_phandle_with_args with cell name */
402 ret = oftree_parse_phandle_with_args(otree, node, "missing", cell, 0, 0,
403 &args);
404 ut_asserteq(-ENOENT, ret);
405 ret = oftree_parse_phandle_with_args(otree, node, prop, "#invalid", 0, 0,
406 &args);
407 ut_asserteq(-EINVAL, ret);
408 ret = oftree_parse_phandle_with_args(otree, node, prop, cell, 0, 0, &args);
Simon Glassf912a722022-09-06 20:27:27 -0600409 ut_assertok(ret);
Christian Marangi7d75d202024-11-10 12:50:21 +0100410 ut_asserteq(1, args.args_count);
411 ut_asserteq(1, args.args[0]);
412 ret = oftree_parse_phandle_with_args(otree, node, prop, cell, 0, 1, &args);
413 ut_assertok(ret);
414 ut_asserteq(1, args.args_count);
415 ut_asserteq(4, args.args[0]);
416 ret = oftree_parse_phandle_with_args(otree, node, prop, cell, 0, 2, &args);
417 ut_assertok(ret);
418 ut_asserteq(5, args.args_count);
419 ut_asserteq(5, args.args[0]);
420 ut_asserteq(1, args.args[4]);
421 ret = oftree_parse_phandle_with_args(otree, node, prop, cell, 0, 3, &args);
422 ut_asserteq(-ENOENT, ret);
423 ret = oftree_parse_phandle_with_args(otree, node, prop, cell, 0, 4, &args);
424 ut_assertok(ret);
425 ut_asserteq(1, args.args_count);
426 ut_asserteq(12, args.args[0]);
427 ret = oftree_parse_phandle_with_args(otree, node, prop, cell, 0, 5, &args);
428 ut_asserteq(-ENOENT, ret);
429
430 /* Test oftree_count_phandle_with_args with cell count */
431 ret = oftree_count_phandle_with_args(otree, node, "missing", NULL, 2);
432 ut_asserteq(-ENOENT, ret);
433 ret = oftree_count_phandle_with_args(otree, node, prop2, NULL, 1);
434 ut_asserteq(3, ret);
435
436 /* Test oftree_parse_phandle_with_args with cell count */
437 ret = oftree_parse_phandle_with_args(otree, node, prop2, NULL, 1, 0, &args);
438 ut_assertok(ret);
439 ut_asserteq(1, ofnode_valid(args.node));
440 ut_asserteq(1, args.args_count);
441 ut_asserteq(10, args.args[0]);
442 ret = oftree_parse_phandle_with_args(otree, node, prop2, NULL, 1, 1, &args);
443 ut_asserteq(-EINVAL, ret);
444 ret = oftree_parse_phandle_with_args(otree, node, prop2, NULL, 1, 2, &args);
445 ut_assertok(ret);
446 ut_asserteq(1, ofnode_valid(args.node));
447 ut_asserteq(1, args.args_count);
448 ut_asserteq(30, args.args[0]);
449 ret = oftree_parse_phandle_with_args(otree, node, prop2, NULL, 1, 3, &args);
450 ut_asserteq(-ENOENT, ret);
Simon Glassf912a722022-09-06 20:27:27 -0600451
Christian Marangia1a1e0e2024-11-10 12:50:23 +0100452 /* Test oftree_parse_phandle */
453 phandle = oftree_parse_phandle(otree, node, "missing", 0);
454 ut_assert(ofnode_equal(ofnode_null(), phandle));
455
456 target = oftree_path(otree, "/other-phandle-node-1");
457 ut_assert(ofnode_valid(target));
458 phandle = oftree_parse_phandle(otree, node, prop3, 0);
459 ut_assert(ofnode_equal(target, phandle));
460
461 target = oftree_path(otree, "/other-phandle-node-2");
462 ut_assert(ofnode_valid(target));
463 phandle = oftree_parse_phandle(otree, node, prop3, 1);
464 ut_assert(ofnode_equal(target, phandle));
465
466 phandle = oftree_parse_phandle(otree, node, prop3, 3);
467 ut_assert(ofnode_equal(ofnode_null(), phandle));
468
Simon Glassf912a722022-09-06 20:27:27 -0600469 return 0;
470}
Simon Glass1a92f832024-08-22 07:57:48 -0600471DM_TEST(dm_test_ofnode_phandle_ot, UTF_OTHER_FDT);
Simon Glassf912a722022-09-06 20:27:27 -0600472
Simon Glass75b8a872023-09-26 08:14:39 -0600473/* test ofnode_read_chosen_string/node/prop() */
Simon Glassf3455962020-01-27 08:49:43 -0700474static int dm_test_ofnode_read_chosen(struct unit_test_state *uts)
475{
476 const char *str;
Simon Glasse09223c2020-01-27 08:49:46 -0700477 const u32 *val;
Simon Glassf3455962020-01-27 08:49:43 -0700478 ofnode node;
Simon Glasse09223c2020-01-27 08:49:46 -0700479 int size;
Simon Glassf3455962020-01-27 08:49:43 -0700480
481 str = ofnode_read_chosen_string("setting");
482 ut_assertnonnull(str);
483 ut_asserteq_str("sunrise ohoka", str);
484 ut_asserteq_ptr(NULL, ofnode_read_chosen_string("no-setting"));
485
486 node = ofnode_get_chosen_node("other-node");
487 ut_assert(ofnode_valid(node));
488 ut_asserteq_str("c-test@5", ofnode_get_name(node));
489
490 node = ofnode_get_chosen_node("setting");
491 ut_assert(!ofnode_valid(node));
492
Simon Glasse09223c2020-01-27 08:49:46 -0700493 val = ofnode_read_chosen_prop("int-values", &size);
494 ut_assertnonnull(val);
495 ut_asserteq(8, size);
496 ut_asserteq(0x1937, fdt32_to_cpu(val[0]));
497 ut_asserteq(72993, fdt32_to_cpu(val[1]));
498
Simon Glassf3455962020-01-27 08:49:43 -0700499 return 0;
500}
Simon Glass1a92f832024-08-22 07:57:48 -0600501DM_TEST(dm_test_ofnode_read_chosen, UTF_SCAN_PDATA | UTF_SCAN_FDT);
developercf8bc132020-05-02 11:35:10 +0200502
Simon Glass75b8a872023-09-26 08:14:39 -0600503/* test ofnode_get_aliases_node/prop() */
Michal Simek92a88622020-07-28 12:51:08 +0200504static int dm_test_ofnode_read_aliases(struct unit_test_state *uts)
505{
506 const void *val;
507 ofnode node;
508 int size;
509
Michael Walle7efcdfd2021-02-25 16:51:11 +0100510 node = ofnode_get_aliases_node("ethernet3");
Michal Simek92a88622020-07-28 12:51:08 +0200511 ut_assert(ofnode_valid(node));
512 ut_asserteq_str("sbe5", ofnode_get_name(node));
513
514 node = ofnode_get_aliases_node("unknown");
515 ut_assert(!ofnode_valid(node));
516
517 val = ofnode_read_aliases_prop("spi0", &size);
518 ut_assertnonnull(val);
519 ut_asserteq(7, size);
520 ut_asserteq_str("/spi@0", (const char *)val);
521
522 return 0;
523}
Simon Glass1a92f832024-08-22 07:57:48 -0600524DM_TEST(dm_test_ofnode_read_aliases, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Michal Simek92a88622020-07-28 12:51:08 +0200525
developercf8bc132020-05-02 11:35:10 +0200526static int dm_test_ofnode_get_child_count(struct unit_test_state *uts)
527{
528 ofnode node, child_node;
529 u32 val;
530
531 node = ofnode_path("/i-test");
532 ut_assert(ofnode_valid(node));
533
534 val = ofnode_get_child_count(node);
535 ut_asserteq(3, val);
536
537 child_node = ofnode_first_subnode(node);
538 ut_assert(ofnode_valid(child_node));
539 val = ofnode_get_child_count(child_node);
540 ut_asserteq(0, val);
541
542 return 0;
543}
544DM_TEST(dm_test_ofnode_get_child_count,
Simon Glass1a92f832024-08-22 07:57:48 -0600545 UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass5de5b3b2020-11-28 17:50:02 -0700546
Simon Glass75b8a872023-09-26 08:14:39 -0600547/* test ofnode_get_child_count() with 'other' tree */
Simon Glass9e7a42a2022-09-06 20:27:30 -0600548static int dm_test_ofnode_get_child_count_ot(struct unit_test_state *uts)
549{
550 oftree otree = get_other_oftree(uts);
551 ofnode node, child_node;
552 u32 val;
553
554 node = oftree_path(otree, "/node");
555 ut_assert(ofnode_valid(node));
556
557 val = ofnode_get_child_count(node);
558 ut_asserteq(2, val);
559
560 child_node = ofnode_first_subnode(node);
561 ut_assert(ofnode_valid(child_node));
562 val = ofnode_get_child_count(child_node);
563 ut_asserteq(0, val);
564
565 return 0;
566}
Simon Glassdb6d8722023-09-26 08:14:38 -0600567DM_TEST(dm_test_ofnode_get_child_count_ot,
Simon Glass1a92f832024-08-22 07:57:48 -0600568 UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -0600569
Simon Glass5de5b3b2020-11-28 17:50:02 -0700570static int dm_test_ofnode_is_enabled(struct unit_test_state *uts)
571{
572 ofnode root_node = ofnode_path("/");
573 ofnode node = ofnode_path("/usb@0");
574
575 ut_assert(ofnode_is_enabled(root_node));
576 ut_assert(!ofnode_is_enabled(node));
577
578 return 0;
579}
Simon Glass1a92f832024-08-22 07:57:48 -0600580DM_TEST(dm_test_ofnode_is_enabled, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Chen Guanqiaobe0512f2021-04-12 14:51:12 +0800581
Simon Glass75b8a872023-09-26 08:14:39 -0600582/* test ofnode_is_enabled() with 'other' tree */
Simon Glass9e7a42a2022-09-06 20:27:30 -0600583static int dm_test_ofnode_is_enabled_ot(struct unit_test_state *uts)
584{
585 oftree otree = get_other_oftree(uts);
586 ofnode root_node = oftree_root(otree);
587 ofnode node = oftree_path(otree, "/target");
588
589 ut_assert(ofnode_is_enabled(root_node));
590 ut_assert(!ofnode_is_enabled(node));
591
592 return 0;
593}
Simon Glass1a92f832024-08-22 07:57:48 -0600594DM_TEST(dm_test_ofnode_is_enabled_ot, UTF_OTHER_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -0600595
Simon Glass75b8a872023-09-26 08:14:39 -0600596/* test ofnode_get_addr/size() */
Chen Guanqiaobe0512f2021-04-12 14:51:12 +0800597static int dm_test_ofnode_get_reg(struct unit_test_state *uts)
598{
599 ofnode node;
600 fdt_addr_t addr;
601 fdt_size_t size;
602
603 node = ofnode_path("/translation-test@8000");
604 ut_assert(ofnode_valid(node));
605 addr = ofnode_get_addr(node);
606 size = ofnode_get_size(node);
607 ut_asserteq(0x8000, addr);
608 ut_asserteq(0x4000, size);
609
610 node = ofnode_path("/translation-test@8000/dev@1,100");
611 ut_assert(ofnode_valid(node));
612 addr = ofnode_get_addr(node);
613 size = ofnode_get_size(node);
614 ut_asserteq(0x9000, addr);
615 ut_asserteq(0x1000, size);
616
617 node = ofnode_path("/emul-mux-controller");
618 ut_assert(ofnode_valid(node));
619 addr = ofnode_get_addr(node);
620 size = ofnode_get_size(node);
Patrice Chotardb4c52112022-01-04 08:42:48 +0100621 ut_asserteq_64(FDT_ADDR_T_NONE, addr);
Chen Guanqiaobe0512f2021-04-12 14:51:12 +0800622 ut_asserteq(FDT_SIZE_T_NONE, size);
623
Marek Behún177ab7f2021-05-26 14:08:17 +0200624 node = ofnode_path("/translation-test@8000/noxlatebus@3,300/dev@42");
625 ut_assert(ofnode_valid(node));
626 addr = ofnode_get_addr_size_index_notrans(node, 0, &size);
627 ut_asserteq_64(0x42, addr);
628
Chen Guanqiaobe0512f2021-04-12 14:51:12 +0800629 return 0;
630}
Simon Glass1a92f832024-08-22 07:57:48 -0600631DM_TEST(dm_test_ofnode_get_reg, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Marek Behúne897e3c2021-05-26 14:08:18 +0200632
Simon Glass75b8a872023-09-26 08:14:39 -0600633/* test ofnode_get_addr() with 'other' tree */
Simon Glass9e7a42a2022-09-06 20:27:30 -0600634static int dm_test_ofnode_get_reg_ot(struct unit_test_state *uts)
635{
636 oftree otree = get_other_oftree(uts);
637 ofnode node = oftree_path(otree, "/target");
638 fdt_addr_t addr;
639
640 addr = ofnode_get_addr(node);
641 ut_asserteq(0x8000, addr);
642
643 return 0;
644}
Simon Glass1a92f832024-08-22 07:57:48 -0600645DM_TEST(dm_test_ofnode_get_reg_ot, UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -0600646
Marek Behúne897e3c2021-05-26 14:08:18 +0200647static int dm_test_ofnode_get_path(struct unit_test_state *uts)
648{
649 const char *path = "/translation-test@8000/noxlatebus@3,300/dev@42";
650 char buf[64];
651 ofnode node;
Marek Behúne897e3c2021-05-26 14:08:18 +0200652
653 node = ofnode_path(path);
654 ut_assert(ofnode_valid(node));
655
Simon Glass9e7a42a2022-09-06 20:27:30 -0600656 ut_assertok(ofnode_get_path(node, buf, sizeof(buf)));
Marek Behúne897e3c2021-05-26 14:08:18 +0200657 ut_asserteq_str(path, buf);
658
Simon Glass9e7a42a2022-09-06 20:27:30 -0600659 ut_asserteq(-ENOSPC, ofnode_get_path(node, buf, 32));
Marek Behúne897e3c2021-05-26 14:08:18 +0200660
Simon Glass9e7a42a2022-09-06 20:27:30 -0600661 ut_assertok(ofnode_get_path(ofnode_root(), buf, 32));
Simon Glasse3be5fc2022-09-06 20:27:18 -0600662 ut_asserteq_str("/", buf);
663
Marek Behúne897e3c2021-05-26 14:08:18 +0200664 return 0;
665}
Simon Glass1a92f832024-08-22 07:57:48 -0600666DM_TEST(dm_test_ofnode_get_path, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass0034d962021-08-07 07:24:01 -0600667
Simon Glass75b8a872023-09-26 08:14:39 -0600668/* test ofnode_get_path() with 'other' tree */
Simon Glass9e7a42a2022-09-06 20:27:30 -0600669static int dm_test_ofnode_get_path_ot(struct unit_test_state *uts)
670{
671 oftree otree = get_other_oftree(uts);
672 const char *path = "/node/subnode";
673 ofnode node = oftree_path(otree, path);
674 char buf[64];
675
676 ut_assert(ofnode_valid(node));
677
678 ut_assertok(ofnode_get_path(node, buf, sizeof(buf)));
679 ut_asserteq_str(path, buf);
680
681 ut_assertok(ofnode_get_path(oftree_root(otree), buf, 32));
682 ut_asserteq_str("/", buf);
683
684 return 0;
685}
Simon Glass1a92f832024-08-22 07:57:48 -0600686DM_TEST(dm_test_ofnode_get_path_ot, UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -0600687
Simon Glass75b8a872023-09-26 08:14:39 -0600688/* test ofnode_conf_read_bool/int/str() */
Simon Glass0034d962021-08-07 07:24:01 -0600689static int dm_test_ofnode_conf(struct unit_test_state *uts)
690{
691 ut_assert(!ofnode_conf_read_bool("missing"));
692 ut_assert(ofnode_conf_read_bool("testing-bool"));
693
694 ut_asserteq(123, ofnode_conf_read_int("testing-int", 0));
695 ut_asserteq(6, ofnode_conf_read_int("missing", 6));
696
697 ut_assertnull(ofnode_conf_read_str("missing"));
698 ut_asserteq_str("testing", ofnode_conf_read_str("testing-str"));
699
700 return 0;
701}
Simon Glass1a92f832024-08-22 07:57:48 -0600702DM_TEST(dm_test_ofnode_conf, UTF_SCAN_FDT);
Michael Wallef1f87402021-10-15 15:15:18 +0200703
Michal Simek43c42bd2023-08-31 08:59:05 +0200704static int dm_test_ofnode_options(struct unit_test_state *uts)
705{
Michal Simek6a7c1ce2023-08-31 09:04:27 +0200706 u64 bootscr_address, bootscr_offset;
707 u64 bootscr_flash_offset, bootscr_flash_size;
Christian Marangi81ce47e2024-11-10 12:50:25 +0100708 ofnode node, phandle_node, target;
709
710 node = ofnode_path("/options/u-boot");
711 ut_assert(ofnode_valid(node));
Michal Simek43c42bd2023-08-31 08:59:05 +0200712
Christian Marangicdc38152024-10-01 14:24:44 +0200713 ut_assert(!ofnode_options_read_bool("missing"));
714 ut_assert(ofnode_options_read_bool("testing-bool"));
715
716 ut_asserteq(123, ofnode_options_read_int("testing-int", 0));
717 ut_asserteq(6, ofnode_options_read_int("missing", 6));
718
719 ut_assertnull(ofnode_options_read_str("missing"));
720 ut_asserteq_str("testing", ofnode_options_read_str("testing-str"));
721
Christian Marangi81ce47e2024-11-10 12:50:25 +0100722 ut_asserteq(-EINVAL, ofnode_options_get_by_phandle("missing", &phandle_node));
723
724 target = ofnode_path("/phandle-node-1");
725 ut_assert(ofnode_valid(target));
726 ut_assertok(ofnode_options_get_by_phandle("testing-phandle", &phandle_node));
727 ut_assert(ofnode_equal(target, phandle_node));
728
Michal Simek43c42bd2023-08-31 08:59:05 +0200729 ut_assertok(ofnode_read_bootscript_address(&bootscr_address,
730 &bootscr_offset));
731 ut_asserteq_64(0, bootscr_address);
732 ut_asserteq_64(0x12345678, bootscr_offset);
733
Michal Simek6a7c1ce2023-08-31 09:04:27 +0200734 ut_assertok(ofnode_read_bootscript_flash(&bootscr_flash_offset,
735 &bootscr_flash_size));
736 ut_asserteq_64(0, bootscr_flash_offset);
737 ut_asserteq_64(0x2000, bootscr_flash_size);
738
Michal Simek43c42bd2023-08-31 08:59:05 +0200739 return 0;
740}
741DM_TEST(dm_test_ofnode_options, 0);
742
Michael Wallef1f87402021-10-15 15:15:18 +0200743static int dm_test_ofnode_for_each_compatible_node(struct unit_test_state *uts)
744{
745 const char compatible[] = "denx,u-boot-fdt-test";
746 bool found = false;
747 ofnode node;
748
749 ofnode_for_each_compatible_node(node, compatible) {
750 ut_assert(ofnode_device_is_compatible(node, compatible));
751 found = true;
752 }
753
754 /* There should be at least one matching node */
755 ut_assert(found);
756
757 return 0;
758}
Simon Glass1a92f832024-08-22 07:57:48 -0600759DM_TEST(dm_test_ofnode_for_each_compatible_node, UTF_SCAN_FDT);
Simon Glass73025392021-10-23 17:26:04 -0600760
Simon Glass75b8a872023-09-26 08:14:39 -0600761/* test dm_test_ofnode_string_count/index/list() */
Simon Glass73025392021-10-23 17:26:04 -0600762static int dm_test_ofnode_string(struct unit_test_state *uts)
763{
Simon Glass9580bfc2021-10-23 17:26:07 -0600764 const char **val;
Simon Glass73025392021-10-23 17:26:04 -0600765 const char *out;
766 ofnode node;
767
768 node = ofnode_path("/a-test");
769 ut_assert(ofnode_valid(node));
770
771 /* single string */
772 ut_asserteq(1, ofnode_read_string_count(node, "str-value"));
773 ut_assertok(ofnode_read_string_index(node, "str-value", 0, &out));
774 ut_asserteq_str("test string", out);
775 ut_asserteq(0, ofnode_stringlist_search(node, "str-value",
776 "test string"));
Simon Glass9580bfc2021-10-23 17:26:07 -0600777 ut_asserteq(1, ofnode_read_string_list(node, "str-value", &val));
778 ut_asserteq_str("test string", val[0]);
779 ut_assertnull(val[1]);
780 free(val);
Simon Glass73025392021-10-23 17:26:04 -0600781
782 /* list of strings */
783 ut_asserteq(5, ofnode_read_string_count(node, "mux-control-names"));
784 ut_assertok(ofnode_read_string_index(node, "mux-control-names", 0,
785 &out));
786 ut_asserteq_str("mux0", out);
787 ut_asserteq(0, ofnode_stringlist_search(node, "mux-control-names",
788 "mux0"));
Simon Glass9580bfc2021-10-23 17:26:07 -0600789 ut_asserteq(5, ofnode_read_string_list(node, "mux-control-names",
790 &val));
791 ut_asserteq_str("mux0", val[0]);
792 ut_asserteq_str("mux1", val[1]);
793 ut_asserteq_str("mux2", val[2]);
794 ut_asserteq_str("mux3", val[3]);
795 ut_asserteq_str("mux4", val[4]);
796 ut_assertnull(val[5]);
797 free(val);
Simon Glass73025392021-10-23 17:26:04 -0600798
799 ut_assertok(ofnode_read_string_index(node, "mux-control-names", 4,
800 &out));
801 ut_asserteq_str("mux4", out);
802 ut_asserteq(4, ofnode_stringlist_search(node, "mux-control-names",
803 "mux4"));
804
805 return 0;
806}
Simon Glass1a92f832024-08-22 07:57:48 -0600807DM_TEST(dm_test_ofnode_string, UTF_SCAN_FDT);
Simon Glass73025392021-10-23 17:26:04 -0600808
Simon Glass75b8a872023-09-26 08:14:39 -0600809/* test error returns from ofnode_read_string_count/index/list() */
Simon Glass73025392021-10-23 17:26:04 -0600810static int dm_test_ofnode_string_err(struct unit_test_state *uts)
811{
Simon Glass9580bfc2021-10-23 17:26:07 -0600812 const char **val;
Simon Glass73025392021-10-23 17:26:04 -0600813 const char *out;
814 ofnode node;
815
816 /*
817 * Test error codes only on livetree, as they are different with
818 * flattree
819 */
820 node = ofnode_path("/a-test");
821 ut_assert(ofnode_valid(node));
822
823 /* non-existent property */
824 ut_asserteq(-EINVAL, ofnode_read_string_count(node, "missing"));
825 ut_asserteq(-EINVAL, ofnode_read_string_index(node, "missing", 0,
826 &out));
Simon Glass9580bfc2021-10-23 17:26:07 -0600827 ut_asserteq(-EINVAL, ofnode_read_string_list(node, "missing", &val));
Simon Glass73025392021-10-23 17:26:04 -0600828
829 /* empty property */
830 ut_asserteq(-ENODATA, ofnode_read_string_count(node, "bool-value"));
831 ut_asserteq(-ENODATA, ofnode_read_string_index(node, "bool-value", 0,
832 &out));
Simon Glass9580bfc2021-10-23 17:26:07 -0600833 ut_asserteq(-ENODATA, ofnode_read_string_list(node, "bool-value",
834 &val));
Simon Glass73025392021-10-23 17:26:04 -0600835
836 /* badly formatted string list */
837 ut_asserteq(-EILSEQ, ofnode_read_string_count(node, "int64-value"));
838 ut_asserteq(-EILSEQ, ofnode_read_string_index(node, "int64-value", 0,
839 &out));
Simon Glass9580bfc2021-10-23 17:26:07 -0600840 ut_asserteq(-EILSEQ, ofnode_read_string_list(node, "int64-value",
841 &val));
Simon Glass73025392021-10-23 17:26:04 -0600842
843 /* out of range / not found */
844 ut_asserteq(-ENODATA, ofnode_read_string_index(node, "str-value", 1,
845 &out));
846 ut_asserteq(-ENODATA, ofnode_stringlist_search(node, "str-value",
847 "other"));
848
849 /* negative value for index is not allowed, so don't test for that */
850
851 ut_asserteq(-ENODATA, ofnode_read_string_index(node,
852 "mux-control-names", 5,
853 &out));
854
855 return 0;
856}
Simon Glass1a92f832024-08-22 07:57:48 -0600857DM_TEST(dm_test_ofnode_string_err, UTF_LIVE_TREE);
Marek Behúnf4f1ddc2022-04-07 00:32:57 +0200858
Simon Glass75b8a872023-09-26 08:14:39 -0600859static int dm_test_ofnode_read_phy_mode(struct unit_test_state *uts)
Marek Behúnf4f1ddc2022-04-07 00:32:57 +0200860{
861 ofnode eth_node, phy_node;
Marek Behúnbc194772022-04-07 00:33:01 +0200862 phy_interface_t mode;
Marek Behúnf4f1ddc2022-04-07 00:32:57 +0200863 u32 reg;
864
865 eth_node = ofnode_path("/phy-test-eth");
866 ut_assert(ofnode_valid(eth_node));
867
Marek Behúnbc194772022-04-07 00:33:01 +0200868 mode = ofnode_read_phy_mode(eth_node);
869 ut_assert(mode == PHY_INTERFACE_MODE_2500BASEX);
870
Marek Behúnf4f1ddc2022-04-07 00:32:57 +0200871 phy_node = ofnode_get_phy_node(eth_node);
872 ut_assert(ofnode_valid(phy_node));
873
874 reg = ofnode_read_u32_default(phy_node, "reg", -1U);
875 ut_asserteq_64(0x1, reg);
876
877 return 0;
878}
Simon Glass1a92f832024-08-22 07:57:48 -0600879DM_TEST(dm_test_ofnode_read_phy_mode, UTF_SCAN_FDT);
Simon Glassef75c592022-07-30 15:52:08 -0600880
881/**
882 * make_ofnode_fdt() - Create an FDT for testing with ofnode
883 *
884 * The size is set to the minimum needed
885 *
886 * @uts: Test state
887 * @fdt: Place to write FDT
888 * @size: Maximum size of space for fdt
Simon Glass9e7a42a2022-09-06 20:27:30 -0600889 * @id: id value to add to the tree ('id' property in root node)
Simon Glassef75c592022-07-30 15:52:08 -0600890 */
Simon Glass9e7a42a2022-09-06 20:27:30 -0600891static int make_ofnode_fdt(struct unit_test_state *uts, void *fdt, int size,
892 int id)
Simon Glassef75c592022-07-30 15:52:08 -0600893{
894 ut_assertok(fdt_create(fdt, size));
895 ut_assertok(fdt_finish_reservemap(fdt));
896 ut_assert(fdt_begin_node(fdt, "") >= 0);
897
Simon Glass9e7a42a2022-09-06 20:27:30 -0600898 ut_assertok(fdt_property_u32(fdt, "id", id));
899
Simon Glassef75c592022-07-30 15:52:08 -0600900 ut_assert(fdt_begin_node(fdt, "aliases") >= 0);
901 ut_assertok(fdt_property_string(fdt, "mmc0", "/new-mmc"));
902 ut_assertok(fdt_end_node(fdt));
903
904 ut_assert(fdt_begin_node(fdt, "new-mmc") >= 0);
905 ut_assertok(fdt_end_node(fdt));
906
907 ut_assertok(fdt_end_node(fdt));
908 ut_assertok(fdt_finish(fdt));
909
910 return 0;
911}
912
Simon Glass75b8a872023-09-26 08:14:39 -0600913/* Check that aliases work on the control FDT */
914static int dm_test_ofnode_aliases(struct unit_test_state *uts)
Simon Glassef75c592022-07-30 15:52:08 -0600915{
Simon Glassef75c592022-07-30 15:52:08 -0600916 ofnode node;
917
Simon Glassef75c592022-07-30 15:52:08 -0600918 node = ofnode_get_aliases_node("ethernet3");
919 ut_assert(ofnode_valid(node));
920 ut_asserteq_str("sbe5", ofnode_get_name(node));
921
Simon Glass2b9b14582022-09-06 20:27:21 -0600922 ut_assert(!oftree_valid(oftree_null()));
923
Simon Glassc7599442022-10-20 18:22:49 -0600924 return 0;
925}
Simon Glass1a92f832024-08-22 07:57:48 -0600926DM_TEST(dm_test_ofnode_aliases, UTF_SCAN_FDT);
Simon Glassdad97512022-09-06 20:27:29 -0600927
Simon Glass75b8a872023-09-26 08:14:39 -0600928/**
929 * dm_test_ofnode_root_mult() - Check aliaes on control and 'other' tree
930 *
931 * Check that aliases work only with the control FDT, not with 'other' tree.
932 * This is not actually the desired behaviour. If aliases are implemented for
933 * any tree, then this test should be changed.
934 */
Simon Glassc7599442022-10-20 18:22:49 -0600935static int dm_test_ofnode_root_mult(struct unit_test_state *uts)
936{
937 char fdt[256];
938 oftree tree;
939 ofnode node;
Simon Glassdad97512022-09-06 20:27:29 -0600940
Simon Glassc7599442022-10-20 18:22:49 -0600941 /* skip this test if multiple FDTs are not supported */
942 if (!IS_ENABLED(CONFIG_OFNODE_MULTI_TREE))
943 return -EAGAIN;
944
945 ut_assertok(make_ofnode_fdt(uts, fdt, sizeof(fdt), 0));
946 ut_assertok(get_oftree(uts, fdt, &tree));
Simon Glass2b9b14582022-09-06 20:27:21 -0600947 ut_assert(oftree_valid(tree));
Simon Glassef75c592022-07-30 15:52:08 -0600948
949 /* Make sure they don't work on this new tree */
Simon Glass45ae59d2022-09-06 20:27:24 -0600950 node = oftree_path(tree, "mmc0");
Simon Glassef75c592022-07-30 15:52:08 -0600951 ut_assert(!ofnode_valid(node));
952
953 /* It should appear in the new tree */
Simon Glass45ae59d2022-09-06 20:27:24 -0600954 node = oftree_path(tree, "/new-mmc");
Simon Glassef75c592022-07-30 15:52:08 -0600955 ut_assert(ofnode_valid(node));
956
957 /* ...and not in the control FDT */
Simon Glass45ae59d2022-09-06 20:27:24 -0600958 node = oftree_path(oftree_default(), "/new-mmc");
Simon Glassef75c592022-07-30 15:52:08 -0600959 ut_assert(!ofnode_valid(node));
960
Simon Glassdad97512022-09-06 20:27:29 -0600961 free_oftree(tree);
Simon Glassef75c592022-07-30 15:52:08 -0600962
963 return 0;
964}
Simon Glass1a92f832024-08-22 07:57:48 -0600965DM_TEST(dm_test_ofnode_root_mult, UTF_SCAN_FDT);
Simon Glass270a4432022-07-30 15:52:09 -0600966
Simon Glass75b8a872023-09-26 08:14:39 -0600967/* test ofnode_set_enabled(), ofnode_write_prop() on a livetree */
Simon Glass270a4432022-07-30 15:52:09 -0600968static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts)
969{
970 struct udevice *dev;
971 ofnode node;
972
Simon Glass270a4432022-07-30 15:52:09 -0600973 /* Test enabling devices */
Simon Glass270a4432022-07-30 15:52:09 -0600974 node = ofnode_path("/usb@2");
975
Simon Glass3ee3d152022-07-30 15:52:13 -0600976 ut_assert(!ofnode_is_enabled(node));
977 ut_assertok(ofnode_set_enabled(node, true));
978 ut_asserteq(true, ofnode_is_enabled(node));
Simon Glass270a4432022-07-30 15:52:09 -0600979
980 device_bind_driver_to_node(dm_root(), "usb_sandbox", "usb@2", node,
981 &dev);
982 ut_assertok(uclass_find_device_by_seq(UCLASS_USB, 2, &dev));
983
984 /* Test string property setting */
Simon Glass270a4432022-07-30 15:52:09 -0600985 ut_assert(device_is_compatible(dev, "sandbox,usb"));
986 ofnode_write_string(node, "compatible", "gdsys,super-usb");
987 ut_assert(device_is_compatible(dev, "gdsys,super-usb"));
988 ofnode_write_string(node, "compatible", "sandbox,usb");
989 ut_assert(device_is_compatible(dev, "sandbox,usb"));
990
991 /* Test setting generic properties */
992
993 /* Non-existent in DTB */
994 ut_asserteq_64(FDT_ADDR_T_NONE, dev_read_addr(dev));
995 /* reg = 0x42, size = 0x100 */
Simon Glass5e2cd5e2022-07-30 15:52:10 -0600996 ut_assertok(ofnode_write_prop(node, "reg",
Simon Glass17abed02022-09-06 20:27:32 -0600997 "\x00\x00\x00\x42\x00\x00\x01\x00", 8,
998 false));
Simon Glass270a4432022-07-30 15:52:09 -0600999 ut_asserteq(0x42, dev_read_addr(dev));
1000
1001 /* Test disabling devices */
Simon Glass270a4432022-07-30 15:52:09 -06001002 device_remove(dev, DM_REMOVE_NORMAL);
1003 device_unbind(dev);
1004
Simon Glass3ee3d152022-07-30 15:52:13 -06001005 ut_assert(ofnode_is_enabled(node));
1006 ut_assertok(ofnode_set_enabled(node, false));
1007 ut_assert(!ofnode_is_enabled(node));
Simon Glass270a4432022-07-30 15:52:09 -06001008
1009 return 0;
1010}
Simon Glassb75dc162022-07-30 15:52:11 -06001011DM_TEST(dm_test_ofnode_livetree_writing,
Simon Glass1a92f832024-08-22 07:57:48 -06001012 UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glassd28e31e2022-07-30 15:52:14 -06001013
Simon Glass17abed02022-09-06 20:27:32 -06001014static int check_write_prop(struct unit_test_state *uts, ofnode node)
1015{
1016 char prop[] = "middle-name";
1017 char name[10];
1018 int len;
1019
1020 strcpy(name, "cecil");
1021 len = strlen(name) + 1;
1022 ut_assertok(ofnode_write_prop(node, prop, name, len, false));
1023 ut_asserteq_str(name, ofnode_read_string(node, prop));
1024
1025 /* change the underlying value, this should mess up the live tree */
1026 strcpy(name, "tony");
1027 if (of_live_active()) {
1028 ut_asserteq_str(name, ofnode_read_string(node, prop));
1029 } else {
1030 ut_asserteq_str("cecil", ofnode_read_string(node, prop));
1031 }
1032
1033 /* try again, this time copying the property */
1034 strcpy(name, "mary");
1035 ut_assertok(ofnode_write_prop(node, prop, name, len, true));
1036 ut_asserteq_str(name, ofnode_read_string(node, prop));
1037 strcpy(name, "leah");
1038
1039 /* both flattree and livetree behave the same */
1040 ut_asserteq_str("mary", ofnode_read_string(node, prop));
1041
1042 return 0;
1043}
1044
1045/* writing the tree with and without copying the property */
1046static int dm_test_ofnode_write_copy(struct unit_test_state *uts)
1047{
1048 ofnode node;
1049
1050 node = ofnode_path("/a-test");
1051 ut_assertok(check_write_prop(uts, node));
1052
1053 return 0;
1054}
Simon Glass1a92f832024-08-22 07:57:48 -06001055DM_TEST(dm_test_ofnode_write_copy, UTF_SCAN_FDT);
Simon Glass17abed02022-09-06 20:27:32 -06001056
Simon Glass75b8a872023-09-26 08:14:39 -06001057/* test writing a property to the 'other' tree */
Simon Glass17abed02022-09-06 20:27:32 -06001058static int dm_test_ofnode_write_copy_ot(struct unit_test_state *uts)
1059{
1060 oftree otree = get_other_oftree(uts);
1061 ofnode node, check_node;
1062
1063 node = oftree_path(otree, "/node");
1064 ut_assertok(check_write_prop(uts, node));
1065
1066 /* make sure the control FDT is not touched */
1067 check_node = ofnode_path("/node");
1068 ut_assertnull(ofnode_read_string(check_node, "middle-name"));
1069
1070 return 0;
1071}
Simon Glass1a92f832024-08-22 07:57:48 -06001072DM_TEST(dm_test_ofnode_write_copy_ot, UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glass17abed02022-09-06 20:27:32 -06001073
Simon Glass75b8a872023-09-26 08:14:39 -06001074/* test ofnode_read_u32_index/default() */
Simon Glassd28e31e2022-07-30 15:52:14 -06001075static int dm_test_ofnode_u32(struct unit_test_state *uts)
1076{
1077 ofnode node;
Simon Glasse3be5fc2022-09-06 20:27:18 -06001078 u32 val;
Simon Glassd28e31e2022-07-30 15:52:14 -06001079
1080 node = ofnode_path("/lcd");
1081 ut_assert(ofnode_valid(node));
1082 ut_asserteq(1366, ofnode_read_u32_default(node, "xres", 123));
1083 ut_assertok(ofnode_write_u32(node, "xres", 1367));
1084 ut_asserteq(1367, ofnode_read_u32_default(node, "xres", 123));
1085 ut_assertok(ofnode_write_u32(node, "xres", 1366));
1086
Simon Glasse3be5fc2022-09-06 20:27:18 -06001087 node = ofnode_path("/backlight");
1088 ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 0, &val));
1089 ut_asserteq(0, val);
1090 ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 1, &val));
1091 ut_asserteq(16, val);
1092 ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 8, &val));
1093 ut_asserteq(255, val);
1094 ut_asserteq(-EOVERFLOW,
1095 ofnode_read_u32_index(node, "brightness-levels", 9, &val));
1096 ut_asserteq(-EINVAL, ofnode_read_u32_index(node, "missing", 0, &val));
1097
Simon Glassd28e31e2022-07-30 15:52:14 -06001098 return 0;
1099}
Simon Glass1a92f832024-08-22 07:57:48 -06001100DM_TEST(dm_test_ofnode_u32, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass56bc3322022-09-06 20:27:02 -06001101
Simon Glass75b8a872023-09-26 08:14:39 -06001102/* test ofnode_read_u32_array() */
Simon Glasse3be5fc2022-09-06 20:27:18 -06001103static int dm_test_ofnode_u32_array(struct unit_test_state *uts)
1104{
1105 ofnode node;
1106 u32 val[10];
1107
1108 node = ofnode_path("/a-test");
1109 ut_assert(ofnode_valid(node));
1110 ut_assertok(ofnode_read_u32_array(node, "int-value", val, 1));
1111 ut_asserteq(-EINVAL, ofnode_read_u32_array(node, "missing", val, 1));
1112 ut_asserteq(-EOVERFLOW, ofnode_read_u32_array(node, "bool-value", val,
1113 1));
1114
1115 memset(val, '\0', sizeof(val));
1116 ut_assertok(ofnode_read_u32_array(node, "int-array", val + 1, 3));
1117 ut_asserteq(0, val[0]);
1118 ut_asserteq(5678, val[1]);
1119 ut_asserteq(9123, val[2]);
1120 ut_asserteq(4567, val[3]);
1121 ut_asserteq(0, val[4]);
1122 ut_asserteq(-EOVERFLOW, ofnode_read_u32_array(node, "int-array", val,
1123 4));
1124
1125 return 0;
1126}
Simon Glass1a92f832024-08-22 07:57:48 -06001127DM_TEST(dm_test_ofnode_u32_array, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glasse3be5fc2022-09-06 20:27:18 -06001128
Simon Glassc681e092023-09-26 08:14:45 -06001129/* test ofnode_read_u64() and ofnode_write_u64() */
1130static int dm_test_ofnode_u64(struct unit_test_state *uts)
Simon Glasse3be5fc2022-09-06 20:27:18 -06001131{
1132 ofnode node;
1133 u64 val;
1134
1135 node = ofnode_path("/a-test");
1136 ut_assert(ofnode_valid(node));
1137 ut_assertok(ofnode_read_u64(node, "int64-value", &val));
1138 ut_asserteq_64(0x1111222233334444, val);
Simon Glassc681e092023-09-26 08:14:45 -06001139 ut_assertok(ofnode_write_u64(node, "new-int64-value", 0x9876543210));
1140 ut_assertok(ofnode_read_u64(node, "new-int64-value", &val));
1141 ut_asserteq_64(0x9876543210, val);
1142
Simon Glasse3be5fc2022-09-06 20:27:18 -06001143 ut_asserteq(-EINVAL, ofnode_read_u64(node, "missing", &val));
1144
Michal Simek08a194e2023-08-25 11:37:46 +02001145 ut_assertok(ofnode_read_u64_index(node, "int64-array", 0, &val));
1146 ut_asserteq_64(0x1111222233334444, val);
1147 ut_assertok(ofnode_read_u64_index(node, "int64-array", 1, &val));
1148 ut_asserteq_64(0x4444333322221111, val);
1149 ut_asserteq(-EOVERFLOW,
1150 ofnode_read_u64_index(node, "int64-array", 2, &val));
1151 ut_asserteq(-EINVAL, ofnode_read_u64_index(node, "missing", 0, &val));
1152
Simon Glassc681e092023-09-26 08:14:45 -06001153 ut_assertok(ofnode_write_u64(node, "int64-array", 0x9876543210));
1154 ut_assertok(ofnode_read_u64_index(node, "int64-array", 0, &val));
1155 ut_asserteq_64(0x9876543210, val);
1156 ut_asserteq(-EOVERFLOW,
1157 ofnode_read_u64_index(node, "int64-array", 1, &val));
1158
Simon Glasse3be5fc2022-09-06 20:27:18 -06001159 return 0;
1160}
Simon Glass1a92f832024-08-22 07:57:48 -06001161DM_TEST(dm_test_ofnode_u64, UTF_SCAN_FDT);
Simon Glasse3be5fc2022-09-06 20:27:18 -06001162
Simon Glass56bc3322022-09-06 20:27:02 -06001163static int dm_test_ofnode_add_subnode(struct unit_test_state *uts)
1164{
1165 ofnode node, check, subnode;
1166 char buf[128];
1167
Simon Glass56bc3322022-09-06 20:27:02 -06001168 node = ofnode_path("/lcd");
1169 ut_assert(ofnode_valid(node));
1170 ut_assertok(ofnode_add_subnode(node, "edmund", &subnode));
1171 check = ofnode_path("/lcd/edmund");
1172 ut_asserteq(subnode.of_offset, check.of_offset);
1173 ut_assertok(ofnode_get_path(subnode, buf, sizeof(buf)));
1174 ut_asserteq_str("/lcd/edmund", buf);
1175
1176 if (of_live_active()) {
1177 struct device_node *child;
1178
1179 ut_assertok(of_add_subnode((void *)ofnode_to_np(node), "edmund",
1180 2, &child));
1181 ut_asserteq_str("ed", child->name);
1182 ut_asserteq_str("/lcd/ed", child->full_name);
1183 check = ofnode_path("/lcd/ed");
1184 ut_asserteq_ptr(child, check.np);
1185 ut_assertok(ofnode_get_path(np_to_ofnode(child), buf,
1186 sizeof(buf)));
1187 ut_asserteq_str("/lcd/ed", buf);
1188 }
1189
1190 /* An existing node should be returned with -EEXIST */
1191 ut_asserteq(-EEXIST, ofnode_add_subnode(node, "edmund", &check));
1192 ut_asserteq(subnode.of_offset, check.of_offset);
1193
1194 /* add a root node */
1195 node = ofnode_path("/");
1196 ut_assert(ofnode_valid(node));
1197 ut_assertok(ofnode_add_subnode(node, "lcd2", &subnode));
1198 check = ofnode_path("/lcd2");
1199 ut_asserteq(subnode.of_offset, check.of_offset);
1200 ut_assertok(ofnode_get_path(subnode, buf, sizeof(buf)));
1201 ut_asserteq_str("/lcd2", buf);
1202
1203 if (of_live_active()) {
1204 ulong start;
1205 int i;
1206
1207 /*
1208 * Make sure each of the three malloc()checks in
1209 * of_add_subnode() work
1210 */
1211 for (i = 0; i < 3; i++) {
1212 malloc_enable_testing(i);
1213 start = ut_check_free();
1214 ut_asserteq(-ENOMEM, ofnode_add_subnode(node, "anthony",
1215 &check));
1216 ut_assertok(ut_check_delta(start));
1217 }
1218
1219 /* This should pass since we allow 3 allocations */
1220 malloc_enable_testing(3);
1221 ut_assertok(ofnode_add_subnode(node, "anthony", &check));
1222 malloc_disable_testing();
1223 }
1224
Simon Glass238afb52022-09-06 20:27:03 -06001225 /* write to the empty node */
1226 ut_assertok(ofnode_write_string(subnode, "example", "text"));
1227
Simon Glass56bc3322022-09-06 20:27:02 -06001228 return 0;
1229}
Simon Glass1a92f832024-08-22 07:57:48 -06001230DM_TEST(dm_test_ofnode_add_subnode, UTF_SCAN_PDATA | UTF_SCAN_FDT);
Simon Glass4caa79a2022-09-06 20:27:16 -06001231
1232static int dm_test_ofnode_for_each_prop(struct unit_test_state *uts)
1233{
1234 ofnode node, subnode;
1235 struct ofprop prop;
1236 int count;
1237
Dzmitry Sankouski54f4c832023-01-22 18:21:23 +03001238 node = ofnode_path("/ofnode-foreach");
Simon Glass4caa79a2022-09-06 20:27:16 -06001239 count = 0;
1240
1241 /* we expect "compatible" for each node */
1242 ofnode_for_each_prop(prop, node)
1243 count++;
1244 ut_asserteq(1, count);
1245
1246 /* there are two nodes, each with 2 properties */
1247 ofnode_for_each_subnode(subnode, node)
1248 ofnode_for_each_prop(prop, subnode)
1249 count++;
1250 ut_asserteq(5, count);
1251
1252 return 0;
1253}
Simon Glass1a92f832024-08-22 07:57:48 -06001254DM_TEST(dm_test_ofnode_for_each_prop, UTF_SCAN_FDT);
Simon Glasse3be5fc2022-09-06 20:27:18 -06001255
1256static int dm_test_ofnode_by_compatible(struct unit_test_state *uts)
1257{
1258 const char *compat = "denx,u-boot-fdt-test";
1259 ofnode node;
1260 int count;
1261
1262 count = 0;
1263 for (node = ofnode_null();
1264 node = ofnode_by_compatible(node, compat), ofnode_valid(node);)
1265 count++;
1266 ut_asserteq(11, count);
1267
1268 return 0;
1269}
Simon Glass1a92f832024-08-22 07:57:48 -06001270DM_TEST(dm_test_ofnode_by_compatible, UTF_SCAN_FDT);
Simon Glasse3be5fc2022-09-06 20:27:18 -06001271
Simon Glass75b8a872023-09-26 08:14:39 -06001272/* check ofnode_by_compatible() on the 'other' tree */
Simon Glass9e7a42a2022-09-06 20:27:30 -06001273static int dm_test_ofnode_by_compatible_ot(struct unit_test_state *uts)
1274{
1275 const char *compat = "sandbox-other2";
1276 oftree otree = get_other_oftree(uts);
1277 ofnode node;
1278 int count;
1279
1280 count = 0;
1281 for (node = oftree_root(otree);
1282 node = ofnode_by_compatible(node, compat), ofnode_valid(node);)
1283 count++;
1284 ut_asserteq(2, count);
1285
1286 return 0;
1287}
Simon Glass1a92f832024-08-22 07:57:48 -06001288DM_TEST(dm_test_ofnode_by_compatible_ot, UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -06001289
Simon Glasse3be5fc2022-09-06 20:27:18 -06001290static int dm_test_ofnode_find_subnode(struct unit_test_state *uts)
1291{
1292 ofnode node, subnode;
1293
1294 node = ofnode_path("/buttons");
1295
1296 subnode = ofnode_find_subnode(node, "btn1");
1297 ut_assert(ofnode_valid(subnode));
1298 ut_asserteq_str("btn1", ofnode_get_name(subnode));
1299
1300 subnode = ofnode_find_subnode(node, "btn");
1301 ut_assert(!ofnode_valid(subnode));
1302
1303 return 0;
1304}
Simon Glass1a92f832024-08-22 07:57:48 -06001305DM_TEST(dm_test_ofnode_find_subnode, UTF_SCAN_FDT);
Simon Glasse3be5fc2022-09-06 20:27:18 -06001306
Simon Glass4afa1912025-01-10 17:00:29 -07001307/* check ofnode_find_subnode() with unit addresses */
1308static int dm_test_ofnode_find_subnode_unit(struct unit_test_state *uts)
1309{
1310 ofnode node, subnode;
1311
1312 node = ofnode_path("/some-bus");
1313 ut_assert(ofnode_valid(node));
1314 subnode = ofnode_find_subnode_unit(node, "c-test@5");
1315 ut_assert(ofnode_valid(subnode));
1316 ut_asserteq_str("c-test@5", ofnode_get_name(subnode));
1317
1318 subnode = ofnode_find_subnode_unit(node, "c-test");
1319 ut_assert(ofnode_valid(subnode));
1320 ut_asserteq_str("c-test@5", ofnode_get_name(subnode));
1321
1322 return 0;
1323}
1324DM_TEST(dm_test_ofnode_find_subnode_unit, UTF_SCAN_FDT);
1325
Simon Glass75b8a872023-09-26 08:14:39 -06001326/* test ofnode_find_subnode() on the 'other' tree */
Simon Glass9e7a42a2022-09-06 20:27:30 -06001327static int dm_test_ofnode_find_subnode_ot(struct unit_test_state *uts)
1328{
1329 oftree otree = get_other_oftree(uts);
1330 ofnode node, subnode;
1331
1332 node = oftree_path(otree, "/node");
1333
1334 subnode = ofnode_find_subnode(node, "subnode");
1335 ut_assert(ofnode_valid(subnode));
1336 ut_asserteq_str("subnode", ofnode_get_name(subnode));
1337
1338 subnode = ofnode_find_subnode(node, "btn");
1339 ut_assert(!ofnode_valid(subnode));
1340
1341 return 0;
1342}
Simon Glass1a92f832024-08-22 07:57:48 -06001343DM_TEST(dm_test_ofnode_find_subnode_ot, UTF_OTHER_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -06001344
Simon Glasse3be5fc2022-09-06 20:27:18 -06001345static int dm_test_ofnode_get_name(struct unit_test_state *uts)
1346{
1347 ofnode node;
1348
1349 node = ofnode_path("/buttons");
1350 ut_assert(ofnode_valid(node));
1351 ut_asserteq_str("buttons", ofnode_get_name(node));
1352 ut_asserteq_str("", ofnode_get_name(ofnode_root()));
1353
1354 return 0;
1355}
Simon Glass1a92f832024-08-22 07:57:48 -06001356DM_TEST(dm_test_ofnode_get_name, UTF_SCAN_FDT);
Simon Glass9e7a42a2022-09-06 20:27:30 -06001357
1358/* try to access more FDTs than is supported */
1359static int dm_test_ofnode_too_many(struct unit_test_state *uts)
1360{
1361 const int max_trees = CONFIG_IS_ENABLED(OFNODE_MULTI_TREE,
1362 (CONFIG_OFNODE_MULTI_TREE_MAX), (1));
1363 const int fdt_size = 256;
1364 const int num_trees = max_trees + 1;
1365 char fdt[num_trees][fdt_size];
1366 int i;
1367
1368 for (i = 0; i < num_trees; i++) {
1369 oftree tree;
1370 int ret;
1371
1372 ut_assertok(make_ofnode_fdt(uts, fdt[i], fdt_size, i));
1373 ret = get_oftree(uts, fdt[i], &tree);
1374
1375 /*
1376 * With flat tree we have the control FDT using one slot. Live
1377 * tree has no limit since it uses pointers, not integer tree
1378 * IDs
1379 */
1380 if (of_live_active() || i < max_trees - 1) {
1381 ut_assertok(ret);
1382 } else {
1383 /*
1384 * tree should be invalid when we try to register too
1385 * many trees
1386 */
1387 ut_asserteq(-EOVERFLOW, ret);
1388 }
1389 }
1390
1391 return 0;
1392}
Simon Glass1a92f832024-08-22 07:57:48 -06001393DM_TEST(dm_test_ofnode_too_many, UTF_SCAN_FDT);
Simon Glass7a7229a2022-09-06 20:27:33 -06001394
Simon Glass68164892023-09-26 08:14:37 -06001395static int check_copy_props(struct unit_test_state *uts, ofnode dst, ofnode src)
Simon Glass7a7229a2022-09-06 20:27:33 -06001396{
1397 u32 reg[2], val;
1398
Simon Glass68164892023-09-26 08:14:37 -06001399 ut_assertok(ofnode_copy_props(dst, src));
Simon Glass7a7229a2022-09-06 20:27:33 -06001400
1401 ut_assertok(ofnode_read_u32(dst, "ping-expect", &val));
1402 ut_asserteq(3, val);
1403
1404 ut_asserteq_str("denx,u-boot-fdt-test",
1405 ofnode_read_string(dst, "compatible"));
1406
1407 /* check that a property with the same name is overwritten */
1408 ut_assertok(ofnode_read_u32_array(dst, "reg", reg, ARRAY_SIZE(reg)));
1409 ut_asserteq(3, reg[0]);
1410 ut_asserteq(1, reg[1]);
1411
1412 /* reset the compatible so the live tree does not change */
1413 ut_assertok(ofnode_write_string(dst, "compatible", "nothing"));
1414
1415 return 0;
1416}
1417
1418static int dm_test_ofnode_copy_props(struct unit_test_state *uts)
1419{
1420 ofnode src, dst;
1421
1422 /*
1423 * These nodes are chosen so that the src node is before the destination
1424 * node in the tree. This doesn't matter with livetree, but with
1425 * flattree any attempt to insert a property earlier in the tree will
1426 * mess up the offsets after it.
1427 */
1428 src = ofnode_path("/b-test");
1429 dst = ofnode_path("/some-bus");
1430
Simon Glass68164892023-09-26 08:14:37 -06001431 ut_assertok(check_copy_props(uts, dst, src));
Simon Glass7a7229a2022-09-06 20:27:33 -06001432
1433 /* check a property that is in the destination already */
1434 ut_asserteq_str("mux0", ofnode_read_string(dst, "mux-control-names"));
1435
1436 return 0;
1437}
Simon Glass1a92f832024-08-22 07:57:48 -06001438DM_TEST(dm_test_ofnode_copy_props, UTF_SCAN_FDT);
Simon Glass7a7229a2022-09-06 20:27:33 -06001439
Simon Glass75b8a872023-09-26 08:14:39 -06001440/* test ofnode_copy_props() with the 'other' tree */
Simon Glass7a7229a2022-09-06 20:27:33 -06001441static int dm_test_ofnode_copy_props_ot(struct unit_test_state *uts)
1442{
1443 ofnode src, dst;
1444 oftree otree = get_other_oftree(uts);
1445
1446 src = ofnode_path("/b-test");
1447 dst = oftree_path(otree, "/node/subnode2");
Simon Glass68164892023-09-26 08:14:37 -06001448 ut_assertok(check_copy_props(uts, dst, src));
Simon Glass7a7229a2022-09-06 20:27:33 -06001449
1450 return 0;
1451}
Simon Glass1a92f832024-08-22 07:57:48 -06001452DM_TEST(dm_test_ofnode_copy_props_ot, UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glasse88e2fe2023-06-01 10:22:40 -06001453
1454/* check that the livetree is aligned to a structure boundary */
1455static int dm_test_livetree_align(struct unit_test_state *uts)
1456{
1457 const int align = __alignof__(struct unit_test_state);
1458 struct device_node *node;
1459 u32 *sentinel;
1460 ulong start;
1461
1462 start = (ulong)gd_of_root();
1463 ut_asserteq(start, ALIGN(start, align));
1464
1465 node = gd_of_root();
1466 sentinel = (void *)node - sizeof(u32);
1467
1468 /*
1469 * The sentinel should be overwritten with the root node. If it isn't,
1470 * then the root node is not at the very start of the livetree memory
1471 * area, and free(root) will fail to free the memory used by the
1472 * livetree.
1473 */
1474 ut_assert(*sentinel != BAD_OF_ROOT);
1475
1476 return 0;
1477}
Simon Glass1a92f832024-08-22 07:57:48 -06001478DM_TEST(dm_test_livetree_align, UTF_SCAN_FDT | UTF_LIVE_TREE);
Simon Glass722281b2023-06-01 10:22:42 -06001479
1480/* check that it is possible to load an arbitrary livetree */
1481static int dm_test_livetree_ensure(struct unit_test_state *uts)
1482{
1483 oftree tree;
1484 ofnode node;
1485
1486 /* read from other.dtb */
1487 ut_assertok(test_load_other_fdt(uts));
1488 tree = oftree_from_fdt(uts->other_fdt);
1489 ut_assert(oftree_valid(tree));
1490 node = oftree_path(tree, "/node/subnode");
1491 ut_assert(ofnode_valid(node));
1492 ut_asserteq_str("sandbox-other2",
1493 ofnode_read_string(node, "compatible"));
1494
1495 return 0;
1496}
Simon Glass1a92f832024-08-22 07:57:48 -06001497DM_TEST(dm_test_livetree_ensure, UTF_SCAN_FDT);
Simon Glassa869a1b2023-09-26 08:14:40 -06001498
1499static int dm_test_oftree_new(struct unit_test_state *uts)
1500{
1501 ofnode node, subnode, check;
1502 oftree tree;
1503
1504 ut_assertok(oftree_new(&tree));
1505 node = oftree_root(tree);
1506 ut_assert(ofnode_valid(node));
1507 ut_assertok(ofnode_add_subnode(node, "edmund", &subnode));
1508 check = ofnode_find_subnode(node, "edmund");
1509 ut_asserteq(check.of_offset, subnode.of_offset);
1510
1511 return 0;
1512}
Simon Glass1a92f832024-08-22 07:57:48 -06001513DM_TEST(dm_test_oftree_new, UTF_SCAN_FDT);
Simon Glass7c33c962023-09-26 08:14:41 -06001514
1515static int check_copy_node(struct unit_test_state *uts, ofnode dst, ofnode src,
1516 ofnode *nodep)
1517{
1518 u32 reg[2], val;
1519 ofnode node;
1520
1521 ut_assertok(ofnode_copy_node(dst, "copy-test", src, &node));
1522
1523 ut_assertok(ofnode_read_u32(node, "ping-expect", &val));
1524 ut_asserteq(3, val);
1525
1526 ut_asserteq_str("denx,u-boot-fdt-test",
1527 ofnode_read_string(node, "compatible"));
1528
1529 /* check that a property with the same name is overwritten */
1530 ut_assertok(ofnode_read_u32_array(node, "reg", reg, ARRAY_SIZE(reg)));
1531 ut_asserteq(3, reg[0]);
1532 ut_asserteq(1, reg[1]);
1533
1534 /* reset the compatible so the live tree does not change */
1535 ut_assertok(ofnode_write_string(node, "compatible", "nothing"));
1536 *nodep = node;
1537
1538 return 0;
1539}
1540
1541static int dm_test_ofnode_copy_node(struct unit_test_state *uts)
1542{
1543 ofnode src, dst, node, try;
1544
1545 /*
1546 * These nodes are chosen so that the src node is before the destination
1547 * node in the tree. This doesn't matter with livetree, but with
1548 * flattree any attempt to insert a property earlier in the tree will
1549 * mess up the offsets after it.
1550 */
1551 src = ofnode_path("/b-test");
1552 dst = ofnode_path("/some-bus");
1553
1554 ut_assertok(check_copy_node(uts, dst, src, &node));
1555
1556 /* check trying to copy over an existing node */
1557 ut_asserteq(-EEXIST, ofnode_copy_node(dst, "copy-test", src, &try));
1558 ut_asserteq(try.of_offset, node.of_offset);
1559
1560 return 0;
1561}
Simon Glass1a92f832024-08-22 07:57:48 -06001562DM_TEST(dm_test_ofnode_copy_node, UTF_SCAN_FDT);
Simon Glass7c33c962023-09-26 08:14:41 -06001563
1564/* test ofnode_copy_node() with the 'other' tree */
1565static int dm_test_ofnode_copy_node_ot(struct unit_test_state *uts)
1566{
1567 oftree otree = get_other_oftree(uts);
1568 ofnode src, dst, node;
1569
1570 src = ofnode_path("/b-test");
1571 dst = oftree_path(otree, "/node/subnode2");
1572 ut_assertok(check_copy_node(uts, dst, src, &node));
1573
1574 return 0;
1575}
Simon Glass1a92f832024-08-22 07:57:48 -06001576DM_TEST(dm_test_ofnode_copy_node_ot, UTF_SCAN_FDT | UTF_OTHER_FDT);
Simon Glass45448772023-09-26 08:14:42 -06001577
1578static int dm_test_ofnode_delete(struct unit_test_state *uts)
1579{
1580 ofnode node;
1581
1582 /*
1583 * At present the livetree is not restored after changes made in tests.
1584 * See test_pre_run() for how this is done with the other FDT and
1585 * dm_test_pre_run() where it sets up the root-tree pointer. So use
1586 * nodes which don't matter to other tests.
1587 *
1588 * We could fix this by detecting livetree changes and regenerating it
1589 * before the next test if needed.
1590 */
1591 node = ofnode_path("/leds/iracibble");
1592 ut_assert(ofnode_valid(node));
1593 ut_assertok(ofnode_delete(&node));
1594 ut_assert(!ofnode_valid(node));
1595 ut_assert(!ofnode_valid(ofnode_path("/leds/iracibble")));
1596
1597 node = ofnode_path("/leds/default_on");
1598 ut_assert(ofnode_valid(node));
1599 ut_assertok(ofnode_delete(&node));
1600 ut_assert(!ofnode_valid(node));
1601 ut_assert(!ofnode_valid(ofnode_path("/leds/default_on")));
1602
Heiko Schocher350d2522025-01-28 14:52:46 +01001603 ut_asserteq(7, ofnode_get_child_count(ofnode_path("/leds")));
Simon Glass45448772023-09-26 08:14:42 -06001604
1605 return 0;
1606}
Simon Glass1a92f832024-08-22 07:57:48 -06001607DM_TEST(dm_test_ofnode_delete, UTF_SCAN_FDT);
Simon Glassebbe90b2023-09-26 08:14:43 -06001608
1609static int dm_test_oftree_to_fdt(struct unit_test_state *uts)
1610{
1611 oftree tree, check;
1612 struct abuf buf, buf2;
1613
1614 tree = oftree_default();
1615 ut_assertok(oftree_to_fdt(tree, &buf));
1616 ut_assert(abuf_size(&buf) > SZ_16K);
1617
1618 /* convert it back to a tree and see if it looks OK */
1619 check = oftree_from_fdt(abuf_data(&buf));
1620 ut_assert(oftree_valid(check));
1621
1622 ut_assertok(oftree_to_fdt(check, &buf2));
1623 ut_assert(abuf_size(&buf2) > SZ_16K);
1624 ut_asserteq(abuf_size(&buf), abuf_size(&buf2));
1625 ut_asserteq_mem(abuf_data(&buf), abuf_data(&buf2), abuf_size(&buf));
1626
1627 return 0;
1628}
Simon Glass1a92f832024-08-22 07:57:48 -06001629DM_TEST(dm_test_oftree_to_fdt, UTF_SCAN_FDT);
Simon Glass86ef3992023-09-26 08:14:44 -06001630
1631/* test ofnode_read_bool() and ofnode_write_bool() */
1632static int dm_test_bool(struct unit_test_state *uts)
1633{
1634 const char *propname = "missing-bool-value";
1635 ofnode node;
1636
1637 node = ofnode_path("/a-test");
1638 ut_assert(ofnode_read_bool(node, "bool-value"));
1639 ut_assert(!ofnode_read_bool(node, propname));
1640 ut_assert(!ofnode_has_property(node, propname));
1641
1642 ut_assertok(ofnode_write_bool(node, propname, true));
1643 ut_assert(ofnode_read_bool(node, propname));
1644 ut_assert(ofnode_has_property(node, propname));
1645 ut_assert(ofnode_read_bool(node, "bool-value"));
1646
1647 ut_assertok(ofnode_write_bool(node, propname, false));
1648 ut_assert(!ofnode_read_bool(node, propname));
1649 ut_assert(!ofnode_has_property(node, propname));
1650 ut_assert(ofnode_read_bool(node, "bool-value"));
1651
1652 return 0;
1653}
Simon Glass1a92f832024-08-22 07:57:48 -06001654DM_TEST(dm_test_bool, UTF_SCAN_FDT);
Svyatoslav Ryhel1f5298f2025-02-16 13:14:40 +02001655
1656/* test all helpers found in drivers/core/ofnode_graph.c */
1657static int dm_test_ofnode_graph(struct unit_test_state *uts)
1658{
1659 /* 3 ports with 5 endpoints (2-1-2) */
1660 ofnode graph1 = ofnode_path("/graph1");
1661 /* 1 port with 1 endpoint */
1662 ofnode graph2 = ofnode_path("/graph2");
1663 ofnode node;
1664 u32 id;
1665
1666 ut_asserteq(ofnode_graph_get_endpoint_count(graph1), 5);
1667 ut_asserteq(ofnode_graph_get_endpoint_count(graph2), 1);
1668
1669 ut_asserteq(ofnode_graph_get_port_count(graph1), 3);
1670 ut_asserteq(ofnode_graph_get_port_count(graph2), 1);
1671
1672 /* Request port with reg 2 */
1673 node = ofnode_graph_get_port_by_id(graph1, 2);
1674 ofnode_read_u32(node, "reg", &id);
1675 ut_asserteq(id, 2);
1676
1677 /* Reqest parent from prev requested endpoint */
1678 node = ofnode_graph_get_port_parent(node);
1679 ut_asserteq_str(ofnode_get_name(node), "graph1");
1680
1681 /* Request endpoint under port 1 */
1682 node = ofnode_graph_get_endpoint_by_regs(graph1, 1, -1);
1683 ut_assert(ofnode_has_property(node, "test-property-0"));
1684
1685 /* Reqest remote endpoint from graph2 in graph1 */
1686 node = ofnode_graph_get_endpoint_by_regs(graph2, -1, -1);
1687 node = ofnode_graph_get_remote_endpoint(node);
1688 ut_assert(ofnode_has_property(node, "test-property-1"));
1689
1690 /* Reqest remote parent from graph2 linked endpoint */
1691 node = ofnode_graph_get_endpoint_by_regs(graph2, -1, -1);
1692 node = ofnode_graph_get_remote_port_parent(node);
1693 ut_asserteq_str(ofnode_get_name(node), "graph1");
1694
1695 /* Reqest remote port from graph2 linked endpoint */
1696 node = ofnode_graph_get_endpoint_by_regs(graph2, -1, -1);
1697 node = ofnode_graph_get_remote_port(node);
1698 ofnode_read_u32(node, "reg", &id);
1699 ut_asserteq(id, 2);
1700
1701 /* Reqest remote parent from graph2 linked endpoint */
1702 node = ofnode_graph_get_remote_node(graph2, -1, -1);
1703 ut_asserteq_str(ofnode_get_name(node), "graph1");
1704
1705 return 0;
1706}
1707DM_TEST(dm_test_ofnode_graph, UTF_SCAN_FDT);