blob: e64785101cd762b19826f789df16b6706062b9fa [file] [log] [blame]
Simon Glassf3c6a1d2022-07-13 06:06:59 -06001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Tests for fdt command
4 *
Marek Vasutd578efb2023-04-22 14:59:58 +02005 * Copyright 2022 Google LLC
Simon Glassf3c6a1d2022-07-13 06:06:59 -06006 */
7
Simon Glassf3c6a1d2022-07-13 06:06:59 -06008#include <console.h>
9#include <fdt_support.h>
10#include <mapmem.h>
11#include <asm/global_data.h>
12#include <linux/libfdt.h>
13#include <test/suites.h>
14#include <test/ut.h>
15
16DECLARE_GLOBAL_DATA_PTR;
Marek Vasutf2def362023-03-02 04:08:45 +010017/*
18 * Missing tests:
19 * fdt boardsetup - Do board-specific set up
20 * fdt checksign [<addr>] - check FIT signature
21 * <addr> - address of key blob
22 * default gd->fdt_blob
23 */
Simon Glassf3c6a1d2022-07-13 06:06:59 -060024
25/* Declare a new fdt test */
26#define FDT_TEST(_name, _flags) UNIT_TEST(_name, _flags, fdt_test)
27
28/**
29 * make_test_fdt() - Create an FDT with just a root node
30 *
Simon Glass27c46ab2024-08-22 07:57:56 -060031 * The size is set to the minimum needed. This also sets the working FDT and
32 * checks that the expected output is received from doing so.
Simon Glassf3c6a1d2022-07-13 06:06:59 -060033 *
34 * @uts: Test state
35 * @fdt: Place to write FDT
36 * @size: Maximum size of space for fdt
Simon Glass27c46ab2024-08-22 07:57:56 -060037 * @addrp: Returns address of the devicetree
Simon Glassf3c6a1d2022-07-13 06:06:59 -060038 */
Simon Glass27c46ab2024-08-22 07:57:56 -060039static int make_test_fdt(struct unit_test_state *uts, void *fdt, int size,
40 ulong *addrp)
Simon Glassf3c6a1d2022-07-13 06:06:59 -060041{
Simon Glass27c46ab2024-08-22 07:57:56 -060042 ulong addr;
43
Simon Glassf3c6a1d2022-07-13 06:06:59 -060044 ut_assertok(fdt_create(fdt, size));
45 ut_assertok(fdt_finish_reservemap(fdt));
46 ut_assert(fdt_begin_node(fdt, "") >= 0);
47 ut_assertok(fdt_end_node(fdt));
48 ut_assertok(fdt_finish(fdt));
49
Simon Glass27c46ab2024-08-22 07:57:56 -060050 addr = map_to_sysmem(fdt);
51 set_working_fdt_addr(addr);
52 ut_assert_nextline("Working FDT set to %lx", addr);
53 *addrp = addr;
54
Simon Glassf3c6a1d2022-07-13 06:06:59 -060055 return 0;
56}
57
Marek Vasut15503d02023-03-02 04:08:27 +010058/**
59 * make_fuller_fdt() - Create an FDT with root node and properties
60 *
Simon Glass27c46ab2024-08-22 07:57:56 -060061 * The size is set to the minimum needed. This also sets the working FDT and
62 * checks that the expected output is received from doing so.
Marek Vasut15503d02023-03-02 04:08:27 +010063 *
64 * @uts: Test state
65 * @fdt: Place to write FDT
66 * @size: Maximum size of space for fdt
Simon Glass27c46ab2024-08-22 07:57:56 -060067 * @addrp: Returns address of the devicetree
Marek Vasut15503d02023-03-02 04:08:27 +010068 */
Simon Glass27c46ab2024-08-22 07:57:56 -060069static int make_fuller_fdt(struct unit_test_state *uts, void *fdt, int size,
70 ulong *addrp)
Marek Vasut15503d02023-03-02 04:08:27 +010071{
72 fdt32_t regs[2] = { cpu_to_fdt32(0x1234), cpu_to_fdt32(0x1000) };
Simon Glass27c46ab2024-08-22 07:57:56 -060073 ulong addr;
Marek Vasut15503d02023-03-02 04:08:27 +010074
75 /*
76 * Assemble the following DT for test purposes:
77 *
78 * / {
79 * #address-cells = <0x00000001>;
80 * #size-cells = <0x00000001>;
81 * compatible = "u-boot,fdt-test";
82 * model = "U-Boot FDT test";
83 *
84 * aliases {
85 * badalias = "/bad/alias";
86 * subnodealias = "/test-node@1234/subnode";
87 * testnodealias = "/test-node@1234";
88 * };
89 *
90 * test-node@1234 {
91 * #address-cells = <0x00000000>;
92 * #size-cells = <0x00000000>;
93 * compatible = "u-boot,fdt-test-device1";
94 * clock-names = "fixed", "i2c", "spi", "uart2", "uart1";
95 * u-boot,empty-property;
96 * clock-frequency = <0x00fde800>;
97 * regs = <0x00001234 0x00001000>;
98 *
99 * subnode {
100 * #address-cells = <0x00000000>;
101 * #size-cells = <0x00000000>;
102 * compatible = "u-boot,fdt-subnode-test-device";
103 * };
104 * };
105 * };
106 */
107
108 ut_assertok(fdt_create(fdt, size));
109 ut_assertok(fdt_finish_reservemap(fdt));
110 ut_assert(fdt_begin_node(fdt, "") >= 0);
111
112 ut_assertok(fdt_property_u32(fdt, "#address-cells", 1));
113 ut_assertok(fdt_property_u32(fdt, "#size-cells", 1));
114 /* <string> */
115 ut_assertok(fdt_property_string(fdt, "compatible", "u-boot,fdt-test"));
116 /* <string> */
117 ut_assertok(fdt_property_string(fdt, "model", "U-Boot FDT test"));
118
119 ut_assert(fdt_begin_node(fdt, "aliases") >= 0);
120 /* <string> */
121 ut_assertok(fdt_property_string(fdt, "badalias", "/bad/alias"));
122 /* <string> */
123 ut_assertok(fdt_property_string(fdt, "subnodealias", "/test-node@1234/subnode"));
124 /* <string> */
125 ut_assertok(fdt_property_string(fdt, "testnodealias", "/test-node@1234"));
126 ut_assertok(fdt_end_node(fdt));
127
128 ut_assert(fdt_begin_node(fdt, "test-node@1234") >= 0);
129 ut_assertok(fdt_property_cell(fdt, "#address-cells", 0));
130 ut_assertok(fdt_property_cell(fdt, "#size-cells", 0));
131 /* <string> */
132 ut_assertok(fdt_property_string(fdt, "compatible", "u-boot,fdt-test-device1"));
133 /* <stringlist> */
134 ut_assertok(fdt_property(fdt, "clock-names", "fixed\0i2c\0spi\0uart2\0uart1\0", 26));
135 /* <empty> */
136 ut_assertok(fdt_property(fdt, "u-boot,empty-property", NULL, 0));
137 /*
138 * <u32>
139 * This value is deliberate as it used to break cmd/fdt.c
140 * is_printable_string() implementation.
141 */
142 ut_assertok(fdt_property_u32(fdt, "clock-frequency", 16640000));
143 /* <prop-encoded-array> */
144 ut_assertok(fdt_property(fdt, "regs", &regs, sizeof(regs)));
145 ut_assert(fdt_begin_node(fdt, "subnode") >= 0);
146 ut_assertok(fdt_property_cell(fdt, "#address-cells", 0));
147 ut_assertok(fdt_property_cell(fdt, "#size-cells", 0));
148 ut_assertok(fdt_property_string(fdt, "compatible", "u-boot,fdt-subnode-test-device"));
149 ut_assertok(fdt_end_node(fdt));
150 ut_assertok(fdt_end_node(fdt));
151
152 ut_assertok(fdt_end_node(fdt));
153 ut_assertok(fdt_finish(fdt));
154
Simon Glass27c46ab2024-08-22 07:57:56 -0600155 addr = map_to_sysmem(fdt);
156 set_working_fdt_addr(addr);
157 ut_assert_nextline("Working FDT set to %lx", addr);
158 *addrp = addr;
159
Marek Vasut15503d02023-03-02 04:08:27 +0100160 return 0;
161}
162
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600163/* Test 'fdt addr' getting/setting address */
164static int fdt_test_addr(struct unit_test_state *uts)
165{
166 const void *fdt_blob, *new_fdt;
167 char fdt[256];
168 ulong addr;
169 int ret;
170
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600171 ut_assertok(run_command("fdt addr -c", 0));
172 ut_assert_nextline("Control fdt: %08lx",
173 (ulong)map_to_sysmem(gd->fdt_blob));
Simon Glassc579bd42024-08-22 07:58:03 -0600174 ut_assert_console_end();
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600175
176 /* The working fdt is not set, so this should fail */
177 set_working_fdt_addr(0);
Simon Glass84328cf2022-10-11 09:47:12 -0600178 ut_assert_nextline("Working FDT set to 0");
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600179 ut_asserteq(CMD_RET_FAILURE, run_command("fdt addr", 0));
Simon Glass5ad263f2023-10-01 19:15:18 -0600180
181 /*
182 * sandbox fails the check for !blob since the 0 pointer is mapped to
183 * memory somewhere other than at 0x0
184 */
185 if (IS_ENABLED(CONFIG_SANDBOX))
186 ut_assert_nextline("libfdt fdt_check_header(): FDT_ERR_BADMAGIC");
Simon Glassc579bd42024-08-22 07:58:03 -0600187 ut_assert_console_end();
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600188
189 /* Set up a working FDT and try again */
Simon Glass27c46ab2024-08-22 07:57:56 -0600190 ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt), &addr));
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600191 ut_assertok(run_command("fdt addr", 0));
192 ut_assert_nextline("Working fdt: %08lx", (ulong)map_to_sysmem(fdt));
Simon Glassc579bd42024-08-22 07:58:03 -0600193 ut_assert_console_end();
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600194
195 /* Set the working FDT */
196 set_working_fdt_addr(0);
Simon Glass84328cf2022-10-11 09:47:12 -0600197 ut_assert_nextline("Working FDT set to 0");
Evgeny Bachinine604bc02023-03-20 11:23:13 +0300198 ut_assertok(run_commandf("fdt addr %08lx", addr));
Simon Glass84328cf2022-10-11 09:47:12 -0600199 ut_assert_nextline("Working FDT set to %lx", addr);
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600200 ut_asserteq(addr, map_to_sysmem(working_fdt));
Simon Glassc579bd42024-08-22 07:58:03 -0600201 ut_assert_console_end();
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600202 set_working_fdt_addr(0);
Simon Glass84328cf2022-10-11 09:47:12 -0600203 ut_assert_nextline("Working FDT set to 0");
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600204
Simon Glass84328cf2022-10-11 09:47:12 -0600205 /* Set the control FDT */
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600206 fdt_blob = gd->fdt_blob;
207 gd->fdt_blob = NULL;
Evgeny Bachinine604bc02023-03-20 11:23:13 +0300208 ret = run_commandf("fdt addr -c %08lx", addr);
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600209 new_fdt = gd->fdt_blob;
210 gd->fdt_blob = fdt_blob;
211 ut_assertok(ret);
212 ut_asserteq(addr, map_to_sysmem(new_fdt));
Simon Glassc579bd42024-08-22 07:58:03 -0600213 ut_assert_console_end();
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600214
215 /* Test setting an invalid FDT */
216 fdt[0] = 123;
Evgeny Bachinine604bc02023-03-20 11:23:13 +0300217 ut_asserteq(1, run_commandf("fdt addr %08lx", addr));
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600218 ut_assert_nextline("libfdt fdt_check_header(): FDT_ERR_BADMAGIC");
Simon Glassc579bd42024-08-22 07:58:03 -0600219 ut_assert_console_end();
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600220
221 /* Test detecting an invalid FDT */
222 fdt[0] = 123;
223 set_working_fdt_addr(addr);
Simon Glass84328cf2022-10-11 09:47:12 -0600224 ut_assert_nextline("Working FDT set to %lx", addr);
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600225 ut_asserteq(1, run_commandf("fdt addr"));
226 ut_assert_nextline("libfdt fdt_check_header(): FDT_ERR_BADMAGIC");
Simon Glassc579bd42024-08-22 07:58:03 -0600227 ut_assert_console_end();
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600228
229 return 0;
230}
Simon Glass11fcfa32024-08-22 07:57:50 -0600231FDT_TEST(fdt_test_addr, UTF_CONSOLE);
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600232
233/* Test 'fdt addr' resizing an fdt */
Marek Vasut6e04a892023-03-02 04:08:25 +0100234static int fdt_test_addr_resize(struct unit_test_state *uts)
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600235{
236 char fdt[256];
237 const int newsize = sizeof(fdt) / 2;
238 ulong addr;
239
Simon Glass27c46ab2024-08-22 07:57:56 -0600240 ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt), &addr));
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600241
242 /* Test setting and resizing the working FDT to a larger size */
Evgeny Bachinine604bc02023-03-20 11:23:13 +0300243 ut_assertok(run_commandf("fdt addr %08lx %x", addr, newsize));
Simon Glass84328cf2022-10-11 09:47:12 -0600244 ut_assert_nextline("Working FDT set to %lx", addr);
Simon Glassc579bd42024-08-22 07:58:03 -0600245 ut_assert_console_end();
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600246
247 /* Try shrinking it */
Evgeny Bachinine604bc02023-03-20 11:23:13 +0300248 ut_assertok(run_commandf("fdt addr %08lx %zx", addr, sizeof(fdt) / 4));
Simon Glass84328cf2022-10-11 09:47:12 -0600249 ut_assert_nextline("Working FDT set to %lx", addr);
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600250 ut_assert_nextline("New length %d < existing length %d, ignoring",
251 (int)sizeof(fdt) / 4, newsize);
Simon Glassc579bd42024-08-22 07:58:03 -0600252 ut_assert_console_end();
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600253
254 /* ...quietly */
Evgeny Bachinine604bc02023-03-20 11:23:13 +0300255 ut_assertok(run_commandf("fdt addr -q %08lx %zx", addr, sizeof(fdt) / 4));
Simon Glassc579bd42024-08-22 07:58:03 -0600256 ut_assert_console_end();
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600257
258 /* We cannot easily provoke errors in fdt_open_into(), so ignore that */
259
260 return 0;
261}
Simon Glass11fcfa32024-08-22 07:57:50 -0600262FDT_TEST(fdt_test_addr_resize, UTF_CONSOLE);
Simon Glassf3c6a1d2022-07-13 06:06:59 -0600263
Marek Vasutddf86202023-03-02 04:08:30 +0100264static int fdt_test_move(struct unit_test_state *uts)
265{
266 char fdt[256];
267 ulong addr, newaddr = 0x10000;
268 const int size = sizeof(fdt);
269 uint32_t ts;
270 void *buf;
271
272 /* Original source DT */
Simon Glass27c46ab2024-08-22 07:57:56 -0600273 ut_assertok(make_test_fdt(uts, fdt, size, &addr));
Marek Vasutddf86202023-03-02 04:08:30 +0100274 ts = fdt_totalsize(fdt);
Marek Vasutddf86202023-03-02 04:08:30 +0100275
276 /* Moved target DT location */
277 buf = map_sysmem(newaddr, size);
278 memset(buf, 0, size);
279
280 /* Test moving the working FDT to a new location */
Evgeny Bachinine604bc02023-03-20 11:23:13 +0300281 ut_assertok(run_commandf("fdt move %08lx %08lx %x", addr, newaddr, ts));
Marek Vasutddf86202023-03-02 04:08:30 +0100282 ut_assert_nextline("Working FDT set to %lx", newaddr);
Simon Glassc579bd42024-08-22 07:58:03 -0600283 ut_assert_console_end();
Marek Vasutddf86202023-03-02 04:08:30 +0100284
285 /* Compare the source and destination DTs */
Evgeny Bachinine604bc02023-03-20 11:23:13 +0300286 ut_assertok(run_commandf("cmp.b %08lx %08lx %x", addr, newaddr, ts));
Marek Vasutddf86202023-03-02 04:08:30 +0100287 ut_assert_nextline("Total of %d byte(s) were the same", ts);
Simon Glassc579bd42024-08-22 07:58:03 -0600288 ut_assert_console_end();
Marek Vasutddf86202023-03-02 04:08:30 +0100289
290 return 0;
291}
Simon Glass11fcfa32024-08-22 07:57:50 -0600292FDT_TEST(fdt_test_move, UTF_CONSOLE);
Marek Vasutddf86202023-03-02 04:08:30 +0100293
Marek Vasut6ab4fe22023-03-02 04:08:31 +0100294static int fdt_test_resize(struct unit_test_state *uts)
295{
296 char fdt[256];
297 const unsigned int newsize = 0x2000;
298 uint32_t ts;
299 ulong addr;
300
301 /* Original source DT */
Simon Glass27c46ab2024-08-22 07:57:56 -0600302 ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt), &addr));
Marek Vasut6ab4fe22023-03-02 04:08:31 +0100303 fdt_shrink_to_minimum(fdt, 0); /* Resize with 0 extra bytes */
304 ts = fdt_totalsize(fdt);
Marek Vasut6ab4fe22023-03-02 04:08:31 +0100305
306 /* Test resizing the working FDT and verify the new space was added */
Marek Vasut6ab4fe22023-03-02 04:08:31 +0100307 ut_assertok(run_commandf("fdt resize %x", newsize));
308 ut_asserteq(ts + newsize, fdt_totalsize(fdt));
Simon Glassc579bd42024-08-22 07:58:03 -0600309 ut_assert_console_end();
Marek Vasut6ab4fe22023-03-02 04:08:31 +0100310
311 return 0;
312}
Simon Glass11fcfa32024-08-22 07:57:50 -0600313FDT_TEST(fdt_test_resize, UTF_CONSOLE);
Marek Vasut6ab4fe22023-03-02 04:08:31 +0100314
Marek Vasut76a652a2023-03-02 04:08:32 +0100315static int fdt_test_print_list_common(struct unit_test_state *uts,
316 const char *opc, const char *node)
317{
318 /*
319 * Test printing/listing the working FDT
320 * subnode $node/subnode
321 */
Marek Vasut76a652a2023-03-02 04:08:32 +0100322 ut_assertok(run_commandf("fdt %s %s/subnode", opc, node));
323 ut_assert_nextline("subnode {");
324 ut_assert_nextline("\t#address-cells = <0x00000000>;");
325 ut_assert_nextline("\t#size-cells = <0x00000000>;");
326 ut_assert_nextline("\tcompatible = \"u-boot,fdt-subnode-test-device\";");
327 ut_assert_nextline("};");
Simon Glassc579bd42024-08-22 07:58:03 -0600328 ut_assert_console_end();
Marek Vasut76a652a2023-03-02 04:08:32 +0100329
330 /*
331 * Test printing/listing the working FDT
332 * path / string property model
333 */
Marek Vasut76a652a2023-03-02 04:08:32 +0100334 ut_assertok(run_commandf("fdt %s / model", opc));
335 ut_assert_nextline("model = \"U-Boot FDT test\"");
Simon Glassc579bd42024-08-22 07:58:03 -0600336 ut_assert_console_end();
Marek Vasut76a652a2023-03-02 04:08:32 +0100337
338 /*
339 * Test printing/listing the working FDT
340 * path $node string property compatible
341 */
Marek Vasut76a652a2023-03-02 04:08:32 +0100342 ut_assertok(run_commandf("fdt %s %s compatible", opc, node));
343 ut_assert_nextline("compatible = \"u-boot,fdt-test-device1\"");
Simon Glassc579bd42024-08-22 07:58:03 -0600344 ut_assert_console_end();
Marek Vasut76a652a2023-03-02 04:08:32 +0100345
346 /*
347 * Test printing/listing the working FDT
348 * path $node stringlist property clock-names
349 */
Marek Vasut76a652a2023-03-02 04:08:32 +0100350 ut_assertok(run_commandf("fdt %s %s clock-names", opc, node));
351 ut_assert_nextline("clock-names = \"fixed\", \"i2c\", \"spi\", \"uart2\", \"uart1\"");
Simon Glassc579bd42024-08-22 07:58:03 -0600352 ut_assert_console_end();
Marek Vasut76a652a2023-03-02 04:08:32 +0100353
354 /*
355 * Test printing/listing the working FDT
356 * path $node u32 property clock-frequency
357 */
Marek Vasut76a652a2023-03-02 04:08:32 +0100358 ut_assertok(run_commandf("fdt %s %s clock-frequency", opc, node));
359 ut_assert_nextline("clock-frequency = <0x00fde800>");
Simon Glassc579bd42024-08-22 07:58:03 -0600360 ut_assert_console_end();
Marek Vasut76a652a2023-03-02 04:08:32 +0100361
362 /*
363 * Test printing/listing the working FDT
364 * path $node empty property u-boot,empty-property
365 */
Marek Vasut76a652a2023-03-02 04:08:32 +0100366 ut_assertok(run_commandf("fdt %s %s u-boot,empty-property", opc, node));
367 /*
368 * This is the only 'fdt print' / 'fdt list' incantation which
369 * prefixes the property with node path. This has been in U-Boot
370 * since the beginning of the command 'fdt', keep it.
371 */
372 ut_assert_nextline("%s u-boot,empty-property", node);
Simon Glassc579bd42024-08-22 07:58:03 -0600373 ut_assert_console_end();
Marek Vasut76a652a2023-03-02 04:08:32 +0100374
375 /*
376 * Test printing/listing the working FDT
377 * path $node prop-encoded array property regs
378 */
Marek Vasut76a652a2023-03-02 04:08:32 +0100379 ut_assertok(run_commandf("fdt %s %s regs", opc, node));
380 ut_assert_nextline("regs = <0x00001234 0x00001000>");
Simon Glassc579bd42024-08-22 07:58:03 -0600381 ut_assert_console_end();
Marek Vasut76a652a2023-03-02 04:08:32 +0100382
383 return 0;
384}
385
386static int fdt_test_print_list(struct unit_test_state *uts, bool print)
387{
388 const char *opc = print ? "print" : "list";
389 char fdt[4096];
390 ulong addr;
391 int ret;
392
393 /* Original source DT */
Simon Glass27c46ab2024-08-22 07:57:56 -0600394 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt), &addr));
Marek Vasut76a652a2023-03-02 04:08:32 +0100395
396 /* Test printing/listing the working FDT -- node / */
Marek Vasut76a652a2023-03-02 04:08:32 +0100397 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("};");
Simon Glassc579bd42024-08-22 07:58:03 -0600427 ut_assert_console_end();
Marek Vasut76a652a2023-03-02 04:08:32 +0100428
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}
Simon Glass11fcfa32024-08-22 07:57:50 -0600440FDT_TEST(fdt_test_print, UTF_CONSOLE);
Marek Vasut76a652a2023-03-02 04:08:32 +0100441
442static int fdt_test_list(struct unit_test_state *uts)
443{
444 return fdt_test_print_list(uts, false);
445}
Simon Glass11fcfa32024-08-22 07:57:50 -0600446FDT_TEST(fdt_test_list, UTF_CONSOLE);
Marek Vasut76a652a2023-03-02 04:08:32 +0100447
Marek Vasutfbeca452023-03-02 04:08:26 +0100448/* Test 'fdt get value' reading an fdt */
Marek Vasut9f90cad2023-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{
Marek Vasut9f90cad2023-03-02 04:08:29 +0100454 ut_assertok(run_commandf("fdt get value var %s %s %s",
455 node, prop, idx ? : ""));
Simon Glassf80a9142024-08-22 07:57:55 -0600456 if (strres)
Marek Vasut9f90cad2023-03-02 04:08:29 +0100457 ut_asserteq_str(strres, env_get("var"));
Simon Glassf80a9142024-08-22 07:57:55 -0600458 else
Marek Vasut9f90cad2023-03-02 04:08:29 +0100459 ut_asserteq(intres, env_get_hex("var", 0x1234));
Simon Glassc579bd42024-08-22 07:58:03 -0600460 ut_assert_console_end();
Marek Vasut9f90cad2023-03-02 04:08:29 +0100461
462 return 0;
463}
464
Marek Vasutb7517b42023-03-02 04:08:28 +0100465static int fdt_test_get_value_common(struct unit_test_state *uts,
466 const char *node)
Marek Vasut78c060d2022-11-14 22:50:00 +0100467{
Marek Vasutb7517b42023-03-02 04:08:28 +0100468 /* Test getting default element of $node node clock-names property */
Simon Glassf80a9142024-08-22 07:57:55 -0600469 ut_assertok(fdt_test_get_value_string(uts, node, "clock-names", NULL,
470 "fixed", 0));
Marek Vasut78c060d2022-11-14 22:50:00 +0100471
Marek Vasutb7517b42023-03-02 04:08:28 +0100472 /* Test getting 0th element of $node node clock-names property */
Simon Glassf80a9142024-08-22 07:57:55 -0600473 ut_assertok(fdt_test_get_value_string(uts, node, "clock-names", "0",
474 "fixed", 0));
Marek Vasut78c060d2022-11-14 22:50:00 +0100475
Marek Vasutb7517b42023-03-02 04:08:28 +0100476 /* Test getting 1st element of $node node clock-names property */
Simon Glassf80a9142024-08-22 07:57:55 -0600477 ut_assertok(fdt_test_get_value_string(uts, node, "clock-names", "1",
478 "i2c", 0));
Marek Vasut78c060d2022-11-14 22:50:00 +0100479
Marek Vasutb7517b42023-03-02 04:08:28 +0100480 /* Test getting 2nd element of $node node clock-names property */
Simon Glassf80a9142024-08-22 07:57:55 -0600481 ut_assertok(fdt_test_get_value_string(uts, node, "clock-names", "2",
482 "spi", 0));
Marek Vasut9f90cad2023-03-02 04:08:29 +0100483
484 /*
485 * Test getting default element of $node node regs property.
486 * The result here is highly unusual, the non-index value read from
487 * integer array is a string of concatenated values from the array,
488 * but only if the array is shorter than 40 characters. Anything
489 * longer is an error. This is a special case for handling hashes.
490 */
Simon Glassf80a9142024-08-22 07:57:55 -0600491 ut_assertok(fdt_test_get_value_string(uts, node, "regs", NULL,
492 "3412000000100000", 0));
Marek Vasut9f90cad2023-03-02 04:08:29 +0100493
494 /* Test getting 0th element of $node node regs property */
Simon Glassf80a9142024-08-22 07:57:55 -0600495 ut_assertok(fdt_test_get_value_string(uts, node, "regs", "0", NULL,
496 0x1234));
Marek Vasut9f90cad2023-03-02 04:08:29 +0100497
498 /* Test getting 1st element of $node node regs property */
Simon Glassf80a9142024-08-22 07:57:55 -0600499 ut_assertok(fdt_test_get_value_string(uts, node, "regs", "1", NULL,
500 0x1000));
Marek Vasut78c060d2022-11-14 22:50:00 +0100501
Marek Vasutb7517b42023-03-02 04:08:28 +0100502 /* Test missing 10th element of $node node clock-names property */
Marek Vasutb7517b42023-03-02 04:08:28 +0100503 ut_asserteq(1, run_commandf("fdt get value ften %s clock-names 10", node));
Simon Glassc579bd42024-08-22 07:58:03 -0600504 ut_assert_console_end();
Marek Vasut78c060d2022-11-14 22:50:00 +0100505
Marek Vasut9f90cad2023-03-02 04:08:29 +0100506 /* Test missing 10th element of $node node regs property */
Marek Vasut9f90cad2023-03-02 04:08:29 +0100507 ut_asserteq(1, run_commandf("fdt get value ften %s regs 10", node));
Simon Glassc579bd42024-08-22 07:58:03 -0600508 ut_assert_console_end();
Marek Vasut9f90cad2023-03-02 04:08:29 +0100509
Marek Vasutb7517b42023-03-02 04:08:28 +0100510 /* Test getting default element of $node node nonexistent property */
Marek Vasutb7517b42023-03-02 04:08:28 +0100511 ut_asserteq(1, run_commandf("fdt get value fnone %s nonexistent", node));
Marek Vasut78c060d2022-11-14 22:50:00 +0100512 ut_assert_nextline("libfdt fdt_getprop(): FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -0600513 ut_assert_console_end();
Marek Vasut78c060d2022-11-14 22:50:00 +0100514
Marek Vasutb7517b42023-03-02 04:08:28 +0100515 return 0;
516}
517
518static int fdt_test_get_value(struct unit_test_state *uts)
519{
520 char fdt[4096];
521 ulong addr;
Marek Vasutb7517b42023-03-02 04:08:28 +0100522
Simon Glass27c46ab2024-08-22 07:57:56 -0600523 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt), &addr));
Marek Vasutb7517b42023-03-02 04:08:28 +0100524
Simon Glassf80a9142024-08-22 07:57:55 -0600525 ut_assertok(fdt_test_get_value_common(uts, "/test-node@1234"));
526 ut_assertok(fdt_test_get_value_common(uts, "testnodealias"));
Marek Vasutb7517b42023-03-02 04:08:28 +0100527
Marek Vasut78c060d2022-11-14 22:50:00 +0100528 /* Test getting default element of /nonexistent node */
Marek Vasut78c060d2022-11-14 22:50:00 +0100529 ut_asserteq(1, run_command("fdt get value fnode /nonexistent nonexistent", 1));
530 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -0600531 ut_assert_console_end();
Marek Vasut78c060d2022-11-14 22:50:00 +0100532
Marek Vasutb7517b42023-03-02 04:08:28 +0100533 /* Test getting default element of bad alias */
Marek Vasutb7517b42023-03-02 04:08:28 +0100534 ut_asserteq(1, run_command("fdt get value vbadalias badalias nonexistent", 1));
535 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -0600536 ut_assert_console_end();
Marek Vasutb7517b42023-03-02 04:08:28 +0100537
538 /* Test getting default element of nonexistent alias */
Marek Vasutb7517b42023-03-02 04:08:28 +0100539 ut_asserteq(1, run_command("fdt get value vnoalias noalias nonexistent", 1));
540 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_BADPATH");
Simon Glassc579bd42024-08-22 07:58:03 -0600541 ut_assert_console_end();
Marek Vasutb7517b42023-03-02 04:08:28 +0100542
Marek Vasut78c060d2022-11-14 22:50:00 +0100543 return 0;
544}
Simon Glass11fcfa32024-08-22 07:57:50 -0600545FDT_TEST(fdt_test_get_value, UTF_CONSOLE);
Marek Vasut78c060d2022-11-14 22:50:00 +0100546
Marek Vasut84499932023-03-02 04:08:33 +0100547static int fdt_test_get_name(struct unit_test_state *uts)
548{
549 char fdt[4096];
550 ulong addr;
551
Simon Glass27c46ab2024-08-22 07:57:56 -0600552 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt), &addr));
Marek Vasut84499932023-03-02 04:08:33 +0100553
554 /* Test getting name of node 0 in /, which is /aliases node */
Marek Vasut84499932023-03-02 04:08:33 +0100555 ut_assertok(run_command("fdt get name nzero / 0", 0));
556 ut_asserteq_str("aliases", env_get("nzero"));
Simon Glassc579bd42024-08-22 07:58:03 -0600557 ut_assert_console_end();
Marek Vasut84499932023-03-02 04:08:33 +0100558
559 /* Test getting name of node 1 in /, which is /test-node@1234 node */
Marek Vasut84499932023-03-02 04:08:33 +0100560 ut_assertok(run_command("fdt get name none / 1", 0));
561 ut_asserteq_str("test-node@1234", env_get("none"));
Simon Glassc579bd42024-08-22 07:58:03 -0600562 ut_assert_console_end();
Marek Vasut84499932023-03-02 04:08:33 +0100563
564 /* Test getting name of node -1 in /, which is /aliases node, same as 0 */
Marek Vasut84499932023-03-02 04:08:33 +0100565 ut_assertok(run_command("fdt get name nmone / -1", 0));
566 ut_asserteq_str("aliases", env_get("nmone"));
Simon Glassc579bd42024-08-22 07:58:03 -0600567 ut_assert_console_end();
Marek Vasut84499932023-03-02 04:08:33 +0100568
569 /* Test getting name of node 2 in /, which does not exist */
Marek Vasut84499932023-03-02 04:08:33 +0100570 ut_asserteq(1, run_command("fdt get name ntwo / 2", 1));
571 ut_assert_nextline("libfdt node not found");
Simon Glassc579bd42024-08-22 07:58:03 -0600572 ut_assert_console_end();
Marek Vasut84499932023-03-02 04:08:33 +0100573
574 /* Test getting name of node 0 in /test-node@1234, which is /subnode node */
Marek Vasut84499932023-03-02 04:08:33 +0100575 ut_assertok(run_command("fdt get name snzero /test-node@1234 0", 0));
576 ut_asserteq_str("subnode", env_get("snzero"));
577 ut_assertok(run_command("fdt get name asnzero testnodealias 0", 0));
578 ut_asserteq_str("subnode", env_get("asnzero"));
Simon Glassc579bd42024-08-22 07:58:03 -0600579 ut_assert_console_end();
Marek Vasut84499932023-03-02 04:08:33 +0100580
581 /* Test getting name of node 1 in /test-node@1234, which does not exist */
Marek Vasut84499932023-03-02 04:08:33 +0100582 ut_asserteq(1, run_command("fdt get name snone /test-node@1234 1", 1));
583 ut_assert_nextline("libfdt node not found");
584 ut_asserteq(1, run_command("fdt get name asnone testnodealias 1", 1));
585 ut_assert_nextline("libfdt node not found");
Simon Glassc579bd42024-08-22 07:58:03 -0600586 ut_assert_console_end();
Marek Vasut84499932023-03-02 04:08:33 +0100587
588 /* Test getting name of node -1 in /test-node@1234, which is /subnode node, same as 0 */
Marek Vasut84499932023-03-02 04:08:33 +0100589 ut_assertok(run_command("fdt get name snmone /test-node@1234 -1", 0));
590 ut_asserteq_str("subnode", env_get("snmone"));
591 ut_assertok(run_command("fdt get name asnmone testnodealias -1", 0));
592 ut_asserteq_str("subnode", env_get("asnmone"));
Simon Glassc579bd42024-08-22 07:58:03 -0600593 ut_assert_console_end();
Marek Vasut84499932023-03-02 04:08:33 +0100594
595 /* Test getting name of nonexistent node */
Marek Vasut84499932023-03-02 04:08:33 +0100596 ut_asserteq(1, run_command("fdt get name nonode /nonexistent 0", 1));
597 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -0600598 ut_assert_console_end();
Marek Vasut84499932023-03-02 04:08:33 +0100599
600 /* Test getting name of bad alias */
Marek Vasut84499932023-03-02 04:08:33 +0100601 ut_asserteq(1, run_command("fdt get name vbadalias badalias 0", 1));
602 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -0600603 ut_assert_console_end();
Marek Vasut84499932023-03-02 04:08:33 +0100604
605 /* Test getting name of nonexistent alias */
Marek Vasut84499932023-03-02 04:08:33 +0100606 ut_asserteq(1, run_command("fdt get name vnoalias noalias 0", 1));
607 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_BADPATH");
Simon Glassc579bd42024-08-22 07:58:03 -0600608 ut_assert_console_end();
Marek Vasut84499932023-03-02 04:08:33 +0100609
610 return 0;
611}
Simon Glass11fcfa32024-08-22 07:57:50 -0600612FDT_TEST(fdt_test_get_name, UTF_CONSOLE);
Marek Vasut84499932023-03-02 04:08:33 +0100613
Marek Vasutcadef862023-03-02 04:08:34 +0100614static int fdt_test_get_addr_common(struct unit_test_state *uts, char *fdt,
615 const char *path, const char *prop)
616{
617 unsigned int offset;
618 int path_offset;
619 void *prop_ptr;
620 int len = 0;
621
622 path_offset = fdt_path_offset(fdt, path);
623 ut_assert(path_offset >= 0);
624 prop_ptr = (void *)fdt_getprop(fdt, path_offset, prop, &len);
625 ut_assertnonnull(prop_ptr);
626 offset = (char *)prop_ptr - fdt;
627
Marek Vasutcadef862023-03-02 04:08:34 +0100628 ut_assertok(run_commandf("fdt get addr pstr %s %s", path, prop));
629 ut_asserteq((ulong)map_sysmem(env_get_hex("fdtaddr", 0x1234), 0),
630 (ulong)(map_sysmem(env_get_hex("pstr", 0x1234), 0) - offset));
Simon Glassc579bd42024-08-22 07:58:03 -0600631 ut_assert_console_end();
Marek Vasutcadef862023-03-02 04:08:34 +0100632
633 return 0;
634}
635
636static int fdt_test_get_addr(struct unit_test_state *uts)
637{
638 char fdt[4096];
639 ulong addr;
640
Simon Glass27c46ab2024-08-22 07:57:56 -0600641 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt), &addr));
Marek Vasutcadef862023-03-02 04:08:34 +0100642
643 /* Test getting address of root node / string property "compatible" */
Simon Glassf80a9142024-08-22 07:57:55 -0600644 ut_assertok(fdt_test_get_addr_common(uts, fdt, "/", "compatible"));
Marek Vasutcadef862023-03-02 04:08:34 +0100645
646 /* Test getting address of node /test-node@1234 stringlist property "clock-names" */
Simon Glassf80a9142024-08-22 07:57:55 -0600647 ut_assertok(fdt_test_get_addr_common(uts, fdt, "/test-node@1234",
648 "clock-names"));
649 ut_assertok(fdt_test_get_addr_common(uts, fdt, "testnodealias",
650 "clock-names"));
Marek Vasutcadef862023-03-02 04:08:34 +0100651
652 /* Test getting address of node /test-node@1234 u32 property "clock-frequency" */
Simon Glassf80a9142024-08-22 07:57:55 -0600653 ut_assertok(fdt_test_get_addr_common(uts, fdt, "/test-node@1234",
654 "clock-frequency"));
655 ut_assertok(fdt_test_get_addr_common(uts, fdt, "testnodealias",
656 "clock-frequency"));
Marek Vasutcadef862023-03-02 04:08:34 +0100657
658 /* Test getting address of node /test-node@1234 empty property "u-boot,empty-property" */
Simon Glassf80a9142024-08-22 07:57:55 -0600659 ut_assertok(fdt_test_get_addr_common(uts, fdt, "/test-node@1234",
660 "u-boot,empty-property"));
661 ut_assertok(fdt_test_get_addr_common(uts, fdt, "testnodealias",
662 "u-boot,empty-property"));
Marek Vasutcadef862023-03-02 04:08:34 +0100663
664 /* Test getting address of node /test-node@1234 array property "regs" */
Simon Glassf80a9142024-08-22 07:57:55 -0600665 ut_assertok(fdt_test_get_addr_common(uts, fdt, "/test-node@1234",
666 "regs"));
667 ut_assertok(fdt_test_get_addr_common(uts, fdt, "testnodealias",
668 "regs"));
Marek Vasutcadef862023-03-02 04:08:34 +0100669
670 /* Test getting address of node /test-node@1234/subnode non-existent property "noprop" */
Marek Vasutcadef862023-03-02 04:08:34 +0100671 ut_asserteq(1, run_command("fdt get addr pnoprop /test-node@1234/subnode noprop", 1));
672 ut_assert_nextline("libfdt fdt_getprop(): FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -0600673 ut_assert_console_end();
Marek Vasutcadef862023-03-02 04:08:34 +0100674
675 /* Test getting address of non-existent node /test-node@1234/nonode@1 property "noprop" */
Marek Vasutcadef862023-03-02 04:08:34 +0100676 ut_asserteq(1, run_command("fdt get addr pnonode /test-node@1234/nonode@1 noprop", 1));
677 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -0600678 ut_assert_console_end();
Marek Vasutcadef862023-03-02 04:08:34 +0100679
680 return 0;
681}
Simon Glass11fcfa32024-08-22 07:57:50 -0600682FDT_TEST(fdt_test_get_addr, UTF_CONSOLE);
Marek Vasutcadef862023-03-02 04:08:34 +0100683
Marek Vasutce1b0482023-03-02 04:08:35 +0100684static int fdt_test_get_size_common(struct unit_test_state *uts,
685 const char *path, const char *prop,
686 const unsigned int val)
687{
Marek Vasutce1b0482023-03-02 04:08:35 +0100688 if (prop) {
689 ut_assertok(run_commandf("fdt get size sstr %s %s", path, prop));
690 } else {
691 ut_assertok(run_commandf("fdt get size sstr %s", path));
692 }
693 ut_asserteq(val, env_get_hex("sstr", 0x1234));
Simon Glassc579bd42024-08-22 07:58:03 -0600694 ut_assert_console_end();
Marek Vasutce1b0482023-03-02 04:08:35 +0100695
696 return 0;
697}
698
699static int fdt_test_get_size(struct unit_test_state *uts)
700{
701 char fdt[4096];
702 ulong addr;
703
Simon Glass27c46ab2024-08-22 07:57:56 -0600704 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt), &addr));
Marek Vasutce1b0482023-03-02 04:08:35 +0100705
706 /* Test getting size of root node / string property "compatible" */
Simon Glassf80a9142024-08-22 07:57:55 -0600707 ut_assertok(fdt_test_get_size_common(uts, "/", "compatible", 16));
Marek Vasutce1b0482023-03-02 04:08:35 +0100708
709 /* Test getting size of node /test-node@1234 stringlist property "clock-names" */
Simon Glassf80a9142024-08-22 07:57:55 -0600710 ut_assertok(fdt_test_get_size_common(uts, "/test-node@1234",
711 "clock-names", 26));
712 ut_assertok(fdt_test_get_size_common(uts, "testnodealias",
713 "clock-names", 26));
Marek Vasutce1b0482023-03-02 04:08:35 +0100714
715 /* Test getting size of node /test-node@1234 u32 property "clock-frequency" */
Simon Glassf80a9142024-08-22 07:57:55 -0600716 ut_assertok(fdt_test_get_size_common(uts, "/test-node@1234",
717 "clock-frequency", 4));
718 ut_assertok(fdt_test_get_size_common(uts, "testnodealias",
719 "clock-frequency", 4));
Marek Vasutce1b0482023-03-02 04:08:35 +0100720
721 /* Test getting size of node /test-node@1234 empty property "u-boot,empty-property" */
Simon Glassf80a9142024-08-22 07:57:55 -0600722 ut_assertok(fdt_test_get_size_common(uts, "/test-node@1234",
723 "u-boot,empty-property", 0));
724 ut_assertok(fdt_test_get_size_common(uts, "testnodealias",
725 "u-boot,empty-property", 0));
Marek Vasutce1b0482023-03-02 04:08:35 +0100726
727 /* Test getting size of node /test-node@1234 array property "regs" */
Simon Glassf80a9142024-08-22 07:57:55 -0600728 ut_assertok(fdt_test_get_size_common(uts, "/test-node@1234", "regs",
729 8));
730 ut_assertok(fdt_test_get_size_common(uts, "testnodealias", "regs", 8));
Marek Vasutce1b0482023-03-02 04:08:35 +0100731
732 /* Test getting node count of node / */
Simon Glassf80a9142024-08-22 07:57:55 -0600733 ut_assertok(fdt_test_get_size_common(uts, "/", NULL, 2));
Marek Vasutce1b0482023-03-02 04:08:35 +0100734
735 /* Test getting node count of node /test-node@1234/subnode */
Simon Glassf80a9142024-08-22 07:57:55 -0600736 ut_assertok(fdt_test_get_size_common(uts, "/test-node@1234/subnode",
737 NULL, 0));
738 ut_assertok(fdt_test_get_size_common(uts, "subnodealias", NULL, 0));
Marek Vasutce1b0482023-03-02 04:08:35 +0100739
740 /* Test getting size of node /test-node@1234/subnode non-existent property "noprop" */
Marek Vasutce1b0482023-03-02 04:08:35 +0100741 ut_asserteq(1, run_command("fdt get size pnoprop /test-node@1234/subnode noprop", 1));
742 ut_assert_nextline("libfdt fdt_getprop(): FDT_ERR_NOTFOUND");
743 ut_asserteq(1, run_command("fdt get size pnoprop subnodealias noprop", 1));
744 ut_assert_nextline("libfdt fdt_getprop(): FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -0600745 ut_assert_console_end();
Marek Vasutce1b0482023-03-02 04:08:35 +0100746
747 /* Test getting size of non-existent node /test-node@1234/nonode@1 property "noprop" */
Marek Vasutce1b0482023-03-02 04:08:35 +0100748 ut_asserteq(1, run_command("fdt get size pnonode /test-node@1234/nonode@1 noprop", 1));
749 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -0600750 ut_assert_console_end();
Marek Vasutce1b0482023-03-02 04:08:35 +0100751
752 /* Test getting node count of non-existent node /test-node@1234/nonode@1 */
Marek Vasutce1b0482023-03-02 04:08:35 +0100753 ut_asserteq(1, run_command("fdt get size pnonode /test-node@1234/nonode@1", 1));
754 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -0600755 ut_assert_console_end();
Marek Vasutce1b0482023-03-02 04:08:35 +0100756
757 /* Test getting node count of bad alias badalias */
Marek Vasutce1b0482023-03-02 04:08:35 +0100758 ut_asserteq(1, run_command("fdt get size pnonode badalias noprop", 1));
759 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -0600760 ut_assert_console_end();
Marek Vasutce1b0482023-03-02 04:08:35 +0100761
762 /* Test getting node count of non-existent alias noalias */
Marek Vasutce1b0482023-03-02 04:08:35 +0100763 ut_asserteq(1, run_command("fdt get size pnonode noalias", 1));
764 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_BADPATH");
Simon Glassc579bd42024-08-22 07:58:03 -0600765 ut_assert_console_end();
Marek Vasutce1b0482023-03-02 04:08:35 +0100766
767 return 0;
768}
Simon Glass11fcfa32024-08-22 07:57:50 -0600769FDT_TEST(fdt_test_get_size, UTF_CONSOLE);
Marek Vasutce1b0482023-03-02 04:08:35 +0100770
Marek Vasutf180de42023-03-02 04:08:36 +0100771static int fdt_test_set_single(struct unit_test_state *uts,
772 const char *path, const char *prop,
773 const char *sval, int ival, bool integer)
774{
775 /*
776 * Set single element string/integer/<empty> property into DT, that is:
777 * => fdt set /path property string
778 * => fdt set /path property integer
779 * => fdt set /path property
780 */
Marek Vasutbc8c1402023-03-10 04:33:14 +0100781 if (sval)
Marek Vasutf180de42023-03-02 04:08:36 +0100782 ut_assertok(run_commandf("fdt set %s %s %s", path, prop, sval));
Marek Vasutbc8c1402023-03-10 04:33:14 +0100783 else if (integer)
Marek Vasutf180de42023-03-02 04:08:36 +0100784 ut_assertok(run_commandf("fdt set %s %s <%d>", path, prop, ival));
Marek Vasutbc8c1402023-03-10 04:33:14 +0100785 else
Marek Vasutf180de42023-03-02 04:08:36 +0100786 ut_assertok(run_commandf("fdt set %s %s", path, prop));
Marek Vasutf180de42023-03-02 04:08:36 +0100787
788 /* Validate the property is present and has correct value. */
789 ut_assertok(run_commandf("fdt get value svar %s %s", path, prop));
Marek Vasutbc8c1402023-03-10 04:33:14 +0100790 if (sval)
Marek Vasutf180de42023-03-02 04:08:36 +0100791 ut_asserteq_str(sval, env_get("svar"));
Marek Vasutbc8c1402023-03-10 04:33:14 +0100792 else if (integer)
Marek Vasutf180de42023-03-02 04:08:36 +0100793 ut_asserteq(ival, env_get_hex("svar", 0x1234));
Marek Vasutbc8c1402023-03-10 04:33:14 +0100794 else
Marek Vasutf180de42023-03-02 04:08:36 +0100795 ut_assertnull(env_get("svar"));
Simon Glassc579bd42024-08-22 07:58:03 -0600796 ut_assert_console_end();
Marek Vasutf180de42023-03-02 04:08:36 +0100797
798 return 0;
799}
800
801static int fdt_test_set_multi(struct unit_test_state *uts,
802 const char *path, const char *prop,
803 const char *sval1, const char *sval2,
804 int ival1, int ival2)
805{
806 /*
807 * Set multi element string/integer array property in DT, that is:
808 * => fdt set /path property <string1 string2>
809 * => fdt set /path property <integer1 integer2>
810 *
811 * The set is done twice in here deliberately, The first set adds
812 * the property with an extra trailing element in its array to make
813 * the array longer, the second set is the expected final content of
814 * the array property. The longer array is used to verify that the
815 * new array is correctly sized and read past the new array length
816 * triggers failure.
817 */
Marek Vasutf180de42023-03-02 04:08:36 +0100818 if (sval1 && sval2) {
819 ut_assertok(run_commandf("fdt set %s %s %s %s end", path, prop, sval1, sval2));
820 ut_assertok(run_commandf("fdt set %s %s %s %s", path, prop, sval1, sval2));
821 } else {
822 ut_assertok(run_commandf("fdt set %s %s <%d %d 10>", path, prop, ival1, ival2));
823 ut_assertok(run_commandf("fdt set %s %s <%d %d>", path, prop, ival1, ival2));
824 }
825
826 /*
827 * Validate the property is present and has correct value.
828 *
829 * The "end/10" above and "svarn" below is used to validate that
830 * previous 'fdt set' to longer array does not polute newly set
831 * shorter array.
832 */
833 ut_assertok(run_commandf("fdt get value svar1 %s %s 0", path, prop));
834 ut_assertok(run_commandf("fdt get value svar2 %s %s 1", path, prop));
835 ut_asserteq(1, run_commandf("fdt get value svarn %s %s 2", path, prop));
836 if (sval1 && sval2) {
837 ut_asserteq_str(sval1, env_get("svar1"));
838 ut_asserteq_str(sval2, env_get("svar2"));
839 ut_assertnull(env_get("svarn"));
840 } else {
841 ut_asserteq(ival1, env_get_hex("svar1", 0x1234));
842 ut_asserteq(ival2, env_get_hex("svar2", 0x1234));
843 ut_assertnull(env_get("svarn"));
844 }
Simon Glassc579bd42024-08-22 07:58:03 -0600845 ut_assert_console_end();
Marek Vasutf180de42023-03-02 04:08:36 +0100846
847 return 0;
848}
849
850static int fdt_test_set_node(struct unit_test_state *uts,
851 const char *path, const char *prop)
852{
Simon Glassf80a9142024-08-22 07:57:55 -0600853 ut_assertok(fdt_test_set_single(uts, path, prop, "new", 0, false));
854 ut_assertok(fdt_test_set_single(uts, path, prop, "rewrite", 0, false));
855 ut_assertok(fdt_test_set_single(uts, path, prop, NULL, 42, true));
856 ut_assertok(fdt_test_set_single(uts, path, prop, NULL, 0, false));
857 ut_assertok(fdt_test_set_multi(uts, path, prop, NULL, NULL, 42, 1701));
858 ut_assertok(fdt_test_set_multi(uts, path, prop, NULL, NULL, 74656, 9));
859 ut_assertok(fdt_test_set_multi(uts, path, prop, "42", "1701", 0, 0));
860 ut_assertok(fdt_test_set_multi(uts, path, prop, "74656", "9", 0, 0));
Marek Vasutf180de42023-03-02 04:08:36 +0100861
862 return 0;
863}
864
865static int fdt_test_set(struct unit_test_state *uts)
866{
867 char fdt[8192];
868 ulong addr;
869
Simon Glass27c46ab2024-08-22 07:57:56 -0600870 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt), &addr));
Marek Vasutf180de42023-03-02 04:08:36 +0100871 fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */
Marek Vasutf180de42023-03-02 04:08:36 +0100872
873 /* Test setting of root node / existing property "compatible" */
Simon Glassf80a9142024-08-22 07:57:55 -0600874 ut_assertok(fdt_test_set_node(uts, "/", "compatible"));
Marek Vasutf180de42023-03-02 04:08:36 +0100875
876 /* Test setting of root node / new property "newproperty" */
Simon Glassf80a9142024-08-22 07:57:55 -0600877 ut_assertok(fdt_test_set_node(uts, "/", "newproperty"));
Marek Vasutf180de42023-03-02 04:08:36 +0100878
879 /* Test setting of subnode existing property "compatible" */
Simon Glassf80a9142024-08-22 07:57:55 -0600880 ut_assertok(fdt_test_set_node(uts, "/test-node@1234/subnode",
881 "compatible"));
882 ut_assertok(fdt_test_set_node(uts, "subnodealias", "compatible"));
Marek Vasutf180de42023-03-02 04:08:36 +0100883
884 /* Test setting of subnode new property "newproperty" */
Simon Glassf80a9142024-08-22 07:57:55 -0600885 ut_assertok(fdt_test_set_node(uts, "/test-node@1234/subnode",
886 "newproperty"));
887 ut_assertok(fdt_test_set_node(uts, "subnodealias", "newproperty"));
Marek Vasutf180de42023-03-02 04:08:36 +0100888
889 /* Test setting property of non-existent node */
Marek Vasutf180de42023-03-02 04:08:36 +0100890 ut_asserteq(1, run_command("fdt set /no-node noprop", 1));
891 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -0600892 ut_assert_console_end();
Marek Vasutf180de42023-03-02 04:08:36 +0100893
894 /* Test setting property of non-existent alias */
Marek Vasutf180de42023-03-02 04:08:36 +0100895 ut_asserteq(1, run_command("fdt set noalias noprop", 1));
896 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_BADPATH");
Simon Glassc579bd42024-08-22 07:58:03 -0600897 ut_assert_console_end();
Marek Vasutf180de42023-03-02 04:08:36 +0100898
899 /* Test setting property of bad alias */
Marek Vasutf180de42023-03-02 04:08:36 +0100900 ut_asserteq(1, run_command("fdt set badalias noprop", 1));
901 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -0600902 ut_assert_console_end();
Marek Vasutf180de42023-03-02 04:08:36 +0100903
904 return 0;
905}
Simon Glass11fcfa32024-08-22 07:57:50 -0600906FDT_TEST(fdt_test_set, UTF_CONSOLE);
Marek Vasutf180de42023-03-02 04:08:36 +0100907
Marek Vasute4d26c92023-03-02 04:08:37 +0100908static int fdt_test_mknode(struct unit_test_state *uts)
909{
910 char fdt[8192];
911 ulong addr;
912
Simon Glass27c46ab2024-08-22 07:57:56 -0600913 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt), &addr));
Marek Vasute4d26c92023-03-02 04:08:37 +0100914 fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */
Marek Vasute4d26c92023-03-02 04:08:37 +0100915
916 /* Test creation of new node in / */
Marek Vasute4d26c92023-03-02 04:08:37 +0100917 ut_assertok(run_commandf("fdt mknode / newnode"));
918 ut_assertok(run_commandf("fdt list /newnode"));
919 ut_assert_nextline("newnode {");
920 ut_assert_nextline("};");
Simon Glassc579bd42024-08-22 07:58:03 -0600921 ut_assert_console_end();
Marek Vasute4d26c92023-03-02 04:08:37 +0100922
923 /* Test creation of new node in /test-node@1234 */
Marek Vasute4d26c92023-03-02 04:08:37 +0100924 ut_assertok(run_commandf("fdt mknode /test-node@1234 newsubnode"));
925 ut_assertok(run_commandf("fdt list /test-node@1234/newsubnode"));
926 ut_assert_nextline("newsubnode {");
927 ut_assert_nextline("};");
Simon Glassc579bd42024-08-22 07:58:03 -0600928 ut_assert_console_end();
Marek Vasute4d26c92023-03-02 04:08:37 +0100929
930 /* Test creation of new node in /test-node@1234 by alias */
Marek Vasute4d26c92023-03-02 04:08:37 +0100931 ut_assertok(run_commandf("fdt mknode testnodealias newersubnode"));
932 ut_assertok(run_commandf("fdt list testnodealias/newersubnode"));
933 ut_assert_nextline("newersubnode {");
934 ut_assert_nextline("};");
Simon Glassc579bd42024-08-22 07:58:03 -0600935 ut_assert_console_end();
Marek Vasute4d26c92023-03-02 04:08:37 +0100936
937 /* Test creation of new node in /test-node@1234 over existing node */
Marek Vasute4d26c92023-03-02 04:08:37 +0100938 ut_asserteq(1, run_commandf("fdt mknode testnodealias newsubnode"));
939 ut_assert_nextline("libfdt fdt_add_subnode(): FDT_ERR_EXISTS");
Simon Glassc579bd42024-08-22 07:58:03 -0600940 ut_assert_console_end();
Marek Vasute4d26c92023-03-02 04:08:37 +0100941
942 /* Test creation of new node in /test-node@1234 by alias over existing node */
Marek Vasute4d26c92023-03-02 04:08:37 +0100943 ut_asserteq(1, run_commandf("fdt mknode testnodealias newersubnode"));
944 ut_assert_nextline("libfdt fdt_add_subnode(): FDT_ERR_EXISTS");
Simon Glassc579bd42024-08-22 07:58:03 -0600945 ut_assert_console_end();
Marek Vasute4d26c92023-03-02 04:08:37 +0100946
947 /* Test creation of new node in non-existent node */
Marek Vasute4d26c92023-03-02 04:08:37 +0100948 ut_asserteq(1, run_commandf("fdt mknode /no-node newnosubnode"));
949 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -0600950 ut_assert_console_end();
Marek Vasute4d26c92023-03-02 04:08:37 +0100951
952 /* Test creation of new node in non-existent alias */
Marek Vasute4d26c92023-03-02 04:08:37 +0100953 ut_asserteq(1, run_commandf("fdt mknode noalias newfailsubnode"));
954 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_BADPATH");
Simon Glassc579bd42024-08-22 07:58:03 -0600955 ut_assert_console_end();
Marek Vasute4d26c92023-03-02 04:08:37 +0100956
957 /* Test creation of new node in bad alias */
Marek Vasute4d26c92023-03-02 04:08:37 +0100958 ut_asserteq(1, run_commandf("fdt mknode badalias newbadsubnode"));
959 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -0600960 ut_assert_console_end();
Marek Vasute4d26c92023-03-02 04:08:37 +0100961
962 return 0;
963}
Simon Glass11fcfa32024-08-22 07:57:50 -0600964FDT_TEST(fdt_test_mknode, UTF_CONSOLE);
Marek Vasute4d26c92023-03-02 04:08:37 +0100965
Marek Vasutc3e350f2023-03-02 04:08:38 +0100966static int fdt_test_rm(struct unit_test_state *uts)
967{
968 char fdt[4096];
969 ulong addr;
970
Simon Glass27c46ab2024-08-22 07:57:56 -0600971 ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt), &addr));
Marek Vasutc3e350f2023-03-02 04:08:38 +0100972
973 /* Test removal of property in root node / */
Marek Vasutc3e350f2023-03-02 04:08:38 +0100974 ut_assertok(run_commandf("fdt print / compatible"));
975 ut_assert_nextline("compatible = \"u-boot,fdt-test\"");
976 ut_assertok(run_commandf("fdt rm / compatible"));
977 ut_asserteq(1, run_commandf("fdt print / compatible"));
978 ut_assert_nextline("libfdt fdt_getprop(): FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -0600979 ut_assert_console_end();
Marek Vasutc3e350f2023-03-02 04:08:38 +0100980
981 /* Test removal of property clock-names in subnode /test-node@1234 */
Marek Vasutc3e350f2023-03-02 04:08:38 +0100982 ut_assertok(run_commandf("fdt print /test-node@1234 clock-names"));
983 ut_assert_nextline("clock-names = \"fixed\", \"i2c\", \"spi\", \"uart2\", \"uart1\"");
984 ut_assertok(run_commandf("fdt rm /test-node@1234 clock-names"));
985 ut_asserteq(1, run_commandf("fdt print /test-node@1234 clock-names"));
986 ut_assert_nextline("libfdt fdt_getprop(): FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -0600987 ut_assert_console_end();
Marek Vasutc3e350f2023-03-02 04:08:38 +0100988
989 /* Test removal of property u-boot,empty-property in subnode /test-node@1234 by alias */
Marek Vasutc3e350f2023-03-02 04:08:38 +0100990 ut_assertok(run_commandf("fdt print testnodealias u-boot,empty-property"));
991 ut_assert_nextline("testnodealias u-boot,empty-property");
992 ut_assertok(run_commandf("fdt rm testnodealias u-boot,empty-property"));
993 ut_asserteq(1, run_commandf("fdt print testnodealias u-boot,empty-property"));
994 ut_assert_nextline("libfdt fdt_getprop(): FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -0600995 ut_assert_console_end();
Marek Vasutc3e350f2023-03-02 04:08:38 +0100996
997 /* Test removal of non-existent property noprop in subnode /test-node@1234 */
Marek Vasutc3e350f2023-03-02 04:08:38 +0100998 ut_asserteq(1, run_commandf("fdt rm /test-node@1234 noprop"));
999 ut_assert_nextline("libfdt fdt_delprop(): FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -06001000 ut_assert_console_end();
Marek Vasutc3e350f2023-03-02 04:08:38 +01001001
1002 /* Test removal of non-existent node /no-node@5678 */
Marek Vasutc3e350f2023-03-02 04:08:38 +01001003 ut_asserteq(1, run_commandf("fdt rm /no-node@5678"));
1004 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -06001005 ut_assert_console_end();
Marek Vasutc3e350f2023-03-02 04:08:38 +01001006
1007 /* Test removal of subnode /test-node@1234/subnode by alias */
Marek Vasutc3e350f2023-03-02 04:08:38 +01001008 ut_assertok(run_commandf("fdt rm subnodealias"));
1009 ut_asserteq(1, run_commandf("fdt print /test-node@1234/subnode"));
1010 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -06001011 ut_assert_console_end();
Marek Vasutc3e350f2023-03-02 04:08:38 +01001012
1013 /* Test removal of node by non-existent alias */
Marek Vasutc3e350f2023-03-02 04:08:38 +01001014 ut_asserteq(1, run_commandf("fdt rm noalias"));
1015 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_BADPATH");
Simon Glassc579bd42024-08-22 07:58:03 -06001016 ut_assert_console_end();
Marek Vasutc3e350f2023-03-02 04:08:38 +01001017
1018 /* Test removal of node by bad alias */
Marek Vasutc3e350f2023-03-02 04:08:38 +01001019 ut_asserteq(1, run_commandf("fdt rm noalias"));
1020 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_BADPATH");
Simon Glassc579bd42024-08-22 07:58:03 -06001021 ut_assert_console_end();
Marek Vasutc3e350f2023-03-02 04:08:38 +01001022
1023 /* Test removal of node /test-node@1234 */
Marek Vasutc3e350f2023-03-02 04:08:38 +01001024 ut_assertok(run_commandf("fdt rm /test-node@1234"));
1025 ut_asserteq(1, run_commandf("fdt print /test-node@1234"));
1026 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -06001027 ut_assert_console_end();
Marek Vasutc3e350f2023-03-02 04:08:38 +01001028
1029 /* Test removal of node / */
Marek Vasutc3e350f2023-03-02 04:08:38 +01001030 ut_assertok(run_commandf("fdt rm /"));
1031 ut_asserteq(1, run_commandf("fdt print /"));
Simon Glassc579bd42024-08-22 07:58:03 -06001032 ut_assert_console_end();
Marek Vasutc3e350f2023-03-02 04:08:38 +01001033
1034 return 0;
1035}
Simon Glass11fcfa32024-08-22 07:57:50 -06001036FDT_TEST(fdt_test_rm, UTF_CONSOLE);
Marek Vasutc3e350f2023-03-02 04:08:38 +01001037
Marek Vasut2081b1d2023-03-02 04:08:40 +01001038static int fdt_test_bootcpu(struct unit_test_state *uts)
1039{
1040 char fdt[256];
1041 ulong addr;
1042 int i;
1043
Simon Glass27c46ab2024-08-22 07:57:56 -06001044 ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt), &addr));
Marek Vasut2081b1d2023-03-02 04:08:40 +01001045
1046 /* Test getting default bootcpu entry */
Marek Vasut2081b1d2023-03-02 04:08:40 +01001047 ut_assertok(run_commandf("fdt header get bootcpu boot_cpuid_phys"));
1048 ut_asserteq(0, env_get_ulong("bootcpu", 10, 0x1234));
Simon Glassc579bd42024-08-22 07:58:03 -06001049 ut_assert_console_end();
Marek Vasut2081b1d2023-03-02 04:08:40 +01001050
1051 /* Test setting and getting new bootcpu entry, twice, to test overwrite */
1052 for (i = 42; i <= 43; i++) {
Marek Vasut2081b1d2023-03-02 04:08:40 +01001053 ut_assertok(run_commandf("fdt bootcpu %d", i));
Simon Glassc579bd42024-08-22 07:58:03 -06001054 ut_assert_console_end();
Marek Vasut2081b1d2023-03-02 04:08:40 +01001055
1056 /* Test getting new bootcpu entry */
Marek Vasut2081b1d2023-03-02 04:08:40 +01001057 ut_assertok(run_commandf("fdt header get bootcpu boot_cpuid_phys"));
1058 ut_asserteq(i, env_get_ulong("bootcpu", 10, 0x1234));
Simon Glassc579bd42024-08-22 07:58:03 -06001059 ut_assert_console_end();
Marek Vasut2081b1d2023-03-02 04:08:40 +01001060 }
1061
1062 return 0;
1063}
Simon Glass11fcfa32024-08-22 07:57:50 -06001064FDT_TEST(fdt_test_bootcpu, UTF_CONSOLE);
Marek Vasut2081b1d2023-03-02 04:08:40 +01001065
Marek Vasut06c13ed2023-03-02 04:08:39 +01001066static int fdt_test_header_get(struct unit_test_state *uts,
1067 const char *field, const unsigned long val)
1068{
1069 /* Test getting valid header entry */
Marek Vasut06c13ed2023-03-02 04:08:39 +01001070 ut_assertok(run_commandf("fdt header get fvar %s", field));
1071 ut_asserteq(val, env_get_hex("fvar", 0x1234));
Simon Glassc579bd42024-08-22 07:58:03 -06001072 ut_assert_console_end();
Marek Vasut06c13ed2023-03-02 04:08:39 +01001073
1074 /* Test getting malformed header entry */
Marek Vasut06c13ed2023-03-02 04:08:39 +01001075 ut_asserteq(1, run_commandf("fdt header get fvar typo%stypo", field));
Simon Glassc579bd42024-08-22 07:58:03 -06001076 ut_assert_console_end();
Marek Vasut06c13ed2023-03-02 04:08:39 +01001077
1078 return 0;
1079}
1080
1081static int fdt_test_header(struct unit_test_state *uts)
1082{
1083 char fdt[256];
1084 ulong addr;
1085
Simon Glass27c46ab2024-08-22 07:57:56 -06001086 ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt), &addr));
Marek Vasut06c13ed2023-03-02 04:08:39 +01001087
1088 /* Test header print */
Marek Vasut06c13ed2023-03-02 04:08:39 +01001089 ut_assertok(run_commandf("fdt header"));
1090 ut_assert_nextline("magic:\t\t\t0x%x", fdt_magic(fdt));
1091 ut_assert_nextline("totalsize:\t\t0x%x (%d)", fdt_totalsize(fdt), fdt_totalsize(fdt));
1092 ut_assert_nextline("off_dt_struct:\t\t0x%x", fdt_off_dt_struct(fdt));
1093 ut_assert_nextline("off_dt_strings:\t\t0x%x", fdt_off_dt_strings(fdt));
1094 ut_assert_nextline("off_mem_rsvmap:\t\t0x%x", fdt_off_mem_rsvmap(fdt));
1095 ut_assert_nextline("version:\t\t%d", fdt_version(fdt));
1096 ut_assert_nextline("last_comp_version:\t%d", fdt_last_comp_version(fdt));
1097 ut_assert_nextline("boot_cpuid_phys:\t0x%x", fdt_boot_cpuid_phys(fdt));
1098 ut_assert_nextline("size_dt_strings:\t0x%x", fdt_size_dt_strings(fdt));
1099 ut_assert_nextline("size_dt_struct:\t\t0x%x", fdt_size_dt_struct(fdt));
1100 ut_assert_nextline("number mem_rsv:\t\t0x%x", fdt_num_mem_rsv(fdt));
1101 ut_assert_nextline_empty();
Simon Glassc579bd42024-08-22 07:58:03 -06001102 ut_assert_console_end();
Marek Vasut06c13ed2023-03-02 04:08:39 +01001103
1104 /* Test header get */
Simon Glassf80a9142024-08-22 07:57:55 -06001105 ut_assertok(fdt_test_header_get(uts, "magic", fdt_magic(fdt)));
1106 ut_assertok(fdt_test_header_get(uts, "totalsize", fdt_totalsize(fdt)));
1107 ut_assertok(fdt_test_header_get(uts, "off_dt_struct",
1108 fdt_off_dt_struct(fdt)));
1109 ut_assertok(fdt_test_header_get(uts, "off_dt_strings",
1110 fdt_off_dt_strings(fdt)));
1111 ut_assertok(fdt_test_header_get(uts, "off_mem_rsvmap",
1112 fdt_off_mem_rsvmap(fdt)));
1113 ut_assertok(fdt_test_header_get(uts, "version", fdt_version(fdt)));
1114 ut_assertok(fdt_test_header_get(uts, "last_comp_version",
1115 fdt_last_comp_version(fdt)));
1116 ut_assertok(fdt_test_header_get(uts, "boot_cpuid_phys",
1117 fdt_boot_cpuid_phys(fdt)));
1118 ut_assertok(fdt_test_header_get(uts, "size_dt_strings",
1119 fdt_size_dt_strings(fdt)));
1120 ut_assertok(fdt_test_header_get(uts, "size_dt_struct",
1121 fdt_size_dt_struct(fdt)));
Marek Vasut06c13ed2023-03-02 04:08:39 +01001122
1123 return 0;
1124}
Simon Glass11fcfa32024-08-22 07:57:50 -06001125FDT_TEST(fdt_test_header, UTF_CONSOLE);
Marek Vasut06c13ed2023-03-02 04:08:39 +01001126
Marek Vasut65b6f462023-03-02 04:08:41 +01001127static int fdt_test_memory_cells(struct unit_test_state *uts,
1128 const unsigned int cells)
1129{
1130 unsigned char *pada, *pads;
1131 unsigned char *seta, *sets;
1132 char fdt[8192];
1133 const int size = sizeof(fdt);
1134 fdt32_t *regs;
1135 ulong addr;
1136 char *spc;
1137 int i;
1138
1139 /* Create DT with node /memory { regs = <0x100 0x200>; } and #*cells */
1140 ut_assertnonnull(regs = calloc(2 * cells, sizeof(*regs)));
1141 ut_assertnonnull(pada = calloc(12, cells));
1142 ut_assertnonnull(pads = calloc(12, cells));
1143 ut_assertnonnull(seta = calloc(12, cells));
1144 ut_assertnonnull(sets = calloc(12, cells));
1145 for (i = cells; i >= 1; i--) {
1146 regs[cells - 1] = cpu_to_fdt32(i * 0x10000);
1147 regs[(cells * 2) - 1] = cpu_to_fdt32(~i);
1148 snprintf(seta + (8 * (cells - i)), 9, "%08x", i * 0x10000);
1149 snprintf(sets + (8 * (cells - i)), 9, "%08x", ~i);
1150 spc = (i != 1) ? " " : "";
1151 snprintf(pada + (11 * (cells - i)), 12, "0x%08x%s", i * 0x10000, spc);
1152 snprintf(pads + (11 * (cells - i)), 12, "0x%08x%s", ~i, spc);
1153 }
1154
1155 ut_assertok(fdt_create(fdt, size));
1156 ut_assertok(fdt_finish_reservemap(fdt));
1157 ut_assert(fdt_begin_node(fdt, "") >= 0);
1158 ut_assertok(fdt_property_u32(fdt, "#address-cells", cells));
1159 ut_assertok(fdt_property_u32(fdt, "#size-cells", cells));
1160 ut_assert(fdt_begin_node(fdt, "memory") >= 0);
1161 ut_assertok(fdt_property_string(fdt, "device_type", "memory"));
1162 ut_assertok(fdt_property(fdt, "reg", &regs, cells * 2));
1163 ut_assertok(fdt_end_node(fdt));
1164 ut_assertok(fdt_end_node(fdt));
1165 ut_assertok(fdt_finish(fdt));
1166 fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */
1167 addr = map_to_sysmem(fdt);
1168 set_working_fdt_addr(addr);
Simon Glass56228252024-08-22 07:57:58 -06001169 ut_assert_nextline("Working FDT set to %lx", addr);
Marek Vasut65b6f462023-03-02 04:08:41 +01001170
1171 /* Test updating the memory node */
Marek Vasut65b6f462023-03-02 04:08:41 +01001172 ut_assertok(run_commandf("fdt memory 0x%s 0x%s", seta, sets));
1173 ut_assertok(run_commandf("fdt print /memory"));
1174 ut_assert_nextline("memory {");
1175 ut_assert_nextline("\tdevice_type = \"memory\";");
1176 ut_assert_nextline("\treg = <%s %s>;", pada, pads);
1177 ut_assert_nextline("};");
Simon Glassc579bd42024-08-22 07:58:03 -06001178 ut_assert_console_end();
Marek Vasut65b6f462023-03-02 04:08:41 +01001179
1180 free(sets);
1181 free(seta);
1182 free(pads);
1183 free(pada);
1184 free(regs);
1185
1186 return 0;
1187}
1188
1189static int fdt_test_memory(struct unit_test_state *uts)
1190{
1191 /*
1192 * Test memory fixup for 32 and 64 bit systems, anything bigger is
1193 * so far unsupported and fails because of simple_stroull() being
1194 * 64bit tops in the 'fdt memory' command implementation.
1195 */
Simon Glassf80a9142024-08-22 07:57:55 -06001196 ut_assertok(fdt_test_memory_cells(uts, 1));
1197 ut_assertok(fdt_test_memory_cells(uts, 2));
Marek Vasut65b6f462023-03-02 04:08:41 +01001198
1199 /*
1200 * The 'fdt memory' command is limited to /memory node, it does
1201 * not support any other valid DT memory node format, which is
1202 * either one or multiple /memory@adresss nodes. Therefore, this
1203 * DT variant is not tested here.
1204 */
1205
1206 return 0;
1207}
Simon Glass11fcfa32024-08-22 07:57:50 -06001208FDT_TEST(fdt_test_memory, UTF_CONSOLE);
Marek Vasut65b6f462023-03-02 04:08:41 +01001209
Marek Vasutcd162df2023-03-02 04:08:42 +01001210static int fdt_test_rsvmem(struct unit_test_state *uts)
1211{
1212 char fdt[8192];
1213 ulong addr;
1214
Simon Glass27c46ab2024-08-22 07:57:56 -06001215 ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt), &addr));
Marek Vasutcd162df2023-03-02 04:08:42 +01001216 fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */
1217 fdt_add_mem_rsv(fdt, 0x42, 0x1701);
1218 fdt_add_mem_rsv(fdt, 0x74656, 0x9);
Marek Vasutcd162df2023-03-02 04:08:42 +01001219
1220 /* Test default reserved memory node presence */
Marek Vasutcd162df2023-03-02 04:08:42 +01001221 ut_assertok(run_commandf("fdt rsvmem print"));
1222 ut_assert_nextline("index\t\t start\t\t size");
1223 ut_assert_nextline("------------------------------------------------");
1224 ut_assert_nextline(" %x\t%016x\t%016x", 0, 0x42, 0x1701);
1225 ut_assert_nextline(" %x\t%016x\t%016x", 1, 0x74656, 0x9);
Simon Glassc579bd42024-08-22 07:58:03 -06001226 ut_assert_console_end();
Marek Vasutcd162df2023-03-02 04:08:42 +01001227
1228 /* Test add new reserved memory node */
Marek Vasutcd162df2023-03-02 04:08:42 +01001229 ut_assertok(run_commandf("fdt rsvmem add 0x1234 0x5678"));
1230 ut_assertok(run_commandf("fdt rsvmem print"));
1231 ut_assert_nextline("index\t\t start\t\t size");
1232 ut_assert_nextline("------------------------------------------------");
1233 ut_assert_nextline(" %x\t%016x\t%016x", 0, 0x42, 0x1701);
1234 ut_assert_nextline(" %x\t%016x\t%016x", 1, 0x74656, 0x9);
1235 ut_assert_nextline(" %x\t%016x\t%016x", 2, 0x1234, 0x5678);
Simon Glassc579bd42024-08-22 07:58:03 -06001236 ut_assert_console_end();
Marek Vasutcd162df2023-03-02 04:08:42 +01001237
1238 /* Test delete reserved memory node */
Marek Vasutcd162df2023-03-02 04:08:42 +01001239 ut_assertok(run_commandf("fdt rsvmem delete 0"));
1240 ut_assertok(run_commandf("fdt rsvmem print"));
1241 ut_assert_nextline("index\t\t start\t\t size");
1242 ut_assert_nextline("------------------------------------------------");
1243 ut_assert_nextline(" %x\t%016x\t%016x", 0, 0x74656, 0x9);
1244 ut_assert_nextline(" %x\t%016x\t%016x", 1, 0x1234, 0x5678);
Simon Glassc579bd42024-08-22 07:58:03 -06001245 ut_assert_console_end();
Marek Vasutcd162df2023-03-02 04:08:42 +01001246
1247 /* Test re-add new reserved memory node */
Marek Vasutcd162df2023-03-02 04:08:42 +01001248 ut_assertok(run_commandf("fdt rsvmem add 0x42 0x1701"));
1249 ut_assertok(run_commandf("fdt rsvmem print"));
1250 ut_assert_nextline("index\t\t start\t\t size");
1251 ut_assert_nextline("------------------------------------------------");
1252 ut_assert_nextline(" %x\t%016x\t%016x", 0, 0x74656, 0x9);
1253 ut_assert_nextline(" %x\t%016x\t%016x", 1, 0x1234, 0x5678);
1254 ut_assert_nextline(" %x\t%016x\t%016x", 2, 0x42, 0x1701);
Simon Glassc579bd42024-08-22 07:58:03 -06001255 ut_assert_console_end();
Marek Vasutcd162df2023-03-02 04:08:42 +01001256
1257 /* Test delete nonexistent reserved memory node */
Marek Vasutcd162df2023-03-02 04:08:42 +01001258 ut_asserteq(1, run_commandf("fdt rsvmem delete 10"));
1259 ut_assert_nextline("libfdt fdt_del_mem_rsv(): FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -06001260 ut_assert_console_end();
Marek Vasutcd162df2023-03-02 04:08:42 +01001261
1262 return 0;
1263}
Simon Glass11fcfa32024-08-22 07:57:50 -06001264FDT_TEST(fdt_test_rsvmem, UTF_CONSOLE);
Marek Vasutcd162df2023-03-02 04:08:42 +01001265
Marek Vasut8d450da2023-03-02 04:08:43 +01001266static int fdt_test_chosen(struct unit_test_state *uts)
1267{
1268 const char *env_bootargs = env_get("bootargs");
1269 char fdt[8192];
1270 ulong addr;
1271
Simon Glass27c46ab2024-08-22 07:57:56 -06001272 ut_assertok(make_test_fdt(uts, fdt, sizeof(fdt), &addr));
Marek Vasut8d450da2023-03-02 04:08:43 +01001273 fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */
Marek Vasut8d450da2023-03-02 04:08:43 +01001274
1275 /* Test default chosen node presence, fail as there is no /chosen node */
Marek Vasut8d450da2023-03-02 04:08:43 +01001276 ut_asserteq(1, run_commandf("fdt print /chosen"));
1277 ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
Simon Glassc579bd42024-08-22 07:58:03 -06001278 ut_assert_console_end();
Marek Vasut8d450da2023-03-02 04:08:43 +01001279
1280 /* Test add new chosen node without initrd */
Marek Vasut8d450da2023-03-02 04:08:43 +01001281 ut_assertok(run_commandf("fdt chosen"));
1282 ut_assertok(run_commandf("fdt print /chosen"));
1283 ut_assert_nextline("chosen {");
1284 ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */
1285 if (env_bootargs)
1286 ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs);
Tim Harvey009d1562024-06-18 14:06:09 -07001287 if (IS_ENABLED(CONFIG_DM_RNG) &&
1288 !IS_ENABLED(CONFIG_MEASURED_BOOT) &&
1289 !IS_ENABLED(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT))
1290 ut_assert_nextlinen("\tkaslr-seed = ");
Marek Vasut8d450da2023-03-02 04:08:43 +01001291 ut_assert_nextline("};");
Simon Glassc579bd42024-08-22 07:58:03 -06001292 ut_assert_console_end();
Marek Vasut8d450da2023-03-02 04:08:43 +01001293
1294 /* Test add new chosen node with initrd */
Marek Vasut8d450da2023-03-02 04:08:43 +01001295 ut_assertok(run_commandf("fdt chosen 0x1234 0x5678"));
1296 ut_assertok(run_commandf("fdt print /chosen"));
1297 ut_assert_nextline("chosen {");
1298 ut_assert_nextline("\tlinux,initrd-end = <0x%08x 0x%08x>;",
1299 upper_32_bits(0x1234 + 0x5678 - 1),
1300 lower_32_bits(0x1234 + 0x5678 - 1));
1301 ut_assert_nextline("\tlinux,initrd-start = <0x%08x 0x%08x>;",
1302 upper_32_bits(0x1234), lower_32_bits(0x1234));
1303 ut_assert_nextlinen("\tu-boot,version = "); /* Ignore the version string */
1304 if (env_bootargs)
1305 ut_assert_nextline("\tbootargs = \"%s\";", env_bootargs);
Tim Harvey009d1562024-06-18 14:06:09 -07001306 if (IS_ENABLED(CONFIG_DM_RNG) &&
1307 !IS_ENABLED(CONFIG_MEASURED_BOOT) &&
1308 !IS_ENABLED(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT))
1309 ut_assert_nextlinen("\tkaslr-seed = ");
Marek Vasut8d450da2023-03-02 04:08:43 +01001310 ut_assert_nextline("};");
Simon Glassc579bd42024-08-22 07:58:03 -06001311 ut_assert_console_end();
Marek Vasut8d450da2023-03-02 04:08:43 +01001312
1313 return 0;
1314}
Simon Glass11fcfa32024-08-22 07:57:50 -06001315FDT_TEST(fdt_test_chosen, UTF_CONSOLE);
Marek Vasut8d450da2023-03-02 04:08:43 +01001316
Marek Vasutdc0ccea2023-03-02 04:08:44 +01001317static int fdt_test_apply(struct unit_test_state *uts)
1318{
1319 char fdt[8192], fdto[8192];
1320 ulong addr, addro;
1321
1322 /* Create base DT with __symbols__ node */
1323 ut_assertok(fdt_create(fdt, sizeof(fdt)));
1324 ut_assertok(fdt_finish_reservemap(fdt));
1325 ut_assert(fdt_begin_node(fdt, "") >= 0);
1326 ut_assert(fdt_begin_node(fdt, "__symbols__") >= 0);
1327 ut_assertok(fdt_end_node(fdt));
1328 ut_assertok(fdt_end_node(fdt));
1329 ut_assertok(fdt_finish(fdt));
1330 fdt_shrink_to_minimum(fdt, 4096); /* Resize with 4096 extra bytes */
1331 addr = map_to_sysmem(fdt);
1332 set_working_fdt_addr(addr);
Simon Glass56228252024-08-22 07:57:58 -06001333 ut_assert_nextline("Working FDT set to %lx", addr);
Marek Vasutdc0ccea2023-03-02 04:08:44 +01001334
1335 /* Create DTO which adds single property to root node / */
1336 ut_assertok(fdt_create(fdto, sizeof(fdto)));
1337 ut_assertok(fdt_finish_reservemap(fdto));
1338 ut_assert(fdt_begin_node(fdto, "") >= 0);
1339 ut_assert(fdt_begin_node(fdto, "fragment") >= 0);
1340 ut_assertok(fdt_property_string(fdto, "target-path", "/"));
1341 ut_assert(fdt_begin_node(fdto, "__overlay__") >= 0);
1342 ut_assertok(fdt_property_string(fdto, "newstring", "newvalue"));
1343 ut_assertok(fdt_end_node(fdto));
1344 ut_assertok(fdt_end_node(fdto));
1345 ut_assertok(fdt_finish(fdto));
1346 addro = map_to_sysmem(fdto);
1347
1348 /* Test default DT print */
Marek Vasutdc0ccea2023-03-02 04:08:44 +01001349 ut_assertok(run_commandf("fdt print /"));
1350 ut_assert_nextline("/ {");
1351 ut_assert_nextline("\t__symbols__ {");
1352 ut_assert_nextline("\t};");
1353 ut_assert_nextline("};");
Simon Glassc579bd42024-08-22 07:58:03 -06001354 ut_assert_console_end();
Marek Vasutdc0ccea2023-03-02 04:08:44 +01001355
1356 /* Test simple DTO application */
Evgeny Bachinine604bc02023-03-20 11:23:13 +03001357 ut_assertok(run_commandf("fdt apply 0x%08lx", addro));
Marek Vasutdc0ccea2023-03-02 04:08:44 +01001358 ut_assertok(run_commandf("fdt print /"));
1359 ut_assert_nextline("/ {");
1360 ut_assert_nextline("\tnewstring = \"newvalue\";");
1361 ut_assert_nextline("\t__symbols__ {");
1362 ut_assert_nextline("\t};");
1363 ut_assert_nextline("};");
Simon Glassc579bd42024-08-22 07:58:03 -06001364 ut_assert_console_end();
Marek Vasutdc0ccea2023-03-02 04:08:44 +01001365
1366 /*
1367 * Create complex DTO which:
1368 * - modifies newstring property in root node /
1369 * - adds new properties to root node /
1370 * - adds new subnode with properties to root node /
1371 * - adds phandle to the subnode and therefore __symbols__ node
1372 */
1373 ut_assertok(fdt_create(fdto, sizeof(fdto)));
1374 ut_assertok(fdt_finish_reservemap(fdto));
1375 ut_assert(fdt_begin_node(fdto, "") >= 0);
1376 ut_assertok(fdt_property_cell(fdto, "#address-cells", 1));
1377 ut_assertok(fdt_property_cell(fdto, "#size-cells", 0));
1378
1379 ut_assert(fdt_begin_node(fdto, "fragment@0") >= 0);
1380 ut_assertok(fdt_property_string(fdto, "target-path", "/"));
1381 ut_assert(fdt_begin_node(fdto, "__overlay__") >= 0);
1382 ut_assertok(fdt_property_string(fdto, "newstring", "newervalue"));
1383 ut_assertok(fdt_property_u32(fdto, "newu32", 0x12345678));
1384 ut_assertok(fdt_property(fdto, "empty-property", NULL, 0));
1385 ut_assert(fdt_begin_node(fdto, "subnode") >= 0);
1386 ut_assertok(fdt_property_string(fdto, "subnewstring", "newervalue"));
1387 ut_assertok(fdt_property_u32(fdto, "subnewu32", 0x12345678));
1388 ut_assertok(fdt_property(fdto, "subempty-property", NULL, 0));
1389 ut_assertok(fdt_property_u32(fdto, "phandle", 0x01));
1390 ut_assertok(fdt_end_node(fdto));
1391 ut_assertok(fdt_end_node(fdto));
1392 ut_assertok(fdt_end_node(fdto));
1393
1394 ut_assert(fdt_begin_node(fdto, "__symbols__") >= 0);
1395 ut_assertok(fdt_property_string(fdto, "subnodephandle", "/fragment@0/__overlay__/subnode"));
1396 ut_assertok(fdt_end_node(fdto));
1397 ut_assertok(fdt_finish(fdto));
1398 addro = map_to_sysmem(fdto);
1399
1400 /* Test complex DTO application */
Evgeny Bachinine604bc02023-03-20 11:23:13 +03001401 ut_assertok(run_commandf("fdt apply 0x%08lx", addro));
Marek Vasutdc0ccea2023-03-02 04:08:44 +01001402 ut_assertok(run_commandf("fdt print /"));
1403 ut_assert_nextline("/ {");
1404 ut_assert_nextline("\tempty-property;");
1405 ut_assert_nextline("\tnewu32 = <0x12345678>;");
1406 ut_assert_nextline("\tnewstring = \"newervalue\";");
1407 ut_assert_nextline("\tsubnode {");
1408 ut_assert_nextline("\t\tphandle = <0x00000001>;");
1409 ut_assert_nextline("\t\tsubempty-property;");
1410 ut_assert_nextline("\t\tsubnewu32 = <0x12345678>;");
1411 ut_assert_nextline("\t\tsubnewstring = \"newervalue\";");
1412 ut_assert_nextline("\t};");
1413 ut_assert_nextline("\t__symbols__ {");
1414 ut_assert_nextline("\t\tsubnodephandle = \"/subnode\";");
1415 ut_assert_nextline("\t};");
1416 ut_assert_nextline("};");
Simon Glassc579bd42024-08-22 07:58:03 -06001417 ut_assert_console_end();
Marek Vasutdc0ccea2023-03-02 04:08:44 +01001418
1419 /*
1420 * Create complex DTO which:
1421 * - modifies subnewu32 property in subnode via phandle and uses __fixups__ node
1422 */
1423 ut_assertok(fdt_create(fdto, sizeof(fdto)));
1424 ut_assertok(fdt_finish_reservemap(fdto));
1425 ut_assert(fdt_begin_node(fdto, "") >= 0);
1426 ut_assertok(fdt_property_cell(fdto, "#address-cells", 1));
1427 ut_assertok(fdt_property_cell(fdto, "#size-cells", 0));
1428
1429 ut_assert(fdt_begin_node(fdto, "fragment@0") >= 0);
1430 ut_assertok(fdt_property_u32(fdto, "target", 0xffffffff));
1431 ut_assert(fdt_begin_node(fdto, "__overlay__") >= 0);
1432 ut_assertok(fdt_property_u32(fdto, "subnewu32", 0xabcdef01));
1433 ut_assertok(fdt_end_node(fdto));
1434 ut_assertok(fdt_end_node(fdto));
1435
1436 ut_assert(fdt_begin_node(fdto, "__fixups__") >= 0);
1437 ut_assertok(fdt_property_string(fdto, "subnodephandle", "/fragment@0:target:0"));
1438 ut_assertok(fdt_end_node(fdto));
1439 ut_assertok(fdt_end_node(fdto));
1440 ut_assertok(fdt_finish(fdto));
1441 addro = map_to_sysmem(fdto);
1442
1443 /* Test complex DTO application */
Evgeny Bachinine604bc02023-03-20 11:23:13 +03001444 ut_assertok(run_commandf("fdt apply 0x%08lx", addro));
Marek Vasutdc0ccea2023-03-02 04:08:44 +01001445 ut_assertok(run_commandf("fdt print /"));
1446 ut_assert_nextline("/ {");
1447 ut_assert_nextline("\tempty-property;");
1448 ut_assert_nextline("\tnewu32 = <0x12345678>;");
1449 ut_assert_nextline("\tnewstring = \"newervalue\";");
1450 ut_assert_nextline("\tsubnode {");
1451 ut_assert_nextline("\t\tphandle = <0x00000001>;");
1452 ut_assert_nextline("\t\tsubempty-property;");
1453 ut_assert_nextline("\t\tsubnewu32 = <0xabcdef01>;");
1454 ut_assert_nextline("\t\tsubnewstring = \"newervalue\";");
1455 ut_assert_nextline("\t};");
1456 ut_assert_nextline("\t__symbols__ {");
1457 ut_assert_nextline("\t\tsubnodephandle = \"/subnode\";");
1458 ut_assert_nextline("\t};");
1459 ut_assert_nextline("};");
Simon Glassc579bd42024-08-22 07:58:03 -06001460 ut_assert_console_end();
Marek Vasutdc0ccea2023-03-02 04:08:44 +01001461
1462 return 0;
1463}
Simon Glass11fcfa32024-08-22 07:57:50 -06001464FDT_TEST(fdt_test_apply, UTF_CONSOLE);
Marek Vasutdc0ccea2023-03-02 04:08:44 +01001465
Simon Glassf3c6a1d2022-07-13 06:06:59 -06001466int do_ut_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
1467{
1468 struct unit_test *tests = UNIT_TEST_SUITE_START(fdt_test);
1469 const int n_ents = UNIT_TEST_SUITE_COUNT(fdt_test);
1470
1471 return cmd_ut_category("fdt", "fdt_test_", tests, n_ents, argc, argv);
1472}