uboot/test/cmd/fdt.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Tests for fdt command
   4 *
   5 * Copyright 2022 Google LLC
   6 */
   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;
  18/*
  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 */
  25
  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
  49/**
  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
 145/* 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);
 161        ut_assert_nextline("Working FDT set to 0");
 162        ut_asserteq(CMD_RET_FAILURE, run_command("fdt addr", 0));
 163        ut_assert_nextline("libfdt fdt_check_header(): FDT_ERR_BADMAGIC");
 164        ut_assertok(ut_check_console_end(uts));
 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);
 170        ut_assert_nextline("Working FDT set to %lx", addr);
 171        ut_assertok(run_command("fdt addr", 0));
 172        ut_assert_nextline("Working fdt: %08lx", (ulong)map_to_sysmem(fdt));
 173        ut_assertok(ut_check_console_end(uts));
 174
 175        /* Set the working FDT */
 176        set_working_fdt_addr(0);
 177        ut_assert_nextline("Working FDT set to 0");
 178        ut_assertok(run_commandf("fdt addr %08lx", addr));
 179        ut_assert_nextline("Working FDT set to %lx", addr);
 180        ut_asserteq(addr, map_to_sysmem(working_fdt));
 181        ut_assertok(ut_check_console_end(uts));
 182        set_working_fdt_addr(0);
 183        ut_assert_nextline("Working FDT set to 0");
 184
 185        /* Set the control FDT */
 186        fdt_blob = gd->fdt_blob;
 187        gd->fdt_blob = NULL;
 188        ret = run_commandf("fdt addr -c %08lx", addr);
 189        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;
 197        ut_asserteq(1, run_commandf("fdt addr %08lx", addr));
 198        ut_assert_nextline("libfdt fdt_check_header(): FDT_ERR_BADMAGIC");
 199        ut_assertok(ut_check_console_end(uts));
 200
 201        /* Test detecting an invalid FDT */
 202        fdt[0] = 123;
 203        set_working_fdt_addr(addr);
 204        ut_assert_nextline("Working FDT set to %lx", addr);
 205        ut_asserteq(1, run_commandf("fdt addr"));
 206        ut_assert_nextline("libfdt fdt_check_header(): FDT_ERR_BADMAGIC");
 207        ut_assertok(ut_check_console_end(uts));
 208
 209        return 0;
 210}
 211FDT_TEST(fdt_test_addr, UT_TESTF_CONSOLE_REC);
 212
 213/* Test 'fdt addr' resizing an fdt */
 214static int fdt_test_addr_resize(struct unit_test_state *uts)
 215{
 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());
 226        ut_assertok(run_commandf("fdt addr %08lx %x", addr, newsize));
 227        ut_assert_nextline("Working FDT set to %lx", addr);
 228        ut_assertok(ut_check_console_end(uts));
 229
 230        /* Try shrinking it */
 231        ut_assertok(run_commandf("fdt addr %08lx %zx", addr, sizeof(fdt) / 4));
 232        ut_assert_nextline("Working FDT set to %lx", addr);
 233        ut_assert_nextline("New length %d < existing length %d, ignoring",
 234                           (int)sizeof(fdt) / 4, newsize);
 235        ut_assertok(ut_check_console_end(uts));
 236
 237        /* ...quietly */
 238        ut_assertok(run_commandf("fdt addr -q %08lx %zx", addr, sizeof(fdt) / 4));
 239        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}
 245FDT_TEST(fdt_test_addr_resize, UT_TESTF_CONSOLE_REC);
 246
 247static 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());
 267        ut_assertok(run_commandf("fdt move %08lx %08lx %x", addr, newaddr, ts));
 268        ut_assert_nextline("Working FDT set to %lx", newaddr);
 269        ut_assertok(ut_check_console_end(uts));
 270
 271        /* Compare the source and destination DTs */
 272        ut_assertok(console_record_reset_enable());
 273        ut_assertok(run_commandf("cmp.b %08lx %08lx %x", addr, newaddr, ts));
 274        ut_assert_nextline("Total of %d byte(s) were the same", ts);
 275        ut_assertok(ut_check_console_end(uts));
 276
 277        return 0;
 278}
 279FDT_TEST(fdt_test_move, UT_TESTF_CONSOLE_REC);
 280
 281static 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
 305static 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
 448/* Test 'fdt get value' reading an fdt */
 449static 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
 467static 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 */
 471        fdt_test_get_value_string(uts, node, "clock-names", NULL, "fixed", 0);
 472
 473        /* Test getting 0th element of $node node clock-names property */
 474        fdt_test_get_value_string(uts, node, "clock-names", "0", "fixed", 0);
 475
 476        /* Test getting 1st element of $node node clock-names property */
 477        fdt_test_get_value_string(uts, node, "clock-names", "1", "i2c", 0);
 478
 479        /* Test getting 2nd element of $node node clock-names property */
 480        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);
 496
 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
 502        /* Test missing 10th element of $node node regs property */
 503        ut_assertok(console_record_reset_enable());
 504        ut_asserteq(1, run_commandf("fdt get value ften %s regs 10", node));
 505        ut_assertok(ut_check_console_end(uts));
 506
 507        /* Test getting default element of $node node nonexistent property */
 508        ut_assertok(console_record_reset_enable());
 509        ut_asserteq(1, run_commandf("fdt get value fnone %s nonexistent", node));
 510        ut_assert_nextline("libfdt fdt_getprop(): FDT_ERR_NOTFOUND");
 511        ut_assertok(ut_check_console_end(uts));
 512
 513        return 0;
 514}
 515
 516static int fdt_test_get_value(struct unit_test_state *uts)
 517{
 518        char fdt[4096];
 519        ulong addr;
 520        int ret;
 521
 522        ut_assertok(make_fuller_fdt(uts, fdt, sizeof(fdt)));
 523        addr = map_to_sysmem(fdt);
 524        set_working_fdt_addr(addr);
 525
 526        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;
 531
 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
 538        /* Test getting default element of bad alias */
 539        ut_assertok(console_record_reset_enable());
 540        ut_asserteq(1, run_command("fdt get value vbadalias badalias nonexistent", 1));
 541        ut_assert_nextline("libfdt fdt_path_offset() returned FDT_ERR_NOTFOUND");
 542        ut_assertok(ut_check_console_end(uts));
 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
 550        return 0;
 551}
 552FDT_TEST(fdt_test_get_value, UT_TESTF_CONSOLE_REC);
 553
 554static 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
 633static 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
 700static 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
 787static 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());
 798        if (sval)
 799                ut_assertok(run_commandf("fdt set %s %s %s", path, prop, sval));
 800        else if (integer)
 801                ut_assertok(run_commandf("fdt set %s %s <%d>", path, prop, ival));
 802        else
 803                ut_assertok(run_commandf("fdt set %s %s", path, prop));
 804
 805        /* Validate the property is present and has correct value. */
 806        ut_assertok(run_commandf("fdt get value svar %s %s", path, prop));
 807        if (sval)
 808                ut_asserteq_str(sval, env_get("svar"));
 809        else if (integer)
 810                ut_asserteq(ival, env_get_hex("svar", 0x1234));
 811        else
 812                ut_assertnull(env_get("svar"));
 813        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
 929static 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
 997static 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
1081static 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
1114static 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
1173static 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
1256static 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
1319static 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
1367static 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());
1408        ut_assertok(run_commandf("fdt apply 0x%08lx", addro));
1409        ut_assertok(run_commandf("fdt print /"));
1410        ut_assert_nextline("/ {");
1411        ut_assert_nextline("\tnewstring = \"newvalue\";");
1412        ut_assert_nextline("\t__symbols__ {");
1413        ut_assert_nextline("\t};");
1414        ut_assert_nextline("};");
1415        ut_assertok(ut_check_console_end(uts));
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());
1453        ut_assertok(run_commandf("fdt apply 0x%08lx", addro));
1454        ut_assertok(run_commandf("fdt print /"));
1455        ut_assert_nextline("/ {");
1456        ut_assert_nextline("\tempty-property;");
1457        ut_assert_nextline("\tnewu32 = <0x12345678>;");
1458        ut_assert_nextline("\tnewstring = \"newervalue\";");
1459        ut_assert_nextline("\tsubnode {");
1460        ut_assert_nextline("\t\tphandle = <0x00000001>;");
1461        ut_assert_nextline("\t\tsubempty-property;");
1462        ut_assert_nextline("\t\tsubnewu32 = <0x12345678>;");
1463        ut_assert_nextline("\t\tsubnewstring = \"newervalue\";");
1464        ut_assert_nextline("\t};");
1465        ut_assert_nextline("\t__symbols__ {");
1466        ut_assert_nextline("\t\tsubnodephandle = \"/subnode\";");
1467        ut_assert_nextline("\t};");
1468        ut_assert_nextline("};");
1469        ut_assertok(ut_check_console_end(uts));
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());
1497        ut_assertok(run_commandf("fdt apply 0x%08lx", addro));
1498        ut_assertok(run_commandf("fdt print /"));
1499        ut_assert_nextline("/ {");
1500        ut_assert_nextline("\tempty-property;");
1501        ut_assert_nextline("\tnewu32 = <0x12345678>;");
1502        ut_assert_nextline("\tnewstring = \"newervalue\";");
1503        ut_assert_nextline("\tsubnode {");
1504        ut_assert_nextline("\t\tphandle = <0x00000001>;");
1505        ut_assert_nextline("\t\tsubempty-property;");
1506        ut_assert_nextline("\t\tsubnewu32 = <0xabcdef01>;");
1507        ut_assert_nextline("\t\tsubnewstring = \"newervalue\";");
1508        ut_assert_nextline("\t};");
1509        ut_assert_nextline("\t__symbols__ {");
1510        ut_assert_nextline("\t\tsubnodephandle = \"/subnode\";");
1511        ut_assert_nextline("\t};");
1512        ut_assert_nextline("};");
1513        ut_assertok(ut_check_console_end(uts));
1514
1515        return 0;
1516}
1517FDT_TEST(fdt_test_apply, UT_TESTF_CONSOLE_REC);
1518
1519int 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}
1526