In this patch, "setprop_reg" test program is added to test fdt_setprop_reg() interface. Signed-off-by: AKASHI Takahiro <takahiro.akashi@xxxxxxxxxx> --- tests/.gitignore | 1 + tests/Makefile.tests | 1 + tests/run_tests.sh | 5 +++ tests/setprop_reg.c | 89 ++++++++++++++++++++++++++++++++++++++++++++ tests/testdata.h | 3 ++ tests/tests.h | 3 ++ tests/testutils.c | 48 ++++++++++++++++++++++++ 7 files changed, 150 insertions(+) create mode 100644 tests/setprop_reg.c diff --git a/tests/.gitignore b/tests/.gitignore index 12af43868e09..c833f3b1f194 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -58,6 +58,7 @@ tmp.* /set_name /setprop /setprop_inplace +/setprop_reg /sized_cells /string_escapes /stringlist diff --git a/tests/Makefile.tests b/tests/Makefile.tests index b02d8bf3d15b..2fa1ccc23cbe 100644 --- a/tests/Makefile.tests +++ b/tests/Makefile.tests @@ -10,6 +10,7 @@ LIB_TESTS_L = get_mem_rsv \ notfound \ addr_size_cells \ addr_size_cells2 \ + setprop_reg \ stringlist \ setprop_inplace nop_property nop_node \ sw_tree1 sw_states \ diff --git a/tests/run_tests.sh b/tests/run_tests.sh index ca3fc867db31..5db8041872c7 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -424,6 +424,11 @@ libfdt_tests () { run_dtc_test -I dts -O dtb -o property_iterate.dtb property_iterate.dts run_test property_iterate property_iterate.dtb + run_dtc_test -I dts -O dtb -o unit-addr-without-reg.dtb unit-addr-without-reg.dts + run_test setprop_reg unit-addr-without-reg.dtb 1 1 + run_test setprop_reg unit-addr-without-reg.dtb 2 2 + run_test setprop_reg unit-addr-without-reg.dtb 2 1 + # Tests for behaviour on various sorts of corrupted trees run_test truncated_property run_test truncated_string diff --git a/tests/setprop_reg.c b/tests/setprop_reg.c new file mode 100644 index 000000000000..7b3e5f64d588 --- /dev/null +++ b/tests/setprop_reg.c @@ -0,0 +1,89 @@ +/* + * libfdt - Flat Device Tree manipulation + * Testcase for fdt_setprop_reg() + * Copyright (C) 2018 AKASHI Takahiro, Linaro Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> + +#include <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +int main(int argc, char *argv[]) +{ + void *fdt, *buf; + int offset, xac, xsc, err; + uint64_t addr, size; + + if (argc != 4) + CONFIG("Usage: %s <dtb file> <address-cells> <size-cells\n", + argv[0]); + + test_init(argc, argv); + fdt = load_blob(argv[1]); + xac = strtol(argv[2], NULL, 10); + xsc = strtol(argv[3], NULL, 10); + + buf = xmalloc(0x1000); + if (!buf) + FAIL("Couldn't allocate temporary buffer"); + err = fdt_open_into(fdt, buf, 0x1000); + if (err) + FAIL("fdt_open_into(): %s", fdt_strerror(err)); + + fdt = buf; + + /* Set up */ + err = fdt_setprop_cell(fdt, 0, "#address-cells", xac); + if (err) + FAIL("fdt_setprop_cell(\"#address-cells\"): %s", + fdt_strerror(err)); + err = fdt_setprop_cell(fdt, 0, "#size-cells", xsc); + if (err) + FAIL("fdt_setprop_cell(\"#size-cells\"): %s", + fdt_strerror(err)); + + offset = fdt_path_offset(fdt, "/node@1"); + if (offset < 0) + FAIL("Couldn't find path %s", "/node@1"); + + addr = TEST_MEMREGION_ADDR; + if (xac > 1) + addr += 0x8765432100000000; + size = TEST_MEMREGION_SIZE; + if (xsc > 1) + size += 0x0fedcba900000000; + + /* Do test */ + err = fdt_setprop_reg(fdt, offset, "prop-memregion", addr, size); + if (err) + FAIL("Failed to set \"prop-memregion\" to <0x%0*lx 0x%0*lx>: %s", + xac * 8, addr, xsc * 8, size, fdt_strerror(err)); + check_getprop_reg(fdt, offset, "prop-memregion", addr, size); + + err = fdt_setprop_reg(fdt, offset, NULL, addr, size); + if (err) + FAIL("Failed to set \"reg\"(NULL) to <0x%0*lx 0x%0*lx>: %s", + xac * 8, addr, xsc * 8, size, fdt_strerror(err)); + check_getprop_reg(fdt, offset, "reg", addr, size); + + PASS(); +} diff --git a/tests/testdata.h b/tests/testdata.h index 68dcbaceada4..387a57ced4ff 100644 --- a/tests/testdata.h +++ b/tests/testdata.h @@ -40,6 +40,9 @@ #define TEST_CHAR4 '\'' #define TEST_CHAR5 '\xff' +#define TEST_MEMREGION_ADDR 0x12345678 +#define TEST_MEMREGION_SIZE 0x9abcdef0 + #ifndef __ASSEMBLY__ extern struct fdt_header test_tree1; extern struct fdt_header truncated_property; diff --git a/tests/tests.h b/tests/tests.h index dc8120eb6d9d..8857818e4304 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -128,6 +128,9 @@ const void *check_get_prop_offset(void *fdt, int poffset, const char *in_name, check_get_prop_offset(fdt, poffset, name, sizeof(x), &x); \ }) +const void *check_getprop_reg(void *fdt, int nodeoffset, const char *name, + uint64_t addr, uint64_t size); + int nodename_eq(const char *s1, const char *s2); void vg_prepare_blob(void *fdt, size_t bufsize); void *load_blob(const char *filename); diff --git a/tests/testutils.c b/tests/testutils.c index bbfda90b9cdd..60d69a42477c 100644 --- a/tests/testutils.c +++ b/tests/testutils.c @@ -184,6 +184,54 @@ const void *check_get_prop_offset(void *fdt, int poffset, const char *exp_name, return propval; } +const void *check_getprop_reg(void *fdt, int nodeoffset, const char *name, + uint64_t addr, uint64_t size) +{ + const void *propval; + int parent, xac, xsc, buf_size, cells; + char *buf, *p; + fdt32_t val; + + parent = fdt_parent_offset(fdt, nodeoffset); + if (parent < 0) + FAIL("Couldn't find a prent node: %s", fdt_strerror(parent)); + + xac = fdt_address_cells(fdt, parent); + xsc = fdt_size_cells(fdt, parent); + + if (xac <= 0) + FAIL("Couldn't identify #address-cells: %s", + fdt_strerror(xac)); + if (xsc <= 0) + FAIL("Couldn't identify #size-cells: %s", + fdt_strerror(xsc)); + + buf_size = (xac + xsc) * sizeof(fdt32_t); + buf = malloc(buf_size); + if (!buf) + FAIL("Couldn't allocate temporary buffer"); + + p = buf; + cells = xac; + while (cells) { + val = cpu_to_fdt32(addr >> (32 * (--cells))); + memcpy(p, &val, sizeof(val)); + p += sizeof(val); + } + cells = xsc; + while (cells) { + val = cpu_to_fdt32(size >> (32 * (--cells))); + memcpy(p, &val, sizeof(val)); + p += sizeof(val); + } + + propval = check_getprop(fdt, nodeoffset, name, buf_size, + (const void *)buf); + + free(buf); + + return propval; +} int nodename_eq(const char *s1, const char *s2) { -- 2.19.1