diff options
| author | fishsoupisgood <github@madingley.org> | 2019-04-29 01:17:54 +0100 | 
|---|---|---|
| committer | fishsoupisgood <github@madingley.org> | 2019-05-27 03:43:43 +0100 | 
| commit | 3f2546b2ef55b661fd8dd69682b38992225e86f6 (patch) | |
| tree | 65ca85f13617aee1dce474596800950f266a456c /dtc/tests | |
| download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip | |
Diffstat (limited to 'dtc/tests')
164 files changed, 8349 insertions, 0 deletions
| diff --git a/dtc/tests/.gitignore b/dtc/tests/.gitignore new file mode 100644 index 00000000..bb5e33a2 --- /dev/null +++ b/dtc/tests/.gitignore @@ -0,0 +1,57 @@ +*.dtb +*.dts.test.s +*.test.dts +tmp.* +/add_subnode_with_nops +/appendprop[12] +/asm_tree_dump +/boot-cpuid +/char_literal +/del_node +/del_property +/dtbs_equal_ordered +/dtbs_equal_unordered +/dtb_reverse +/dumptrees +/extra-terminating-null +/find_property +/get_alias +/get_mem_rsv +/get_name +/get_path +/get_phandle +/getprop +/incbin +/integer-expressions +/mangle-layout +/move_and_save +/node_check_compatible +/node_offset_by_compatible +/node_offset_by_phandle +/node_offset_by_prop_value +/nop_node +/nop_property +/nopulate +/notfound +/open_pack +/parent_offset +/path-references +/path_offset +/path_offset_aliases +/phandle_format +/propname_escapes +/references +/root_node +/rw_tree1 +/set_name +/setprop +/setprop_inplace +/sized_cells +/string_escapes +/subnode_iterate +/subnode_offset +/supernode_atdepth_offset +/sw_tree1 +/truncated_property +/utilfdt_test +/value-labels diff --git a/dtc/tests/Makefile.tests b/dtc/tests/Makefile.tests new file mode 100644 index 00000000..dafb6184 --- /dev/null +++ b/dtc/tests/Makefile.tests @@ -0,0 +1,82 @@ +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 \ +	get_alias \ +	char_literal \ +	sized_cells \ +	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 \ +	appendprop1 appendprop2 propname_escapes \ +	string_escapes references path-references phandle_format \ +	boot-cpuid incbin \ +	extra-terminating-null \ +	dtbs_equal_ordered \ +	dtb_reverse dtbs_equal_unordered \ +	add_subnode_with_nops path_offset_aliases \ +	utilfdt_test \ +	integer-expressions \ +	subnode_iterate +LIB_TESTS = $(LIB_TESTS_L:%=$(TESTS_PREFIX)%) + +LIBTREE_TESTS_L = truncated_property +LIBTREE_TESTS = $(LIBTREE_TESTS_L:%=$(TESTS_PREFIX)%) + +DL_LIB_TESTS_L = asm_tree_dump value-labels +DL_LIB_TESTS = $(DL_LIB_TESTS_L:%=$(TESTS_PREFIX)%) + +TESTS = $(LIB_TESTS) $(LIBTREE_TESTS) $(DL_LIB_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_L += dumptrees +TESTS_CLEANFILES = $(TESTS) $(TESTS_CLEANFILES_L:%=$(TESTS_PREFIX)%) + +.PHONY: tests +tests:	$(TESTS) $(TESTS_TREES) + +$(LIB_TESTS): %: $(TESTS_PREFIX)testutils.o util.o $(LIBFDT_archive) + +$(DL_LIB_TESTS): %: %.o $(TESTS_PREFIX)testutils.o util.o $(LIBFDT_archive) +	@$(VECHO) LD [libdl] $@ +	$(LINK.c) -o $@ $^ -ldl + +$(LIBTREE_TESTS): %: $(TESTS_PREFIX)testutils.o $(TESTS_PREFIX)trees.o \ +		util.o $(LIBFDT_archive) + +$(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 ${TESTS_BIN} +	cd $(TESTS_PREFIX); ./run_tests.sh + +checkm: tests ${TESTS_BIN} +	cd $(TESTS_PREFIX); ./run_tests.sh -m 2>&1 | tee vglog.$$$$ + +checkv:	tests ${TESTS_BIN} +	cd $(TESTS_PREFIX); ./run_tests.sh -v + +ifneq ($(DEPTARGETS),) +-include $(TESTS_DEPFILES) +endif + diff --git a/dtc/tests/add_subnode_with_nops.c b/dtc/tests/add_subnode_with_nops.c new file mode 100644 index 00000000..95ddf6a5 --- /dev/null +++ b/dtc/tests/add_subnode_with_nops.c @@ -0,0 +1,84 @@ +/* + * 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 <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/dtc/tests/aliases.dts b/dtc/tests/aliases.dts new file mode 100644 index 00000000..39d88ffc --- /dev/null +++ b/dtc/tests/aliases.dts @@ -0,0 +1,21 @@ +/dts-v1/; + +/ { +	aliases { +		s1 = &sub1; +		ss1 = &subsub1; +		sss1 = &subsubsub1; +	}; + +	sub1: subnode@1 { +		compatible = "subnode1"; + +		subsub1: subsubnode { +			compatible = "subsubnode1", "subsubnode"; + +			subsubsub1: subsubsubnode { +				compatible = "subsubsubnode1", "subsubsubnode"; +			}; +		}; +	}; +}; diff --git a/dtc/tests/appendprop.dts b/dtc/tests/appendprop.dts new file mode 100644 index 00000000..f4bc730e --- /dev/null +++ b/dtc/tests/appendprop.dts @@ -0,0 +1,8 @@ +/dts-v1/; + +/ { +	prop-str = "hello world", "nastystring: \a\b\t\n\v\f\r\\\""; +	prop-int64 = /bits/ 64 <0xdeadbeef01abcdef 0xdeadbeef01abcdef>; +	prop-int = <0xdeadbeef 123456789>; +	prop-bytes = [00010203040001020304]; +}; diff --git a/dtc/tests/appendprop1.c b/dtc/tests/appendprop1.c new file mode 100644 index 00000000..9d6b3add --- /dev/null +++ b/dtc/tests/appendprop1.c @@ -0,0 +1,70 @@ +/* + * libfdt - Flat Device Tree manipulation + *	Testcase for fdt_appendprop() + * 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 <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; +	uint8_t bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04}; + +	test_init(argc, argv); + +	/* Create an empty tree first */ +	fdt = xmalloc(SPACE); +	CHECK(fdt_create(fdt, SPACE)); +	CHECK(fdt_finish_reservemap(fdt)); +	CHECK(fdt_begin_node(fdt, "")); +	CHECK(fdt_end_node(fdt)); +	CHECK(fdt_finish(fdt)); + +	/* Now use appendprop to add properties */ +	CHECK(fdt_open_into(fdt, fdt, SPACE)); + +	CHECK(fdt_appendprop(fdt, 0, "prop-bytes", bytes, sizeof(bytes))); +	CHECK(fdt_appendprop_cell(fdt, 0, "prop-int", TEST_VALUE_1)); +	CHECK(fdt_appendprop_u64(fdt, 0, "prop-int64", TEST_VALUE64_1)); +	CHECK(fdt_appendprop_string(fdt, 0, "prop-str", TEST_STRING_1)); + +	CHECK(fdt_pack(fdt)); + +	save_blob("appendprop1.test.dtb", fdt); + +	PASS(); +} diff --git a/dtc/tests/appendprop2.c b/dtc/tests/appendprop2.c new file mode 100644 index 00000000..ca1446c5 --- /dev/null +++ b/dtc/tests/appendprop2.c @@ -0,0 +1,64 @@ +/* + * libfdt - Flat Device Tree manipulation + *	Testcase for fdt_appendprop() + * 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 <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, *buf; +	int err; +	uint8_t bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04}; + +	test_init(argc, argv); +	fdt = load_blob_arg(argc, argv); + +	buf = xmalloc(SPACE); +	CHECK(fdt_open_into(fdt, buf, SPACE)); +	fdt = buf; + +	CHECK(fdt_appendprop(fdt, 0, "prop-bytes", bytes, sizeof(bytes))); +	CHECK(fdt_appendprop_cell(fdt, 0, "prop-int", TEST_VALUE_2)); +	CHECK(fdt_appendprop_u64(fdt, 0, "prop-int64", TEST_VALUE64_1)); +	CHECK(fdt_appendprop_string(fdt, 0, "prop-str", TEST_STRING_2)); + +	CHECK(fdt_pack(fdt)); + +	save_blob("appendprop2.test.dtb", fdt); + +	PASS(); +} diff --git a/dtc/tests/asm_tree_dump.c b/dtc/tests/asm_tree_dump.c new file mode 100644 index 00000000..bd12edaa --- /dev/null +++ b/dtc/tests/asm_tree_dump.c @@ -0,0 +1,61 @@ +/* + * libfdt - Flat Device Tree manipulation + *	Tests if an asm tree built into a shared object matches a given dtb + * 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 <errno.h> + +#include <dlfcn.h> + +#include <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +int main(int argc, char *argv[]) +{ +	void *sohandle; +	void *fdt; +	int err; + +	test_init(argc, argv); +	if (argc != 3) +		CONFIG("Usage: %s <so file> <dtb file>", argv[0]); + +	sohandle = dlopen(argv[1], RTLD_NOW); +	if (!sohandle) +		FAIL("Couldn't dlopen() %s", argv[1]); + +	fdt = dlsym(sohandle, "dt_blob_start"); +	if (!fdt) +		FAIL("Couldn't locate \"dt_blob_start\" symbol in %s", +		     argv[1]); + +	err = fdt_check_header(fdt); +	if (err != 0) +		FAIL("%s contains invalid tree: %s", argv[1], +		     fdt_strerror(err)); + +	save_blob(argv[2], fdt); + +	PASS(); +} diff --git a/dtc/tests/bad-empty-ranges.dts b/dtc/tests/bad-empty-ranges.dts new file mode 100644 index 00000000..2be7bc85 --- /dev/null +++ b/dtc/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/dtc/tests/bad-name-property.dts b/dtc/tests/bad-name-property.dts new file mode 100644 index 00000000..4fde4bef --- /dev/null +++ b/dtc/tests/bad-name-property.dts @@ -0,0 +1,7 @@ +/dts-v1/; + +/ { +	node@0 { +		name = "badthing"; +	}; +}; diff --git a/dtc/tests/bad-ncells.dts b/dtc/tests/bad-ncells.dts new file mode 100644 index 00000000..636198cb --- /dev/null +++ b/dtc/tests/bad-ncells.dts @@ -0,0 +1,7 @@ +/dts-v1/; + +/ { +	#address-cells = "badthing"; +	#size-cells = "badthing"; +	#interrupt-cells = "badthing"; +}; diff --git a/dtc/tests/bad-reg-ranges.dts b/dtc/tests/bad-reg-ranges.dts new file mode 100644 index 00000000..77419f5b --- /dev/null +++ b/dtc/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/dtc/tests/bad-string-props.dts b/dtc/tests/bad-string-props.dts new file mode 100644 index 00000000..396f8206 --- /dev/null +++ b/dtc/tests/bad-string-props.dts @@ -0,0 +1,7 @@ +/dts-v1/; + +/ { +	device_type = <0xdeadbeef>; +	model = <0xdeadbeef>; +	status = <0xdeadbeef>; +}; diff --git a/dtc/tests/base01.asm b/dtc/tests/base01.asm new file mode 100644 index 00000000..266e4465 --- /dev/null +++ b/dtc/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/dtc/tests/base01.cmd b/dtc/tests/base01.cmd new file mode 100644 index 00000000..e1fce6c8 --- /dev/null +++ b/dtc/tests/base01.cmd @@ -0,0 +1 @@ +dtc -f -b 0 -V 16 -I dts -O asm diff --git a/dtc/tests/base01.dts b/dtc/tests/base01.dts new file mode 100644 index 00000000..97a5dd50 --- /dev/null +++ b/dtc/tests/base01.dts @@ -0,0 +1,33 @@ +/dts-v1/; + +/ { +	model = "SomeModel"; +	compatible = "Nothing"; +	#address-cells = <2>; +	#size-cells = <2>; + +        memory@0 { +                device_type = "memory"; +		reg = <0x00000000 0x00000000 0x00000000 0x20000000>; +        }; + +	cpus { +		#address-cells = <1>; +		#size-cells = <0>; +		d10 = < 10>;		// hex: 0xa +		d23 = < 23>;		// hex: 0x17 +		b101 = < 0x5>;	// hex: 0x5 +		o17 = < 017>;		// hex: 0xf +		hd00d = < 0xd00d>;	// hex: 0xd00d + +		//   hex:  0x4d2    0x163e      0x2334    0xd80 +		stuff = < 1234     5678     9012     3456>; + + +		bad-d-1 = < 0>;		// Hrm. 0 +		bad-d-2 = < 123456789012345>; +		bad-o-1 = < 00>; +		bad-o-2 = < 0123456123456>; +	}; + +}; diff --git a/dtc/tests/base01.stderr b/dtc/tests/base01.stderr new file mode 100644 index 00000000..0510b0fb --- /dev/null +++ b/dtc/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/dtc/tests/boot-cpuid.c b/dtc/tests/boot-cpuid.c new file mode 100644 index 00000000..ca39f4b6 --- /dev/null +++ b/dtc/tests/boot-cpuid.c @@ -0,0 +1,47 @@ +/* + * 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 <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/dtc/tests/boot-cpuid.dts b/dtc/tests/boot-cpuid.dts new file mode 100644 index 00000000..7021a241 --- /dev/null +++ b/dtc/tests/boot-cpuid.dts @@ -0,0 +1,16 @@ +/dts-v1/; + +/ { +	cpus { +		cpu@10 { +			device_type = "cpu"; +			compatible = "fake-cpu"; +			reg = <0x10>; +		}; +		cpu@11 { +			device_type = "cpu"; +			compatible = "fake-cpu"; +			reg = <0x11>; +		}; +	}; +}; diff --git a/dtc/tests/char_literal.c b/dtc/tests/char_literal.c new file mode 100644 index 00000000..d7a47734 --- /dev/null +++ b/dtc/tests/char_literal.c @@ -0,0 +1,49 @@ +/* + * libfdt - Flat Device Tree manipulation + *	Testcase for character literals in dtc + * Copyright (C) 2006 David Gibson, IBM Corporation. + * Copyright (C) 2011 The Chromium Authors. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> + +#include <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +int main(int argc, char *argv[]) +{ +	void *fdt; +	uint32_t expected_cells[5]; + +	expected_cells[0] = cpu_to_fdt32((unsigned char)TEST_CHAR1); +	expected_cells[1] = cpu_to_fdt32((unsigned char)TEST_CHAR2); +	expected_cells[2] = cpu_to_fdt32((unsigned char)TEST_CHAR3); +	expected_cells[3] = cpu_to_fdt32((unsigned char)TEST_CHAR4); +	expected_cells[4] = cpu_to_fdt32((unsigned char)TEST_CHAR5); + +	test_init(argc, argv); +	fdt = load_blob_arg(argc, argv); + +	check_getprop(fdt, 0, "char-literal-cells", +		      sizeof(expected_cells), expected_cells); + +	PASS(); +} diff --git a/dtc/tests/char_literal.dts b/dtc/tests/char_literal.dts new file mode 100644 index 00000000..22e17eda --- /dev/null +++ b/dtc/tests/char_literal.dts @@ -0,0 +1,5 @@ +/dts-v1/; + +/ { +	char-literal-cells = <'\r' 'b' '\0' '\'' '\xff'>; +}; diff --git a/dtc/tests/comments-cmp.dts b/dtc/tests/comments-cmp.dts new file mode 100644 index 00000000..4ee9f52d --- /dev/null +++ b/dtc/tests/comments-cmp.dts @@ -0,0 +1,16 @@ +/dts-v1/; + +/ { +	prop1; +	prop2; +	prop3; +	prop4; +	prop5; +	prop6; +	prop7; +	prop8; +	prop9; +	prop10; +	child { +	}; +}; diff --git a/dtc/tests/comments.dts b/dtc/tests/comments.dts new file mode 100644 index 00000000..0b04b6b8 --- /dev/null +++ b/dtc/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/dtc/tests/data.S b/dtc/tests/data.S new file mode 100644 index 00000000..86ad539f --- /dev/null +++ b/dtc/tests/data.S @@ -0,0 +1,3 @@ +/* Used in combination with dtc -Oasm output to embed + * a device tree in the data section of a .o */ +	.data diff --git a/dtc/tests/default-addr-size.dts b/dtc/tests/default-addr-size.dts new file mode 100644 index 00000000..e964a553 --- /dev/null +++ b/dtc/tests/default-addr-size.dts @@ -0,0 +1,7 @@ +/dts-v1/; + +/ { +	node { +		reg = <0 0 0>; +	}; +}; diff --git a/dtc/tests/del_node.c b/dtc/tests/del_node.c new file mode 100644 index 00000000..45cb0601 --- /dev/null +++ b/dtc/tests/del_node.c @@ -0,0 +1,123 @@ +/* + * 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 <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/dtc/tests/del_property.c b/dtc/tests/del_property.c new file mode 100644 index 00000000..42fd7cb1 --- /dev/null +++ b/dtc/tests/del_property.c @@ -0,0 +1,90 @@ +/* + * 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 <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/dtc/tests/delete_reinstate_multilabel.dts b/dtc/tests/delete_reinstate_multilabel.dts new file mode 100644 index 00000000..281a6b28 --- /dev/null +++ b/dtc/tests/delete_reinstate_multilabel.dts @@ -0,0 +1,37 @@ +/dts-v1/; + +/* Create some nodes and properties with multiple labels */ + +/ { +	label1: label2: prop = "value"; + +	label3: label4: node { +		label5: label6: prop = "value"; +	}; +}; + +/* Delete them, and everything that's part of them, i.e. the labels */ + +/ { +	/delete-property/ prop; +	/delete-node/ node; +}; + +/* + * Re-instate them. None of the old labels should come back + * + * Note: Do not add any new/extra labels here. As of the time of writing, + * when dtc adds labels to an object, they are added to the head of the list + * of labels, and this test is specifically about ensuring the correct + * handling of lists of labels where the first label in the list is marked as + * deleted. Failure to observe this note may result in the test passing when + * it should not. + */ + +/ { +	prop = "value"; + +	node { +		prop = "value"; +	}; +}; diff --git a/dtc/tests/delete_reinstate_multilabel_ref.dts b/dtc/tests/delete_reinstate_multilabel_ref.dts new file mode 100644 index 00000000..28fa1174 --- /dev/null +++ b/dtc/tests/delete_reinstate_multilabel_ref.dts @@ -0,0 +1,9 @@ +/dts-v1/; + +/ { +	prop = "value"; + +	node { +		prop = "value"; +	}; +}; diff --git a/dtc/tests/dependencies.cmp b/dtc/tests/dependencies.cmp new file mode 100644 index 00000000..bcd94320 --- /dev/null +++ b/dtc/tests/dependencies.cmp @@ -0,0 +1 @@ +dependencies.test.dtb: dependencies.dts deps_inc1.dtsi deps_inc2.dtsi diff --git a/dtc/tests/dependencies.dts b/dtc/tests/dependencies.dts new file mode 100644 index 00000000..2cfe31bd --- /dev/null +++ b/dtc/tests/dependencies.dts @@ -0,0 +1,6 @@ +/dts-v1/; + +/include/ "deps_inc1.dtsi" + +/ { +}; diff --git a/dtc/tests/deps_inc1.dtsi b/dtc/tests/deps_inc1.dtsi new file mode 100644 index 00000000..5c607dcf --- /dev/null +++ b/dtc/tests/deps_inc1.dtsi @@ -0,0 +1 @@ +/include/ "deps_inc2.dtsi" diff --git a/dtc/tests/deps_inc2.dtsi b/dtc/tests/deps_inc2.dtsi new file mode 100644 index 00000000..710cecca --- /dev/null +++ b/dtc/tests/deps_inc2.dtsi @@ -0,0 +1 @@ +/* Empty */ diff --git a/dtc/tests/dtb_reverse.c b/dtc/tests/dtb_reverse.c new file mode 100644 index 00000000..527fd713 --- /dev/null +++ b/dtc/tests/dtb_reverse.c @@ -0,0 +1,163 @@ +/* + * libfdt - Flat Device Tree manipulation + *	Tests if two given dtbs are structurally equal (including order) + * Copyright (C) 2010 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 <limits.h> + +#include <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +#define CHECK(code) \ +	{ \ +		err = (code); \ +		if (err) \ +			FAIL(#code ": %s", fdt_strerror(err)); \ +	} + +static void reverse_reservemap(void *in, void *out, int n) +{ +	int err; +	uint64_t addr, size; + +	verbose_printf("reverse_reservemap(): %d/%d\n", +		       n, fdt_num_mem_rsv(in)); + +	if (n < (fdt_num_mem_rsv(in)-1)) +		reverse_reservemap(in, out, n+1); + +	CHECK(fdt_get_mem_rsv(in, n, &addr, &size)); +	CHECK(fdt_add_reservemap_entry(out, addr, size)); +	verbose_printf("Added entry 0x%llx 0x%llx\n", +		       (unsigned long long)addr, (unsigned long long)size); +} + +static void reverse_properties(void *in, void *out, int offset) +{ +	int err; +	int len; +	const char *name; +	const void *data; + +	data = fdt_getprop_by_offset(in, offset, &name, &len); +	if (!data) +		FAIL("fdt_getprop_by_offset(): %s\n", fdt_strerror(len)); + +	verbose_printf("reverse_properties(): offset=%d  name=%s\n", +		       offset, name); + +	offset = fdt_next_property_offset(in, offset); +	if (offset >= 0) +		reverse_properties(in, out, offset); +	else if (offset != -FDT_ERR_NOTFOUND) +		FAIL("fdt_next_property_offset(): %s\n", fdt_strerror(offset)); + +	CHECK(fdt_property(out, name, data, len)); +	verbose_printf("  -> output property %s\n", name); +} + +static void reverse_node(void *in, void *out, int nodeoffset); + +static void reverse_children(void *in, void *out, int offset) +{ +	int err; +	int nextoffset = offset; +	int depth = 1; + +	do { +		char path[PATH_MAX]; + +		CHECK(fdt_get_path(in, nextoffset, path, sizeof(path))); +		verbose_printf("reverse_children() offset=%d nextoffset=%d [%s]" +			       " depth=%d\n", offset, nextoffset, path, depth); + +		nextoffset = fdt_next_node(in, nextoffset, &depth); +	} while ((depth >= 0) && (depth != 1)); + +	if (depth == 1) +		reverse_children(in, out, nextoffset); + +	reverse_node(in, out, offset); +} + +static void reverse_node(void *in, void *out, int nodeoffset) +{ +	const char *name = fdt_get_name(in, nodeoffset, NULL); +	char path[PATH_MAX]; +	int err; +	int offset; +	int depth = 0; + +	CHECK(fdt_get_path(in, nodeoffset, path, sizeof(path))); +	verbose_printf("reverse_node(): nodeoffset=%d [%s]\n", +		       nodeoffset, path); + +	CHECK(fdt_begin_node(out, name)); + +	offset = fdt_first_property_offset(in, nodeoffset); +	if (offset >= 0) +		reverse_properties(in, out, offset); +	else if (offset != -FDT_ERR_NOTFOUND) +		FAIL("fdt_first_property(): %s\n", fdt_strerror(offset)); + +	offset = fdt_next_node(in, nodeoffset, &depth); + +	if (depth == 1) +		reverse_children(in, out, offset); + +	CHECK(fdt_end_node(out)); +} + +int main(int argc, char *argv[]) +{ +	void *in, *out; +	char outname[PATH_MAX]; +	int bufsize; +	int err; + +	test_init(argc, argv); +	if (argc != 2) +		CONFIG("Usage: %s <dtb file>", argv[0]); + +	in = load_blob(argv[1]); +	sprintf(outname, "%s.reversed.test.dtb", argv[1]); + +	bufsize = fdt_totalsize(in); +	out = xmalloc(bufsize); + +	CHECK(fdt_create(out, bufsize)); + +	fdt_set_boot_cpuid_phys(out, fdt_boot_cpuid_phys(in)); + +	reverse_reservemap(in, out, 0); +	CHECK(fdt_finish_reservemap(out)); + +	reverse_node(in, out, 0); + +	CHECK(fdt_finish(out)); + +	save_blob(outname, out); + +	PASS(); +} diff --git a/dtc/tests/dtbs_equal_ordered.c b/dtc/tests/dtbs_equal_ordered.c new file mode 100644 index 00000000..12495dea --- /dev/null +++ b/dtc/tests/dtbs_equal_ordered.c @@ -0,0 +1,173 @@ +/* + * 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +int notequal; /* = 0 */ + +#define MISMATCH(fmt, ...)			\ +	do { \ +		if (notequal) \ +			PASS(); \ +		else \ +			FAIL(fmt, ##__VA_ARGS__);	\ +	} while (0) + +#define MATCH()			\ +	do { \ +		if (!notequal) \ +			PASS(); \ +		else \ +			FAIL("Trees match which shouldn't");	\ +	} while (0) + +#define CHECK(code) \ +	{ \ +		err = (code); \ +		if (err) \ +			FAIL(#code ": %s", fdt_strerror(err)); \ +	} + +static 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)) +		MISMATCH("Trees have different number of reserve entries"); +	for (i = 0; i < fdt_num_mem_rsv(fdt1); i++) { +		CHECK(fdt_get_mem_rsv(fdt1, i, &addr1, &size1)); +		CHECK(fdt_get_mem_rsv(fdt2, i, &addr2, &size2)); + +		if ((addr1 != addr2) || (size1 != size2)) +			MISMATCH("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); +	} +} + +static 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) +			MISMATCH("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)) +			    MISMATCH("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)) +				MISMATCH("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) +				MISMATCH("Property length mismatch %u != %u " +					 "at (%d, %d)", len1, len2, offset1, offset2); + +			if (memcmp(prop1->data, prop2->data, len1) != 0) +				MISMATCH("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) +	    && ((argc != 4) || !streq(argv[1], "-n"))) +		CONFIG("Usage: %s [-n] <dtb file> <dtb file>", argv[0]); +	if (argc == 4) +		notequal = 1; + +	fdt1 = load_blob(argv[argc-2]); +	fdt2 = load_blob(argv[argc-1]); + +	compare_mem_rsv(fdt1, fdt2); +	compare_structure(fdt1, fdt2); + +	cpuid1 = fdt_boot_cpuid_phys(fdt1); +	cpuid2 = fdt_boot_cpuid_phys(fdt2); +	if (cpuid1 != cpuid2) +		MISMATCH("boot_cpuid_phys mismatch 0x%x != 0x%x", +			 cpuid1, cpuid2); + +	MATCH(); +} diff --git a/dtc/tests/dtbs_equal_unordered.c b/dtc/tests/dtbs_equal_unordered.c new file mode 100644 index 00000000..20b4356f --- /dev/null +++ b/dtc/tests/dtbs_equal_unordered.c @@ -0,0 +1,223 @@ +/* + * 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 <limits.h> + +#include <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +int notequal; /* = 0 */ + +#define MISMATCH(fmt, ...)			\ +	do { \ +		if (notequal) \ +			PASS(); \ +		else \ +			FAIL(fmt, ##__VA_ARGS__);	\ +	} while (0) + +#define MATCH()			\ +	do { \ +		if (!notequal) \ +			PASS(); \ +		else \ +			FAIL("Trees match which shouldn't");	\ +	} while (0) + +#define CHECK(code) \ +	{ \ +		err = (code); \ +		if (err) \ +			FAIL(#code ": %s", fdt_strerror(err)); \ +	} + +static int mem_rsv_cmp(const void *p1, const void *p2) +{ +	const struct fdt_reserve_entry *re1 = p1; +	const struct fdt_reserve_entry *re2 = p2; + +	if (re1->address < re2->address) +		return -1; +	else if (re1->address > re2->address) +		return 1; + +	if (re1->size < re2->size) +		return -1; +	else if (re1->size > re2->size) +		return 1; + +	return 0; +} + +static void compare_mem_rsv(void *fdt1, void *fdt2) +{ +	int i; +	uint64_t addr1, size1, addr2, size2; +	int err; + +	if (fdt_num_mem_rsv(fdt1) != fdt_num_mem_rsv(fdt2)) +		MISMATCH("Trees have different number of reserve entries"); + +	qsort((char *)fdt1 + fdt_off_mem_rsvmap(fdt1), fdt_num_mem_rsv(fdt1), +	      sizeof(struct fdt_reserve_entry), mem_rsv_cmp); +	qsort((char *)fdt2 + fdt_off_mem_rsvmap(fdt2), fdt_num_mem_rsv(fdt2), +	      sizeof(struct fdt_reserve_entry), mem_rsv_cmp); + +	for (i = 0; i < fdt_num_mem_rsv(fdt1); i++) { +		CHECK(fdt_get_mem_rsv(fdt1, i, &addr1, &size1)); +		CHECK(fdt_get_mem_rsv(fdt2, i, &addr2, &size2)); + +		if ((addr1 != addr2) || (size1 != size2)) +			MISMATCH("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); +	} +} + +static void compare_properties(const void *fdt1, int offset1, +			       const void *fdt2, int offset2) +{ +	int offset = offset1; + +	/* Check the properties */ +	for (offset = fdt_first_property_offset(fdt1, offset1); +	     offset >= 0; +	     offset = fdt_next_property_offset(fdt1, offset)) { +		const char *name; +		int len1, len2; +		const void *data1, *data2; +		int i; + +		data1 = fdt_getprop_by_offset(fdt1, offset, &name, &len1); +		if (!data1) +			FAIL("fdt_getprop_by_offset(): %s\n", +			     fdt_strerror(len1)); + +		verbose_printf("Property '%s'\n", name); + +		data2 = fdt_getprop(fdt2, offset2, name, &len2); +		if (!data2) { +			if (len2 == -FDT_ERR_NOTFOUND) +				MISMATCH("Property '%s' missing\n", name); +			else +				FAIL("fdt_get_property(): %s\n", +				     fdt_strerror(len2)); +		} + +		verbose_printf("len1=%d data1=", len1); +		for (i = 0; i < len1; i++) +			verbose_printf(" %02x", ((const char *)data1)[i]); +		verbose_printf("\nlen2=%d data2=", len2); +		for (i = 0; i < len1; i++) +			verbose_printf(" %02x", ((const char *)data2)[i]); +		verbose_printf("\n"); + +		if (len1 != len2) +			MISMATCH("Property '%s' mismatched length %d vs. %d\n", +			     name, len1, len2); +		else if (memcmp(data1, data2, len1) != 0) +			MISMATCH("Property '%s' mismatched value\n", name); +	} +} + +static void compare_node(const void *fdt1, int offset1, +			 const void *fdt2, int offset2); + +static void compare_subnodes(const void *fdt1, int offset1, +			     const void *fdt2, int offset2, +			     int recurse) +{ +	int coffset1, coffset2, depth; + +	for (depth = 0, coffset1 = offset1; +	     (coffset1 >= 0) && (depth >= 0); +	      coffset1 = fdt_next_node(fdt1, coffset1, &depth)) +		if (depth == 1) { +			const char *name = fdt_get_name(fdt1, coffset1, NULL); + +			verbose_printf("Subnode %s\n", name); +			coffset2 = fdt_subnode_offset(fdt2, offset2, name); +			if (coffset2 == -FDT_ERR_NOTFOUND) +				MISMATCH("Subnode %s missing\n", name); +			else if (coffset2 < 0) +				FAIL("fdt_subnode_offset(): %s\n", +				     fdt_strerror(coffset2)); + +			if (recurse) +				compare_node(fdt1, coffset1, fdt2, coffset2); +		} +} + +static void compare_node(const void *fdt1, int offset1, +			 const void *fdt2, int offset2) +{ +	int err; +	char path1[PATH_MAX], path2[PATH_MAX]; + +	CHECK(fdt_get_path(fdt1, offset1, path1, sizeof(path1))); +	CHECK(fdt_get_path(fdt2, offset2, path2, sizeof(path2))); + +	if (!streq(path1, path2)) +		TEST_BUG("Path mismatch %s vs. %s\n", path1, path2); + +	verbose_printf("Checking %s\n", path1); + +	compare_properties(fdt1, offset1, fdt2, offset2); +	compare_properties(fdt2, offset2, fdt1, offset1); + +	compare_subnodes(fdt1, offset1, fdt2, offset2, 1); +	compare_subnodes(fdt2, offset2, fdt1, offset1, 0); +} + +int main(int argc, char *argv[]) +{ +	void *fdt1, *fdt2; +	uint32_t cpuid1, cpuid2; + +	test_init(argc, argv); +	if ((argc != 3) +	    && ((argc != 4) || !streq(argv[1], "-n"))) +		CONFIG("Usage: %s [-n] <dtb file> <dtb file>", argv[0]); +	if (argc == 4) +		notequal = 1; + +	fdt1 = load_blob(argv[argc-2]); +	fdt2 = load_blob(argv[argc-1]); + +	compare_mem_rsv(fdt1, fdt2); +	compare_node(fdt1, 0, fdt2, 0); + +	cpuid1 = fdt_boot_cpuid_phys(fdt1); +	cpuid2 = fdt_boot_cpuid_phys(fdt2); +	if (cpuid1 != cpuid2) +		MISMATCH("boot_cpuid_phys mismatch 0x%x != 0x%x", +		     cpuid1, cpuid2); + +	MATCH(); +} diff --git a/dtc/tests/dtc-checkfails.sh b/dtc/tests/dtc-checkfails.sh new file mode 100755 index 00000000..76ded15c --- /dev/null +++ b/dtc/tests/dtc-checkfails.sh @@ -0,0 +1,44 @@ +#! /bin/sh + +. ./tests.sh + +for x; do +    shift +    if [ "$x" = "-n" ]; then +	for x; do +	    shift +	    if [ "$x" = "--" ]; then +		break; +	    fi +	    NOCHECKS="$NOCHECKS $x" +	done +	break; +    fi +    if [ "$x" = "--" ]; then +	break; +    fi +    YESCHECKS="$YESCHECKS $x" +done + +LOG=tmp.log.$$ +rm -f $LOG +trap "rm -f $LOG" 0 + +verbose_run_log "$LOG" $VALGRIND "$DTC" -o /dev/null "$@" +ret="$?" + +FAIL_IF_SIGNAL $ret + +for c in $YESCHECKS; do +    if ! grep -E "^(ERROR)|(Warning) \($c\):" $LOG > /dev/null; then +	FAIL "Failed to trigger check \"$c\"" +    fi +done + +for c in $NOCHECKS; do +    if grep -E "^(ERROR)|(Warning) \($c\):" $LOG > /dev/null; then +	FAIL "Incorrectly triggered check \"$c\"" +    fi +done + +PASS diff --git a/dtc/tests/dtc-fails.sh b/dtc/tests/dtc-fails.sh new file mode 100755 index 00000000..4ddcb273 --- /dev/null +++ b/dtc/tests/dtc-fails.sh @@ -0,0 +1,30 @@ +#! /bin/sh + +. ./tests.sh + +if [ "$1" = "-n" ]; then +    NEG="$1" +    shift +fi + +OUTPUT="$1" +shift + +verbose_run $VALGRIND "$DTC" -o "$OUTPUT" "$@" +ret="$?" + +FAIL_IF_SIGNAL $ret + +if [ -n "$NEG" ]; then +    if [ ! -e "$OUTPUT" ]; then +	FAIL "Produced no output" +    fi +else +    if [ -e "$OUTPUT" ]; then +	FAIL "Incorrectly produced output" +    fi +fi + +rm -f "$OUTPUT" + +PASS diff --git a/dtc/tests/dtc-fatal.sh b/dtc/tests/dtc-fatal.sh new file mode 100644 index 00000000..6781ced9 --- /dev/null +++ b/dtc/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/dtc/tests/dumptrees.c b/dtc/tests/dumptrees.c new file mode 100644 index 00000000..bebf553c --- /dev/null +++ b/dtc/tests/dumptrees.c @@ -0,0 +1,69 @@ +/* + * 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 <libfdt.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/dtc/tests/dup-nodename.dts b/dtc/tests/dup-nodename.dts new file mode 100644 index 00000000..2a3aa759 --- /dev/null +++ b/dtc/tests/dup-nodename.dts @@ -0,0 +1,8 @@ +/dts-v1/; + +/ { +	node { +	}; +	node { +	}; +}; diff --git a/dtc/tests/dup-phandle.dts b/dtc/tests/dup-phandle.dts new file mode 100644 index 00000000..c266c612 --- /dev/null +++ b/dtc/tests/dup-phandle.dts @@ -0,0 +1,10 @@ +/dts-v1/; + +/ { +	node1 { +		linux,phandle = <1>; +	}; +	node2 { +		linux,phandle = <1>; +	}; +}; diff --git a/dtc/tests/dup-propname.dts b/dtc/tests/dup-propname.dts new file mode 100644 index 00000000..8145f6e9 --- /dev/null +++ b/dtc/tests/dup-propname.dts @@ -0,0 +1,6 @@ +/dts-v1/; + +/ { +	prop; +	prop; +}; diff --git a/dtc/tests/empty.dts b/dtc/tests/empty.dts new file mode 100644 index 00000000..e160dad6 --- /dev/null +++ b/dtc/tests/empty.dts @@ -0,0 +1,4 @@ +/dts-v1/; + +/ { +}; diff --git a/dtc/tests/escapes.dts b/dtc/tests/escapes.dts new file mode 100644 index 00000000..e05ab46b --- /dev/null +++ b/dtc/tests/escapes.dts @@ -0,0 +1,7 @@ +/dts-v1/; + +/ { +	compatible = "test_string_escapes"; +	escape-str = "nastystring: \a\b\t\n\v\f\r\\\""; +	escape-str-2 = "\xde\xad\xbe\xef"; +}; diff --git a/dtc/tests/extra-terminating-null.c b/dtc/tests/extra-terminating-null.c new file mode 100644 index 00000000..dc1fe89a --- /dev/null +++ b/dtc/tests/extra-terminating-null.c @@ -0,0 +1,58 @@ +/* + * libfdt - Flat Device Tree manipulation + *	Testcase for properties with more than one terminating null + * Copyright (C) 2009 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static void check_extranull(void *fdt, const char *prop, const char *str, int numnulls) +{ +	int len = strlen(str); +	char checkbuf[len+numnulls]; + +	memset(checkbuf, 0, sizeof(checkbuf)); +	memcpy(checkbuf, TEST_STRING_1, len); + +	check_getprop(fdt, 0, prop, len+numnulls, checkbuf); +} + +int main(int argc, char *argv[]) +{ +	void *fdt; + +	test_init(argc, argv); + +	fdt = load_blob_arg(argc, argv); + +	check_extranull(fdt, "extranull0", TEST_STRING_1, 1); +	check_extranull(fdt, "extranull1,1", TEST_STRING_1, 2); +	check_extranull(fdt, "extranull1,2", TEST_STRING_1, 2); +	check_extranull(fdt, "extranull2,1", TEST_STRING_1, 3); +	check_extranull(fdt, "extranull2,2", TEST_STRING_1, 3); +	check_extranull(fdt, "extranull2,3", TEST_STRING_1, 3); +	check_extranull(fdt, "extranull2,4", TEST_STRING_1, 3); + +	PASS(); +} diff --git a/dtc/tests/extra-terminating-null.dts b/dtc/tests/extra-terminating-null.dts new file mode 100644 index 00000000..b6cc19c1 --- /dev/null +++ b/dtc/tests/extra-terminating-null.dts @@ -0,0 +1,11 @@ +/dts-v1/; + +/ { +	extranull0 = "hello world"; +	extranull1,1 = "hello world\0"; +	extranull1,2 = "hello world", ""; +	extranull2,1 = "hello world\0\0"; +	extranull2,2 = "hello world", "", ""; +	extranull2,3 = "hello world\0", ""; +	extranull2,4 = "hello world", "\0"; +}; diff --git a/dtc/tests/fdtget-runtest.sh b/dtc/tests/fdtget-runtest.sh new file mode 100755 index 00000000..8d8b0587 --- /dev/null +++ b/dtc/tests/fdtget-runtest.sh @@ -0,0 +1,24 @@ +#! /bin/sh + +. ./tests.sh + +LOG=tmp.log.$$ +EXPECT=tmp.expect.$$ +rm -f $LOG $EXPECT +trap "rm -f $LOG $EXPECT" 0 + +expect="$1" +printf '%b\n' "$expect" > $EXPECT +shift + +verbose_run_log_check "$LOG" $VALGRIND $DTGET "$@" + +if cmp $EXPECT $LOG>/dev/null; then +    PASS +else +    if [ -z "$QUIET_TEST" ]; then +	echo "EXPECTED :-:" +	cat $EXPECT +    fi +    FAIL "Results differ from expected" +fi diff --git a/dtc/tests/fdtput-runtest.sh b/dtc/tests/fdtput-runtest.sh new file mode 100644 index 00000000..527a9688 --- /dev/null +++ b/dtc/tests/fdtput-runtest.sh @@ -0,0 +1,39 @@ +#! /bin/sh + +# Run script for fdtput tests +# We run fdtput to update the device tree, thn fdtget to check it + +# Usage +#    fdtput-runtest.sh name expected_output dtb_file node property flags value + +. ./tests.sh + +LOG=tmp.log.$$ +EXPECT=tmp.expect.$$ +rm -f $LOG $EXPECT +trap "rm -f $LOG $EXPECT" 0 + +expect="$1" +echo $expect >$EXPECT +dtb="$2" +node="$3" +property="$4" +flags="$5" +shift 5 +value="$@" + +# First run fdtput +verbose_run_check $VALGRIND "$DTPUT" "$dtb" "$node" "$property" $value $flags + +# Now fdtget to read the value +verbose_run_log_check "$LOG" $VALGRIND "$DTGET" "$dtb" "$node" "$property" $flags + +if cmp $EXPECT $LOG >/dev/null; then +    PASS +else +    if [ -z "$QUIET_TEST" ]; then +	echo "EXPECTED :-:" +	cat $EXPECT +    fi +    FAIL "Results differ from expected" +fi diff --git a/dtc/tests/find_property.c b/dtc/tests/find_property.c new file mode 100644 index 00000000..4dc3030e --- /dev/null +++ b/dtc/tests/find_property.c @@ -0,0 +1,41 @@ +/* + * 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 <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/dtc/tests/get_alias.c b/dtc/tests/get_alias.c new file mode 100644 index 00000000..50607957 --- /dev/null +++ b/dtc/tests/get_alias.c @@ -0,0 +1,57 @@ +/* + * libfdt - Flat Device Tree manipulation + *	Testcase for fdt_get_alias() + * 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static void check_alias(void *fdt, const char *path, const char *alias) +{ +	const char *aliaspath; + +	aliaspath = fdt_get_alias(fdt, alias); + +	if (path && !aliaspath) +		FAIL("fdt_get_alias(%s) failed\n", alias); + +	if (strcmp(aliaspath, path) != 0) +		FAIL("fdt_get_alias(%s) returned %s instead of %s\n", +		     alias, aliaspath, path); +} + +int main(int argc, char *argv[]) +{ +	void *fdt; + +	test_init(argc, argv); +	fdt = load_blob_arg(argc, argv); + +	check_alias(fdt, "/subnode@1", "s1"); +	check_alias(fdt, "/subnode@1/subsubnode", "ss1"); +	check_alias(fdt, "/subnode@1/subsubnode/subsubsubnode", "sss1"); + +	PASS(); +} diff --git a/dtc/tests/get_mem_rsv.c b/dtc/tests/get_mem_rsv.c new file mode 100644 index 00000000..18126393 --- /dev/null +++ b/dtc/tests/get_mem_rsv.c @@ -0,0 +1,48 @@ +/* + * 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 <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/dtc/tests/get_name.c b/dtc/tests/get_name.c new file mode 100644 index 00000000..c6ca9f9b --- /dev/null +++ b/dtc/tests/get_name.c @@ -0,0 +1,82 @@ +/* + * 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static 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/dtc/tests/get_path.c b/dtc/tests/get_path.c new file mode 100644 index 00000000..73529765 --- /dev/null +++ b/dtc/tests/get_path.c @@ -0,0 +1,92 @@ +/* + * 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +#define POISON	('\xff') + +static 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); +	verbose_printf("get_path() %s -> %d -> %s\n", path, offset, buf); + +	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 != 0) +			FAIL("fdt_get_path([%d bytes]) returns %d " +			     "instead of 0", buflen, len); +		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); +} + +static 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); +	check_path_buf(fdt, path, pathlen, 0); +	check_path_buf(fdt, path, pathlen, 2); +} + +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/dtc/tests/get_phandle.c b/dtc/tests/get_phandle.c new file mode 100644 index 00000000..2079591d --- /dev/null +++ b/dtc/tests/get_phandle.c @@ -0,0 +1,57 @@ +/* + * 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static 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/dtc/tests/getprop.c b/dtc/tests/getprop.c new file mode 100644 index 00000000..6255badb --- /dev/null +++ b/dtc/tests/getprop.c @@ -0,0 +1,42 @@ +/* + * 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 <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/dtc/tests/incbin.bin b/dtc/tests/incbin.bin new file mode 100644 index 00000000..e6e3e48d --- /dev/null +++ b/dtc/tests/incbin.bin @@ -0,0 +1 @@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
\ No newline at end of file diff --git a/dtc/tests/incbin.c b/dtc/tests/incbin.c new file mode 100644 index 00000000..4100ba02 --- /dev/null +++ b/dtc/tests/incbin.c @@ -0,0 +1,75 @@ +/* + * 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +#define CHUNKSIZE	1024 + +static 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/dtc/tests/incbin.dts b/dtc/tests/incbin.dts new file mode 100644 index 00000000..7c30e0ec --- /dev/null +++ b/dtc/tests/incbin.dts @@ -0,0 +1,6 @@ +/dts-v1/; + +/ { +	incbin = /incbin/("incbin.bin"); +	incbin-partial = /incbin/("incbin.bin", 13, 17); +}; diff --git a/dtc/tests/include0.dts b/dtc/tests/include0.dts new file mode 100644 index 00000000..355ed6a9 --- /dev/null +++ b/dtc/tests/include0.dts @@ -0,0 +1 @@ +/include/ "include1.dts" diff --git a/dtc/tests/include1.dts b/dtc/tests/include1.dts new file mode 100644 index 00000000..893aaffe --- /dev/null +++ b/dtc/tests/include1.dts @@ -0,0 +1,27 @@ +/dts-v1/; + +/include/ "include2.dts" +/memreserve/ /include/ "include3.dts"; + +/ { +	/include/ "include4.dts" +	/include/ "include5.dts" = <0xdeadbeef>; +	prop-int64 /include/ "include5a.dts"; +	prop-str = /include/ "include6.dts"; + +	/include/ "include7.dts" + +	subnode@2 { +		linux,phandle = <0x2000>; +		prop-int = <123456789>; + +		/include/ "include8.dts" +			phandle = <0x2001>; +			compatible = "subsubnode2", "subsubnode"; +			prop-int = <0726746425>; +		}; + +		ss2 { +		}; +	}; +}; diff --git a/dtc/tests/include2.dts b/dtc/tests/include2.dts new file mode 100644 index 00000000..7e189dd7 --- /dev/null +++ b/dtc/tests/include2.dts @@ -0,0 +1 @@ +/memreserve/ 0xdeadbeef00000000 0x100000; diff --git a/dtc/tests/include3.dts b/dtc/tests/include3.dts new file mode 100644 index 00000000..ee9d277a --- /dev/null +++ b/dtc/tests/include3.dts @@ -0,0 +1 @@ +123456789 010000 diff --git a/dtc/tests/include4.dts b/dtc/tests/include4.dts new file mode 100644 index 00000000..b2ddbe5a --- /dev/null +++ b/dtc/tests/include4.dts @@ -0,0 +1 @@ +	compatible = "test_tree1"; diff --git a/dtc/tests/include5.dts b/dtc/tests/include5.dts new file mode 100644 index 00000000..9a35dc54 --- /dev/null +++ b/dtc/tests/include5.dts @@ -0,0 +1 @@ +prop-int diff --git a/dtc/tests/include5a.dts b/dtc/tests/include5a.dts new file mode 100644 index 00000000..39ddba4f --- /dev/null +++ b/dtc/tests/include5a.dts @@ -0,0 +1 @@ += /bits/ 64 <0xdeadbeef01abcdef>
\ No newline at end of file diff --git a/dtc/tests/include6.dts b/dtc/tests/include6.dts new file mode 100644 index 00000000..cd4bc1ab --- /dev/null +++ b/dtc/tests/include6.dts @@ -0,0 +1 @@ +"hello world" diff --git a/dtc/tests/include7.dts b/dtc/tests/include7.dts new file mode 100644 index 00000000..dba5e470 --- /dev/null +++ b/dtc/tests/include7.dts @@ -0,0 +1,12 @@ +	subnode@1 { +		compatible = "subnode1"; +		prop-int = [deadbeef]; + +		subsubnode { +			compatible = "subsubnode1", "subsubnode"; +			prop-int = <0xdeadbeef>; +		}; + +		ss1 { +		}; +	}; diff --git a/dtc/tests/include8.dts b/dtc/tests/include8.dts new file mode 100644 index 00000000..ec700643 --- /dev/null +++ b/dtc/tests/include8.dts @@ -0,0 +1 @@ +subsubnode@0 {
\ No newline at end of file diff --git a/dtc/tests/integer-expressions.c b/dtc/tests/integer-expressions.c new file mode 100644 index 00000000..57e2ff67 --- /dev/null +++ b/dtc/tests/integer-expressions.c @@ -0,0 +1,116 @@ +/* + * Testcase for dtc expression support + * + * 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 <errno.h> + + +#include <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +struct test_expr { +	const char *expr; +	uint32_t result; +} expr_table[] = { +#define TE(expr)	{ #expr, (expr) } +	TE(0xdeadbeef), +	TE(-0x21524111), +	TE(1+1), +	TE(2*3), +	TE(4/2), +	TE(10/3), +	TE(19%4), +	TE(1 << 13), +	TE(0x1000 >> 4), +	TE(3*2+1), TE(3*(2+1)), +	TE(1+2*3), TE((1+2)*3), +	TE(1 < 2), TE(2 < 1), TE(1 < 1), +	TE(1 <= 2), TE(2 <= 1), TE(1 <= 1), +	TE(1 > 2), TE(2 > 1), TE(1 > 1), +	TE(1 >= 2), TE(2 >= 1), TE(1 >= 1), +	TE(1 == 1), TE(1 == 2), +	TE(1 != 1), TE(1 != 2), +	TE(0xabcdabcd & 0xffff0000), +	TE(0xdead4110 ^ 0xf0f0f0f0), +	TE(0xabcd0000 | 0x0000abcd), +	TE(~0x21524110), +	TE(~~0xdeadbeef), +	TE(0 && 0), TE(17 && 0), TE(0 && 17), TE(17 && 17), +	TE(0 || 0), TE(17 || 0), TE(0 || 17), TE(17 || 17), +	TE(!0), TE(!1), TE(!17), TE(!!0), TE(!!17), +	TE(0 ? 17 : 39), TE(1 ? 17 : 39), TE(17 ? 0xdeadbeef : 0xabcd1234), +	TE(11 * 257 * 1321517ULL), +	TE(123456790 - 4/2 + 17%4), +}; + +#define ARRAY_SIZE(x)	(sizeof(x) / sizeof((x)[0])) + +int main(int argc, char *argv[]) +{ +	void *fdt; +	const uint32_t *res; +	int reslen; +	int i; + +	test_init(argc, argv); + +	if ((argc == 3) && (strcmp(argv[1], "-g") == 0)) { +		FILE *f = fopen(argv[2], "w"); + +		if (!f) +			FAIL("Couldn't open \"%s\" for output: %s\n", +			     argv[2], strerror(errno)); + +		fprintf(f, "/dts-v1/;\n"); +		fprintf(f, "/ {\n"); +		fprintf(f, "\texpressions = <\n"); +		for (i = 0; i < ARRAY_SIZE(expr_table); i++) +			fprintf(f, "\t\t(%s)\n", expr_table[i].expr); +		fprintf(f, "\t>;\n"); +		fprintf(f, "};\n"); +		fclose(f); +	} else { +		fdt = load_blob_arg(argc, argv); + +		res = fdt_getprop(fdt, 0, "expressions", &reslen); + +		if (!res) +			FAIL("Error retreiving expression results: %s\n", +		     fdt_strerror(reslen)); + +		if (reslen != (ARRAY_SIZE(expr_table) * sizeof(uint32_t))) +			FAIL("Unexpected length of results %d instead of %zd\n", +			     reslen, ARRAY_SIZE(expr_table) * sizeof(uint32_t)); + +		for (i = 0; i < ARRAY_SIZE(expr_table); i++) +			if (fdt32_to_cpu(res[i]) != expr_table[i].result) +				FAIL("Incorrect result for expression \"%s\"," +				     " 0x%x instead of 0x%x\n", +				     expr_table[i].expr, fdt32_to_cpu(res[i]), +				     expr_table[i].result); +	} + +	PASS(); +} diff --git a/dtc/tests/label01.dts b/dtc/tests/label01.dts new file mode 100644 index 00000000..a8958034 --- /dev/null +++ b/dtc/tests/label01.dts @@ -0,0 +1,63 @@ +/dts-v1/; + +/memreserve/ 0x1000000000000000 0x0000000002000000; +memrsv2: /memreserve/ 0x2000000000000000 0x0100000000000000; +/memreserve/ 0x0000000000000000 0x0000000000000014; + +/ { +	model = "MyBoardName"; +	compatible = "MyBoardName", "MyBoardFamilyName"; +	#address-cells = <2>; +	#size-cells = <2>; + +	cpus { +		linux,phandle = <0x1>; +		#address-cells = <1>; +		#size-cells = <0>; +		PowerPC,970@0 { +			name = "PowerPC,970"; +			device_type = "cpu"; +			reg = <0x00000000>; +			clock-frequency = <1600000000>; +			timebase-frequency = <33333333>; +			linux,boot-cpu; +			i-cache-size = <65536>; +			d-cache-size = <32768>; +		}; + +		PowerPC,970@1 { +			name = "PowerPC,970"; +			device_type = "cpu"; +			reg = <0x00000001>; +			clock-frequency = <1600000000>; +			timebase-frequency = <33333333>; +			i-cache-size = <65536>; +			d-cache-size = <32768>; +		}; + +	}; + +	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} 0x0 cell_mid: 0xffffffff cell_end: >; +		mixed = "abc", pre: [1234] post: , gap: < aligned: 0xa 0xb 0xc>; +		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 = <0x00000000 0x00000000 0x00000000 0x20000000>; +	}; + +	chosen { +		bootargs = "root=/dev/sda2"; +		linux,platform = <0x600>; +	}; + +}; + diff --git a/dtc/tests/label_repeated.dts b/dtc/tests/label_repeated.dts new file mode 100644 index 00000000..34225d33 --- /dev/null +++ b/dtc/tests/label_repeated.dts @@ -0,0 +1,15 @@ +/dts-v1/; + +/ { +	l0: prop = "foo"; + +	l1: node { +	}; +}; + +/ { +	l0: prop = "foo"; + +	l1: node { +	}; +}; diff --git a/dtc/tests/line_directives.dts b/dtc/tests/line_directives.dts new file mode 100644 index 00000000..046ef371 --- /dev/null +++ b/dtc/tests/line_directives.dts @@ -0,0 +1,21 @@ +/dts-v1/; + +/* common format */ +#line 3 "foo.dts" +/* newer gcc format */ +# 9 "baz.dts" 1 +/* flags are optional */ +# 6 "bar.dts" + +/ { +/* + * Make sure optional flags don't consume integer data on next line. The issue + * was that the {WS} in the trailing ({WS}+[0-9]+)? could cross the * line- + * break, and consume the leading "0" of the hex constant, leaving "x12345678" + * to be parsed as a number, which is invalid syntax. + */ +	prop1 = < +# 10 "qux.dts" +		0x12345678 +	>; +}; diff --git a/dtc/tests/lorem.txt b/dtc/tests/lorem.txt new file mode 100644 index 00000000..acff6983 --- /dev/null +++ b/dtc/tests/lorem.txt @@ -0,0 +1,35 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris eros +arcu, egestas non pellentesque non, euismod eu nibh. Proin arcu metus, +dapibus vitae sodales rhoncus, suscipit vel nulla. Etiam lorem est, +aliquam ut fringilla sit amet, condimentum et quam. Duis eu arcu odio, +at pulvinar nisi. Morbi condimentum eros ut turpis rhoncus +pharetra. Pellentesque habitant morbi tristique senectus et netus et +malesuada fames ac turpis egestas. Nam et nulla enim. Etiam fringilla +eleifend neque, at posuere ante lacinia a. Duis orci tortor, dictum ac +gravida ac, euismod eu leo. Sed eget dolor tortor. Pellentesque +venenatis, lectus eu vulputate porta, libero ipsum convallis mi, sit +amet vehicula arcu elit sit amet odio. + +Fusce iaculis massa metus, id sagittis diam. Praesent molestie ante +vel odio tincidunt auctor. Cum sociis natoque penatibus et magnis dis +parturient montes, nascetur ridiculus mus. Duis rutrum vehicula nisl +eget condimentum. In in justo nisl. Nullam id arcu at nisl eleifend +pretium. Nulla interdum ligula id elit mollis dictum a sit amet +quam. Nullam iaculis laoreet ipsum at tempus. Vestibulum in cursus +dui. Curabitur porta lectus eget urna bibendum congue eget elementum +nisi. Proin sit amet lectus ut neque iaculis consectetur eu sit amet +nibh. Maecenas rhoncus dolor ac nunc gravida blandit. Fusce sem felis, +aliquam a porttitor a, porta quis odio. + +Nunc purus lorem, sollicitudin non ultricies id, porta vitae +enim. Nulla tristique gravida leo ut suscipit. Phasellus vitae turpis +libero. Proin ac purus dolor, in suscipit magna. Sed et enim +arcu. Morbi semper aliquet suscipit. Aenean laoreet condimentum massa, +eu pharetra magna fermentum ut. Morbi euismod convallis tortor, eget +fringilla lacus sagittis non. Nullam bibendum posuere feugiat. + +In at pulvinar massa. Mauris nunc lectus, mollis et malesuada +pharetra, cursus sed lacus. Integer dolor urna, interdum a mollis at, +vestibulum non nisl. Sed in urna tortor. Mauris arcu felis, volutpat +quis euismod vel, congue sit amet ipsum. Morbi in aliquet purus. Duis +cras amet. diff --git a/dtc/tests/mangle-layout.c b/dtc/tests/mangle-layout.c new file mode 100644 index 00000000..a76e51e3 --- /dev/null +++ b/dtc/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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +struct bufstate { +	char *buf; +	int size; +}; + +static void expand_buf(struct bufstate *buf, int newsize) +{ +	buf->buf = realloc(buf->buf, newsize); +	if (!buf->buf) +		CONFIG("Allocation failure"); +	buf->size = newsize; +} + +static 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)); +} + +static void add_block(struct bufstate *buf, int version, char block, const void *fdt) +{ +	int align, size, oldsize; +	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); +	} + +	oldsize = buf->size; +	offset = ALIGN(oldsize, align); +	expand_buf(buf, offset+size); +	memset(buf->buf + oldsize, 0, offset - oldsize); + +	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/dtc/tests/mangle-layout.supp b/dtc/tests/mangle-layout.supp new file mode 100644 index 00000000..28904204 --- /dev/null +++ b/dtc/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/dtc/tests/minusone-phandle.dts b/dtc/tests/minusone-phandle.dts new file mode 100644 index 00000000..21d99867 --- /dev/null +++ b/dtc/tests/minusone-phandle.dts @@ -0,0 +1,7 @@ +/dts-v1/; + +/ { +	node { +		linux,phandle = <0xffffffff>; +	}; +}; diff --git a/dtc/tests/move_and_save.c b/dtc/tests/move_and_save.c new file mode 100644 index 00000000..393b60ac --- /dev/null +++ b/dtc/tests/move_and_save.c @@ -0,0 +1,75 @@ +/* + * 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 <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/dtc/tests/multilabel.dts b/dtc/tests/multilabel.dts new file mode 100644 index 00000000..31116cea --- /dev/null +++ b/dtc/tests/multilabel.dts @@ -0,0 +1,42 @@ +/dts-v1/; + +m1: mq: /memreserve/ 0 0x1000; + +/ { +	p0: pw: prop = "foo"; + +	/* Explicit phandles */ +	n1: nx: node1 { +		linux,phandle = <0x2000>; +		ref = <&{/node2}>; /* reference precedes target */ +		p1: px: lref = <&ny>; +	}; +	ny: n2: node2 { +		p2: py: phandle = <0x1>; +		ref = <&{/node1}>; /* reference after target */ +		lref = <&nx>; +	}; + +	/* Implicit phandles */ +	n3: node3 { +		p3: ref = <&{/node4}>; +		lref = <&n4>; +	}; +	n4: node4 { +		p4: prop; +	}; + +	/* Explicit phandle with implicit value */ +	/* This self-reference is the standard way to tag a node as requiring +	 * a phandle (perhaps for reference by nodes that will be dynamically +	 * added) without explicitly allocating it a phandle. +	 * The self-reference requires some special internal handling, though +	 * so check it actually works */ +	n5: nz: node5 { +		linux,phandle = <&n5>; +		phandle = <&nz>; +		n1 = &n1; +		n2 = &n2; +		n3 = &n3; +	}; +}; diff --git a/dtc/tests/multilabel_merge.dts b/dtc/tests/multilabel_merge.dts new file mode 100644 index 00000000..1632300e --- /dev/null +++ b/dtc/tests/multilabel_merge.dts @@ -0,0 +1,66 @@ +/dts-v1/; + +m1: mq: /memreserve/ 0 0x1000; + +/ { +	p0: pw: prop = "foo"; + +	/* Explicit phandles */ +	n1: node1 { +		linux,phandle = <0x2000>; +		ref = <&{/node2}>; /* reference precedes target */ +		p1: lref; +	}; +	node2 { +		phandle = <0x1>; +		ref = <&{/node1}>; /* reference after target */ +		lref = <&nx>; +	}; + +	/* Implicit phandles */ +	n3: node3 { +		p3: ref = <&{/node4}>; +		lref = <&n4>; +	}; +	n4: node4 { +		p4: prop = "foo"; +	}; + +	/* Explicit phandle with implicit value */ +	/* This self-reference is the standard way to tag a node as requiring +	 * a phandle (perhaps for reference by nodes that will be dynamically +	 * added) without explicitly allocating it a phandle. +	 * The self-reference requires some special internal handling, though +	 * so check it actually works */ +	n5: nz: node5 { +		linux,phandle = <&n5>; +		phandle = <&nz>; +		n1 = &n1; +		n2 = &n2; +		n3 = &n3; +	}; +}; + +/ { +	/* Append labels (also changes property content) */ +	nx: node1 { +		px: lref = <&ny>; +	}; + +	/* Add multiple labels */ +	ny: n2: node2 { +		/* Add a label to a property */ +		p2: py: phandle = <0x1>; +	}; + +	/* Reassigning the same label should be a no-op */ +	n3: node3 { +		p3: ref = <&{/node4}>; +	}; + +	/* Redefining a node/property should not remove labels */ +	node4 { +		prop; +	}; + +}; diff --git a/dtc/tests/node_check_compatible.c b/dtc/tests/node_check_compatible.c new file mode 100644 index 00000000..4bdf0919 --- /dev/null +++ b/dtc/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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static 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/dtc/tests/node_offset_by_compatible.c b/dtc/tests/node_offset_by_compatible.c new file mode 100644 index 00000000..f62b591c --- /dev/null +++ b/dtc/tests/node_offset_by_compatible.c @@ -0,0 +1,85 @@ +/* + * 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static 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/dtc/tests/node_offset_by_phandle.c b/dtc/tests/node_offset_by_phandle.c new file mode 100644 index 00000000..becff0fd --- /dev/null +++ b/dtc/tests/node_offset_by_phandle.c @@ -0,0 +1,63 @@ +/* + * 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static 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/dtc/tests/node_offset_by_prop_value.c b/dtc/tests/node_offset_by_prop_value.c new file mode 100644 index 00000000..9212a4ef --- /dev/null +++ b/dtc/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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static 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); +} + +static 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); +} + +static 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/dtc/tests/nonexist-label-ref.dts b/dtc/tests/nonexist-label-ref.dts new file mode 100644 index 00000000..25927a10 --- /dev/null +++ b/dtc/tests/nonexist-label-ref.dts @@ -0,0 +1,8 @@ +/dts-v1/; + +/ { +	ref = <&label>; +	badref = <&nosuchlabel>; +	label: node { +	}; +}; diff --git a/dtc/tests/nonexist-node-ref.dts b/dtc/tests/nonexist-node-ref.dts new file mode 100644 index 00000000..efd41404 --- /dev/null +++ b/dtc/tests/nonexist-node-ref.dts @@ -0,0 +1,8 @@ +/dts-v1/; + +/ { +	ref = < &{/node} >; +	badref = < &{/nosuchnode} >; +	label: node { +	}; +}; diff --git a/dtc/tests/nonexist-node-ref2.dts b/dtc/tests/nonexist-node-ref2.dts new file mode 100644 index 00000000..44b4ebeb --- /dev/null +++ b/dtc/tests/nonexist-node-ref2.dts @@ -0,0 +1,10 @@ +/dts-v1/; + +/ { +	label: node { +	}; +}; + +/* Try to redefine a node using a non-existent label */ +&nosuchnode { +}; diff --git a/dtc/tests/nop_node.c b/dtc/tests/nop_node.c new file mode 100644 index 00000000..c316444f --- /dev/null +++ b/dtc/tests/nop_node.c @@ -0,0 +1,104 @@ +/* + * 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 <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/dtc/tests/nop_property.c b/dtc/tests/nop_property.c new file mode 100644 index 00000000..644b0a66 --- /dev/null +++ b/dtc/tests/nop_property.c @@ -0,0 +1,70 @@ +/* + * 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 <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/dtc/tests/nopulate.c b/dtc/tests/nopulate.c new file mode 100644 index 00000000..cd79872b --- /dev/null +++ b/dtc/tests/nopulate.c @@ -0,0 +1,105 @@ +/* + * 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static 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/dtc/tests/notfound.c b/dtc/tests/notfound.c new file mode 100644 index 00000000..dc623d62 --- /dev/null +++ b/dtc/tests/notfound.c @@ -0,0 +1,70 @@ +/* + * 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static 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[]) +{ +	void *fdt; +	int offset; +	int subnode1_offset; +	int lenerr; + +	test_init(argc, argv); +	fdt = load_blob_arg(argc, argv); + +	fdt_get_property(fdt, 0, "nonexistant-property", &lenerr); +	check_error("fdt_get_property(\"nonexistant-property\")", lenerr); + +	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)); + +	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/dtc/tests/obsolete-chosen-interrupt-controller.dts b/dtc/tests/obsolete-chosen-interrupt-controller.dts new file mode 100644 index 00000000..36dd6e81 --- /dev/null +++ b/dtc/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/dtc/tests/open_pack.c b/dtc/tests/open_pack.c new file mode 100644 index 00000000..407ef6c5 --- /dev/null +++ b/dtc/tests/open_pack.c @@ -0,0 +1,71 @@ +/* + * 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 <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); +	/* don't leak uninitialized memory into our output */ +	memset(buf, 0, 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/dtc/tests/open_pack.supp b/dtc/tests/open_pack.supp new file mode 100644 index 00000000..c954fe78 --- /dev/null +++ b/dtc/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/dtc/tests/parent_offset.c b/dtc/tests/parent_offset.c new file mode 100644 index 00000000..d4ab3cff --- /dev/null +++ b/dtc/tests/parent_offset.c @@ -0,0 +1,90 @@ +/* + * 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static 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; +} + +static 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/dtc/tests/path-references.c b/dtc/tests/path-references.c new file mode 100644 index 00000000..0746b3f7 --- /dev/null +++ b/dtc/tests/path-references.c @@ -0,0 +1,82 @@ +/* + * 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static 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/dtc/tests/path-references.dts b/dtc/tests/path-references.dts new file mode 100644 index 00000000..91e7ef74 --- /dev/null +++ b/dtc/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/dtc/tests/path_offset.c b/dtc/tests/path_offset.c new file mode 100644 index 00000000..4e5b7a11 --- /dev/null +++ b/dtc/tests/path_offset.c @@ -0,0 +1,111 @@ +/* + * 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static 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); + +	if (subsubnode2_offset2 != subsubnode2_offset2_p) +		FAIL("Mismatch between subnode_offset (%d) and path_offset (%d)", +		     subsubnode2_offset2, subsubnode2_offset2_p); + +	PASS(); +} diff --git a/dtc/tests/path_offset_aliases.c b/dtc/tests/path_offset_aliases.c new file mode 100644 index 00000000..78d5a469 --- /dev/null +++ b/dtc/tests/path_offset_aliases.c @@ -0,0 +1,58 @@ +/* + * libfdt - Flat Device Tree manipulation + *	Testcase for fdt_path_offset() + * Copyright (C) 2006 David Gibson, IBM Corporation. + * Copyright 2008 Kumar Gala, Freescale Semiconductor, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> + +#include <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static void check_alias(void *fdt, const char *full_path, const char *alias_path) +{ +	int offset, offset_a; + +	offset = fdt_path_offset(fdt, full_path); +	offset_a = fdt_path_offset(fdt, alias_path); + +	if (offset != offset_a) +		FAIL("Mismatch between %s path_offset (%d) and %s path_offset alias (%d)", +		     full_path, offset, alias_path, offset_a); +} + +int main(int argc, char *argv[]) +{ +	void *fdt; + +	test_init(argc, argv); +	fdt = load_blob_arg(argc, argv); + +	check_alias(fdt, "/subnode@1", "s1"); +	check_alias(fdt, "/subnode@1/subsubnode", "ss1"); +	check_alias(fdt, "/subnode@1/subsubnode", "s1/subsubnode"); +	check_alias(fdt, "/subnode@1/subsubnode/subsubsubnode", "sss1"); +	check_alias(fdt, "/subnode@1/subsubnode/subsubsubnode", "ss1/subsubsubnode"); +	check_alias(fdt, "/subnode@1/subsubnode/subsubsubnode", "s1/subsubnode/subsubsubnode"); + +	PASS(); +} diff --git a/dtc/tests/phandle_format.c b/dtc/tests/phandle_format.c new file mode 100644 index 00000000..5874ae79 --- /dev/null +++ b/dtc/tests/phandle_format.c @@ -0,0 +1,77 @@ +/* + * libfdt - Flat Device Tree manipulation + *	Testcase for phandle format options + * Copyright (C) 2009 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +#define PHANDLE_LEGACY	0x1 +#define PHANDLE_EPAPR	0x2 +#define PHANDLE_BOTH	0x3 + +int main(int argc, char *argv[]) +{ +	void *fdt; +	int phandle_format; +	int n4; +	uint32_t h4; + +	if (argc != 3) +		CONFIG("Usage: %s <dtb file> <legacy|epapr|both>\n", argv[0]); + +	test_init(argc, argv); +	fdt = load_blob(argv[1]); + +	if (streq(argv[2], "legacy")) +		phandle_format = PHANDLE_LEGACY; +	else if (streq(argv[2], "epapr")) +		phandle_format = PHANDLE_EPAPR; +	else if (streq(argv[2], "both")) +		phandle_format = PHANDLE_BOTH; +	else +		CONFIG("Usage: %s <dtb file> <legacy|epapr|both>\n", argv[0]); + +	n4 = fdt_path_offset(fdt, "/node4"); +	if (n4 < 0) +		FAIL("fdt_path_offset(/node4): %s", fdt_strerror(n4)); + +	h4 = fdt_get_phandle(fdt, n4); +	if ((h4 == 0) || (h4 == -1)) +		FAIL("/node4 has bad phandle 0x%x\n", h4); + +	if (phandle_format & PHANDLE_LEGACY) +		check_getprop_cell(fdt, n4, "linux,phandle", h4); +	else +		if (fdt_getprop(fdt, n4, "linux,phandle", NULL)) +			FAIL("linux,phandle property present in non-legacy mode"); + +	if (phandle_format & PHANDLE_EPAPR) +		check_getprop_cell(fdt, n4, "phandle", h4); +	else +		if (fdt_getprop(fdt, n4, "phandle", NULL)) +			FAIL("phandle property present in legacy-only mode"); + +	PASS(); +} diff --git a/dtc/tests/prop-after-subnode.dts b/dtc/tests/prop-after-subnode.dts new file mode 100644 index 00000000..6dd0b660 --- /dev/null +++ b/dtc/tests/prop-after-subnode.dts @@ -0,0 +1,9 @@ +/dts-v1/; + +/ { +	node1 { +	}; +	prop; +	node2 { +	}; +}; diff --git a/dtc/tests/propname_escapes.c b/dtc/tests/propname_escapes.c new file mode 100644 index 00000000..e91bd994 --- /dev/null +++ b/dtc/tests/propname_escapes.c @@ -0,0 +1,42 @@ +/* + * libfdt - Flat Device Tree manipulation + *	Testcase for fdt_getprop() + * Copyright (C) 2006 David Gibson, IBM Corporation. + * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> + +#include <libfdt.h> + +#include "tests.h" + +int main(int argc, char *argv[]) +{ +	void *fdt; + +	test_init(argc, argv); +	fdt = load_blob_arg(argc, argv); + +	check_getprop_cell(fdt, 0, "#address-cells", 1); +	check_getprop_cell(fdt, 0, "#gpio-cells", 2); + +	PASS(); +} diff --git a/dtc/tests/propname_escapes.dts b/dtc/tests/propname_escapes.dts new file mode 100644 index 00000000..9f70618b --- /dev/null +++ b/dtc/tests/propname_escapes.dts @@ -0,0 +1,6 @@ +/dts-v1/; + +/ { +	#address-cells = <1>; +	\#gpio-cells = <2>; +}; diff --git a/dtc/tests/references.c b/dtc/tests/references.c new file mode 100644 index 00000000..c9d05a2f --- /dev/null +++ b/dtc/tests/references.c @@ -0,0 +1,108 @@ +/* + * 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static 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, n5; +	uint32_t h1, h2, h4, h5; + +	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)); +	n5 = fdt_path_offset(fdt, "/node5"); +	if (n5 < 0) +		FAIL("fdt_path_offset(/node5): %s", fdt_strerror(n5)); + +	h1 = fdt_get_phandle(fdt, n1); +	h2 = fdt_get_phandle(fdt, n2); +	h4 = fdt_get_phandle(fdt, n4); +	h5 = fdt_get_phandle(fdt, n5); + +	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); + +	if ((h5 == 0) || (h5 == -1)) +		FAIL("/node5 has bad phandle, 0x%x", h5); +	if ((h5 == h4) || (h5 == h2) || (h5 == h1)) +		FAIL("/node5 has duplicate phandle, 0x%x", h5); + +	check_ref(fdt, n1, h2); +	check_ref(fdt, n2, h1); +	check_ref(fdt, n3, h4); + +	PASS(); +} diff --git a/dtc/tests/references.dts b/dtc/tests/references.dts new file mode 100644 index 00000000..640c9315 --- /dev/null +++ b/dtc/tests/references.dts @@ -0,0 +1,34 @@ +/dts-v1/; + +/ { +	/* Explicit phandles */ +	n1: node1 { +		linux,phandle = <0x2000>; +		ref = <&{/node2}>; /* reference precedes target */ +		lref = <&n2>; +	}; +	n2: node2 { +		phandle = <0x1>; +		ref = <&{/node1}>; /* reference after target */ +		lref = <&n1>; +	}; + +	/* Implicit phandles */ +	n3: node3 { +		ref = <&{/node4}>; +		lref = <&n4>; +	}; +	n4: node4 { +	}; + +	/* Explicit phandle with implicit value */ +	/* This self-reference is the standard way to tag a node as requiring +	 * a phandle (perhaps for reference by nodes that will be dynamically +	 * added) without explicitly allocating it a phandle. +	 * The self-reference requires some special internal handling, though +	 * so check it actually works */ +	n5: node5 { +		linux,phandle = <&n5>; +		phandle = <&n5>; +	}; +}; diff --git a/dtc/tests/reg-ranges-root.dts b/dtc/tests/reg-ranges-root.dts new file mode 100644 index 00000000..9935b415 --- /dev/null +++ b/dtc/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/dtc/tests/reuse-label.dts b/dtc/tests/reuse-label.dts new file mode 100644 index 00000000..98b5ca9d --- /dev/null +++ b/dtc/tests/reuse-label.dts @@ -0,0 +1,15 @@ +/dts-v1/; + +/ { +	label: property1 = "foo"; +	label: property2 = "bar"; + +	test1 = &label; + +	label: node1 { +		prop = "foo"; +	}; +	label: node2 { +		prop = "bar"; +	}; +}; diff --git a/dtc/tests/reuse-label1.dts b/dtc/tests/reuse-label1.dts new file mode 100644 index 00000000..f2295693 --- /dev/null +++ b/dtc/tests/reuse-label1.dts @@ -0,0 +1,10 @@ +/dts-v1/; + +/ { +	label: node1 { +		prop = "foo"; +	}; +	label: node2 { +		prop = "bar"; +	}; +}; diff --git a/dtc/tests/reuse-label2.dts b/dtc/tests/reuse-label2.dts new file mode 100644 index 00000000..01ea6b27 --- /dev/null +++ b/dtc/tests/reuse-label2.dts @@ -0,0 +1,6 @@ +/dts-v1/; + +/ { +	label: property1 = "foo"; +	label: property2 = "bar"; +}; diff --git a/dtc/tests/reuse-label3.dts b/dtc/tests/reuse-label3.dts new file mode 100644 index 00000000..fa3d2c72 --- /dev/null +++ b/dtc/tests/reuse-label3.dts @@ -0,0 +1,9 @@ +/dts-v1/; + +/ { +	label: property = "foo"; + +	label: node { +		property = "foo"; +	}; +}; diff --git a/dtc/tests/reuse-label4.dts b/dtc/tests/reuse-label4.dts new file mode 100644 index 00000000..6805de32 --- /dev/null +++ b/dtc/tests/reuse-label4.dts @@ -0,0 +1,5 @@ +/dts-v1/; + +/ { +	property = label: "foo" label:; +}; diff --git a/dtc/tests/reuse-label5.dts b/dtc/tests/reuse-label5.dts new file mode 100644 index 00000000..b7238e64 --- /dev/null +++ b/dtc/tests/reuse-label5.dts @@ -0,0 +1,6 @@ +/dts-v1/; + +/ { +	prop1 = label: "foo"; +	prop2 = "bar" label:; +}; diff --git a/dtc/tests/reuse-label6.dts b/dtc/tests/reuse-label6.dts new file mode 100644 index 00000000..f5d507c6 --- /dev/null +++ b/dtc/tests/reuse-label6.dts @@ -0,0 +1,6 @@ +/dts-v1/; + +/ { +	label: prop1 = "foo"; +	prop2 = "bar" label:; +}; diff --git a/dtc/tests/root_node.c b/dtc/tests/root_node.c new file mode 100644 index 00000000..58aebf6b --- /dev/null +++ b/dtc/tests/root_node.c @@ -0,0 +1,52 @@ +/* + * 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 <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/dtc/tests/run_tests.sh b/dtc/tests/run_tests.sh new file mode 100755 index 00000000..c0a136bc --- /dev/null +++ b/dtc/tests/run_tests.sh @@ -0,0 +1,644 @@ +#! /bin/sh + +. ./tests.sh + +if [ -z "$CC" ]; then +    CC=gcc +fi + +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" -eq 1 ]; then +	    tot_config=$((tot_config + 1)) +	elif [ "$ret" -eq 2 ]; then +	    tot_fail=$((tot_fail + 1)) +	elif [ "$ret" -eq $VGCODE ]; then +	    tot_vg=$((tot_vg + 1)) +	else +	    tot_strange=$((tot_strange + 1)) +	fi +    fi +} + +shorten_echo () { +    limit=32 +    echo -n "$1" +    shift +    for x; do +	if [ ${#x} -le $limit ]; then +	    echo -n " $x" +	else +	    short=$(echo "$x" | head -c$limit) +	    echo -n " \"$short\"...<${#x} bytes>" +	fi +    done +} + +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 () { +    shorten_echo "$@:	" +    base_run_test wrap_test "$@" +} + +wrap_error () { +    ( +	if verbose_run "$@"; then +	    FAIL "Expected non-zero return code" +	else +	    ret="$?" +	    if [ "$ret" -gt 127 ]; then +		signame=$(kill -l $((ret - 128))) +		FAIL "Killed by SIG$signame" +	    else +		PASS +	    fi +	fi +    ) +} + +run_wrap_error_test () { +    shorten_echo "$@" +    echo -n " {!= 0}:	" +    base_run_test wrap_error "$@" +} + +run_dtc_test () { +    echo -n "dtc $@:	" +    base_run_test wrap_test $VALGRIND $DTC "$@" +} + +asm_to_so () { +    $CC -shared -o $1.test.so data.S $1.test.s +} + +asm_to_so_test () { +    run_wrap_test asm_to_so "$@" +} + +run_fdtget_test () { +    expect="$1" +    shift +    echo -n "fdtget-runtest.sh "$expect" $@:	" +    base_run_test sh fdtget-runtest.sh "$expect" "$@" +} + +run_fdtput_test () { +    expect="$1" +    shift +    shorten_echo fdtput-runtest.sh "$expect" "$@" +    echo -n ":	" +    base_run_test sh fdtput-runtest.sh "$expect" "$@" +} + +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 +    run_test appendprop1 +    run_test appendprop2 appendprop1.test.dtb +    run_dtc_test -I dts -O dtb -o appendprop.test.dtb appendprop.dts +    run_test dtbs_equal_ordered appendprop2.test.dtb appendprop.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 + +    run_dtc_test -I dts -O dtb -o subnode_iterate.dtb subnode_iterate.dts +    run_test subnode_iterate subnode_iterate.dtb + +    # 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_escapes.test.dtb propname_escapes.dts +    run_test propname_escapes dtc_escapes.test.dtb + +    run_dtc_test -I dts -O dtb -o line_directives.test.dtb line_directives.dts + +    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_char_literal.test.dtb char_literal.dts +    run_test char_literal dtc_char_literal.test.dtb + +    run_dtc_test -I dts -O dtb -o dtc_sized_cells.test.dtb sized_cells.dts +    run_test sized_cells dtc_sized_cells.test.dtb + +    run_dtc_test -I dts -O dtb -o dtc_extra-terminating-null.test.dtb extra-terminating-null.dts +    run_test extra-terminating-null dtc_extra-terminating-null.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_path-references.test.dtb path-references.dts +    run_test path-references dtc_path-references.test.dtb + +    run_test phandle_format dtc_references.test.dtb both +    for f in legacy epapr both; do +	run_dtc_test -I dts -O dtb -H $f -o dtc_references.test.$f.dtb references.dts +	run_test phandle_format dtc_references.test.$f.dtb $f +    done + +    run_dtc_test -I dts -O dtb -o multilabel.test.dtb multilabel.dts +    run_test references multilabel.test.dtb + +    run_dtc_test -I dts -O dtb -o label_repeated.test.dtb label_repeated.dts + +    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 aliases support in fdt_path_offset +    run_dtc_test -I dts -O dtb -o aliases.dtb aliases.dts +    run_test get_alias aliases.dtb +    run_test path_offset_aliases aliases.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 -o boot_cpuid.test.dtb boot-cpuid.dts +    run_test boot-cpuid boot_cpuid.test.dtb 16 + +    run_dtc_test -I dts -O dtb -b 17 -o boot_cpuid_17.test.dtb boot-cpuid.dts +    run_test boot-cpuid boot_cpuid_17.test.dtb 17 + +    run_dtc_test -I dtb -O dtb -o preserve_boot_cpuid.test.dtb boot_cpuid.test.dtb +    run_test boot-cpuid preserve_boot_cpuid.test.dtb 16 +    run_test dtbs_equal_ordered preserve_boot_cpuid.test.dtb boot_cpuid.test.dtb + +    run_dtc_test -I dtb -O dtb -o preserve_boot_cpuid_17.test.dtb boot_cpuid_17.test.dtb +    run_test boot-cpuid preserve_boot_cpuid_17.test.dtb 17 +    run_test dtbs_equal_ordered preserve_boot_cpuid_17.test.dtb boot_cpuid_17.test.dtb + +    run_dtc_test -I dtb -O dtb -b17 -o override17_boot_cpuid.test.dtb boot_cpuid.test.dtb +    run_test boot-cpuid override17_boot_cpuid.test.dtb 17 + +    run_dtc_test -I dtb -O dtb -b0 -o override0_boot_cpuid_17.test.dtb boot_cpuid_17.test.dtb +    run_test boot-cpuid override0_boot_cpuid_17.test.dtb 0 + + +    # Check -Oasm mode +    for tree in test_tree1.dts escapes.dts references.dts path-references.dts \ +	comments.dts aliases.dts include0.dts incbin.dts \ +	value-labels.dts ; do +	run_dtc_test -I dts -O asm -o oasm_$tree.test.s $tree +	asm_to_so_test oasm_$tree +	run_dtc_test -I dts -O dtb -o $tree.test.dtb $tree +	run_test asm_tree_dump ./oasm_$tree.test.so oasm_$tree.test.dtb +	run_wrap_test cmp oasm_$tree.test.dtb $tree.test.dtb +    done + +    run_test value-labels ./oasm_value-labels.dts.test.so + +    # Check -Odts mode preserve all dtb information +    for tree in test_tree1.dtb dtc_tree1.test.dtb dtc_escapes.test.dtb \ +	dtc_extra-terminating-null.test.dtb dtc_references.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 merge/overlay functionality +    run_dtc_test -I dts -O dtb -o dtc_tree1_merge.test.dtb test_tree1_merge.dts +    tree1_tests dtc_tree1_merge.test.dtb test_tree1.dtb +    run_dtc_test -I dts -O dtb -o dtc_tree1_merge_labelled.test.dtb test_tree1_merge_labelled.dts +    tree1_tests dtc_tree1_merge_labelled.test.dtb test_tree1.dtb +    run_dtc_test -I dts -O dtb -o multilabel_merge.test.dtb multilabel_merge.dts +    run_test references multilabel.test.dtb +    run_test dtbs_equal_ordered multilabel.test.dtb multilabel_merge.test.dtb +    run_dtc_test -I dts -O dtb -o dtc_tree1_merge_path.test.dtb test_tree1_merge_path.dts +    tree1_tests dtc_tree1_merge_path.test.dtb test_tree1.dtb + +    # Check prop/node delete functionality +    run_dtc_test -I dts -O dtb -o dtc_tree1_delete.test.dtb test_tree1_delete.dts +    tree1_tests dtc_tree1_delete.test.dtb + +    run_dtc_test -I dts -O dts -o delete_reinstate_multilabel.dts.test.dts delete_reinstate_multilabel.dts +    run_wrap_test cmp delete_reinstate_multilabel.dts.test.dts delete_reinstate_multilabel_ref.dts + +    # 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 +    run_sh_test dtc-fatal.sh -I dts -O dtb nonexist-node-ref2.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 + +    run_sh_test dtc-checkfails.sh duplicate_label -- -I dts -O dtb reuse-label1.dts +    run_sh_test dtc-checkfails.sh duplicate_label -- -I dts -O dtb reuse-label2.dts +    run_sh_test dtc-checkfails.sh duplicate_label -- -I dts -O dtb reuse-label3.dts +    run_sh_test dtc-checkfails.sh duplicate_label -- -I dts -O dtb reuse-label4.dts +    run_sh_test dtc-checkfails.sh duplicate_label -- -I dts -O dtb reuse-label5.dts +    run_sh_test dtc-checkfails.sh duplicate_label -- -I dts -O dtb reuse-label6.dts + +    # Check warning options +    run_sh_test dtc-checkfails.sh address_cells_is_cell interrupt_cells_is_cell -n size_cells_is_cell -- -Wno_size_cells_is_cell -I dts -O dtb bad-ncells.dts +    run_sh_test dtc-fails.sh -n test-warn-output.test.dtb -I dts -O dtb bad-ncells.dts +    run_sh_test dtc-fails.sh test-error-output.test.dtb -I dts -O dtb bad-ncells.dts -Esize_cells_is_cell +    run_sh_test dtc-checkfails.sh always_fail -- -Walways_fail -I dts -O dtb test_tree1.dts +    run_sh_test dtc-checkfails.sh -n always_fail -- -Walways_fail -Wno_always_fail -I dts -O dtb test_tree1.dts +    run_sh_test dtc-fails.sh test-negation-1.test.dtb -Ealways_fail -I dts -O dtb test_tree1.dts +    run_sh_test dtc-fails.sh -n test-negation-2.test.dtb -Ealways_fail -Eno_always_fail -I dts -O dtb test_tree1.dts +    run_sh_test dtc-fails.sh test-negation-3.test.dtb -Ealways_fail -Wno_always_fail -I dts -O dtb test_tree1.dts +    run_sh_test dtc-fails.sh -n test-negation-4.test.dtb -Esize_cells_is_cell -Eno_size_cells_is_cell -I dts -O dtb bad-ncells.dts +    run_sh_test dtc-checkfails.sh size_cells_is_cell -- -Esize_cells_is_cell -Eno_size_cells_is_cell -I dts -O dtb bad-ncells.dts + +    # 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 integer expresisons +    run_test integer-expressions -g integer-expressions.test.dts +    run_dtc_test -I dts -O dtb -o integer-expressions.test.dtb integer-expressions.test.dts +    run_test integer-expressions integer-expressions.test.dtb + +    # 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 + +    # Dependencies +    run_dtc_test -I dts -O dtb -o dependencies.test.dtb -d dependencies.test.d dependencies.dts +    run_wrap_test cmp dependencies.test.d dependencies.cmp + +    # Search paths +    run_wrap_error_test $DTC -I dts -O dtb -o search_paths.dtb search_paths.dts +    run_dtc_test -i search_dir -I dts -O dtb -o search_paths.dtb \ +	search_paths.dts +    run_wrap_error_test $DTC -i search_dir_b -I dts -O dtb \ +	-o search_paths_b.dtb search_paths_b.dts +    run_dtc_test -i search_dir_b -i search_dir -I dts -O dtb \ +	-o search_paths_b.dtb search_paths_b.dts +    run_dtc_test -I dts -O dtb -o search_paths_subdir.dtb \ +	search_dir_b/search_paths_subdir.dts +} + +cmp_tests () { +    basetree="$1" +    shift +    wrongtrees="$@" + +    run_test dtb_reverse $basetree + +    # First dtbs_equal_ordered +    run_test dtbs_equal_ordered $basetree $basetree +    run_test dtbs_equal_ordered -n $basetree $basetree.reversed.test.dtb +    for tree in $wrongtrees; do +	run_test dtbs_equal_ordered -n $basetree $tree +    done + +    # now unordered +    run_test dtbs_equal_unordered $basetree $basetree +    run_test dtbs_equal_unordered $basetree $basetree.reversed.test.dtb +    run_test dtbs_equal_unordered $basetree.reversed.test.dtb $basetree +    for tree in $wrongtrees; do +	run_test dtbs_equal_unordered -n $basetree $tree +    done + +    # now dtc --sort +    run_dtc_test -I dtb -O dtb -s -o $basetree.sorted.test.dtb $basetree +    run_test dtbs_equal_unordered $basetree $basetree.sorted.test.dtb +    run_dtc_test -I dtb -O dtb -s -o $basetree.reversed.sorted.test.dtb $basetree.reversed.test.dtb +    run_test dtbs_equal_unordered $basetree.reversed.test.dtb $basetree.reversed.sorted.test.dtb +    run_test dtbs_equal_ordered $basetree.sorted.test.dtb $basetree.reversed.sorted.test.dtb +} + +dtbs_equal_tests () { +    WRONG_TREE1="" +    for x in 1 2 3 4 5 6 7 8 9; do +	run_dtc_test -I dts -O dtb -o test_tree1_wrong$x.test.dtb test_tree1_wrong$x.dts +	WRONG_TREE1="$WRONG_TREE1 test_tree1_wrong$x.test.dtb" +    done +    cmp_tests test_tree1.dtb $WRONG_TREE1 +} + +fdtget_tests () { +    dts=label01.dts +    dtb=$dts.fdtget.test.dtb +    run_dtc_test -O dtb -o $dtb $dts + +    # run_fdtget_test <expected-result> [<flags>] <file> <node> <property> +    run_fdtget_test "MyBoardName" $dtb / model +    run_fdtget_test "MyBoardName MyBoardFamilyName" $dtb / compatible +    run_fdtget_test "77 121 66 111 \ +97 114 100 78 97 109 101 0 77 121 66 111 97 114 100 70 97 109 105 \ +108 121 78 97 109 101 0" -t bu $dtb / compatible +    run_fdtget_test "MyBoardName MyBoardFamilyName" -t s $dtb / compatible +    run_fdtget_test 32768 $dtb /cpus/PowerPC,970@1 d-cache-size +    run_fdtget_test 8000 -tx $dtb /cpus/PowerPC,970@1 d-cache-size +    run_fdtget_test "61 62 63 0" -tbx $dtb /randomnode tricky1 +    run_fdtget_test "a b c d de ea ad be ef" -tbx $dtb /randomnode blob + +    # Here the property size is not a multiple of 4 bytes, so it should fail +    run_wrap_error_test $DTGET -tlx $dtb /randomnode mixed +    run_fdtget_test "6162 6300 1234 0 a 0 b 0 c" -thx $dtb /randomnode mixed +    run_fdtget_test "61 62 63 0 12 34 0 0 0 a 0 0 0 b 0 0 0 c" \ +	-thhx $dtb /randomnode mixed +    run_wrap_error_test $DTGET -ts $dtb /randomnode doctor-who + +    # Test multiple arguments +    run_fdtget_test "MyBoardName\nmemory" -ts $dtb / model /memory device_type + +    # Test defaults +    run_wrap_error_test $DTGET -tx $dtb /randomnode doctor-who +    run_fdtget_test "<the dead silence>" -tx \ +	-d "<the dead silence>" $dtb /randomnode doctor-who +    run_fdtget_test "<blink>" -tx -d "<blink>" $dtb /memory doctor-who +} + +fdtput_tests () { +    dts=label01.dts +    dtb=$dts.fdtput.test.dtb +    text=lorem.txt + +    # Allow just enough space for $text +    run_dtc_test -O dtb -p $(stat -c %s $text) -o $dtb $dts + +    # run_fdtput_test <expected-result> <file> <node> <property> <flags> <value> +    run_fdtput_test "a_model" $dtb / model -ts "a_model" +    run_fdtput_test "board1 board2" $dtb / compatible -ts board1 board2 +    run_fdtput_test "board1 board2" $dtb / compatible -ts "board1 board2" +    run_fdtput_test "32768" $dtb /cpus/PowerPC,970@1 d-cache-size "" "32768" +    run_fdtput_test "8001" $dtb /cpus/PowerPC,970@1 d-cache-size -tx 0x8001 +    run_fdtput_test "2 3 12" $dtb /randomnode tricky1 -tbi "02 003 12" +    run_fdtput_test "a b c ea ad be ef" $dtb /randomnode blob \ +	-tbx "a b c ea ad be ef" +    run_fdtput_test "a0b0c0d deeaae ef000000" $dtb /randomnode blob \ +	-tx "a0b0c0d deeaae ef000000" +    run_fdtput_test "$(cat $text)" $dtb /randomnode blob -ts "$(cat $text)" + +    # Test expansion of the blob when insufficient room for property +    run_fdtput_test "$(cat $text $text)" $dtb /randomnode blob -ts "$(cat $text $text)" + +    # Start again with a fresh dtb +    run_dtc_test -O dtb -p $(stat -c %s $text) -o $dtb $dts + +    # Node creation +    run_wrap_error_test $DTPUT $dtb -c /baldrick sod +    run_wrap_test $DTPUT $dtb -c /chosen/son /chosen/daughter +    run_fdtput_test "eva" $dtb /chosen/daughter name "" -ts "eva" +    run_fdtput_test "adam" $dtb /chosen/son name "" -ts "adam" + +    # Not allowed to create an existing node +    run_wrap_error_test $DTPUT $dtb -c /chosen +    run_wrap_error_test $DTPUT $dtb -c /chosen/son + +    # Automatic node creation +    run_wrap_test $DTPUT $dtb -cp /blackadder/the-second/turnip \ +	/blackadder/the-second/potato +    run_fdtput_test 1000 $dtb /blackadder/the-second/turnip cost "" 1000 +    run_fdtput_test "fine wine" $dtb /blackadder/the-second/potato drink \ +	"-ts" "fine wine" +    run_wrap_test $DTPUT $dtb -p /you/are/drunk/sir/winston slurp -ts twice + +    # Test expansion of the blob when insufficent room for a new node +    run_wrap_test $DTPUT $dtb -cp "$(cat $text $text)/longish" + +    # Allowed to create an existing node with -p +    run_wrap_test $DTPUT $dtb -cp /chosen +    run_wrap_test $DTPUT $dtb -cp /chosen/son + +    # TODO: Add tests for verbose mode? +} + +utilfdt_tests () { +    run_test utilfdt_test +} + +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 utilfdt dtc dtbs_equal fdtget fdtput" +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 +	    ;; +	"utilfdt") +	    utilfdt_tests +	    ;; +	"dtc") +	    dtc_tests +	    ;; +	"dtbs_equal") +	    dtbs_equal_tests +	    ;; +	"fdtget") +	    fdtget_tests +	    ;; +	"fdtput") +	    fdtput_tests +	    ;; +    esac +done + +echo "********** TEST SUMMARY" +echo "*     Total testcases:	$tot_tests" +echo "*                PASS:	$tot_pass" +echo "*                FAIL:	$tot_fail" +echo "*   Bad configuration:	$tot_config" +if [ -n "$VALGRIND" ]; then +    echo "*    valgrind errors:	$tot_vg" +fi +echo "* Strange test result:	$tot_strange" +echo "**********" + diff --git a/dtc/tests/rw_tree1.c b/dtc/tests/rw_tree1.c new file mode 100644 index 00000000..efd47189 --- /dev/null +++ b/dtc/tests/rw_tree1.c @@ -0,0 +1,95 @@ +/* + * 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 <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, s1, s2; + +	test_init(argc, argv); + +	fdt = xmalloc(SPACE); + +	/* First create empty tree with SW */ +	CHECK(fdt_create_empty_tree(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_u32(fdt, 0, "prop-int", TEST_VALUE_1)); +	CHECK(fdt_setprop_u64(fdt, 0, "prop-int64", TEST_VALUE64_1)); +	CHECK(fdt_setprop_string(fdt, 0, "prop-str", TEST_STRING_1)); + +	OFF_CHECK(offset, fdt_add_subnode(fdt, 0, "subnode@1")); +	s1 = offset; +	CHECK(fdt_setprop_string(fdt, s1, "compatible", "subnode1")); +	CHECK(fdt_setprop_cell(fdt, s1, "prop-int", TEST_VALUE_1)); +	OFF_CHECK(offset, fdt_add_subnode(fdt, s1, "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, s1, "ss1")); + +	OFF_CHECK(offset, fdt_add_subnode(fdt, 0, "subnode@2")); +	s2 = offset; +	CHECK(fdt_setprop_cell(fdt, s2, "linux,phandle", PHANDLE_1)); +	CHECK(fdt_setprop_cell(fdt, s2, "prop-int", TEST_VALUE_2)); +	OFF_CHECK(offset, fdt_add_subnode(fdt, s2, "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)); +	OFF_CHECK(offset, fdt_add_subnode(fdt, s2, "ss2")); + +	CHECK(fdt_pack(fdt)); + +	save_blob("rw_tree1.test.dtb", fdt); + +	PASS(); +} diff --git a/dtc/tests/search_dir/search_test.dtsi b/dtc/tests/search_dir/search_test.dtsi new file mode 100644 index 00000000..217fb80a --- /dev/null +++ b/dtc/tests/search_dir/search_test.dtsi @@ -0,0 +1,4 @@ +/include/ "search_test2.dtsi" + +/ { +}; diff --git a/dtc/tests/search_dir/search_test2.dtsi b/dtc/tests/search_dir/search_test2.dtsi new file mode 100644 index 00000000..7b9099e5 --- /dev/null +++ b/dtc/tests/search_dir/search_test2.dtsi @@ -0,0 +1,3 @@ + +/ { +}; diff --git a/dtc/tests/search_dir_b/search_paths_subdir.dts b/dtc/tests/search_dir_b/search_paths_subdir.dts new file mode 100644 index 00000000..5c5c9622 --- /dev/null +++ b/dtc/tests/search_dir_b/search_paths_subdir.dts @@ -0,0 +1,6 @@ +/dts-v1/; + +/include/ "search_test_c.dtsi" + +/ { +}; diff --git a/dtc/tests/search_dir_b/search_test_b.dtsi b/dtc/tests/search_dir_b/search_test_b.dtsi new file mode 100644 index 00000000..b06a7d6e --- /dev/null +++ b/dtc/tests/search_dir_b/search_test_b.dtsi @@ -0,0 +1,4 @@ +/include/ "search_test_b2.dtsi" + +/ { +}; diff --git a/dtc/tests/search_dir_b/search_test_b2.dtsi b/dtc/tests/search_dir_b/search_test_b2.dtsi new file mode 100644 index 00000000..2526b43d --- /dev/null +++ b/dtc/tests/search_dir_b/search_test_b2.dtsi @@ -0,0 +1,5 @@ + +/include/ "search_test.dtsi" + +/ { +}; diff --git a/dtc/tests/search_dir_b/search_test_c.dtsi b/dtc/tests/search_dir_b/search_test_c.dtsi new file mode 100644 index 00000000..336d7a25 --- /dev/null +++ b/dtc/tests/search_dir_b/search_test_c.dtsi @@ -0,0 +1,2 @@ +/ { +}; diff --git a/dtc/tests/search_paths.dts b/dtc/tests/search_paths.dts new file mode 100644 index 00000000..a2bf179e --- /dev/null +++ b/dtc/tests/search_paths.dts @@ -0,0 +1,6 @@ +/dts-v1/; + +/include/ "search_test.dtsi" + +/ { +}; diff --git a/dtc/tests/search_paths_b.dts b/dtc/tests/search_paths_b.dts new file mode 100644 index 00000000..6ace6e24 --- /dev/null +++ b/dtc/tests/search_paths_b.dts @@ -0,0 +1,6 @@ +/dts-v1/; + +/include/ "search_test_b.dtsi" + +/ { +}; diff --git a/dtc/tests/set_name.c b/dtc/tests/set_name.c new file mode 100644 index 00000000..98615873 --- /dev/null +++ b/dtc/tests/set_name.c @@ -0,0 +1,90 @@ +/* + * 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static 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/dtc/tests/setprop.c b/dtc/tests/setprop.c new file mode 100644 index 00000000..d089f8d5 --- /dev/null +++ b/dtc/tests/setprop.c @@ -0,0 +1,95 @@ +/* + * 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 <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); + +	err = fdt_setprop_u32(fdt, 0, "prop-u32", TEST_VALUE_2); +	if (err) +		FAIL("Failed to set \"prop-u32\" to 0x%08x: %s", +		     TEST_VALUE_2, fdt_strerror(err)); +	check_getprop_cell(fdt, 0, "prop-u32", TEST_VALUE_2); + +	err = fdt_setprop_cell(fdt, 0, "prop-cell", TEST_VALUE_2); +	if (err) +		FAIL("Failed to set \"prop-cell\" to 0x%08x: %s", +		     TEST_VALUE_2, fdt_strerror(err)); +	check_getprop_cell(fdt, 0, "prop-cell", TEST_VALUE_2); + +	err = fdt_setprop_u64(fdt, 0, "prop-u64", TEST_VALUE64_1); +	if (err) +		FAIL("Failed to set \"prop-u64\" to 0x%016llx: %s", +		     TEST_VALUE64_1, fdt_strerror(err)); +	check_getprop_64(fdt, 0, "prop-u64", TEST_VALUE64_1); +	 +	PASS(); +} diff --git a/dtc/tests/setprop_inplace.c b/dtc/tests/setprop_inplace.c new file mode 100644 index 00000000..daef182d --- /dev/null +++ b/dtc/tests/setprop_inplace.c @@ -0,0 +1,87 @@ +/* + * 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 <inttypes.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <stdint.h> + +#include <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +int main(int argc, char *argv[]) +{ +	void *fdt; +	const uint32_t *intp; +	const uint64_t *int64p; +	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 0x%08x: %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); + + +	int64p = check_getprop_64(fdt, 0, "prop-int64", TEST_VALUE64_1); + +	verbose_printf("Old int64 value was 0x%016" PRIx64 "\n", *int64p); +	err = fdt_setprop_inplace_u64(fdt, 0, "prop-int64", ~TEST_VALUE64_1); +	if (err) +		FAIL("Failed to set \"prop-int64\" to 0x%016llx: %s", +		     ~TEST_VALUE64_1, fdt_strerror(err)); +	int64p = check_getprop_64(fdt, 0, "prop-int64", ~TEST_VALUE64_1); +	verbose_printf("New int64 value is 0x%016" PRIx64 "\n", *int64p); + +	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/dtc/tests/sized_cells.c b/dtc/tests/sized_cells.c new file mode 100644 index 00000000..94da03b8 --- /dev/null +++ b/dtc/tests/sized_cells.c @@ -0,0 +1,83 @@ +/* + * libfdt - Flat Device Tree manipulation + *	Testcase for variable sized cells in dtc + * Copyright (C) 2006 David Gibson, IBM Corporation. + * Copyright (C) 2011 The Chromium Authors. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> + +#include <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static void check_compare_properties(void *fdt, +				     char const *name_one, +				     char const *name_two) +{ +	const void *propval; +	int proplen; + +	propval = fdt_getprop(fdt, 0, name_one, &proplen); + +	if (!propval) +		FAIL("fdt_getprop(\"%s\"): %s", +		     name_one, +		     fdt_strerror(proplen)); + +	check_getprop(fdt, 0, name_two, proplen, propval); +} + +int main(int argc, char *argv[]) +{ +	void *fdt; +	uint8_t expected_8[6] = {TEST_CHAR1, +				 TEST_CHAR2, +				 TEST_CHAR3, +				 TEST_CHAR4, +				 TEST_CHAR5, +				 TEST_VALUE_1 >> 24}; +	uint16_t expected_16[6]; +	uint32_t expected_32[6]; +	uint64_t expected_64[6]; +	int i; + +	for (i = 0; i < 5; ++i) { +		expected_16[i] = cpu_to_fdt16(expected_8[i]); +		expected_32[i] = cpu_to_fdt32(expected_8[i]); +		expected_64[i] = cpu_to_fdt64(expected_8[i]); +	} + +	expected_16[5] = cpu_to_fdt16(TEST_VALUE_1 >> 16); +	expected_32[5] = cpu_to_fdt32(TEST_VALUE_1); +	expected_64[5] = cpu_to_fdt64(TEST_ADDR_1); + +	test_init(argc, argv); +	fdt = load_blob_arg(argc, argv); + +	check_getprop(fdt, 0, "cells-8b", sizeof(expected_8), expected_8); +	check_getprop(fdt, 0, "cells-16b", sizeof(expected_16), expected_16); +	check_getprop(fdt, 0, "cells-32b", sizeof(expected_32), expected_32); +	check_getprop(fdt, 0, "cells-64b", sizeof(expected_64), expected_64); + +	check_compare_properties(fdt, "cells-one-16b", "cells-one-32b"); + +	PASS(); +} diff --git a/dtc/tests/sized_cells.dts b/dtc/tests/sized_cells.dts new file mode 100644 index 00000000..efea9f56 --- /dev/null +++ b/dtc/tests/sized_cells.dts @@ -0,0 +1,11 @@ +/dts-v1/; + +/ { +	cells-8b = /bits/ 8 <'\r' 'b' '\0' '\'' '\xff' 0xde>; +	cells-16b = /bits/ 16 <'\r' 'b' '\0' '\'' '\xff' 0xdead>; +	cells-32b = /bits/ 32 <'\r' 'b' '\0' '\'' '\xff' 0xdeadbeef>; +	cells-64b = /bits/ 64 <'\r' 'b' '\0' '\'' '\xff' 0xdeadbeef00000000>; + +	cells-one-16b = /bits/ 16 <0x1234 0x5678 0x0 0xffff>; +	cells-one-32b = <0x12345678 0x0000ffff>; +}; diff --git a/dtc/tests/string_escapes.c b/dtc/tests/string_escapes.c new file mode 100644 index 00000000..8cdee4bb --- /dev/null +++ b/dtc/tests/string_escapes.c @@ -0,0 +1,43 @@ +/* + * 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 <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/dtc/tests/subnode_iterate.c b/dtc/tests/subnode_iterate.c new file mode 100644 index 00000000..b9f379d5 --- /dev/null +++ b/dtc/tests/subnode_iterate.c @@ -0,0 +1,94 @@ +/* + * libfdt - Flat Device Tree manipulation + *	Tests that fdt_next_subnode() works as expected + * + * Copyright (C) 2013 Google, Inc + * + * 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static void test_node(void *fdt, int parent_offset) +{ +	fdt32_t subnodes; +	const fdt32_t *prop; +	int offset; +	int count; +	int len; + +	/* This property indicates the number of subnodes to expect */ +	prop = fdt_getprop(fdt, parent_offset, "subnodes", &len); +	if (!prop || len != sizeof(fdt32_t)) { +		FAIL("Missing/invalid subnodes property at '%s'", +		     fdt_get_name(fdt, parent_offset, NULL)); +	} +	subnodes = cpu_to_fdt32(*prop); + +	count = 0; +	for (offset = fdt_first_subnode(fdt, parent_offset); +	     offset >= 0; +	     offset = fdt_next_subnode(fdt, offset)) +		count++; + +	if (count != subnodes) { +		FAIL("Node '%s': Expected %d subnodes, got %d\n", +		     fdt_get_name(fdt, parent_offset, NULL), subnodes, +		     count); +	} +} + +static void check_fdt_next_subnode(void *fdt) +{ +	int offset; +	int count = 0; + +	for (offset = fdt_first_subnode(fdt, 0); +	     offset >= 0; +	     offset = fdt_next_subnode(fdt, offset)) { +		test_node(fdt, offset); +		count++; +	} + +	if (count != 2) +		FAIL("Expected %d tests, got %d\n", 2, count); +} + +int main(int argc, char *argv[]) +{ +	void *fdt; + +	test_init(argc, argv); +	if (argc != 2) +		CONFIG("Usage: %s <dtb file>", argv[0]); + +	fdt = load_blob(argv[1]); +	if (!fdt) +		FAIL("No device tree available"); + +	check_fdt_next_subnode(fdt); + +	PASS(); +} diff --git a/dtc/tests/subnode_iterate.dts b/dtc/tests/subnode_iterate.dts new file mode 100644 index 00000000..14a0d3ab --- /dev/null +++ b/dtc/tests/subnode_iterate.dts @@ -0,0 +1,44 @@ +/dts-v1/; + +/ { +	#address-cells = <1>; +	#size-cells = <0>; + +	test1 { +		subnodes = <2>; +		linux,phandle = <0x1>; +		#address-cells = <1>; +		#size-cells = <0>; +		PowerPC,970@0 { +			name = "PowerPC,970"; +			device_type = "cpu"; +			reg = <0x00000000>; +			clock-frequency = <1600000000>; +			timebase-frequency = <33333333>; +			linux,boot-cpu; +			i-cache-size = <65536>; +			d-cache-size = <32768>; +			another-sub-node { +				should-be-ignored; +				yet-another { +					should-also-be-ignored; +				}; +			}; +		}; + +		PowerPC,970@1 { +			name = "PowerPC,970"; +			device_type = "cpu"; +			reg = <0x00000001>; +			clock-frequency = <1600000000>; +			timebase-frequency = <33333333>; +			i-cache-size = <65536>; +			d-cache-size = <32768>; +		}; +	}; + +	test2 { +		subnodes = <0>; +	}; +}; + diff --git a/dtc/tests/subnode_offset.c b/dtc/tests/subnode_offset.c new file mode 100644 index 00000000..231fcb50 --- /dev/null +++ b/dtc/tests/subnode_offset.c @@ -0,0 +1,98 @@ +/* + * 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static 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; +	int ss12_off, ss21_off; + +	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"); + +	check_subnode(fdt, subnode1_offset, "ss1"); +	ss21_off = fdt_subnode_offset(fdt, subnode2_offset, "ss1"); +	if (ss21_off != -FDT_ERR_NOTFOUND) +		FAIL("Incorrectly found ss1 in subnode2"); + +	ss12_off = fdt_subnode_offset(fdt, subnode1_offset, "ss2"); +	if (ss12_off != -FDT_ERR_NOTFOUND) +		FAIL("Incorrectly found ss2 in subnode1"); +	check_subnode(fdt, subnode2_offset, "ss2"); + +	PASS(); +} diff --git a/dtc/tests/supernode_atdepth_offset.c b/dtc/tests/supernode_atdepth_offset.c new file mode 100644 index 00000000..43e120d7 --- /dev/null +++ b/dtc/tests/supernode_atdepth_offset.c @@ -0,0 +1,145 @@ +/* + * 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 <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +static 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; +} + +static 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; +} + +static 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); +} + +static 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); +} + +static 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/dtc/tests/sw_tree1.c b/dtc/tests/sw_tree1.c new file mode 100644 index 00000000..8eb6e5fe --- /dev/null +++ b/dtc/tests/sw_tree1.c @@ -0,0 +1,99 @@ +/* + * 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 <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_u32(fdt, "prop-int", TEST_VALUE_1)); +	CHECK(fdt_property_u64(fdt, "prop-int64", TEST_VALUE64_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_begin_node(fdt, "ss1")); +	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, "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_begin_node(fdt, "ss2")); +	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/dtc/tests/test01.asm b/dtc/tests/test01.asm new file mode 100644 index 00000000..bbf66c77 --- /dev/null +++ b/dtc/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/dtc/tests/test01.dts b/dtc/tests/test01.dts new file mode 100644 index 00000000..f9fd1653 --- /dev/null +++ b/dtc/tests/test01.dts @@ -0,0 +1,57 @@ +/dts-v1/; + +/memreserve/ 0x1000000000000000 0x0000000002000000; +/memreserve/ 0x2000000000000000 0x0100000000000000; +/memreserve/ 0x0000000000000000 0x0000000000000014; + +/ { +	model = "MyBoardName"; +	compatible = "MyBoardName", "MyBoardFamilyName"; +	#address-cells = <2>; +	#size-cells = <2>; + +	cpus { +		linux,phandle = <0x1>; +		#address-cells = <1>; +		#size-cells = <0>; +		PowerPC,970@0 { +			name = "PowerPC,970"; +			device_type = "cpu"; +			reg = <0x00000000>; +			clock-frequency = <1600000000>; +			timebase-frequency = <33333333>; +			linux,boot-cpu; +			i-cache-size = <65536>; +			d-cache-size = <32768>; +		}; + +		PowerPC,970@1 { +			name = "PowerPC,970"; +			device_type = "cpu"; +			reg = <0x00000001>; +			clock-frequency = <1600000000>; +			timebase-frequency = <33333333>; +			i-cache-size = <65536>; +			d-cache-size = <32768>; +		}; + +	}; + +	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], <0xa 0xb 0xc>; +	}; + +	memory@0 { +		device_type = "memory"; +		memreg: reg = <0x00000000 0x00000000 0x00000000 0x20000000>; +	}; + +	chosen { +		bootargs = "root=/dev/sda2"; +		linux,platform = <0x600>; +	}; + +}; diff --git a/dtc/tests/test01.stderr b/dtc/tests/test01.stderr new file mode 100644 index 00000000..82ea3f63 --- /dev/null +++ b/dtc/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/dtc/tests/test_kernel_dts b/dtc/tests/test_kernel_dts new file mode 100755 index 00000000..238f3f7c --- /dev/null +++ b/dtc/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/dtc/tests/test_tree1.dts b/dtc/tests/test_tree1.dts new file mode 100644 index 00000000..c7b170c5 --- /dev/null +++ b/dtc/tests/test_tree1.dts @@ -0,0 +1,3 @@ +/dts-v1/; + +/include/ "test_tree1_body.dtsi" diff --git a/dtc/tests/test_tree1_body.dtsi b/dtc/tests/test_tree1_body.dtsi new file mode 100644 index 00000000..14461913 --- /dev/null +++ b/dtc/tests/test_tree1_body.dtsi @@ -0,0 +1,36 @@ +/memreserve/ 0xdeadbeef00000000 0x100000; +/memreserve/ 123456789 010000; + +/ { +	compatible = "test_tree1"; +	prop-int = <0xdeadbeef>; +	prop-int64 = /bits/ 64 <0xdeadbeef01abcdef>; +	prop-str = "hello world"; + +	subnode@1 { +		compatible = "subnode1"; +		prop-int = [deadbeef]; + +		subsubnode { +			compatible = "subsubnode1", "subsubnode"; +			prop-int = <0xdeadbeef>; +		}; + +		ss1 { +		}; +	}; + +	subnode@2 { +		linux,phandle = <0x2000>; +		prop-int = <123456789>; + +		ssn0: subsubnode@0 { +			phandle = <0x2001>; +			compatible = "subsubnode2", "subsubnode"; +			prop-int = <0726746425>; +		}; + +		ss2 { +		}; +	}; +}; diff --git a/dtc/tests/test_tree1_delete.dts b/dtc/tests/test_tree1_delete.dts new file mode 100644 index 00000000..a2f1bfdc --- /dev/null +++ b/dtc/tests/test_tree1_delete.dts @@ -0,0 +1,68 @@ +/dts-v1/; + +/include/ "test_tree1_body.dtsi" + +/ { +	nonexistant-property = <0xdeadbeef>; + +	nonexistant-subnode { +		prop-int = <1>; +	}; + +	dellabel: deleted-by-label { +		prop-int = <1>; +	}; + +	subnode@1 { +		delete-this-str = "deadbeef"; +	}; + +}; + +/ { +	/delete-property/ nonexistant-property; + +	/delete-node/ nonexistant-subnode; + +	subnode@1 { +		/delete-property/ delete-this-str; +	}; +}; + +/delete-node/ &dellabel; + +/ { +	/delete-property/ prop-str; +}; + +/ { +	prop-str = "hello world"; +}; + +/ { +	subnode@1 { +		/delete-node/ ss1; +	}; +}; + +/ { +	subnode@1 { +		ss1 { +		}; +	}; +}; + +/{ +	duplabel1: foo1 = "bar"; +	duplabel2: foo2 = "bar"; +}; + +/{ +	duplabel1: baz1 = "qux"; +	duplabel2: baz2 = "qux"; +}; + +/{ +	/delete-property/ foo1; +	/delete-property/ baz2; +}; diff --git a/dtc/tests/test_tree1_merge.dts b/dtc/tests/test_tree1_merge.dts new file mode 100644 index 00000000..ded08d87 --- /dev/null +++ b/dtc/tests/test_tree1_merge.dts @@ -0,0 +1,44 @@ +/dts-v1/; +/memreserve/ 0xdeadbeef00000000 0x100000; +/memreserve/ 123456789 010000; + +/ { +	compatible = "test_tree1"; +	prop-int = "wrong!"; +	prop-str = "hello world"; + +	subnode@1 { +		compatible = "subnode1"; + +		subsubnode { +			compatible = "subsubnode1", "subsubnode"; +			prop-int = <0xdeadbeef>; +		}; + +		ss1 { +		}; +	}; + +	subnode@2 { +		linux,phandle = <0x2000>; +		prop-int = <123456789>; + +		ss2 { +		}; +	}; +}; + +/ { +	prop-int = <0xdeadbeef>; +	prop-int64 = /bits/ 64 <0xdeadbeef01abcdef>; +	subnode@1 { +		prop-int = [deadbeef]; +	}; +	subnode@2 { +		ssn0: subsubnode@0 { +			phandle = <0x2001>; +			compatible = "subsubnode2", "subsubnode"; +			prop-int = <0726746425>; +		}; +	}; +}; diff --git a/dtc/tests/test_tree1_merge_labelled.dts b/dtc/tests/test_tree1_merge_labelled.dts new file mode 100644 index 00000000..29953b0a --- /dev/null +++ b/dtc/tests/test_tree1_merge_labelled.dts @@ -0,0 +1,42 @@ +/dts-v1/; + +/memreserve/ 0xdeadbeef00000000 0x100000; +/memreserve/ 123456789 010000; + +/ { +	compatible = "test_tree1"; +	prop-int = <0xdeadbeef>; +	prop-int64 = /bits/ 64 <0xdeadbeef01abcdef>; +	prop-str = "hello world"; + +	subnode@1 { +		compatible = "subnode1"; +		prop-int = [deadbeef]; + +		subsubnode { +			compatible = "subsubnode1", "subsubnode"; +			prop-int = <0xdeadbeef>; +		}; + +		ss1 { +		}; +	}; + +	subnode@2 { +		linux,phandle = <0x2000>; +		prop-int = <123456789>; + +		ssn0: subsubnode@0 { +			phandle = <0x2001>; +			prop-int = <0xbad>; +		}; + +		ss2 { +		}; +	}; +}; + +&ssn0 { +	compatible = "subsubnode2", "subsubnode"; +	prop-int = <0726746425>; +}; diff --git a/dtc/tests/test_tree1_merge_path.dts b/dtc/tests/test_tree1_merge_path.dts new file mode 100644 index 00000000..168d066f --- /dev/null +++ b/dtc/tests/test_tree1_merge_path.dts @@ -0,0 +1,42 @@ +/dts-v1/; + +/memreserve/ 0xdeadbeef00000000 0x100000; +/memreserve/ 123456789 010000; + +/ { +	compatible = "test_tree1"; +	prop-int = <0xdeadbeef>; +	prop-int64 = /bits/ 64 <0xdeadbeef01abcdef>; +	prop-str = "hello world"; + +	subnode@1 { +		compatible = "subnode1"; +		prop-int = [deadbeef]; + +		subsubnode { +			compatible = "subsubnode1", "subsubnode"; +			prop-int = <0xdeadbeef>; +		}; + +		ss1 { +		}; +	}; + +	subnode@2 { +		linux,phandle = <0x2000>; +		prop-int = <123456789>; + +		ssn0: subsubnode@0 { +			phandle = <0x2001>; +			prop-int = <0xbad>; +		}; + +		ss2 { +		}; +	}; +}; + +&{/subnode@2/subsubnode@0} { +	compatible = "subsubnode2", "subsubnode"; +	prop-int = <0726746425>; +}; diff --git a/dtc/tests/test_tree1_wrong1.dts b/dtc/tests/test_tree1_wrong1.dts new file mode 100644 index 00000000..d71820a2 --- /dev/null +++ b/dtc/tests/test_tree1_wrong1.dts @@ -0,0 +1,36 @@ +/dts-v1/; + +/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>; +		}; + +		ss1 { +		}; +	}; + +	subnode@2 { +		linux,phandle = <0x2000>; +		prop-int = <123456789>; + +		subsubnode@0 { +			phandle = <0x2001>; +			compatible = "subsubnode2", "subsubnode"; +			prop-int = <0726746425>; +		}; + +		ss2 { +		}; +	}; +}; diff --git a/dtc/tests/test_tree1_wrong2.dts b/dtc/tests/test_tree1_wrong2.dts new file mode 100644 index 00000000..ac27023c --- /dev/null +++ b/dtc/tests/test_tree1_wrong2.dts @@ -0,0 +1,36 @@ +/dts-v1/; + +/memreserve/ 0xdeadbeef00000000 0x100000; +/memreserve/ 123456789 010000; + +/ { +	compatible = "test_tree1"; +	prop-str = "hello world"; + +	subnode@1 { +		compatible = "subnode1"; +		prop-int = [deadbeef]; + +		subsubnode { +			compatible = "subsubnode1", "subsubnode"; +			prop-int = <0xdeadbeef>; +		}; + +		ss1 { +		}; +	}; + +	subnode@2 { +		linux,phandle = <0x2000>; +		prop-int = <123456789>; + +		subsubnode@0 { +			phandle = <0x2001>; +			compatible = "subsubnode2", "subsubnode"; +			prop-int = <0726746425>; +		}; + +		ss2 { +		}; +	}; +}; diff --git a/dtc/tests/test_tree1_wrong3.dts b/dtc/tests/test_tree1_wrong3.dts new file mode 100644 index 00000000..80be2fac --- /dev/null +++ b/dtc/tests/test_tree1_wrong3.dts @@ -0,0 +1,36 @@ +/dts-v1/; + +/memreserve/ 0xdeadbeef00000000 0x100000; +/memreserve/ 123456789 010000; + +/ { +	compatible = "test_tree1"; +	prop-int = <0xdeadbeef>; +	prop-str = "hello world"; + +	subnode@1 { +		compatible = "subnode1"; + +		subsubnode { +			compatible = "subsubnode1", "subsubnode"; +			prop-int = <0xdeadbeef>; +		}; + +		ss1 { +		}; +	}; + +	subnode@2 { +		linux,phandle = <0x2000>; +		prop-int = <123456789>; + +		subsubnode@0 { +			phandle = <0x2001>; +			compatible = "subsubnode2", "subsubnode"; +			prop-int = <0726746425>; +		}; + +		ss2 { +		}; +	}; +}; diff --git a/dtc/tests/test_tree1_wrong4.dts b/dtc/tests/test_tree1_wrong4.dts new file mode 100644 index 00000000..09bb13b8 --- /dev/null +++ b/dtc/tests/test_tree1_wrong4.dts @@ -0,0 +1,34 @@ +/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>; +		}; + +		ss1 { +		}; +	}; + +	subnode@2 { +		linux,phandle = <0x2000>; +		prop-int = <123456789>; + +		subsubnode@0 { +			phandle = <0x2001>; +			compatible = "subsubnode2", "subsubnode"; +			prop-int = <0726746425>; +		}; +	}; +}; diff --git a/dtc/tests/test_tree1_wrong5.dts b/dtc/tests/test_tree1_wrong5.dts new file mode 100644 index 00000000..ef4c4f7b --- /dev/null +++ b/dtc/tests/test_tree1_wrong5.dts @@ -0,0 +1,37 @@ +/dts-v1/; + +/memreserve/ 0xdeadbeef00000000 0x100000; +/memreserve/ 123456789 010000; + +/ { +	compatible = "test_tree1"; +	prop-int = <0xdeadbefe>; +	prop-str = "hello world"; + +	subnode@1 { +		compatible = "subnode1"; +		prop-int = [deadbeef]; + +		subsubnode { +			compatible = "subsubnode1", "subsubnode"; +			prop-int = <0xdeadbeef>; +		}; + +		ss1 { +		}; +	}; + +	subnode@2 { +		linux,phandle = <0x2000>; +		prop-int = <123456789>; + +		subsubnode@0 { +			phandle = <0x2001>; +			compatible = "subsubnode2", "subsubnode"; +			prop-int = <0726746425>; +		}; + +		ss2 { +		}; +	}; +}; diff --git a/dtc/tests/test_tree1_wrong6.dts b/dtc/tests/test_tree1_wrong6.dts new file mode 100644 index 00000000..98d6eda7 --- /dev/null +++ b/dtc/tests/test_tree1_wrong6.dts @@ -0,0 +1,38 @@ +/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>; +		}; + +		ss1 { +			extra-prop; +		}; +	}; + +	subnode@2 { +		linux,phandle = <0x2000>; +		prop-int = <123456789>; + +		subsubnode@0 { +			phandle = <0x2001>; +			compatible = "subsubnode2", "subsubnode"; +			prop-int = <0726746425>; +		}; + +		ss2 { +		}; +	}; +}; diff --git a/dtc/tests/test_tree1_wrong7.dts b/dtc/tests/test_tree1_wrong7.dts new file mode 100644 index 00000000..f57ace09 --- /dev/null +++ b/dtc/tests/test_tree1_wrong7.dts @@ -0,0 +1,39 @@ +/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>; +		}; + +		ss1 { +		}; +	}; + +	subnode@2 { +		linux,phandle = <0x2000>; +		prop-int = <123456789>; + +		subsubnode@0 { +			phandle = <0x2001>; +			compatible = "subsubnode2", "subsubnode"; +			prop-int = <0726746425>; +		}; + +		ss2 { +			extranode { +			}; +		}; +	}; +}; diff --git a/dtc/tests/test_tree1_wrong8.dts b/dtc/tests/test_tree1_wrong8.dts new file mode 100644 index 00000000..811ce6c0 --- /dev/null +++ b/dtc/tests/test_tree1_wrong8.dts @@ -0,0 +1,37 @@ +/dts-v1/; + +/memreserve/ 0xdeadbeef00000000 0x100000; +/memreserve/ 123456789 010001; + +/ { +	compatible = "test_tree1"; +	prop-int = <0xdeadbeef>; +	prop-str = "hello world"; + +	subnode@1 { +		compatible = "subnode1"; +		prop-int = [deadbeef]; + +		subsubnode { +			compatible = "subsubnode1", "subsubnode"; +			prop-int = <0xdeadbeef>; +		}; + +		ss1 { +		}; +	}; + +	subnode@2 { +		linux,phandle = <0x2000>; +		prop-int = <123456789>; + +		subsubnode@0 { +			phandle = <0x2001>; +			compatible = "subsubnode2", "subsubnode"; +			prop-int = <0726746425>; +		}; + +		ss2 { +		}; +	}; +}; diff --git a/dtc/tests/test_tree1_wrong9.dts b/dtc/tests/test_tree1_wrong9.dts new file mode 100644 index 00000000..6ff6fab2 --- /dev/null +++ b/dtc/tests/test_tree1_wrong9.dts @@ -0,0 +1,38 @@ +/dts-v1/; + +/memreserve/ 0xdeadbeef00000000 0x100000; +/memreserve/ 123456789 010000; +/memreserve/ 0 1; + +/ { +	compatible = "test_tree1"; +	prop-int = <0xdeadbeef>; +	prop-str = "hello world"; + +	subnode@1 { +		compatible = "subnode1"; +		prop-int = [deadbeef]; + +		subsubnode { +			compatible = "subsubnode1", "subsubnode"; +			prop-int = <0xdeadbeef>; +		}; + +		ss1 { +		}; +	}; + +	subnode@2 { +		linux,phandle = <0x2000>; +		prop-int = <123456789>; + +		subsubnode@0 { +			phandle = <0x2001>; +			compatible = "subsubnode2", "subsubnode"; +			prop-int = <0726746425>; +		}; + +		ss2 { +		}; +	}; +}; diff --git a/dtc/tests/testdata.h b/dtc/tests/testdata.h new file mode 100644 index 00000000..ce715e4c --- /dev/null +++ b/dtc/tests/testdata.h @@ -0,0 +1,36 @@ +#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 TEST_VALUE64_1	ASM_CONST_LL(0xdeadbeef01abcdef) + +#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" + +#define TEST_CHAR1	'\r' +#define TEST_CHAR2	'b' +#define TEST_CHAR3	'\0' +#define TEST_CHAR4	'\'' +#define TEST_CHAR5	'\xff' + +#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/dtc/tests/tests.h b/dtc/tests/tests.h new file mode 100644 index 00000000..56a843cd --- /dev/null +++ b/dtc/tests/tests.h @@ -0,0 +1,129 @@ +#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 ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +#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) + +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_64(fdt, nodeoffset, name, val) \ +	({ \ +		uint64_t x = cpu_to_fdt64(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); + +#include "util.h" + +#endif /* _TESTS_H */ diff --git a/dtc/tests/tests.sh b/dtc/tests/tests.sh new file mode 100644 index 00000000..31530d5e --- /dev/null +++ b/dtc/tests/tests.sh @@ -0,0 +1,61 @@ +# Common functions for shell testcases + +PASS () { +    echo "PASS" +    exit 0 +} + +FAIL () { +    echo "FAIL" "$@" +    exit 2 +} + +FAIL_IF_SIGNAL () { +    ret="$1" +    if [ "$ret" -gt 127 ]; then +	signame=$(kill -l $((ret - 128))) +	FAIL "Killed by SIG$signame" +    fi +} + +DTC=../dtc +DTGET=../fdtget +DTPUT=../fdtput + +verbose_run () { +    if [ -z "$QUIET_TEST" ]; then +	"$@" +    else +	"$@" > /dev/null 2> /dev/null +    fi +} + +verbose_run_check () { +    verbose_run "$@" +    ret="$?" +    FAIL_IF_SIGNAL $ret +    if [ $ret != 0 ]; then +	FAIL "Returned error code $ret" +    fi +} + +verbose_run_log () { +    LOG="$1" +    shift +    "$@" > "$LOG" 2>&1 +    ret=$? +    if [ -z "$QUIET_TEST" ]; then +	cat "$LOG" >&2 +    fi +    return $ret +} + +verbose_run_log_check () { +    verbose_run_log "$@" +    ret="$?" +    FAIL_IF_SIGNAL $ret +    if [ $ret != 0 ]; then +	FAIL "Returned error code $ret" +    fi +} + diff --git a/dtc/tests/testutils.c b/dtc/tests/testutils.c new file mode 100644 index 00000000..f185133a --- /dev/null +++ b/dtc/tests/testutils.c @@ -0,0 +1,203 @@ +/* + * 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) +{ +	char *blob; +	int ret = utilfdt_read_err(filename, &blob); + +	if (ret) +		CONFIG("Couldn't open blob from \"%s\": %s", filename, +		       strerror(ret)); +	return blob; +} + +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 ret = utilfdt_write_err(filename, fdt); + +	if (ret) +		CONFIG("Couldn't write blob to \"%s\": %s", filename, +		       strerror(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/dtc/tests/trees.S b/dtc/tests/trees.S new file mode 100644 index 00000000..cae01876 --- /dev/null +++ b/dtc/tests/trees.S @@ -0,0 +1,201 @@ +#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_INT64(tree, name, val) \ +	PROPHDR(tree, name, 8) \ +	FDTQUAD(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_INT64(test_tree1, prop_int64, TEST_VALUE64_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 + +	BEGIN_NODE("ss1") +	END_NODE + +	END_NODE + +	BEGIN_NODE("subnode@2") +	PROP_INT(test_tree1, linux_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 + +	BEGIN_NODE("ss2") +	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_int64, "prop-int64") +	STRING(test_tree1, prop_str, "prop-str") +	STRING(test_tree1, linux_phandle, "linux,phandle") +	STRING(test_tree1, phandle, "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/dtc/tests/truncated_property.c b/dtc/tests/truncated_property.c new file mode 100644 index 00000000..f820d99e --- /dev/null +++ b/dtc/tests/truncated_property.c @@ -0,0 +1,47 @@ +/* + * 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 <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/dtc/tests/utilfdt_test.c b/dtc/tests/utilfdt_test.c new file mode 100644 index 00000000..274c3d68 --- /dev/null +++ b/dtc/tests/utilfdt_test.c @@ -0,0 +1,127 @@ +/* + * Copyright 2011 The Chromium Authors, All Rights Reserved. + * + * utilfdt_test - Tests for utilfdt library + * + * 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 <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <stdarg.h> + +#include <libfdt.h> +#include <util.h> + +#include "tests.h" +#include "testdata.h" + +static void check(const char *fmt, int expect_type, int expect_size) +{ +	int type; +	int size; + +	if (utilfdt_decode_type(fmt, &type, &size)) +		FAIL("format '%s': valid format string returned failure", fmt); +	if (expect_type != type) +		FAIL("format '%s': expected type='%c', got type='%c'", fmt, +		     expect_type, type); +	if (expect_size != size) +		FAIL("format '%s': expected size=%d, got size=%d", fmt, +		     expect_size, size); +} + +static void checkfail(const char *fmt) +{ +	int type; +	int size; + +	if (!utilfdt_decode_type(fmt, &type, &size)) +		FAIL("format '%s': invalid format string returned success", +		     fmt); +} + +/** + * Add the given modifier to each of the valid sizes, and check that we get + * correct values. + * + * \param modifier	Modifer string to use as a prefix + * \param expected_size	The size (in bytes) that we expect (ignored for + *			strings) + */ +static void check_sizes(char *modifier, int expected_size) +{ +	char fmt[10], *ptr; + +	/* set up a string with a hole in it for the format character */ +	if (strlen(modifier) + 2 >= sizeof(fmt)) +		FAIL("modifier string '%s' too long", modifier); +	strcpy(fmt, modifier); +	ptr = fmt + strlen(fmt); +	ptr[1] = '\0'; + +	/* now try each format character in turn */ +	*ptr = 'i'; +	check(fmt, 'i', expected_size); + +	*ptr = 'u'; +	check(fmt, 'u', expected_size); + +	*ptr = 'x'; +	check(fmt, 'x', expected_size); + +	*ptr = 's'; +	check(fmt, 's', -1); +} + +static void test_utilfdt_decode_type(void) +{ +	char fmt[10]; +	int ch; + +	/* check all the valid modifiers and sizes */ +	check_sizes("", -1); +	check_sizes("b", 1); +	check_sizes("hh", 1); +	check_sizes("h", 2); +	check_sizes("l", 4); + +	/* try every other character */ +	checkfail(""); +	for (ch = ' '; ch < 127; ch++) { +		if (!strchr("iuxs", ch)) { +			*fmt = ch; +			fmt[1] = '\0'; +			checkfail(fmt); +		} +	} + +	/* try a few modifiers at the end */ +	checkfail("sx"); +	checkfail("ihh"); +	checkfail("xb"); + +	/* and one for the doomsday archives */ +	checkfail("He has all the virtues I dislike and none of the vices " +			"I admire."); +} + +int main(int argc, char *argv[]) +{ +	test_utilfdt_decode_type(); +	PASS(); +} diff --git a/dtc/tests/value-labels.c b/dtc/tests/value-labels.c new file mode 100644 index 00000000..dcf20593 --- /dev/null +++ b/dtc/tests/value-labels.c @@ -0,0 +1,127 @@ +/* + * libfdt - Flat Device Tree manipulation + *	Test labels within values + * 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 <errno.h> + +#include <dlfcn.h> + +#include <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +struct val_label { +	const char *labelname; +	int propoff; +}; + +struct val_label labels1[] = { +	{ "start1", 0 }, +	{ "mid1", 2 }, +	{ "end1", -1 }, +}; + +struct val_label labels2[] = { +	{ "start2", 0 }, +	{ "innerstart2", 0 }, +	{ "innermid2", 4 }, +	{ "innerend2", -1 }, +	{ "end2", -1 }, +}; + +struct val_label labels3[] = { +	{ "start3", 0 }, +	{ "innerstart3", 0 }, +	{ "innermid3", 1 }, +	{ "innerend3", -1 }, +	{ "end3", -1 }, +}; + +static void check_prop_labels(void *sohandle, void *fdt, const char *name, +			      const struct val_label* labels, int n) +{ +	const struct fdt_property *prop; +	const char *p; +	int len; +	int i; + +	prop = fdt_get_property(fdt, 0, name, &len); +	if (!prop) +		FAIL("Couldn't locate property \"%s\"", name); + +	p = dlsym(sohandle, name); +	if (!p) +		FAIL("Couldn't locate label symbol \"%s\"", name); + +	if (p != (const char *)prop) +		FAIL("Label \"%s\" does not point to correct property", name); + +	for (i = 0; i < n; i++) { +		int off = labels[i].propoff; + +		if (off == -1) +			off = len; + +		p = dlsym(sohandle, labels[i].labelname); +		if (!p) +			FAIL("Couldn't locate label symbol \"%s\"", name); + +		if ((p - prop->data) != off) +			FAIL("Label \"%s\" points to offset %ld instead of %d" +			     "in property \"%s\"", labels[i].labelname, +			     (long)(p - prop->data), off, name); +	} +} + +int main(int argc, char *argv[]) +{ +	void *sohandle; +	void *fdt; +	int err; + +	test_init(argc, argv); +	if (argc != 2) +		CONFIG("Usage: %s <so file>", argv[0]); + +	sohandle = dlopen(argv[1], RTLD_NOW); +	if (!sohandle) +		FAIL("Couldn't dlopen() %s", argv[1]); + +	fdt = dlsym(sohandle, "dt_blob_start"); +	if (!fdt) +		FAIL("Couldn't locate \"dt_blob_start\" symbol in %s", +		     argv[1]); + +	err = fdt_check_header(fdt); +	if (err != 0) +		FAIL("%s contains invalid tree: %s", argv[1], +		     fdt_strerror(err)); + + +	check_prop_labels(sohandle, fdt, "prop1", labels1, ARRAY_SIZE(labels1)); +	check_prop_labels(sohandle, fdt, "prop2", labels2, ARRAY_SIZE(labels2)); +	check_prop_labels(sohandle, fdt, "prop3", labels3, ARRAY_SIZE(labels3)); + +	PASS(); +} diff --git a/dtc/tests/value-labels.dts b/dtc/tests/value-labels.dts new file mode 100644 index 00000000..490c609f --- /dev/null +++ b/dtc/tests/value-labels.dts @@ -0,0 +1,8 @@ +/dts-v1/; + +/ { +	prop1: prop1 = start1: "a", mid1: "b" end1:; +	prop2: prop2 = start2: < innerstart2: 0xdeadbeef innermid2: 0xabcd1234 innerend2: > end2:; +	prop3: prop3 = start3: [ innerstart3: ab innermid3: cd innerend3: ] end3:; +}; + diff --git a/dtc/tests/zero-phandle.dts b/dtc/tests/zero-phandle.dts new file mode 100644 index 00000000..7997d980 --- /dev/null +++ b/dtc/tests/zero-phandle.dts @@ -0,0 +1,7 @@ +/dts-v1/; + +/ { +	node { +		linux,phandle = <0>; +	}; +}; | 
