aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorRafal Jaworowski <raj@FreeBSD.org>2010-02-27 20:19:06 +0000
committerRafal Jaworowski <raj@FreeBSD.org>2010-02-27 20:19:06 +0000
commitcb591ed2094735990f9316644c81ffd8534e7228 (patch)
tree8a7cdb6480d8f929c6d8fdebee38759b0f4b5a9c /tests
downloadsrc-cb591ed2094735990f9316644c81ffd8534e7228.tar.gz
src-cb591ed2094735990f9316644c81ffd8534e7228.zip
Initial import of the Device Tree Compiler (DTC) package v1.2.0.vendor/dtc/1.2.0
Obtained from: git://git.jdl.com/software/dtc.git
Notes
Notes: svn path=/vendor/dtc/dist/; revision=204431 svn path=/vendor/dtc/1.2.0/; revision=204432; tag=vendor/dtc/1.2.0
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.tests65
-rw-r--r--tests/add_subnode_with_nops.c85
-rw-r--r--tests/bad-empty-ranges.dts11
-rw-r--r--tests/bad-name-property.dts7
-rw-r--r--tests/bad-ncells.dts7
-rw-r--r--tests/bad-reg-ranges.dts12
-rw-r--r--tests/bad-string-props.dts7
-rw-r--r--tests/base01.asm175
-rw-r--r--tests/base01.cmd1
-rw-r--r--tests/base01.dts31
-rw-r--r--tests/base01.stderr6
-rw-r--r--tests/boot-cpuid.c48
-rw-r--r--tests/comments-cmp.dts16
-rw-r--r--tests/comments.dts39
-rw-r--r--tests/default-addr-size.dts7
-rw-r--r--tests/del_node.c124
-rw-r--r--tests/del_property.c91
-rw-r--r--tests/dtbs_equal_ordered.c149
-rwxr-xr-xtests/dtc-checkfails.sh33
-rwxr-xr-xtests/dtc-fatal.sh14
-rw-r--r--tests/dumptrees.c71
-rw-r--r--tests/dup-nodename.dts8
-rw-r--r--tests/dup-phandle.dts10
-rw-r--r--tests/dup-propname.dts6
-rw-r--r--tests/empty.dts2
-rw-r--r--tests/escapes.dts5
-rw-r--r--tests/find_property.c42
-rw-r--r--tests/get_mem_rsv.c49
-rw-r--r--tests/get_name.c83
-rw-r--r--tests/get_path.c89
-rw-r--r--tests/get_phandle.c58
-rw-r--r--tests/getprop.c43
-rw-r--r--tests/incbin.bin1
-rw-r--r--tests/incbin.c76
-rw-r--r--tests/incbin.dts6
-rw-r--r--tests/include0.dts1
-rw-r--r--tests/include1.dts23
-rw-r--r--tests/include2.dts1
-rw-r--r--tests/include3.dts1
-rw-r--r--tests/include4.dts1
-rw-r--r--tests/include5.dts1
-rw-r--r--tests/include6.dts1
-rw-r--r--tests/include7.dts9
-rw-r--r--tests/include8.dts1
-rw-r--r--tests/label01.dts61
-rw-r--r--tests/mangle-layout.c164
-rw-r--r--tests/mangle-layout.supp7
-rw-r--r--tests/minusone-phandle.dts7
-rw-r--r--tests/move_and_save.c76
-rw-r--r--tests/node_check_compatible.c62
-rw-r--r--tests/node_offset_by_compatible.c86
-rw-r--r--tests/node_offset_by_phandle.c64
-rw-r--r--tests/node_offset_by_prop_value.c110
-rw-r--r--tests/nonexist-label-ref.dts8
-rw-r--r--tests/nonexist-node-ref.dts8
-rw-r--r--tests/nop_node.c105
-rw-r--r--tests/nop_property.c71
-rw-r--r--tests/nopulate.c106
-rw-r--r--tests/notfound.c73
-rw-r--r--tests/obsolete-chosen-interrupt-controller.dts13
-rw-r--r--tests/open_pack.c70
-rw-r--r--tests/open_pack.supp7
-rw-r--r--tests/parent_offset.c91
-rw-r--r--tests/path-references.c83
-rw-r--r--tests/path-references.dts14
-rw-r--r--tests/path_offset.c108
-rw-r--r--tests/prop-after-subnode.dts9
-rw-r--r--tests/references.c100
-rw-r--r--tests/references.dts23
-rw-r--r--tests/references_dts0.dts21
-rw-r--r--tests/reg-ranges-root.dts8
-rw-r--r--tests/root_node.c53
-rwxr-xr-xtests/run_tests.sh346
-rw-r--r--tests/rw_tree1.c101
-rw-r--r--tests/set_name.c91
-rw-r--r--tests/setprop.c78
-rw-r--r--tests/setprop_inplace.c72
-rw-r--r--tests/string_escapes.c44
-rw-r--r--tests/subnode_offset.c88
-rw-r--r--tests/supernode_atdepth_offset.c146
-rw-r--r--tests/sw_tree1.c94
-rw-r--r--tests/test01.asm294
-rw-r--r--tests/test01.dts55
-rw-r--r--tests/test01.stderr4
-rwxr-xr-xtests/test_kernel_dts86
-rw-r--r--tests/test_tree1.dts31
-rw-r--r--tests/test_tree1_dts0.dts29
-rw-r--r--tests/testdata.h28
-rw-r--r--tests/tests.h137
-rwxr-xr-xtests/tests.sh32
-rw-r--r--tests/testutils.c240
-rw-r--r--tests/trees.S186
-rw-r--r--tests/truncated_property.c48
-rw-r--r--tests/zero-phandle.dts7
94 files changed, 5361 insertions, 0 deletions
diff --git a/tests/Makefile.tests b/tests/Makefile.tests
new file mode 100644
index 000000000000..704c95da8c59
--- /dev/null
+++ b/tests/Makefile.tests
@@ -0,0 +1,65 @@
+LIB_TESTS_L = get_mem_rsv \
+ root_node find_property subnode_offset path_offset \
+ get_name getprop get_phandle \
+ get_path supernode_atdepth_offset parent_offset \
+ node_offset_by_prop_value node_offset_by_phandle \
+ node_check_compatible node_offset_by_compatible \
+ notfound \
+ setprop_inplace nop_property nop_node \
+ sw_tree1 \
+ move_and_save mangle-layout nopulate \
+ open_pack rw_tree1 set_name setprop del_property del_node \
+ string_escapes references path-references boot-cpuid incbin \
+ dtbs_equal_ordered \
+ add_subnode_with_nops
+LIB_TESTS = $(LIB_TESTS_L:%=$(TESTS_PREFIX)%)
+
+LIBTREE_TESTS_L = truncated_property
+LIBTREE_TESTS = $(LIBTREE_TESTS_L:%=$(TESTS_PREFIX)%)
+
+TESTS = $(LIB_TESTS) $(LIBTREE_TESTS)
+
+TESTS_TREES_L = test_tree1.dtb
+TESTS_TREES = $(TESTS_TREES_L:%=$(TESTS_PREFIX)%)
+
+TESTS_TARGETS = $(TESTS) $(TESTS_TREES)
+
+TESTS_DEPFILES = $(TESTS:%=%.d) \
+ $(addprefix $(TESTS_PREFIX),testutils.d trees.d dumptrees.d)
+
+TESTS_CLEANFILES_L = *.output vglog.* vgcore.* *.dtb *.test.dts *.dtsv1 tmp.*
+TESTS_CLEANFILES = $(TESTS_CLEANFILES_L:%=$(TESTS_PREFIX)%)
+
+BIN += $(TESTS) $(TESTS_PREFIX)dumptrees
+
+.PHONY: tests
+tests: $(TESTS) $(TESTS_TREES)
+
+$(LIB_TESTS): %: $(TESTS_PREFIX)testutils.o $(LIBFDT_lib)
+
+$(LIBTREE_TESTS): %: $(TESTS_PREFIX)testutils.o $(TESTS_PREFIX)trees.o $(LIBFDT_lib)
+
+$(TESTS_PREFIX)dumptrees: $(TESTS_PREFIX)trees.o
+
+$(TESTS_TREES): $(TESTS_PREFIX)dumptrees
+ @$(VECHO) DUMPTREES
+ cd $(TESTS_PREFIX); ./dumptrees >/dev/null
+
+tests_clean:
+ @$(VECHO) CLEAN "(tests)"
+ rm -f $(STD_CLEANFILES:%=$(TESTS_PREFIX)%)
+ rm -f $(TESTS_CLEANFILES)
+
+check: tests dtc convert-dtsv0
+ cd $(TESTS_PREFIX); ./run_tests.sh
+
+checkm: tests dtc convert-dtsv0
+ cd $(TESTS_PREFIX); ./run_tests.sh -m 2>&1 | tee vglog.$$$$
+
+checkv: tests dtc convert-dtsv0
+ cd $(TESTS_PREFIX); ./run_tests.sh -v
+
+ifneq ($(DEPTARGETS),)
+-include $(TESTS_DEPFILES)
+endif
+
diff --git a/tests/add_subnode_with_nops.c b/tests/add_subnode_with_nops.c
new file mode 100644
index 000000000000..4fb8f0245523
--- /dev/null
+++ b/tests/add_subnode_with_nops.c
@@ -0,0 +1,85 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_nop_node()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <ctype.h>
+#include <stdint.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+#define SPACE 65536
+
+#define CHECK(code) \
+ { \
+ err = (code); \
+ if (err) \
+ FAIL(#code ": %s", fdt_strerror(err)); \
+ }
+
+#define OFF_CHECK(off, code) \
+ { \
+ (off) = (code); \
+ if (off < 0) \
+ FAIL(#code ": %s", fdt_strerror(off)); \
+ }
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ int err;
+ int offset;
+
+ test_init(argc, argv);
+
+ fdt = xmalloc(SPACE);
+
+ CHECK(fdt_create(fdt, SPACE));
+
+ CHECK(fdt_finish_reservemap(fdt));
+ CHECK(fdt_begin_node(fdt, ""));
+ CHECK(fdt_property_cell(fdt, "prop1", TEST_VALUE_1));
+ CHECK(fdt_property_cell(fdt, "prop2", TEST_VALUE_2));
+ CHECK(fdt_end_node(fdt));
+ CHECK(fdt_finish(fdt));
+
+ verbose_printf("Built empty tree, totalsize = %d\n",
+ fdt_totalsize(fdt));
+
+ CHECK(fdt_open_into(fdt, fdt, SPACE));
+
+ check_getprop_cell(fdt, 0, "prop1", TEST_VALUE_1);
+ check_getprop_cell(fdt, 0, "prop2", TEST_VALUE_2);
+
+ CHECK(fdt_nop_property(fdt, 0, "prop1"));
+
+ check_getprop_cell(fdt, 0, "prop2", TEST_VALUE_2);
+
+ OFF_CHECK(offset, fdt_add_subnode(fdt, 0, "subnode"));
+
+ check_getprop_cell(fdt, 0, "prop2", TEST_VALUE_2);
+
+ PASS();
+}
diff --git a/tests/bad-empty-ranges.dts b/tests/bad-empty-ranges.dts
new file mode 100644
index 000000000000..2be7bc858dae
--- /dev/null
+++ b/tests/bad-empty-ranges.dts
@@ -0,0 +1,11 @@
+/dts-v1/;
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ node {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ };
+};
diff --git a/tests/bad-name-property.dts b/tests/bad-name-property.dts
new file mode 100644
index 000000000000..4fde4bef118c
--- /dev/null
+++ b/tests/bad-name-property.dts
@@ -0,0 +1,7 @@
+/dts-v1/;
+
+/ {
+ node@0 {
+ name = "badthing";
+ };
+};
diff --git a/tests/bad-ncells.dts b/tests/bad-ncells.dts
new file mode 100644
index 000000000000..636198cbfcca
--- /dev/null
+++ b/tests/bad-ncells.dts
@@ -0,0 +1,7 @@
+/dts-v1/;
+
+/ {
+ #address-cells = "badthing";
+ #size-cells = "badthing";
+ #interrupt-cells = "badthing";
+};
diff --git a/tests/bad-reg-ranges.dts b/tests/bad-reg-ranges.dts
new file mode 100644
index 000000000000..77419f5bf76b
--- /dev/null
+++ b/tests/bad-reg-ranges.dts
@@ -0,0 +1,12 @@
+/dts-v1/;
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ node {
+ reg = <0 0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0>;
+ };
+};
diff --git a/tests/bad-string-props.dts b/tests/bad-string-props.dts
new file mode 100644
index 000000000000..396f82069cf7
--- /dev/null
+++ b/tests/bad-string-props.dts
@@ -0,0 +1,7 @@
+/dts-v1/;
+
+/ {
+ device_type = <0xdeadbeef>;
+ model = <0xdeadbeef>;
+ status = <0xdeadbeef>;
+};
diff --git a/tests/base01.asm b/tests/base01.asm
new file mode 100644
index 000000000000..266e446517e9
--- /dev/null
+++ b/tests/base01.asm
@@ -0,0 +1,175 @@
+/* autogenerated by dtc, do not edit */
+
+#define OF_DT_HEADER 0xd00dfeed
+#define OF_DT_BEGIN_NODE 0x1
+#define OF_DT_END_NODE 0x2
+#define OF_DT_PROP 0x3
+#define OF_DT_END 0x9
+
+ .globl dt_blob_start
+dt_blob_start:
+_dt_blob_start:
+ .globl dt_header
+dt_header:
+_dt_header:
+ .long OF_DT_HEADER /* magic */
+ .long _dt_blob_end - _dt_blob_start /* totalsize */
+ .long _dt_struct_start - _dt_blob_start /* off_dt_struct */
+ .long _dt_strings_start - _dt_blob_start /* off_dt_strings */
+ .long _dt_reserve_map - _dt_blob_start /* off_dt_strings */
+ .long 16 /* version */
+ .long 16 /* last_comp_version */
+ .long 0 /*boot_cpuid_phys*/
+ .long _dt_strings_end - _dt_strings_start /* size_dt_strings */
+ .balign 8
+ .globl dt_reserve_map
+dt_reserve_map:
+_dt_reserve_map:
+/* Memory reserve map from source file */
+ .long 0, 0
+ .long 0, 0
+ .globl dt_struct_start
+dt_struct_start:
+_dt_struct_start:
+ .long OF_DT_BEGIN_NODE
+ .string ""
+ .balign 4
+ .long OF_DT_PROP
+ .long 0xa
+ .long 0x0
+ .long 0x536f6d65
+ .long 0x4d6f6465
+ .short 0x6c00
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x8
+ .long 0x6
+ .long 0x4e6f7468
+ .long 0x696e6700
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x11
+ .long 0x2
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x20
+ .long 0x2
+ .balign 4
+ .long OF_DT_BEGIN_NODE
+ .string "memory@0"
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x7
+ .long 0x2c
+ .long 0x6d656d6f
+ .short 0x7279
+ .byte 0x0
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x10
+ .long 0x38
+ .long 0x0
+ .long 0x0
+ .long 0x0
+ .long 0x20000000
+ .balign 4
+ .long OF_DT_END_NODE
+ .long OF_DT_BEGIN_NODE
+ .string "cpus"
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x11
+ .long 0x1
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x20
+ .long 0x0
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x3c
+ .long 0xa
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x40
+ .long 0x17
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x44
+ .long 0x5
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x49
+ .long 0xf
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x4d
+ .long 0xd00d
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x10
+ .long 0x53
+ .long 0x4d2
+ .long 0x162e
+ .long 0x2334
+ .long 0xd80
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x59
+ .long 0x0
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x61
+ .long 0xffffffff
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x69
+ .long 0x0
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x71
+ .long 0xffffffff
+ .balign 4
+ .long OF_DT_END_NODE
+ .long OF_DT_END_NODE
+ .long OF_DT_END
+ .globl dt_struct_end
+dt_struct_end:
+_dt_struct_end:
+ .globl dt_strings_start
+dt_strings_start:
+_dt_strings_start:
+ .string "model"
+ .string "compatible"
+ .string "#address-cells"
+ .string "#size-cells"
+ .string "device_type"
+ .string "reg"
+ .string "d10"
+ .string "d23"
+ .string "b101"
+ .string "o17"
+ .string "hd00d"
+ .string "stuff"
+ .string "bad-d-1"
+ .string "bad-d-2"
+ .string "bad-o-1"
+ .string "bad-o-2"
+ .globl dt_strings_end
+dt_strings_end:
+_dt_strings_end:
+ .globl dt_blob_end
+dt_blob_end:
+_dt_blob_end:
diff --git a/tests/base01.cmd b/tests/base01.cmd
new file mode 100644
index 000000000000..e1fce6c88843
--- /dev/null
+++ b/tests/base01.cmd
@@ -0,0 +1 @@
+dtc -f -b 0 -V 16 -I dts -O asm
diff --git a/tests/base01.dts b/tests/base01.dts
new file mode 100644
index 000000000000..f84bc49620ca
--- /dev/null
+++ b/tests/base01.dts
@@ -0,0 +1,31 @@
+/ {
+ model = "SomeModel";
+ compatible = "Nothing";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ memory@0 {
+ device_type = "memory";
+ reg = <00000000 00000000 00000000 20000000>;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ d10 = <d# 10>; // hex: 0xa
+ d23 = <d# 23>; // hex: 0x17
+ b101 = <b# 101>; // hex: 0x5
+ o17 = <o# 17>; // hex: 0xf
+ hd00d = <h# d00d>; // hex: 0xd00d
+
+ // hex: 0x4d2 0x163e 0x2334 0xd80
+ stuff = <d# 1234 d# 5678 d# 9012 d# 3456>;
+
+
+ bad-d-1 = <d# abc123>; // Hrm. 0
+ bad-d-2 = <d# 123456789012345>;
+ bad-o-1 = <o# 891>;
+ bad-o-2 = <o# 123456123456>;
+ };
+
+};
diff --git a/tests/base01.stderr b/tests/base01.stderr
new file mode 100644
index 000000000000..0510b0fb4dbc
--- /dev/null
+++ b/tests/base01.stderr
@@ -0,0 +1,6 @@
+DTC: dts->asm on file "tests/base01.dts"
+Line 26: Invalid cell value '123456789012345'; -1 assumed
+Line 27: Invalid cell value '891'; 0 assumed
+Line 28: Invalid cell value '123456123456'; -1 assumed
+ERROR: Missing /chosen node
+Input tree has errors
diff --git a/tests/boot-cpuid.c b/tests/boot-cpuid.c
new file mode 100644
index 000000000000..7b5433dbacbf
--- /dev/null
+++ b/tests/boot-cpuid.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ uint32_t cpuid;
+
+ test_init(argc, argv);
+
+ if (argc != 3)
+ CONFIG("Usage: %s <dtb file> <cpuid>", argv[0]);
+
+ fdt = load_blob(argv[1]);
+ cpuid = strtoul(argv[2], NULL, 0);
+
+ if (fdt_boot_cpuid_phys(fdt) != cpuid)
+ FAIL("Incorrect boot_cpuid_phys (0x%x instead of 0x%x)",
+ fdt_boot_cpuid_phys(fdt), cpuid);
+
+ PASS();
+}
diff --git a/tests/comments-cmp.dts b/tests/comments-cmp.dts
new file mode 100644
index 000000000000..4ee9f52dc0a5
--- /dev/null
+++ b/tests/comments-cmp.dts
@@ -0,0 +1,16 @@
+/dts-v1/;
+
+/ {
+ prop1;
+ prop2;
+ prop3;
+ prop4;
+ prop5;
+ prop6;
+ prop7;
+ prop8;
+ prop9;
+ prop10;
+ child {
+ };
+};
diff --git a/tests/comments.dts b/tests/comments.dts
new file mode 100644
index 000000000000..0b04b6b88b9f
--- /dev/null
+++ b/tests/comments.dts
@@ -0,0 +1,39 @@
+/* regexps for lexing comments are.. tricky. Check if we've actually
+ * got it right */
+/dts-v1/;
+
+/ {
+ // line comment
+ prop1;
+ /* comment */
+ prop2;
+ /* multiline
+
+ notaprop1;
+
+ comment */
+ prop3;
+ /**/
+ prop4;
+ /***/
+ prop5;
+ /****/
+ prop6;
+ /* another
+ * multiline
+ * comment */
+ prop7;
+ /* yet
+ * another
+ * multline
+ * comment
+ */
+ prop8;
+ /** try this */
+ prop9;
+ /* and this **/
+ prop10;
+ child /* finally */ {
+ };
+};
+/* final comment */
diff --git a/tests/default-addr-size.dts b/tests/default-addr-size.dts
new file mode 100644
index 000000000000..e964a553fa2d
--- /dev/null
+++ b/tests/default-addr-size.dts
@@ -0,0 +1,7 @@
+/dts-v1/;
+
+/ {
+ node {
+ reg = <0 0 0>;
+ };
+};
diff --git a/tests/del_node.c b/tests/del_node.c
new file mode 100644
index 000000000000..afad5027b791
--- /dev/null
+++ b/tests/del_node.c
@@ -0,0 +1,124 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_nop_node()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <ctype.h>
+#include <stdint.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ int subnode1_offset, subnode2_offset, subsubnode2_offset;
+ int err;
+ int oldsize, delsize, newsize;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ fdt = open_blob_rw(fdt);
+
+ oldsize = fdt_totalsize(fdt);
+
+ subnode1_offset = fdt_path_offset(fdt, "/subnode@1");
+ if (subnode1_offset < 0)
+ FAIL("Couldn't find \"/subnode@1\": %s",
+ fdt_strerror(subnode1_offset));
+ check_getprop_cell(fdt, subnode1_offset, "prop-int", TEST_VALUE_1);
+
+ subnode2_offset = fdt_path_offset(fdt, "/subnode@2");
+ if (subnode2_offset < 0)
+ FAIL("Couldn't find \"/subnode@2\": %s",
+ fdt_strerror(subnode2_offset));
+ check_getprop_cell(fdt, subnode2_offset, "prop-int", TEST_VALUE_2);
+
+ subsubnode2_offset = fdt_path_offset(fdt, "/subnode@2/subsubnode");
+ if (subsubnode2_offset < 0)
+ FAIL("Couldn't find \"/subnode@2/subsubnode\": %s",
+ fdt_strerror(subsubnode2_offset));
+ check_getprop_cell(fdt, subsubnode2_offset, "prop-int", TEST_VALUE_2);
+
+ err = fdt_del_node(fdt, subnode1_offset);
+ if (err)
+ FAIL("fdt_del_node(subnode1): %s", fdt_strerror(err));
+
+ subnode1_offset = fdt_path_offset(fdt, "/subnode@1");
+ if (subnode1_offset != -FDT_ERR_NOTFOUND)
+ FAIL("fdt_path_offset(subnode1) returned \"%s\" instead of \"%s\"",
+ fdt_strerror(subnode1_offset),
+ fdt_strerror(-FDT_ERR_NOTFOUND));
+
+ subnode2_offset = fdt_path_offset(fdt, "/subnode@2");
+ if (subnode2_offset < 0)
+ FAIL("Couldn't find \"/subnode2\": %s",
+ fdt_strerror(subnode2_offset));
+ check_getprop_cell(fdt, subnode2_offset, "prop-int", TEST_VALUE_2);
+
+ subsubnode2_offset = fdt_path_offset(fdt, "/subnode@2/subsubnode");
+ if (subsubnode2_offset < 0)
+ FAIL("Couldn't find \"/subnode@2/subsubnode\": %s",
+ fdt_strerror(subsubnode2_offset));
+ check_getprop_cell(fdt, subsubnode2_offset, "prop-int", TEST_VALUE_2);
+
+ err = fdt_del_node(fdt, subnode2_offset);
+ if (err)
+ FAIL("fdt_del_node(subnode2): %s", fdt_strerror(err));
+
+ subnode1_offset = fdt_path_offset(fdt, "/subnode@1");
+ if (subnode1_offset != -FDT_ERR_NOTFOUND)
+ FAIL("fdt_path_offset(subnode1) returned \"%s\" instead of \"%s\"",
+ fdt_strerror(subnode1_offset),
+ fdt_strerror(-FDT_ERR_NOTFOUND));
+
+ subnode2_offset = fdt_path_offset(fdt, "/subnode@2");
+ if (subnode2_offset != -FDT_ERR_NOTFOUND)
+ FAIL("fdt_path_offset(subnode2) returned \"%s\" instead of \"%s\"",
+ fdt_strerror(subnode2_offset),
+ fdt_strerror(-FDT_ERR_NOTFOUND));
+
+ subsubnode2_offset = fdt_path_offset(fdt, "/subnode@2/subsubnode");
+ if (subsubnode2_offset != -FDT_ERR_NOTFOUND)
+ FAIL("fdt_path_offset(subsubnode2) returned \"%s\" instead of \"%s\"",
+ fdt_strerror(subsubnode2_offset),
+ fdt_strerror(-FDT_ERR_NOTFOUND));
+
+ delsize = fdt_totalsize(fdt);
+
+ err = fdt_pack(fdt);
+ if (err)
+ FAIL("fdt_pack(): %s", fdt_strerror(err));
+
+ newsize = fdt_totalsize(fdt);
+
+ verbose_printf("oldsize = %d, delsize = %d, newsize = %d\n",
+ oldsize, delsize, newsize);
+
+ if (newsize >= oldsize)
+ FAIL("Tree failed to shrink after deletions");
+
+ PASS();
+}
diff --git a/tests/del_property.c b/tests/del_property.c
new file mode 100644
index 000000000000..449eca6150c6
--- /dev/null
+++ b/tests/del_property.c
@@ -0,0 +1,91 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_delprop()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <ctype.h>
+#include <stdint.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ const uint32_t *intp;
+ const char *strp;
+ int err, lenerr;
+ int oldsize, delsize, newsize;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ fdt = open_blob_rw(fdt);
+
+ oldsize = fdt_totalsize(fdt);
+
+ intp = check_getprop_cell(fdt, 0, "prop-int", TEST_VALUE_1);
+ verbose_printf("int value was 0x%08x\n", *intp);
+
+ err = fdt_delprop(fdt, 0, "prop-int");
+ if (err)
+ FAIL("Failed to delete \"prop-int\": %s", fdt_strerror(err));
+
+ intp = fdt_getprop(fdt, 0, "prop-int", &lenerr);
+ if (intp)
+ FAIL("prop-int still present after deletion");
+ if (lenerr != -FDT_ERR_NOTFOUND)
+ FAIL("Unexpected error on second getprop: %s",
+ fdt_strerror(lenerr));
+
+ strp = check_getprop(fdt, 0, "prop-str", strlen(TEST_STRING_1)+1,
+ TEST_STRING_1);
+ verbose_printf("string value was \"%s\"\n", strp);
+ err = fdt_delprop(fdt, 0, "prop-str");
+ if (err)
+ FAIL("Failed to delete \"prop-str\": %s", fdt_strerror(err));
+
+ strp = fdt_getprop(fdt, 0, "prop-str", &lenerr);
+ if (strp)
+ FAIL("prop-str still present after deletion");
+ if (lenerr != -FDT_ERR_NOTFOUND)
+ FAIL("Unexpected error on second getprop: %s",
+ fdt_strerror(lenerr));
+
+ delsize = fdt_totalsize(fdt);
+
+ err = fdt_pack(fdt);
+ if (err)
+ FAIL("fdt_pack(): %s\n", fdt_strerror(err));
+
+ newsize = fdt_totalsize(fdt);
+
+ verbose_printf("oldsize = %d, delsize = %d, newsize = %d\n",
+ oldsize, delsize, newsize);
+
+ if (newsize >= oldsize)
+ FAIL("Tree failed to shrink after deletions");
+
+ PASS();
+}
diff --git a/tests/dtbs_equal_ordered.c b/tests/dtbs_equal_ordered.c
new file mode 100644
index 000000000000..a0b42aecc7e0
--- /dev/null
+++ b/tests/dtbs_equal_ordered.c
@@ -0,0 +1,149 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Tests if two given dtbs are structurally equal (including order)
+ * Copyright (C) 2007 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+void compare_mem_rsv(const void *fdt1, const void *fdt2)
+{
+ int i;
+ uint64_t addr1, size1, addr2, size2;
+ int err;
+
+ if (fdt_num_mem_rsv(fdt1) != fdt_num_mem_rsv(fdt2))
+ FAIL("Trees have different number of reserve entries");
+ for (i = 0; i < fdt_num_mem_rsv(fdt1); i++) {
+ err = fdt_get_mem_rsv(fdt1, i, &addr1, &size1);
+ if (err)
+ FAIL("fdt_get_mem_rsv(fdt1, %d, ...): %s", i,
+ fdt_strerror(err));
+ err = fdt_get_mem_rsv(fdt2, i, &addr2, &size2);
+ if (err)
+ FAIL("fdt_get_mem_rsv(fdt2, %d, ...): %s", i,
+ fdt_strerror(err));
+ if ((addr1 != addr2) || (size1 != size2))
+ FAIL("Mismatch in reserve entry %d: "
+ "(0x%llx, 0x%llx) != (0x%llx, 0x%llx)", i,
+ (unsigned long long)addr1,
+ (unsigned long long)size1,
+ (unsigned long long)addr2,
+ (unsigned long long)size2);
+ }
+}
+
+void compare_structure(const void *fdt1, const void *fdt2)
+{
+ int nextoffset1 = 0, nextoffset2 = 0;
+ int offset1, offset2;
+ uint32_t tag1, tag2;
+ const char *name1, *name2;
+ int err;
+ const struct fdt_property *prop1, *prop2;
+ int len1, len2;
+
+ while (1) {
+ do {
+ offset1 = nextoffset1;
+ tag1 = fdt_next_tag(fdt1, offset1, &nextoffset1);
+ } while (tag1 == FDT_NOP);
+ do {
+ offset2 = nextoffset2;
+ tag2 = fdt_next_tag(fdt2, offset2, &nextoffset2);
+ } while (tag2 == FDT_NOP);
+
+ if (tag1 != tag2)
+ FAIL("Tag mismatch (%d != %d) at (%d, %d)",
+ tag1, tag2, offset1, offset2);
+
+ switch (tag1) {
+ case FDT_BEGIN_NODE:
+ name1 = fdt_get_name(fdt1, offset1, &err);
+ if (!name1)
+ FAIL("fdt_get_name(fdt1, %d, ..): %s",
+ offset1, fdt_strerror(err));
+ name2 = fdt_get_name(fdt2, offset2, NULL);
+ if (!name2)
+ FAIL("fdt_get_name(fdt2, %d, ..): %s",
+ offset2, fdt_strerror(err));
+ if (!streq(name1, name2))
+ FAIL("Name mismatch (\"%s\" != \"%s\") at (%d, %d)",
+ name1, name2, offset1, offset2);
+ break;
+
+ case FDT_PROP:
+ prop1 = fdt_offset_ptr(fdt1, offset1, sizeof(*prop1));
+ if (!prop1)
+ FAIL("Could get fdt1 property at %d", offset1);
+ prop2 = fdt_offset_ptr(fdt2, offset2, sizeof(*prop2));
+ if (!prop2)
+ FAIL("Could get fdt2 property at %d", offset2);
+
+ name1 = fdt_string(fdt1, fdt32_to_cpu(prop1->nameoff));
+ name2 = fdt_string(fdt2, fdt32_to_cpu(prop2->nameoff));
+ if (!streq(name1, name2))
+ FAIL("Property name mismatch \"%s\" != \"%s\" "
+ "at (%d, %d)", name1, name2, offset1, offset2);
+ len1 = fdt32_to_cpu(prop1->len);
+ len2 = fdt32_to_cpu(prop2->len);
+ if (len1 != len2)
+ FAIL("Property length mismatch %u != %u "
+ "at (%d, %d)", len1, len2, offset1, offset2);
+
+ if (memcmp(prop1->data, prop2->data, len1) != 0)
+ FAIL("Property value mismatch at (%d, %d)",
+ offset1, offset2);
+ break;
+
+ case FDT_END:
+ return;
+ }
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ void *fdt1, *fdt2;
+ uint32_t cpuid1, cpuid2;
+
+ test_init(argc, argv);
+ if (argc != 3)
+ CONFIG("Usage: %s <dtb file> <dtb file>", argv[0]);
+ fdt1 = load_blob(argv[1]);
+ fdt2 = load_blob(argv[2]);
+
+ compare_mem_rsv(fdt1, fdt2);
+ compare_structure(fdt1, fdt2);
+
+ cpuid1 = fdt_boot_cpuid_phys(fdt1);
+ cpuid2 = fdt_boot_cpuid_phys(fdt2);
+ if (cpuid1 != cpuid2)
+ FAIL("boot_cpuid_phys mismatch 0x%x != 0x%x",
+ cpuid1, cpuid2);
+
+ PASS();
+}
diff --git a/tests/dtc-checkfails.sh b/tests/dtc-checkfails.sh
new file mode 100755
index 000000000000..c58694fc7bbb
--- /dev/null
+++ b/tests/dtc-checkfails.sh
@@ -0,0 +1,33 @@
+#! /bin/sh
+
+. ./tests.sh
+
+for x; do
+ shift
+ if [ "$x" = "--" ]; then
+ break;
+ fi
+ CHECKS="$CHECKS $x"
+done
+
+LOG="tmp.log.$$"
+
+rm -f $TMPFILE $LOG
+
+verbose_run_log "$LOG" $VALGRIND "$DTC" -o /dev/null "$@"
+ret="$?"
+
+if [ "$ret" -gt 127 ]; then
+ signame=$(kill -l $[ret - 128])
+ FAIL "Killed by SIG$signame"
+fi
+
+for c in $CHECKS; do
+ if ! grep -E "^(ERROR)|(Warning) \($c\):" $LOG > /dev/null; then
+ FAIL "Failed to trigger check \"$c\""
+ fi
+done
+
+rm -f $LOG
+
+PASS
diff --git a/tests/dtc-fatal.sh b/tests/dtc-fatal.sh
new file mode 100755
index 000000000000..6781ced9a670
--- /dev/null
+++ b/tests/dtc-fatal.sh
@@ -0,0 +1,14 @@
+#! /bin/sh
+
+. ./tests.sh
+
+verbose_run $VALGRIND "$DTC" -o/dev/null "$@"
+ret="$?"
+
+if [ "$ret" -gt 127 ]; then
+ FAIL "dtc killed by signal (ret=$ret)"
+elif [ "$ret" != "1" ]; then
+ FAIL "dtc returned incorrect status $ret instead of 1"
+fi
+
+PASS
diff --git a/tests/dumptrees.c b/tests/dumptrees.c
new file mode 100644
index 000000000000..fa1f56368413
--- /dev/null
+++ b/tests/dumptrees.c
@@ -0,0 +1,71 @@
+/*
+ * dumptrees - utility for libfdt testing
+ *
+ * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2006.
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdint.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+#include <libfdt_env.h>
+
+#include "testdata.h"
+
+struct {
+ void *blob;
+ const char *filename;
+} trees[] = {
+#define TREE(name) { &_##name, #name ".dtb" }
+ TREE(test_tree1),
+ TREE(bad_node_char), TREE(bad_node_format), TREE(bad_prop_char),
+};
+
+#define NUM_TREES (sizeof(trees) / sizeof(trees[0]))
+
+int main(int argc, char *argv[])
+{
+ int i;
+
+ for (i = 0; i < NUM_TREES; i++) {
+ void *blob = trees[i].blob;
+ const char *filename = trees[i].filename;
+ int size;
+ int fd;
+ int ret;
+
+ size = fdt_totalsize(blob);
+
+ printf("Tree \"%s\", %d bytes\n", filename, size);
+
+ fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (fd < 0)
+ perror("open()");
+
+ ret = write(fd, blob, size);
+ if (ret != size)
+ perror("write()");
+
+ close(fd);
+ }
+ exit(0);
+}
diff --git a/tests/dup-nodename.dts b/tests/dup-nodename.dts
new file mode 100644
index 000000000000..2a3aa7596b9c
--- /dev/null
+++ b/tests/dup-nodename.dts
@@ -0,0 +1,8 @@
+/dts-v1/;
+
+/ {
+ node {
+ };
+ node {
+ };
+};
diff --git a/tests/dup-phandle.dts b/tests/dup-phandle.dts
new file mode 100644
index 000000000000..c266c6127bcc
--- /dev/null
+++ b/tests/dup-phandle.dts
@@ -0,0 +1,10 @@
+/dts-v1/;
+
+/ {
+ node1 {
+ linux,phandle = <1>;
+ };
+ node2 {
+ linux,phandle = <1>;
+ };
+};
diff --git a/tests/dup-propname.dts b/tests/dup-propname.dts
new file mode 100644
index 000000000000..8145f6e9d81d
--- /dev/null
+++ b/tests/dup-propname.dts
@@ -0,0 +1,6 @@
+/dts-v1/;
+
+/ {
+ prop;
+ prop;
+};
diff --git a/tests/empty.dts b/tests/empty.dts
new file mode 100644
index 000000000000..336d7a250678
--- /dev/null
+++ b/tests/empty.dts
@@ -0,0 +1,2 @@
+/ {
+};
diff --git a/tests/escapes.dts b/tests/escapes.dts
new file mode 100644
index 000000000000..f1b8dbc8409f
--- /dev/null
+++ b/tests/escapes.dts
@@ -0,0 +1,5 @@
+/ {
+ compatible = "test_string_escapes";
+ escape-str = "nastystring: \a\b\t\n\v\f\r\\\"";
+ escape-str-2 = "\xde\xad\xbe\xef";
+};
diff --git a/tests/find_property.c b/tests/find_property.c
new file mode 100644
index 000000000000..74a696587c32
--- /dev/null
+++ b/tests/find_property.c
@@ -0,0 +1,42 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_property_offset()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ check_property_cell(fdt, 0, "prop-int", TEST_VALUE_1);
+ check_property(fdt, 0, "prop-str", strlen(TEST_STRING_1)+1, TEST_STRING_1);
+
+ PASS();
+}
diff --git a/tests/get_mem_rsv.c b/tests/get_mem_rsv.c
new file mode 100644
index 000000000000..554c78868f94
--- /dev/null
+++ b/tests/get_mem_rsv.c
@@ -0,0 +1,49 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_get_mem_rsv() and fdt_num_mem_rsv()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ int rc;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ rc = fdt_num_mem_rsv(fdt);
+ if (rc < 0)
+ FAIL("fdt_num_mem_rsv(): %s", fdt_strerror(rc));
+ if (rc != 2)
+ FAIL("fdt_num_mem_rsv() returned %d instead of 2", rc);
+
+ check_mem_rsv(fdt, 0, TEST_ADDR_1, TEST_SIZE_1);
+ check_mem_rsv(fdt, 1, TEST_ADDR_2, TEST_SIZE_2);
+ PASS();
+}
diff --git a/tests/get_name.c b/tests/get_name.c
new file mode 100644
index 000000000000..22003b4703ef
--- /dev/null
+++ b/tests/get_name.c
@@ -0,0 +1,83 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_get_name()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+void check_name(void *fdt, const char *path)
+{
+ int offset;
+ const char *getname, *getname2, *checkname;
+ int len;
+
+ checkname = strrchr(path, '/');
+ if (!checkname)
+ TEST_BUG();
+ checkname += 1;
+
+ offset = fdt_path_offset(fdt, path);
+ if (offset < 0)
+ FAIL("Couldn't find %s", path);
+
+ getname = fdt_get_name(fdt, offset, &len);
+ verbose_printf("fdt_get_name(%d) returns \"%s\" (len=%d)\n",
+ offset, getname, len);
+ if (!getname)
+ FAIL("fdt_get_name(%d): %s", offset, fdt_strerror(len));
+
+ if (strcmp(getname, checkname) != 0)
+ FAIL("fdt_get_name(%s) returned \"%s\" instead of \"%s\"",
+ path, getname, checkname);
+
+ if (len != strlen(getname))
+ FAIL("fdt_get_name(%s) returned length %d instead of %zd",
+ path, len, strlen(getname));
+
+ /* Now check that it doesn't break if we omit len */
+ getname2 = fdt_get_name(fdt, offset, NULL);
+ if (!getname2)
+ FAIL("fdt_get_name(%d, NULL) failed", offset);
+ if (strcmp(getname2, getname) != 0)
+ FAIL("fdt_get_name(%d, NULL) returned \"%s\" instead of \"%s\"",
+ offset, getname2, getname);
+}
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ check_name(fdt, "/");
+ check_name(fdt, "/subnode@1");
+ check_name(fdt, "/subnode@2");
+ check_name(fdt, "/subnode@1/subsubnode");
+ check_name(fdt, "/subnode@2/subsubnode@0");
+
+ PASS();
+}
diff --git a/tests/get_path.c b/tests/get_path.c
new file mode 100644
index 000000000000..0d208bb020af
--- /dev/null
+++ b/tests/get_path.c
@@ -0,0 +1,89 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_get_path()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+#define POISON ('\xff')
+
+void check_path_buf(void *fdt, const char *path, int pathlen, int buflen)
+{
+ int offset;
+ char buf[buflen+1];
+ int len;
+
+ offset = fdt_path_offset(fdt, path);
+ if (offset < 0)
+ FAIL("Couldn't find path \"%s\": %s", path, fdt_strerror(offset));
+
+ memset(buf, POISON, sizeof(buf)); /* poison the buffer */
+
+ len = fdt_get_path(fdt, offset, buf, buflen);
+ if (buflen <= pathlen) {
+ if (len != -FDT_ERR_NOSPACE)
+ FAIL("fdt_get_path([%d bytes]) returns %d with "
+ "insufficient buffer space", buflen, len);
+ } else {
+ if (len < 0)
+ FAIL("fdt_get_path([%d bytes]): %s", buflen,
+ fdt_strerror(len));
+ if (len != pathlen)
+ FAIL("fdt_get_path([%d bytes]) reports length %d "
+ "instead of %d", buflen, len, pathlen);
+ if (strcmp(buf, path) != 0)
+ FAIL("fdt_get_path([%d bytes]) returns \"%s\" "
+ "instead of \"%s\"", buflen, buf, path);
+ }
+
+ if (buf[buflen] != POISON)
+ FAIL("fdt_get_path([%d bytes]) overran buffer", buflen);
+}
+
+void check_path(void *fdt, const char *path)
+{
+ int pathlen = strlen(path);
+
+ check_path_buf(fdt, path, pathlen, 1024);
+ check_path_buf(fdt, path, pathlen, pathlen+1);
+ check_path_buf(fdt, path, pathlen, pathlen);
+}
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ check_path(fdt, "/");
+ check_path(fdt, "/subnode@1");
+ check_path(fdt, "/subnode@2");
+ check_path(fdt, "/subnode@1/subsubnode");
+ check_path(fdt, "/subnode@2/subsubnode@0");
+
+ PASS();
+}
diff --git a/tests/get_phandle.c b/tests/get_phandle.c
new file mode 100644
index 000000000000..f7650b85b0f2
--- /dev/null
+++ b/tests/get_phandle.c
@@ -0,0 +1,58 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_get_phandle()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+void check_phandle(void *fdt, const char *path, uint32_t checkhandle)
+{
+ int offset;
+ uint32_t phandle;
+
+ offset = fdt_path_offset(fdt, path);
+ if (offset < 0)
+ FAIL("Couldn't find %s", path);
+
+ phandle = fdt_get_phandle(fdt, offset);
+ if (phandle != checkhandle)
+ FAIL("fdt_get_phandle(%s) returned 0x%x instead of 0x%x\n",
+ path, phandle, checkhandle);
+}
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ check_phandle(fdt, "/", 0);
+ check_phandle(fdt, "/subnode@2", PHANDLE_1);
+ check_phandle(fdt, "/subnode@2/subsubnode@0", PHANDLE_2);
+
+ PASS();
+}
diff --git a/tests/getprop.c b/tests/getprop.c
new file mode 100644
index 000000000000..239856e7c958
--- /dev/null
+++ b/tests/getprop.c
@@ -0,0 +1,43 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_getprop()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ check_getprop_cell(fdt, 0, "prop-int", TEST_VALUE_1);
+ check_getprop(fdt, 0, "prop-str", strlen(TEST_STRING_1)+1, TEST_STRING_1);
+
+ PASS();
+}
diff --git a/tests/incbin.bin b/tests/incbin.bin
new file mode 100644
index 000000000000..e6e3e48d40bb
--- /dev/null
+++ b/tests/incbin.bin
@@ -0,0 +1 @@
+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ \ No newline at end of file
diff --git a/tests/incbin.c b/tests/incbin.c
new file mode 100644
index 000000000000..5ab35082e939
--- /dev/null
+++ b/tests/incbin.c
@@ -0,0 +1,76 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for string escapes in dtc
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <errno.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+#define CHUNKSIZE 1024
+
+char *load_file(const char *name, int *len)
+{
+ FILE *f;
+ char *buf = NULL;
+ int bufsize = 0, n;
+
+ *len = 0;
+
+ f = fopen(name, "r");
+ if (!f)
+ FAIL("Couldn't open \"%s\": %s", name, strerror(errno));
+
+ while (!feof(f)) {
+ if (bufsize < (*len + CHUNKSIZE)) {
+ buf = xrealloc(buf, *len + CHUNKSIZE);
+ bufsize = *len + CHUNKSIZE;
+ }
+
+ n = fread(buf + *len, 1, CHUNKSIZE, f);
+ if (ferror(f))
+ FAIL("Error reading \"%s\": %s", name, strerror(errno));
+ *len += n;
+ }
+
+ return buf;
+}
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ char *incbin;
+ int len;
+
+ test_init(argc, argv);
+
+ incbin = load_file("incbin.bin", &len);
+ fdt = load_blob_arg(argc, argv);
+
+ check_getprop(fdt, 0, "incbin", len, incbin);
+ check_getprop(fdt, 0, "incbin-partial", 17, incbin + 13);
+
+ PASS();
+}
diff --git a/tests/incbin.dts b/tests/incbin.dts
new file mode 100644
index 000000000000..7c30e0ec47ed
--- /dev/null
+++ b/tests/incbin.dts
@@ -0,0 +1,6 @@
+/dts-v1/;
+
+/ {
+ incbin = /incbin/("incbin.bin");
+ incbin-partial = /incbin/("incbin.bin", 13, 17);
+};
diff --git a/tests/include0.dts b/tests/include0.dts
new file mode 100644
index 000000000000..355ed6a924d5
--- /dev/null
+++ b/tests/include0.dts
@@ -0,0 +1 @@
+/include/ "include1.dts"
diff --git a/tests/include1.dts b/tests/include1.dts
new file mode 100644
index 000000000000..0c7f42e03fab
--- /dev/null
+++ b/tests/include1.dts
@@ -0,0 +1,23 @@
+/dts-v1/;
+
+/include/ "include2.dts"
+/memreserve/ /include/ "include3.dts";
+
+/ {
+ /include/ "include4.dts"
+ /include/ "include5.dts" = <0xdeadbeef>;
+ prop-str = /include/ "include6.dts";
+
+ /include/ "include7.dts"
+
+ subnode@2 {
+ linux,phandle = <0x2000>;
+ prop-int = <123456789>;
+
+ /include/ "include8.dts"
+ linux,phandle = <0x2001>;
+ compatible = "subsubnode2", "subsubnode";
+ prop-int = <0726746425>;
+ };
+ };
+};
diff --git a/tests/include2.dts b/tests/include2.dts
new file mode 100644
index 000000000000..7e189dd778f1
--- /dev/null
+++ b/tests/include2.dts
@@ -0,0 +1 @@
+/memreserve/ 0xdeadbeef00000000 0x100000;
diff --git a/tests/include3.dts b/tests/include3.dts
new file mode 100644
index 000000000000..ee9d277aac5e
--- /dev/null
+++ b/tests/include3.dts
@@ -0,0 +1 @@
+123456789 010000
diff --git a/tests/include4.dts b/tests/include4.dts
new file mode 100644
index 000000000000..b2ddbe5a072e
--- /dev/null
+++ b/tests/include4.dts
@@ -0,0 +1 @@
+ compatible = "test_tree1";
diff --git a/tests/include5.dts b/tests/include5.dts
new file mode 100644
index 000000000000..9a35dc54eaa3
--- /dev/null
+++ b/tests/include5.dts
@@ -0,0 +1 @@
+prop-int
diff --git a/tests/include6.dts b/tests/include6.dts
new file mode 100644
index 000000000000..cd4bc1ab64cc
--- /dev/null
+++ b/tests/include6.dts
@@ -0,0 +1 @@
+"hello world"
diff --git a/tests/include7.dts b/tests/include7.dts
new file mode 100644
index 000000000000..fa726f9c3b9e
--- /dev/null
+++ b/tests/include7.dts
@@ -0,0 +1,9 @@
+ subnode@1 {
+ compatible = "subnode1";
+ prop-int = [deadbeef];
+
+ subsubnode {
+ compatible = "subsubnode1", "subsubnode";
+ prop-int = <0xdeadbeef>;
+ };
+ };
diff --git a/tests/include8.dts b/tests/include8.dts
new file mode 100644
index 000000000000..ec7006437657
--- /dev/null
+++ b/tests/include8.dts
@@ -0,0 +1 @@
+subsubnode@0 { \ No newline at end of file
diff --git a/tests/label01.dts b/tests/label01.dts
new file mode 100644
index 000000000000..372b17aa486d
--- /dev/null
+++ b/tests/label01.dts
@@ -0,0 +1,61 @@
+/memreserve/ 1000000000000000 0000000002000000;
+memrsv2: /memreserve/ 2000000000000000-20ffffffffffffff;
+/memreserve/ 0-13;
+
+/ {
+ model = "MyBoardName";
+ compatible = "MyBoardName", "MyBoardFamilyName";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ linux,phandle = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ PowerPC,970@0 {
+ name = "PowerPC,970";
+ device_type = "cpu";
+ reg = <0>;
+ clock-frequency = <5f5e1000>;
+ timebase-frequency = <1FCA055>;
+ linux,boot-cpu;
+ i-cache-size = <10000>;
+ d-cache-size = <8000>;
+ };
+
+ PowerPC,970@1 {
+ name = "PowerPC,970";
+ device_type = "cpu";
+ reg = <1>;
+ clock-frequency = <5f5e1000>;
+ timebase-frequency = <1FCA055>;
+ i-cache-size = <10000>;
+ d-cache-size = <8000>;
+ };
+
+ };
+
+ node: randomnode {
+ prop: string = str: "foo", str_mid: "stuffstuff\t\t\t\n\n\n" str_end: ;
+ blob = [byte: 0a 0b 0c 0d byte_mid: de ea ad be ef byte_end: ];
+ ref = < cell: &/memory@0 0 cell_mid: ffffffff cell_end: >;
+ mixed = "abc", pre: [1234] post: , gap: < aligned: a b c>;
+ tricky1 = [61 lt1: 62 63 00];
+ subnode: child {
+ };
+ /* subnode_end: is auto-generated by node emit */
+ };
+ /* node_end: is auto-generated by node emit */
+
+ memory@0 {
+ device_type = "memory";
+ memreg: reg = <00000000 00000000 00000000 20000000>;
+ };
+
+ chosen {
+ bootargs = "root=/dev/sda2";
+ linux,platform = <00000600>;
+ };
+
+};
+
diff --git a/tests/mangle-layout.c b/tests/mangle-layout.c
new file mode 100644
index 000000000000..bd6ac406943c
--- /dev/null
+++ b/tests/mangle-layout.c
@@ -0,0 +1,164 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase/tool for rearranging blocks of a dtb
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <limits.h>
+#include <stdint.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+struct bufstate {
+ char *buf;
+ int size;
+};
+
+void expand_buf(struct bufstate *buf, int newsize)
+{
+ buf->buf = realloc(buf->buf, newsize);
+ if (!buf->buf)
+ CONFIG("Allocation failure");
+ buf->size = newsize;
+}
+
+void new_header(struct bufstate *buf, int version, const void *fdt)
+{
+ int hdrsize;
+
+ if (version == 16)
+ hdrsize = FDT_V16_SIZE;
+ else if (version == 17)
+ hdrsize = FDT_V17_SIZE;
+ else
+ CONFIG("Bad version %d", version);
+
+ expand_buf(buf, hdrsize);
+ memset(buf->buf, 0, hdrsize);
+
+ fdt_set_magic(buf->buf, FDT_MAGIC);
+ fdt_set_version(buf->buf, version);
+ fdt_set_last_comp_version(buf->buf, 16);
+ fdt_set_boot_cpuid_phys(buf->buf, fdt_boot_cpuid_phys(fdt));
+}
+
+void add_block(struct bufstate *buf, int version, char block, const void *fdt)
+{
+ int align, size;
+ const void *src;
+ int offset;
+
+ switch (block) {
+ case 'm':
+ /* Memory reserve map */
+ align = 8;
+ src = (const char *)fdt + fdt_off_mem_rsvmap(fdt);
+ size = (fdt_num_mem_rsv(fdt) + 1)
+ * sizeof(struct fdt_reserve_entry);
+ break;
+
+ case 't':
+ /* Structure block */
+ align = 4;
+ src = (const char *)fdt + fdt_off_dt_struct(fdt);
+ size = fdt_size_dt_struct(fdt);
+ break;
+
+ case 's':
+ /* Strings block */
+ align = 1;
+ src = (const char *)fdt + fdt_off_dt_strings(fdt);
+ size = fdt_size_dt_strings(fdt);
+ break;
+ default:
+ CONFIG("Bad block '%c'", block);
+ }
+
+ offset = ALIGN(buf->size, align);
+
+ expand_buf(buf, offset+size);
+
+ memcpy(buf->buf + offset, src, size);
+
+ switch (block) {
+ case 'm':
+ fdt_set_off_mem_rsvmap(buf->buf, offset);
+ break;
+
+ case 't':
+ fdt_set_off_dt_struct(buf->buf, offset);
+ if (version >= 17)
+ fdt_set_size_dt_struct(buf->buf, size);
+ break;
+
+ case 's':
+ fdt_set_off_dt_strings(buf->buf, offset);
+ fdt_set_size_dt_strings(buf->buf, size);
+ break;
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ int version;
+ const char *blockorder;
+ struct bufstate buf = {NULL, 0};
+ int err;
+ const char *inname;
+ char outname[PATH_MAX];
+
+ test_init(argc, argv);
+ if (argc != 4)
+ CONFIG("Usage: %s <dtb file> <version> <block order>", argv[0]);
+
+ inname = argv[1];
+ fdt = load_blob(argv[1]);
+ version = atoi(argv[2]);
+ blockorder = argv[3];
+ sprintf(outname, "v%d.%s.%s", version, blockorder, inname);
+
+ if ((version != 16) && (version != 17))
+ CONFIG("Version must be 16 or 17");
+
+ if (fdt_version(fdt) < 17)
+ CONFIG("Input tree must be v17");
+
+ new_header(&buf, version, fdt);
+
+ while (*blockorder) {
+ add_block(&buf, version, *blockorder, fdt);
+ blockorder++;
+ }
+
+ fdt_set_totalsize(buf.buf, buf.size);
+
+ err = fdt_check_header(buf.buf);
+ if (err)
+ FAIL("Output tree fails check: %s", fdt_strerror(err));
+
+ save_blob(outname, buf.buf);
+
+ PASS();
+}
diff --git a/tests/mangle-layout.supp b/tests/mangle-layout.supp
new file mode 100644
index 000000000000..289042042edc
--- /dev/null
+++ b/tests/mangle-layout.supp
@@ -0,0 +1,7 @@
+{
+ uninitialized alignment gaps can be dumped to output
+ Memcheck:Param
+ write(buf)
+ obj:/lib/ld-*.so
+ fun:main
+}
diff --git a/tests/minusone-phandle.dts b/tests/minusone-phandle.dts
new file mode 100644
index 000000000000..21d99867a239
--- /dev/null
+++ b/tests/minusone-phandle.dts
@@ -0,0 +1,7 @@
+/dts-v1/;
+
+/ {
+ node {
+ linux,phandle = <0xffffffff>;
+ };
+};
diff --git a/tests/move_and_save.c b/tests/move_and_save.c
new file mode 100644
index 000000000000..410ccb3be715
--- /dev/null
+++ b/tests/move_and_save.c
@@ -0,0 +1,76 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Basic testcase for read-only access
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <limits.h>
+#include <stdint.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int main(int argc, char *argv[])
+{
+ void *fdt, *fdt1, *fdt2, *fdt3;
+ char *buf;
+ int shuntsize;
+ int bufsize;
+ int err;
+ const char *inname;
+ char outname[PATH_MAX];
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+ inname = argv[1];
+
+ shuntsize = ALIGN(fdt_totalsize(fdt) / 2, sizeof(uint64_t));
+ bufsize = fdt_totalsize(fdt) + shuntsize;
+ buf = xmalloc(bufsize);
+
+ fdt1 = buf;
+ err = fdt_move(fdt, fdt1, bufsize);
+ if (err)
+ FAIL("Failed to move tree into new buffer: %s",
+ fdt_strerror(err));
+ sprintf(outname, "moved.%s", inname);
+ save_blob(outname, fdt1);
+
+ fdt2 = buf + shuntsize;
+ err = fdt_move(fdt1, fdt2, bufsize-shuntsize);
+ if (err)
+ FAIL("Failed to shunt tree %d bytes: %s",
+ shuntsize, fdt_strerror(err));
+ sprintf(outname, "shunted.%s", inname);
+ save_blob(outname, fdt2);
+
+ fdt3 = buf;
+ err = fdt_move(fdt2, fdt3, bufsize);
+ if (err)
+ FAIL("Failed to deshunt tree %d bytes: %s",
+ shuntsize, fdt_strerror(err));
+ sprintf(outname, "deshunted.%s", inname);
+ save_blob(outname, fdt3);
+
+ PASS();
+}
diff --git a/tests/node_check_compatible.c b/tests/node_check_compatible.c
new file mode 100644
index 000000000000..04b6b4083769
--- /dev/null
+++ b/tests/node_check_compatible.c
@@ -0,0 +1,62 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_node_check_compatible()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+void check_compatible(const void *fdt, const char *path, const char *compat)
+{
+ int offset, err;
+
+ offset = fdt_path_offset(fdt, path);
+ if (offset < 0)
+ FAIL("fdt_path_offset(%s): %s", path, fdt_strerror(offset));
+
+ err = fdt_node_check_compatible(fdt, offset, compat);
+ if (err < 0)
+ FAIL("fdt_node_check_compatible(%s): %s", path,
+ fdt_strerror(err));
+ if (err != 0)
+ FAIL("%s is not compatible with \"%s\"", path, compat);
+}
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ check_compatible(fdt, "/", "test_tree1");
+ check_compatible(fdt, "/subnode@1/subsubnode", "subsubnode1");
+ check_compatible(fdt, "/subnode@1/subsubnode", "subsubnode");
+ check_compatible(fdt, "/subnode@2/subsubnode", "subsubnode2");
+ check_compatible(fdt, "/subnode@2/subsubnode", "subsubnode");
+
+ PASS();
+}
diff --git a/tests/node_offset_by_compatible.c b/tests/node_offset_by_compatible.c
new file mode 100644
index 000000000000..02e9874bb7be
--- /dev/null
+++ b/tests/node_offset_by_compatible.c
@@ -0,0 +1,86 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_node_offset_by_compatible()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <stdarg.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+void check_search(void *fdt, const char *compat, ...)
+{
+ va_list ap;
+ int offset = -1, target;
+
+ va_start(ap, compat);
+ do {
+ target = va_arg(ap, int);
+ verbose_printf("Searching (target = %d): %d ->",
+ target, offset);
+ offset = fdt_node_offset_by_compatible(fdt, offset, compat);
+ verbose_printf("%d\n", offset);
+
+ if (offset != target)
+ FAIL("fdt_node_offset_by_compatible(%s) returns %d "
+ "instead of %d", compat, offset, target);
+ } while (target >= 0);
+
+ va_end(ap);
+}
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ int subnode1_offset, subnode2_offset;
+ int subsubnode1_offset, subsubnode2_offset;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ subnode1_offset = fdt_path_offset(fdt, "/subnode@1");
+ subnode2_offset = fdt_path_offset(fdt, "/subnode@2");
+ subsubnode1_offset = fdt_path_offset(fdt, "/subnode@1/subsubnode");
+ subsubnode2_offset = fdt_path_offset(fdt, "/subnode@2/subsubnode@0");
+
+ if ((subnode1_offset < 0) || (subnode2_offset < 0)
+ || (subsubnode1_offset < 0) || (subsubnode2_offset < 0))
+ FAIL("Can't find required nodes");
+
+ check_search(fdt, "test_tree1", 0, -FDT_ERR_NOTFOUND);
+ check_search(fdt, "subnode1", subnode1_offset, -FDT_ERR_NOTFOUND);
+ check_search(fdt, "subsubnode1", subsubnode1_offset, -FDT_ERR_NOTFOUND);
+ check_search(fdt, "subsubnode2", subsubnode2_offset, -FDT_ERR_NOTFOUND);
+ /* Eek.. HACK to make this work whatever the order in the
+ * example tree */
+ if (subsubnode1_offset < subsubnode2_offset)
+ check_search(fdt, "subsubnode", subsubnode1_offset,
+ subsubnode2_offset, -FDT_ERR_NOTFOUND);
+ else
+ check_search(fdt, "subsubnode", subsubnode2_offset,
+ subsubnode1_offset, -FDT_ERR_NOTFOUND);
+ check_search(fdt, "nothing-like-this", -FDT_ERR_NOTFOUND);
+
+ PASS();
+}
diff --git a/tests/node_offset_by_phandle.c b/tests/node_offset_by_phandle.c
new file mode 100644
index 000000000000..e9fd9392d806
--- /dev/null
+++ b/tests/node_offset_by_phandle.c
@@ -0,0 +1,64 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_node_offset_by_phandle()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <stdarg.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+void check_search(void *fdt, uint32_t phandle, int target)
+{
+ int offset;
+
+ offset = fdt_node_offset_by_phandle(fdt, phandle);
+
+ if (offset != target)
+ FAIL("fdt_node_offset_by_phandle(0x%x) returns %d "
+ "instead of %d", phandle, offset, target);
+}
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ int subnode2_offset, subsubnode2_offset;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ subnode2_offset = fdt_path_offset(fdt, "/subnode@2");
+ subsubnode2_offset = fdt_path_offset(fdt, "/subnode@2/subsubnode@0");
+
+ if ((subnode2_offset < 0) || (subsubnode2_offset < 0))
+ FAIL("Can't find required nodes");
+
+ check_search(fdt, PHANDLE_1, subnode2_offset);
+ check_search(fdt, PHANDLE_2, subsubnode2_offset);
+ check_search(fdt, ~PHANDLE_1, -FDT_ERR_NOTFOUND);
+ check_search(fdt, 0, -FDT_ERR_BADPHANDLE);
+ check_search(fdt, -1, -FDT_ERR_BADPHANDLE);
+
+ PASS();
+}
diff --git a/tests/node_offset_by_prop_value.c b/tests/node_offset_by_prop_value.c
new file mode 100644
index 000000000000..c55110a1be01
--- /dev/null
+++ b/tests/node_offset_by_prop_value.c
@@ -0,0 +1,110 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_path_offset()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <stdarg.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+void vcheck_search(void *fdt, const char *propname, const void *propval,
+ int proplen, va_list ap)
+{
+ int offset = -1, target;
+
+ do {
+ target = va_arg(ap, int);
+ verbose_printf("Searching (target = %d): %d ->",
+ target, offset);
+ offset = fdt_node_offset_by_prop_value(fdt, offset, propname,
+ propval, proplen);
+ verbose_printf("%d\n", offset);
+
+ if (offset != target)
+ FAIL("fdt_node_offset_by_prop_value() returns %d "
+ "instead of %d", offset, target);
+ } while (target >= 0);
+}
+
+void check_search(void *fdt, const char *propname, const void *propval,
+ int proplen, ...)
+{
+ va_list ap;
+
+ va_start(ap, proplen);
+ vcheck_search(fdt, propname, propval, proplen, ap);
+ va_end(ap);
+}
+
+void check_search_str(void *fdt, const char *propname, const char *propval, ...)
+{
+ va_list ap;
+
+ va_start(ap, propval);
+ vcheck_search(fdt, propname, propval, strlen(propval)+1, ap);
+ va_end(ap);
+}
+
+#define check_search_cell(fdt, propname, propval, ...) \
+ { \
+ uint32_t val = cpu_to_fdt32(propval); \
+ check_search((fdt), (propname), &val, sizeof(val), \
+ ##__VA_ARGS__); \
+ }
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ int subnode1_offset, subnode2_offset;
+ int subsubnode1_offset, subsubnode2_offset;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ subnode1_offset = fdt_path_offset(fdt, "/subnode@1");
+ subnode2_offset = fdt_path_offset(fdt, "/subnode@2");
+ subsubnode1_offset = fdt_path_offset(fdt, "/subnode@1/subsubnode");
+ subsubnode2_offset = fdt_path_offset(fdt, "/subnode@2/subsubnode@0");
+
+ if ((subnode1_offset < 0) || (subnode2_offset < 0)
+ || (subsubnode1_offset < 0) || (subsubnode2_offset < 0))
+ FAIL("Can't find required nodes");
+
+ check_search_cell(fdt, "prop-int", TEST_VALUE_1, 0, subnode1_offset,
+ subsubnode1_offset, -FDT_ERR_NOTFOUND);
+
+ check_search_cell(fdt, "prop-int", TEST_VALUE_2, subnode2_offset,
+ subsubnode2_offset, -FDT_ERR_NOTFOUND);
+
+ check_search_str(fdt, "prop-str", TEST_STRING_1, 0, -FDT_ERR_NOTFOUND);
+
+ check_search_str(fdt, "prop-str", "no such string", -FDT_ERR_NOTFOUND);
+
+ check_search_cell(fdt, "prop-int", TEST_VALUE_1+1, -FDT_ERR_NOTFOUND);
+
+ check_search(fdt, "no-such-prop", NULL, 0, -FDT_ERR_NOTFOUND);
+
+ PASS();
+}
diff --git a/tests/nonexist-label-ref.dts b/tests/nonexist-label-ref.dts
new file mode 100644
index 000000000000..25927a109ac3
--- /dev/null
+++ b/tests/nonexist-label-ref.dts
@@ -0,0 +1,8 @@
+/dts-v1/;
+
+/ {
+ ref = <&label>;
+ badref = <&nosuchlabel>;
+ label: node {
+ };
+};
diff --git a/tests/nonexist-node-ref.dts b/tests/nonexist-node-ref.dts
new file mode 100644
index 000000000000..efd41404bfce
--- /dev/null
+++ b/tests/nonexist-node-ref.dts
@@ -0,0 +1,8 @@
+/dts-v1/;
+
+/ {
+ ref = < &{/node} >;
+ badref = < &{/nosuchnode} >;
+ label: node {
+ };
+};
diff --git a/tests/nop_node.c b/tests/nop_node.c
new file mode 100644
index 000000000000..ea3a18f6acb5
--- /dev/null
+++ b/tests/nop_node.c
@@ -0,0 +1,105 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_nop_node()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <ctype.h>
+#include <stdint.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ int subnode1_offset, subnode2_offset, subsubnode2_offset;
+ int err;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ subnode1_offset = fdt_path_offset(fdt, "/subnode@1");
+ if (subnode1_offset < 0)
+ FAIL("Couldn't find \"/subnode1\": %s",
+ fdt_strerror(subnode1_offset));
+ check_getprop_cell(fdt, subnode1_offset, "prop-int", TEST_VALUE_1);
+
+ subnode2_offset = fdt_path_offset(fdt, "/subnode@2");
+ if (subnode2_offset < 0)
+ FAIL("Couldn't find \"/subnode2\": %s",
+ fdt_strerror(subnode2_offset));
+ check_getprop_cell(fdt, subnode2_offset, "prop-int", TEST_VALUE_2);
+
+ subsubnode2_offset = fdt_path_offset(fdt, "/subnode@2/subsubnode");
+ if (subsubnode2_offset < 0)
+ FAIL("Couldn't find \"/subnode@2/subsubnode\": %s",
+ fdt_strerror(subsubnode2_offset));
+ check_getprop_cell(fdt, subsubnode2_offset, "prop-int", TEST_VALUE_2);
+
+ err = fdt_nop_node(fdt, subnode1_offset);
+ if (err)
+ FAIL("fdt_nop_node(subnode1): %s", fdt_strerror(err));
+
+ subnode1_offset = fdt_path_offset(fdt, "/subnode@1");
+ if (subnode1_offset != -FDT_ERR_NOTFOUND)
+ FAIL("fdt_path_offset(subnode1) returned \"%s\" instead of \"%s\"",
+ fdt_strerror(subnode1_offset),
+ fdt_strerror(-FDT_ERR_NOTFOUND));
+
+ subnode2_offset = fdt_path_offset(fdt, "/subnode@2");
+ if (subnode2_offset < 0)
+ FAIL("Couldn't find \"/subnode2\": %s",
+ fdt_strerror(subnode2_offset));
+ check_getprop_cell(fdt, subnode2_offset, "prop-int", TEST_VALUE_2);
+
+ subsubnode2_offset = fdt_path_offset(fdt, "/subnode@2/subsubnode");
+ if (subsubnode2_offset < 0)
+ FAIL("Couldn't find \"/subnode@2/subsubnode\": %s",
+ fdt_strerror(subsubnode2_offset));
+ check_getprop_cell(fdt, subsubnode2_offset, "prop-int", TEST_VALUE_2);
+
+ err = fdt_nop_node(fdt, subnode2_offset);
+ if (err)
+ FAIL("fdt_nop_node(subnode2): %s", fdt_strerror(err));
+
+ subnode1_offset = fdt_path_offset(fdt, "/subnode@1");
+ if (subnode1_offset != -FDT_ERR_NOTFOUND)
+ FAIL("fdt_path_offset(subnode1) returned \"%s\" instead of \"%s\"",
+ fdt_strerror(subnode1_offset),
+ fdt_strerror(-FDT_ERR_NOTFOUND));
+
+ subnode2_offset = fdt_path_offset(fdt, "/subnode@2");
+ if (subnode2_offset != -FDT_ERR_NOTFOUND)
+ FAIL("fdt_path_offset(subnode2) returned \"%s\" instead of \"%s\"",
+ fdt_strerror(subnode2_offset),
+ fdt_strerror(-FDT_ERR_NOTFOUND));
+
+ subsubnode2_offset = fdt_path_offset(fdt, "/subnode@2/subsubnode");
+ if (subsubnode2_offset != -FDT_ERR_NOTFOUND)
+ FAIL("fdt_path_offset(subsubnode2) returned \"%s\" instead of \"%s\"",
+ fdt_strerror(subsubnode2_offset),
+ fdt_strerror(-FDT_ERR_NOTFOUND));
+
+ PASS();
+}
diff --git a/tests/nop_property.c b/tests/nop_property.c
new file mode 100644
index 000000000000..e6ef4d973149
--- /dev/null
+++ b/tests/nop_property.c
@@ -0,0 +1,71 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_nop_property()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <ctype.h>
+#include <stdint.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ const uint32_t *intp;
+ const char *strp;
+ int err;
+ int lenerr;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ intp = check_getprop_cell(fdt, 0, "prop-int", TEST_VALUE_1);
+ verbose_printf("int value was 0x%08x\n", *intp);
+
+ err = fdt_nop_property(fdt, 0, "prop-int");
+ if (err)
+ FAIL("Failed to nop \"prop-int\": %s", fdt_strerror(err));
+
+ intp = fdt_getprop(fdt, 0, "prop-int", &lenerr);
+ if (intp)
+ FAIL("prop-int still present after nopping");
+ if (lenerr != -FDT_ERR_NOTFOUND)
+ FAIL("Unexpected error on second getprop: %s", fdt_strerror(err));
+
+ strp = check_getprop(fdt, 0, "prop-str", strlen(TEST_STRING_1)+1,
+ TEST_STRING_1);
+ verbose_printf("string value was \"%s\"\n", strp);
+ err = fdt_nop_property(fdt, 0, "prop-str");
+ if (err)
+ FAIL("Failed to nop \"prop-str\": %s", fdt_strerror(err));
+
+ strp = fdt_getprop(fdt, 0, "prop-str", &lenerr);
+ if (strp)
+ FAIL("prop-str still present after nopping");
+ if (lenerr != -FDT_ERR_NOTFOUND)
+ FAIL("Unexpected error on second getprop: %s", fdt_strerror(err));
+
+ PASS();
+}
diff --git a/tests/nopulate.c b/tests/nopulate.c
new file mode 100644
index 000000000000..e56839a2a69f
--- /dev/null
+++ b/tests/nopulate.c
@@ -0,0 +1,106 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase/tool for rearranging blocks of a dtb
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <limits.h>
+#include <stdint.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int nopulate_struct(char *buf, const char *fdt)
+{
+ int offset, nextoffset = 0;
+ uint32_t tag;
+ char *p;
+
+ p = buf;
+
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+
+ memcpy(p, (const char *)fdt + fdt_off_dt_struct(fdt) + offset,
+ nextoffset - offset);
+ p += nextoffset - offset;
+
+ *((uint32_t *)p) = cpu_to_fdt32(FDT_NOP);
+ p += FDT_TAGSIZE;
+
+ } while (tag != FDT_END);
+
+ return p - buf;
+}
+
+int main(int argc, char *argv[])
+{
+ char *fdt, *fdt2, *buf;
+ int newsize, struct_start, struct_end_old, struct_end_new, delta;
+ const char *inname;
+ char outname[PATH_MAX];
+
+ test_init(argc, argv);
+ if (argc != 2)
+ CONFIG("Usage: %s <dtb file>", argv[0]);
+
+ inname = argv[1];
+ fdt = load_blob(argv[1]);
+ sprintf(outname, "noppy.%s", inname);
+
+ if (fdt_version(fdt) < 17)
+ FAIL("Can't deal with version <17");
+
+ buf = xmalloc(2 * fdt_size_dt_struct(fdt));
+
+ newsize = nopulate_struct(buf, fdt);
+
+ verbose_printf("Nopulated structure block has new size %d\n", newsize);
+
+ /* Replace old strcutre block with the new */
+
+ fdt2 = xmalloc(fdt_totalsize(fdt) + newsize);
+
+ struct_start = fdt_off_dt_struct(fdt);
+ delta = newsize - fdt_size_dt_struct(fdt);
+ struct_end_old = struct_start + fdt_size_dt_struct(fdt);
+ struct_end_new = struct_start + newsize;
+
+ memcpy(fdt2, fdt, struct_start);
+ memcpy(fdt2 + struct_start, buf, newsize);
+ memcpy(fdt2 + struct_end_new, fdt + struct_end_old,
+ fdt_totalsize(fdt) - struct_end_old);
+
+ fdt_set_totalsize(fdt2, fdt_totalsize(fdt) + delta);
+ fdt_set_size_dt_struct(fdt2, newsize);
+
+ if (fdt_off_mem_rsvmap(fdt) > struct_start)
+ fdt_set_off_mem_rsvmap(fdt2, fdt_off_mem_rsvmap(fdt) + delta);
+ if (fdt_off_dt_strings(fdt) > struct_start)
+ fdt_set_off_dt_strings(fdt2, fdt_off_dt_strings(fdt) + delta);
+
+ save_blob(outname, fdt2);
+
+ PASS();
+}
diff --git a/tests/notfound.c b/tests/notfound.c
new file mode 100644
index 000000000000..ae28c44d2efc
--- /dev/null
+++ b/tests/notfound.c
@@ -0,0 +1,73 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for behaviour on searching for a non-existent node
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+void check_error(const char *s, int err)
+{
+ if (err != -FDT_ERR_NOTFOUND)
+ FAIL("%s return error %s instead of -FDT_ERR_NOTFOUND", s,
+ fdt_strerror(err));
+}
+
+int main(int argc, char *argv[])
+{
+ const struct fdt_property *prop;
+ void *fdt;
+ int offset;
+ int subnode1_offset;
+ const void *val;
+ int lenerr;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ prop = fdt_get_property(fdt, 0, "nonexistant-property", &lenerr);
+ check_error("fdt_get_property(\"nonexistant-property\")", lenerr);
+
+ val = fdt_getprop(fdt, 0, "nonexistant-property", &lenerr);
+ check_error("fdt_getprop(\"nonexistant-property\"", lenerr);
+
+ subnode1_offset = fdt_subnode_offset(fdt, 0, "subnode@1");
+ if (subnode1_offset < 0)
+ FAIL("Couldn't find subnode1: %s", fdt_strerror(subnode1_offset));
+
+ val = fdt_getprop(fdt, subnode1_offset, "prop-str", &lenerr);
+ check_error("fdt_getprop(\"prop-str\")", lenerr);
+
+ offset = fdt_subnode_offset(fdt, 0, "nonexistant-subnode");
+ check_error("fdt_subnode_offset(\"nonexistant-subnode\")", offset);
+
+ offset = fdt_subnode_offset(fdt, 0, "subsubnode");
+ check_error("fdt_subnode_offset(\"subsubnode\")", offset);
+
+ offset = fdt_path_offset(fdt, "/nonexistant-subnode");
+ check_error("fdt_path_offset(\"/nonexistant-subnode\")", offset);
+
+ PASS();
+}
diff --git a/tests/obsolete-chosen-interrupt-controller.dts b/tests/obsolete-chosen-interrupt-controller.dts
new file mode 100644
index 000000000000..36dd6e81d143
--- /dev/null
+++ b/tests/obsolete-chosen-interrupt-controller.dts
@@ -0,0 +1,13 @@
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ PIC: pic@0 {
+ reg = <0x0 0x10>;
+ interrupt-controller;
+ };
+ chosen {
+ interrupt-controller = <&PIC>;
+ };
+};
diff --git a/tests/open_pack.c b/tests/open_pack.c
new file mode 100644
index 000000000000..d6140249c054
--- /dev/null
+++ b/tests/open_pack.c
@@ -0,0 +1,70 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Basic testcase for read-only access
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <limits.h>
+#include <stdint.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int main(int argc, char *argv[])
+{
+ void *fdt, *fdt1;
+ void *buf;
+ int oldsize, bufsize, packsize;
+ int err;
+ const char *inname;
+ char outname[PATH_MAX];
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+ inname = argv[1];
+
+ oldsize = fdt_totalsize(fdt);
+
+ bufsize = oldsize * 2;
+
+ buf = xmalloc(bufsize);
+
+ fdt1 = buf;
+ err = fdt_open_into(fdt, fdt1, bufsize);
+ if (err)
+ FAIL("fdt_open_into(): %s", fdt_strerror(err));
+ sprintf(outname, "opened.%s", inname);
+ save_blob(outname, fdt1);
+
+ err = fdt_pack(fdt1);
+ if (err)
+ FAIL("fdt_pack(): %s", fdt_strerror(err));
+ sprintf(outname, "repacked.%s", inname);
+ save_blob(outname, fdt1);
+
+ packsize = fdt_totalsize(fdt1);
+
+ verbose_printf("oldsize = %d, bufsize = %d, packsize = %d\n",
+ oldsize, bufsize, packsize);
+ PASS();
+}
diff --git a/tests/open_pack.supp b/tests/open_pack.supp
new file mode 100644
index 000000000000..c954fe789f1f
--- /dev/null
+++ b/tests/open_pack.supp
@@ -0,0 +1,7 @@
+{
+ opened blob dumps uninitialized data
+ Memcheck:Param
+ write(buf)
+ obj:/lib/ld-*.so
+ fun:main
+}
diff --git a/tests/parent_offset.c b/tests/parent_offset.c
new file mode 100644
index 000000000000..8336c72f1276
--- /dev/null
+++ b/tests/parent_offset.c
@@ -0,0 +1,91 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_parent_offset()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int path_parent_len(const char *path)
+{
+ const char *p = strrchr(path, '/');
+
+ if (!p)
+ TEST_BUG();
+ if (p == path)
+ return 1;
+ else
+ return p - path;
+}
+
+void check_path(struct fdt_header *fdt, const char *path)
+{
+ char *parentpath;
+ int nodeoffset, parentoffset, parentpathoffset, pathparentlen;
+
+ pathparentlen = path_parent_len(path);
+ parentpath = alloca(pathparentlen + 1);
+ strncpy(parentpath, path, pathparentlen);
+ parentpath[pathparentlen] = '\0';
+
+ verbose_printf("Path: \"%s\"\tParent: \"%s\"\n", path, parentpath);
+
+ nodeoffset = fdt_path_offset(fdt, path);
+ if (nodeoffset < 0)
+ FAIL("fdt_path_offset(%s): %s", path, fdt_strerror(nodeoffset));
+
+ parentpathoffset = fdt_path_offset(fdt, parentpath);
+ if (parentpathoffset < 0)
+ FAIL("fdt_path_offset(%s): %s", parentpath,
+ fdt_strerror(parentpathoffset));
+
+ parentoffset = fdt_parent_offset(fdt, nodeoffset);
+ if (parentoffset < 0)
+ FAIL("fdt_parent_offset(): %s", fdt_strerror(parentoffset));
+
+ if (parentoffset != parentpathoffset)
+ FAIL("fdt_parent_offset() returns %d instead of %d",
+ parentoffset, parentpathoffset);
+}
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ int err;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ check_path(fdt, "/subnode@1");
+ check_path(fdt, "/subnode@2");
+ check_path(fdt, "/subnode@1/subsubnode");
+ check_path(fdt, "/subnode@2/subsubnode@0");
+ err = fdt_parent_offset(fdt, 0);
+ if (err != -FDT_ERR_NOTFOUND)
+ FAIL("fdt_parent_offset(/) returns %d instead of "
+ "-FDT_ERR_NOTFOUND", err);
+
+ PASS();
+}
diff --git a/tests/path-references.c b/tests/path-references.c
new file mode 100644
index 000000000000..b96c5b2f496a
--- /dev/null
+++ b/tests/path-references.c
@@ -0,0 +1,83 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for string references in dtc
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+void check_ref(const void *fdt, int node, const char *checkpath)
+{
+ const char *p;
+ int len;
+
+ p = fdt_getprop(fdt, node, "ref", &len);
+ if (!p)
+ FAIL("fdt_getprop(%d, \"ref\"): %s", node, fdt_strerror(len));
+ if (!streq(p, checkpath))
+ FAIL("'ref' in node at %d has value \"%s\" instead of \"%s\"",
+ node, p, checkpath);
+
+ p = fdt_getprop(fdt, node, "lref", &len);
+ if (!p)
+ FAIL("fdt_getprop(%d, \"lref\"): %s", node, fdt_strerror(len));
+ if (!streq(p, checkpath))
+ FAIL("'lref' in node at %d has value \"%s\" instead of \"%s\"",
+ node, p, checkpath);
+}
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ const char *p;
+ int len, multilen;
+ int n1, n2;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ n1 = fdt_path_offset(fdt, "/node1");
+ if (n1 < 0)
+ FAIL("fdt_path_offset(/node1): %s", fdt_strerror(n1));
+ n2 = fdt_path_offset(fdt, "/node2");
+ if (n2 < 0)
+ FAIL("fdt_path_offset(/node2): %s", fdt_strerror(n2));
+
+ check_ref(fdt, n1, "/node2");
+ check_ref(fdt, n2, "/node1");
+
+ /* Check multiple reference */
+ multilen = strlen("/node1") + strlen("/node2") + 2;
+ p = fdt_getprop(fdt, 0, "multiref", &len);
+ if (!p)
+ FAIL("fdt_getprop(0, \"multiref\"): %s", fdt_strerror(len));
+ if (len != multilen)
+ FAIL("multiref has wrong length, %d instead of %d",
+ len, multilen);
+ if ((!streq(p, "/node1") || !streq(p + strlen("/node1") + 1, "/node2")))
+ FAIL("multiref has wrong value");
+
+ PASS();
+}
diff --git a/tests/path-references.dts b/tests/path-references.dts
new file mode 100644
index 000000000000..91e7ef745aae
--- /dev/null
+++ b/tests/path-references.dts
@@ -0,0 +1,14 @@
+/dts-v1/;
+
+/ {
+ /* Check multiple references case */
+ multiref = &n1 , &n2;
+ n1: node1 {
+ ref = &{/node2}; /* reference precedes target */
+ lref = &n2;
+ };
+ n2: node2 {
+ ref = &{/node1}; /* reference after target */
+ lref = &n1;
+ };
+};
diff --git a/tests/path_offset.c b/tests/path_offset.c
new file mode 100644
index 000000000000..4b014ac194e0
--- /dev/null
+++ b/tests/path_offset.c
@@ -0,0 +1,108 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_path_offset()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int check_subnode(void *fdt, int parent, const char *name)
+{
+ int offset;
+ const struct fdt_node_header *nh;
+ uint32_t tag;
+
+ verbose_printf("Checking subnode \"%s\" of %d...", name, parent);
+ offset = fdt_subnode_offset(fdt, parent, name);
+ verbose_printf("offset %d...", offset);
+ if (offset < 0)
+ FAIL("fdt_subnode_offset(\"%s\"): %s", name, fdt_strerror(offset));
+ nh = fdt_offset_ptr(fdt, offset, sizeof(*nh));
+ verbose_printf("pointer %p\n", nh);
+ if (! nh)
+ FAIL("NULL retrieving subnode \"%s\"", name);
+
+ tag = fdt32_to_cpu(nh->tag);
+
+ if (tag != FDT_BEGIN_NODE)
+ FAIL("Incorrect tag 0x%08x on property \"%s\"", tag, name);
+ if (!nodename_eq(nh->name, name))
+ FAIL("Subnode name mismatch \"%s\" instead of \"%s\"",
+ nh->name, name);
+
+ return offset;
+}
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ int root_offset;
+ int subnode1_offset, subnode2_offset;
+ int subnode1_offset_p, subnode2_offset_p;
+ int subsubnode1_offset, subsubnode2_offset, subsubnode2_offset2;
+ int subsubnode1_offset_p, subsubnode2_offset_p, subsubnode2_offset2_p;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ root_offset = fdt_path_offset(fdt, "/");
+ if (root_offset < 0)
+ FAIL("fdt_path_offset(\"/\") failed: %s",
+ fdt_strerror(root_offset));
+ else if (root_offset != 0)
+ FAIL("fdt_path_offset(\"/\") returns incorrect offset %d",
+ root_offset);
+ subnode1_offset = check_subnode(fdt, 0, "subnode@1");
+ subnode2_offset = check_subnode(fdt, 0, "subnode@2");
+
+ subnode1_offset_p = fdt_path_offset(fdt, "/subnode@1");
+ subnode2_offset_p = fdt_path_offset(fdt, "/subnode@2");
+
+ if (subnode1_offset != subnode1_offset_p)
+ FAIL("Mismatch between subnode_offset (%d) and path_offset (%d)",
+ subnode1_offset, subnode1_offset_p);
+
+ if (subnode2_offset != subnode2_offset_p)
+ FAIL("Mismatch between subnode_offset (%d) and path_offset (%d)",
+ subnode2_offset, subnode2_offset_p);
+
+ subsubnode1_offset = check_subnode(fdt, subnode1_offset, "subsubnode");
+ subsubnode2_offset = check_subnode(fdt, subnode2_offset, "subsubnode@0");
+ subsubnode2_offset2 = check_subnode(fdt, subnode2_offset, "subsubnode");
+
+ subsubnode1_offset_p = fdt_path_offset(fdt, "/subnode@1/subsubnode");
+ subsubnode2_offset_p = fdt_path_offset(fdt, "/subnode@2/subsubnode@0");
+ subsubnode2_offset2_p = fdt_path_offset(fdt, "/subnode@2/subsubnode");
+
+ if (subsubnode1_offset != subsubnode1_offset_p)
+ FAIL("Mismatch between subnode_offset (%d) and path_offset (%d)",
+ subsubnode1_offset, subsubnode1_offset_p);
+
+ if (subsubnode2_offset != subsubnode2_offset_p)
+ FAIL("Mismatch between subnode_offset (%d) and path_offset (%d)",
+ subsubnode2_offset, subsubnode2_offset_p);
+
+ PASS();
+}
diff --git a/tests/prop-after-subnode.dts b/tests/prop-after-subnode.dts
new file mode 100644
index 000000000000..6dd0b660fcd1
--- /dev/null
+++ b/tests/prop-after-subnode.dts
@@ -0,0 +1,9 @@
+/dts-v1/;
+
+/ {
+ node1 {
+ };
+ prop;
+ node2 {
+ };
+};
diff --git a/tests/references.c b/tests/references.c
new file mode 100644
index 000000000000..e98d450d4a53
--- /dev/null
+++ b/tests/references.c
@@ -0,0 +1,100 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for phandle references in dtc
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+void check_ref(const void *fdt, int node, uint32_t checkref)
+{
+ const uint32_t *p;
+ uint32_t ref;
+ int len;
+
+ p = fdt_getprop(fdt, node, "ref", &len);
+ if (!p)
+ FAIL("fdt_getprop(%d, \"ref\"): %s", node, fdt_strerror(len));
+ if (len != sizeof(*p))
+ FAIL("'ref' in node at %d has wrong size (%d instead of %zd)",
+ node, len, sizeof(*p));
+ ref = fdt32_to_cpu(*p);
+ if (ref != checkref)
+ FAIL("'ref' in node at %d has value 0x%x instead of 0x%x",
+ node, ref, checkref);
+
+ p = fdt_getprop(fdt, node, "lref", &len);
+ if (!p)
+ FAIL("fdt_getprop(%d, \"lref\"): %s", node, fdt_strerror(len));
+ if (len != sizeof(*p))
+ FAIL("'lref' in node at %d has wrong size (%d instead of %zd)",
+ node, len, sizeof(*p));
+ ref = fdt32_to_cpu(*p);
+ if (ref != checkref)
+ FAIL("'lref' in node at %d has value 0x%x instead of 0x%x",
+ node, ref, checkref);
+}
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ int n1, n2, n3, n4;
+ uint32_t h1, h2, h4;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ n1 = fdt_path_offset(fdt, "/node1");
+ if (n1 < 0)
+ FAIL("fdt_path_offset(/node1): %s", fdt_strerror(n1));
+ n2 = fdt_path_offset(fdt, "/node2");
+ if (n2 < 0)
+ FAIL("fdt_path_offset(/node2): %s", fdt_strerror(n2));
+ n3 = fdt_path_offset(fdt, "/node3");
+ if (n3 < 0)
+ FAIL("fdt_path_offset(/node3): %s", fdt_strerror(n3));
+ n4 = fdt_path_offset(fdt, "/node4");
+ if (n4 < 0)
+ FAIL("fdt_path_offset(/node4): %s", fdt_strerror(n4));
+
+ h1 = fdt_get_phandle(fdt, n1);
+ h2 = fdt_get_phandle(fdt, n2);
+ h4 = fdt_get_phandle(fdt, n4);
+
+ if (h1 != 0x2000)
+ FAIL("/node1 has wrong phandle, 0x%x instead of 0x%x",
+ h1, 0x2000);
+ if (h2 != 0x1)
+ FAIL("/node2 has wrong phandle, 0x%x instead of 0x%x",
+ h2, 0x1);
+ if ((h4 == 0x2000) || (h4 == 0x1) || (h4 == 0))
+ FAIL("/node4 has bad phandle, 0x%x", h4);
+
+ check_ref(fdt, n1, h2);
+ check_ref(fdt, n2, h1);
+ check_ref(fdt, n3, h4);
+
+ PASS();
+}
diff --git a/tests/references.dts b/tests/references.dts
new file mode 100644
index 000000000000..36b6f51d7763
--- /dev/null
+++ b/tests/references.dts
@@ -0,0 +1,23 @@
+/dts-v1/;
+
+/ {
+ /* Explicit phandles */
+ n1: node1 {
+ linux,phandle = <0x2000>;
+ ref = <&{/node2}>; /* reference precedes target */
+ lref = <&n2>;
+ };
+ n2: node2 {
+ linux,phandle = <0x1>;
+ ref = <&{/node1}>; /* reference after target */
+ lref = <&n1>;
+ };
+
+ /* Implicit phandles */
+ n3: node3 {
+ ref = <&{/node4}>;
+ lref = <&n4>;
+ };
+ n4: node4 {
+ };
+};
diff --git a/tests/references_dts0.dts b/tests/references_dts0.dts
new file mode 100644
index 000000000000..df82c23465f3
--- /dev/null
+++ b/tests/references_dts0.dts
@@ -0,0 +1,21 @@
+/ {
+ /* Explicit phandles */
+ n1: node1 {
+ linux,phandle = <2000>;
+ ref = <&/node2>; /* reference precedes target */
+ lref = <&n2>;
+ };
+ n2: node2 {
+ linux,phandle = <1>;
+ ref = <&/node1>; /* reference after target */
+ lref = <&n1>;
+ };
+
+ /* Implicit phandles */
+ n3: node3 {
+ ref = <&/node4>;
+ lref = <&n4>;
+ };
+ n4: node4 {
+ };
+};
diff --git a/tests/reg-ranges-root.dts b/tests/reg-ranges-root.dts
new file mode 100644
index 000000000000..9935b415ff6d
--- /dev/null
+++ b/tests/reg-ranges-root.dts
@@ -0,0 +1,8 @@
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x1000 0x10>;
+ ranges = <0x1000 0x2000 0x1000>;
+};
diff --git a/tests/root_node.c b/tests/root_node.c
new file mode 100644
index 000000000000..3f478299f9c6
--- /dev/null
+++ b/tests/root_node.c
@@ -0,0 +1,53 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Basic testcase for read-only access
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ const struct fdt_node_header *nh;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ nh = fdt_offset_ptr(fdt, 0, sizeof(*nh));
+
+ if (! nh)
+ FAIL("NULL retrieving root node");
+
+ if (fdt32_to_cpu(nh->tag) != FDT_BEGIN_NODE)
+ FAIL("Wrong tag on root node");
+
+ if (strlen(nh->name) != 0)
+ FAIL("Wrong name for root node, \"%s\" instead of empty",
+ nh->name);
+
+ PASS();
+}
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
new file mode 100755
index 000000000000..7bfc399e5637
--- /dev/null
+++ b/tests/run_tests.sh
@@ -0,0 +1,346 @@
+#! /bin/sh
+
+. ./tests.sh
+
+export QUIET_TEST=1
+
+export VALGRIND=
+VGCODE=126
+
+tot_tests=0
+tot_pass=0
+tot_fail=0
+tot_config=0
+tot_vg=0
+tot_strange=0
+
+base_run_test() {
+ tot_tests=$((tot_tests + 1))
+ if VALGRIND="$VALGRIND" "$@"; then
+ tot_pass=$((tot_pass + 1))
+ else
+ ret="$?"
+ if [ "$ret" == "1" ]; then
+ tot_config=$((tot_config + 1))
+ elif [ "$ret" == "2" ]; then
+ tot_fail=$((tot_fail + 1))
+ elif [ "$ret" == "$VGCODE" ]; then
+ tot_vg=$((tot_vg + 1))
+ else
+ tot_strange=$((tot_strange + 1))
+ fi
+ fi
+}
+
+run_test () {
+ echo -n "$@: "
+ if [ -n "$VALGRIND" -a -f $1.supp ]; then
+ VGSUPP="--suppressions=$1.supp"
+ fi
+ base_run_test $VALGRIND $VGSUPP "./$@"
+}
+
+run_sh_test () {
+ echo -n "$@: "
+ base_run_test sh "$@"
+}
+
+wrap_test () {
+ (
+ if verbose_run "$@"; then
+ PASS
+ else
+ ret="$?"
+ if [ "$ret" -gt 127 ]; then
+ signame=$(kill -l $((ret - 128)))
+ FAIL "Killed by SIG$signame"
+ else
+ FAIL "Returned error code $ret"
+ fi
+ fi
+ )
+}
+
+run_wrap_test () {
+ echo -n "$@: "
+ base_run_test wrap_test "$@"
+}
+
+run_dtc_test () {
+ echo -n "dtc $@: "
+ base_run_test wrap_test $VALGRIND $DTC "$@"
+}
+
+CONVERT=../convert-dtsv0
+
+run_convert_test () {
+ echo -n "convert-dtsv0 $@: "
+ base_run_test wrap_test $VALGRIND $CONVERT "$@"
+}
+
+tree1_tests () {
+ TREE=$1
+
+ # Read-only tests
+ run_test get_mem_rsv $TREE
+ run_test root_node $TREE
+ run_test find_property $TREE
+ run_test subnode_offset $TREE
+ run_test path_offset $TREE
+ run_test get_name $TREE
+ run_test getprop $TREE
+ run_test get_phandle $TREE
+ run_test get_path $TREE
+ run_test supernode_atdepth_offset $TREE
+ run_test parent_offset $TREE
+ run_test node_offset_by_prop_value $TREE
+ run_test node_offset_by_phandle $TREE
+ run_test node_check_compatible $TREE
+ run_test node_offset_by_compatible $TREE
+ run_test notfound $TREE
+
+ # Write-in-place tests
+ run_test setprop_inplace $TREE
+ run_test nop_property $TREE
+ run_test nop_node $TREE
+}
+
+tree1_tests_rw () {
+ TREE=$1
+
+ # Read-write tests
+ run_test set_name $TREE
+ run_test setprop $TREE
+ run_test del_property $TREE
+ run_test del_node $TREE
+}
+
+check_tests () {
+ tree="$1"
+ shift
+ run_sh_test dtc-checkfails.sh "$@" -- -I dts -O dtb $tree
+ run_dtc_test -I dts -O dtb -o $tree.test.dtb -f $tree
+ run_sh_test dtc-checkfails.sh "$@" -- -I dtb -O dtb $tree.test.dtb
+}
+
+ALL_LAYOUTS="mts mst tms tsm smt stm"
+
+libfdt_tests () {
+ tree1_tests test_tree1.dtb
+
+ # Sequential write tests
+ run_test sw_tree1
+ tree1_tests sw_tree1.test.dtb
+ tree1_tests unfinished_tree1.test.dtb
+ run_test dtbs_equal_ordered test_tree1.dtb sw_tree1.test.dtb
+
+ # fdt_move tests
+ for tree in test_tree1.dtb sw_tree1.test.dtb unfinished_tree1.test.dtb; do
+ rm -f moved.$tree shunted.$tree deshunted.$tree
+ run_test move_and_save $tree
+ run_test dtbs_equal_ordered $tree moved.$tree
+ run_test dtbs_equal_ordered $tree shunted.$tree
+ run_test dtbs_equal_ordered $tree deshunted.$tree
+ done
+
+ # v16 and alternate layout tests
+ for tree in test_tree1.dtb; do
+ for version in 17 16; do
+ for layout in $ALL_LAYOUTS; do
+ run_test mangle-layout $tree $version $layout
+ tree1_tests v$version.$layout.$tree
+ run_test dtbs_equal_ordered $tree v$version.$layout.$tree
+ done
+ done
+ done
+
+ # Read-write tests
+ for basetree in test_tree1.dtb; do
+ for version in 17 16; do
+ for layout in $ALL_LAYOUTS; do
+ tree=v$version.$layout.$basetree
+ rm -f opened.$tree repacked.$tree
+ run_test open_pack $tree
+ tree1_tests opened.$tree
+ tree1_tests repacked.$tree
+
+ tree1_tests_rw $tree
+ tree1_tests_rw opened.$tree
+ tree1_tests_rw repacked.$tree
+ done
+ done
+ done
+ run_test rw_tree1
+ tree1_tests rw_tree1.test.dtb
+ tree1_tests_rw rw_tree1.test.dtb
+
+ for basetree in test_tree1.dtb sw_tree1.test.dtb rw_tree1.test.dtb; do
+ run_test nopulate $basetree
+ run_test dtbs_equal_ordered $basetree noppy.$basetree
+ tree1_tests noppy.$basetree
+ tree1_tests_rw noppy.$basetree
+ done
+
+ # Tests for behaviour on various sorts of corrupted trees
+ run_test truncated_property
+
+ # Specific bug tests
+ run_test add_subnode_with_nops
+}
+
+dtc_tests () {
+ run_dtc_test -I dts -O dtb -o dtc_tree1.test.dtb test_tree1.dts
+ tree1_tests dtc_tree1.test.dtb
+ tree1_tests_rw dtc_tree1.test.dtb
+ run_test dtbs_equal_ordered dtc_tree1.test.dtb test_tree1.dtb
+
+ run_dtc_test -I dts -O dtb -o dtc_tree1_dts0.test.dtb test_tree1_dts0.dts
+ tree1_tests dtc_tree1_dts0.test.dtb
+ tree1_tests_rw dtc_tree1_dts0.test.dtb
+
+ run_dtc_test -I dts -O dtb -o dtc_escapes.test.dtb escapes.dts
+ run_test string_escapes dtc_escapes.test.dtb
+
+ run_dtc_test -I dts -O dtb -o dtc_references.test.dtb references.dts
+ run_test references dtc_references.test.dtb
+
+ run_dtc_test -I dts -O dtb -o dtc_references_dts0.test.dtb references_dts0.dts
+ run_test references dtc_references_dts0.test.dtb
+
+ run_dtc_test -I dts -O dtb -o dtc_path-references.test.dtb path-references.dts
+ run_test path-references dtc_path-references.test.dtb
+
+ run_dtc_test -I dts -O dtb -o dtc_comments.test.dtb comments.dts
+ run_dtc_test -I dts -O dtb -o dtc_comments-cmp.test.dtb comments-cmp.dts
+ run_test dtbs_equal_ordered dtc_comments.test.dtb dtc_comments-cmp.test.dtb
+
+ # Check /include/ directive
+ run_dtc_test -I dts -O dtb -o includes.test.dtb include0.dts
+ run_test dtbs_equal_ordered includes.test.dtb test_tree1.dtb
+
+ # Check /incbin/ directive
+ run_dtc_test -I dts -O dtb -o incbin.test.dtb incbin.dts
+ run_test incbin incbin.test.dtb
+
+ # Check boot_cpuid_phys handling
+ run_dtc_test -I dts -O dtb -b 17 -o boot_cpuid.test.dtb empty.dts
+ run_test boot-cpuid boot_cpuid.test.dtb 17
+ run_dtc_test -I dtb -O dtb -b 17 -o boot_cpuid_test_tree1.test.dtb test_tree1.dtb
+ run_test boot-cpuid boot_cpuid_test_tree1.test.dtb 17
+ run_dtc_test -I dtb -O dtb -o boot_cpuid_preserved_test_tree1.test.dtb boot_cpuid_test_tree1.test.dtb
+ run_test dtbs_equal_ordered boot_cpuid_preserved_test_tree1.test.dtb boot_cpuid_test_tree1.test.dtb
+
+ # Check -Odts mode preserve all dtb information
+ for tree in test_tree1.dtb dtc_tree1.test.dtb dtc_escapes.test.dtb ; do
+ run_dtc_test -I dtb -O dts -o odts_$tree.test.dts $tree
+ run_dtc_test -I dts -O dtb -o odts_$tree.test.dtb odts_$tree.test.dts
+ run_test dtbs_equal_ordered $tree odts_$tree.test.dtb
+ done
+
+ # Check version conversions
+ for tree in test_tree1.dtb ; do
+ for aver in 1 2 3 16 17; do
+ atree="ov${aver}_$tree.test.dtb"
+ run_dtc_test -I dtb -O dtb -V$aver -o $atree $tree
+ for bver in 16 17; do
+ btree="ov${bver}_$atree"
+ run_dtc_test -I dtb -O dtb -V$bver -o $btree $atree
+ run_test dtbs_equal_ordered $btree $tree
+ done
+ done
+ done
+
+ # Check some checks
+ check_tests dup-nodename.dts duplicate_node_names
+ check_tests dup-propname.dts duplicate_property_names
+ check_tests dup-phandle.dts explicit_phandles
+ check_tests zero-phandle.dts explicit_phandles
+ check_tests minusone-phandle.dts explicit_phandles
+ run_sh_test dtc-checkfails.sh phandle_references -- -I dts -O dtb nonexist-node-ref.dts
+ run_sh_test dtc-checkfails.sh phandle_references -- -I dts -O dtb nonexist-label-ref.dts
+ check_tests bad-name-property.dts name_properties
+
+ check_tests bad-ncells.dts address_cells_is_cell size_cells_is_cell interrupt_cells_is_cell
+ check_tests bad-string-props.dts device_type_is_string model_is_string status_is_string
+ check_tests bad-reg-ranges.dts reg_format ranges_format
+ check_tests bad-empty-ranges.dts ranges_format
+ check_tests reg-ranges-root.dts reg_format ranges_format
+ check_tests default-addr-size.dts avoid_default_addr_size
+ check_tests obsolete-chosen-interrupt-controller.dts obsolete_chosen_interrupt_controller
+ run_sh_test dtc-checkfails.sh node_name_chars -- -I dtb -O dtb bad_node_char.dtb
+ run_sh_test dtc-checkfails.sh node_name_format -- -I dtb -O dtb bad_node_format.dtb
+ run_sh_test dtc-checkfails.sh prop_name_chars -- -I dtb -O dtb bad_prop_char.dtb
+
+ # Check for proper behaviour reading from stdin
+ run_dtc_test -I dts -O dtb -o stdin_dtc_tree1.test.dtb - < test_tree1.dts
+ run_wrap_test cmp stdin_dtc_tree1.test.dtb dtc_tree1.test.dtb
+ run_dtc_test -I dtb -O dts -o stdin_odts_test_tree1.dtb.test.dts - < test_tree1.dtb
+ run_wrap_test cmp stdin_odts_test_tree1.dtb.test.dts odts_test_tree1.dtb.test.dts
+
+ # Check for graceful failure in some error conditions
+ run_sh_test dtc-fatal.sh -I dts -O dtb nosuchfile.dts
+ run_sh_test dtc-fatal.sh -I dtb -O dtb nosuchfile.dtb
+ run_sh_test dtc-fatal.sh -I fs -O dtb nosuchfile
+}
+
+convert_tests () {
+ V0_DTS="test_tree1_dts0.dts references_dts0.dts empty.dts escapes.dts \
+ test01.dts label01.dts"
+ for dts in $V0_DTS; do
+ run_dtc_test -I dts -O dtb -o cvtraw_$dts.test.dtb $dts
+ run_dtc_test -I dts -O dts -o cvtdtc_$dts.test.dts $dts
+ run_dtc_test -I dts -O dtb -o cvtdtc_$dts.test.dtb cvtdtc_$dts.test.dts
+ run_convert_test $dts
+ run_dtc_test -I dts -O dtb -o cvtcvt_$dts.test.dtb ${dts}v1
+
+ run_wrap_test cmp cvtraw_$dts.test.dtb cvtdtc_$dts.test.dtb
+ run_wrap_test cmp cvtraw_$dts.test.dtb cvtcvt_$dts.test.dtb
+ done
+}
+
+while getopts "vt:m" ARG ; do
+ case $ARG in
+ "v")
+ unset QUIET_TEST
+ ;;
+ "t")
+ TESTSETS=$OPTARG
+ ;;
+ "m")
+ VALGRIND="valgrind --tool=memcheck -q --error-exitcode=$VGCODE"
+ ;;
+ esac
+done
+
+if [ -z "$TESTSETS" ]; then
+ TESTSETS="libfdt dtc convert"
+fi
+
+# Make sure we don't have stale blobs lying around
+rm -f *.test.dtb *.test.dts
+
+for set in $TESTSETS; do
+ case $set in
+ "libfdt")
+ libfdt_tests
+ ;;
+ "dtc")
+ dtc_tests
+ ;;
+ "convert")
+ convert_tests
+ ;;
+ esac
+done
+
+echo -e "********** TEST SUMMARY"
+echo -e "* Total testcases: $tot_tests"
+echo -e "* PASS: $tot_pass"
+echo -e "* FAIL: $tot_fail"
+echo -e "* Bad configuration: $tot_config"
+if [ -n "$VALGRIND" ]; then
+ echo -e "* valgrind errors: $tot_vg"
+fi
+echo -e "* Strange test result: $tot_strange"
+echo -e "**********"
+
diff --git a/tests/rw_tree1.c b/tests/rw_tree1.c
new file mode 100644
index 000000000000..8f335c96a188
--- /dev/null
+++ b/tests/rw_tree1.c
@@ -0,0 +1,101 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_nop_node()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <ctype.h>
+#include <stdint.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+#define SPACE 65536
+
+#define CHECK(code) \
+ { \
+ err = (code); \
+ if (err) \
+ FAIL(#code ": %s", fdt_strerror(err)); \
+ }
+
+#define OFF_CHECK(off, code) \
+ { \
+ (off) = (code); \
+ if (off < 0) \
+ FAIL(#code ": %s", fdt_strerror(off)); \
+ }
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ int err;
+ int offset;
+
+ test_init(argc, argv);
+
+ fdt = xmalloc(SPACE);
+
+ /* First create empty tree with SW */
+ CHECK(fdt_create(fdt, SPACE));
+
+ CHECK(fdt_finish_reservemap(fdt));
+ CHECK(fdt_begin_node(fdt, ""));
+ CHECK(fdt_end_node(fdt));
+ CHECK(fdt_finish(fdt));
+
+ verbose_printf("Built empty tree, totalsize = %d\n",
+ fdt_totalsize(fdt));
+
+ CHECK(fdt_open_into(fdt, fdt, SPACE));
+
+ CHECK(fdt_add_mem_rsv(fdt, TEST_ADDR_1, TEST_SIZE_1));
+ CHECK(fdt_add_mem_rsv(fdt, TEST_ADDR_2, TEST_SIZE_2));
+
+ CHECK(fdt_setprop_string(fdt, 0, "compatible", "test_tree1"));
+ CHECK(fdt_setprop_cell(fdt, 0, "prop-int", TEST_VALUE_1));
+ CHECK(fdt_setprop_string(fdt, 0, "prop-str", TEST_STRING_1));
+
+ OFF_CHECK(offset, fdt_add_subnode(fdt, 0, "subnode@1"));
+ CHECK(fdt_setprop_string(fdt, offset, "compatible", "subnode1"));
+ CHECK(fdt_setprop_cell(fdt, offset, "prop-int", TEST_VALUE_1));
+ OFF_CHECK(offset, fdt_add_subnode(fdt, offset, "subsubnode"));
+ CHECK(fdt_setprop(fdt, offset, "compatible",
+ "subsubnode1\0subsubnode", 23));
+ CHECK(fdt_setprop_cell(fdt, offset, "prop-int", TEST_VALUE_1));
+
+ OFF_CHECK(offset, fdt_add_subnode(fdt, 0, "subnode@2"));
+ CHECK(fdt_setprop_cell(fdt, offset, "linux,phandle", PHANDLE_1));
+ CHECK(fdt_setprop_cell(fdt, offset, "prop-int", TEST_VALUE_2));
+ OFF_CHECK(offset, fdt_add_subnode(fdt, offset, "subsubnode@0"));
+ CHECK(fdt_setprop_cell(fdt, offset, "linux,phandle", PHANDLE_2));
+ CHECK(fdt_setprop(fdt, offset, "compatible",
+ "subsubnode2\0subsubnode", 23));
+ CHECK(fdt_setprop_cell(fdt, offset, "prop-int", TEST_VALUE_2));
+
+ CHECK(fdt_pack(fdt));
+
+ save_blob("rw_tree1.test.dtb", fdt);
+
+ PASS();
+}
diff --git a/tests/set_name.c b/tests/set_name.c
new file mode 100644
index 000000000000..49817a9ed981
--- /dev/null
+++ b/tests/set_name.c
@@ -0,0 +1,91 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_set_name()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+void check_set_name(void *fdt, const char *path, const char *newname)
+{
+ int offset;
+ const char *getname, *oldname;
+ int len, err;
+
+ oldname = strrchr(path, '/');
+ if (!oldname)
+ TEST_BUG();
+ oldname += 1;
+
+ offset = fdt_path_offset(fdt, path);
+ if (offset < 0)
+ FAIL("Couldn't find %s", path);
+
+ getname = fdt_get_name(fdt, offset, &len);
+ verbose_printf("fdt_get_name(%d) returns \"%s\" (len=%d)\n",
+ offset, getname, len);
+ if (!getname)
+ FAIL("fdt_get_name(%d): %s", offset, fdt_strerror(len));
+
+ if (strcmp(getname, oldname) != 0)
+ FAIL("fdt_get_name(%s) returned \"%s\" instead of \"%s\"",
+ path, getname, oldname);
+
+ if (len != strlen(getname))
+ FAIL("fdt_get_name(%s) returned length %d instead of %zd",
+ path, len, strlen(getname));
+
+ err = fdt_set_name(fdt, offset, newname);
+ if (err)
+ FAIL("fdt_set_name(%d, \"%s\"): %s", offset, newname,
+ fdt_strerror(err));
+
+ getname = fdt_get_name(fdt, offset, &len);
+ if (!getname)
+ FAIL("fdt_get_name(%d): %s", offset, fdt_strerror(len));
+
+ if (strcmp(getname, newname) != 0)
+ FAIL("fdt_get_name(%s) returned \"%s\" instead of \"%s\"",
+ path, getname, newname);
+
+ if (len != strlen(getname))
+ FAIL("fdt_get_name(%s) returned length %d instead of %zd",
+ path, len, strlen(getname));
+}
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+ fdt = open_blob_rw(fdt);
+
+ check_set_name(fdt, "/subnode@1", "subnode@17");
+ check_set_name(fdt, "/subnode@2/subsubnode@0", "fred@0");
+ check_set_name(fdt, "/subnode@17/subsubnode", "something@0");
+
+ PASS();
+}
diff --git a/tests/setprop.c b/tests/setprop.c
new file mode 100644
index 000000000000..386b87b408b6
--- /dev/null
+++ b/tests/setprop.c
@@ -0,0 +1,78 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_setprop()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <ctype.h>
+#include <stdint.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+#define SPACE 65536
+#define NEW_STRING "here is quite a long test string, blah blah blah"
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ void *buf;
+ const uint32_t *intp;
+ const char *strp;
+ int err;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ buf = xmalloc(SPACE);
+
+ err = fdt_open_into(fdt, buf, SPACE);
+ if (err)
+ FAIL("fdt_open_into(): %s", fdt_strerror(err));
+
+ fdt = buf;
+
+ intp = check_getprop_cell(fdt, 0, "prop-int", TEST_VALUE_1);
+
+ verbose_printf("Old int value was 0x%08x\n", *intp);
+ err = fdt_setprop_string(fdt, 0, "prop-int", NEW_STRING);
+ if (err)
+ FAIL("Failed to set \"prop-int\" to \"%s\": %s",
+ NEW_STRING, fdt_strerror(err));
+
+ strp = check_getprop_string(fdt, 0, "prop-int", NEW_STRING);
+ verbose_printf("New value is \"%s\"\n", strp);
+
+ strp = check_getprop(fdt, 0, "prop-str", strlen(TEST_STRING_1)+1,
+ TEST_STRING_1);
+
+ verbose_printf("Old string value was \"%s\"\n", strp);
+ err = fdt_setprop(fdt, 0, "prop-str", NULL, 0);
+ if (err)
+ FAIL("Failed to empty \"prop-str\": %s",
+ fdt_strerror(err));
+
+ check_getprop(fdt, 0, "prop-str", 0, NULL);
+
+ PASS();
+}
diff --git a/tests/setprop_inplace.c b/tests/setprop_inplace.c
new file mode 100644
index 000000000000..aa0cd9694df2
--- /dev/null
+++ b/tests/setprop_inplace.c
@@ -0,0 +1,72 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_setprop_inplace()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <ctype.h>
+#include <stdint.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ const uint32_t *intp;
+ const char *strp;
+ char *xstr;
+ int xlen, i;
+ int err;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ intp = check_getprop_cell(fdt, 0, "prop-int", TEST_VALUE_1);
+
+ verbose_printf("Old int value was 0x%08x\n", *intp);
+ err = fdt_setprop_inplace_cell(fdt, 0, "prop-int", ~TEST_VALUE_1);
+ if (err)
+ FAIL("Failed to set \"prop-int\" to 0x08%x: %s",
+ ~TEST_VALUE_1, fdt_strerror(err));
+ intp = check_getprop_cell(fdt, 0, "prop-int", ~TEST_VALUE_1);
+ verbose_printf("New int value is 0x%08x\n", *intp);
+
+ strp = check_getprop(fdt, 0, "prop-str", strlen(TEST_STRING_1)+1,
+ TEST_STRING_1);
+
+ verbose_printf("Old string value was \"%s\"\n", strp);
+ xstr = strdup(strp);
+ xlen = strlen(xstr);
+ for (i = 0; i < xlen; i++)
+ xstr[i] = toupper(xstr[i]);
+ err = fdt_setprop_inplace(fdt, 0, "prop-str", xstr, xlen+1);
+ if (err)
+ FAIL("Failed to set \"prop-str\" to \"%s\": %s",
+ xstr, fdt_strerror(err));
+
+ strp = check_getprop(fdt, 0, "prop-str", xlen+1, xstr);
+ verbose_printf("New string value is \"%s\"\n", strp);
+
+ PASS();
+}
diff --git a/tests/string_escapes.c b/tests/string_escapes.c
new file mode 100644
index 000000000000..30eb6a8d3d4d
--- /dev/null
+++ b/tests/string_escapes.c
@@ -0,0 +1,44 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for string escapes in dtc
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ check_getprop(fdt, 0, "escape-str",
+ strlen(TEST_STRING_2)+1, TEST_STRING_2);
+ check_getprop(fdt, 0, "escape-str-2",
+ strlen(TEST_STRING_3)+1, TEST_STRING_3);
+
+ PASS();
+}
diff --git a/tests/subnode_offset.c b/tests/subnode_offset.c
new file mode 100644
index 000000000000..ac2f32e18a3b
--- /dev/null
+++ b/tests/subnode_offset.c
@@ -0,0 +1,88 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_subnode_offset()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int check_subnode(struct fdt_header *fdt, int parent, const char *name)
+{
+ int offset;
+ const struct fdt_node_header *nh;
+ uint32_t tag;
+
+ verbose_printf("Checking subnode \"%s\" of %d...", name, parent);
+ offset = fdt_subnode_offset(fdt, parent, name);
+ verbose_printf("offset %d...", offset);
+ if (offset < 0)
+ FAIL("fdt_subnode_offset(\"%s\"): %s", name, fdt_strerror(offset));
+ nh = fdt_offset_ptr(fdt, offset, sizeof(*nh));
+ verbose_printf("pointer %p\n", nh);
+ if (! nh)
+ FAIL("NULL retrieving subnode \"%s\"", name);
+
+ tag = fdt32_to_cpu(nh->tag);
+
+ if (tag != FDT_BEGIN_NODE)
+ FAIL("Incorrect tag 0x%08x on property \"%s\"", tag, name);
+ if (!nodename_eq(nh->name, name))
+ FAIL("Subnode name mismatch \"%s\" instead of \"%s\"",
+ nh->name, name);
+
+ return offset;
+}
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ int subnode1_offset, subnode2_offset;
+ int subsubnode1_offset, subsubnode2_offset, subsubnode2_offset2;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ subnode1_offset = check_subnode(fdt, 0, "subnode@1");
+ subnode2_offset = check_subnode(fdt, 0, "subnode@2");
+
+ if (subnode1_offset == subnode2_offset)
+ FAIL("Different subnodes have same offset");
+
+ check_property_cell(fdt, subnode1_offset, "prop-int", TEST_VALUE_1);
+ check_property_cell(fdt, subnode2_offset, "prop-int", TEST_VALUE_2);
+
+ subsubnode1_offset = check_subnode(fdt, subnode1_offset, "subsubnode");
+ subsubnode2_offset = check_subnode(fdt, subnode2_offset, "subsubnode@0");
+ subsubnode2_offset2 = check_subnode(fdt, subnode2_offset, "subsubnode");
+
+ check_property_cell(fdt, subsubnode1_offset, "prop-int", TEST_VALUE_1);
+ check_property_cell(fdt, subsubnode2_offset, "prop-int", TEST_VALUE_2);
+ check_property_cell(fdt, subsubnode2_offset2, "prop-int", TEST_VALUE_2);
+
+ if (subsubnode2_offset != subsubnode2_offset2)
+ FAIL("Different offsets with and without unit address");
+
+ PASS();
+}
diff --git a/tests/supernode_atdepth_offset.c b/tests/supernode_atdepth_offset.c
new file mode 100644
index 000000000000..1245813d267a
--- /dev/null
+++ b/tests/supernode_atdepth_offset.c
@@ -0,0 +1,146 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_supernode_atdepth_offset()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int path_depth(const char *path)
+{
+ const char *p;
+ int depth = 0;
+
+ if (path[0] != '/')
+ TEST_BUG();
+
+ if (strcmp(path, "/") == 0)
+ return 0;
+ for (p = path; *p; p++)
+ if (*p == '/')
+ depth++;
+
+ /* Special case for path == "/" */
+ if (p == (path + 1))
+ return 0;
+ else
+ return depth;
+}
+
+int path_prefix(const char *path, int depth)
+{
+ const char *p;
+ int i;
+
+ if (path[0] != '/')
+ TEST_BUG();
+
+ if (depth == 0)
+ return 1;
+
+ p = path;
+ for (i = 0; i < depth; i++)
+ p = p+1 + strcspn(p+1, "/");
+
+ return p - path;
+}
+
+void check_supernode_atdepth(struct fdt_header *fdt, const char *path,
+ int depth)
+{
+ int pdepth = path_depth(path);
+ char *superpath;
+ int nodeoffset, supernodeoffset, superpathoffset, pathprefixlen;
+ int nodedepth;
+
+ pathprefixlen = path_prefix(path, depth);
+ superpath = alloca(pathprefixlen + 1);
+ strncpy(superpath, path, pathprefixlen);
+ superpath[pathprefixlen] = '\0';
+
+ verbose_printf("Path %s (%d), depth %d, supernode is %s\n",
+ path, pdepth, depth, superpath);
+
+ nodeoffset = fdt_path_offset(fdt, path);
+ if (nodeoffset < 0)
+ FAIL("fdt_path_offset(%s): %s", path, fdt_strerror(nodeoffset));
+ superpathoffset = fdt_path_offset(fdt, superpath);
+ if (superpathoffset < 0)
+ FAIL("fdt_path_offset(%s): %s", superpath,
+ fdt_strerror(superpathoffset));
+
+ supernodeoffset = fdt_supernode_atdepth_offset(fdt, nodeoffset,
+ depth, &nodedepth);
+ if (supernodeoffset < 0)
+ FAIL("fdt_supernode_atdepth_offset(): %s",
+ fdt_strerror(supernodeoffset));
+
+ if (supernodeoffset != superpathoffset)
+ FAIL("fdt_supernode_atdepth_offset() returns %d instead of %d",
+ supernodeoffset, superpathoffset);
+
+ if (nodedepth != pdepth)
+ FAIL("fdt_supernode_atdept_offset() returns node depth %d "
+ "instead of %d", nodedepth, pdepth);
+}
+
+void check_supernode_overdepth(struct fdt_header *fdt, const char *path)
+{
+ int pdepth = path_depth(path);
+ int nodeoffset, err;
+
+ nodeoffset = fdt_path_offset(fdt, path);
+ if (nodeoffset < 0)
+ FAIL("fdt_path_offset(%s): %s", path, fdt_strerror(nodeoffset));
+
+ err = fdt_supernode_atdepth_offset(fdt, nodeoffset, pdepth + 1, NULL);
+ if (err != -FDT_ERR_NOTFOUND)
+ FAIL("fdt_supernode_atdept_offset(%s, %d) returns %d instead "
+ "of FDT_ERR_NOTFOUND", path, pdepth+1, err);
+}
+
+void check_path(struct fdt_header *fdt, const char *path)
+{
+ int i;
+
+ for (i = 0; i <= path_depth(path); i++)
+ check_supernode_atdepth(fdt, path, i);
+ check_supernode_overdepth(fdt, path);
+}
+int main(int argc, char *argv[])
+{
+ void *fdt;
+
+ test_init(argc, argv);
+ fdt = load_blob_arg(argc, argv);
+
+ check_path(fdt, "/");
+ check_path(fdt, "/subnode@1");
+ check_path(fdt, "/subnode@2");
+ check_path(fdt, "/subnode@1/subsubnode");
+ check_path(fdt, "/subnode@2/subsubnode@0");
+
+ PASS();
+}
diff --git a/tests/sw_tree1.c b/tests/sw_tree1.c
new file mode 100644
index 000000000000..2a94b63985a8
--- /dev/null
+++ b/tests/sw_tree1.c
@@ -0,0 +1,94 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_nop_node()
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <ctype.h>
+#include <stdint.h>
+
+#include <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+#define SPACE 65536
+
+#define CHECK(code) \
+ { \
+ err = (code); \
+ if (err) \
+ FAIL(#code ": %s", fdt_strerror(err)); \
+ }
+
+int main(int argc, char *argv[])
+{
+ void *fdt;
+ int err;
+
+ test_init(argc, argv);
+
+ fdt = xmalloc(SPACE);
+ CHECK(fdt_create(fdt, SPACE));
+
+ CHECK(fdt_add_reservemap_entry(fdt, TEST_ADDR_1, TEST_SIZE_1));
+ CHECK(fdt_add_reservemap_entry(fdt, TEST_ADDR_2, TEST_SIZE_2));
+ CHECK(fdt_finish_reservemap(fdt));
+
+ CHECK(fdt_begin_node(fdt, ""));
+ CHECK(fdt_property_string(fdt, "compatible", "test_tree1"));
+ CHECK(fdt_property_cell(fdt, "prop-int", TEST_VALUE_1));
+ CHECK(fdt_property_string(fdt, "prop-str", TEST_STRING_1));
+
+ CHECK(fdt_begin_node(fdt, "subnode@1"));
+ CHECK(fdt_property_string(fdt, "compatible", "subnode1"));
+ CHECK(fdt_property_cell(fdt, "prop-int", TEST_VALUE_1));
+ CHECK(fdt_begin_node(fdt, "subsubnode"));
+ CHECK(fdt_property(fdt, "compatible", "subsubnode1\0subsubnode",
+ 23));
+ CHECK(fdt_property_cell(fdt, "prop-int", TEST_VALUE_1));
+ CHECK(fdt_end_node(fdt));
+ CHECK(fdt_end_node(fdt));
+
+ CHECK(fdt_begin_node(fdt, "subnode@2"));
+ CHECK(fdt_property_cell(fdt, "linux,phandle", PHANDLE_1));
+ CHECK(fdt_property_cell(fdt, "prop-int", TEST_VALUE_2));
+ CHECK(fdt_begin_node(fdt, "subsubnode@0"));
+ CHECK(fdt_property_cell(fdt, "linux,phandle", PHANDLE_2));
+ CHECK(fdt_property(fdt, "compatible", "subsubnode2\0subsubnode",
+ 23));
+ CHECK(fdt_property_cell(fdt, "prop-int", TEST_VALUE_2));
+ CHECK(fdt_end_node(fdt));
+ CHECK(fdt_end_node(fdt));
+
+ CHECK(fdt_end_node(fdt));
+
+ save_blob("unfinished_tree1.test.dtb", fdt);
+
+ CHECK(fdt_finish(fdt));
+
+ verbose_printf("Completed tree, totalsize = %d\n",
+ fdt_totalsize(fdt));
+
+ save_blob("sw_tree1.test.dtb", fdt);
+
+ PASS();
+}
diff --git a/tests/test01.asm b/tests/test01.asm
new file mode 100644
index 000000000000..bbf66c771d88
--- /dev/null
+++ b/tests/test01.asm
@@ -0,0 +1,294 @@
+/* autogenerated by dtc, do not edit */
+
+#define OF_DT_HEADER 0xd00dfeed
+#define OF_DT_BEGIN_NODE 0x1
+#define OF_DT_END_NODE 0x2
+#define OF_DT_PROP 0x3
+#define OF_DT_END 0x9
+
+ .globl dt_blob_start
+dt_blob_start:
+_dt_blob_start:
+ .globl dt_header
+dt_header:
+_dt_header:
+ .long OF_DT_HEADER /* magic */
+ .long _dt_blob_end - _dt_blob_start /* totalsize */
+ .long _dt_struct_start - _dt_blob_start /* off_dt_struct */
+ .long _dt_strings_start - _dt_blob_start /* off_dt_strings */
+ .long _dt_reserve_map - _dt_blob_start /* off_dt_strings */
+ .long 16 /* version */
+ .long 16 /* last_comp_version */
+ .long 0 /*boot_cpuid_phys*/
+ .long _dt_strings_end - _dt_strings_start /* size_dt_strings */
+ .balign 8
+ .globl dt_reserve_map
+dt_reserve_map:
+_dt_reserve_map:
+/* Memory reserve map from source file */
+ .long 0x10000000
+ .long 0x00000000
+ .long 0x00000000
+ .long 0x02000000
+ .long 0x20000000
+ .long 0x00000000
+ .long 0x01000000
+ .long 0x00000000
+ .long 0x00000000
+ .long 0x00000000
+ .long 0x00000000
+ .long 0x00000014
+ .long 0, 0
+ .long 0, 0
+ .globl dt_struct_start
+dt_struct_start:
+_dt_struct_start:
+ .long OF_DT_BEGIN_NODE
+ .string ""
+ .balign 4
+ .long OF_DT_PROP
+ .long 0xc
+ .long 0x0
+ .long 0x4d79426f
+ .long 0x6172644e
+ .long 0x616d6500
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x1e
+ .long 0x6
+ .long 0x4d79426f
+ .long 0x6172644e
+ .long 0x616d6500
+ .long 0x4d79426f
+ .long 0x61726446
+ .long 0x616d696c
+ .long 0x794e616d
+ .short 0x6500
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x11
+ .long 0x2
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x20
+ .long 0x2
+ .balign 4
+ .long OF_DT_BEGIN_NODE
+ .string "cpus"
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x2c
+ .long 0x1
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x11
+ .long 0x1
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x20
+ .long 0x0
+ .balign 4
+ .long OF_DT_BEGIN_NODE
+ .string "PowerPC,970@0"
+ .balign 4
+ .long OF_DT_PROP
+ .long 0xc
+ .long 0x3a
+ .long 0x506f7765
+ .long 0x7250432c
+ .long 0x39373000
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x3f
+ .long 0x63707500
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x4b
+ .long 0x0
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x4f
+ .long 0x5f5e1000
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x5f
+ .long 0x1fca055
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x0
+ .long 0x72
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x81
+ .long 0x10000
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x8e
+ .long 0x8000
+ .balign 4
+ .long OF_DT_END_NODE
+ .long OF_DT_BEGIN_NODE
+ .string "PowerPC,970@1"
+ .balign 4
+ .long OF_DT_PROP
+ .long 0xc
+ .long 0x3a
+ .long 0x506f7765
+ .long 0x7250432c
+ .long 0x39373000
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x3f
+ .long 0x63707500
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x4b
+ .long 0x1
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x4f
+ .long 0x5f5e1000
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x5f
+ .long 0x1fca055
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x81
+ .long 0x10000
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x8e
+ .long 0x8000
+ .balign 4
+ .long OF_DT_END_NODE
+ .long OF_DT_END_NODE
+ .long OF_DT_BEGIN_NODE
+ .string "randomnode"
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x13
+ .long 0x9b
+ .long 0xff007374
+ .long 0x75666673
+ .long 0x74756666
+ .long 0x909090a
+ .short 0xa0a
+ .byte 0x0
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x9
+ .long 0xa2
+ .long 0xa0b0c0d
+ .long 0xdeeaadbe
+ .byte 0xef
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0xa7
+ .long 0x2
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x14
+ .long 0xab
+ .long 0x61626300
+ .long 0x12340000
+ .long 0xa
+ .long 0xb
+ .long 0xc
+ .balign 4
+ .long OF_DT_END_NODE
+ .long OF_DT_BEGIN_NODE
+ .string "memory@0"
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x7
+ .long 0x3f
+ .long 0x6d656d6f
+ .short 0x7279
+ .byte 0x0
+ .balign 4
+ .globl memreg
+memreg:
+ .long OF_DT_PROP
+ .long 0x10
+ .long 0x4b
+ .long 0x0
+ .long 0x0
+ .long 0x0
+ .long 0x20000000
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0x2c
+ .long 0x2
+ .balign 4
+ .long OF_DT_END_NODE
+ .long OF_DT_BEGIN_NODE
+ .string "chosen"
+ .balign 4
+ .long OF_DT_PROP
+ .long 0xf
+ .long 0xb1
+ .long 0x726f6f74
+ .long 0x3d2f6465
+ .long 0x762f7364
+ .short 0x6132
+ .byte 0x0
+ .balign 4
+ .long OF_DT_PROP
+ .long 0x4
+ .long 0xba
+ .long 0x600
+ .balign 4
+ .long OF_DT_END_NODE
+ .long OF_DT_END_NODE
+ .long OF_DT_END
+ .globl dt_struct_end
+dt_struct_end:
+_dt_struct_end:
+ .globl dt_strings_start
+dt_strings_start:
+_dt_strings_start:
+ .string "model"
+ .string "compatible"
+ .string "#address-cells"
+ .string "#size-cells"
+ .string "linux,phandle"
+ .string "name"
+ .string "device_type"
+ .string "reg"
+ .string "clock-frequency"
+ .string "timebase-frequency"
+ .string "linux,boot-cpu"
+ .string "i-cache-size"
+ .string "d-cache-size"
+ .string "string"
+ .string "blob"
+ .string "ref"
+ .string "mixed"
+ .string "bootargs"
+ .string "linux,platform"
+ .globl dt_strings_end
+dt_strings_end:
+_dt_strings_end:
+ .globl dt_blob_end
+dt_blob_end:
+_dt_blob_end:
diff --git a/tests/test01.dts b/tests/test01.dts
new file mode 100644
index 000000000000..ed2b178e1845
--- /dev/null
+++ b/tests/test01.dts
@@ -0,0 +1,55 @@
+/memreserve/ 1000000000000000 0000000002000000;
+/memreserve/ 2000000000000000-20ffffffffffffff;
+/memreserve/ 0-13;
+
+/ {
+ model = "MyBoardName";
+ compatible = "MyBoardName", "MyBoardFamilyName";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ linux,phandle = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ PowerPC,970@0 {
+ name = "PowerPC,970";
+ device_type = "cpu";
+ reg = <0>;
+ clock-frequency = <5f5e1000>;
+ timebase-frequency = <1FCA055>;
+ linux,boot-cpu;
+ i-cache-size = <10000>;
+ d-cache-size = <8000>;
+ };
+
+ PowerPC,970@1 {
+ name = "PowerPC,970";
+ device_type = "cpu";
+ reg = <1>;
+ clock-frequency = <5f5e1000>;
+ timebase-frequency = <1FCA055>;
+ i-cache-size = <10000>;
+ d-cache-size = <8000>;
+ };
+
+ };
+
+ randomnode {
+ string = "\xff\0stuffstuff\t\t\t\n\n\n";
+ blob = [0a 0b 0c 0d de ea ad be ef];
+ ref = < &/memory@0 >;
+ mixed = "abc", [1234], <a b c>;
+ };
+
+ memory@0 {
+ device_type = "memory";
+ memreg: reg = <00000000 00000000 00000000 20000000>;
+ };
+
+ chosen {
+ bootargs = "root=/dev/sda2";
+ linux,platform = <00000600>;
+ };
+
+};
diff --git a/tests/test01.stderr b/tests/test01.stderr
new file mode 100644
index 000000000000..82ea3f63467e
--- /dev/null
+++ b/tests/test01.stderr
@@ -0,0 +1,4 @@
+DTC: dts->asm on file "test.dts"
+Warning: "linux,boot-cpu" property is deprecated in blob version 2 or higher
+Warning: /chosen has no "linux,stdout-path" property
+Warning: /chosen has no "interrupt-controller" property
diff --git a/tests/test_kernel_dts b/tests/test_kernel_dts
new file mode 100755
index 000000000000..238f3f7c636a
--- /dev/null
+++ b/tests/test_kernel_dts
@@ -0,0 +1,86 @@
+#!/usr/bin/perl
+
+my $dtc_old = "/home/jdl/FSL/dtc/dtc-old";
+my $dtc_new = "/home/jdl/FSL/dtc/dtc-new";
+
+my $basic_options = "-b 0 -f -I dts -O dtb";
+
+my $linux_dts_dir = "/usr/src/linux-2.6/arch/powerpc/boot/dts";
+
+# Yeah, sure, we could, like, readdir() this instead...
+my @boards = (
+ "bamboo",
+ "ebony",
+ "ep88xc",
+ "holly",
+ "kilauea",
+ "kuroboxHD",
+ "kuroboxHG",
+ "lite5200",
+ "lite5200b",
+ "mpc7448hpc2",
+ "mpc8272ads",
+ "mpc8313erdb",
+ "mpc832x_mds",
+ "mpc832x_rdb",
+ "mpc8349emitx",
+ "mpc8349emitxgp",
+ "mpc834x_mds",
+ "mpc836x_mds",
+ "mpc8540ads",
+ "mpc8541cds",
+ "mpc8544ds",
+ "mpc8548cds",
+ "mpc8555cds",
+ "mpc8560ads",
+ "mpc8568mds",
+ "mpc8572ds",
+ "mpc8610_hpcd",
+ "mpc8641_hpcn",
+ "mpc866ads", # Feh. Bad node references...
+ "mpc885ads",
+ "pq2fads",
+ "prpmc2800",
+ "ps3",
+ "sequoia",
+ "walnut",
+);
+
+foreach my $board (@boards) {
+ my $dts_file = "$linux_dts_dir/$board.dts";
+
+ my $old_dtb_file = "/tmp/$board.dtb.old";
+ my $new_dtb_file = "/tmp/$board.dtb.new";
+
+ my $cmd_old = "$dtc_old $basic_options -o $old_dtb_file $dts_file";
+ my $cmd_new = "$dtc_new $basic_options -o $new_dtb_file $dts_file";
+ my $cmd_cmp = "cmp $old_dtb_file $new_dtb_file";
+
+ print "------------------------------------------------\n";
+ print "OLD: $cmd_old\n";
+ unlink($old_dtb_file) if (-f $old_dtb_file);
+ system("$cmd_old >& /dev/null");
+ my $status = $?;
+ if ($status) {
+ print " FAILED to run old DTC on $board\n";
+ }
+
+ print "NEW: $cmd_new\n";
+ unlink($new_dtb_file) if (-f $new_dtb_file);
+ system("$cmd_new >& /dev/null");
+ $status = $?;
+ if ($status) {
+ print " FAILED to run new DTC on $board\n";
+ }
+
+ if (-f $old_dtb_file && -f $new_dtb_file) {
+ print "CMP: $cmd_cmp\n";
+ system($cmd_cmp);
+ $status = $?;
+ if ($status) {
+ print " FAILED $board\n";
+ }
+ } else {
+ printf " FAILED: Missing dtb file\n";
+ }
+}
diff --git a/tests/test_tree1.dts b/tests/test_tree1.dts
new file mode 100644
index 000000000000..27602af45bf3
--- /dev/null
+++ b/tests/test_tree1.dts
@@ -0,0 +1,31 @@
+/dts-v1/;
+
+/memreserve/ 0xdeadbeef00000000 0x100000;
+/memreserve/ 123456789 010000;
+
+/ {
+ compatible = "test_tree1";
+ prop-int = <0xdeadbeef>;
+ prop-str = "hello world";
+
+ subnode@1 {
+ compatible = "subnode1";
+ prop-int = [deadbeef];
+
+ subsubnode {
+ compatible = "subsubnode1", "subsubnode";
+ prop-int = <0xdeadbeef>;
+ };
+ };
+
+ subnode@2 {
+ linux,phandle = <0x2000>;
+ prop-int = <123456789>;
+
+ subsubnode@0 {
+ linux,phandle = <0x2001>;
+ compatible = "subsubnode2", "subsubnode";
+ prop-int = <0726746425>;
+ };
+ };
+};
diff --git a/tests/test_tree1_dts0.dts b/tests/test_tree1_dts0.dts
new file mode 100644
index 000000000000..bc65819033fc
--- /dev/null
+++ b/tests/test_tree1_dts0.dts
@@ -0,0 +1,29 @@
+/memreserve/ deadbeef00000000-deadbeef000fffff;
+/memreserve/ 75bcd15 1000;
+
+/ {
+ compatible = "test_tree1";
+ prop-int = <deadbeef>;
+ prop-str = "hello world";
+
+ subnode@1 {
+ compatible = "subnode1";
+ prop-int = [deadbeef];
+
+ subsubnode {
+ compatible = "subsubnode1", "subsubnode";
+ prop-int = <h# deadbeef>;
+ };
+ };
+
+ subnode@2 {
+ linux,phandle = <2000>;
+ prop-int = <d# 123456789>;
+
+ subsubnode@0 {
+ linux,phandle = <2001>;
+ compatible = "subsubnode2", "subsubnode";
+ prop-int = <o# 0726746425>;
+ };
+ };
+};
diff --git a/tests/testdata.h b/tests/testdata.h
new file mode 100644
index 000000000000..5b5a9a3b37ea
--- /dev/null
+++ b/tests/testdata.h
@@ -0,0 +1,28 @@
+#ifdef __ASSEMBLY__
+#define ASM_CONST_LL(x) (x)
+#else
+#define ASM_CONST_LL(x) (x##ULL)
+#endif
+
+#define TEST_ADDR_1 ASM_CONST_LL(0xdeadbeef00000000)
+#define TEST_SIZE_1 ASM_CONST_LL(0x100000)
+#define TEST_ADDR_2 ASM_CONST_LL(123456789)
+#define TEST_SIZE_2 ASM_CONST_LL(010000)
+
+#define TEST_VALUE_1 0xdeadbeef
+#define TEST_VALUE_2 123456789
+
+#define PHANDLE_1 0x2000
+#define PHANDLE_2 0x2001
+
+#define TEST_STRING_1 "hello world"
+#define TEST_STRING_2 "nastystring: \a\b\t\n\v\f\r\\\""
+#define TEST_STRING_3 "\xde\xad\xbe\xef"
+
+#ifndef __ASSEMBLY__
+extern struct fdt_header _test_tree1;
+extern struct fdt_header _truncated_property;
+extern struct fdt_header _bad_node_char;
+extern struct fdt_header _bad_node_format;
+extern struct fdt_header _bad_prop_char;
+#endif /* ! __ASSEMBLY */
diff --git a/tests/tests.h b/tests/tests.h
new file mode 100644
index 000000000000..c273f3cec0b2
--- /dev/null
+++ b/tests/tests.h
@@ -0,0 +1,137 @@
+#ifndef _TESTS_H
+#define _TESTS_H
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase definitions
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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
+ */
+
+#define DEBUG
+
+/* Test return codes */
+#define RC_PASS 0
+#define RC_CONFIG 1
+#define RC_FAIL 2
+#define RC_BUG 99
+
+extern int verbose_test;
+extern char *test_name;
+void test_init(int argc, char *argv[]);
+
+#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
+#define PALIGN(p, a) ((void *)ALIGN((unsigned long)(p), (a)))
+
+#define streq(s1, s2) (strcmp((s1),(s2)) == 0)
+
+/* Each test case must define this function */
+void cleanup(void);
+
+#define verbose_printf(...) \
+ if (verbose_test) { \
+ printf(__VA_ARGS__); \
+ fflush(stdout); \
+ }
+#define ERR "ERR: "
+#define ERROR(fmt, args...) fprintf(stderr, ERR fmt, ## args)
+
+
+#define PASS() \
+ do { \
+ cleanup(); \
+ printf("PASS\n"); \
+ exit(RC_PASS); \
+ } while (0)
+
+#define PASS_INCONCLUSIVE() \
+ do { \
+ cleanup(); \
+ printf("PASS (inconclusive)\n"); \
+ exit(RC_PASS); \
+ } while (0)
+
+#define IRRELEVANT() \
+ do { \
+ cleanup(); \
+ printf("PASS (irrelevant)\n"); \
+ exit(RC_PASS); \
+ } while (0)
+
+/* Look out, gcc extension below... */
+#define FAIL(fmt, ...) \
+ do { \
+ cleanup(); \
+ printf("FAIL\t" fmt "\n", ##__VA_ARGS__); \
+ exit(RC_FAIL); \
+ } while (0)
+
+#define CONFIG(fmt, ...) \
+ do { \
+ cleanup(); \
+ printf("Bad configuration: " fmt "\n", ##__VA_ARGS__); \
+ exit(RC_CONFIG); \
+ } while (0)
+
+#define TEST_BUG(fmt, ...) \
+ do { \
+ cleanup(); \
+ printf("BUG in testsuite: " fmt "\n", ##__VA_ARGS__); \
+ exit(RC_BUG); \
+ } while (0)
+
+static inline void *xmalloc(size_t size)
+{
+ void *p = malloc(size);
+ if (! p)
+ FAIL("malloc() failure");
+ return p;
+}
+
+static inline void *xrealloc(void *p, size_t size)
+{
+ p = realloc(p, size);
+ if (! p)
+ FAIL("realloc() failure");
+ return p;
+}
+
+void check_mem_rsv(void *fdt, int n, uint64_t addr, uint64_t size);
+
+void check_property(void *fdt, int nodeoffset, const char *name,
+ int len, const void *val);
+#define check_property_cell(fdt, nodeoffset, name, val) \
+ ({ \
+ uint32_t x = cpu_to_fdt32(val); \
+ check_property(fdt, nodeoffset, name, sizeof(x), &x); \
+ })
+
+
+const void *check_getprop(void *fdt, int nodeoffset, const char *name,
+ int len, const void *val);
+#define check_getprop_cell(fdt, nodeoffset, name, val) \
+ ({ \
+ uint32_t x = cpu_to_fdt32(val); \
+ check_getprop(fdt, nodeoffset, name, sizeof(x), &x); \
+ })
+#define check_getprop_string(fdt, nodeoffset, name, s) \
+ check_getprop((fdt), (nodeoffset), (name), strlen(s)+1, (s))
+int nodename_eq(const char *s1, const char *s2);
+void *load_blob(const char *filename);
+void *load_blob_arg(int argc, char *argv[]);
+void save_blob(const char *filename, void *blob);
+void *open_blob_rw(void *blob);
+
+#endif /* _TESTS_H */
diff --git a/tests/tests.sh b/tests/tests.sh
new file mode 100755
index 000000000000..30ffead41eab
--- /dev/null
+++ b/tests/tests.sh
@@ -0,0 +1,32 @@
+# Common functions for shell testcases
+
+PASS () {
+ echo "PASS"
+ exit 0
+}
+
+FAIL () {
+ echo "FAIL" "$@"
+ exit 2
+}
+
+DTC=../dtc
+
+verbose_run () {
+ if [ -z "$QUIET_TEST" ]; then
+ "$@"
+ else
+ "$@" > /dev/null 2> /dev/null
+ fi
+}
+
+verbose_run_log () {
+ LOG="$1"
+ shift
+ "$@" > "$LOG" 2>&1
+ ret=$?
+ if [ -z "$QUIET_TEST" ]; then
+ cat "$LOG" >&2
+ fi
+ return $ret
+}
diff --git a/tests/testutils.c b/tests/testutils.c
new file mode 100644
index 000000000000..b0a22304cf2d
--- /dev/null
+++ b/tests/testutils.c
@@ -0,0 +1,240 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase common utility functions
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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
+ */
+
+#define _GNU_SOURCE /* for strsignal() in glibc. FreeBSD has it either way */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <libfdt.h>
+
+#include "tests.h"
+
+int verbose_test = 1;
+char *test_name;
+
+void __attribute__((weak)) cleanup(void)
+{
+}
+
+static void sigint_handler(int signum, siginfo_t *si, void *uc)
+{
+ cleanup();
+ fprintf(stderr, "%s: %s (pid=%d)\n", test_name,
+ strsignal(signum), getpid());
+ exit(RC_BUG);
+}
+
+void test_init(int argc, char *argv[])
+{
+ int err;
+ struct sigaction sa_int = {
+ .sa_sigaction = sigint_handler,
+ };
+
+ test_name = argv[0];
+
+ err = sigaction(SIGINT, &sa_int, NULL);
+ if (err)
+ FAIL("Can't install SIGINT handler");
+
+ if (getenv("QUIET_TEST"))
+ verbose_test = 0;
+
+ verbose_printf("Starting testcase \"%s\", pid %d\n",
+ test_name, getpid());
+}
+
+void check_mem_rsv(void *fdt, int n, uint64_t addr, uint64_t size)
+{
+ int err;
+ uint64_t addr_v, size_v;
+
+ err = fdt_get_mem_rsv(fdt, n, &addr_v, &size_v);
+ if (err < 0)
+ FAIL("fdt_get_mem_rsv(%d): %s", n, fdt_strerror(err));
+ if ((addr_v != addr) || (size_v != size))
+ FAIL("fdt_get_mem_rsv() returned (0x%llx,0x%llx) "
+ "instead of (0x%llx,0x%llx)",
+ (unsigned long long)addr_v, (unsigned long long)size_v,
+ (unsigned long long)addr, (unsigned long long)size);
+}
+
+void check_property(void *fdt, int nodeoffset, const char *name,
+ int len, const void *val)
+{
+ const struct fdt_property *prop;
+ int retlen;
+ uint32_t tag, nameoff, proplen;
+ const char *propname;
+
+ verbose_printf("Checking property \"%s\"...", name);
+ prop = fdt_get_property(fdt, nodeoffset, name, &retlen);
+ verbose_printf("pointer %p\n", prop);
+ if (! prop)
+ FAIL("Error retreiving \"%s\" pointer: %s", name,
+ fdt_strerror(retlen));
+
+ tag = fdt32_to_cpu(prop->tag);
+ nameoff = fdt32_to_cpu(prop->nameoff);
+ proplen = fdt32_to_cpu(prop->len);
+
+ if (tag != FDT_PROP)
+ FAIL("Incorrect tag 0x%08x on property \"%s\"", tag, name);
+
+ propname = fdt_string(fdt, nameoff);
+ if (!propname || !streq(propname, name))
+ FAIL("Property name mismatch \"%s\" instead of \"%s\"",
+ propname, name);
+ if (proplen != retlen)
+ FAIL("Length retrieved for \"%s\" by fdt_get_property()"
+ " differs from stored length (%d != %d)",
+ name, retlen, proplen);
+ if (proplen != len)
+ FAIL("Size mismatch on property \"%s\": %d insead of %d",
+ name, proplen, len);
+ if (memcmp(val, prop->data, len) != 0)
+ FAIL("Data mismatch on property \"%s\"", name);
+}
+
+const void *check_getprop(void *fdt, int nodeoffset, const char *name,
+ int len, const void *val)
+{
+ const void *propval;
+ int proplen;
+
+ propval = fdt_getprop(fdt, nodeoffset, name, &proplen);
+ if (! propval)
+ FAIL("fdt_getprop(\"%s\"): %s", name, fdt_strerror(proplen));
+
+ if (proplen != len)
+ FAIL("Size mismatch on property \"%s\": %d insead of %d",
+ name, proplen, len);
+ if (memcmp(val, propval, len) != 0)
+ FAIL("Data mismatch on property \"%s\"", name);
+
+ return propval;
+}
+
+int nodename_eq(const char *s1, const char *s2)
+{
+ int len = strlen(s2);
+
+ len = strlen(s2);
+ if (strncmp(s1, s2, len) != 0)
+ return 0;
+ if (s1[len] == '\0')
+ return 1;
+ else if (!memchr(s2, '@', len) && (s1[len] == '@'))
+ return 1;
+ else
+ return 0;
+}
+
+#define CHUNKSIZE 128
+
+void *load_blob(const char *filename)
+{
+ int fd;
+ int offset = 0;
+ int bufsize = 1024;
+ char *p = NULL;
+ int ret;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ CONFIG("Couldn't open blob from \"%s\": %s", filename,
+ strerror(errno));
+
+ p = xmalloc(bufsize);
+ do {
+ if (offset == bufsize) {
+ bufsize *= 2;
+ p = xrealloc(p, bufsize);
+ }
+
+ ret = read(fd, &p[offset], bufsize - offset);
+ if (ret < 0)
+ CONFIG("Couldn't read from \"%s\": %s", filename,
+ strerror(errno));
+
+ offset += ret;
+ } while (ret != 0);
+
+ return p;
+}
+
+void *load_blob_arg(int argc, char *argv[])
+{
+ if (argc != 2)
+ CONFIG("Usage: %s <dtb file>", argv[0]);
+ return load_blob(argv[1]);
+}
+
+void save_blob(const char *filename, void *fdt)
+{
+ int fd;
+ int totalsize;
+ int offset;
+ char *p;
+ int ret;
+
+ fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ if (fd < 0)
+ CONFIG("Couldn't open \"%s\" to write blob: %s", filename,
+ strerror(errno));
+
+ totalsize = fdt_totalsize(fdt);
+ offset = 0;
+ p = fdt;
+
+ while (offset < totalsize) {
+ ret = write(fd, p + offset, totalsize - offset);
+ if (ret < 0)
+ CONFIG("Couldn't write to \"%s\": %s", filename,
+ strerror(errno));
+ offset += ret;
+ }
+}
+
+void *open_blob_rw(void *blob)
+{
+ int err;
+ void *buf = blob;
+
+ err = fdt_open_into(blob, buf, fdt_totalsize(blob));
+ if (err == -FDT_ERR_NOSPACE) {
+ /* Ran out of space converting to v17 */
+ int newsize = fdt_totalsize(blob) + 8;
+
+ buf = xmalloc(newsize);
+ err = fdt_open_into(blob, buf, newsize);
+ }
+ if (err)
+ FAIL("fdt_open_into(): %s", fdt_strerror(err));
+ return buf;
+}
diff --git a/tests/trees.S b/tests/trees.S
new file mode 100644
index 000000000000..cedf5f948a53
--- /dev/null
+++ b/tests/trees.S
@@ -0,0 +1,186 @@
+#include <fdt.h>
+#include "testdata.h"
+
+#define FDTLONG(val) \
+ .byte ((val) >> 24) & 0xff ; \
+ .byte ((val) >> 16) & 0xff ; \
+ .byte ((val) >> 8) & 0xff ; \
+ .byte (val) & 0xff ;
+
+#define FDTQUAD(val) \
+ .byte ((val) >> 56) & 0xff ; \
+ .byte ((val) >> 48) & 0xff ; \
+ .byte ((val) >> 40) & 0xff ; \
+ .byte ((val) >> 32) & 0xff ; \
+ .byte ((val) >> 24) & 0xff ; \
+ .byte ((val) >> 16) & 0xff ; \
+ .byte ((val) >> 8) & 0xff ; \
+ .byte (val) & 0xff ;
+
+#define TREE_HDR(tree) \
+ .balign 8 ; \
+ .globl _##tree ; \
+_##tree: \
+tree: \
+ FDTLONG(FDT_MAGIC) ; \
+ FDTLONG(tree##_end - tree) ; \
+ FDTLONG(tree##_struct - tree) ; \
+ FDTLONG(tree##_strings - tree) ; \
+ FDTLONG(tree##_rsvmap - tree) ; \
+ FDTLONG(0x11) ; \
+ FDTLONG(0x10) ; \
+ FDTLONG(0) ; \
+ FDTLONG(tree##_strings_end - tree##_strings) ; \
+ FDTLONG(tree##_struct_end - tree##_struct) ;
+
+#define RSVMAP_ENTRY(addr, len) \
+ FDTQUAD(addr) ; \
+ FDTQUAD(len) ; \
+
+#define EMPTY_RSVMAP(tree) \
+ .balign 8 ; \
+tree##_rsvmap: ; \
+ RSVMAP_ENTRY(0, 0) \
+tree##_rsvmap_end: ;
+
+#define PROPHDR(tree, name, len) \
+ FDTLONG(FDT_PROP) ; \
+ FDTLONG(len) ; \
+ FDTLONG(tree##_##name - tree##_strings) ;
+
+#define PROP_INT(tree, name, val) \
+ PROPHDR(tree, name, 4) \
+ FDTLONG(val) ;
+
+#define PROP_STR(tree, name, str) \
+ PROPHDR(tree, name, 55f - 54f) \
+54: \
+ .string str ; \
+55: \
+ .balign 4 ;
+
+#define BEGIN_NODE(name) \
+ FDTLONG(FDT_BEGIN_NODE) ; \
+ .string name ; \
+ .balign 4 ;
+
+#define END_NODE \
+ FDTLONG(FDT_END_NODE) ;
+
+#define STRING(tree, name, str) \
+tree##_##name: ; \
+ .string str ;
+
+ .data
+
+ TREE_HDR(test_tree1)
+
+ .balign 8
+test_tree1_rsvmap:
+ RSVMAP_ENTRY(TEST_ADDR_1, TEST_SIZE_1)
+ RSVMAP_ENTRY(TEST_ADDR_2, TEST_SIZE_2)
+ RSVMAP_ENTRY(0, 0)
+test_tree1_rsvmap_end:
+
+test_tree1_struct:
+ BEGIN_NODE("")
+ PROP_STR(test_tree1, compatible, "test_tree1")
+ PROP_INT(test_tree1, prop_int, TEST_VALUE_1)
+ PROP_STR(test_tree1, prop_str, TEST_STRING_1)
+
+ BEGIN_NODE("subnode@1")
+ PROP_STR(test_tree1, compatible, "subnode1")
+ PROP_INT(test_tree1, prop_int, TEST_VALUE_1)
+
+ BEGIN_NODE("subsubnode")
+ PROP_STR(test_tree1, compatible, "subsubnode1\0subsubnode")
+ PROP_INT(test_tree1, prop_int, TEST_VALUE_1)
+ END_NODE
+ END_NODE
+
+ BEGIN_NODE("subnode@2")
+ PROP_INT(test_tree1, phandle, PHANDLE_1)
+ PROP_INT(test_tree1, prop_int, TEST_VALUE_2)
+
+ BEGIN_NODE("subsubnode@0")
+ PROP_INT(test_tree1, phandle, PHANDLE_2)
+ PROP_STR(test_tree1, compatible, "subsubnode2\0subsubnode")
+ PROP_INT(test_tree1, prop_int, TEST_VALUE_2)
+ END_NODE
+ END_NODE
+
+ END_NODE
+ FDTLONG(FDT_END)
+test_tree1_struct_end:
+
+test_tree1_strings:
+ STRING(test_tree1, compatible, "compatible")
+ STRING(test_tree1, prop_int, "prop-int")
+ STRING(test_tree1, prop_str, "prop-str")
+ STRING(test_tree1, phandle, "linux,phandle")
+test_tree1_strings_end:
+test_tree1_end:
+
+
+ TREE_HDR(truncated_property)
+ EMPTY_RSVMAP(truncated_property)
+
+truncated_property_struct:
+ BEGIN_NODE("")
+ PROPHDR(truncated_property, prop_truncated, 4)
+ /* Oops, no actual property data here */
+truncated_property_struct_end:
+
+truncated_property_strings:
+ STRING(truncated_property, prop_truncated, "truncated")
+truncated_property_strings_end:
+
+truncated_property_end:
+
+
+ TREE_HDR(bad_node_char)
+ EMPTY_RSVMAP(bad_node_char)
+
+bad_node_char_struct:
+ BEGIN_NODE("")
+ BEGIN_NODE("sub$node")
+ END_NODE
+ END_NODE
+ FDTLONG(FDT_END)
+bad_node_char_struct_end:
+
+bad_node_char_strings:
+bad_node_char_strings_end:
+bad_node_char_end:
+
+
+ TREE_HDR(bad_node_format)
+ EMPTY_RSVMAP(bad_node_format)
+
+bad_node_format_struct:
+ BEGIN_NODE("")
+ BEGIN_NODE("subnode@1@2")
+ END_NODE
+ END_NODE
+ FDTLONG(FDT_END)
+bad_node_format_struct_end:
+
+bad_node_format_strings:
+bad_node_format_strings_end:
+bad_node_format_end:
+
+
+ TREE_HDR(bad_prop_char)
+ EMPTY_RSVMAP(bad_prop_char)
+
+bad_prop_char_struct:
+ BEGIN_NODE("")
+ PROP_INT(bad_prop_char, prop, TEST_VALUE_1)
+ END_NODE
+ FDTLONG(FDT_END)
+bad_prop_char_struct_end:
+
+bad_prop_char_strings:
+ STRING(bad_prop_char, prop, "prop$erty")
+bad_prop_char_strings_end:
+bad_prop_char_end:
diff --git a/tests/truncated_property.c b/tests/truncated_property.c
new file mode 100644
index 000000000000..56daa2276be9
--- /dev/null
+++ b/tests/truncated_property.c
@@ -0,0 +1,48 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for misbehaviour on a truncated property
+ * Copyright (C) 2006 David Gibson, IBM Corporation.
+ *
+ * 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 <fdt.h>
+#include <libfdt.h>
+
+#include "tests.h"
+#include "testdata.h"
+
+int main(int argc, char *argv[])
+{
+ void *fdt = &_truncated_property;
+ const void *prop;
+ int len;
+
+ test_init(argc, argv);
+
+ prop = fdt_getprop(fdt, 0, "truncated", &len);
+ if (prop)
+ FAIL("fdt_getprop() succeeded on truncated property");
+ if (len != -FDT_ERR_BADSTRUCTURE)
+ FAIL("fdt_getprop() failed with \"%s\" instead of \"%s\"",
+ fdt_strerror(len), fdt_strerror(-FDT_ERR_BADSTRUCTURE));
+
+ PASS();
+}
diff --git a/tests/zero-phandle.dts b/tests/zero-phandle.dts
new file mode 100644
index 000000000000..7997d980d8a1
--- /dev/null
+++ b/tests/zero-phandle.dts
@@ -0,0 +1,7 @@
+/dts-v1/;
+
+/ {
+ node {
+ linux,phandle = <0>;
+ };
+};