• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libfdt - Flat Device Tree manipulation
3  *	Testcase for fdt_nop_node()
4  * Copyright (C) 2006 David Gibson, IBM Corporation.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License
8  * as published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <ctype.h>
25 #include <stdint.h>
26 
27 #include <libfdt.h>
28 
29 #include "tests.h"
30 #include "testdata.h"
31 
32 #define SPACE	65536
33 
34 static enum {
35 	FIXED = 0,
36 	RESIZE,
37 	REALLOC,
38 } alloc_mode;
39 
realloc_fdt(void ** fdt,size_t * size,bool created)40 static void realloc_fdt(void **fdt, size_t *size, bool created)
41 {
42 	switch (alloc_mode) {
43 	case FIXED:
44 		if (!(*fdt))
45 			*fdt = xmalloc(*size);
46 		else
47 			FAIL("Ran out of space");
48 		return;
49 
50 	case RESIZE:
51 		if (!(*fdt)) {
52 			*fdt = xmalloc(SPACE);
53 		} else if (*size < SPACE) {
54 			*size += 1;
55 			fdt_resize(*fdt, *fdt, *size);
56 		} else {
57 			FAIL("Ran out of space");
58 		}
59 		return;
60 
61 	case REALLOC:
62 		*size += 1;
63 		*fdt = xrealloc(*fdt, *size);
64 		if (created)
65 			fdt_resize(*fdt, *fdt, *size);
66 		return;
67 
68 	default:
69 		CONFIG("Bad allocation mode");
70 	}
71 }
72 
73 #define CHECK(code) \
74 	do {			      \
75 		err = (code);			     \
76 		if (err == -FDT_ERR_NOSPACE)			\
77 			realloc_fdt(&fdt, &size, created);		\
78 		else if (err)						\
79 			FAIL(#code ": %s", fdt_strerror(err));		\
80 	} while (err != 0)
81 
main(int argc,char * argv[])82 int main(int argc, char *argv[])
83 {
84 	void *fdt = NULL;
85 	size_t size;
86 	int err;
87 	bool created = false;
88 	void *place;
89 	const char place_str[] = "this is a placeholder string\0string2";
90 	int place_len = sizeof(place_str);
91 
92 	test_init(argc, argv);
93 
94 	if (argc == 1) {
95 		alloc_mode = FIXED;
96 		size = SPACE;
97 	} else if (argc == 2) {
98 		if (streq(argv[1], "resize")) {
99 			alloc_mode = REALLOC;
100 			size = 0;
101 		} else if (streq(argv[1], "realloc")) {
102 			alloc_mode = REALLOC;
103 			size = 0;
104 		} else {
105 			char *endp;
106 
107 			size = strtoul(argv[1], &endp, 0);
108 			if (*endp == '\0')
109 				alloc_mode = FIXED;
110 			else
111 				CONFIG("Bad allocation mode \"%s\" specified",
112 				       argv[1]);
113 		}
114 	}
115 
116 	fdt = xmalloc(size);
117 	CHECK(fdt_create(fdt, size));
118 
119 	created = true;
120 
121 	CHECK(fdt_add_reservemap_entry(fdt, TEST_ADDR_1, TEST_SIZE_1));
122 
123 	CHECK(fdt_add_reservemap_entry(fdt, TEST_ADDR_2, TEST_SIZE_2));
124 	CHECK(fdt_finish_reservemap(fdt));
125 
126 	CHECK(fdt_begin_node(fdt, ""));
127 	CHECK(fdt_property_string(fdt, "compatible", "test_tree1"));
128 	CHECK(fdt_property_u32(fdt, "prop-int", TEST_VALUE_1));
129 	CHECK(fdt_property_u64(fdt, "prop-int64", TEST_VALUE64_1));
130 	CHECK(fdt_property_string(fdt, "prop-str", TEST_STRING_1));
131 	CHECK(fdt_property_u32(fdt, "#address-cells", 1));
132 	CHECK(fdt_property_u32(fdt, "#size-cells", 0));
133 
134 	CHECK(fdt_begin_node(fdt, "subnode@1"));
135 	CHECK(fdt_property_string(fdt, "compatible", "subnode1"));
136 	CHECK(fdt_property_u32(fdt, "reg", 1));
137 	CHECK(fdt_property_cell(fdt, "prop-int", TEST_VALUE_1));
138 	CHECK(fdt_begin_node(fdt, "subsubnode"));
139 	CHECK(fdt_property(fdt, "compatible", "subsubnode1\0subsubnode",
140 			   23));
141 	CHECK(fdt_property_placeholder(fdt, "placeholder", place_len, &place));
142 	memcpy(place, place_str, place_len);
143 	CHECK(fdt_property_cell(fdt, "prop-int", TEST_VALUE_1));
144 	CHECK(fdt_end_node(fdt));
145 	CHECK(fdt_begin_node(fdt, "ss1"));
146 	CHECK(fdt_end_node(fdt));
147 	CHECK(fdt_end_node(fdt));
148 
149 	CHECK(fdt_begin_node(fdt, "subnode@2"));
150 	CHECK(fdt_property_u32(fdt, "reg", 2));
151 	CHECK(fdt_property_cell(fdt, "linux,phandle", PHANDLE_1));
152 	CHECK(fdt_property_cell(fdt, "prop-int", TEST_VALUE_2));
153 	CHECK(fdt_property_u32(fdt, "#address-cells", 1));
154 	CHECK(fdt_property_u32(fdt, "#size-cells", 0));
155 	CHECK(fdt_begin_node(fdt, "subsubnode@0"));
156 	CHECK(fdt_property_u32(fdt, "reg", 0));
157 	CHECK(fdt_property_cell(fdt, "phandle", PHANDLE_2));
158 	CHECK(fdt_property(fdt, "compatible", "subsubnode2\0subsubnode",
159 			   23));
160 	CHECK(fdt_property_cell(fdt, "prop-int", TEST_VALUE_2));
161 	CHECK(fdt_end_node(fdt));
162 	CHECK(fdt_begin_node(fdt, "ss2"));
163 	CHECK(fdt_end_node(fdt));
164 
165 	CHECK(fdt_end_node(fdt));
166 
167 	CHECK(fdt_end_node(fdt));
168 
169 	save_blob("unfinished_tree1.test.dtb", fdt);
170 
171 	CHECK(fdt_finish(fdt));
172 
173 	verbose_printf("Completed tree, totalsize = %d\n",
174 		       fdt_totalsize(fdt));
175 
176 	save_blob("sw_tree1.test.dtb", fdt);
177 
178 	PASS();
179 }
180