1 // SPDX-License-Identifier: GPL-2.0+
3 * Tests for fdt command
5 * Copyright 2022 Google LLCmap_to_sysmem(fdt));
10 #include <fdt_support.h>
12 #include <asm/global_data.h>
13 #include <linux/libfdt.h>
14 #include <test/suites.h>
17 DECLARE_GLOBAL_DATA_PTR;
20 * fdt boardsetup - Do board-specific set up
21 * fdt checksign [<addr>] - check FIT signature
22 * <addr> - address of key blob
23 * default gd->fdt_blob
26 /* Declare a new fdt test */
27 #define FDT_TEST(_name, _flags) UNIT_TEST(_name, _flags, fdt_test)
30 * make_test_fdt() - Create an FDT with just a root node
32 * The size is set to the minimum needed
35 * @fdt: Place to write FDT
36 * @size: Maximum size of space for fdt
38 static int make_test_fdt(struct unit_test_state *uts, void *fdt, int size)
40 ut_assertok(fdt_create(fdt, size));
41 ut_assertok(fdt_finish_reservemap(fdt));
42 ut_assert(fdt_begin_node(fdt, "") >= 0);
43 ut_assertok(fdt_end_node(fdt));
44 ut_assertok(fdt_finish(fdt));
50 * make_fuller_fdt() - Create an FDT with root node and properties
52 * The size is set to the minimum needed
55 * @fdt: Place to write FDT
56 * @size: Maximum size of space for fdt
58 static int make_fuller_fdt(struct unit_test_state *uts, void *fdt, int size)
60 fdt32_t regs[2] = { cpu_to_fdt32(0x1234), cpu_to_fdt32(0x1000) };
63 * Assemble the following DT for test purposes:
66 * #address-cells = <0x00000001>;
67 * #size-cells = <0x00000001>;
68 * compatible = "u-boot,fdt-test";
69 * model = "U-Boot FDT test";
72 * badalias = "/bad/alias";
73 * subnodealias = "/test-node@1234/subnode";
74 * testnodealias = "/test-node@1234";
78 * #address-cells = <0x00000000>;
79 * #size-cells = <0x00000000>;
80 * compatible = "u-boot,fdt-test-device1";
81 * clock-names = "fixed", "i2c", "spi", "uart2", "uart1";
82 * u-boot,empty-property;
83 * clock-frequency = <0x00fde800>;
84 * regs = <0x00001234 0x00001000>;
87 * #address-cells = <0x00000000>;
88 * #size-cells = <0x00000000>;
89 * compatible = "u-boot,fdt-subnode-test-device";
95 ut_assertok(fdt_create(fdt, size));
96 ut_assertok(fdt_finish_reservemap(fdt));
97 ut_assert(fdt_begin_node(fdt, "") >= 0);
99 ut_assertok(fdt_property_u32(fdt, "#address-cells", 1));
100 ut_assertok(fdt_property_u32(fdt, "#size-cells", 1));
102 ut_assertok(fdt_property_string(fdt, "compatible", "u-boot,fdt-test"));
104 ut_assertok(fdt_property_string(fdt, "model", "U-Boot FDT test"));
106 ut_assert(fdt_begin_node(fdt, "aliases") >= 0);
108 ut_assertok(fdt_property_string(fdt, "badalias", "/bad/alias"));
110 ut_assertok(fdt_property_string(fdt, "subnodealias", "/test-node@1234/subnode"));
112 ut_assertok(fdt_property_string(fdt, "testnodealias", "/test-node@1234"));
113 ut_assertok(fdt_end_node(fdt));
115 ut_assert(fdt_begin_node(fdt, "test-node@1234") >= 0);
116 ut_assertok(fdt_property_cell(fdt, "#address-cells", 0));
117 ut_assertok(fdt_property_cell(fdt, "#size-cells", 0));
119 ut_assertok(fdt_property_string(fdt, "compatible", "u-boot,fdt-test-device1"));
121 ut_assertok(fdt_property(fdt, "clock-names", "fixed\0i2c\0spi\0uart2\0uart1\0", 26));
123 ut_assertok(fdt_property(fdt, "u-boot,empty-property", NULL, 0));
126 * This value is deliberate as it used to break cmd/fdt.c
127 * is_printable_string() implementation.
129 ut_assertok(fdt_property_u32(fdt, "clock-frequency", 16640000));
130 /* <prop-encoded-array> */
131 ut_assertok(fdt_property(fdt, "regs", ®s, sizeof(regs)));
132 ut_assert(fdt_begin_node(fdt, "subnode") >= 0);
133 ut_assertok(fdt_property_cell(fdt, "#address-cells", 0));
134 ut_assertok(fdt_property_cell(fdt, "#size-cells", 0));
135 ut_assertok(fdt_property_string(fdt, "compatible", "u-boot,fdt-subnode-test-device"));
136 ut_assertok(fdt_end_node(fdt));
137 ut_assertok(fdt_end_node(fdt));
139 ut_assertok(fdt_end_node(fdt));
140 ut_assertok(fdt_finish(fdt));
145 /* Test 'fdt addr' getting/setting address */
146 static int fdt_test_addr(struct unit_test_state *uts)
148 const void *fdt_blob, *new_fdt;
153 ut_assertok(console_record_reset_enable());
154 ut_assertok(run_command("fdt addr -c", 0));
155 ut_assert_nextline("Control fdt: %08lx",
156 (ulong)map_to_sysmem(gd->fdt_blob));
157 ut_assertok(ut_check_console_end(uts));
159 /* The working fdt is not set, so this should fail */
160 set_working_fdt_addr(0);
161 ut_assert_nextline("Working FDT set to 0");
162 ut_asserteq(CMD_RET_FAILURE, run_command("fdt addr", 0));
163 ut_assert_nextline("libfdt fdt_check_header(): FDT_ERR_BADMAGIC");
164 ut_assertok(ut_check_console_end(uts));
166 /* Set up a working FDT and try again */
167 ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt)));
168 addr = map_to_sysmem(fdt);
169 set_working_fdt_addr(addr);
170 ut_assert_nextline("Working FDT set to %lx", addr);
171 ut_assertok(run_command("fdt addr", 0));
172 ut_assert_nextline("Working fdt: %08lx", (ulong)map_to_sysmem(fdt));
173 ut_assertok(ut_check_console_end(uts));
175 /* Set the working FDT */
176 set_working_fdt_addr(0);
177 ut_assert_nextline("Working FDT set to 0");
178 ut_assertok(run_commandf("fdt addr %08lx", addr));
179 ut_assert_nextline("Working FDT set to %lx", addr);
180 ut_asserteq(addr, map_to_sysmem(working_fdt));
181 ut_assertok(ut_check_console_end(uts));
182 set_working_fdt_addr(0);
183 ut_assert_nextline("Working FDT set to 0");
185 /* Set the control FDT */
186 fdt_blob = gd->fdt_blob;
188 ret = run_commandf("fdt addr -c %08lx", addr);
189 new_fdt = gd->fdt_blob;
190 gd->fdt_blob = fdt_blob;
192 ut_asserteq(addr, map_to_sysmem(new_fdt));
193 ut_assertok(ut_check_console_end(uts));
195 /* Test setting an invalid FDT */
197 ut_asserteq(1, run_commandf("fdt addr %08lx", addr));
198 ut_assert_nextline("libfdt fdt_check_header(): FDT_ERR_BADMAGIC");
199 ut_assertok(ut_check_console_end(uts));
201 /* Test detecting an invalid FDT */
203 set_working_fdt_addr(addr);
204 ut_assert_nextline("Working FDT set to %lx", addr);
205 ut_asserteq(1, run_commandf("fdt addr"));
206 ut_assert_nextline("libfdt fdt_check_header(): FDT_ERR_BADMAGIC");
207 ut_assertok(ut_check_console_end(uts));
211 FDT_TEST(fdt_test_addr, UT_TESTF_CONSOLE_REC);
213 /* Test 'fdt addr' resizing an fdt */
214 static int fdt_test_addr_resize(struct unit_test_state *uts)
217 const int newsize = sizeof(fdt) / 2;
220 ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt)));
221 addr = map_to_sysmem(fdt);
222 set_working_fdt_addr(addr);
224 /* Test setting and resizing the working FDT to a larger size */
225 ut_assertok(console_record_reset_enable());
226 ut_assertok(run_commandf("fdt addr %08lx %x", addr, newsize));
227 ut_assert_nextline("Working FDT set to %lx", addr);
228 ut_assertok(ut_check_console_end(uts));
230 /* Try shrinking it */
231 ut_assertok(run_commandf("fdt addr %08lx %zx", addr, sizeof(fdt) / 4));
232 ut_assert_nextline("Working FDT set to %lx", addr);
233 ut_assert_nextline("New length %d < existing length %d, ignoring",
234 (int)sizeof(fdt) / 4, newsize);
235 ut_assertok(ut_check_console_end(uts));
238 ut_assertok(run_commandf("fdt addr -q %08lx %zx", addr, sizeof(fdt) / 4));
239 ut_assertok(ut_check_console_end(uts));
241 /* We cannot easily provoke errors in fdt_open_into(), so ignore that */
245 FDT_TEST(fdt_test_addr_resize, UT_TESTF_CONSOLE_REC);
247 static int fdt_test_move(struct unit_test_state *uts)
250 ulong addr, newaddr = 0x10000;
251 const int size = sizeof(fdt);
255 /* Original source DT */
256 ut_assertok(make_test_fdt(uts, fdt, size));
257 ts = fdt_totalsize(fdt);
258 addr = map_to_sysmem(fdt);
259 set_working_fdt_addr(addr);
261 /* Moved target DT location */
262 buf = map_sysmem(newaddr, size);
263 memset(buf, 0, size);
265 /* Test moving the working FDT to a new location */
266 ut_assertok(console_record_reset_enable());
267 ut_assertok(run_commandf("fdt move %08lx %08lx %x", addr, newaddr, ts));
268 ut_assert_nextline("Working FDT set to %lx", newaddr);
269 ut_assertok(ut_check_console_end(uts));
271 /* Compare the source and destination DTs */
272 ut_assertok(console_record_reset_enable());
273 ut_assertok(run_commandf("cmp.b %08lx %08lx %x", addr, newaddr, ts));
274 ut_assert_nextline("Total of %d byte(s) were the same", ts);
275 ut_assertok(ut_check_console_end(uts));
279 FDT_TEST(fdt_test_move, UT_TESTF_CONSOLE_REC);
281 static int fdt_test_resize(struct unit_test_state *uts)
284 const unsigned int newsize = 0x2000;
288 /* Original source DT */
289 ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt)));
290 fdt_shrink_to_minimum(fdt, 0); /* Resize with 0 extra bytes */
291 ts = fdt_totalsize(fdt);
292 addr = map_to_sysmem(fdt);
293 set_working_fdt_addr(addr);
295 /* Test resizing the working FDT and verify the new space was added */
296 ut_assertok(console_record_reset_enable());
297 ut_assertok(run_commandf("fdt resize %x", newsize));
298 ut_asserteq(ts + newsize, fdt_totalsize(fdt));
299 ut_assertok(ut_check_console_end(uts));
303 FDT_TEST(fdt_test_resize, UT_TESTF_CONSOLE_REC);
305 static int fdt_test_print_list_common(struct unit_test_state *uts,
306 const char *opc, const char *node)
309 * Test printing/listing the working FDT
310 * subnode $node/subnode
312 ut_assertok(console_record_reset_enable());
313 ut_assertok(run_commandf("fdt %s %s/subnode", opc, node));
314 ut_assert_nextline("subnode {");
315 ut_assert_nextline("\t#address-cells = <0x00000000>;");
316 ut_assert_nextline("\t#size-cells = <0x00000000>;");
317 ut_assert_nextline("\tcompatible = \"u-boot,fdt-subnode-test-device\";");
318 ut_assert_nextline("};");
319 ut_assertok(ut_check_console_end(uts));
322 * Test printing/listing the working FDT
323 * path / string property model
325 ut_assertok(console_record_reset_enable());
326 ut_assertok(run_commandf("fdt %s / model", opc));
327 ut_assert_nextline("model = \"U-Boot FDT test\"");
328 ut_assertok(ut_check_console_end(uts));
331 * Test printing/listing the working FDT
332 * path $node string property compatible
334 ut_assertok(console_record_reset_enable());
335 ut_assertok(run_commandf("fdt %s %s compatible", opc, node));
336 ut_assert_nextline("compatible = \"u-boot,fdt-test-device1\"");
337 ut_assertok(ut_check_console_end(uts));
340 * Test printing/listing the working FDT
341 * path $node stringlist property clock-names
343 ut_assertok(console_record_reset_enable());
344 ut_assertok(run_commandf("fdt %s %s clock-names", opc, node));
345 ut_assert_nextline("clock-names = \"fixed\", \"i2c\", \"spi\", \"uart2\", \"uart1\"");
346 ut_assertok(ut_check_console_end(uts));
349 * Test printing/listing the working FDT
350 * path $node u32 property clock-frequency
352 ut_assertok(console_record_reset_enable());
353 ut_assertok(run_commandf("fdt %s %s clock-frequency", opc, node));
354 ut_assert_nextline("clock-frequency = <0x00fde800>");
355 ut_assertok(ut_check_console_end(uts));
358 * Test printing/listing the working FDT
359 * path $node empty property u-boot,empty-property
361 ut_assertok(console_record_reset_enable());
362 ut_assertok(run_commandf("fdt %s %s u-boot,empty-property", opc, node));
364 * This is the only 'fdt print' / 'fdt list' incantation which
365 * prefixes the property with node path. This has been in U-Boot
366 * since the beginning of the command 'fdt', keep it.
368 ut_assert_nextline("%s u-boot,empty-property", node);
369 ut_assertok(ut_check_console_end(uts));
372 * Test printing/listing the working FDT
373 * path $node prop-encoded array property regs
375 ut_assertok(console_record_reset_enable());
376 ut_assertok(run_commandf("fdt %s %s regs", opc, node));
377 ut_assert_nextline("regs = <0x00001234 0x00001000>");
378 ut_assertok(ut_check_console_end(uts));
383 static int fdt_test_print_list(struct unit_test_state *uts, bool print)
385 const char *opc = print ? "print" : "list";
390 /* Original source DT */
391 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt)));
392 addr = map_to_sysmem(fdt);
393 set_working_fdt_addr(addr);
395 /* Test printing/listing the working FDT -- node / */
396 ut_assertok(console_record_reset_enable());
397 ut_assertok(run_commandf("fdt %s", opc));
398 ut_assert_nextline("/ {");
399 ut_assert_nextline("\t#address-cells = <0x00000001>;");
400 ut_assert_nextline("\t#size-cells = <0x00000001>;");
401 ut_assert_nextline("\tcompatible = \"u-boot,fdt-test\";");
402 ut_assert_nextline("\tmodel = \"U-Boot FDT test\";");
403 ut_assert_nextline("\taliases {");
405 ut_assert_nextline("\t\tbadalias = \"/bad/alias\";");
406 ut_assert_nextline("\t\tsubnodealias = \"/test-node@1234/subnode\";");
407 ut_assert_nextline("\t\ttestnodealias = \"/test-node@1234\";");
409 ut_assert_nextline("\t};");
410 ut_assert_nextline("\ttest-node@1234 {");
412 ut_assert_nextline("\t\t#address-cells = <0x00000000>;");
413 ut_assert_nextline("\t\t#size-cells = <0x00000000>;");
414 ut_assert_nextline("\t\tcompatible = \"u-boot,fdt-test-device1\";");
415 ut_assert_nextline("\t\tclock-names = \"fixed\", \"i2c\", \"spi\", \"uart2\", \"uart1\";");
416 ut_assert_nextline("\t\tu-boot,empty-property;");
417 ut_assert_nextline("\t\tclock-frequency = <0x00fde800>;");
418 ut_assert_nextline("\t\tregs = <0x00001234 0x00001000>;");
419 ut_assert_nextline("\t\tsubnode {");
420 ut_assert_nextline("\t\t\t#address-cells = <0x00000000>;");
421 ut_assert_nextline("\t\t\t#size-cells = <0x00000000>;");
422 ut_assert_nextline("\t\t\tcompatible = \"u-boot,fdt-subnode-test-device\";");
423 ut_assert_nextline("\t\t};");
425 ut_assert_nextline("\t};");
426 ut_assert_nextline("};");
427 ut_assertok(ut_check_console_end(uts));
429 ret = fdt_test_print_list_common(uts, opc, "/test-node@1234");
431 ret = fdt_test_print_list_common(uts, opc, "testnodealias");
436 static int fdt_test_print(struct unit_test_state *uts)
438 return fdt_test_print_list(uts, true);
440 FDT_TEST(fdt_test_print, UT_TESTF_CONSOLE_REC);
442 static int fdt_test_list(struct unit_test_state *uts)
444 return fdt_test_print_list(uts, false);
446 FDT_TEST(fdt_test_list, UT_TESTF_CONSOLE_REC);
448 /* Test 'fdt get value' reading an fdt */
449 static int fdt_test_get_value_string(struct unit_test_state *uts,
450 const char *node, const char *prop,
451 const char *idx, const char *strres,
454 ut_assertok(console_record_reset_enable());
455 ut_assertok(run_commandf("fdt get value var %s %s %s",
456 node, prop, idx ? : ""));
458 ut_asserteq_str(strres, env_get("var"));
460 ut_asserteq(intres, env_get_hex("var", 0x1234));
462 ut_assertok(ut_check_console_end(uts));
467 static int fdt_test_get_value_common(struct unit_test_state *uts,
470 /* Test getting default element of $node node clock-names property */
471 fdt_test_get_value_string(uts, node, "clock-names", NULL, "fixed", 0);
473 /* Test getting 0th element of $node node clock-names property */
474 fdt_test_get_value_string(uts, node, "clock-names", "0", "fixed", 0);
476 /* Test getting 1st element of $node node clock-names property */
477 fdt_test_get_value_string(uts, node, "clock-names", "1", "i2c", 0);
479 /* Test getting 2nd element of $node node clock-names property */
480 fdt_test_get_value_string(uts, node, "clock-names", "2", "spi", 0);
483 * Test getting default element of $node node regs property.
484 * The result here is highly unusual, the non-index value read from
485 * integer array is a string of concatenated values from the array,
486 * but only if the array is shorter than 40 characters. Anything
487 * longer is an error. This is a special case for handling hashes.
489 fdt_test_get_value_string(uts, node, "regs", NULL, "3412000000100000", 0);
491 /* Test getting 0th element of $node node regs property */
492 fdt_test_get_value_string(uts, node, "regs", "0", NULL, 0x1234);
494 /* Test getting 1st element of $node node regs property */
495 fdt_test_get_value_string(uts, node, "regs", "1", NULL, 0x1000);
497 /* Test missing 10th element of $node node clock-names property */
498 ut_assertok(console_record_reset_enable());
499 ut_asserteq(1, run_commandf("fdt get value ften %s clock-names 10", node));
500 ut_assertok(ut_check_console_end(uts));
502 /* Test missing 10th element of $node node regs property */
503 ut_assertok(console_record_reset_enable());
504 ut_asserteq(1, run_commandf("fdt get value ften %s regs 10", node));
505 ut_assertok(ut_check_console_end(uts));
507 /* Test getting default element of $node node nonexistent property */
508 ut_assertok(console_record_reset_enable());
509 ut_asserteq(1, run_commandf("fdt get value fnone %s nonexistent", node));
510 ut_assert_nextline("libfdt fdt_getprop(): FDT_ERR_NOTFOUND");
511 ut_assertok(ut_check_console_end(uts));
516 static int fdt_test_get_value(struct unit_test_state *uts)
522 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt)));
523 addr = map_to_sysmem(fdt);
524 set_working_fdt_addr(addr);
526 ret = fdt_test_get_value_common(uts, "/test-node@1234");
528 ret = fdt_test_get_value_common(uts, "testnodealias");
532 /* Test getting default element of /nonexistent node */
533 ut_assertok(console_record_reset_enable());
534 ut_asserteq(1, run_command("fdt get value fnode /nonexistent nonexistent", 1));
535 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
536 ut_assertok(ut_check_console_end(uts));
538 /* Test getting default element of bad alias */
539 ut_assertok(console_record_reset_enable());
540 ut_asserteq(1, run_command("fdt get value vbadalias badalias nonexistent", 1));
541 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
542 ut_assertok(ut_check_console_end(uts));
544 /* Test getting default element of nonexistent alias */
545 ut_assertok(console_record_reset_enable());
546 ut_asserteq(1, run_command("fdt get value vnoalias noalias nonexistent", 1));
547 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_BADPATH");
548 ut_assertok(ut_check_console_end(uts));
552 FDT_TEST(fdt_test_get_value, UT_TESTF_CONSOLE_REC);
554 static int fdt_test_get_name(struct unit_test_state *uts)
559 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt)));
560 addr = map_to_sysmem(fdt);
561 set_working_fdt_addr(addr);
563 /* Test getting name of node 0 in /, which is /aliases node */
564 ut_assertok(console_record_reset_enable());
565 ut_assertok(run_command("fdt get name nzero / 0", 0));
566 ut_asserteq_str("aliases", env_get("nzero"));
567 ut_assertok(ut_check_console_end(uts));
569 /* Test getting name of node 1 in /, which is /test-node@1234 node */
570 ut_assertok(console_record_reset_enable());
571 ut_assertok(run_command("fdt get name none / 1", 0));
572 ut_asserteq_str("test-node@1234", env_get("none"));
573 ut_assertok(ut_check_console_end(uts));
575 /* Test getting name of node -1 in /, which is /aliases node, same as 0 */
576 ut_assertok(console_record_reset_enable());
577 ut_assertok(run_command("fdt get name nmone / -1", 0));
578 ut_asserteq_str("aliases", env_get("nmone"));
579 ut_assertok(ut_check_console_end(uts));
581 /* Test getting name of node 2 in /, which does not exist */
582 ut_assertok(console_record_reset_enable());
583 ut_asserteq(1, run_command("fdt get name ntwo / 2", 1));
584 ut_assert_nextline("libfdt node not found");
585 ut_assertok(ut_check_console_end(uts));
587 /* Test getting name of node 0 in /test-node@1234, which is /subnode node */
588 ut_assertok(console_record_reset_enable());
589 ut_assertok(run_command("fdt get name snzero /test-node@1234 0", 0));
590 ut_asserteq_str("subnode", env_get("snzero"));
591 ut_assertok(run_command("fdt get name asnzero testnodealias 0", 0));
592 ut_asserteq_str("subnode", env_get("asnzero"));
593 ut_assertok(ut_check_console_end(uts));
595 /* Test getting name of node 1 in /test-node@1234, which does not exist */
596 ut_assertok(console_record_reset_enable());
597 ut_asserteq(1, run_command("fdt get name snone /test-node@1234 1", 1));
598 ut_assert_nextline("libfdt node not found");
599 ut_asserteq(1, run_command("fdt get name asnone testnodealias 1", 1));
600 ut_assert_nextline("libfdt node not found");
601 ut_assertok(ut_check_console_end(uts));
603 /* Test getting name of node -1 in /test-node@1234, which is /subnode node, same as 0 */
604 ut_assertok(console_record_reset_enable());
605 ut_assertok(run_command("fdt get name snmone /test-node@1234 -1", 0));
606 ut_asserteq_str("subnode", env_get("snmone"));
607 ut_assertok(run_command("fdt get name asnmone testnodealias -1", 0));
608 ut_asserteq_str("subnode", env_get("asnmone"));
609 ut_assertok(ut_check_console_end(uts));
611 /* Test getting name of nonexistent node */
612 ut_assertok(console_record_reset_enable());
613 ut_asserteq(1, run_command("fdt get name nonode /nonexistent 0", 1));
614 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
615 ut_assertok(ut_check_console_end(uts));
617 /* Test getting name of bad alias */
618 ut_assertok(console_record_reset_enable());
619 ut_asserteq(1, run_command("fdt get name vbadalias badalias 0", 1));
620 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
621 ut_assertok(ut_check_console_end(uts));
623 /* Test getting name of nonexistent alias */
624 ut_assertok(console_record_reset_enable());
625 ut_asserteq(1, run_command("fdt get name vnoalias noalias 0", 1));
626 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_BADPATH");
627 ut_assertok(ut_check_console_end(uts));
631 FDT_TEST(fdt_test_get_name, UT_TESTF_CONSOLE_REC);
633 static int fdt_test_get_addr_common(struct unit_test_state *uts, char *fdt,
634 const char *path, const char *prop)
641 path_offset = fdt_path_offset(fdt, path);
642 ut_assert(path_offset >= 0);
643 prop_ptr = (void *)fdt_getprop(fdt, path_offset, prop, &len);
644 ut_assertnonnull(prop_ptr);
645 offset = (char *)prop_ptr - fdt;
647 ut_assertok(console_record_reset_enable());
648 ut_assertok(run_commandf("fdt get addr pstr %s %s", path, prop));
649 ut_asserteq((ulong)map_sysmem(env_get_hex("fdtaddr", 0x1234), 0),
650 (ulong)(map_sysmem(env_get_hex("pstr", 0x1234), 0) - offset));
651 ut_assertok(ut_check_console_end(uts));
656 static int fdt_test_get_addr(struct unit_test_state *uts)
661 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt)));
662 addr = map_to_sysmem(fdt);
663 set_working_fdt_addr(addr);
665 /* Test getting address of root node / string property "compatible" */
666 fdt_test_get_addr_common(uts, fdt, "/", "compatible");
668 /* Test getting address of node /test-node@1234 stringlist property "clock-names" */
669 fdt_test_get_addr_common(uts, fdt, "/test-node@1234", "clock-names");
670 fdt_test_get_addr_common(uts, fdt, "testnodealias", "clock-names");
672 /* Test getting address of node /test-node@1234 u32 property "clock-frequency" */
673 fdt_test_get_addr_common(uts, fdt, "/test-node@1234", "clock-frequency");
674 fdt_test_get_addr_common(uts, fdt, "testnodealias", "clock-frequency");
676 /* Test getting address of node /test-node@1234 empty property "u-boot,empty-property" */
677 fdt_test_get_addr_common(uts, fdt, "/test-node@1234", "u-boot,empty-property");
678 fdt_test_get_addr_common(uts, fdt, "testnodealias", "u-boot,empty-property");
680 /* Test getting address of node /test-node@1234 array property "regs" */
681 fdt_test_get_addr_common(uts, fdt, "/test-node@1234", "regs");
682 fdt_test_get_addr_common(uts, fdt, "testnodealias", "regs");
684 /* Test getting address of node /test-node@1234/subnode non-existent property "noprop" */
685 ut_assertok(console_record_reset_enable());
686 ut_asserteq(1, run_command("fdt get addr pnoprop /test-node@1234/subnode noprop", 1));
687 ut_assert_nextline("libfdt fdt_getprop(): FDT_ERR_NOTFOUND");
688 ut_assertok(ut_check_console_end(uts));
690 /* Test getting address of non-existent node /test-node@1234/nonode@1 property "noprop" */
691 ut_assertok(console_record_reset_enable());
692 ut_asserteq(1, run_command("fdt get addr pnonode /test-node@1234/nonode@1 noprop", 1));
693 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
694 ut_assertok(ut_check_console_end(uts));
698 FDT_TEST(fdt_test_get_addr, UT_TESTF_CONSOLE_REC);
700 static int fdt_test_get_size_common(struct unit_test_state *uts,
701 const char *path, const char *prop,
702 const unsigned int val)
704 ut_assertok(console_record_reset_enable());
706 ut_assertok(run_commandf("fdt get size sstr %s %s", path, prop));
708 ut_assertok(run_commandf("fdt get size sstr %s", path));
710 ut_asserteq(val, env_get_hex("sstr", 0x1234));
711 ut_assertok(ut_check_console_end(uts));
716 static int fdt_test_get_size(struct unit_test_state *uts)
721 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt)));
722 addr = map_to_sysmem(fdt);
723 set_working_fdt_addr(addr);
725 /* Test getting size of root node / string property "compatible" */
726 fdt_test_get_size_common(uts, "/", "compatible", 16);
728 /* Test getting size of node /test-node@1234 stringlist property "clock-names" */
729 fdt_test_get_size_common(uts, "/test-node@1234", "clock-names", 26);
730 fdt_test_get_size_common(uts, "testnodealias", "clock-names", 26);
732 /* Test getting size of node /test-node@1234 u32 property "clock-frequency" */
733 fdt_test_get_size_common(uts, "/test-node@1234", "clock-frequency", 4);
734 fdt_test_get_size_common(uts, "testnodealias", "clock-frequency", 4);
736 /* Test getting size of node /test-node@1234 empty property "u-boot,empty-property" */
737 fdt_test_get_size_common(uts, "/test-node@1234", "u-boot,empty-property", 0);
738 fdt_test_get_size_common(uts, "testnodealias", "u-boot,empty-property", 0);
740 /* Test getting size of node /test-node@1234 array property "regs" */
741 fdt_test_get_size_common(uts, "/test-node@1234", "regs", 8);
742 fdt_test_get_size_common(uts, "testnodealias", "regs", 8);
744 /* Test getting node count of node / */
745 fdt_test_get_size_common(uts, "/", NULL, 2);
747 /* Test getting node count of node /test-node@1234/subnode */
748 fdt_test_get_size_common(uts, "/test-node@1234/subnode", NULL, 0);
749 fdt_test_get_size_common(uts, "subnodealias", NULL, 0);
751 /* Test getting size of node /test-node@1234/subnode non-existent property "noprop" */
752 ut_assertok(console_record_reset_enable());
753 ut_asserteq(1, run_command("fdt get size pnoprop /test-node@1234/subnode noprop", 1));
754 ut_assert_nextline("libfdt fdt_getprop(): FDT_ERR_NOTFOUND");
755 ut_asserteq(1, run_command("fdt get size pnoprop subnodealias noprop", 1));
756 ut_assert_nextline("libfdt fdt_getprop(): FDT_ERR_NOTFOUND");
757 ut_assertok(ut_check_console_end(uts));
759 /* Test getting size of non-existent node /test-node@1234/nonode@1 property "noprop" */
760 ut_assertok(console_record_reset_enable());
761 ut_asserteq(1, run_command("fdt get size pnonode /test-node@1234/nonode@1 noprop", 1));
762 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
763 ut_assertok(ut_check_console_end(uts));
765 /* Test getting node count of non-existent node /test-node@1234/nonode@1 */
766 ut_assertok(console_record_reset_enable());
767 ut_asserteq(1, run_command("fdt get size pnonode /test-node@1234/nonode@1", 1));
768 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
769 ut_assertok(ut_check_console_end(uts));
771 /* Test getting node count of bad alias badalias */
772 ut_assertok(console_record_reset_enable());
773 ut_asserteq(1, run_command("fdt get size pnonode badalias noprop", 1));
774 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
775 ut_assertok(ut_check_console_end(uts));
777 /* Test getting node count of non-existent alias noalias */
778 ut_assertok(console_record_reset_enable());
779 ut_asserteq(1, run_command("fdt get size pnonode noalias", 1));
780 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_BADPATH");
781 ut_assertok(ut_check_console_end(uts));
785 FDT_TEST(fdt_test_get_size, UT_TESTF_CONSOLE_REC);
787 static int fdt_test_set_single(struct unit_test_state *uts,
788 const char *path, const char *prop,
789 const char *sval, int ival, bool integer)
792 * Set single element string/integer/<empty> property into DT, that is:
793 * => fdt set /path property string
794 * => fdt set /path property integer
795 * => fdt set /path property
797 ut_assertok(console_record_reset_enable());
799 ut_assertok(run_commandf("fdt set %s %s %s", path, prop, sval));
801 ut_assertok(run_commandf("fdt set %s %s <%d>", path, prop, ival));
803 ut_assertok(run_commandf("fdt set %s %s", path, prop));
805 /* Validate the property is present and has correct value. */
806 ut_assertok(run_commandf("fdt get value svar %s %s", path, prop));
808 ut_asserteq_str(sval, env_get("svar"));
810 ut_asserteq(ival, env_get_hex("svar", 0x1234));
812 ut_assertnull(env_get("svar"));
813 ut_assertok(ut_check_console_end(uts));
818 static int fdt_test_set_multi(struct unit_test_state *uts,
819 const char *path, const char *prop,
820 const char *sval1, const char *sval2,
821 int ival1, int ival2)
824 * Set multi element string/integer array property in DT, that is:
825 * => fdt set /path property <string1 string2>
826 * => fdt set /path property <integer1 integer2>
828 * The set is done twice in here deliberately, The first set adds
829 * the property with an extra trailing element in its array to make
830 * the array longer, the second set is the expected final content of
831 * the array property. The longer array is used to verify that the
832 * new array is correctly sized and read past the new array length
835 ut_assertok(console_record_reset_enable());
836 if (sval1 && sval2) {
837 ut_assertok(run_commandf("fdt set %s %s %s %s end", path, prop, sval1, sval2));
838 ut_assertok(run_commandf("fdt set %s %s %s %s", path, prop, sval1, sval2));
840 ut_assertok(run_commandf("fdt set %s %s <%d %d 10>", path, prop, ival1, ival2));
841 ut_assertok(run_commandf("fdt set %s %s <%d %d>", path, prop, ival1, ival2));
845 * Validate the property is present and has correct value.
847 * The "end/10" above and "svarn" below is used to validate that
848 * previous 'fdt set' to longer array does not polute newly set
851 ut_assertok(run_commandf("fdt get value svar1 %s %s 0", path, prop));
852 ut_assertok(run_commandf("fdt get value svar2 %s %s 1", path, prop));
853 ut_asserteq(1, run_commandf("fdt get value svarn %s %s 2", path, prop));
854 if (sval1 && sval2) {
855 ut_asserteq_str(sval1, env_get("svar1"));
856 ut_asserteq_str(sval2, env_get("svar2"));
857 ut_assertnull(env_get("svarn"));
859 ut_asserteq(ival1, env_get_hex("svar1", 0x1234));
860 ut_asserteq(ival2, env_get_hex("svar2", 0x1234));
861 ut_assertnull(env_get("svarn"));
863 ut_assertok(ut_check_console_end(uts));
868 static int fdt_test_set_node(struct unit_test_state *uts,
869 const char *path, const char *prop)
871 fdt_test_set_single(uts, path, prop, "new", 0, false);
872 fdt_test_set_single(uts, path, prop, "rewrite", 0, false);
873 fdt_test_set_single(uts, path, prop, NULL, 42, true);
874 fdt_test_set_single(uts, path, prop, NULL, 0, false);
875 fdt_test_set_multi(uts, path, prop, NULL, NULL, 42, 1701);
876 fdt_test_set_multi(uts, path, prop, NULL, NULL, 74656, 9);
877 fdt_test_set_multi(uts, path, prop, "42", "1701", 0, 0);
878 fdt_test_set_multi(uts, path, prop, "74656", "9", 0, 0);
883 static int fdt_test_set(struct unit_test_state *uts)
888 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt)));
889 fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */
890 addr = map_to_sysmem(fdt);
891 set_working_fdt_addr(addr);
893 /* Test setting of root node / existing property "compatible" */
894 fdt_test_set_node(uts, "/", "compatible");
896 /* Test setting of root node / new property "newproperty" */
897 fdt_test_set_node(uts, "/", "newproperty");
899 /* Test setting of subnode existing property "compatible" */
900 fdt_test_set_node(uts, "/test-node@1234/subnode", "compatible");
901 fdt_test_set_node(uts, "subnodealias", "compatible");
903 /* Test setting of subnode new property "newproperty" */
904 fdt_test_set_node(uts, "/test-node@1234/subnode", "newproperty");
905 fdt_test_set_node(uts, "subnodealias", "newproperty");
907 /* Test setting property of non-existent node */
908 ut_assertok(console_record_reset_enable());
909 ut_asserteq(1, run_command("fdt set /no-node noprop", 1));
910 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
911 ut_assertok(ut_check_console_end(uts));
913 /* Test setting property of non-existent alias */
914 ut_assertok(console_record_reset_enable());
915 ut_asserteq(1, run_command("fdt set noalias noprop", 1));
916 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_BADPATH");
917 ut_assertok(ut_check_console_end(uts));
919 /* Test setting property of bad alias */
920 ut_assertok(console_record_reset_enable());
921 ut_asserteq(1, run_command("fdt set badalias noprop", 1));
922 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
923 ut_assertok(ut_check_console_end(uts));
927 FDT_TEST(fdt_test_set, UT_TESTF_CONSOLE_REC);
929 static int fdt_test_mknode(struct unit_test_state *uts)
934 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt)));
935 fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */
936 addr = map_to_sysmem(fdt);
937 set_working_fdt_addr(addr);
939 /* Test creation of new node in / */
940 ut_assertok(console_record_reset_enable());
941 ut_assertok(run_commandf("fdt mknode / newnode"));
942 ut_assertok(run_commandf("fdt list /newnode"));
943 ut_assert_nextline("newnode {");
944 ut_assert_nextline("};");
945 ut_assertok(ut_check_console_end(uts));
947 /* Test creation of new node in /test-node@1234 */
948 ut_assertok(console_record_reset_enable());
949 ut_assertok(run_commandf("fdt mknode /test-node@1234 newsubnode"));
950 ut_assertok(run_commandf("fdt list /test-node@1234/newsubnode"));
951 ut_assert_nextline("newsubnode {");
952 ut_assert_nextline("};");
953 ut_assertok(ut_check_console_end(uts));
955 /* Test creation of new node in /test-node@1234 by alias */
956 ut_assertok(console_record_reset_enable());
957 ut_assertok(run_commandf("fdt mknode testnodealias newersubnode"));
958 ut_assertok(run_commandf("fdt list testnodealias/newersubnode"));
959 ut_assert_nextline("newersubnode {");
960 ut_assert_nextline("};");
961 ut_assertok(ut_check_console_end(uts));
963 /* Test creation of new node in /test-node@1234 over existing node */
964 ut_assertok(console_record_reset_enable());
965 ut_asserteq(1, run_commandf("fdt mknode testnodealias newsubnode"));
966 ut_assert_nextline("libfdt fdt_add_subnode(): FDT_ERR_EXISTS");
967 ut_assertok(ut_check_console_end(uts));
969 /* Test creation of new node in /test-node@1234 by alias over existing node */
970 ut_assertok(console_record_reset_enable());
971 ut_asserteq(1, run_commandf("fdt mknode testnodealias newersubnode"));
972 ut_assert_nextline("libfdt fdt_add_subnode(): FDT_ERR_EXISTS");
973 ut_assertok(ut_check_console_end(uts));
975 /* Test creation of new node in non-existent node */
976 ut_assertok(console_record_reset_enable());
977 ut_asserteq(1, run_commandf("fdt mknode /no-node newnosubnode"));
978 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
979 ut_assertok(ut_check_console_end(uts));
981 /* Test creation of new node in non-existent alias */
982 ut_assertok(console_record_reset_enable());
983 ut_asserteq(1, run_commandf("fdt mknode noalias newfailsubnode"));
984 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_BADPATH");
985 ut_assertok(ut_check_console_end(uts));
987 /* Test creation of new node in bad alias */
988 ut_assertok(console_record_reset_enable());
989 ut_asserteq(1, run_commandf("fdt mknode badalias newbadsubnode"));
990 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
991 ut_assertok(ut_check_console_end(uts));
995 FDT_TEST(fdt_test_mknode, UT_TESTF_CONSOLE_REC);
997 static int fdt_test_rm(struct unit_test_state *uts)
1002 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt)));
1003 addr = map_to_sysmem(fdt);
1004 set_working_fdt_addr(addr);
1006 /* Test removal of property in root node / */
1007 ut_assertok(console_record_reset_enable());
1008 ut_assertok(run_commandf("fdt print / compatible"));
1009 ut_assert_nextline("compatible = \"u-boot,fdt-test\"");
1010 ut_assertok(run_commandf("fdt rm / compatible"));
1011 ut_asserteq(1, run_commandf("fdt print / compatible"));
1012 ut_assert_nextline("libfdt fdt_getprop(): FDT_ERR_NOTFOUND");
1013 ut_assertok(ut_check_console_end(uts));
1015 /* Test removal of property clock-names in subnode /test-node@1234 */
1016 ut_assertok(console_record_reset_enable());
1017 ut_assertok(run_commandf("fdt print /test-node@1234 clock-names"));
1018 ut_assert_nextline("clock-names = \"fixed\", \"i2c\", \"spi\", \"uart2\", \"uart1\"");
1019 ut_assertok(run_commandf("fdt rm /test-node@1234 clock-names"));
1020 ut_asserteq(1, run_commandf("fdt print /test-node@1234 clock-names"));
1021 ut_assert_nextline("libfdt fdt_getprop(): FDT_ERR_NOTFOUND");
1022 ut_assertok(ut_check_console_end(uts));
1024 /* Test removal of property u-boot,empty-property in subnode /test-node@1234 by alias */
1025 ut_assertok(console_record_reset_enable());
1026 ut_assertok(run_commandf("fdt print testnodealias u-boot,empty-property"));
1027 ut_assert_nextline("testnodealias u-boot,empty-property");
1028 ut_assertok(run_commandf("fdt rm testnodealias u-boot,empty-property"));
1029 ut_asserteq(1, run_commandf("fdt print testnodealias u-boot,empty-property"));
1030 ut_assert_nextline("libfdt fdt_getprop(): FDT_ERR_NOTFOUND");
1031 ut_assertok(ut_check_console_end(uts));
1033 /* Test removal of non-existent property noprop in subnode /test-node@1234 */
1034 ut_assertok(console_record_reset_enable());
1035 ut_asserteq(1, run_commandf("fdt rm /test-node@1234 noprop"));
1036 ut_assert_nextline("libfdt fdt_delprop(): FDT_ERR_NOTFOUND");
1037 ut_assertok(ut_check_console_end(uts));
1039 /* Test removal of non-existent node /no-node@5678 */
1040 ut_assertok(console_record_reset_enable());
1041 ut_asserteq(1, run_commandf("fdt rm /no-node@5678"));
1042 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
1043 ut_assertok(ut_check_console_end(uts));
1045 /* Test removal of subnode /test-node@1234/subnode by alias */
1046 ut_assertok(console_record_reset_enable());
1047 ut_assertok(run_commandf("fdt rm subnodealias"));
1048 ut_asserteq(1, run_commandf("fdt print /test-node@1234/subnode"));
1049 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
1050 ut_assertok(ut_check_console_end(uts));
1052 /* Test removal of node by non-existent alias */
1053 ut_assertok(console_record_reset_enable());
1054 ut_asserteq(1, run_commandf("fdt rm noalias"));
1055 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_BADPATH");
1056 ut_assertok(ut_check_console_end(uts));
1058 /* Test removal of node by bad alias */
1059 ut_assertok(console_record_reset_enable());
1060 ut_asserteq(1, run_commandf("fdt rm noalias"));
1061 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_BADPATH");
1062 ut_assertok(ut_check_console_end(uts));
1064 /* Test removal of node /test-node@1234 */
1065 ut_assertok(console_record_reset_enable());
1066 ut_assertok(run_commandf("fdt rm /test-node@1234"));
1067 ut_asserteq(1, run_commandf("fdt print /test-node@1234"));
1068 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
1069 ut_assertok(ut_check_console_end(uts));
1071 /* Test removal of node / */
1072 ut_assertok(console_record_reset_enable());
1073 ut_assertok(run_commandf("fdt rm /"));
1074 ut_asserteq(1, run_commandf("fdt print /"));
1075 ut_assertok(ut_check_console_end(uts));
1079 FDT_TEST(fdt_test_rm, UT_TESTF_CONSOLE_REC);
1081 static int fdt_test_bootcpu(struct unit_test_state *uts)
1087 ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt)));
1088 addr = map_to_sysmem(fdt);
1089 set_working_fdt_addr(addr);
1091 /* Test getting default bootcpu entry */
1092 ut_assertok(console_record_reset_enable());
1093 ut_assertok(run_commandf("fdt header get bootcpu boot_cpuid_phys"));
1094 ut_asserteq(0, env_get_ulong("bootcpu", 10, 0x1234));
1095 ut_assertok(ut_check_console_end(uts));
1097 /* Test setting and getting new bootcpu entry, twice, to test overwrite */
1098 for (i = 42; i <= 43; i++) {
1099 ut_assertok(console_record_reset_enable());
1100 ut_assertok(run_commandf("fdt bootcpu %d", i));
1101 ut_assertok(ut_check_console_end(uts));
1103 /* Test getting new bootcpu entry */
1104 ut_assertok(console_record_reset_enable());
1105 ut_assertok(run_commandf("fdt header get bootcpu boot_cpuid_phys"));
1106 ut_asserteq(i, env_get_ulong("bootcpu", 10, 0x1234));
1107 ut_assertok(ut_check_console_end(uts));
1112 FDT_TEST(fdt_test_bootcpu, UT_TESTF_CONSOLE_REC);
1114 static int fdt_test_header_get(struct unit_test_state *uts,
1115 const char *field, const unsigned long val)
1117 /* Test getting valid header entry */
1118 ut_assertok(console_record_reset_enable());
1119 ut_assertok(run_commandf("fdt header get fvar %s", field));
1120 ut_asserteq(val, env_get_hex("fvar", 0x1234));
1121 ut_assertok(ut_check_console_end(uts));
1123 /* Test getting malformed header entry */
1124 ut_assertok(console_record_reset_enable());
1125 ut_asserteq(1, run_commandf("fdt header get fvar typo%stypo", field));
1126 ut_assertok(ut_check_console_end(uts));
1131 static int fdt_test_header(struct unit_test_state *uts)
1136 ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt)));
1137 addr = map_to_sysmem(fdt);
1138 set_working_fdt_addr(addr);
1140 /* Test header print */
1141 ut_assertok(console_record_reset_enable());
1142 ut_assertok(run_commandf("fdt header"));
1143 ut_assert_nextline("magic:\t\t\t0x%x", fdt_magic(fdt));
1144 ut_assert_nextline("totalsize:\t\t0x%x (%d)", fdt_totalsize(fdt), fdt_totalsize(fdt));
1145 ut_assert_nextline("off_dt_struct:\t\t0x%x", fdt_off_dt_struct(fdt));
1146 ut_assert_nextline("off_dt_strings:\t\t0x%x", fdt_off_dt_strings(fdt));
1147 ut_assert_nextline("off_mem_rsvmap:\t\t0x%x", fdt_off_mem_rsvmap(fdt));
1148 ut_assert_nextline("version:\t\t%d", fdt_version(fdt));
1149 ut_assert_nextline("last_comp_version:\t%d", fdt_last_comp_version(fdt));
1150 ut_assert_nextline("boot_cpuid_phys:\t0x%x", fdt_boot_cpuid_phys(fdt));
1151 ut_assert_nextline("size_dt_strings:\t0x%x", fdt_size_dt_strings(fdt));
1152 ut_assert_nextline("size_dt_struct:\t\t0x%x", fdt_size_dt_struct(fdt));
1153 ut_assert_nextline("number mem_rsv:\t\t0x%x", fdt_num_mem_rsv(fdt));
1154 ut_assert_nextline_empty();
1155 ut_assertok(ut_check_console_end(uts));
1157 /* Test header get */
1158 fdt_test_header_get(uts, "magic", fdt_magic(fdt));
1159 fdt_test_header_get(uts, "totalsize", fdt_totalsize(fdt));
1160 fdt_test_header_get(uts, "off_dt_struct", fdt_off_dt_struct(fdt));
1161 fdt_test_header_get(uts, "off_dt_strings", fdt_off_dt_strings(fdt));
1162 fdt_test_header_get(uts, "off_mem_rsvmap", fdt_off_mem_rsvmap(fdt));
1163 fdt_test_header_get(uts, "version", fdt_version(fdt));
1164 fdt_test_header_get(uts, "last_comp_version", fdt_last_comp_version(fdt));
1165 fdt_test_header_get(uts, "boot_cpuid_phys", fdt_boot_cpuid_phys(fdt));
1166 fdt_test_header_get(uts, "size_dt_strings", fdt_size_dt_strings(fdt));
1167 fdt_test_header_get(uts, "size_dt_struct", fdt_size_dt_struct(fdt));
1171 FDT_TEST(fdt_test_header, UT_TESTF_CONSOLE_REC);
1173 static int fdt_test_memory_cells(struct unit_test_state *uts,
1174 const unsigned int cells)
1176 unsigned char *pada, *pads;
1177 unsigned char *seta, *sets;
1179 const int size = sizeof(fdt);
1185 /* Create DT with node /memory { regs = <0x100 0x200>; } and #*cells */
1186 ut_assertnonnull(regs = calloc(2 * cells, sizeof(*regs)));
1187 ut_assertnonnull(pada = calloc(12, cells));
1188 ut_assertnonnull(pads = calloc(12, cells));
1189 ut_assertnonnull(seta = calloc(12, cells));
1190 ut_assertnonnull(sets = calloc(12, cells));
1191 for (i = cells; i >= 1; i--) {
1192 regs[cells - 1] = cpu_to_fdt32(i * 0x10000);
1193 regs[(cells * 2) - 1] = cpu_to_fdt32(~i);
1194 snprintf(seta + (8 * (cells - i)), 9, "%08x", i * 0x10000);
1195 snprintf(sets + (8 * (cells - i)), 9, "%08x", ~i);
1196 spc = (i != 1) ? " " : "";
1197 snprintf(pada + (11 * (cells - i)), 12, "0x%08x%s", i * 0x10000, spc);
1198 snprintf(pads + (11 * (cells - i)), 12, "0x%08x%s", ~i, spc);
1201 ut_assertok(fdt_create(fdt, size));
1202 ut_assertok(fdt_finish_reservemap(fdt));
1203 ut_assert(fdt_begin_node(fdt, "") >= 0);
1204 ut_assertok(fdt_property_u32(fdt, "#address-cells", cells));
1205 ut_assertok(fdt_property_u32(fdt, "#size-cells", cells));
1206 ut_assert(fdt_begin_node(fdt, "memory") >= 0);
1207 ut_assertok(fdt_property_string(fdt, "device_type", "memory"));
1208 ut_assertok(fdt_property(fdt, "reg", ®s, cells * 2));
1209 ut_assertok(fdt_end_node(fdt));
1210 ut_assertok(fdt_end_node(fdt));
1211 ut_assertok(fdt_finish(fdt));
1212 fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */
1213 addr = map_to_sysmem(fdt);
1214 set_working_fdt_addr(addr);
1216 /* Test updating the memory node */
1217 ut_assertok(console_record_reset_enable());
1218 ut_assertok(run_commandf("fdt memory 0x%s 0x%s", seta, sets));
1219 ut_assertok(run_commandf("fdt print /memory"));
1220 ut_assert_nextline("memory {");
1221 ut_assert_nextline("\tdevice_type = \"memory\";");
1222 ut_assert_nextline("\treg = <%s %s>;", pada, pads);
1223 ut_assert_nextline("};");
1224 ut_assertok(ut_check_console_end(uts));
1235 static int fdt_test_memory(struct unit_test_state *uts)
1238 * Test memory fixup for 32 and 64 bit systems, anything bigger is
1239 * so far unsupported and fails because of simple_stroull() being
1240 * 64bit tops in the 'fdt memory' command implementation.
1242 fdt_test_memory_cells(uts, 1);
1243 fdt_test_memory_cells(uts, 2);
1246 * The 'fdt memory' command is limited to /memory node, it does
1247 * not support any other valid DT memory node format, which is
1248 * either one or multiple /memory@adresss nodes. Therefore, this
1249 * DT variant is not tested here.
1254 FDT_TEST(fdt_test_memory, UT_TESTF_CONSOLE_REC);
1256 static int fdt_test_rsvmem(struct unit_test_state *uts)
1261 ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt)));
1262 fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */
1263 fdt_add_mem_rsv(fdt, 0x42, 0x1701);
1264 fdt_add_mem_rsv(fdt, 0x74656, 0x9);
1265 addr = map_to_sysmem(fdt);
1266 set_working_fdt_addr(addr);
1268 /* Test default reserved memory node presence */
1269 ut_assertok(console_record_reset_enable());
1270 ut_assertok(run_commandf("fdt rsvmem print"));
1271 ut_assert_nextline("index\t\t start\t\t size");
1272 ut_assert_nextline("------------------------------------------------");
1273 ut_assert_nextline(" %x\t%016x\t%016x", 0, 0x42, 0x1701);
1274 ut_assert_nextline(" %x\t%016x\t%016x", 1, 0x74656, 0x9);
1275 ut_assertok(ut_check_console_end(uts));
1277 /* Test add new reserved memory node */
1278 ut_assertok(console_record_reset_enable());
1279 ut_assertok(run_commandf("fdt rsvmem add 0x1234 0x5678"));
1280 ut_assertok(run_commandf("fdt rsvmem print"));
1281 ut_assert_nextline("index\t\t start\t\t size");
1282 ut_assert_nextline("------------------------------------------------");
1283 ut_assert_nextline(" %x\t%016x\t%016x", 0, 0x42, 0x1701);
1284 ut_assert_nextline(" %x\t%016x\t%016x", 1, 0x74656, 0x9);
1285 ut_assert_nextline(" %x\t%016x\t%016x", 2, 0x1234, 0x5678);
1286 ut_assertok(ut_check_console_end(uts));
1288 /* Test delete reserved memory node */
1289 ut_assertok(console_record_reset_enable());
1290 ut_assertok(run_commandf("fdt rsvmem delete 0"));
1291 ut_assertok(run_commandf("fdt rsvmem print"));
1292 ut_assert_nextline("index\t\t start\t\t size");
1293 ut_assert_nextline("------------------------------------------------");
1294 ut_assert_nextline(" %x\t%016x\t%016x", 0, 0x74656, 0x9);
1295 ut_assert_nextline(" %x\t%016x\t%016x", 1, 0x1234, 0x5678);
1296 ut_assertok(ut_check_console_end(uts));
1298 /* Test re-add new reserved memory node */
1299 ut_assertok(console_record_reset_enable());
1300 ut_assertok(run_commandf("fdt rsvmem add 0x42 0x1701"));
1301 ut_assertok(run_commandf("fdt rsvmem print"));
1302 ut_assert_nextline("index\t\t start\t\t size");
1303 ut_assert_nextline("------------------------------------------------");
1304 ut_assert_nextline(" %x\t%016x\t%016x", 0, 0x74656, 0x9);
1305 ut_assert_nextline(" %x\t%016x\t%016x", 1, 0x1234, 0x5678);
1306 ut_assert_nextline(" %x\t%016x\t%016x", 2, 0x42, 0x1701);
1307 ut_assertok(ut_check_console_end(uts));
1309 /* Test delete nonexistent reserved memory node */
1310 ut_assertok(console_record_reset_enable());
1311 ut_asserteq(1, run_commandf("fdt rsvmem delete 10"));
1312 ut_assert_nextline("libfdt fdt_del_mem_rsv(): FDT_ERR_NOTFOUND");
1313 ut_assertok(ut_check_console_end(uts));
1317 FDT_TEST(fdt_test_rsvmem, UT_TESTF_CONSOLE_REC);
1319 static int fdt_test_chosen(struct unit_test_state *uts)
1321 const char *env_bootargs = env_get("bootargs");
1325 ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt)));
1326 fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */
1327 addr = map_to_sysmem(fdt);
1328 set_working_fdt_addr(addr);
1330 /* Test default chosen node presence, fail as there is no /chosen node */
1331 ut_assertok(console_record_reset_enable());
1332 ut_asserteq(1, run_commandf("fdt print /chosen"));
1333 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
1334 ut_assertok(ut_check_console_end(uts));
1336 /* Test add new chosen node without initrd */
1337 ut_assertok(console_record_reset_enable());
1338 ut_assertok(run_commandf("fdt chosen"));
1339 ut_assertok(run_commandf("fdt print /chosen"));
1340 ut_assert_nextline("chosen {");
1341 ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */
1343 ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs);
1344 ut_assert_nextline("};");
1345 ut_assertok(ut_check_console_end(uts));
1347 /* Test add new chosen node with initrd */
1348 ut_assertok(console_record_reset_enable());
1349 ut_assertok(run_commandf("fdt chosen 0x1234 0x5678"));
1350 ut_assertok(run_commandf("fdt print /chosen"));
1351 ut_assert_nextline("chosen {");
1352 ut_assert_nextline("\tlinux,initrd-end = <0x%08x 0x%08x>;",
1353 upper_32_bits(0x1234 + 0x5678 - 1),
1354 lower_32_bits(0x1234 + 0x5678 - 1));
1355 ut_assert_nextline("\tlinux,initrd-start = <0x%08x 0x%08x>;",
1356 upper_32_bits(0x1234), lower_32_bits(0x1234));
1357 ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */
1359 ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs);
1360 ut_assert_nextline("};");
1361 ut_assertok(ut_check_console_end(uts));
1365 FDT_TEST(fdt_test_chosen, UT_TESTF_CONSOLE_REC);
1367 static int fdt_test_apply(struct unit_test_state *uts)
1369 char fdt[8192], fdto[8192];
1372 /* Create base DT with __symbols__ node */
1373 ut_assertok(fdt_create(fdt, sizeof(fdt)));
1374 ut_assertok(fdt_finish_reservemap(fdt));
1375 ut_assert(fdt_begin_node(fdt, "") >= 0);
1376 ut_assert(fdt_begin_node(fdt, "__symbols__") >= 0);
1377 ut_assertok(fdt_end_node(fdt));
1378 ut_assertok(fdt_end_node(fdt));
1379 ut_assertok(fdt_finish(fdt));
1380 fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */
1381 addr = map_to_sysmem(fdt);
1382 set_working_fdt_addr(addr);
1384 /* Create DTO which adds single property to root node / */
1385 ut_assertok(fdt_create(fdto, sizeof(fdto)));
1386 ut_assertok(fdt_finish_reservemap(fdto));
1387 ut_assert(fdt_begin_node(fdto, "") >= 0);
1388 ut_assert(fdt_begin_node(fdto, "fragment") >= 0);
1389 ut_assertok(fdt_property_string(fdto, "target-path", "/"));
1390 ut_assert(fdt_begin_node(fdto, "__overlay__") >= 0);
1391 ut_assertok(fdt_property_string(fdto, "newstring", "newvalue"));
1392 ut_assertok(fdt_end_node(fdto));
1393 ut_assertok(fdt_end_node(fdto));
1394 ut_assertok(fdt_finish(fdto));
1395 addro = map_to_sysmem(fdto);
1397 /* Test default DT print */
1398 ut_assertok(console_record_reset_enable());
1399 ut_assertok(run_commandf("fdt print /"));
1400 ut_assert_nextline("/ {");
1401 ut_assert_nextline("\t__symbols__ {");
1402 ut_assert_nextline("\t};");
1403 ut_assert_nextline("};");
1404 ut_assertok(ut_check_console_end(uts));
1406 /* Test simple DTO application */
1407 ut_assertok(console_record_reset_enable());
1408 ut_assertok(run_commandf("fdt apply 0x%08lx", addro));
1409 ut_assertok(run_commandf("fdt print /"));
1410 ut_assert_nextline("/ {");
1411 ut_assert_nextline("\tnewstring = \"newvalue\";");
1412 ut_assert_nextline("\t__symbols__ {");
1413 ut_assert_nextline("\t};");
1414 ut_assert_nextline("};");
1415 ut_assertok(ut_check_console_end(uts));
1418 * Create complex DTO which:
1419 * - modifies newstring property in root node /
1420 * - adds new properties to root node /
1421 * - adds new subnode with properties to root node /
1422 * - adds phandle to the subnode and therefore __symbols__ node
1424 ut_assertok(fdt_create(fdto, sizeof(fdto)));
1425 ut_assertok(fdt_finish_reservemap(fdto));
1426 ut_assert(fdt_begin_node(fdto, "") >= 0);
1427 ut_assertok(fdt_property_cell(fdto, "#address-cells", 1));
1428 ut_assertok(fdt_property_cell(fdto, "#size-cells", 0));
1430 ut_assert(fdt_begin_node(fdto, "fragment@0") >= 0);
1431 ut_assertok(fdt_property_string(fdto, "target-path", "/"));
1432 ut_assert(fdt_begin_node(fdto, "__overlay__") >= 0);
1433 ut_assertok(fdt_property_string(fdto, "newstring", "newervalue"));
1434 ut_assertok(fdt_property_u32(fdto, "newu32", 0x12345678));
1435 ut_assertok(fdt_property(fdto, "empty-property", NULL, 0));
1436 ut_assert(fdt_begin_node(fdto, "subnode") >= 0);
1437 ut_assertok(fdt_property_string(fdto, "subnewstring", "newervalue"));
1438 ut_assertok(fdt_property_u32(fdto, "subnewu32", 0x12345678));
1439 ut_assertok(fdt_property(fdto, "subempty-property", NULL, 0));
1440 ut_assertok(fdt_property_u32(fdto, "phandle", 0x01));
1441 ut_assertok(fdt_end_node(fdto));
1442 ut_assertok(fdt_end_node(fdto));
1443 ut_assertok(fdt_end_node(fdto));
1445 ut_assert(fdt_begin_node(fdto, "__symbols__") >= 0);
1446 ut_assertok(fdt_property_string(fdto, "subnodephandle", "/fragment@0/__overlay__/subnode"));
1447 ut_assertok(fdt_end_node(fdto));
1448 ut_assertok(fdt_finish(fdto));
1449 addro = map_to_sysmem(fdto);
1451 /* Test complex DTO application */
1452 ut_assertok(console_record_reset_enable());
1453 ut_assertok(run_commandf("fdt apply 0x%08lx", addro));
1454 ut_assertok(run_commandf("fdt print /"));
1455 ut_assert_nextline("/ {");
1456 ut_assert_nextline("\tempty-property;");
1457 ut_assert_nextline("\tnewu32 = <0x12345678>;");
1458 ut_assert_nextline("\tnewstring = \"newervalue\";");
1459 ut_assert_nextline("\tsubnode {");
1460 ut_assert_nextline("\t\tphandle = <0x00000001>;");
1461 ut_assert_nextline("\t\tsubempty-property;");
1462 ut_assert_nextline("\t\tsubnewu32 = <0x12345678>;");
1463 ut_assert_nextline("\t\tsubnewstring = \"newervalue\";");
1464 ut_assert_nextline("\t};");
1465 ut_assert_nextline("\t__symbols__ {");
1466 ut_assert_nextline("\t\tsubnodephandle = \"/subnode\";");
1467 ut_assert_nextline("\t};");
1468 ut_assert_nextline("};");
1469 ut_assertok(ut_check_console_end(uts));
1472 * Create complex DTO which:
1473 * - modifies subnewu32 property in subnode via phandle and uses __fixups__ node
1475 ut_assertok(fdt_create(fdto, sizeof(fdto)));
1476 ut_assertok(fdt_finish_reservemap(fdto));
1477 ut_assert(fdt_begin_node(fdto, "") >= 0);
1478 ut_assertok(fdt_property_cell(fdto, "#address-cells", 1));
1479 ut_assertok(fdt_property_cell(fdto, "#size-cells", 0));
1481 ut_assert(fdt_begin_node(fdto, "fragment@0") >= 0);
1482 ut_assertok(fdt_property_u32(fdto, "target", 0xffffffff));
1483 ut_assert(fdt_begin_node(fdto, "__overlay__") >= 0);
1484 ut_assertok(fdt_property_u32(fdto, "subnewu32", 0xabcdef01));
1485 ut_assertok(fdt_end_node(fdto));
1486 ut_assertok(fdt_end_node(fdto));
1488 ut_assert(fdt_begin_node(fdto, "__fixups__") >= 0);
1489 ut_assertok(fdt_property_string(fdto, "subnodephandle", "/fragment@0:target:0"));
1490 ut_assertok(fdt_end_node(fdto));
1491 ut_assertok(fdt_end_node(fdto));
1492 ut_assertok(fdt_finish(fdto));
1493 addro = map_to_sysmem(fdto);
1495 /* Test complex DTO application */
1496 ut_assertok(console_record_reset_enable());
1497 ut_assertok(run_commandf("fdt apply 0x%08lx", addro));
1498 ut_assertok(run_commandf("fdt print /"));
1499 ut_assert_nextline("/ {");
1500 ut_assert_nextline("\tempty-property;");
1501 ut_assert_nextline("\tnewu32 = <0x12345678>;");
1502 ut_assert_nextline("\tnewstring = \"newervalue\";");
1503 ut_assert_nextline("\tsubnode {");
1504 ut_assert_nextline("\t\tphandle = <0x00000001>;");
1505 ut_assert_nextline("\t\tsubempty-property;");
1506 ut_assert_nextline("\t\tsubnewu32 = <0xabcdef01>;");
1507 ut_assert_nextline("\t\tsubnewstring = \"newervalue\";");
1508 ut_assert_nextline("\t};");
1509 ut_assert_nextline("\t__symbols__ {");
1510 ut_assert_nextline("\t\tsubnodephandle = \"/subnode\";");
1511 ut_assert_nextline("\t};");
1512 ut_assert_nextline("};");
1513 ut_assertok(ut_check_console_end(uts));
1517 FDT_TEST(fdt_test_apply, UT_TESTF_CONSOLE_REC);
1519 int do_ut_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
1521 struct unit_test *tests = UNIT_TEST_SUITE_START(fdt_test);
1522 const int n_ents = UNIT_TEST_SUITE_COUNT(fdt_test);
1524 return cmd_ut_category("fdt", "fdt_test_", tests, n_ents, argc, argv);