| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287 |
- // SPDX-License-Identifier: GPL-2.0+
- /*
- * Copyright 2022 Google LLC
- *
- * There are two types of tests in this file:
- * - normal ones which act on the control FDT (gd->fdt_blob or gd->of_root)
- * - 'other' ones which act on the 'other' FDT (other.dts)
- *
- * The 'other' ones have an _ot suffix.
- *
- * The latter are used to check behaviour with multiple device trees,
- * particularly with flat tree, where a tree ID is included in ofnode as part of
- * the node offset. These tests are typically just for making sure that the
- * offset makes it to libfdt correctly and that the resulting return value is
- * correctly turned into an ofnode. The 'other' tests do not fully check the
- * behaviour of each ofnode function, since that is done by the normal ones.
- */
- #include <common.h>
- #include <dm.h>
- #include <log.h>
- #include <of_live.h>
- #include <dm/device-internal.h>
- #include <dm/lists.h>
- #include <dm/of_extra.h>
- #include <dm/root.h>
- #include <dm/test.h>
- #include <dm/uclass-internal.h>
- #include <test/test.h>
- #include <test/ut.h>
- /**
- * get_other_oftree() - Convert a flat tree into an oftree object
- *
- * @uts: Test state
- * @return: oftree object for the 'other' FDT (see sandbox' other.dts)
- */
- oftree get_other_oftree(struct unit_test_state *uts)
- {
- oftree tree;
- if (of_live_active())
- tree = oftree_from_np(uts->of_other);
- else
- tree = oftree_from_fdt(uts->other_fdt);
- /* An invalid tree may cause failure or crashes */
- if (!oftree_valid(tree))
- ut_reportf("test needs the UT_TESTF_OTHER_FDT flag");
- return tree;
- }
- /**
- * get_oftree() - Convert a flat tree into an oftree object
- *
- * @uts: Test state
- * @fdt: Pointer to flat tree
- * @treep: Returns the tree, on success
- * Return: 0 if OK, 1 if the tree failed to unflatten, -EOVERFLOW if there are
- * too many flat trees to allow another one to be registers (see
- * oftree_ensure())
- */
- int get_oftree(struct unit_test_state *uts, void *fdt, oftree *treep)
- {
- oftree tree;
- if (of_live_active()) {
- struct device_node *root;
- ut_assertok(unflatten_device_tree(fdt, &root));
- tree = oftree_from_np(root);
- } else {
- tree = oftree_from_fdt(fdt);
- if (!oftree_valid(tree))
- return -EOVERFLOW;
- }
- *treep = tree;
- return 0;
- }
- /**
- * free_oftree() - Free memory used by get_oftree()
- *
- * @tree: Tree to free
- */
- void free_oftree(oftree tree)
- {
- if (of_live_active())
- free(tree.np);
- }
- static int dm_test_ofnode_compatible(struct unit_test_state *uts)
- {
- ofnode root_node = ofnode_path("/");
- ut_assert(ofnode_valid(root_node));
- ut_assert(ofnode_device_is_compatible(root_node, "sandbox"));
- return 0;
- }
- DM_TEST(dm_test_ofnode_compatible,
- UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
- /* check ofnode_device_is_compatible() with the 'other' FDT */
- static int dm_test_ofnode_compatible_ot(struct unit_test_state *uts)
- {
- oftree otree = get_other_oftree(uts);
- ofnode oroot = oftree_root(otree);
- ut_assert(ofnode_valid(oroot));
- ut_assert(ofnode_device_is_compatible(oroot, "sandbox-other"));
- return 0;
- }
- DM_TEST(dm_test_ofnode_compatible_ot, UT_TESTF_OTHER_FDT);
- static int dm_test_ofnode_get_by_phandle(struct unit_test_state *uts)
- {
- /* test invalid phandle */
- ut_assert(!ofnode_valid(ofnode_get_by_phandle(0)));
- ut_assert(!ofnode_valid(ofnode_get_by_phandle(-1)));
- /* test first valid phandle */
- ut_assert(ofnode_valid(ofnode_get_by_phandle(1)));
- /* test unknown phandle */
- ut_assert(!ofnode_valid(ofnode_get_by_phandle(0x1000000)));
- ut_assert(ofnode_valid(oftree_get_by_phandle(oftree_default(), 1)));
- return 0;
- }
- DM_TEST(dm_test_ofnode_get_by_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_get_by_phandle_ot(struct unit_test_state *uts)
- {
- oftree otree = get_other_oftree(uts);
- ofnode node;
- ut_assert(ofnode_valid(oftree_get_by_phandle(oftree_default(), 1)));
- node = oftree_get_by_phandle(otree, 1);
- ut_assert(ofnode_valid(node));
- ut_asserteq_str("target", ofnode_get_name(node));
- return 0;
- }
- DM_TEST(dm_test_ofnode_get_by_phandle_ot, UT_TESTF_OTHER_FDT);
- static int check_prop_values(struct unit_test_state *uts, ofnode start,
- const char *propname, const char *propval,
- int expect_count)
- {
- int proplen = strlen(propval) + 1;
- const char *str;
- ofnode node;
- int count;
- /* Find first matching node, there should be at least one */
- node = ofnode_by_prop_value(start, propname, propval, proplen);
- ut_assert(ofnode_valid(node));
- str = ofnode_read_string(node, propname);
- ut_assert(str && !strcmp(str, propval));
- /* Find the rest of the matching nodes */
- count = 1;
- while (true) {
- node = ofnode_by_prop_value(node, propname, propval, proplen);
- if (!ofnode_valid(node))
- break;
- str = ofnode_read_string(node, propname);
- ut_asserteq_str(propval, str);
- count++;
- }
- ut_asserteq(expect_count, count);
- return 0;
- }
- static int dm_test_ofnode_by_prop_value(struct unit_test_state *uts)
- {
- ut_assertok(check_prop_values(uts, ofnode_null(), "compatible",
- "denx,u-boot-fdt-test", 11));
- return 0;
- }
- DM_TEST(dm_test_ofnode_by_prop_value, UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_by_prop_value_ot(struct unit_test_state *uts)
- {
- oftree otree = get_other_oftree(uts);
- ut_assertok(check_prop_values(uts, oftree_root(otree), "str-prop",
- "other", 2));
- return 0;
- }
- DM_TEST(dm_test_ofnode_by_prop_value_ot, UT_TESTF_OTHER_FDT);
- static int dm_test_ofnode_fmap(struct unit_test_state *uts)
- {
- struct fmap_entry entry;
- ofnode node;
- node = ofnode_path("/cros-ec/flash");
- ut_assert(ofnode_valid(node));
- ut_assertok(ofnode_read_fmap_entry(node, &entry));
- ut_asserteq(0x08000000, entry.offset);
- ut_asserteq(0x20000, entry.length);
- return 0;
- }
- DM_TEST(dm_test_ofnode_fmap, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_read(struct unit_test_state *uts)
- {
- const u32 *val;
- ofnode node;
- int size;
- node = ofnode_path("/a-test");
- ut_assert(ofnode_valid(node));
- val = ofnode_read_prop(node, "int-value", &size);
- ut_assertnonnull(val);
- ut_asserteq(4, size);
- ut_asserteq(1234, fdt32_to_cpu(val[0]));
- val = ofnode_read_prop(node, "missing", &size);
- ut_assertnull(val);
- ut_asserteq(-FDT_ERR_NOTFOUND, size);
- /* Check it works without a size parameter */
- val = ofnode_read_prop(node, "missing", NULL);
- ut_assertnull(val);
- return 0;
- }
- DM_TEST(dm_test_ofnode_read, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_read_ot(struct unit_test_state *uts)
- {
- oftree otree = get_other_oftree(uts);
- const char *val;
- ofnode node;
- int size;
- node = oftree_path(otree, "/node/subnode");
- ut_assert(ofnode_valid(node));
- val = ofnode_read_prop(node, "str-prop", &size);
- ut_assertnonnull(val);
- ut_asserteq_str("other", val);
- ut_asserteq(6, size);
- return 0;
- }
- DM_TEST(dm_test_ofnode_read_ot, UT_TESTF_OTHER_FDT);
- static int dm_test_ofnode_phandle(struct unit_test_state *uts)
- {
- struct ofnode_phandle_args args;
- ofnode node;
- int ret;
- const char prop[] = "test-gpios";
- const char cell[] = "#gpio-cells";
- const char prop2[] = "phandle-value";
- node = ofnode_path("/a-test");
- ut_assert(ofnode_valid(node));
- /* Test ofnode_count_phandle_with_args with cell name */
- ret = ofnode_count_phandle_with_args(node, "missing", cell, 0);
- ut_asserteq(-ENOENT, ret);
- ret = ofnode_count_phandle_with_args(node, prop, "#invalid", 0);
- ut_asserteq(-EINVAL, ret);
- ret = ofnode_count_phandle_with_args(node, prop, cell, 0);
- ut_asserteq(5, ret);
- /* Test ofnode_parse_phandle_with_args with cell name */
- ret = ofnode_parse_phandle_with_args(node, "missing", cell, 0, 0,
- &args);
- ut_asserteq(-ENOENT, ret);
- ret = ofnode_parse_phandle_with_args(node, prop, "#invalid", 0, 0,
- &args);
- ut_asserteq(-EINVAL, ret);
- ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 0, &args);
- ut_assertok(ret);
- ut_asserteq(1, args.args_count);
- ut_asserteq(1, args.args[0]);
- ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 1, &args);
- ut_assertok(ret);
- ut_asserteq(1, args.args_count);
- ut_asserteq(4, args.args[0]);
- ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 2, &args);
- ut_assertok(ret);
- ut_asserteq(5, args.args_count);
- ut_asserteq(5, args.args[0]);
- ut_asserteq(1, args.args[4]);
- ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 3, &args);
- ut_asserteq(-ENOENT, ret);
- ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 4, &args);
- ut_assertok(ret);
- ut_asserteq(1, args.args_count);
- ut_asserteq(12, args.args[0]);
- ret = ofnode_parse_phandle_with_args(node, prop, cell, 0, 5, &args);
- ut_asserteq(-ENOENT, ret);
- /* Test ofnode_count_phandle_with_args with cell count */
- ret = ofnode_count_phandle_with_args(node, "missing", NULL, 2);
- ut_asserteq(-ENOENT, ret);
- ret = ofnode_count_phandle_with_args(node, prop2, NULL, 1);
- ut_asserteq(3, ret);
- /* Test ofnode_parse_phandle_with_args with cell count */
- ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 0, &args);
- ut_assertok(ret);
- ut_asserteq(1, ofnode_valid(args.node));
- ut_asserteq(1, args.args_count);
- ut_asserteq(10, args.args[0]);
- ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 1, &args);
- ut_asserteq(-EINVAL, ret);
- ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 2, &args);
- ut_assertok(ret);
- ut_asserteq(1, ofnode_valid(args.node));
- ut_asserteq(1, args.args_count);
- ut_asserteq(30, args.args[0]);
- ret = ofnode_parse_phandle_with_args(node, prop2, NULL, 1, 3, &args);
- ut_asserteq(-ENOENT, ret);
- return 0;
- }
- DM_TEST(dm_test_ofnode_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_phandle_ot(struct unit_test_state *uts)
- {
- oftree otree = get_other_oftree(uts);
- struct ofnode_phandle_args args;
- ofnode node;
- int ret;
- node = oftree_path(otree, "/node");
- /* Test ofnode_count_phandle_with_args with cell name */
- ret = ofnode_count_phandle_with_args(node, "missing", "#gpio-cells", 0);
- ut_asserteq(-ENOENT, ret);
- ret = ofnode_count_phandle_with_args(node, "target", "#invalid", 0);
- ut_asserteq(-EINVAL, ret);
- ret = ofnode_count_phandle_with_args(node, "target", "#gpio-cells", 0);
- ut_asserteq(1, ret);
- ret = ofnode_parse_phandle_with_args(node, "target", "#gpio-cells", 0,
- 0, &args);
- ut_assertok(ret);
- ut_asserteq(2, args.args_count);
- ut_asserteq(3, args.args[0]);
- ut_asserteq(4, args.args[1]);
- return 0;
- }
- DM_TEST(dm_test_ofnode_phandle_ot, UT_TESTF_OTHER_FDT);
- static int dm_test_ofnode_read_chosen(struct unit_test_state *uts)
- {
- const char *str;
- const u32 *val;
- ofnode node;
- int size;
- str = ofnode_read_chosen_string("setting");
- ut_assertnonnull(str);
- ut_asserteq_str("sunrise ohoka", str);
- ut_asserteq_ptr(NULL, ofnode_read_chosen_string("no-setting"));
- node = ofnode_get_chosen_node("other-node");
- ut_assert(ofnode_valid(node));
- ut_asserteq_str("c-test@5", ofnode_get_name(node));
- node = ofnode_get_chosen_node("setting");
- ut_assert(!ofnode_valid(node));
- val = ofnode_read_chosen_prop("int-values", &size);
- ut_assertnonnull(val);
- ut_asserteq(8, size);
- ut_asserteq(0x1937, fdt32_to_cpu(val[0]));
- ut_asserteq(72993, fdt32_to_cpu(val[1]));
- return 0;
- }
- DM_TEST(dm_test_ofnode_read_chosen, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_read_aliases(struct unit_test_state *uts)
- {
- const void *val;
- ofnode node;
- int size;
- node = ofnode_get_aliases_node("ethernet3");
- ut_assert(ofnode_valid(node));
- ut_asserteq_str("sbe5", ofnode_get_name(node));
- node = ofnode_get_aliases_node("unknown");
- ut_assert(!ofnode_valid(node));
- val = ofnode_read_aliases_prop("spi0", &size);
- ut_assertnonnull(val);
- ut_asserteq(7, size);
- ut_asserteq_str("/spi@0", (const char *)val);
- return 0;
- }
- DM_TEST(dm_test_ofnode_read_aliases, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_get_child_count(struct unit_test_state *uts)
- {
- ofnode node, child_node;
- u32 val;
- node = ofnode_path("/i-test");
- ut_assert(ofnode_valid(node));
- val = ofnode_get_child_count(node);
- ut_asserteq(3, val);
- child_node = ofnode_first_subnode(node);
- ut_assert(ofnode_valid(child_node));
- val = ofnode_get_child_count(child_node);
- ut_asserteq(0, val);
- return 0;
- }
- DM_TEST(dm_test_ofnode_get_child_count,
- UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_get_child_count_ot(struct unit_test_state *uts)
- {
- oftree otree = get_other_oftree(uts);
- ofnode node, child_node;
- u32 val;
- node = oftree_path(otree, "/node");
- ut_assert(ofnode_valid(node));
- val = ofnode_get_child_count(node);
- ut_asserteq(2, val);
- child_node = ofnode_first_subnode(node);
- ut_assert(ofnode_valid(child_node));
- val = ofnode_get_child_count(child_node);
- ut_asserteq(0, val);
- return 0;
- }
- DM_TEST(dm_test_ofnode_get_child_count_ot, UT_TESTF_OTHER_FDT);
- static int dm_test_ofnode_is_enabled(struct unit_test_state *uts)
- {
- ofnode root_node = ofnode_path("/");
- ofnode node = ofnode_path("/usb@0");
- ut_assert(ofnode_is_enabled(root_node));
- ut_assert(!ofnode_is_enabled(node));
- return 0;
- }
- DM_TEST(dm_test_ofnode_is_enabled, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_is_enabled_ot(struct unit_test_state *uts)
- {
- oftree otree = get_other_oftree(uts);
- ofnode root_node = oftree_root(otree);
- ofnode node = oftree_path(otree, "/target");
- ut_assert(ofnode_is_enabled(root_node));
- ut_assert(!ofnode_is_enabled(node));
- return 0;
- }
- DM_TEST(dm_test_ofnode_is_enabled_ot, UT_TESTF_OTHER_FDT);
- static int dm_test_ofnode_get_reg(struct unit_test_state *uts)
- {
- ofnode node;
- fdt_addr_t addr;
- fdt_size_t size;
- node = ofnode_path("/translation-test@8000");
- ut_assert(ofnode_valid(node));
- addr = ofnode_get_addr(node);
- size = ofnode_get_size(node);
- ut_asserteq(0x8000, addr);
- ut_asserteq(0x4000, size);
- node = ofnode_path("/translation-test@8000/dev@1,100");
- ut_assert(ofnode_valid(node));
- addr = ofnode_get_addr(node);
- size = ofnode_get_size(node);
- ut_asserteq(0x9000, addr);
- ut_asserteq(0x1000, size);
- node = ofnode_path("/emul-mux-controller");
- ut_assert(ofnode_valid(node));
- addr = ofnode_get_addr(node);
- size = ofnode_get_size(node);
- ut_asserteq_64(FDT_ADDR_T_NONE, addr);
- ut_asserteq(FDT_SIZE_T_NONE, size);
- node = ofnode_path("/translation-test@8000/noxlatebus@3,300/dev@42");
- ut_assert(ofnode_valid(node));
- addr = ofnode_get_addr_size_index_notrans(node, 0, &size);
- ut_asserteq_64(0x42, addr);
- return 0;
- }
- DM_TEST(dm_test_ofnode_get_reg, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_get_reg_ot(struct unit_test_state *uts)
- {
- oftree otree = get_other_oftree(uts);
- ofnode node = oftree_path(otree, "/target");
- fdt_addr_t addr;
- addr = ofnode_get_addr(node);
- ut_asserteq(0x8000, addr);
- return 0;
- }
- DM_TEST(dm_test_ofnode_get_reg_ot, UT_TESTF_OTHER_FDT);
- static int dm_test_ofnode_get_path(struct unit_test_state *uts)
- {
- const char *path = "/translation-test@8000/noxlatebus@3,300/dev@42";
- char buf[64];
- ofnode node;
- node = ofnode_path(path);
- ut_assert(ofnode_valid(node));
- ut_assertok(ofnode_get_path(node, buf, sizeof(buf)));
- ut_asserteq_str(path, buf);
- ut_asserteq(-ENOSPC, ofnode_get_path(node, buf, 32));
- ut_assertok(ofnode_get_path(ofnode_root(), buf, 32));
- ut_asserteq_str("/", buf);
- return 0;
- }
- DM_TEST(dm_test_ofnode_get_path, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_get_path_ot(struct unit_test_state *uts)
- {
- oftree otree = get_other_oftree(uts);
- const char *path = "/node/subnode";
- ofnode node = oftree_path(otree, path);
- char buf[64];
- ut_assert(ofnode_valid(node));
- ut_assertok(ofnode_get_path(node, buf, sizeof(buf)));
- ut_asserteq_str(path, buf);
- ut_assertok(ofnode_get_path(oftree_root(otree), buf, 32));
- ut_asserteq_str("/", buf);
- return 0;
- }
- DM_TEST(dm_test_ofnode_get_path_ot, UT_TESTF_OTHER_FDT);
- static int dm_test_ofnode_conf(struct unit_test_state *uts)
- {
- ut_assert(!ofnode_conf_read_bool("missing"));
- ut_assert(ofnode_conf_read_bool("testing-bool"));
- ut_asserteq(123, ofnode_conf_read_int("testing-int", 0));
- ut_asserteq(6, ofnode_conf_read_int("missing", 6));
- ut_assertnull(ofnode_conf_read_str("missing"));
- ut_asserteq_str("testing", ofnode_conf_read_str("testing-str"));
- return 0;
- }
- DM_TEST(dm_test_ofnode_conf, 0);
- static int dm_test_ofnode_for_each_compatible_node(struct unit_test_state *uts)
- {
- const char compatible[] = "denx,u-boot-fdt-test";
- bool found = false;
- ofnode node;
- ofnode_for_each_compatible_node(node, compatible) {
- ut_assert(ofnode_device_is_compatible(node, compatible));
- found = true;
- }
- /* There should be at least one matching node */
- ut_assert(found);
- return 0;
- }
- DM_TEST(dm_test_ofnode_for_each_compatible_node, UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_string(struct unit_test_state *uts)
- {
- const char **val;
- const char *out;
- ofnode node;
- node = ofnode_path("/a-test");
- ut_assert(ofnode_valid(node));
- /* single string */
- ut_asserteq(1, ofnode_read_string_count(node, "str-value"));
- ut_assertok(ofnode_read_string_index(node, "str-value", 0, &out));
- ut_asserteq_str("test string", out);
- ut_asserteq(0, ofnode_stringlist_search(node, "str-value",
- "test string"));
- ut_asserteq(1, ofnode_read_string_list(node, "str-value", &val));
- ut_asserteq_str("test string", val[0]);
- ut_assertnull(val[1]);
- free(val);
- /* list of strings */
- ut_asserteq(5, ofnode_read_string_count(node, "mux-control-names"));
- ut_assertok(ofnode_read_string_index(node, "mux-control-names", 0,
- &out));
- ut_asserteq_str("mux0", out);
- ut_asserteq(0, ofnode_stringlist_search(node, "mux-control-names",
- "mux0"));
- ut_asserteq(5, ofnode_read_string_list(node, "mux-control-names",
- &val));
- ut_asserteq_str("mux0", val[0]);
- ut_asserteq_str("mux1", val[1]);
- ut_asserteq_str("mux2", val[2]);
- ut_asserteq_str("mux3", val[3]);
- ut_asserteq_str("mux4", val[4]);
- ut_assertnull(val[5]);
- free(val);
- ut_assertok(ofnode_read_string_index(node, "mux-control-names", 4,
- &out));
- ut_asserteq_str("mux4", out);
- ut_asserteq(4, ofnode_stringlist_search(node, "mux-control-names",
- "mux4"));
- return 0;
- }
- DM_TEST(dm_test_ofnode_string, 0);
- static int dm_test_ofnode_string_err(struct unit_test_state *uts)
- {
- const char **val;
- const char *out;
- ofnode node;
- /*
- * Test error codes only on livetree, as they are different with
- * flattree
- */
- node = ofnode_path("/a-test");
- ut_assert(ofnode_valid(node));
- /* non-existent property */
- ut_asserteq(-EINVAL, ofnode_read_string_count(node, "missing"));
- ut_asserteq(-EINVAL, ofnode_read_string_index(node, "missing", 0,
- &out));
- ut_asserteq(-EINVAL, ofnode_read_string_list(node, "missing", &val));
- /* empty property */
- ut_asserteq(-ENODATA, ofnode_read_string_count(node, "bool-value"));
- ut_asserteq(-ENODATA, ofnode_read_string_index(node, "bool-value", 0,
- &out));
- ut_asserteq(-ENODATA, ofnode_read_string_list(node, "bool-value",
- &val));
- /* badly formatted string list */
- ut_asserteq(-EILSEQ, ofnode_read_string_count(node, "int64-value"));
- ut_asserteq(-EILSEQ, ofnode_read_string_index(node, "int64-value", 0,
- &out));
- ut_asserteq(-EILSEQ, ofnode_read_string_list(node, "int64-value",
- &val));
- /* out of range / not found */
- ut_asserteq(-ENODATA, ofnode_read_string_index(node, "str-value", 1,
- &out));
- ut_asserteq(-ENODATA, ofnode_stringlist_search(node, "str-value",
- "other"));
- /* negative value for index is not allowed, so don't test for that */
- ut_asserteq(-ENODATA, ofnode_read_string_index(node,
- "mux-control-names", 5,
- &out));
- return 0;
- }
- DM_TEST(dm_test_ofnode_string_err, UT_TESTF_LIVE_TREE);
- static int dm_test_ofnode_get_phy(struct unit_test_state *uts)
- {
- ofnode eth_node, phy_node;
- phy_interface_t mode;
- u32 reg;
- eth_node = ofnode_path("/phy-test-eth");
- ut_assert(ofnode_valid(eth_node));
- mode = ofnode_read_phy_mode(eth_node);
- ut_assert(mode == PHY_INTERFACE_MODE_2500BASEX);
- phy_node = ofnode_get_phy_node(eth_node);
- ut_assert(ofnode_valid(phy_node));
- reg = ofnode_read_u32_default(phy_node, "reg", -1U);
- ut_asserteq_64(0x1, reg);
- return 0;
- }
- DM_TEST(dm_test_ofnode_get_phy, 0);
- /**
- * make_ofnode_fdt() - Create an FDT for testing with ofnode
- *
- * The size is set to the minimum needed
- *
- * @uts: Test state
- * @fdt: Place to write FDT
- * @size: Maximum size of space for fdt
- * @id: id value to add to the tree ('id' property in root node)
- */
- static int make_ofnode_fdt(struct unit_test_state *uts, void *fdt, int size,
- int id)
- {
- ut_assertok(fdt_create(fdt, size));
- ut_assertok(fdt_finish_reservemap(fdt));
- ut_assert(fdt_begin_node(fdt, "") >= 0);
- ut_assertok(fdt_property_u32(fdt, "id", id));
- ut_assert(fdt_begin_node(fdt, "aliases") >= 0);
- ut_assertok(fdt_property_string(fdt, "mmc0", "/new-mmc"));
- ut_assertok(fdt_end_node(fdt));
- ut_assert(fdt_begin_node(fdt, "new-mmc") >= 0);
- ut_assertok(fdt_end_node(fdt));
- ut_assertok(fdt_end_node(fdt));
- ut_assertok(fdt_finish(fdt));
- return 0;
- }
- static int dm_test_ofnode_root(struct unit_test_state *uts)
- {
- ofnode node;
- /* Check that aliases work on the control FDT */
- node = ofnode_get_aliases_node("ethernet3");
- ut_assert(ofnode_valid(node));
- ut_asserteq_str("sbe5", ofnode_get_name(node));
- ut_assert(!oftree_valid(oftree_null()));
- return 0;
- }
- DM_TEST(dm_test_ofnode_root, UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_root_mult(struct unit_test_state *uts)
- {
- char fdt[256];
- oftree tree;
- ofnode node;
- /* skip this test if multiple FDTs are not supported */
- if (!IS_ENABLED(CONFIG_OFNODE_MULTI_TREE))
- return -EAGAIN;
- ut_assertok(make_ofnode_fdt(uts, fdt, sizeof(fdt), 0));
- ut_assertok(get_oftree(uts, fdt, &tree));
- ut_assert(oftree_valid(tree));
- /* Make sure they don't work on this new tree */
- node = oftree_path(tree, "mmc0");
- ut_assert(!ofnode_valid(node));
- /* It should appear in the new tree */
- node = oftree_path(tree, "/new-mmc");
- ut_assert(ofnode_valid(node));
- /* ...and not in the control FDT */
- node = oftree_path(oftree_default(), "/new-mmc");
- ut_assert(!ofnode_valid(node));
- free_oftree(tree);
- return 0;
- }
- DM_TEST(dm_test_ofnode_root_mult, UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts)
- {
- struct udevice *dev;
- ofnode node;
- /* Test enabling devices */
- node = ofnode_path("/usb@2");
- ut_assert(!ofnode_is_enabled(node));
- ut_assertok(ofnode_set_enabled(node, true));
- ut_asserteq(true, ofnode_is_enabled(node));
- device_bind_driver_to_node(dm_root(), "usb_sandbox", "usb@2", node,
- &dev);
- ut_assertok(uclass_find_device_by_seq(UCLASS_USB, 2, &dev));
- /* Test string property setting */
- ut_assert(device_is_compatible(dev, "sandbox,usb"));
- ofnode_write_string(node, "compatible", "gdsys,super-usb");
- ut_assert(device_is_compatible(dev, "gdsys,super-usb"));
- ofnode_write_string(node, "compatible", "sandbox,usb");
- ut_assert(device_is_compatible(dev, "sandbox,usb"));
- /* Test setting generic properties */
- /* Non-existent in DTB */
- ut_asserteq_64(FDT_ADDR_T_NONE, dev_read_addr(dev));
- /* reg = 0x42, size = 0x100 */
- ut_assertok(ofnode_write_prop(node, "reg",
- "\x00\x00\x00\x42\x00\x00\x01\x00", 8,
- false));
- ut_asserteq(0x42, dev_read_addr(dev));
- /* Test disabling devices */
- device_remove(dev, DM_REMOVE_NORMAL);
- device_unbind(dev);
- ut_assert(ofnode_is_enabled(node));
- ut_assertok(ofnode_set_enabled(node, false));
- ut_assert(!ofnode_is_enabled(node));
- return 0;
- }
- DM_TEST(dm_test_ofnode_livetree_writing,
- UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
- static int check_write_prop(struct unit_test_state *uts, ofnode node)
- {
- char prop[] = "middle-name";
- char name[10];
- int len;
- strcpy(name, "cecil");
- len = strlen(name) + 1;
- ut_assertok(ofnode_write_prop(node, prop, name, len, false));
- ut_asserteq_str(name, ofnode_read_string(node, prop));
- /* change the underlying value, this should mess up the live tree */
- strcpy(name, "tony");
- if (of_live_active()) {
- ut_asserteq_str(name, ofnode_read_string(node, prop));
- } else {
- ut_asserteq_str("cecil", ofnode_read_string(node, prop));
- }
- /* try again, this time copying the property */
- strcpy(name, "mary");
- ut_assertok(ofnode_write_prop(node, prop, name, len, true));
- ut_asserteq_str(name, ofnode_read_string(node, prop));
- strcpy(name, "leah");
- /* both flattree and livetree behave the same */
- ut_asserteq_str("mary", ofnode_read_string(node, prop));
- return 0;
- }
- /* writing the tree with and without copying the property */
- static int dm_test_ofnode_write_copy(struct unit_test_state *uts)
- {
- ofnode node;
- node = ofnode_path("/a-test");
- ut_assertok(check_write_prop(uts, node));
- return 0;
- }
- DM_TEST(dm_test_ofnode_write_copy, UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_write_copy_ot(struct unit_test_state *uts)
- {
- oftree otree = get_other_oftree(uts);
- ofnode node, check_node;
- node = oftree_path(otree, "/node");
- ut_assertok(check_write_prop(uts, node));
- /* make sure the control FDT is not touched */
- check_node = ofnode_path("/node");
- ut_assertnull(ofnode_read_string(check_node, "middle-name"));
- return 0;
- }
- DM_TEST(dm_test_ofnode_write_copy_ot, UT_TESTF_OTHER_FDT);
- static int dm_test_ofnode_u32(struct unit_test_state *uts)
- {
- ofnode node;
- u32 val;
- node = ofnode_path("/lcd");
- ut_assert(ofnode_valid(node));
- ut_asserteq(1366, ofnode_read_u32_default(node, "xres", 123));
- ut_assertok(ofnode_write_u32(node, "xres", 1367));
- ut_asserteq(1367, ofnode_read_u32_default(node, "xres", 123));
- ut_assertok(ofnode_write_u32(node, "xres", 1366));
- node = ofnode_path("/backlight");
- ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 0, &val));
- ut_asserteq(0, val);
- ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 1, &val));
- ut_asserteq(16, val);
- ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 8, &val));
- ut_asserteq(255, val);
- ut_asserteq(-EOVERFLOW,
- ofnode_read_u32_index(node, "brightness-levels", 9, &val));
- ut_asserteq(-EINVAL, ofnode_read_u32_index(node, "missing", 0, &val));
- return 0;
- }
- DM_TEST(dm_test_ofnode_u32, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_u32_array(struct unit_test_state *uts)
- {
- ofnode node;
- u32 val[10];
- node = ofnode_path("/a-test");
- ut_assert(ofnode_valid(node));
- ut_assertok(ofnode_read_u32_array(node, "int-value", val, 1));
- ut_asserteq(-EINVAL, ofnode_read_u32_array(node, "missing", val, 1));
- ut_asserteq(-EOVERFLOW, ofnode_read_u32_array(node, "bool-value", val,
- 1));
- memset(val, '\0', sizeof(val));
- ut_assertok(ofnode_read_u32_array(node, "int-array", val + 1, 3));
- ut_asserteq(0, val[0]);
- ut_asserteq(5678, val[1]);
- ut_asserteq(9123, val[2]);
- ut_asserteq(4567, val[3]);
- ut_asserteq(0, val[4]);
- ut_asserteq(-EOVERFLOW, ofnode_read_u32_array(node, "int-array", val,
- 4));
- return 0;
- }
- DM_TEST(dm_test_ofnode_u32_array, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_u64(struct unit_test_state *uts)
- {
- ofnode node;
- u64 val;
- node = ofnode_path("/a-test");
- ut_assert(ofnode_valid(node));
- ut_assertok(ofnode_read_u64(node, "int64-value", &val));
- ut_asserteq_64(0x1111222233334444, val);
- ut_asserteq(-EINVAL, ofnode_read_u64(node, "missing", &val));
- return 0;
- }
- DM_TEST(dm_test_ofnode_u64, UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_add_subnode(struct unit_test_state *uts)
- {
- ofnode node, check, subnode;
- char buf[128];
- node = ofnode_path("/lcd");
- ut_assert(ofnode_valid(node));
- ut_assertok(ofnode_add_subnode(node, "edmund", &subnode));
- check = ofnode_path("/lcd/edmund");
- ut_asserteq(subnode.of_offset, check.of_offset);
- ut_assertok(ofnode_get_path(subnode, buf, sizeof(buf)));
- ut_asserteq_str("/lcd/edmund", buf);
- if (of_live_active()) {
- struct device_node *child;
- ut_assertok(of_add_subnode((void *)ofnode_to_np(node), "edmund",
- 2, &child));
- ut_asserteq_str("ed", child->name);
- ut_asserteq_str("/lcd/ed", child->full_name);
- check = ofnode_path("/lcd/ed");
- ut_asserteq_ptr(child, check.np);
- ut_assertok(ofnode_get_path(np_to_ofnode(child), buf,
- sizeof(buf)));
- ut_asserteq_str("/lcd/ed", buf);
- }
- /* An existing node should be returned with -EEXIST */
- ut_asserteq(-EEXIST, ofnode_add_subnode(node, "edmund", &check));
- ut_asserteq(subnode.of_offset, check.of_offset);
- /* add a root node */
- node = ofnode_path("/");
- ut_assert(ofnode_valid(node));
- ut_assertok(ofnode_add_subnode(node, "lcd2", &subnode));
- check = ofnode_path("/lcd2");
- ut_asserteq(subnode.of_offset, check.of_offset);
- ut_assertok(ofnode_get_path(subnode, buf, sizeof(buf)));
- ut_asserteq_str("/lcd2", buf);
- if (of_live_active()) {
- ulong start;
- int i;
- /*
- * Make sure each of the three malloc()checks in
- * of_add_subnode() work
- */
- for (i = 0; i < 3; i++) {
- malloc_enable_testing(i);
- start = ut_check_free();
- ut_asserteq(-ENOMEM, ofnode_add_subnode(node, "anthony",
- &check));
- ut_assertok(ut_check_delta(start));
- }
- /* This should pass since we allow 3 allocations */
- malloc_enable_testing(3);
- ut_assertok(ofnode_add_subnode(node, "anthony", &check));
- malloc_disable_testing();
- }
- /* write to the empty node */
- ut_assertok(ofnode_write_string(subnode, "example", "text"));
- return 0;
- }
- DM_TEST(dm_test_ofnode_add_subnode, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_for_each_prop(struct unit_test_state *uts)
- {
- ofnode node, subnode;
- struct ofprop prop;
- int count;
- node = ofnode_path("/ofnode-foreach");
- count = 0;
- /* we expect "compatible" for each node */
- ofnode_for_each_prop(prop, node)
- count++;
- ut_asserteq(1, count);
- /* there are two nodes, each with 2 properties */
- ofnode_for_each_subnode(subnode, node)
- ofnode_for_each_prop(prop, subnode)
- count++;
- ut_asserteq(5, count);
- return 0;
- }
- DM_TEST(dm_test_ofnode_for_each_prop, UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_by_compatible(struct unit_test_state *uts)
- {
- const char *compat = "denx,u-boot-fdt-test";
- ofnode node;
- int count;
- count = 0;
- for (node = ofnode_null();
- node = ofnode_by_compatible(node, compat), ofnode_valid(node);)
- count++;
- ut_asserteq(11, count);
- return 0;
- }
- DM_TEST(dm_test_ofnode_by_compatible, UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_by_compatible_ot(struct unit_test_state *uts)
- {
- const char *compat = "sandbox-other2";
- oftree otree = get_other_oftree(uts);
- ofnode node;
- int count;
- count = 0;
- for (node = oftree_root(otree);
- node = ofnode_by_compatible(node, compat), ofnode_valid(node);)
- count++;
- ut_asserteq(2, count);
- return 0;
- }
- DM_TEST(dm_test_ofnode_by_compatible_ot, UT_TESTF_OTHER_FDT);
- static int dm_test_ofnode_find_subnode(struct unit_test_state *uts)
- {
- ofnode node, subnode;
- node = ofnode_path("/buttons");
- subnode = ofnode_find_subnode(node, "btn1");
- ut_assert(ofnode_valid(subnode));
- ut_asserteq_str("btn1", ofnode_get_name(subnode));
- subnode = ofnode_find_subnode(node, "btn");
- ut_assert(!ofnode_valid(subnode));
- return 0;
- }
- DM_TEST(dm_test_ofnode_find_subnode, UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_find_subnode_ot(struct unit_test_state *uts)
- {
- oftree otree = get_other_oftree(uts);
- ofnode node, subnode;
- node = oftree_path(otree, "/node");
- subnode = ofnode_find_subnode(node, "subnode");
- ut_assert(ofnode_valid(subnode));
- ut_asserteq_str("subnode", ofnode_get_name(subnode));
- subnode = ofnode_find_subnode(node, "btn");
- ut_assert(!ofnode_valid(subnode));
- return 0;
- }
- DM_TEST(dm_test_ofnode_find_subnode_ot, UT_TESTF_OTHER_FDT);
- static int dm_test_ofnode_get_name(struct unit_test_state *uts)
- {
- ofnode node;
- node = ofnode_path("/buttons");
- ut_assert(ofnode_valid(node));
- ut_asserteq_str("buttons", ofnode_get_name(node));
- ut_asserteq_str("", ofnode_get_name(ofnode_root()));
- return 0;
- }
- DM_TEST(dm_test_ofnode_get_name, UT_TESTF_SCAN_FDT);
- /* try to access more FDTs than is supported */
- static int dm_test_ofnode_too_many(struct unit_test_state *uts)
- {
- const int max_trees = CONFIG_IS_ENABLED(OFNODE_MULTI_TREE,
- (CONFIG_OFNODE_MULTI_TREE_MAX), (1));
- const int fdt_size = 256;
- const int num_trees = max_trees + 1;
- char fdt[num_trees][fdt_size];
- int i;
- for (i = 0; i < num_trees; i++) {
- oftree tree;
- int ret;
- ut_assertok(make_ofnode_fdt(uts, fdt[i], fdt_size, i));
- ret = get_oftree(uts, fdt[i], &tree);
- /*
- * With flat tree we have the control FDT using one slot. Live
- * tree has no limit since it uses pointers, not integer tree
- * IDs
- */
- if (of_live_active() || i < max_trees - 1) {
- ut_assertok(ret);
- } else {
- /*
- * tree should be invalid when we try to register too
- * many trees
- */
- ut_asserteq(-EOVERFLOW, ret);
- }
- }
- return 0;
- }
- DM_TEST(dm_test_ofnode_too_many, UT_TESTF_SCAN_FDT);
- static int check_copy_props(struct unit_test_state *uts, ofnode src,
- ofnode dst)
- {
- u32 reg[2], val;
- ut_assertok(ofnode_copy_props(src, dst));
- ut_assertok(ofnode_read_u32(dst, "ping-expect", &val));
- ut_asserteq(3, val);
- ut_asserteq_str("denx,u-boot-fdt-test",
- ofnode_read_string(dst, "compatible"));
- /* check that a property with the same name is overwritten */
- ut_assertok(ofnode_read_u32_array(dst, "reg", reg, ARRAY_SIZE(reg)));
- ut_asserteq(3, reg[0]);
- ut_asserteq(1, reg[1]);
- /* reset the compatible so the live tree does not change */
- ut_assertok(ofnode_write_string(dst, "compatible", "nothing"));
- return 0;
- }
- static int dm_test_ofnode_copy_props(struct unit_test_state *uts)
- {
- ofnode src, dst;
- /*
- * These nodes are chosen so that the src node is before the destination
- * node in the tree. This doesn't matter with livetree, but with
- * flattree any attempt to insert a property earlier in the tree will
- * mess up the offsets after it.
- */
- src = ofnode_path("/b-test");
- dst = ofnode_path("/some-bus");
- ut_assertok(check_copy_props(uts, src, dst));
- /* check a property that is in the destination already */
- ut_asserteq_str("mux0", ofnode_read_string(dst, "mux-control-names"));
- return 0;
- }
- DM_TEST(dm_test_ofnode_copy_props, UT_TESTF_SCAN_FDT);
- static int dm_test_ofnode_copy_props_ot(struct unit_test_state *uts)
- {
- ofnode src, dst;
- oftree otree = get_other_oftree(uts);
- src = ofnode_path("/b-test");
- dst = oftree_path(otree, "/node/subnode2");
- ut_assertok(check_copy_props(uts, src, dst));
- return 0;
- }
- DM_TEST(dm_test_ofnode_copy_props_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT);
- /* check that the livetree is aligned to a structure boundary */
- static int dm_test_livetree_align(struct unit_test_state *uts)
- {
- const int align = __alignof__(struct unit_test_state);
- struct device_node *node;
- u32 *sentinel;
- ulong start;
- start = (ulong)gd_of_root();
- ut_asserteq(start, ALIGN(start, align));
- node = gd_of_root();
- sentinel = (void *)node - sizeof(u32);
- /*
- * The sentinel should be overwritten with the root node. If it isn't,
- * then the root node is not at the very start of the livetree memory
- * area, and free(root) will fail to free the memory used by the
- * livetree.
- */
- ut_assert(*sentinel != BAD_OF_ROOT);
- return 0;
- }
- DM_TEST(dm_test_livetree_align, UT_TESTF_LIVE_TREE);
- /* check that it is possible to load an arbitrary livetree */
- static int dm_test_livetree_ensure(struct unit_test_state *uts)
- {
- oftree tree;
- ofnode node;
- /* read from other.dtb */
- ut_assertok(test_load_other_fdt(uts));
- tree = oftree_from_fdt(uts->other_fdt);
- ut_assert(oftree_valid(tree));
- node = oftree_path(tree, "/node/subnode");
- ut_assert(ofnode_valid(node));
- ut_asserteq_str("sandbox-other2",
- ofnode_read_string(node, "compatible"));
- return 0;
- }
- DM_TEST(dm_test_livetree_ensure, 0);
|