123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- /*
- * Copyright (c) 2016 NextThing Co
- * Copyright (c) 2016 Free Electrons
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
- #include <common.h>
- #include <command.h>
- #include <errno.h>
- #include <malloc.h>
- #include <linux/sizes.h>
- #include <test/ut.h>
- #include <test/overlay.h>
- /* 4k ought to be enough for anybody */
- #define FDT_COPY_SIZE (4 * SZ_1K)
- extern u32 __dtb_test_fdt_base_begin;
- extern u32 __dtb_test_fdt_overlay_begin;
- static int fdt_getprop_u32_by_index(void *fdt, const char *path,
- const char *name, int index,
- u32 *out)
- {
- const fdt32_t *val;
- int node_off;
- int len;
- node_off = fdt_path_offset(fdt, path);
- if (node_off < 0)
- return node_off;
- val = fdt_getprop(fdt, node_off, name, &len);
- if (!val || (len < (sizeof(uint32_t) * (index + 1))))
- return -FDT_ERR_NOTFOUND;
- *out = fdt32_to_cpu(*(val + index));
- return 0;
- }
- static int fdt_getprop_u32(void *fdt, const char *path, const char *name,
- u32 *out)
- {
- return fdt_getprop_u32_by_index(fdt, path, name, 0, out);
- }
- static int fdt_getprop_str(void *fdt, const char *path, const char *name,
- const char **out)
- {
- int node_off;
- int len;
- node_off = fdt_path_offset(fdt, path);
- if (node_off < 0)
- return node_off;
- *out = fdt_stringlist_get(fdt, node_off, name, 0, &len);
- return len < 0 ? len : 0;
- }
- static int fdt_overlay_change_int_property(struct unit_test_state *uts)
- {
- void *fdt = uts->priv;
- u32 val = 0;
- ut_assertok(fdt_getprop_u32(fdt, "/test-node", "test-int-property",
- &val));
- ut_asserteq(43, val);
- return CMD_RET_SUCCESS;
- }
- OVERLAY_TEST(fdt_overlay_change_int_property, 0);
- static int fdt_overlay_change_str_property(struct unit_test_state *uts)
- {
- void *fdt = uts->priv;
- const char *val = NULL;
- ut_assertok(fdt_getprop_str(fdt, "/test-node", "test-str-property",
- &val));
- ut_asserteq_str("foobar", val);
- return CMD_RET_SUCCESS;
- }
- OVERLAY_TEST(fdt_overlay_change_str_property, 0);
- static int fdt_overlay_add_str_property(struct unit_test_state *uts)
- {
- void *fdt = uts->priv;
- const char *val = NULL;
- ut_assertok(fdt_getprop_str(fdt, "/test-node", "test-str-property-2",
- &val));
- ut_asserteq_str("foobar2", val);
- return CMD_RET_SUCCESS;
- }
- OVERLAY_TEST(fdt_overlay_add_str_property, 0);
- static int fdt_overlay_add_node_by_phandle(struct unit_test_state *uts)
- {
- void *fdt = uts->priv;
- int off;
- off = fdt_path_offset(fdt, "/test-node/new-node");
- ut_assert(off >= 0);
- ut_assertnonnull(fdt_getprop(fdt, off, "new-property", NULL));
- return CMD_RET_SUCCESS;
- }
- OVERLAY_TEST(fdt_overlay_add_node_by_phandle, 0);
- static int fdt_overlay_add_node_by_path(struct unit_test_state *uts)
- {
- void *fdt = uts->priv;
- int off;
- off = fdt_path_offset(fdt, "/new-node");
- ut_assert(off >= 0);
- ut_assertnonnull(fdt_getprop(fdt, off, "new-property", NULL));
- return CMD_RET_SUCCESS;
- }
- OVERLAY_TEST(fdt_overlay_add_node_by_path, 0);
- static int fdt_overlay_add_subnode_property(struct unit_test_state *uts)
- {
- void *fdt = uts->priv;
- int off;
- off = fdt_path_offset(fdt, "/test-node/sub-test-node");
- ut_assert(off >= 0);
- ut_assertnonnull(fdt_getprop(fdt, off, "sub-test-property", NULL));
- ut_assertnonnull(fdt_getprop(fdt, off, "new-sub-test-property", NULL));
- return CMD_RET_SUCCESS;
- }
- OVERLAY_TEST(fdt_overlay_add_subnode_property, 0);
- static int fdt_overlay_local_phandle(struct unit_test_state *uts)
- {
- uint32_t local_phandle;
- void *fdt = uts->priv;
- u32 val = 0;
- int off;
- off = fdt_path_offset(fdt, "/new-local-node");
- ut_assert(off >= 0);
- local_phandle = fdt_get_phandle(fdt, off);
- ut_assert(local_phandle);
- ut_assertok(fdt_getprop_u32_by_index(fdt, "/", "test-several-phandle",
- 0, &val));
- ut_asserteq(local_phandle, val);
- ut_assertok(fdt_getprop_u32_by_index(fdt, "/", "test-several-phandle",
- 1, &val));
- ut_asserteq(local_phandle, val);
- return CMD_RET_SUCCESS;
- }
- OVERLAY_TEST(fdt_overlay_local_phandle, 0);
- static int fdt_overlay_local_phandles(struct unit_test_state *uts)
- {
- uint32_t local_phandle, test_phandle;
- void *fdt = uts->priv;
- u32 val = 0;
- int off;
- off = fdt_path_offset(fdt, "/new-local-node");
- ut_assert(off >= 0);
- local_phandle = fdt_get_phandle(fdt, off);
- ut_assert(local_phandle);
- off = fdt_path_offset(fdt, "/test-node");
- ut_assert(off >= 0);
- test_phandle = fdt_get_phandle(fdt, off);
- ut_assert(test_phandle);
- ut_assertok(fdt_getprop_u32_by_index(fdt, "/", "test-phandle", 0,
- &val));
- ut_asserteq(test_phandle, val);
- ut_assertok(fdt_getprop_u32_by_index(fdt, "/", "test-phandle", 1,
- &val));
- ut_asserteq(local_phandle, val);
- return CMD_RET_SUCCESS;
- }
- OVERLAY_TEST(fdt_overlay_local_phandles, 0);
- int do_ut_overlay(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
- {
- struct unit_test *tests = ll_entry_start(struct unit_test,
- overlay_test);
- const int n_ents = ll_entry_count(struct unit_test, overlay_test);
- struct unit_test_state *uts;
- struct unit_test *test;
- void *fdt_base = &__dtb_test_fdt_base_begin;
- void *fdt_overlay = &__dtb_test_fdt_overlay_begin;
- void *fdt_base_copy, *fdt_overlay_copy;
- uts = calloc(1, sizeof(*uts));
- if (!uts)
- return -ENOMEM;
- ut_assertok(fdt_check_header(fdt_base));
- ut_assertok(fdt_check_header(fdt_overlay));
- fdt_base_copy = malloc(FDT_COPY_SIZE);
- if (!fdt_base_copy)
- return -ENOMEM;
- uts->priv = fdt_base_copy;
- fdt_overlay_copy = malloc(FDT_COPY_SIZE);
- if (!fdt_overlay_copy)
- return -ENOMEM;
- /*
- * Resize the FDT to 4k so that we have room to operate on
- *
- * (and relocate it since the memory might be mapped
- * read-only)
- */
- ut_assertok(fdt_open_into(fdt_base, fdt_base_copy, FDT_COPY_SIZE));
- /*
- * Resize the overlay to 4k so that we have room to operate on
- *
- * (and relocate it since the memory might be mapped
- * read-only)
- */
- ut_assertok(fdt_open_into(fdt_overlay, fdt_overlay_copy,
- FDT_COPY_SIZE));
- /* Apply the overlay */
- ut_assertok(fdt_overlay_apply(fdt_base_copy, fdt_overlay_copy));
- if (argc == 1)
- printf("Running %d environment tests\n", n_ents);
- for (test = tests; test < tests + n_ents; test++) {
- if (argc > 1 && strcmp(argv[1], test->name))
- continue;
- printf("Test: %s\n", test->name);
- uts->start = mallinfo();
- test->func(uts);
- }
- printf("Failures: %d\n", uts->fail_count);
- free(fdt_overlay_copy);
- free(fdt_base_copy);
- free(uts);
- return uts->fail_count ? CMD_RET_FAILURE : 0;
- }
|