blob: 1f103a1d7eb4da3075589ccd5aac381a5a490460 [file] [log] [blame]
Simon Glass74724482022-07-13 06:06:59 -06001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Tests for fdt command
4 *
Marek Vasutf53e9732023-04-22 14:59:58 +02005 * Copyright 2022 Google LLC
Simon Glass74724482022-07-13 06:06:59 -06006 */
7
8#include <common.h>
9#include <console.h>
10#include <fdt_support.h>
11#include <mapmem.h>
12#include <asm/global_data.h>
13#include <linux/libfdt.h>
14#include <test/suites.h>
15#include <test/ut.h>
16
17DECLARE_GLOBAL_DATA_PTR;
Marek Vasut3998b452023-03-02 04:08:45 +010018/*
19 * Missing tests:
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
24 */
Simon Glass74724482022-07-13 06:06:59 -060025
26/* Declare a new fdt test */
27#define FDT_TEST(_name, _flags) UNIT_TEST(_name, _flags, fdt_test)
28
29/**
30 * make_test_fdt() - Create an FDT with just a root node
31 *
32 * The size is set to the minimum needed
33 *
34 * @uts: Test state
35 * @fdt: Place to write FDT
36 * @size: Maximum size of space for fdt
37 */
38static int make_test_fdt(struct unit_test_state *uts, void *fdt, int size)
39{
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));
45
46 return 0;
47}
48
Marek Vasutd6729762023-03-02 04:08:27 +010049/**
50 * make_fuller_fdt() - Create an FDT with root node and properties
51 *
52 * The size is set to the minimum needed
53 *
54 * @uts: Test state
55 * @fdt: Place to write FDT
56 * @size: Maximum size of space for fdt
57 */
58static int make_fuller_fdt(struct unit_test_state *uts, void *fdt, int size)
59{
60 fdt32_t regs[2] = { cpu_to_fdt32(0x1234), cpu_to_fdt32(0x1000) };
61
62 /*
63 * Assemble the following DT for test purposes:
64 *
65 * / {
66 * #address-cells = <0x00000001>;
67 * #size-cells = <0x00000001>;
68 * compatible = "u-boot,fdt-test";
69 * model = "U-Boot FDT test";
70 *
71 * aliases {
72 * badalias = "/bad/alias";
73 * subnodealias = "/test-node@1234/subnode";
74 * testnodealias = "/test-node@1234";
75 * };
76 *
77 * 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>;
85 *
86 * subnode {
87 * #address-cells = <0x00000000>;
88 * #size-cells = <0x00000000>;
89 * compatible = "u-boot,fdt-subnode-test-device";
90 * };
91 * };
92 * };
93 */
94
95 ut_assertok(fdt_create(fdt, size));
96 ut_assertok(fdt_finish_reservemap(fdt));
97 ut_assert(fdt_begin_node(fdt, "") >= 0);
98
99 ut_assertok(fdt_property_u32(fdt, "#address-cells", 1));
100 ut_assertok(fdt_property_u32(fdt, "#size-cells", 1));
101 /* <string> */
102 ut_assertok(fdt_property_string(fdt, "compatible", "u-boot,fdt-test"));
103 /* <string> */
104 ut_assertok(fdt_property_string(fdt, "model", "U-Boot FDT test"));
105
106 ut_assert(fdt_begin_node(fdt, "aliases") >= 0);
107 /* <string> */
108 ut_assertok(fdt_property_string(fdt, "badalias", "/bad/alias"));
109 /* <string> */
110 ut_assertok(fdt_property_string(fdt, "subnodealias", "/test-node@1234/subnode"));
111 /* <string> */
112 ut_assertok(fdt_property_string(fdt, "testnodealias", "/test-node@1234"));
113 ut_assertok(fdt_end_node(fdt));
114
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));
118 /* <string> */
119 ut_assertok(fdt_property_string(fdt, "compatible", "u-boot,fdt-test-device1"));
120 /* <stringlist> */
121 ut_assertok(fdt_property(fdt, "clock-names", "fixed\0i2c\0spi\0uart2\0uart1\0", 26));
122 /* <empty> */
123 ut_assertok(fdt_property(fdt, "u-boot,empty-property", NULL, 0));
124 /*
125 * <u32>
126 * This value is deliberate as it used to break cmd/fdt.c
127 * is_printable_string() implementation.
128 */
129 ut_assertok(fdt_property_u32(fdt, "clock-frequency", 16640000));
130 /* <prop-encoded-array> */
131 ut_assertok(fdt_property(fdt, "regs", &regs, 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));
138
139 ut_assertok(fdt_end_node(fdt));
140 ut_assertok(fdt_finish(fdt));
141
142 return 0;
143}
144
Simon Glass74724482022-07-13 06:06:59 -0600145/* Test 'fdt addr' getting/setting address */
146static int fdt_test_addr(struct unit_test_state *uts)
147{
148 const void *fdt_blob, *new_fdt;
149 char fdt[256];
150 ulong addr;
151 int ret;
152
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));
158
159 /* The working fdt is not set, so this should fail */
160 set_working_fdt_addr(0);
Simon Glassbaf41412022-10-11 09:47:12 -0600161 ut_assert_nextline("Working FDT set to 0");
Simon Glass74724482022-07-13 06:06:59 -0600162 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));
165
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);
Simon Glassbaf41412022-10-11 09:47:12 -0600170 ut_assert_nextline("Working FDT set to %lx", addr);
Simon Glass74724482022-07-13 06:06:59 -0600171 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));
174
175 /* Set the working FDT */
176 set_working_fdt_addr(0);
Simon Glassbaf41412022-10-11 09:47:12 -0600177 ut_assert_nextline("Working FDT set to 0");
Evgeny Bachinin0d73c232023-03-20 11:23:13 +0300178 ut_assertok(run_commandf("fdt addr %08lx", addr));
Simon Glassbaf41412022-10-11 09:47:12 -0600179 ut_assert_nextline("Working FDT set to %lx", addr);
Simon Glass74724482022-07-13 06:06:59 -0600180 ut_asserteq(addr, map_to_sysmem(working_fdt));
181 ut_assertok(ut_check_console_end(uts));
182 set_working_fdt_addr(0);
Simon Glassbaf41412022-10-11 09:47:12 -0600183 ut_assert_nextline("Working FDT set to 0");
Simon Glass74724482022-07-13 06:06:59 -0600184
Simon Glassbaf41412022-10-11 09:47:12 -0600185 /* Set the control FDT */
Simon Glass74724482022-07-13 06:06:59 -0600186 fdt_blob = gd->fdt_blob;
187 gd->fdt_blob = NULL;
Evgeny Bachinin0d73c232023-03-20 11:23:13 +0300188 ret = run_commandf("fdt addr -c %08lx", addr);
Simon Glass74724482022-07-13 06:06:59 -0600189 new_fdt = gd->fdt_blob;
190 gd->fdt_blob = fdt_blob;
191 ut_assertok(ret);
192 ut_asserteq(addr, map_to_sysmem(new_fdt));
193 ut_assertok(ut_check_console_end(uts));
194
195 /* Test setting an invalid FDT */
196 fdt[0] = 123;
Evgeny Bachinin0d73c232023-03-20 11:23:13 +0300197 ut_asserteq(1, run_commandf("fdt addr %08lx", addr));
Simon Glass74724482022-07-13 06:06:59 -0600198 ut_assert_nextline("libfdt fdt_check_header(): FDT_ERR_BADMAGIC");
199 ut_assertok(ut_check_console_end(uts));
200
201 /* Test detecting an invalid FDT */
202 fdt[0] = 123;
203 set_working_fdt_addr(addr);
Simon Glassbaf41412022-10-11 09:47:12 -0600204 ut_assert_nextline("Working FDT set to %lx", addr);
Simon Glass74724482022-07-13 06:06:59 -0600205 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));
208
209 return 0;
210}
211FDT_TEST(fdt_test_addr, UT_TESTF_CONSOLE_REC);
212
213/* Test 'fdt addr' resizing an fdt */
Marek Vasutab40faf2023-03-02 04:08:25 +0100214static int fdt_test_addr_resize(struct unit_test_state *uts)
Simon Glass74724482022-07-13 06:06:59 -0600215{
216 char fdt[256];
217 const int newsize = sizeof(fdt) / 2;
218 ulong addr;
219
220 ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt)));
221 addr = map_to_sysmem(fdt);
222 set_working_fdt_addr(addr);
223
224 /* Test setting and resizing the working FDT to a larger size */
225 ut_assertok(console_record_reset_enable());
Evgeny Bachinin0d73c232023-03-20 11:23:13 +0300226 ut_assertok(run_commandf("fdt addr %08lx %x", addr, newsize));
Simon Glassbaf41412022-10-11 09:47:12 -0600227 ut_assert_nextline("Working FDT set to %lx", addr);
Simon Glass74724482022-07-13 06:06:59 -0600228 ut_assertok(ut_check_console_end(uts));
229
230 /* Try shrinking it */
Evgeny Bachinin0d73c232023-03-20 11:23:13 +0300231 ut_assertok(run_commandf("fdt addr %08lx %zx", addr, sizeof(fdt) / 4));
Simon Glassbaf41412022-10-11 09:47:12 -0600232 ut_assert_nextline("Working FDT set to %lx", addr);
Simon Glass74724482022-07-13 06:06:59 -0600233 ut_assert_nextline("New length %d < existing length %d, ignoring",
234 (int)sizeof(fdt) / 4, newsize);
235 ut_assertok(ut_check_console_end(uts));
236
237 /* ...quietly */
Evgeny Bachinin0d73c232023-03-20 11:23:13 +0300238 ut_assertok(run_commandf("fdt addr -q %08lx %zx", addr, sizeof(fdt) / 4));
Simon Glass74724482022-07-13 06:06:59 -0600239 ut_assertok(ut_check_console_end(uts));
240
241 /* We cannot easily provoke errors in fdt_open_into(), so ignore that */
242
243 return 0;
244}
Marek Vasutab40faf2023-03-02 04:08:25 +0100245FDT_TEST(fdt_test_addr_resize, UT_TESTF_CONSOLE_REC);
Simon Glass74724482022-07-13 06:06:59 -0600246
Marek Vasut05728722023-03-02 04:08:30 +0100247static int fdt_test_move(struct unit_test_state *uts)
248{
249 char fdt[256];
250 ulong addr, newaddr = 0x10000;
251 const int size = sizeof(fdt);
252 uint32_t ts;
253 void *buf;
254
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);
260
261 /* Moved target DT location */
262 buf = map_sysmem(newaddr, size);
263 memset(buf, 0, size);
264
265 /* Test moving the working FDT to a new location */
266 ut_assertok(console_record_reset_enable());
Evgeny Bachinin0d73c232023-03-20 11:23:13 +0300267 ut_assertok(run_commandf("fdt move %08lx %08lx %x", addr, newaddr, ts));
Marek Vasut05728722023-03-02 04:08:30 +0100268 ut_assert_nextline("Working FDT set to %lx", newaddr);
269 ut_assertok(ut_check_console_end(uts));
270
271 /* Compare the source and destination DTs */
272 ut_assertok(console_record_reset_enable());
Evgeny Bachinin0d73c232023-03-20 11:23:13 +0300273 ut_assertok(run_commandf("cmp.b %08lx %08lx %x", addr, newaddr, ts));
Marek Vasut05728722023-03-02 04:08:30 +0100274 ut_assert_nextline("Total of %d byte(s) were the same", ts);
275 ut_assertok(ut_check_console_end(uts));
276
277 return 0;
278}
279FDT_TEST(fdt_test_move, UT_TESTF_CONSOLE_REC);
280
Marek Vasut8fa28352023-03-02 04:08:31 +0100281static int fdt_test_resize(struct unit_test_state *uts)
282{
283 char fdt[256];
284 const unsigned int newsize = 0x2000;
285 uint32_t ts;
286 ulong addr;
287
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);
294
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));
300
301 return 0;
302}
303FDT_TEST(fdt_test_resize, UT_TESTF_CONSOLE_REC);
304
Marek Vasutb0cd7cc2023-03-02 04:08:32 +0100305static int fdt_test_print_list_common(struct unit_test_state *uts,
306 const char *opc, const char *node)
307{
308 /*
309 * Test printing/listing the working FDT
310 * subnode $node/subnode
311 */
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));
320
321 /*
322 * Test printing/listing the working FDT
323 * path / string property model
324 */
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));
329
330 /*
331 * Test printing/listing the working FDT
332 * path $node string property compatible
333 */
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));
338
339 /*
340 * Test printing/listing the working FDT
341 * path $node stringlist property clock-names
342 */
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));
347
348 /*
349 * Test printing/listing the working FDT
350 * path $node u32 property clock-frequency
351 */
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));
356
357 /*
358 * Test printing/listing the working FDT
359 * path $node empty property u-boot,empty-property
360 */
361 ut_assertok(console_record_reset_enable());
362 ut_assertok(run_commandf("fdt %s %s u-boot,empty-property", opc, node));
363 /*
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.
367 */
368 ut_assert_nextline("%s u-boot,empty-property", node);
369 ut_assertok(ut_check_console_end(uts));
370
371 /*
372 * Test printing/listing the working FDT
373 * path $node prop-encoded array property regs
374 */
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));
379
380 return 0;
381}
382
383static int fdt_test_print_list(struct unit_test_state *uts, bool print)
384{
385 const char *opc = print ? "print" : "list";
386 char fdt[4096];
387 ulong addr;
388 int ret;
389
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);
394
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 {");
404 if (print) {
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\";");
408 }
409 ut_assert_nextline("\t};");
410 ut_assert_nextline("\ttest-node@1234 {");
411 if (print) {
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};");
424 }
425 ut_assert_nextline("\t};");
426 ut_assert_nextline("};");
427 ut_assertok(ut_check_console_end(uts));
428
429 ret = fdt_test_print_list_common(uts, opc, "/test-node@1234");
430 if (!ret)
431 ret = fdt_test_print_list_common(uts, opc, "testnodealias");
432
433 return 0;
434}
435
436static int fdt_test_print(struct unit_test_state *uts)
437{
438 return fdt_test_print_list(uts, true);
439}
440FDT_TEST(fdt_test_print, UT_TESTF_CONSOLE_REC);
441
442static int fdt_test_list(struct unit_test_state *uts)
443{
444 return fdt_test_print_list(uts, false);
445}
446FDT_TEST(fdt_test_list, UT_TESTF_CONSOLE_REC);
447
Marek Vasut025b9d82023-03-02 04:08:26 +0100448/* Test 'fdt get value' reading an fdt */
Marek Vasutf1df20a2023-03-02 04:08:29 +0100449static 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,
452 const int intres)
453{
454 ut_assertok(console_record_reset_enable());
455 ut_assertok(run_commandf("fdt get value var %s %s %s",
456 node, prop, idx ? : ""));
457 if (strres) {
458 ut_asserteq_str(strres, env_get("var"));
459 } else {
460 ut_asserteq(intres, env_get_hex("var", 0x1234));
461 }
462 ut_assertok(ut_check_console_end(uts));
463
464 return 0;
465}
466
Marek Vasut39e07272023-03-02 04:08:28 +0100467static int fdt_test_get_value_common(struct unit_test_state *uts,
468 const char *node)
469{
470 /* Test getting default element of $node node clock-names property */
Marek Vasutf1df20a2023-03-02 04:08:29 +0100471 fdt_test_get_value_string(uts, node, "clock-names", NULL, "fixed", 0);
Marek Vasut39e07272023-03-02 04:08:28 +0100472
473 /* Test getting 0th element of $node node clock-names property */
Marek Vasutf1df20a2023-03-02 04:08:29 +0100474 fdt_test_get_value_string(uts, node, "clock-names", "0", "fixed", 0);
Marek Vasut39e07272023-03-02 04:08:28 +0100475
476 /* Test getting 1st element of $node node clock-names property */
Marek Vasutf1df20a2023-03-02 04:08:29 +0100477 fdt_test_get_value_string(uts, node, "clock-names", "1", "i2c", 0);
Marek Vasut39e07272023-03-02 04:08:28 +0100478
479 /* Test getting 2nd element of $node node clock-names property */
Marek Vasutf1df20a2023-03-02 04:08:29 +0100480 fdt_test_get_value_string(uts, node, "clock-names", "2", "spi", 0);
481
482 /*
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.
488 */
489 fdt_test_get_value_string(uts, node, "regs", NULL, "3412000000100000", 0);
490
491 /* Test getting 0th element of $node node regs property */
492 fdt_test_get_value_string(uts, node, "regs", "0", NULL, 0x1234);
493
494 /* Test getting 1st element of $node node regs property */
495 fdt_test_get_value_string(uts, node, "regs", "1", NULL, 0x1000);
Marek Vasut39e07272023-03-02 04:08:28 +0100496
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));
501
Marek Vasutf1df20a2023-03-02 04:08:29 +0100502 /* 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));
506
Marek Vasut39e07272023-03-02 04:08:28 +0100507 /* 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));
512
513 return 0;
514}
515
Marek Vasut025b9d82023-03-02 04:08:26 +0100516static int fdt_test_get_value(struct unit_test_state *uts)
Marek Vasutd83615b2022-11-14 22:50:00 +0100517{
Marek Vasutd6729762023-03-02 04:08:27 +0100518 char fdt[4096];
Marek Vasutd83615b2022-11-14 22:50:00 +0100519 ulong addr;
Marek Vasut39e07272023-03-02 04:08:28 +0100520 int ret;
Marek Vasutd83615b2022-11-14 22:50:00 +0100521
Marek Vasutd6729762023-03-02 04:08:27 +0100522 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt)));
523 addr = map_to_sysmem(fdt);
Marek Vasutd83615b2022-11-14 22:50:00 +0100524 set_working_fdt_addr(addr);
525
Marek Vasut39e07272023-03-02 04:08:28 +0100526 ret = fdt_test_get_value_common(uts, "/test-node@1234");
527 if (!ret)
528 ret = fdt_test_get_value_common(uts, "testnodealias");
529 if (ret)
530 return ret;
Marek Vasutd83615b2022-11-14 22:50:00 +0100531
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));
537
Marek Vasut39e07272023-03-02 04:08:28 +0100538 /* 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));
543
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));
549
Marek Vasutd83615b2022-11-14 22:50:00 +0100550 return 0;
551}
Marek Vasut025b9d82023-03-02 04:08:26 +0100552FDT_TEST(fdt_test_get_value, UT_TESTF_CONSOLE_REC);
Marek Vasutd83615b2022-11-14 22:50:00 +0100553
Marek Vasut890d3fc2023-03-02 04:08:33 +0100554static int fdt_test_get_name(struct unit_test_state *uts)
555{
556 char fdt[4096];
557 ulong addr;
558
559 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt)));
560 addr = map_to_sysmem(fdt);
561 set_working_fdt_addr(addr);
562
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));
568
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));
574
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));
580
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));
586
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));
594
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));
602
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));
610
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));
616
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));
622
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));
628
629 return 0;
630}
631FDT_TEST(fdt_test_get_name, UT_TESTF_CONSOLE_REC);
632
Marek Vasutb6d1dec2023-03-02 04:08:34 +0100633static int fdt_test_get_addr_common(struct unit_test_state *uts, char *fdt,
634 const char *path, const char *prop)
635{
636 unsigned int offset;
637 int path_offset;
638 void *prop_ptr;
639 int len = 0;
640
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;
646
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));
652
653 return 0;
654}
655
656static int fdt_test_get_addr(struct unit_test_state *uts)
657{
658 char fdt[4096];
659 ulong addr;
660
661 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt)));
662 addr = map_to_sysmem(fdt);
663 set_working_fdt_addr(addr);
664
665 /* Test getting address of root node / string property "compatible" */
666 fdt_test_get_addr_common(uts, fdt, "/", "compatible");
667
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");
671
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");
675
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");
679
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");
683
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));
689
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));
695
696 return 0;
697}
698FDT_TEST(fdt_test_get_addr, UT_TESTF_CONSOLE_REC);
699
Marek Vasut66e975a2023-03-02 04:08:35 +0100700static int fdt_test_get_size_common(struct unit_test_state *uts,
701 const char *path, const char *prop,
702 const unsigned int val)
703{
704 ut_assertok(console_record_reset_enable());
705 if (prop) {
706 ut_assertok(run_commandf("fdt get size sstr %s %s", path, prop));
707 } else {
708 ut_assertok(run_commandf("fdt get size sstr %s", path));
709 }
710 ut_asserteq(val, env_get_hex("sstr", 0x1234));
711 ut_assertok(ut_check_console_end(uts));
712
713 return 0;
714}
715
716static int fdt_test_get_size(struct unit_test_state *uts)
717{
718 char fdt[4096];
719 ulong addr;
720
721 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt)));
722 addr = map_to_sysmem(fdt);
723 set_working_fdt_addr(addr);
724
725 /* Test getting size of root node / string property "compatible" */
726 fdt_test_get_size_common(uts, "/", "compatible", 16);
727
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);
731
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);
735
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);
739
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);
743
744 /* Test getting node count of node / */
745 fdt_test_get_size_common(uts, "/", NULL, 2);
746
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);
750
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));
758
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));
764
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));
770
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));
776
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));
782
783 return 0;
784}
785FDT_TEST(fdt_test_get_size, UT_TESTF_CONSOLE_REC);
786
Marek Vasut8bd49a82023-03-02 04:08:36 +0100787static 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)
790{
791 /*
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
796 */
797 ut_assertok(console_record_reset_enable());
Marek Vasuta96dea22023-03-10 04:33:14 +0100798 if (sval)
Marek Vasut8bd49a82023-03-02 04:08:36 +0100799 ut_assertok(run_commandf("fdt set %s %s %s", path, prop, sval));
Marek Vasuta96dea22023-03-10 04:33:14 +0100800 else if (integer)
Marek Vasut8bd49a82023-03-02 04:08:36 +0100801 ut_assertok(run_commandf("fdt set %s %s <%d>", path, prop, ival));
Marek Vasuta96dea22023-03-10 04:33:14 +0100802 else
Marek Vasut8bd49a82023-03-02 04:08:36 +0100803 ut_assertok(run_commandf("fdt set %s %s", path, prop));
Marek Vasut8bd49a82023-03-02 04:08:36 +0100804
805 /* Validate the property is present and has correct value. */
806 ut_assertok(run_commandf("fdt get value svar %s %s", path, prop));
Marek Vasuta96dea22023-03-10 04:33:14 +0100807 if (sval)
Marek Vasut8bd49a82023-03-02 04:08:36 +0100808 ut_asserteq_str(sval, env_get("svar"));
Marek Vasuta96dea22023-03-10 04:33:14 +0100809 else if (integer)
Marek Vasut8bd49a82023-03-02 04:08:36 +0100810 ut_asserteq(ival, env_get_hex("svar", 0x1234));
Marek Vasuta96dea22023-03-10 04:33:14 +0100811 else
Marek Vasut8bd49a82023-03-02 04:08:36 +0100812 ut_assertnull(env_get("svar"));
Marek Vasut8bd49a82023-03-02 04:08:36 +0100813 ut_assertok(ut_check_console_end(uts));
814
815 return 0;
816}
817
818static 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)
822{
823 /*
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>
827 *
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
833 * triggers failure.
834 */
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));
839 } else {
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));
842 }
843
844 /*
845 * Validate the property is present and has correct value.
846 *
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
849 * shorter array.
850 */
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"));
858 } else {
859 ut_asserteq(ival1, env_get_hex("svar1", 0x1234));
860 ut_asserteq(ival2, env_get_hex("svar2", 0x1234));
861 ut_assertnull(env_get("svarn"));
862 }
863 ut_assertok(ut_check_console_end(uts));
864
865 return 0;
866}
867
868static int fdt_test_set_node(struct unit_test_state *uts,
869 const char *path, const char *prop)
870{
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);
879
880 return 0;
881}
882
883static int fdt_test_set(struct unit_test_state *uts)
884{
885 char fdt[8192];
886 ulong addr;
887
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);
892
893 /* Test setting of root node / existing property "compatible" */
894 fdt_test_set_node(uts, "/", "compatible");
895
896 /* Test setting of root node / new property "newproperty" */
897 fdt_test_set_node(uts, "/", "newproperty");
898
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");
902
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");
906
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));
912
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));
918
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));
924
925 return 0;
926}
927FDT_TEST(fdt_test_set, UT_TESTF_CONSOLE_REC);
928
Marek Vasut6c285942023-03-02 04:08:37 +0100929static int fdt_test_mknode(struct unit_test_state *uts)
930{
931 char fdt[8192];
932 ulong addr;
933
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);
938
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));
946
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));
954
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));
962
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));
968
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));
974
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));
980
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));
986
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));
992
993 return 0;
994}
995FDT_TEST(fdt_test_mknode, UT_TESTF_CONSOLE_REC);
996
Marek Vasute46a4382023-03-02 04:08:38 +0100997static int fdt_test_rm(struct unit_test_state *uts)
998{
999 char fdt[4096];
1000 ulong addr;
1001
1002 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt)));
1003 addr = map_to_sysmem(fdt);
1004 set_working_fdt_addr(addr);
1005
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));
1014
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));
1023
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));
1032
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));
1038
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));
1044
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));
1051
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));
1057
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));
1063
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));
1070
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));
1076
1077 return 0;
1078}
1079FDT_TEST(fdt_test_rm, UT_TESTF_CONSOLE_REC);
1080
Marek Vasut26281512023-03-02 04:08:40 +01001081static int fdt_test_bootcpu(struct unit_test_state *uts)
1082{
1083 char fdt[256];
1084 ulong addr;
1085 int i;
1086
1087 ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt)));
1088 addr = map_to_sysmem(fdt);
1089 set_working_fdt_addr(addr);
1090
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));
1096
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));
1102
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));
1108 }
1109
1110 return 0;
1111}
1112FDT_TEST(fdt_test_bootcpu, UT_TESTF_CONSOLE_REC);
1113
Marek Vasut927e03b2023-03-02 04:08:39 +01001114static int fdt_test_header_get(struct unit_test_state *uts,
1115 const char *field, const unsigned long val)
1116{
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));
1122
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));
1127
1128 return 0;
1129}
1130
1131static int fdt_test_header(struct unit_test_state *uts)
1132{
1133 char fdt[256];
1134 ulong addr;
1135
1136 ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt)));
1137 addr = map_to_sysmem(fdt);
1138 set_working_fdt_addr(addr);
1139
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));
1156
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));
1168
1169 return 0;
1170}
1171FDT_TEST(fdt_test_header, UT_TESTF_CONSOLE_REC);
1172
Marek Vasutd9b4c9f2023-03-02 04:08:41 +01001173static int fdt_test_memory_cells(struct unit_test_state *uts,
1174 const unsigned int cells)
1175{
1176 unsigned char *pada, *pads;
1177 unsigned char *seta, *sets;
1178 char fdt[8192];
1179 const int size = sizeof(fdt);
1180 fdt32_t *regs;
1181 ulong addr;
1182 char *spc;
1183 int i;
1184
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);
1199 }
1200
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", &regs, 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);
1215
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));
1225
1226 free(sets);
1227 free(seta);
1228 free(pads);
1229 free(pada);
1230 free(regs);
1231
1232 return 0;
1233}
1234
1235static int fdt_test_memory(struct unit_test_state *uts)
1236{
1237 /*
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.
1241 */
1242 fdt_test_memory_cells(uts, 1);
1243 fdt_test_memory_cells(uts, 2);
1244
1245 /*
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.
1250 */
1251
1252 return 0;
1253}
1254FDT_TEST(fdt_test_memory, UT_TESTF_CONSOLE_REC);
1255
Marek Vasut50daa2e2023-03-02 04:08:42 +01001256static int fdt_test_rsvmem(struct unit_test_state *uts)
1257{
1258 char fdt[8192];
1259 ulong addr;
1260
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);
1267
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));
1276
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));
1287
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));
1297
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));
1308
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));
1314
1315 return 0;
1316}
1317FDT_TEST(fdt_test_rsvmem, UT_TESTF_CONSOLE_REC);
1318
Marek Vasut77291e62023-03-02 04:08:43 +01001319static int fdt_test_chosen(struct unit_test_state *uts)
1320{
1321 const char *env_bootargs = env_get("bootargs");
1322 char fdt[8192];
1323 ulong addr;
1324
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);
1329
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));
1335
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 */
1342 if (env_bootargs)
1343 ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs);
1344 ut_assert_nextline("};");
1345 ut_assertok(ut_check_console_end(uts));
1346
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 */
1358 if (env_bootargs)
1359 ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs);
1360 ut_assert_nextline("};");
1361 ut_assertok(ut_check_console_end(uts));
1362
1363 return 0;
1364}
1365FDT_TEST(fdt_test_chosen, UT_TESTF_CONSOLE_REC);
1366
Marek Vasutc5fe73e2023-03-02 04:08:44 +01001367static int fdt_test_apply(struct unit_test_state *uts)
1368{
1369 char fdt[8192], fdto[8192];
1370 ulong addr, addro;
1371
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);
1383
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);
1396
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));
1405
1406 /* Test simple DTO application */
1407 ut_assertok(console_record_reset_enable());
Evgeny Bachinin0d73c232023-03-20 11:23:13 +03001408 ut_assertok(run_commandf("fdt apply 0x%08lx", addro));
Marek Vasutc5fe73e2023-03-02 04:08:44 +01001409 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));
1416
1417 /*
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
1423 */
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));
1429
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));
1444
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);
1450
1451 /* Test complex DTO application */
1452 ut_assertok(console_record_reset_enable());
Evgeny Bachinin0d73c232023-03-20 11:23:13 +03001453 ut_assertok(run_commandf("fdt apply 0x%08lx", addro));
Marek Vasutc5fe73e2023-03-02 04:08:44 +01001454 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));
1470
1471 /*
1472 * Create complex DTO which:
1473 * - modifies subnewu32 property in subnode via phandle and uses __fixups__ node
1474 */
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));
1480
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));
1487
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);
1494
1495 /* Test complex DTO application */
1496 ut_assertok(console_record_reset_enable());
Evgeny Bachinin0d73c232023-03-20 11:23:13 +03001497 ut_assertok(run_commandf("fdt apply 0x%08lx", addro));
Marek Vasutc5fe73e2023-03-02 04:08:44 +01001498 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));
1514
1515 return 0;
1516}
1517FDT_TEST(fdt_test_apply, UT_TESTF_CONSOLE_REC);
1518
Simon Glass74724482022-07-13 06:06:59 -06001519int do_ut_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
1520{
1521 struct unit_test *tests = UNIT_TEST_SUITE_START(fdt_test);
1522 const int n_ents = UNIT_TEST_SUITE_COUNT(fdt_test);
1523
1524 return cmd_ut_category("fdt", "fdt_test_", tests, n_ents, argc, argv);
1525}