aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorAKASHI Takahiro <takahiro.akashi@linaro.org>2019-03-27 15:15:52 +0900
committerDavid Gibson <david@gibson.dropbear.id.au>2019-03-29 12:12:29 +1100
commit7fcf8208b8a98f65ce938a64fab674add3656f27 (patch)
treeca512ab8387d896c469382e7c34e0ffb188badc5 /tests
parentae795b2db7a43f8f076a8b688761244ed0f93128 (diff)
downloaddtc-7fcf8208b8a98f65ce938a64fab674add3656f27.zip
dtc-7fcf8208b8a98f65ce938a64fab674add3656f27.tar.gz
dtc-7fcf8208b8a98f65ce938a64fab674add3656f27.tar.bz2
libfdt: add fdt_append_addrrange()
This function will append an address range property using parent node's "#address-cells" and "#size-cells" properties. It will be used in implementing kdump with kexec_file_load system call at linux kernel for arm64 once it is merged into kernel tree. Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> Message-Id: <20190327061552.17170-2-takahiro.akashi@linaro.org> [dwg: Correct a SEGV error in the testcase] Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'tests')
-rw-r--r--tests/.gitignore1
-rw-r--r--tests/Makefile.tests1
-rw-r--r--tests/appendprop_addrrange.c108
-rwxr-xr-xtests/run_tests.sh5
-rw-r--r--tests/testdata.h6
-rw-r--r--tests/tests.h3
-rw-r--r--tests/testutils.c58
7 files changed, 182 insertions, 0 deletions
diff --git a/tests/.gitignore b/tests/.gitignore
index 12af438..0bc78aa 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -8,6 +8,7 @@ tmp.*
/addr_size_cells
/addr_size_cells2
/appendprop[12]
+/appendprop_addrrange
/asm_tree_dump
/boot-cpuid
/char_literal
diff --git a/tests/Makefile.tests b/tests/Makefile.tests
index b02d8bf..b77f121 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 \
+ appendprop_addrrange \
stringlist \
setprop_inplace nop_property nop_node \
sw_tree1 sw_states \
diff --git a/tests/appendprop_addrrange.c b/tests/appendprop_addrrange.c
new file mode 100644
index 0000000..b079fba
--- /dev/null
+++ b/tests/appendprop_addrrange.c
@@ -0,0 +1,108 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_appendprop_addrrange()
+ * 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, num, i, err;
+ uint64_t addr, size;
+
+ if (argc != 5)
+ CONFIG("Usage: %s <dtb file> <address-cells> <size-cells> <num>\n",
+ argv[0]);
+
+ test_init(argc, argv);
+ fdt = load_blob(argv[1]);
+ xac = strtol(argv[2], NULL, 10);
+ xsc = strtol(argv[3], NULL, 10);
+ num = strtol(argv[4], 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 += TEST_MEMREGION_ADDR_HI;
+ size = TEST_MEMREGION_SIZE;
+ if (xsc > 1)
+ size += TEST_MEMREGION_SIZE_HI;
+
+ /*
+ * Do test
+ */
+ /* 1. repeat append's */
+ for (i = 0; i < num; i++) {
+ err = fdt_appendprop_addrrange(fdt, 0, offset,
+ "prop-memregion", addr, size);
+ if (err)
+ FAIL("Failed to append[%d] \"prop-memregion\": %s",
+ i, fdt_strerror(err));
+
+ check_getprop_addrrange(fdt, 0, offset, "prop-memregion",
+ i + 1);
+
+ addr += size;
+ size += TEST_MEMREGION_SIZE_INC;
+ }
+
+ /* 2. default property name */
+ addr = TEST_MEMREGION_ADDR;
+ if (xac > 1)
+ addr += TEST_MEMREGION_ADDR_HI;
+ size = TEST_MEMREGION_SIZE;
+ if (xsc > 1)
+ size += TEST_MEMREGION_SIZE_HI;
+
+ err = fdt_appendprop_addrrange(fdt, 0, offset, "reg", addr, size);
+ if (err)
+ FAIL("Failed to set \"reg\": %s", fdt_strerror(err));
+ check_getprop_addrrange(fdt, 0, offset, "reg", 1);
+
+ PASS();
+}
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index 04fc1e8..f6b308f 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 appendprop_addrrange unit-addr-without-reg.dtb 1 1 1
+ run_test appendprop_addrrange unit-addr-without-reg.dtb 2 2 2
+ run_test appendprop_addrrange unit-addr-without-reg.dtb 2 1 3
+
# Tests for behaviour on various sorts of corrupted trees
run_test truncated_property
run_test truncated_string
diff --git a/tests/testdata.h b/tests/testdata.h
index 68dcbac..0d08efb 100644
--- a/tests/testdata.h
+++ b/tests/testdata.h
@@ -40,6 +40,12 @@
#define TEST_CHAR4 '\''
#define TEST_CHAR5 '\xff'
+#define TEST_MEMREGION_ADDR 0x12345678
+#define TEST_MEMREGION_ADDR_HI 0x8765432100000000
+#define TEST_MEMREGION_SIZE 0x9abcdef0
+#define TEST_MEMREGION_SIZE_HI 0x0fedcba900000000
+#define TEST_MEMREGION_SIZE_INC 0x1000
+
#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 dc8120e..75735d6 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_addrrange(void *fdt, int parent, int nodeoffset,
+ const char *name, int num);
+
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 bbfda90..a250d5a 100644
--- a/tests/testutils.c
+++ b/tests/testutils.c
@@ -45,6 +45,7 @@ static inline void VALGRIND_MAKE_MEM_DEFINED(void *p, size_t len)
#include <libfdt.h>
#include "tests.h"
+#include "testdata.h"
/* For FDT_SW_MAGIC */
#include "libfdt_internal.h"
@@ -184,6 +185,63 @@ const void *check_get_prop_offset(void *fdt, int poffset, const char *exp_name,
return propval;
}
+const void *check_getprop_addrrange(void *fdt, int parent, int nodeoffset,
+ const char *name, int num)
+{
+ const void *propval;
+ int xac, xsc, buf_size, cells, i;
+ char *buf, *p;
+ uint64_t addr, size;
+ fdt32_t val;
+
+ 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) * num;
+ buf = malloc(buf_size);
+ if (!buf)
+ FAIL("Couldn't allocate temporary buffer");
+
+ /* expected value */
+ addr = TEST_MEMREGION_ADDR;
+ if (xac > 1)
+ addr += TEST_MEMREGION_ADDR_HI;
+ size = TEST_MEMREGION_SIZE;
+ if (xsc > 1)
+ size += TEST_MEMREGION_SIZE_HI;
+ for (p = buf, i = 0; i < num; i++) {
+ 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);
+ }
+
+ addr += size;
+ size += TEST_MEMREGION_SIZE_INC;
+ }
+
+ /* check */
+ propval = check_getprop(fdt, nodeoffset, name, buf_size,
+ (const void *)buf);
+
+ free(buf);
+
+ return propval;
+}
int nodename_eq(const char *s1, const char *s2)
{