device-tree-compiler-1.4.0+dfsg.orig/0000775000000000000000000000000012261543523014271 5ustar device-tree-compiler-1.4.0+dfsg.orig/dtc-lexer.l0000664000000000000000000001270712261525673016352 0ustar /* * (C) Copyright David Gibson , IBM Corporation. 2005. * * * 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 */ %option noyywrap nounput noinput never-interactive %x INCLUDE %x BYTESTRING %x PROPNODENAME %s V1 PROPNODECHAR [a-zA-Z0-9,._+*#?@-] PATHCHAR ({PROPNODECHAR}|[/]) LABEL [a-zA-Z_][a-zA-Z0-9_]* STRING \"([^\\"]|\\.)*\" CHAR_LITERAL '([^']|\\')*' WS [[:space:]] COMMENT "/*"([^*]|\*+[^*/])*\*+"/" LINECOMMENT "//".*\n %{ #include "dtc.h" #include "srcpos.h" #include "dtc-parser.tab.h" YYLTYPE yylloc; /* CAUTION: this will stop working if we ever use yyless() or yyunput() */ #define YY_USER_ACTION \ { \ srcpos_update(&yylloc, yytext, yyleng); \ } /*#define LEXDEBUG 1*/ #ifdef LEXDEBUG #define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__) #else #define DPRINT(fmt, ...) do { } while (0) #endif static int dts_version = 1; #define BEGIN_DEFAULT() DPRINT("\n"); \ BEGIN(V1); \ static void push_input_file(const char *filename); static int pop_input_file(void); %} %% <*>"/include/"{WS}*{STRING} { char *name = strchr(yytext, '\"') + 1; yytext[yyleng-1] = '\0'; push_input_file(name); } <*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? { char *line, *tmp, *fn; /* skip text before line # */ line = yytext; while (!isdigit(*line)) line++; /* skip digits in line # */ tmp = line; while (!isspace(*tmp)) tmp++; /* "NULL"-terminate line # */ *tmp = '\0'; /* start of filename */ fn = strchr(tmp + 1, '"') + 1; /* strip trailing " from filename */ tmp = strchr(fn, '"'); *tmp = 0; /* -1 since #line is the number of the next line */ srcpos_set_line(xstrdup(fn), atoi(line) - 1); } <*><> { if (!pop_input_file()) { yyterminate(); } } <*>{STRING} { DPRINT("String: %s\n", yytext); yylval.data = data_copy_escape_string(yytext+1, yyleng-2); return DT_STRING; } <*>"/dts-v1/" { DPRINT("Keyword: /dts-v1/\n"); dts_version = 1; BEGIN_DEFAULT(); return DT_V1; } <*>"/memreserve/" { DPRINT("Keyword: /memreserve/\n"); BEGIN_DEFAULT(); return DT_MEMRESERVE; } <*>"/bits/" { DPRINT("Keyword: /bits/\n"); BEGIN_DEFAULT(); return DT_BITS; } <*>"/delete-property/" { DPRINT("Keyword: /delete-property/\n"); DPRINT("\n"); BEGIN(PROPNODENAME); return DT_DEL_PROP; } <*>"/delete-node/" { DPRINT("Keyword: /delete-node/\n"); DPRINT("\n"); BEGIN(PROPNODENAME); return DT_DEL_NODE; } <*>{LABEL}: { DPRINT("Label: %s\n", yytext); yylval.labelref = xstrdup(yytext); yylval.labelref[yyleng-1] = '\0'; return DT_LABEL; } ([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? { yylval.literal = xstrdup(yytext); DPRINT("Literal: '%s'\n", yylval.literal); return DT_LITERAL; } <*>{CHAR_LITERAL} { yytext[yyleng-1] = '\0'; yylval.literal = xstrdup(yytext+1); DPRINT("Character literal: %s\n", yylval.literal); return DT_CHAR_LITERAL; } <*>\&{LABEL} { /* label reference */ DPRINT("Ref: %s\n", yytext+1); yylval.labelref = xstrdup(yytext+1); return DT_REF; } <*>"&{/"{PATHCHAR}+\} { /* new-style path reference */ yytext[yyleng-1] = '\0'; DPRINT("Ref: %s\n", yytext+2); yylval.labelref = xstrdup(yytext+2); return DT_REF; } [0-9a-fA-F]{2} { yylval.byte = strtol(yytext, NULL, 16); DPRINT("Byte: %02x\n", (int)yylval.byte); return DT_BYTE; } "]" { DPRINT("/BYTESTRING\n"); BEGIN_DEFAULT(); return ']'; } \\?{PROPNODECHAR}+ { DPRINT("PropNodeName: %s\n", yytext); yylval.propnodename = xstrdup((yytext[0] == '\\') ? yytext + 1 : yytext); BEGIN_DEFAULT(); return DT_PROPNODENAME; } "/incbin/" { DPRINT("Binary Include\n"); return DT_INCBIN; } <*>{WS}+ /* eat whitespace */ <*>{COMMENT}+ /* eat C-style comments */ <*>{LINECOMMENT}+ /* eat C++-style comments */ <*>"<<" { return DT_LSHIFT; }; <*>">>" { return DT_RSHIFT; }; <*>"<=" { return DT_LE; }; <*>">=" { return DT_GE; }; <*>"==" { return DT_EQ; }; <*>"!=" { return DT_NE; }; <*>"&&" { return DT_AND; }; <*>"||" { return DT_OR; }; <*>. { DPRINT("Char: %c (\\x%02x)\n", yytext[0], (unsigned)yytext[0]); if (yytext[0] == '[') { DPRINT("\n"); BEGIN(BYTESTRING); } if ((yytext[0] == '{') || (yytext[0] == ';')) { DPRINT("\n"); BEGIN(PROPNODENAME); } return yytext[0]; } %% static void push_input_file(const char *filename) { assert(filename); srcfile_push(filename); yyin = current_srcfile->f; yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE)); } static int pop_input_file(void) { if (srcfile_pop() == 0) return 0; yypop_buffer_state(); yyin = current_srcfile->f; return 1; } device-tree-compiler-1.4.0+dfsg.orig/tests/0000775000000000000000000000000012261525674015442 5ustar device-tree-compiler-1.4.0+dfsg.orig/tests/node_offset_by_prop_value.c0000664000000000000000000000634312261525674023035 0ustar /* * 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 #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/default-addr-size.dts0000664000000000000000000000005712261525673021463 0ustar /dts-v1/; / { node { reg = <0 0 0>; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/add_subnode_with_nops.c0000664000000000000000000000410412261525673022145 0ustar /* * 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 #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/supernode_atdepth_offset.c0000664000000000000000000000737512261525674022705 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/incbin.dts0000664000000000000000000000014612261525673017420 0ustar /dts-v1/; / { incbin = /incbin/("incbin.bin"); incbin-partial = /incbin/("incbin.bin", 13, 17); }; device-tree-compiler-1.4.0+dfsg.orig/tests/sw_tree1.c0000664000000000000000000000560312261525674017343 0ustar /* * 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 #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/get_mem_rsv.c0000664000000000000000000000263012261525673020115 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/value-labels.c0000664000000000000000000000602012261525674020160 0ustar /* * 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 #include #include #include #include #include #include #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 ", 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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/include6.dts0000664000000000000000000000001612261525673017663 0ustar "hello world" device-tree-compiler-1.4.0+dfsg.orig/tests/find_property.c0000664000000000000000000000237112261525673020474 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/fdtput-runtest.sh0000664000000000000000000000140612261525673021006 0ustar #! /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 device-tree-compiler-1.4.0+dfsg.orig/tests/deps_inc2.dtsi0000664000000000000000000000001412261525673020167 0ustar /* Empty */ device-tree-compiler-1.4.0+dfsg.orig/tests/search_dir_b/0000775000000000000000000000000012261525674020046 5ustar device-tree-compiler-1.4.0+dfsg.orig/tests/search_dir_b/search_test_b2.dtsi0000664000000000000000000000004612261525674023622 0ustar /include/ "search_test.dtsi" / { }; device-tree-compiler-1.4.0+dfsg.orig/tests/search_dir_b/search_test_b.dtsi0000664000000000000000000000005012261525674023533 0ustar /include/ "search_test_b2.dtsi" / { }; device-tree-compiler-1.4.0+dfsg.orig/tests/search_dir_b/search_test_c.dtsi0000664000000000000000000000000712261525674023536 0ustar / { }; device-tree-compiler-1.4.0+dfsg.orig/tests/search_dir_b/search_paths_subdir.dts0000664000000000000000000000006212261525674024574 0ustar /dts-v1/; /include/ "search_test_c.dtsi" / { }; device-tree-compiler-1.4.0+dfsg.orig/tests/nonexist-label-ref.dts0000664000000000000000000000012012261525674021645 0ustar /dts-v1/; / { ref = <&label>; badref = <&nosuchlabel>; label: node { }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/search_dir/0000775000000000000000000000000012261525674017545 5ustar device-tree-compiler-1.4.0+dfsg.orig/tests/search_dir/search_test.dtsi0000664000000000000000000000004612261525674022736 0ustar /include/ "search_test2.dtsi" / { }; device-tree-compiler-1.4.0+dfsg.orig/tests/search_dir/search_test2.dtsi0000664000000000000000000000001012261525674023007 0ustar / { }; device-tree-compiler-1.4.0+dfsg.orig/tests/bad-ncells.dts0000664000000000000000000000015312261525673020160 0ustar /dts-v1/; / { #address-cells = "badthing"; #size-cells = "badthing"; #interrupt-cells = "badthing"; }; device-tree-compiler-1.4.0+dfsg.orig/tests/mangle-layout.supp0000664000000000000000000000017412261525674021133 0ustar { uninitialized alignment gaps can be dumped to output Memcheck:Param write(buf) obj:/lib/ld-*.so fun:main } device-tree-compiler-1.4.0+dfsg.orig/tests/char_literal.dts0000664000000000000000000000010512261525673020602 0ustar /dts-v1/; / { char-literal-cells = <'\r' 'b' '\0' '\'' '\xff'>; }; device-tree-compiler-1.4.0+dfsg.orig/tests/bad-name-property.dts0000664000000000000000000000006512261525673021504 0ustar /dts-v1/; / { node@0 { name = "badthing"; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/setprop_inplace.c0000664000000000000000000000530212261525674020775 0ustar /* * 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 #include #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/del_node.c0000664000000000000000000001000212261525673017347 0ustar /* * 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 #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/fdtget-runtest.sh0000775000000000000000000000057712261525673020770 0ustar #! /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 device-tree-compiler-1.4.0+dfsg.orig/tests/dtc-checkfails.sh0000775000000000000000000000130212261525673020640 0ustar #! /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 device-tree-compiler-1.4.0+dfsg.orig/tests/base01.asm0000664000000000000000000000562712261525673017230 0ustar /* 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: device-tree-compiler-1.4.0+dfsg.orig/tests/reuse-label3.dts0000664000000000000000000000012412261525674020436 0ustar /dts-v1/; / { label: property = "foo"; label: node { property = "foo"; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/string_escapes.c0000664000000000000000000000244212261525674020621 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/setprop.c0000664000000000000000000000540012261525674017301 0ustar /* * 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 #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/search_paths.dts0000664000000000000000000000006012261525674020616 0ustar /dts-v1/; /include/ "search_test.dtsi" / { }; device-tree-compiler-1.4.0+dfsg.orig/tests/references.c0000664000000000000000000000627412261525674017740 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/trees.S0000664000000000000000000001027612261525674016716 0ustar #include #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: device-tree-compiler-1.4.0+dfsg.orig/tests/nop_node.c0000664000000000000000000000715012261525674017412 0ustar /* * 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 #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/minusone-phandle.dts0000664000000000000000000000007612261525674021427 0ustar /dts-v1/; / { node { linux,phandle = <0xffffffff>; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/asm_tree_dump.c0000664000000000000000000000315612261525673020436 0ustar /* * 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 #include #include #include #include #include #include #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 ", 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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/get_phandle.c0000664000000000000000000000315312261525673020061 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/reuse-label6.dts0000664000000000000000000000010012261525674020433 0ustar /dts-v1/; / { label: prop1 = "foo"; prop2 = "bar" label:; }; device-tree-compiler-1.4.0+dfsg.orig/tests/propname_escapes.c0000664000000000000000000000236712261525674021142 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/prop-after-subnode.dts0000664000000000000000000000006312261525674021671 0ustar /dts-v1/; / { node1 { }; prop; node2 { }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/include4.dts0000664000000000000000000000003412261525673017661 0ustar compatible = "test_tree1"; device-tree-compiler-1.4.0+dfsg.orig/tests/path-references.dts0000664000000000000000000000036012261525674021230 0ustar /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; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/subnode_iterate.c0000664000000000000000000000445712261525674020774 0ustar /* * 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 #include #include #include #include #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 ", argv[0]); fdt = load_blob(argv[1]); if (!fdt) FAIL("No device tree available"); check_fdt_next_subnode(fdt); PASS(); } device-tree-compiler-1.4.0+dfsg.orig/tests/reuse-label1.dts0000664000000000000000000000013212261525674020433 0ustar /dts-v1/; / { label: node1 { prop = "foo"; }; label: node2 { prop = "bar"; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/integer-expressions.c0000664000000000000000000000610312261525673021622 0ustar /* * 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 #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/path_offset.c0000664000000000000000000000746212261525674020121 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/test_tree1_wrong7.dts0000664000000000000000000000110112261525674021531 0ustar /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 { }; }; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/reuse-label5.dts0000664000000000000000000000010012261525674020432 0ustar /dts-v1/; / { prop1 = label: "foo"; prop2 = "bar" label:; }; device-tree-compiler-1.4.0+dfsg.orig/tests/delete_reinstate_multilabel_ref.dts0000664000000000000000000000010212261525673024534 0ustar /dts-v1/; / { prop = "value"; node { prop = "value"; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/bad-reg-ranges.dts0000664000000000000000000000023112261525673020727 0ustar /dts-v1/; / { #address-cells = <2>; #size-cells = <2>; node { reg = <0 0>; #address-cells = <1>; #size-cells = <1>; ranges = <0 0 0>; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/include3.dts0000664000000000000000000000002112261525673017654 0ustar 123456789 010000 device-tree-compiler-1.4.0+dfsg.orig/tests/label01.dts0000664000000000000000000000271212261525673017377 0ustar /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>; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/dependencies.cmp0000664000000000000000000000010612261525673020565 0ustar dependencies.test.dtb: dependencies.dts deps_inc1.dtsi deps_inc2.dtsi device-tree-compiler-1.4.0+dfsg.orig/tests/path_offset_aliases.c0000664000000000000000000000361512261525674021616 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/obsolete-chosen-interrupt-controller.dts0000664000000000000000000000025212261525674025461 0ustar /dts-v1/; / { #address-cells = <1>; #size-cells = <1>; PIC: pic@0 { reg = <0x0 0x10>; interrupt-controller; }; chosen { interrupt-controller = <&PIC>; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/multilabel.dts0000664000000000000000000000160412261525674020311 0ustar /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; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/dtbs_equal_unordered.c0000664000000000000000000001352712261525673022007 0ustar /* * 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 #include #include #include #include #include #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] ", 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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/include2.dts0000664000000000000000000000005212261525673017657 0ustar /memreserve/ 0xdeadbeef00000000 0x100000; device-tree-compiler-1.4.0+dfsg.orig/tests/testdata.h0000664000000000000000000000170112261525674017423 0ustar #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 */ device-tree-compiler-1.4.0+dfsg.orig/tests/get_name.c0000664000000000000000000000451712261525673017373 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/tests.h0000664000000000000000000000701512261525674016760 0ustar #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 */ device-tree-compiler-1.4.0+dfsg.orig/tests/base01.dts0000664000000000000000000000121512261525673017227 0ustar /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>; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/dtc-fatal.sh0000664000000000000000000000037212261525673017636 0ustar #! /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 device-tree-compiler-1.4.0+dfsg.orig/tests/test_tree1_wrong9.dts0000664000000000000000000000107612261525674021546 0ustar /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 { }; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/extra-terminating-null.c0000664000000000000000000000346512261525673022227 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/truncated_property.c0000664000000000000000000000265212261525674021550 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/test_tree1.dts0000664000000000000000000000005412261525674020234 0ustar /dts-v1/; /include/ "test_tree1_body.dtsi" device-tree-compiler-1.4.0+dfsg.orig/tests/dup-propname.dts0000664000000000000000000000004012261525673020556 0ustar /dts-v1/; / { prop; prop; }; device-tree-compiler-1.4.0+dfsg.orig/tests/test_tree1_delete.dts0000664000000000000000000000134212261525674021557 0ustar /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; }; device-tree-compiler-1.4.0+dfsg.orig/tests/reuse-label.dts0000664000000000000000000000024312261525674020355 0ustar /dts-v1/; / { label: property1 = "foo"; label: property2 = "bar"; test1 = &label; label: node1 { prop = "foo"; }; label: node2 { prop = "bar"; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/sized_cells.dts0000664000000000000000000000055412261525674020462 0ustar /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>; }; device-tree-compiler-1.4.0+dfsg.orig/tests/include7.dts0000664000000000000000000000026112261525673017666 0ustar subnode@1 { compatible = "subnode1"; prop-int = [deadbeef]; subsubnode { compatible = "subsubnode1", "subsubnode"; prop-int = <0xdeadbeef>; }; ss1 { }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/test_tree1_body.dtsi0000664000000000000000000000112512261525674021422 0ustar /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 { }; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/test01.asm0000664000000000000000000001142412261525674017266 0ustar /* 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: device-tree-compiler-1.4.0+dfsg.orig/tests/lorem.txt0000664000000000000000000000400712261525674017322 0ustar 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. device-tree-compiler-1.4.0+dfsg.orig/tests/nonexist-node-ref2.dts0000664000000000000000000000015712261525674021607 0ustar /dts-v1/; / { label: node { }; }; /* Try to redefine a node using a non-existent label */ &nosuchnode { }; device-tree-compiler-1.4.0+dfsg.orig/tests/dup-phandle.dts0000664000000000000000000000013212261525673020352 0ustar /dts-v1/; / { node1 { linux,phandle = <1>; }; node2 { linux,phandle = <1>; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/sized_cells.c0000664000000000000000000000462312261525674020113 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/root_node.c0000664000000000000000000000266112261525674017603 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/zero-phandle.dts0000664000000000000000000000006512261525674020547 0ustar /dts-v1/; / { node { linux,phandle = <0>; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/data.S0000664000000000000000000000015512261525673016477 0ustar /* Used in combination with dtc -Oasm output to embed * a device tree in the data section of a .o */ .data device-tree-compiler-1.4.0+dfsg.orig/tests/line_directives.dts0000664000000000000000000000073112261525674021327 0ustar /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 >; }; device-tree-compiler-1.4.0+dfsg.orig/tests/test_kernel_dts0000775000000000000000000000401012261525674020554 0ustar #!/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"; } } device-tree-compiler-1.4.0+dfsg.orig/tests/search_paths_b.dts0000664000000000000000000000006212261525674021121 0ustar /dts-v1/; /include/ "search_test_b.dtsi" / { }; device-tree-compiler-1.4.0+dfsg.orig/tests/open_pack.c0000664000000000000000000000357612261525674017560 0ustar /* * 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 #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/test_tree1_merge_path.dts0000664000000000000000000000122412261525674022427 0ustar /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>; }; device-tree-compiler-1.4.0+dfsg.orig/tests/move_and_save.c0000664000000000000000000000404412261525674020416 0ustar /* * 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 #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/references.dts0000664000000000000000000000137412261525674020304 0ustar /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>; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/reuse-label4.dts0000664000000000000000000000006312261525674020441 0ustar /dts-v1/; / { property = label: "foo" label:; }; device-tree-compiler-1.4.0+dfsg.orig/tests/appendprop1.c0000664000000000000000000000361712261525673020045 0ustar /* * 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 #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/mangle-layout.c0000664000000000000000000000736612261525674020400 0ustar /* * 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 #include #include #include #include #include #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 ", 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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/test_tree1_wrong4.dts0000664000000000000000000000103612261525674021535 0ustar /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>; }; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/Makefile.tests0000664000000000000000000000450112261525673020242 0ustar 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 device-tree-compiler-1.4.0+dfsg.orig/tests/base01.cmd0000664000000000000000000000004012261525673017173 0ustar dtc -f -b 0 -V 16 -I dts -O asm device-tree-compiler-1.4.0+dfsg.orig/tests/dtb_reverse.c0000664000000000000000000001007312261525673020112 0ustar /* * 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 #include #include #include #include #include #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 ", 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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/include8.dts0000664000000000000000000000001612261525673017665 0ustar subsubnode@0 {device-tree-compiler-1.4.0+dfsg.orig/tests/dumptrees.c0000664000000000000000000000336212261525673017621 0ustar /* * dumptrees - utility for libfdt testing * * (C) Copyright David Gibson , 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 #include #include #include #include #include #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); } device-tree-compiler-1.4.0+dfsg.orig/tests/get_path.c0000664000000000000000000000513312261525673017402 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/include0.dts0000664000000000000000000000003112261525673017652 0ustar /include/ "include1.dts" device-tree-compiler-1.4.0+dfsg.orig/tests/test_tree1_merge.dts0000664000000000000000000000123612261525674021416 0ustar /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>; }; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/test_tree1_wrong2.dts0000664000000000000000000000102212261525674021526 0ustar /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 { }; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/test_tree1_wrong5.dts0000664000000000000000000000105412261525674021536 0ustar /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 { }; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/incbin.c0000664000000000000000000000347412261525673017057 0ustar /* * 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 #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/testutils.c0000664000000000000000000001205012261525674017644 0ustar /* * 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 #include #include #include #include #include #include #include #include #include #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 ", 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; } device-tree-compiler-1.4.0+dfsg.orig/tests/open_pack.supp0000664000000000000000000000015412261525674020312 0ustar { opened blob dumps uninitialized data Memcheck:Param write(buf) obj:/lib/ld-*.so fun:main } device-tree-compiler-1.4.0+dfsg.orig/tests/test_tree1_wrong3.dts0000664000000000000000000000102312261525674021530 0ustar /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 { }; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/incbin.bin0000664000000000000000000000006412261525673017375 0ustar abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZdevice-tree-compiler-1.4.0+dfsg.orig/tests/run_tests.sh0000775000000000000000000005311512261525674020034 0ustar #! /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 [] 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 "" -tx \ -d "" $dtb /randomnode doctor-who run_fdtget_test "" -tx -d "" $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 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 "**********" device-tree-compiler-1.4.0+dfsg.orig/tests/escapes.dts0000664000000000000000000000021412261525673017575 0ustar /dts-v1/; / { compatible = "test_string_escapes"; escape-str = "nastystring: \a\b\t\n\v\f\r\\\""; escape-str-2 = "\xde\xad\xbe\xef"; }; device-tree-compiler-1.4.0+dfsg.orig/tests/nonexist-node-ref.dts0000664000000000000000000000013012261525674021514 0ustar /dts-v1/; / { ref = < &{/node} >; badref = < &{/nosuchnode} >; label: node { }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/nopulate.c0000664000000000000000000000547512261525674017450 0ustar /* * 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 #include #include #include #include #include #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 ", 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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/tests.sh0000664000000000000000000000156012261525674017142 0ustar # 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 } device-tree-compiler-1.4.0+dfsg.orig/tests/test_tree1_wrong1.dts0000664000000000000000000000100212261525674021523 0ustar /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 { }; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/aliases.dts0000664000000000000000000000045712261525673017604 0ustar /dts-v1/; / { aliases { s1 = &sub1; ss1 = &subsub1; sss1 = &subsubsub1; }; sub1: subnode@1 { compatible = "subnode1"; subsub1: subsubnode { compatible = "subsubnode1", "subsubnode"; subsubsub1: subsubsubnode { compatible = "subsubsubnode1", "subsubsubnode"; }; }; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/multilabel_merge.dts0000664000000000000000000000235512261525674021474 0ustar /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; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/include5.dts0000664000000000000000000000001112261525673017655 0ustar prop-int device-tree-compiler-1.4.0+dfsg.orig/tests/test01.dts0000664000000000000000000000224012261525674017274 0ustar /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>; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/empty.dts0000664000000000000000000000002212261525673017305 0ustar /dts-v1/; / { }; device-tree-compiler-1.4.0+dfsg.orig/tests/char_literal.c0000664000000000000000000000315312261525673020240 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/propname_escapes.dts0000664000000000000000000000007612261525674021505 0ustar /dts-v1/; / { #address-cells = <1>; \#gpio-cells = <2>; }; device-tree-compiler-1.4.0+dfsg.orig/tests/deps_inc1.dtsi0000664000000000000000000000003312261525673020167 0ustar /include/ "deps_inc2.dtsi" device-tree-compiler-1.4.0+dfsg.orig/tests/include5a.dts0000664000000000000000000000004012261525673020020 0ustar = /bits/ 64 <0xdeadbeef01abcdef>device-tree-compiler-1.4.0+dfsg.orig/tests/path-references.c0000664000000000000000000000463612261525674020672 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/node_offset_by_compatible.c0000664000000000000000000000541712261525674023001 0ustar /* * 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 #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/set_name.c0000664000000000000000000000507612261525674017411 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/appendprop2.c0000664000000000000000000000333312261525673020041 0ustar /* * 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 #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/node_offset_by_phandle.c0000664000000000000000000000361612261525674022274 0ustar /* * 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 #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/appendprop.dts0000664000000000000000000000033312261525673020324 0ustar /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]; }; device-tree-compiler-1.4.0+dfsg.orig/tests/test_tree1_wrong8.dts0000664000000000000000000000105412261525674021541 0ustar /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 { }; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/notfound.c0000664000000000000000000000433012261525674017442 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/label_repeated.dts0000664000000000000000000000014212261525674021103 0ustar /dts-v1/; / { l0: prop = "foo"; l1: node { }; }; / { l0: prop = "foo"; l1: node { }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/test01.stderr0000664000000000000000000000033412261525674020007 0ustar 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 device-tree-compiler-1.4.0+dfsg.orig/tests/dup-nodename.dts0000664000000000000000000000005212261525673020526 0ustar /dts-v1/; / { node { }; node { }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/test_tree1_wrong6.dts0000664000000000000000000000107312261525674021540 0ustar /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 { }; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/base01.stderr0000664000000000000000000000037212261525673017743 0ustar 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 device-tree-compiler-1.4.0+dfsg.orig/tests/del_property.c0000664000000000000000000000477312261525673020330 0ustar /* * 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 #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/include1.dts0000664000000000000000000000072612261525673017666 0ustar /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 { }; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/comments.dts0000664000000000000000000000071012261525673020000 0ustar /* 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 */ device-tree-compiler-1.4.0+dfsg.orig/tests/node_check_compatible.c0000664000000000000000000000355212261525674022074 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/boot-cpuid.c0000664000000000000000000000244412261525673017656 0ustar /* * 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 #include #include #include #include #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 ", 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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/dtc-fails.sh0000775000000000000000000000056012261525673017647 0ustar #! /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 device-tree-compiler-1.4.0+dfsg.orig/tests/bad-string-props.dts0000664000000000000000000000013612261525673021350 0ustar /dts-v1/; / { device_type = <0xdeadbeef>; model = <0xdeadbeef>; status = <0xdeadbeef>; }; device-tree-compiler-1.4.0+dfsg.orig/tests/utilfdt_test.c0000664000000000000000000000612112261525674020320 0ustar /* * 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 #include #include #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/dtbs_equal_ordered.c0000664000000000000000000001104412261525673021434 0ustar /* * 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 #include #include #include #include #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] ", 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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/phandle_format.c0000664000000000000000000000426712261525674020602 0ustar /* * 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 #include #include #include #include #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 \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 \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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/value-labels.dts0000664000000000000000000000035112261525674020531 0ustar /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:; }; device-tree-compiler-1.4.0+dfsg.orig/tests/test_tree1_merge_labelled.dts0000664000000000000000000000117712261525674023246 0ustar /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>; }; device-tree-compiler-1.4.0+dfsg.orig/tests/delete_reinstate_multilabel.dts0000664000000000000000000000146712261525673023717 0ustar /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"; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/.gitignore0000664000000000000000000000151112261525673017427 0ustar *.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 device-tree-compiler-1.4.0+dfsg.orig/tests/extra-terminating-null.dts0000664000000000000000000000040712261525673022570 0ustar /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"; }; device-tree-compiler-1.4.0+dfsg.orig/tests/reg-ranges-root.dts0000664000000000000000000000016512261525674021173 0ustar /dts-v1/; / { #address-cells = <1>; #size-cells = <1>; reg = <0x1000 0x10>; ranges = <0x1000 0x2000 0x1000>; }; device-tree-compiler-1.4.0+dfsg.orig/tests/boot-cpuid.dts0000664000000000000000000000031012261525673020214 0ustar /dts-v1/; / { cpus { cpu@10 { device_type = "cpu"; compatible = "fake-cpu"; reg = <0x10>; }; cpu@11 { device_type = "cpu"; compatible = "fake-cpu"; reg = <0x11>; }; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/reuse-label2.dts0000664000000000000000000000011012261525674020430 0ustar /dts-v1/; / { label: property1 = "foo"; label: property2 = "bar"; }; device-tree-compiler-1.4.0+dfsg.orig/tests/comments-cmp.dts0000664000000000000000000000016012261525673020554 0ustar /dts-v1/; / { prop1; prop2; prop3; prop4; prop5; prop6; prop7; prop8; prop9; prop10; child { }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/subnode_offset.c0000664000000000000000000000640012261525674020613 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/parent_offset.c0000664000000000000000000000501412261525674020445 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/rw_tree1.c0000664000000000000000000000554512261525674017347 0ustar /* * 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 #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/get_alias.c0000664000000000000000000000313412261525673017536 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/getprop.c0000664000000000000000000000236012261525673017266 0ustar /* * 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 #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/subnode_iterate.dts0000664000000000000000000000137112261525674021334 0ustar /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>; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/bad-empty-ranges.dts0000664000000000000000000000020012261525673021304 0ustar /dts-v1/; / { #address-cells = <2>; #size-cells = <2>; node { #address-cells = <1>; #size-cells = <1>; ranges; }; }; device-tree-compiler-1.4.0+dfsg.orig/tests/nop_property.c0000664000000000000000000000413112261525674020345 0ustar /* * 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 #include #include #include #include #include #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(); } device-tree-compiler-1.4.0+dfsg.orig/tests/dependencies.dts0000664000000000000000000000005612261525673020604 0ustar /dts-v1/; /include/ "deps_inc1.dtsi" / { }; device-tree-compiler-1.4.0+dfsg.orig/Makefile.utils0000664000000000000000000000055412261525673017102 0ustar # # This is not a complete Makefile of itself. Instead, it is designed to # be easily embeddable into other systems of Makefiles. # FDTDUMP_SRCS = \ fdtdump.c \ util.c FDTDUMP_OBJS = $(FDTDUMP_SRCS:%.c=%.o) FDTGET_SRCS = \ fdtget.c \ util.c FDTGET_OBJS = $(FDTGET_SRCS:%.c=%.o) FDTPUT_SRCS = \ fdtput.c \ util.c FDTPUT_OBJS = $(FDTPUT_SRCS:%.c=%.o) device-tree-compiler-1.4.0+dfsg.orig/Makefile.dtc0000664000000000000000000000056412261525673016515 0ustar # Makefile.dtc # # This is not a complete Makefile of itself. Instead, it is designed to # be easily embeddable into other systems of Makefiles. # DTC_SRCS = \ checks.c \ data.c \ dtc.c \ flattree.c \ fstree.c \ livetree.c \ srcpos.c \ treesource.c \ util.c DTC_GEN_SRCS = dtc-lexer.lex.c dtc-parser.tab.c DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o) device-tree-compiler-1.4.0+dfsg.orig/dtc-parser.y0000664000000000000000000002412612261525673016542 0ustar /* * (C) Copyright David Gibson , IBM Corporation. 2005. * * * 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 #include "dtc.h" #include "srcpos.h" YYLTYPE yylloc; extern int yylex(void); extern void print_error(char const *fmt, ...); extern void yyerror(char const *s); extern struct boot_info *the_boot_info; extern int treesource_error; static unsigned long long eval_literal(const char *s, int base, int bits); static unsigned char eval_char_literal(const char *s); %} %union { char *propnodename; char *literal; char *labelref; unsigned int cbase; uint8_t byte; struct data data; struct { struct data data; int bits; } array; struct property *prop; struct property *proplist; struct node *node; struct node *nodelist; struct reserve_info *re; uint64_t integer; } %token DT_V1 %token DT_MEMRESERVE %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR %token DT_BITS %token DT_DEL_PROP %token DT_DEL_NODE %token DT_PROPNODENAME %token DT_LITERAL %token DT_CHAR_LITERAL %token DT_BASE %token DT_BYTE %token DT_STRING %token DT_LABEL %token DT_REF %token DT_INCBIN %type propdata %type propdataprefix %type memreserve %type memreserves %type arrayprefix %type bytestring %type propdef %type proplist %type devicetree %type nodedef %type subnode %type subnodes %type integer_prim %type integer_unary %type integer_mul %type integer_add %type integer_shift %type integer_rela %type integer_eq %type integer_bitand %type integer_bitxor %type integer_bitor %type integer_and %type integer_or %type integer_trinary %type integer_expr %% sourcefile: DT_V1 ';' memreserves devicetree { the_boot_info = build_boot_info($3, $4, guess_boot_cpuid($4)); } ; memreserves: /* empty */ { $$ = NULL; } | memreserve memreserves { $$ = chain_reserve_entry($1, $2); } ; memreserve: DT_MEMRESERVE integer_prim integer_prim ';' { $$ = build_reserve_entry($2, $3); } | DT_LABEL memreserve { add_label(&$2->labels, $1); $$ = $2; } ; devicetree: '/' nodedef { $$ = name_node($2, ""); } | devicetree '/' nodedef { $$ = merge_nodes($1, $3); } | devicetree DT_REF nodedef { struct node *target = get_node_by_ref($1, $2); if (target) merge_nodes(target, $3); else print_error("label or path, '%s', not found", $2); $$ = $1; } | devicetree DT_DEL_NODE DT_REF ';' { struct node *target = get_node_by_ref($1, $3); if (!target) print_error("label or path, '%s', not found", $3); else delete_node(target); $$ = $1; } ; nodedef: '{' proplist subnodes '}' ';' { $$ = build_node($2, $3); } ; proplist: /* empty */ { $$ = NULL; } | proplist propdef { $$ = chain_property($2, $1); } ; propdef: DT_PROPNODENAME '=' propdata ';' { $$ = build_property($1, $3); } | DT_PROPNODENAME ';' { $$ = build_property($1, empty_data); } | DT_DEL_PROP DT_PROPNODENAME ';' { $$ = build_property_delete($2); } | DT_LABEL propdef { add_label(&$2->labels, $1); $$ = $2; } ; propdata: propdataprefix DT_STRING { $$ = data_merge($1, $2); } | propdataprefix arrayprefix '>' { $$ = data_merge($1, $2.data); } | propdataprefix '[' bytestring ']' { $$ = data_merge($1, $3); } | propdataprefix DT_REF { $$ = data_add_marker($1, REF_PATH, $2); } | propdataprefix DT_INCBIN '(' DT_STRING ',' integer_prim ',' integer_prim ')' { FILE *f = srcfile_relative_open($4.val, NULL); struct data d; if ($6 != 0) if (fseek(f, $6, SEEK_SET) != 0) print_error("Couldn't seek to offset %llu in \"%s\": %s", (unsigned long long)$6, $4.val, strerror(errno)); d = data_copy_file(f, $8); $$ = data_merge($1, d); fclose(f); } | propdataprefix DT_INCBIN '(' DT_STRING ')' { FILE *f = srcfile_relative_open($4.val, NULL); struct data d = empty_data; d = data_copy_file(f, -1); $$ = data_merge($1, d); fclose(f); } | propdata DT_LABEL { $$ = data_add_marker($1, LABEL, $2); } ; propdataprefix: /* empty */ { $$ = empty_data; } | propdata ',' { $$ = $1; } | propdataprefix DT_LABEL { $$ = data_add_marker($1, LABEL, $2); } ; arrayprefix: DT_BITS DT_LITERAL '<' { $$.data = empty_data; $$.bits = eval_literal($2, 0, 7); if (($$.bits != 8) && ($$.bits != 16) && ($$.bits != 32) && ($$.bits != 64)) { print_error("Only 8, 16, 32 and 64-bit elements" " are currently supported"); $$.bits = 32; } } | '<' { $$.data = empty_data; $$.bits = 32; } | arrayprefix integer_prim { if ($1.bits < 64) { uint64_t mask = (1ULL << $1.bits) - 1; /* * Bits above mask must either be all zero * (positive within range of mask) or all one * (negative and sign-extended). The second * condition is true if when we set all bits * within the mask to one (i.e. | in the * mask), all bits are one. */ if (($2 > mask) && (($2 | mask) != -1ULL)) print_error( "integer value out of range " "%016lx (%d bits)", $1.bits); } $$.data = data_append_integer($1.data, $2, $1.bits); } | arrayprefix DT_REF { uint64_t val = ~0ULL >> (64 - $1.bits); if ($1.bits == 32) $1.data = data_add_marker($1.data, REF_PHANDLE, $2); else print_error("References are only allowed in " "arrays with 32-bit elements."); $$.data = data_append_integer($1.data, val, $1.bits); } | arrayprefix DT_LABEL { $$.data = data_add_marker($1.data, LABEL, $2); } ; integer_prim: DT_LITERAL { $$ = eval_literal($1, 0, 64); } | DT_CHAR_LITERAL { $$ = eval_char_literal($1); } | '(' integer_expr ')' { $$ = $2; } ; integer_expr: integer_trinary ; integer_trinary: integer_or | integer_or '?' integer_expr ':' integer_trinary { $$ = $1 ? $3 : $5; } ; integer_or: integer_and | integer_or DT_OR integer_and { $$ = $1 || $3; } ; integer_and: integer_bitor | integer_and DT_AND integer_bitor { $$ = $1 && $3; } ; integer_bitor: integer_bitxor | integer_bitor '|' integer_bitxor { $$ = $1 | $3; } ; integer_bitxor: integer_bitand | integer_bitxor '^' integer_bitand { $$ = $1 ^ $3; } ; integer_bitand: integer_eq | integer_bitand '&' integer_eq { $$ = $1 & $3; } ; integer_eq: integer_rela | integer_eq DT_EQ integer_rela { $$ = $1 == $3; } | integer_eq DT_NE integer_rela { $$ = $1 != $3; } ; integer_rela: integer_shift | integer_rela '<' integer_shift { $$ = $1 < $3; } | integer_rela '>' integer_shift { $$ = $1 > $3; } | integer_rela DT_LE integer_shift { $$ = $1 <= $3; } | integer_rela DT_GE integer_shift { $$ = $1 >= $3; } ; integer_shift: integer_shift DT_LSHIFT integer_add { $$ = $1 << $3; } | integer_shift DT_RSHIFT integer_add { $$ = $1 >> $3; } | integer_add ; integer_add: integer_add '+' integer_mul { $$ = $1 + $3; } | integer_add '-' integer_mul { $$ = $1 - $3; } | integer_mul ; integer_mul: integer_mul '*' integer_unary { $$ = $1 * $3; } | integer_mul '/' integer_unary { $$ = $1 / $3; } | integer_mul '%' integer_unary { $$ = $1 % $3; } | integer_unary ; integer_unary: integer_prim | '-' integer_unary { $$ = -$2; } | '~' integer_unary { $$ = ~$2; } | '!' integer_unary { $$ = !$2; } ; bytestring: /* empty */ { $$ = empty_data; } | bytestring DT_BYTE { $$ = data_append_byte($1, $2); } | bytestring DT_LABEL { $$ = data_add_marker($1, LABEL, $2); } ; subnodes: /* empty */ { $$ = NULL; } | subnode subnodes { $$ = chain_node($1, $2); } | subnode propdef { print_error("syntax error: properties must precede subnodes"); YYERROR; } ; subnode: DT_PROPNODENAME nodedef { $$ = name_node($2, $1); } | DT_DEL_NODE DT_PROPNODENAME ';' { $$ = name_node(build_node_delete(), $2); } | DT_LABEL subnode { add_label(&$2->labels, $1); $$ = $2; } ; %% void print_error(char const *fmt, ...) { va_list va; va_start(va, fmt); srcpos_verror(&yylloc, fmt, va); va_end(va); treesource_error = 1; } void yyerror(char const *s) { print_error("%s", s); } static unsigned long long eval_literal(const char *s, int base, int bits) { unsigned long long val; char *e; errno = 0; val = strtoull(s, &e, base); if (*e) { size_t uls = strspn(e, "UL"); if (e[uls]) print_error("bad characters in literal"); } if ((errno == ERANGE) || ((bits < 64) && (val >= (1ULL << bits)))) print_error("literal out of range"); else if (errno != 0) print_error("bad literal"); return val; } static unsigned char eval_char_literal(const char *s) { int i = 1; char c = s[0]; if (c == '\0') { print_error("empty character literal"); return 0; } /* * If the first character in the character literal is a \ then process * the remaining characters as an escape encoding. If the first * character is neither an escape or a terminator it should be the only * character in the literal and will be returned. */ if (c == '\\') c = get_escape_char(s, &i); if (s[i] != '\0') print_error("malformed character literal"); return c; } device-tree-compiler-1.4.0+dfsg.orig/fdtget.c0000664000000000000000000002135212261525673015723 0ustar /* * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. * * Portions from U-Boot cmd_fdt.c (C) Copyright 2007 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com * Based on code written by: * Pantelis Antoniou and * Matthew McClintock * * 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 #include #include #include #include #include #include #include "util.h" enum display_mode { MODE_SHOW_VALUE, /* show values for node properties */ MODE_LIST_PROPS, /* list the properties for a node */ MODE_LIST_SUBNODES, /* list the subnodes of a node */ }; /* Holds information which controls our output and options */ struct display_info { int type; /* data type (s/i/u/x or 0 for default) */ int size; /* data size (1/2/4) */ enum display_mode mode; /* display mode that we are using */ const char *default_val; /* default value if node/property not found */ }; static void report_error(const char *where, int err) { fprintf(stderr, "Error at '%s': %s\n", where, fdt_strerror(err)); } /** * Displays data of a given length according to selected options * * If a specific data type is provided in disp, then this is used. Otherwise * we try to guess the data type / size from the contents. * * @param disp Display information / options * @param data Data to display * @param len Maximum length of buffer * @return 0 if ok, -1 if data does not match format */ static int show_data(struct display_info *disp, const char *data, int len) { int i, size; const uint8_t *p = (const uint8_t *)data; const char *s; int value; int is_string; char fmt[3]; /* no data, don't print */ if (len == 0) return 0; is_string = (disp->type) == 's' || (!disp->type && util_is_printable_string(data, len)); if (is_string) { if (data[len - 1] != '\0') { fprintf(stderr, "Unterminated string\n"); return -1; } for (s = data; s - data < len; s += strlen(s) + 1) { if (s != data) printf(" "); printf("%s", (const char *)s); } return 0; } size = disp->size; if (size == -1) { size = (len % 4) == 0 ? 4 : 1; } else if (len % size) { fprintf(stderr, "Property length must be a multiple of " "selected data size\n"); return -1; } fmt[0] = '%'; fmt[1] = disp->type ? disp->type : 'd'; fmt[2] = '\0'; for (i = 0; i < len; i += size, p += size) { if (i) printf(" "); value = size == 4 ? fdt32_to_cpu(*(const uint32_t *)p) : size == 2 ? (*p << 8) | p[1] : *p; printf(fmt, value); } return 0; } /** * List all properties in a node, one per line. * * @param blob FDT blob * @param node Node to display * @return 0 if ok, or FDT_ERR... if not. */ static int list_properties(const void *blob, int node) { const struct fdt_property *data; const char *name; int prop; prop = fdt_first_property_offset(blob, node); do { /* Stop silently when there are no more properties */ if (prop < 0) return prop == -FDT_ERR_NOTFOUND ? 0 : prop; data = fdt_get_property_by_offset(blob, prop, NULL); name = fdt_string(blob, fdt32_to_cpu(data->nameoff)); if (name) puts(name); prop = fdt_next_property_offset(blob, prop); } while (1); } #define MAX_LEVEL 32 /* how deeply nested we will go */ /** * List all subnodes in a node, one per line * * @param blob FDT blob * @param node Node to display * @return 0 if ok, or FDT_ERR... if not. */ static int list_subnodes(const void *blob, int node) { int nextoffset; /* next node offset from libfdt */ uint32_t tag; /* current tag */ int level = 0; /* keep track of nesting level */ const char *pathp; int depth = 1; /* the assumed depth of this node */ while (level >= 0) { tag = fdt_next_tag(blob, node, &nextoffset); switch (tag) { case FDT_BEGIN_NODE: pathp = fdt_get_name(blob, node, NULL); if (level <= depth) { if (pathp == NULL) pathp = "/* NULL pointer error */"; if (*pathp == '\0') pathp = "/"; /* root is nameless */ if (level == 1) puts(pathp); } level++; if (level >= MAX_LEVEL) { printf("Nested too deep, aborting.\n"); return 1; } break; case FDT_END_NODE: level--; if (level == 0) level = -1; /* exit the loop */ break; case FDT_END: return 1; case FDT_PROP: break; default: if (level <= depth) printf("Unknown tag 0x%08X\n", tag); return 1; } node = nextoffset; } return 0; } /** * Show the data for a given node (and perhaps property) according to the * display option provided. * * @param blob FDT blob * @param disp Display information / options * @param node Node to display * @param property Name of property to display, or NULL if none * @return 0 if ok, -ve on error */ static int show_data_for_item(const void *blob, struct display_info *disp, int node, const char *property) { const void *value = NULL; int len, err = 0; switch (disp->mode) { case MODE_LIST_PROPS: err = list_properties(blob, node); break; case MODE_LIST_SUBNODES: err = list_subnodes(blob, node); break; default: assert(property); value = fdt_getprop(blob, node, property, &len); if (value) { if (show_data(disp, value, len)) err = -1; else printf("\n"); } else if (disp->default_val) { puts(disp->default_val); } else { report_error(property, len); err = -1; } break; } return err; } /** * Run the main fdtget operation, given a filename and valid arguments * * @param disp Display information / options * @param filename Filename of blob file * @param arg List of arguments to process * @param arg_count Number of arguments * @param return 0 if ok, -ve on error */ static int do_fdtget(struct display_info *disp, const char *filename, char **arg, int arg_count, int args_per_step) { char *blob; const char *prop; int i, node; blob = utilfdt_read(filename); if (!blob) return -1; for (i = 0; i + args_per_step <= arg_count; i += args_per_step) { node = fdt_path_offset(blob, arg[i]); if (node < 0) { if (disp->default_val) { puts(disp->default_val); continue; } else { report_error(arg[i], node); return -1; } } prop = args_per_step == 1 ? NULL : arg[i + 1]; if (show_data_for_item(blob, disp, node, prop)) return -1; } return 0; } /* Usage related data. */ static const char usage_synopsis[] = "read values from device tree\n" " fdtget
[ ]...\n" " fdtget -p
[ ]...\n" "\n" "Each value is printed on a new line.\n" USAGE_TYPE_MSG; static const char usage_short_opts[] = "t:pld:" USAGE_COMMON_SHORT_OPTS; static struct option const usage_long_opts[] = { {"type", a_argument, NULL, 't'}, {"properties", no_argument, NULL, 'p'}, {"list", no_argument, NULL, 'l'}, {"default", a_argument, NULL, 'd'}, USAGE_COMMON_LONG_OPTS, }; static const char * const usage_opts_help[] = { "Type of data", "List properties for each node", "List subnodes for each node", "Default value to display when the property is missing", USAGE_COMMON_OPTS_HELP }; int main(int argc, char *argv[]) { int opt; char *filename = NULL; struct display_info disp; int args_per_step = 2; /* set defaults */ memset(&disp, '\0', sizeof(disp)); disp.size = -1; disp.mode = MODE_SHOW_VALUE; while ((opt = util_getopt_long()) != EOF) { switch (opt) { case_USAGE_COMMON_FLAGS case 't': if (utilfdt_decode_type(optarg, &disp.type, &disp.size)) usage("invalid type string"); break; case 'p': disp.mode = MODE_LIST_PROPS; args_per_step = 1; break; case 'l': disp.mode = MODE_LIST_SUBNODES; args_per_step = 1; break; case 'd': disp.default_val = optarg; break; } } if (optind < argc) filename = argv[optind++]; if (!filename) usage("missing filename"); argv += optind; argc -= optind; /* Allow no arguments, and silently succeed */ if (!argc) return 0; /* Check for node, property arguments */ if (args_per_step == 2 && (argc % 2)) usage("must have an even number of arguments"); if (do_fdtget(&disp, filename, argv, argc, args_per_step)) return 1; return 0; } device-tree-compiler-1.4.0+dfsg.orig/util.h0000664000000000000000000001663612261525674015442 0ustar #ifndef _UTIL_H #define _UTIL_H #include #include /* * Copyright 2011 The Chromium Authors, All Rights Reserved. * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc. * * 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 */ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) static inline void __attribute__((noreturn)) die(const char *str, ...) { va_list ap; va_start(ap, str); fprintf(stderr, "FATAL ERROR: "); vfprintf(stderr, str, ap); exit(1); } static inline void *xmalloc(size_t len) { void *new = malloc(len); if (!new) die("malloc() failed\n"); return new; } static inline void *xrealloc(void *p, size_t len) { void *new = realloc(p, len); if (!new) die("realloc() failed (len=%d)\n", len); return new; } extern char *xstrdup(const char *s); extern char *join_path(const char *path, const char *name); /** * Check a property of a given length to see if it is all printable and * has a valid terminator. The property can contain either a single string, * or multiple strings each of non-zero length. * * @param data The string to check * @param len The string length including terminator * @return 1 if a valid printable string, 0 if not */ int util_is_printable_string(const void *data, int len); /* * Parse an escaped character starting at index i in string s. The resulting * character will be returned and the index i will be updated to point at the * character directly after the end of the encoding, this may be the '\0' * terminator of the string. */ char get_escape_char(const char *s, int *i); /** * Read a device tree file into a buffer. This will report any errors on * stderr. * * @param filename The filename to read, or - for stdin * @return Pointer to allocated buffer containing fdt, or NULL on error */ char *utilfdt_read(const char *filename); /** * Like utilfdt_read(), but also passes back the size of the file read. * * @param len If non-NULL, the amount of data we managed to read */ char *utilfdt_read_len(const char *filename, off_t *len); /** * Read a device tree file into a buffer. Does not report errors, but only * returns them. The value returned can be passed to strerror() to obtain * an error message for the user. * * @param filename The filename to read, or - for stdin * @param buffp Returns pointer to buffer containing fdt * @return 0 if ok, else an errno value representing the error */ int utilfdt_read_err(const char *filename, char **buffp); /** * Like utilfdt_read_err(), but also passes back the size of the file read. * * @param len If non-NULL, the amount of data we managed to read */ int utilfdt_read_err_len(const char *filename, char **buffp, off_t *len); /** * Write a device tree buffer to a file. This will report any errors on * stderr. * * @param filename The filename to write, or - for stdout * @param blob Poiner to buffer containing fdt * @return 0 if ok, -1 on error */ int utilfdt_write(const char *filename, const void *blob); /** * Write a device tree buffer to a file. Does not report errors, but only * returns them. The value returned can be passed to strerror() to obtain * an error message for the user. * * @param filename The filename to write, or - for stdout * @param blob Poiner to buffer containing fdt * @return 0 if ok, else an errno value representing the error */ int utilfdt_write_err(const char *filename, const void *blob); /** * Decode a data type string. The purpose of this string * * The string consists of an optional character followed by the type: * Modifier characters: * hh or b 1 byte * h 2 byte * l 4 byte, default * * Type character: * s string * i signed integer * u unsigned integer * x hex * * TODO: Implement ll modifier (8 bytes) * TODO: Implement o type (octal) * * @param fmt Format string to process * @param type Returns type found(s/d/u/x), or 0 if none * @param size Returns size found(1,2,4,8) or 4 if none * @return 0 if ok, -1 on error (no type given, or other invalid format) */ int utilfdt_decode_type(const char *fmt, int *type, int *size); /* * This is a usage message fragment for the -t option. It is the format * supported by utilfdt_decode_type. */ #define USAGE_TYPE_MSG \ "\ts=string, i=int, u=unsigned, x=hex\n" \ "\tOptional modifier prefix:\n" \ "\t\thh or b=byte, h=2 byte, l=4 byte (default)"; /** * Print property data in a readable format to stdout * * Properties that look like strings will be printed as strings. Otherwise * the data will be displayed either as cells (if len is a multiple of 4 * bytes) or bytes. * * If len is 0 then this function does nothing. * * @param data Pointers to property data * @param len Length of property data */ void utilfdt_print_data(const char *data, int len); /** * Show source version and exit */ void util_version(void) __attribute__((noreturn)); /** * Show usage and exit * * This helps standardize the output of various utils. You most likely want * to use the usage() helper below rather than call this. * * @param errmsg If non-NULL, an error message to display * @param synopsis The initial example usage text (and possible examples) * @param short_opts The string of short options * @param long_opts The structure of long options * @param opts_help An array of help strings (should align with long_opts) */ void util_usage(const char *errmsg, const char *synopsis, const char *short_opts, struct option const long_opts[], const char * const opts_help[]) __attribute__((noreturn)); /** * Show usage and exit * * If you name all your usage variables with usage_xxx, then you can call this * help macro rather than expanding all arguments yourself. * * @param errmsg If non-NULL, an error message to display */ #define usage(errmsg) \ util_usage(errmsg, usage_synopsis, usage_short_opts, \ usage_long_opts, usage_opts_help) /** * Call getopt_long() with standard options * * Since all util code runs getopt in the same way, provide a helper. */ #define util_getopt_long() getopt_long(argc, argv, usage_short_opts, \ usage_long_opts, NULL) /* Helper for aligning long_opts array */ #define a_argument required_argument /* Helper for usage_short_opts string constant */ #define USAGE_COMMON_SHORT_OPTS "hV" /* Helper for usage_long_opts option array */ #define USAGE_COMMON_LONG_OPTS \ {"help", no_argument, NULL, 'h'}, \ {"version", no_argument, NULL, 'V'}, \ {NULL, no_argument, NULL, 0x0} /* Helper for usage_opts_help array */ #define USAGE_COMMON_OPTS_HELP \ "Print this help and exit", \ "Print version and exit", \ NULL /* Helper for getopt case statements */ #define case_USAGE_COMMON_FLAGS \ case 'h': usage(NULL); \ case 'V': util_version(); \ case '?': usage("unknown option"); #endif /* _UTIL_H */ device-tree-compiler-1.4.0+dfsg.orig/TODO0000664000000000000000000000040412261525673014765 0ustar - Bugfixes: * Proper handling of boot cpu information - Generate mem reserve map * linux,reserve-map property * generating reserve entry for device tree itself * generating reserve entries from tce, rtas etc. properties - Expression support - Macro system device-tree-compiler-1.4.0+dfsg.orig/Makefile0000664000000000000000000001273312261525673015745 0ustar # # Device Tree Compiler # # # Version information will be constructed in this order: # EXTRAVERSION might be "-rc", for example. # LOCAL_VERSION is likely from command line. # CONFIG_LOCALVERSION from some future config system. # VERSION = 1 PATCHLEVEL = 4 SUBLEVEL = 0 EXTRAVERSION = LOCAL_VERSION = CONFIG_LOCALVERSION = CPPFLAGS = -I libfdt -I . WARNINGS = -Werror -Wall -Wpointer-arith -Wcast-qual -Wnested-externs \ -Wstrict-prototypes -Wmissing-prototypes -Wredundant-decls CFLAGS = -g -Os -fPIC -Werror $(WARNINGS) BISON = bison LEX = flex INSTALL = /usr/bin/install DESTDIR = PREFIX = $(HOME) BINDIR = $(PREFIX)/bin LIBDIR = $(PREFIX)/lib INCLUDEDIR = $(PREFIX)/include HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \ sed -e 's/\(cygwin\).*/cygwin/') ifeq ($(HOSTOS),darwin) SHAREDLIB_EXT=dylib SHAREDLIB_LINK_OPTIONS=-dynamiclib -Wl,-install_name -Wl, else SHAREDLIB_EXT=so SHAREDLIB_LINK_OPTIONS=-shared -Wl,--version-script=$(LIBFDT_version) -Wl,-soname, endif # # Overall rules # ifdef V VECHO = : else VECHO = echo " " ARFLAGS = rc .SILENT: endif NODEPTARGETS = clean ifeq ($(MAKECMDGOALS),) DEPTARGETS = all else DEPTARGETS = $(filter-out $(NODEPTARGETS),$(MAKECMDGOALS)) endif # # Rules for versioning # DTC_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) VERSION_FILE = version_gen.h CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ else if [ -x /bin/bash ]; then echo /bin/bash; \ else echo sh; fi ; fi) nullstring := space := $(nullstring) # end of line localver_config = $(subst $(space),, $(string) \ $(patsubst "%",%,$(CONFIG_LOCALVERSION))) localver_cmd = $(subst $(space),, $(string) \ $(patsubst "%",%,$(LOCALVERSION))) localver_scm = $(shell $(CONFIG_SHELL) ./scripts/setlocalversion) localver_full = $(localver_config)$(localver_cmd)$(localver_scm) dtc_version = $(DTC_VERSION)$(localver_full) # Contents of the generated version file. define filechk_version (echo "#define DTC_VERSION \"DTC $(dtc_version)\""; ) endef define filechk set -e; \ echo ' CHK $@'; \ mkdir -p $(dir $@); \ $(filechk_$(1)) < $< > $@.tmp; \ if [ -r $@ ] && cmp -s $@ $@.tmp; then \ rm -f $@.tmp; \ else \ echo ' UPD $@'; \ mv -f $@.tmp $@; \ fi; endef include Makefile.convert-dtsv0 include Makefile.dtc include Makefile.utils BIN += convert-dtsv0 BIN += dtc BIN += fdtdump BIN += fdtget BIN += fdtput SCRIPTS = dtdiff all: $(BIN) libfdt ifneq ($(DEPTARGETS),) -include $(DTC_OBJS:%.o=%.d) -include $(CONVERT_OBJS:%.o=%.d) -include $(FDTDUMP_OBJS:%.o=%.d) -include $(FDTGET_OBJS:%.o=%.d) -include $(FDTPUT_OBJS:%.o=%.d) endif # # Rules for libfdt # LIBFDT_objdir = libfdt LIBFDT_srcdir = libfdt LIBFDT_archive = $(LIBFDT_objdir)/libfdt.a LIBFDT_lib = $(LIBFDT_objdir)/libfdt-$(DTC_VERSION).$(SHAREDLIB_EXT) LIBFDT_include = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_INCLUDES)) LIBFDT_version = $(addprefix $(LIBFDT_srcdir)/,$(LIBFDT_VERSION)) include $(LIBFDT_srcdir)/Makefile.libfdt .PHONY: libfdt libfdt: $(LIBFDT_archive) $(LIBFDT_lib) $(LIBFDT_archive): $(addprefix $(LIBFDT_objdir)/,$(LIBFDT_OBJS)) $(LIBFDT_lib): $(addprefix $(LIBFDT_objdir)/,$(LIBFDT_OBJS)) libfdt_clean: @$(VECHO) CLEAN "(libfdt)" rm -f $(addprefix $(LIBFDT_objdir)/,$(STD_CLEANFILES)) rm -f $(LIBFDT_objdir)/*.so ifneq ($(DEPTARGETS),) -include $(LIBFDT_OBJS:%.o=$(LIBFDT_objdir)/%.d) endif # This stops make from generating the lex and bison output during # auto-dependency computation, but throwing them away as an # intermediate target and building them again "for real" .SECONDARY: $(DTC_GEN_SRCS) $(CONVERT_GEN_SRCS) install: all $(SCRIPTS) @$(VECHO) INSTALL $(INSTALL) -d $(DESTDIR)$(BINDIR) $(INSTALL) $(BIN) $(SCRIPTS) $(DESTDIR)$(BINDIR) $(INSTALL) -d $(DESTDIR)$(LIBDIR) $(INSTALL) $(LIBFDT_lib) $(DESTDIR)$(LIBDIR) ln -sf $(notdir $(LIBFDT_lib)) $(DESTDIR)$(LIBDIR)/$(LIBFDT_soname) ln -sf $(LIBFDT_soname) $(DESTDIR)$(LIBDIR)/libfdt.$(SHAREDLIB_EXT) $(INSTALL) -m 644 $(LIBFDT_archive) $(DESTDIR)$(LIBDIR) $(INSTALL) -d $(DESTDIR)$(INCLUDEDIR) $(INSTALL) -m 644 $(LIBFDT_include) $(DESTDIR)$(INCLUDEDIR) $(VERSION_FILE): Makefile FORCE $(call filechk,version) dtc: $(DTC_OBJS) convert-dtsv0: $(CONVERT_OBJS) @$(VECHO) LD $@ $(LINK.c) -o $@ $^ fdtdump: $(FDTDUMP_OBJS) fdtget: $(FDTGET_OBJS) $(LIBFDT_archive) fdtput: $(FDTPUT_OBJS) $(LIBFDT_archive) # # Testsuite rules # TESTS_PREFIX=tests/ TESTS_BIN += dtc TESTS_BIN += convert-dtsv0 TESTS_BIN += fdtput TESTS_BIN += fdtget include tests/Makefile.tests # # Clean rules # STD_CLEANFILES = *~ *.o *.$(SHAREDLIB_EXT) *.d *.a *.i *.s core a.out vgcore.* \ *.tab.[ch] *.lex.c *.output clean: libfdt_clean tests_clean @$(VECHO) CLEAN rm -f $(STD_CLEANFILES) rm -f $(VERSION_FILE) rm -f $(BIN) # # Generic compile rules # %: %.o @$(VECHO) LD $@ $(LINK.c) -o $@ $^ %.o: %.c @$(VECHO) CC $@ $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $< %.o: %.S @$(VECHO) AS $@ $(CC) $(CPPFLAGS) $(AFLAGS) -D__ASSEMBLY__ -o $@ -c $< %.d: %.c @$(VECHO) DEP $< $(CC) $(CPPFLAGS) -MM -MG -MT "$*.o $@" $< > $@ %.d: %.S @$(VECHO) DEP $< $(CC) $(CPPFLAGS) -MM -MG -MT "$*.o $@" $< > $@ %.i: %.c @$(VECHO) CPP $@ $(CC) $(CPPFLAGS) -E $< > $@ %.s: %.c @$(VECHO) CC -S $@ $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -S $< %.a: @$(VECHO) AR $@ $(AR) $(ARFLAGS) $@ $^ $(LIBFDT_lib): @$(VECHO) LD $@ $(CC) $(LDFLAGS) -fPIC $(SHAREDLIB_LINK_OPTIONS)$(LIBFDT_soname) -o $(LIBFDT_lib) $^ %.lex.c: %.l @$(VECHO) LEX $@ $(LEX) -o$@ $< %.tab.c %.tab.h %.output: %.y @$(VECHO) BISON $@ $(BISON) -d $< FORCE: device-tree-compiler-1.4.0+dfsg.orig/checks.c0000664000000000000000000005015012261525673015704 0ustar /* * (C) Copyright David Gibson , IBM Corporation. 2007. * * * 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 "dtc.h" #ifdef TRACE_CHECKS #define TRACE(c, ...) \ do { \ fprintf(stderr, "=== %s: ", (c)->name); \ fprintf(stderr, __VA_ARGS__); \ fprintf(stderr, "\n"); \ } while (0) #else #define TRACE(c, fmt, ...) do { } while (0) #endif enum checkstatus { UNCHECKED = 0, PREREQ, PASSED, FAILED, }; struct check; typedef void (*tree_check_fn)(struct check *c, struct node *dt); typedef void (*node_check_fn)(struct check *c, struct node *dt, struct node *node); typedef void (*prop_check_fn)(struct check *c, struct node *dt, struct node *node, struct property *prop); struct check { const char *name; tree_check_fn tree_fn; node_check_fn node_fn; prop_check_fn prop_fn; void *data; bool warn, error; enum checkstatus status; int inprogress; int num_prereqs; struct check **prereq; }; #define CHECK_ENTRY(nm, tfn, nfn, pfn, d, w, e, ...) \ static struct check *nm##_prereqs[] = { __VA_ARGS__ }; \ static struct check nm = { \ .name = #nm, \ .tree_fn = (tfn), \ .node_fn = (nfn), \ .prop_fn = (pfn), \ .data = (d), \ .warn = (w), \ .error = (e), \ .status = UNCHECKED, \ .num_prereqs = ARRAY_SIZE(nm##_prereqs), \ .prereq = nm##_prereqs, \ }; #define WARNING(nm, tfn, nfn, pfn, d, ...) \ CHECK_ENTRY(nm, tfn, nfn, pfn, d, true, false, __VA_ARGS__) #define ERROR(nm, tfn, nfn, pfn, d, ...) \ CHECK_ENTRY(nm, tfn, nfn, pfn, d, false, true, __VA_ARGS__) #define CHECK(nm, tfn, nfn, pfn, d, ...) \ CHECK_ENTRY(nm, tfn, nfn, pfn, d, false, false, __VA_ARGS__) #define TREE_WARNING(nm, d, ...) \ WARNING(nm, check_##nm, NULL, NULL, d, __VA_ARGS__) #define TREE_ERROR(nm, d, ...) \ ERROR(nm, check_##nm, NULL, NULL, d, __VA_ARGS__) #define TREE_CHECK(nm, d, ...) \ CHECK(nm, check_##nm, NULL, NULL, d, __VA_ARGS__) #define NODE_WARNING(nm, d, ...) \ WARNING(nm, NULL, check_##nm, NULL, d, __VA_ARGS__) #define NODE_ERROR(nm, d, ...) \ ERROR(nm, NULL, check_##nm, NULL, d, __VA_ARGS__) #define NODE_CHECK(nm, d, ...) \ CHECK(nm, NULL, check_##nm, NULL, d, __VA_ARGS__) #define PROP_WARNING(nm, d, ...) \ WARNING(nm, NULL, NULL, check_##nm, d, __VA_ARGS__) #define PROP_ERROR(nm, d, ...) \ ERROR(nm, NULL, NULL, check_##nm, d, __VA_ARGS__) #define PROP_CHECK(nm, d, ...) \ CHECK(nm, NULL, NULL, check_##nm, d, __VA_ARGS__) #ifdef __GNUC__ static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3))); #endif static inline void check_msg(struct check *c, const char *fmt, ...) { va_list ap; va_start(ap, fmt); if ((c->warn && (quiet < 1)) || (c->error && (quiet < 2))) { fprintf(stderr, "%s (%s): ", (c->error) ? "ERROR" : "Warning", c->name); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); } } #define FAIL(c, ...) \ do { \ TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ (c)->status = FAILED; \ check_msg((c), __VA_ARGS__); \ } while (0) static void check_nodes_props(struct check *c, struct node *dt, struct node *node) { struct node *child; struct property *prop; TRACE(c, "%s", node->fullpath); if (c->node_fn) c->node_fn(c, dt, node); if (c->prop_fn) for_each_property(node, prop) { TRACE(c, "%s\t'%s'", node->fullpath, prop->name); c->prop_fn(c, dt, node, prop); } for_each_child(node, child) check_nodes_props(c, dt, child); } static int run_check(struct check *c, struct node *dt) { int error = 0; int i; assert(!c->inprogress); if (c->status != UNCHECKED) goto out; c->inprogress = 1; for (i = 0; i < c->num_prereqs; i++) { struct check *prq = c->prereq[i]; error |= run_check(prq, dt); if (prq->status != PASSED) { c->status = PREREQ; check_msg(c, "Failed prerequisite '%s'", c->prereq[i]->name); } } if (c->status != UNCHECKED) goto out; if (c->node_fn || c->prop_fn) check_nodes_props(c, dt, dt); if (c->tree_fn) c->tree_fn(c, dt); if (c->status == UNCHECKED) c->status = PASSED; TRACE(c, "\tCompleted, status %d", c->status); out: c->inprogress = 0; if ((c->status != PASSED) && (c->error)) error = 1; return error; } /* * Utility check functions */ /* A check which always fails, for testing purposes only */ static inline void check_always_fail(struct check *c, struct node *dt) { FAIL(c, "always_fail check"); } TREE_CHECK(always_fail, NULL); static void check_is_string(struct check *c, struct node *root, struct node *node) { struct property *prop; char *propname = c->data; prop = get_property(node, propname); if (!prop) return; /* Not present, assumed ok */ if (!data_is_one_string(prop->val)) FAIL(c, "\"%s\" property in %s is not a string", propname, node->fullpath); } #define WARNING_IF_NOT_STRING(nm, propname) \ WARNING(nm, NULL, check_is_string, NULL, (propname)) #define ERROR_IF_NOT_STRING(nm, propname) \ ERROR(nm, NULL, check_is_string, NULL, (propname)) static void check_is_cell(struct check *c, struct node *root, struct node *node) { struct property *prop; char *propname = c->data; prop = get_property(node, propname); if (!prop) return; /* Not present, assumed ok */ if (prop->val.len != sizeof(cell_t)) FAIL(c, "\"%s\" property in %s is not a single cell", propname, node->fullpath); } #define WARNING_IF_NOT_CELL(nm, propname) \ WARNING(nm, NULL, check_is_cell, NULL, (propname)) #define ERROR_IF_NOT_CELL(nm, propname) \ ERROR(nm, NULL, check_is_cell, NULL, (propname)) /* * Structural check functions */ static void check_duplicate_node_names(struct check *c, struct node *dt, struct node *node) { struct node *child, *child2; for_each_child(node, child) for (child2 = child->next_sibling; child2; child2 = child2->next_sibling) if (streq(child->name, child2->name)) FAIL(c, "Duplicate node name %s", child->fullpath); } NODE_ERROR(duplicate_node_names, NULL); static void check_duplicate_property_names(struct check *c, struct node *dt, struct node *node) { struct property *prop, *prop2; for_each_property(node, prop) { for (prop2 = prop->next; prop2; prop2 = prop2->next) { if (prop2->deleted) continue; if (streq(prop->name, prop2->name)) FAIL(c, "Duplicate property name %s in %s", prop->name, node->fullpath); } } } NODE_ERROR(duplicate_property_names, NULL); #define LOWERCASE "abcdefghijklmnopqrstuvwxyz" #define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ" #define DIGITS "0123456789" #define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-" static void check_node_name_chars(struct check *c, struct node *dt, struct node *node) { int n = strspn(node->name, c->data); if (n < strlen(node->name)) FAIL(c, "Bad character '%c' in node %s", node->name[n], node->fullpath); } NODE_ERROR(node_name_chars, PROPNODECHARS "@"); static void check_node_name_format(struct check *c, struct node *dt, struct node *node) { if (strchr(get_unitname(node), '@')) FAIL(c, "Node %s has multiple '@' characters in name", node->fullpath); } NODE_ERROR(node_name_format, NULL, &node_name_chars); static void check_property_name_chars(struct check *c, struct node *dt, struct node *node, struct property *prop) { int n = strspn(prop->name, c->data); if (n < strlen(prop->name)) FAIL(c, "Bad character '%c' in property name \"%s\", node %s", prop->name[n], prop->name, node->fullpath); } PROP_ERROR(property_name_chars, PROPNODECHARS); #define DESCLABEL_FMT "%s%s%s%s%s" #define DESCLABEL_ARGS(node,prop,mark) \ ((mark) ? "value of " : ""), \ ((prop) ? "'" : ""), \ ((prop) ? (prop)->name : ""), \ ((prop) ? "' in " : ""), (node)->fullpath static void check_duplicate_label(struct check *c, struct node *dt, const char *label, struct node *node, struct property *prop, struct marker *mark) { struct node *othernode = NULL; struct property *otherprop = NULL; struct marker *othermark = NULL; othernode = get_node_by_label(dt, label); if (!othernode) otherprop = get_property_by_label(dt, label, &othernode); if (!othernode) othermark = get_marker_label(dt, label, &othernode, &otherprop); if (!othernode) return; if ((othernode != node) || (otherprop != prop) || (othermark != mark)) FAIL(c, "Duplicate label '%s' on " DESCLABEL_FMT " and " DESCLABEL_FMT, label, DESCLABEL_ARGS(node, prop, mark), DESCLABEL_ARGS(othernode, otherprop, othermark)); } static void check_duplicate_label_node(struct check *c, struct node *dt, struct node *node) { struct label *l; for_each_label(node->labels, l) check_duplicate_label(c, dt, l->label, node, NULL, NULL); } static void check_duplicate_label_prop(struct check *c, struct node *dt, struct node *node, struct property *prop) { struct marker *m = prop->val.markers; struct label *l; for_each_label(prop->labels, l) check_duplicate_label(c, dt, l->label, node, prop, NULL); for_each_marker_of_type(m, LABEL) check_duplicate_label(c, dt, m->ref, node, prop, m); } ERROR(duplicate_label, NULL, check_duplicate_label_node, check_duplicate_label_prop, NULL); static void check_explicit_phandles(struct check *c, struct node *root, struct node *node, struct property *prop) { struct marker *m; struct node *other; cell_t phandle; if (!streq(prop->name, "phandle") && !streq(prop->name, "linux,phandle")) return; if (prop->val.len != sizeof(cell_t)) { FAIL(c, "%s has bad length (%d) %s property", node->fullpath, prop->val.len, prop->name); return; } m = prop->val.markers; for_each_marker_of_type(m, REF_PHANDLE) { assert(m->offset == 0); if (node != get_node_by_ref(root, m->ref)) /* "Set this node's phandle equal to some * other node's phandle". That's nonsensical * by construction. */ { FAIL(c, "%s in %s is a reference to another node", prop->name, node->fullpath); return; } /* But setting this node's phandle equal to its own * phandle is allowed - that means allocate a unique * phandle for this node, even if it's not otherwise * referenced. The value will be filled in later, so * no further checking for now. */ return; } phandle = propval_cell(prop); if ((phandle == 0) || (phandle == -1)) { FAIL(c, "%s has bad value (0x%x) in %s property", node->fullpath, phandle, prop->name); return; } if (node->phandle && (node->phandle != phandle)) FAIL(c, "%s has %s property which replaces existing phandle information", node->fullpath, prop->name); other = get_node_by_phandle(root, phandle); if (other && (other != node)) { FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)", node->fullpath, phandle, other->fullpath); return; } node->phandle = phandle; } PROP_ERROR(explicit_phandles, NULL); static void check_name_properties(struct check *c, struct node *root, struct node *node) { struct property **pp, *prop = NULL; for (pp = &node->proplist; *pp; pp = &((*pp)->next)) if (streq((*pp)->name, "name")) { prop = *pp; break; } if (!prop) return; /* No name property, that's fine */ if ((prop->val.len != node->basenamelen+1) || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) { FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead" " of base node name)", node->fullpath, prop->val.val); } else { /* The name property is correct, and therefore redundant. * Delete it */ *pp = prop->next; free(prop->name); data_free(prop->val); free(prop); } } ERROR_IF_NOT_STRING(name_is_string, "name"); NODE_ERROR(name_properties, NULL, &name_is_string); /* * Reference fixup functions */ static void fixup_phandle_references(struct check *c, struct node *dt, struct node *node, struct property *prop) { struct marker *m = prop->val.markers; struct node *refnode; cell_t phandle; for_each_marker_of_type(m, REF_PHANDLE) { assert(m->offset + sizeof(cell_t) <= prop->val.len); refnode = get_node_by_ref(dt, m->ref); if (! refnode) { FAIL(c, "Reference to non-existent node or label \"%s\"\n", m->ref); continue; } phandle = get_node_phandle(dt, refnode); *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); } } ERROR(phandle_references, NULL, NULL, fixup_phandle_references, NULL, &duplicate_node_names, &explicit_phandles); static void fixup_path_references(struct check *c, struct node *dt, struct node *node, struct property *prop) { struct marker *m = prop->val.markers; struct node *refnode; char *path; for_each_marker_of_type(m, REF_PATH) { assert(m->offset <= prop->val.len); refnode = get_node_by_ref(dt, m->ref); if (!refnode) { FAIL(c, "Reference to non-existent node or label \"%s\"\n", m->ref); continue; } path = refnode->fullpath; prop->val = data_insert_at_marker(prop->val, m, path, strlen(path) + 1); } } ERROR(path_references, NULL, NULL, fixup_path_references, NULL, &duplicate_node_names); /* * Semantic checks */ WARNING_IF_NOT_CELL(address_cells_is_cell, "#address-cells"); WARNING_IF_NOT_CELL(size_cells_is_cell, "#size-cells"); WARNING_IF_NOT_CELL(interrupt_cells_is_cell, "#interrupt-cells"); WARNING_IF_NOT_STRING(device_type_is_string, "device_type"); WARNING_IF_NOT_STRING(model_is_string, "model"); WARNING_IF_NOT_STRING(status_is_string, "status"); static void fixup_addr_size_cells(struct check *c, struct node *dt, struct node *node) { struct property *prop; node->addr_cells = -1; node->size_cells = -1; prop = get_property(node, "#address-cells"); if (prop) node->addr_cells = propval_cell(prop); prop = get_property(node, "#size-cells"); if (prop) node->size_cells = propval_cell(prop); } WARNING(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL, &address_cells_is_cell, &size_cells_is_cell); #define node_addr_cells(n) \ (((n)->addr_cells == -1) ? 2 : (n)->addr_cells) #define node_size_cells(n) \ (((n)->size_cells == -1) ? 1 : (n)->size_cells) static void check_reg_format(struct check *c, struct node *dt, struct node *node) { struct property *prop; int addr_cells, size_cells, entrylen; prop = get_property(node, "reg"); if (!prop) return; /* No "reg", that's fine */ if (!node->parent) { FAIL(c, "Root node has a \"reg\" property"); return; } if (prop->val.len == 0) FAIL(c, "\"reg\" property in %s is empty", node->fullpath); addr_cells = node_addr_cells(node->parent); size_cells = node_size_cells(node->parent); entrylen = (addr_cells + size_cells) * sizeof(cell_t); if ((prop->val.len % entrylen) != 0) FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) " "(#address-cells == %d, #size-cells == %d)", node->fullpath, prop->val.len, addr_cells, size_cells); } NODE_WARNING(reg_format, NULL, &addr_size_cells); static void check_ranges_format(struct check *c, struct node *dt, struct node *node) { struct property *prop; int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen; prop = get_property(node, "ranges"); if (!prop) return; if (!node->parent) { FAIL(c, "Root node has a \"ranges\" property"); return; } p_addr_cells = node_addr_cells(node->parent); p_size_cells = node_size_cells(node->parent); c_addr_cells = node_addr_cells(node); c_size_cells = node_size_cells(node); entrylen = (p_addr_cells + c_addr_cells + c_size_cells) * sizeof(cell_t); if (prop->val.len == 0) { if (p_addr_cells != c_addr_cells) FAIL(c, "%s has empty \"ranges\" property but its " "#address-cells (%d) differs from %s (%d)", node->fullpath, c_addr_cells, node->parent->fullpath, p_addr_cells); if (p_size_cells != c_size_cells) FAIL(c, "%s has empty \"ranges\" property but its " "#size-cells (%d) differs from %s (%d)", node->fullpath, c_size_cells, node->parent->fullpath, p_size_cells); } else if ((prop->val.len % entrylen) != 0) { FAIL(c, "\"ranges\" property in %s has invalid length (%d bytes) " "(parent #address-cells == %d, child #address-cells == %d, " "#size-cells == %d)", node->fullpath, prop->val.len, p_addr_cells, c_addr_cells, c_size_cells); } } NODE_WARNING(ranges_format, NULL, &addr_size_cells); /* * Style checks */ static void check_avoid_default_addr_size(struct check *c, struct node *dt, struct node *node) { struct property *reg, *ranges; if (!node->parent) return; /* Ignore root node */ reg = get_property(node, "reg"); ranges = get_property(node, "ranges"); if (!reg && !ranges) return; if ((node->parent->addr_cells == -1)) FAIL(c, "Relying on default #address-cells value for %s", node->fullpath); if ((node->parent->size_cells == -1)) FAIL(c, "Relying on default #size-cells value for %s", node->fullpath); } NODE_WARNING(avoid_default_addr_size, NULL, &addr_size_cells); static void check_obsolete_chosen_interrupt_controller(struct check *c, struct node *dt) { struct node *chosen; struct property *prop; chosen = get_node_by_path(dt, "/chosen"); if (!chosen) return; prop = get_property(chosen, "interrupt-controller"); if (prop) FAIL(c, "/chosen has obsolete \"interrupt-controller\" " "property"); } TREE_WARNING(obsolete_chosen_interrupt_controller, NULL); static struct check *check_table[] = { &duplicate_node_names, &duplicate_property_names, &node_name_chars, &node_name_format, &property_name_chars, &name_is_string, &name_properties, &duplicate_label, &explicit_phandles, &phandle_references, &path_references, &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell, &device_type_is_string, &model_is_string, &status_is_string, &addr_size_cells, ®_format, &ranges_format, &avoid_default_addr_size, &obsolete_chosen_interrupt_controller, &always_fail, }; static void enable_warning_error(struct check *c, bool warn, bool error) { int i; /* Raising level, also raise it for prereqs */ if ((warn && !c->warn) || (error && !c->error)) for (i = 0; i < c->num_prereqs; i++) enable_warning_error(c->prereq[i], warn, error); c->warn = c->warn || warn; c->error = c->error || error; } static void disable_warning_error(struct check *c, bool warn, bool error) { int i; /* Lowering level, also lower it for things this is the prereq * for */ if ((warn && c->warn) || (error && c->error)) { for (i = 0; i < ARRAY_SIZE(check_table); i++) { struct check *cc = check_table[i]; int j; for (j = 0; j < cc->num_prereqs; j++) if (cc->prereq[j] == c) disable_warning_error(cc, warn, error); } } c->warn = c->warn && !warn; c->error = c->error && !error; } void parse_checks_option(bool warn, bool error, const char *optarg) { int i; const char *name = optarg; bool enable = true; if ((strncmp(optarg, "no-", 3) == 0) || (strncmp(optarg, "no_", 3) == 0)) { name = optarg + 3; enable = false; } for (i = 0; i < ARRAY_SIZE(check_table); i++) { struct check *c = check_table[i]; if (streq(c->name, name)) { if (enable) enable_warning_error(c, warn, error); else disable_warning_error(c, warn, error); return; } } die("Unrecognized check name \"%s\"\n", name); } void process_checks(int force, struct boot_info *bi) { struct node *dt = bi->dt; int i; int error = 0; for (i = 0; i < ARRAY_SIZE(check_table); i++) { struct check *c = check_table[i]; if (c->warn || c->error) error = error || run_check(c, dt); } if (error) { if (!force) { fprintf(stderr, "ERROR: Input tree has errors, aborting " "(use -f to force output)\n"); exit(2); } else if (quiet < 3) { fprintf(stderr, "Warning: Input tree has errors, " "output forced\n"); } } } device-tree-compiler-1.4.0+dfsg.orig/Makefile.convert-dtsv00000664000000000000000000000043612261525673020457 0ustar # # This is not a complete Makefile of itself. # Instead, it is designed to be easily embeddable # into other systems of Makefiles. # CONVERT_SRCS = \ srcpos.c \ util.c CONVERT_GEN_SRCS = convert-dtsv0-lexer.lex.c CONVERT_OBJS = $(CONVERT_SRCS:%.c=%.o) $(CONVERT_GEN_SRCS:%.c=%.o) device-tree-compiler-1.4.0+dfsg.orig/README.license0000664000000000000000000000555212261525673016607 0ustar Licensing and contribution policy of dtc and libfdt =================================================== This dtc package contains two pieces of software: dtc itself, and libfdt which comprises the files in the libfdt/ subdirectory. These two pieces of software, although closely related, are quite distinct. dtc does not incoporate or rely on libfdt for its operation, nor vice versa. It is important that these two pieces of software have different license conditions. As the copyright banners in each source file attest, dtc is licensed under the GNU GPL. The full text of the GPL can be found in the file entitled 'GPL' which should be included in this package. dtc code, therefore, may not be incorporated into works which do not have a GPL compatible license. libfdt, however, is GPL/BSD dual-licensed. That is, it may be used either under the terms of the GPL, or under the terms of the 2-clause BSD license (aka the ISC license). The full terms of that license are given in the copyright banners of each of the libfdt source files. This is, in practice, equivalent to being BSD licensed, since the terms of the BSD license are strictly more permissive than the GPL. I made the decision to license libfdt in this way because I want to encourage widespread and correct usage of flattened device trees, including by proprietary or otherwise GPL-incompatible firmware or tools. Allowing libfdt to be used under the terms of the BSD license makes that it easier for vendors or authors of such software to do so. This does mean that libfdt code could be "stolen" - say, included in a proprietary fimware and extended without contributing those extensions back to the libfdt mainline. While I hope that doesn't happen, I believe the goal of allowing libfdt to be widely used is more important than avoiding that. libfdt is quite small, and hardly rocket science; so the incentive for such impolite behaviour is small, and the inconvenience caused therby is not dire. Licenses such as the LGPL which would allow code to be used in non-GPL software, but also require contributions to be returned were considered. However, libfdt is designed to be used in firmwares and other environments with unusual technical constraints. It's difficult to anticipate all possible changes which might be needed to meld libfdt into such environments and so difficult to suitably word a license that puts the boundary between what is and isn't permitted in the intended place. Again, I judged encouraging widespread use of libfdt by keeping the license terms simple and familiar to be the more important goal. **IMPORTANT** It's intended that all of libfdt as released remain permissively licensed this way. Therefore only contributions which are released under these terms can be merged into the libfdt mainline. David Gibson (principal original author of dtc and libfdt) 2 November 2007 device-tree-compiler-1.4.0+dfsg.orig/livetree.c0000664000000000000000000003313012261525673016262 0ustar /* * (C) Copyright David Gibson , IBM Corporation. 2005. * * * 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 "dtc.h" /* * Tree building functions */ void add_label(struct label **labels, char *label) { struct label *new; /* Make sure the label isn't already there */ for_each_label_withdel(*labels, new) if (streq(new->label, label)) { new->deleted = 0; return; } new = xmalloc(sizeof(*new)); memset(new, 0, sizeof(*new)); new->label = label; new->next = *labels; *labels = new; } void delete_labels(struct label **labels) { struct label *label; for_each_label(*labels, label) label->deleted = 1; } struct property *build_property(char *name, struct data val) { struct property *new = xmalloc(sizeof(*new)); memset(new, 0, sizeof(*new)); new->name = name; new->val = val; return new; } struct property *build_property_delete(char *name) { struct property *new = xmalloc(sizeof(*new)); memset(new, 0, sizeof(*new)); new->name = name; new->deleted = 1; return new; } struct property *chain_property(struct property *first, struct property *list) { assert(first->next == NULL); first->next = list; return first; } struct property *reverse_properties(struct property *first) { struct property *p = first; struct property *head = NULL; struct property *next; while (p) { next = p->next; p->next = head; head = p; p = next; } return head; } struct node *build_node(struct property *proplist, struct node *children) { struct node *new = xmalloc(sizeof(*new)); struct node *child; memset(new, 0, sizeof(*new)); new->proplist = reverse_properties(proplist); new->children = children; for_each_child(new, child) { child->parent = new; } return new; } struct node *build_node_delete(void) { struct node *new = xmalloc(sizeof(*new)); memset(new, 0, sizeof(*new)); new->deleted = 1; return new; } struct node *name_node(struct node *node, char *name) { assert(node->name == NULL); node->name = name; return node; } struct node *merge_nodes(struct node *old_node, struct node *new_node) { struct property *new_prop, *old_prop; struct node *new_child, *old_child; struct label *l; old_node->deleted = 0; /* Add new node labels to old node */ for_each_label_withdel(new_node->labels, l) add_label(&old_node->labels, l->label); /* Move properties from the new node to the old node. If there * is a collision, replace the old value with the new */ while (new_node->proplist) { /* Pop the property off the list */ new_prop = new_node->proplist; new_node->proplist = new_prop->next; new_prop->next = NULL; if (new_prop->deleted) { delete_property_by_name(old_node, new_prop->name); free(new_prop); continue; } /* Look for a collision, set new value if there is */ for_each_property_withdel(old_node, old_prop) { if (streq(old_prop->name, new_prop->name)) { /* Add new labels to old property */ for_each_label_withdel(new_prop->labels, l) add_label(&old_prop->labels, l->label); old_prop->val = new_prop->val; old_prop->deleted = 0; free(new_prop); new_prop = NULL; break; } } /* if no collision occurred, add property to the old node. */ if (new_prop) add_property(old_node, new_prop); } /* Move the override child nodes into the primary node. If * there is a collision, then merge the nodes. */ while (new_node->children) { /* Pop the child node off the list */ new_child = new_node->children; new_node->children = new_child->next_sibling; new_child->parent = NULL; new_child->next_sibling = NULL; if (new_child->deleted) { delete_node_by_name(old_node, new_child->name); free(new_child); continue; } /* Search for a collision. Merge if there is */ for_each_child_withdel(old_node, old_child) { if (streq(old_child->name, new_child->name)) { merge_nodes(old_child, new_child); new_child = NULL; break; } } /* if no collision occured, add child to the old node. */ if (new_child) add_child(old_node, new_child); } /* The new node contents are now merged into the old node. Free * the new node. */ free(new_node); return old_node; } struct node *chain_node(struct node *first, struct node *list) { assert(first->next_sibling == NULL); first->next_sibling = list; return first; } void add_property(struct node *node, struct property *prop) { struct property **p; prop->next = NULL; p = &node->proplist; while (*p) p = &((*p)->next); *p = prop; } void delete_property_by_name(struct node *node, char *name) { struct property *prop = node->proplist; while (prop) { if (!strcmp(prop->name, name)) { delete_property(prop); return; } prop = prop->next; } } void delete_property(struct property *prop) { prop->deleted = 1; delete_labels(&prop->labels); } void add_child(struct node *parent, struct node *child) { struct node **p; child->next_sibling = NULL; child->parent = parent; p = &parent->children; while (*p) p = &((*p)->next_sibling); *p = child; } void delete_node_by_name(struct node *parent, char *name) { struct node *node = parent->children; while (node) { if (!strcmp(node->name, name)) { delete_node(node); return; } node = node->next_sibling; } } void delete_node(struct node *node) { struct property *prop; struct node *child; node->deleted = 1; for_each_child(node, child) delete_node(child); for_each_property(node, prop) delete_property(prop); delete_labels(&node->labels); } struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size) { struct reserve_info *new = xmalloc(sizeof(*new)); memset(new, 0, sizeof(*new)); new->re.address = address; new->re.size = size; return new; } struct reserve_info *chain_reserve_entry(struct reserve_info *first, struct reserve_info *list) { assert(first->next == NULL); first->next = list; return first; } struct reserve_info *add_reserve_entry(struct reserve_info *list, struct reserve_info *new) { struct reserve_info *last; new->next = NULL; if (! list) return new; for (last = list; last->next; last = last->next) ; last->next = new; return list; } struct boot_info *build_boot_info(struct reserve_info *reservelist, struct node *tree, uint32_t boot_cpuid_phys) { struct boot_info *bi; bi = xmalloc(sizeof(*bi)); bi->reservelist = reservelist; bi->dt = tree; bi->boot_cpuid_phys = boot_cpuid_phys; return bi; } /* * Tree accessor functions */ const char *get_unitname(struct node *node) { if (node->name[node->basenamelen] == '\0') return ""; else return node->name + node->basenamelen + 1; } struct property *get_property(struct node *node, const char *propname) { struct property *prop; for_each_property(node, prop) if (streq(prop->name, propname)) return prop; return NULL; } cell_t propval_cell(struct property *prop) { assert(prop->val.len == sizeof(cell_t)); return fdt32_to_cpu(*((cell_t *)prop->val.val)); } struct property *get_property_by_label(struct node *tree, const char *label, struct node **node) { struct property *prop; struct node *c; *node = tree; for_each_property(tree, prop) { struct label *l; for_each_label(prop->labels, l) if (streq(l->label, label)) return prop; } for_each_child(tree, c) { prop = get_property_by_label(c, label, node); if (prop) return prop; } *node = NULL; return NULL; } struct marker *get_marker_label(struct node *tree, const char *label, struct node **node, struct property **prop) { struct marker *m; struct property *p; struct node *c; *node = tree; for_each_property(tree, p) { *prop = p; m = p->val.markers; for_each_marker_of_type(m, LABEL) if (streq(m->ref, label)) return m; } for_each_child(tree, c) { m = get_marker_label(c, label, node, prop); if (m) return m; } *prop = NULL; *node = NULL; return NULL; } struct node *get_subnode(struct node *node, const char *nodename) { struct node *child; for_each_child(node, child) if (streq(child->name, nodename)) return child; return NULL; } struct node *get_node_by_path(struct node *tree, const char *path) { const char *p; struct node *child; if (!path || ! (*path)) { if (tree->deleted) return NULL; return tree; } while (path[0] == '/') path++; p = strchr(path, '/'); for_each_child(tree, child) { if (p && strneq(path, child->name, p-path)) return get_node_by_path(child, p+1); else if (!p && streq(path, child->name)) return child; } return NULL; } struct node *get_node_by_label(struct node *tree, const char *label) { struct node *child, *node; struct label *l; assert(label && (strlen(label) > 0)); for_each_label(tree->labels, l) if (streq(l->label, label)) return tree; for_each_child(tree, child) { node = get_node_by_label(child, label); if (node) return node; } return NULL; } struct node *get_node_by_phandle(struct node *tree, cell_t phandle) { struct node *child, *node; assert((phandle != 0) && (phandle != -1)); if (tree->phandle == phandle) { if (tree->deleted) return NULL; return tree; } for_each_child(tree, child) { node = get_node_by_phandle(child, phandle); if (node) return node; } return NULL; } struct node *get_node_by_ref(struct node *tree, const char *ref) { if (ref[0] == '/') return get_node_by_path(tree, ref); else return get_node_by_label(tree, ref); } cell_t get_node_phandle(struct node *root, struct node *node) { static cell_t phandle = 1; /* FIXME: ick, static local */ if ((node->phandle != 0) && (node->phandle != -1)) return node->phandle; while (get_node_by_phandle(root, phandle)) phandle++; node->phandle = phandle; if (!get_property(node, "linux,phandle") && (phandle_format & PHANDLE_LEGACY)) add_property(node, build_property("linux,phandle", data_append_cell(empty_data, phandle))); if (!get_property(node, "phandle") && (phandle_format & PHANDLE_EPAPR)) add_property(node, build_property("phandle", data_append_cell(empty_data, phandle))); /* If the node *does* have a phandle property, we must * be dealing with a self-referencing phandle, which will be * fixed up momentarily in the caller */ return node->phandle; } uint32_t guess_boot_cpuid(struct node *tree) { struct node *cpus, *bootcpu; struct property *reg; cpus = get_node_by_path(tree, "/cpus"); if (!cpus) return 0; bootcpu = cpus->children; if (!bootcpu) return 0; reg = get_property(bootcpu, "reg"); if (!reg || (reg->val.len != sizeof(uint32_t))) return 0; /* FIXME: Sanity check node? */ return propval_cell(reg); } static int cmp_reserve_info(const void *ax, const void *bx) { const struct reserve_info *a, *b; a = *((const struct reserve_info * const *)ax); b = *((const struct reserve_info * const *)bx); if (a->re.address < b->re.address) return -1; else if (a->re.address > b->re.address) return 1; else if (a->re.size < b->re.size) return -1; else if (a->re.size > b->re.size) return 1; else return 0; } static void sort_reserve_entries(struct boot_info *bi) { struct reserve_info *ri, **tbl; int n = 0, i = 0; for (ri = bi->reservelist; ri; ri = ri->next) n++; if (n == 0) return; tbl = xmalloc(n * sizeof(*tbl)); for (ri = bi->reservelist; ri; ri = ri->next) tbl[i++] = ri; qsort(tbl, n, sizeof(*tbl), cmp_reserve_info); bi->reservelist = tbl[0]; for (i = 0; i < (n-1); i++) tbl[i]->next = tbl[i+1]; tbl[n-1]->next = NULL; free(tbl); } static int cmp_prop(const void *ax, const void *bx) { const struct property *a, *b; a = *((const struct property * const *)ax); b = *((const struct property * const *)bx); return strcmp(a->name, b->name); } static void sort_properties(struct node *node) { int n = 0, i = 0; struct property *prop, **tbl; for_each_property_withdel(node, prop) n++; if (n == 0) return; tbl = xmalloc(n * sizeof(*tbl)); for_each_property_withdel(node, prop) tbl[i++] = prop; qsort(tbl, n, sizeof(*tbl), cmp_prop); node->proplist = tbl[0]; for (i = 0; i < (n-1); i++) tbl[i]->next = tbl[i+1]; tbl[n-1]->next = NULL; free(tbl); } static int cmp_subnode(const void *ax, const void *bx) { const struct node *a, *b; a = *((const struct node * const *)ax); b = *((const struct node * const *)bx); return strcmp(a->name, b->name); } static void sort_subnodes(struct node *node) { int n = 0, i = 0; struct node *subnode, **tbl; for_each_child_withdel(node, subnode) n++; if (n == 0) return; tbl = xmalloc(n * sizeof(*tbl)); for_each_child_withdel(node, subnode) tbl[i++] = subnode; qsort(tbl, n, sizeof(*tbl), cmp_subnode); node->children = tbl[0]; for (i = 0; i < (n-1); i++) tbl[i]->next_sibling = tbl[i+1]; tbl[n-1]->next_sibling = NULL; free(tbl); } static void sort_node(struct node *node) { struct node *c; sort_properties(node); sort_subnodes(node); for_each_child_withdel(node, c) sort_node(c); } void sort_tree(struct boot_info *bi) { sort_reserve_entries(bi); sort_node(bi->dt); } device-tree-compiler-1.4.0+dfsg.orig/srcpos.c0000664000000000000000000001673212261525673015765 0ustar /* * Copyright 2007 Jon Loeliger, Freescale Semiconductor, Inc. * * 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 */ #define _GNU_SOURCE #include #include "dtc.h" #include "srcpos.h" /* A node in our list of directories to search for source/include files */ struct search_path { struct search_path *next; /* next node in list, NULL for end */ const char *dirname; /* name of directory to search */ }; /* This is the list of directories that we search for source files */ static struct search_path *search_path_head, **search_path_tail; static char *dirname(const char *path) { const char *slash = strrchr(path, '/'); if (slash) { int len = slash - path; char *dir = xmalloc(len + 1); memcpy(dir, path, len); dir[len] = '\0'; return dir; } return NULL; } FILE *depfile; /* = NULL */ struct srcfile_state *current_srcfile; /* = NULL */ /* Detect infinite include recursion. */ #define MAX_SRCFILE_DEPTH (100) static int srcfile_depth; /* = 0 */ /** * Try to open a file in a given directory. * * If the filename is an absolute path, then dirname is ignored. If it is a * relative path, then we look in that directory for the file. * * @param dirname Directory to look in, or NULL for none * @param fname Filename to look for * @param fp Set to NULL if file did not open * @return allocated filename on success (caller must free), NULL on failure */ static char *try_open(const char *dirname, const char *fname, FILE **fp) { char *fullname; if (!dirname || fname[0] == '/') fullname = xstrdup(fname); else fullname = join_path(dirname, fname); *fp = fopen(fullname, "r"); if (!*fp) { free(fullname); fullname = NULL; } return fullname; } /** * Open a file for read access * * If it is a relative filename, we search the full search path for it. * * @param fname Filename to open * @param fp Returns pointer to opened FILE, or NULL on failure * @return pointer to allocated filename, which caller must free */ static char *fopen_any_on_path(const char *fname, FILE **fp) { const char *cur_dir = NULL; struct search_path *node; char *fullname; /* Try current directory first */ assert(fp); if (current_srcfile) cur_dir = current_srcfile->dir; fullname = try_open(cur_dir, fname, fp); /* Failing that, try each search path in turn */ for (node = search_path_head; !*fp && node; node = node->next) fullname = try_open(node->dirname, fname, fp); return fullname; } FILE *srcfile_relative_open(const char *fname, char **fullnamep) { FILE *f; char *fullname; if (streq(fname, "-")) { f = stdin; fullname = xstrdup(""); } else { fullname = fopen_any_on_path(fname, &f); if (!f) die("Couldn't open \"%s\": %s\n", fname, strerror(errno)); } if (depfile) fprintf(depfile, " %s", fullname); if (fullnamep) *fullnamep = fullname; else free(fullname); return f; } void srcfile_push(const char *fname) { struct srcfile_state *srcfile; if (srcfile_depth++ >= MAX_SRCFILE_DEPTH) die("Includes nested too deeply"); srcfile = xmalloc(sizeof(*srcfile)); srcfile->f = srcfile_relative_open(fname, &srcfile->name); srcfile->dir = dirname(srcfile->name); srcfile->prev = current_srcfile; srcfile->lineno = 1; srcfile->colno = 1; current_srcfile = srcfile; } int srcfile_pop(void) { struct srcfile_state *srcfile = current_srcfile; assert(srcfile); current_srcfile = srcfile->prev; if (fclose(srcfile->f)) die("Error closing \"%s\": %s\n", srcfile->name, strerror(errno)); /* FIXME: We allow the srcfile_state structure to leak, * because it could still be referenced from a location * variable being carried through the parser somewhere. To * fix this we could either allocate all the files from a * table, or use a pool allocator. */ return current_srcfile ? 1 : 0; } void srcfile_add_search_path(const char *dirname) { struct search_path *node; /* Create the node */ node = xmalloc(sizeof(*node)); node->next = NULL; node->dirname = xstrdup(dirname); /* Add to the end of our list */ if (search_path_tail) *search_path_tail = node; else search_path_head = node; search_path_tail = &node->next; } /* * The empty source position. */ struct srcpos srcpos_empty = { .first_line = 0, .first_column = 0, .last_line = 0, .last_column = 0, .file = NULL, }; #define TAB_SIZE 8 void srcpos_update(struct srcpos *pos, const char *text, int len) { int i; pos->file = current_srcfile; pos->first_line = current_srcfile->lineno; pos->first_column = current_srcfile->colno; for (i = 0; i < len; i++) if (text[i] == '\n') { current_srcfile->lineno++; current_srcfile->colno = 1; } else if (text[i] == '\t') { current_srcfile->colno = ALIGN(current_srcfile->colno, TAB_SIZE); } else { current_srcfile->colno++; } pos->last_line = current_srcfile->lineno; pos->last_column = current_srcfile->colno; } struct srcpos * srcpos_copy(struct srcpos *pos) { struct srcpos *pos_new; pos_new = xmalloc(sizeof(struct srcpos)); memcpy(pos_new, pos, sizeof(struct srcpos)); return pos_new; } void srcpos_dump(struct srcpos *pos) { printf("file : \"%s\"\n", pos->file ? (char *) pos->file : ""); printf("first_line : %d\n", pos->first_line); printf("first_column: %d\n", pos->first_column); printf("last_line : %d\n", pos->last_line); printf("last_column : %d\n", pos->last_column); printf("file : %s\n", pos->file->name); } char * srcpos_string(struct srcpos *pos) { const char *fname = ""; char *pos_str; int rc; if (pos) fname = pos->file->name; if (pos->first_line != pos->last_line) rc = asprintf(&pos_str, "%s:%d.%d-%d.%d", fname, pos->first_line, pos->first_column, pos->last_line, pos->last_column); else if (pos->first_column != pos->last_column) rc = asprintf(&pos_str, "%s:%d.%d-%d", fname, pos->first_line, pos->first_column, pos->last_column); else rc = asprintf(&pos_str, "%s:%d.%d", fname, pos->first_line, pos->first_column); if (rc == -1) die("Couldn't allocate in srcpos string"); return pos_str; } void srcpos_verror(struct srcpos *pos, char const *fmt, va_list va) { const char *srcstr; srcstr = srcpos_string(pos); fprintf(stderr, "Error: %s ", srcstr); vfprintf(stderr, fmt, va); fprintf(stderr, "\n"); } void srcpos_error(struct srcpos *pos, char const *fmt, ...) { va_list va; va_start(va, fmt); srcpos_verror(pos, fmt, va); va_end(va); } void srcpos_warn(struct srcpos *pos, char const *fmt, ...) { const char *srcstr; va_list va; va_start(va, fmt); srcstr = srcpos_string(pos); fprintf(stderr, "Warning: %s ", srcstr); vfprintf(stderr, fmt, va); fprintf(stderr, "\n"); va_end(va); } void srcpos_set_line(char *f, int l) { current_srcfile->name = f; current_srcfile->lineno = l; } device-tree-compiler-1.4.0+dfsg.orig/Documentation/0000775000000000000000000000000012261525673017110 5ustar device-tree-compiler-1.4.0+dfsg.orig/Documentation/dts-format.txt0000664000000000000000000001025012261525673021727 0ustar Device Tree Source Format (version 1) ===================================== The Device Tree Source (DTS) format is a textual representation of a device tree in a form that can be processed by dtc into a binary device tree in the form expected by the kernel. The description below is not a formal syntax definition of DTS, but describes the basic constructs used to represent device trees. Node and property definitions ----------------------------- Device tree nodes are defined with a node name and unit address with braces marking the start and end of the node definition. They may be preceded by a label. [label:] node-name[@unit-address] { [properties definitions] [child nodes] } Nodes may contain property definitions and/or child node definitions. If both are present, properties must come before child nodes. Property definitions are name value pairs in the form: [label:] property-name = value; except for properties with empty (zero length) value which have the form: [label:] property-name; Property values may be defined as an array of 8, 16, 32, or 64-bit integer elements, as NUL-terminated strings, as bytestrings or a combination of these. * Arrays are represented by angle brackets surrounding a space separated list of C-style integers or character literals. Array elements default to 32-bits in size. An array of 32-bit elements is also known as a cell list or a list of cells. A cell being an unsigned 32-bit integer. e.g. interrupts = <17 0xc>; * A 64-bit value can be represented with two 32-bit elements. e.g. clock-frequency = <0x00000001 0x00000000>; * The storage size of an element can be changed using the /bits/ prefix. The /bits/ prefix allows for the creation of 8, 16, 32, and 64-bit elements. The resulting array will not be padded to a multiple of the default 32-bit element size. e.g. interrupts = /bits/ 8 <17 0xc>; e.g. clock-frequency = /bits/ 64 <0x0000000100000000>; * A NUL-terminated string value is represented using double quotes (the property value is considered to include the terminating NUL character). e.g. compatible = "simple-bus"; * A bytestring is enclosed in square brackets [] with each byte represented by two hexadecimal digits. Spaces between each byte are optional. e.g. local-mac-address = [00 00 12 34 56 78]; or equivalently local-mac-address = [000012345678]; * Values may have several comma-separated components, which are concatenated together. e.g. compatible = "ns16550", "ns8250"; example = <0xf00f0000 19>, "a strange property format"; * In an array a reference to another node will be expanded to that node's phandle. References may by '&' followed by a node's label: e.g. interrupt-parent = < &mpic >; or they may be '&' followed by a node's full path in braces: e.g. interrupt-parent = < &{/soc/interrupt-controller@40000} >; References are only permitted in arrays that have an element size of 32-bits. * Outside an array, a reference to another node will be expanded to that node's full path. e.g. ethernet0 = &EMAC0; * Labels may also appear before or after any component of a property value, or between elements of an array, or between bytes of a bytestring. e.g. reg = reglabel: <0 sizelabel: 0x1000000>; e.g. prop = [ab cd ef byte4: 00 ff fe]; e.g. str = start: "string value" end: ; File layout ----------- Version 1 DTS files have the overall layout: /dts-v1/; [memory reservations] / { [property definitions] [child nodes] }; * The "/dts-v1/;" must be present to identify the file as a version 1 DTS (dts files without this tag will be treated by dtc as being in the obsolete "version 0", which uses a different format for integers amongst other small but incompatible changes). * Memory reservations define an entry for the device tree blob's memory reservation table. They have the form: e.g. /memreserve/
; Where
and are 64-bit C-style integers. * The / { ... }; section defines the root node of the device tree. * C style (/* ... */) and C++ style (// ...) comments are supported. -- David Gibson -- Yoder Stuart -- Anton Staaf device-tree-compiler-1.4.0+dfsg.orig/Documentation/dtc-paper.tex0000664000000000000000000006576212261525673021531 0ustar \documentclass[a4paper,twocolumn]{article} \usepackage{abstract} \usepackage{xspace} \usepackage{amssymb} \usepackage{latexsym} \usepackage{tabularx} \usepackage[T1]{fontenc} \usepackage{calc} \usepackage{listings} \usepackage{color} \usepackage{url} \title{Device trees everywhere} \author{David Gibson \texttt{<{dwg}{@}{au1.ibm.com}>}\\ Benjamin Herrenschmidt \texttt{<{benh}{@}{kernel.crashing.org}>}\\ \emph{OzLabs, IBM Linux Technology Center}} \newcommand{\R}{\textsuperscript{\textregistered}\xspace} \newcommand{\tm}{\textsuperscript{\texttrademark}\xspace} \newcommand{\tge}{$\geqslant$} %\newcommand{\ditto}{\textquotedbl\xspace} \newcommand{\fixme}[1]{$\bigstar$\emph{\textbf{\large #1}}$\bigstar$\xspace} \newcommand{\ppc}{\mbox{PowerPC}\xspace} \newcommand{\of}{Open Firmware\xspace} \newcommand{\benh}{Ben Herrenschmidt\xspace} \newcommand{\kexec}{\texttt{kexec()}\xspace} \newcommand{\dtbeginnode}{\texttt{OF\_DT\_BEGIN\_NODE\xspace}} \newcommand{\dtendnode}{\texttt{OF\_DT\_END\_NODE\xspace}} \newcommand{\dtprop}{\texttt{OF\_DT\_PROP\xspace}} \newcommand{\dtend}{\texttt{OF\_DT\_END\xspace}} \newcommand{\dtc}{\texttt{dtc}\xspace} \newcommand{\phandle}{\texttt{linux,phandle}\xspace} \begin{document} \maketitle \begin{abstract} We present a method for booting a \ppc{}\R Linux\R kernel on an embedded machine. To do this, we supply the kernel with a compact flattened-tree representation of the system's hardware based on the device tree supplied by Open Firmware on IBM\R servers and Apple\R Power Macintosh\R machines. The ``blob'' representing the device tree can be created using \dtc --- the Device Tree Compiler --- that turns a simple text representation of the tree into the compact representation used by the kernel. The compiler can produce either a binary ``blob'' or an assembler file ready to be built into a firmware or bootwrapper image. This flattened-tree approach is now the only supported method of booting a \texttt{ppc64} kernel without Open Firmware, and we plan to make it the only supported method for all \texttt{powerpc} kernels in the future. \end{abstract} \section{Introduction} \subsection{OF and the device tree} Historically, ``everyday'' \ppc machines have booted with the help of \of (OF), a firmware environment defined by IEEE1275 \cite{IEEE1275}. Among other boot-time services, OF maintains a device tree that describes all of the system's hardware devices and how they're connected. During boot, before taking control of memory management, the Linux kernel uses OF calls to scan the device tree and transfer it to an internal representation that is used at run time to look up various device information. The device tree consists of nodes representing devices or buses\footnote{Well, mostly. There are a few special exceptions.}. Each node contains \emph{properties}, name--value pairs that give information about the device. The values are arbitrary byte strings, and for some properties, they contain tables or other structured information. \subsection{The bad old days} Embedded systems, by contrast, usually have a minimal firmware that might supply a few vital system parameters (size of RAM and the like), but nothing as detailed or complete as the OF device tree. This has meant that the various 32-bit \ppc embedded ports have required a variety of hacks spread across the kernel to deal with the lack of device tree. These vary from specialised boot wrappers to parse parameters (which are at least reasonably localised) to CONFIG-dependent hacks in drivers to override normal probe logic with hardcoded addresses for a particular board. As well as being ugly of itself, such CONFIG-dependent hacks make it hard to build a single kernel image that supports multiple embedded machines. Until relatively recently, the only 64-bit \ppc machines without OF were legacy (pre-POWER5\R) iSeries\R machines. iSeries machines often only have virtual IO devices, which makes it quite simple to work around the lack of a device tree. Even so, the lack means the iSeries boot sequence must be quite different from the pSeries or Macintosh, which is not ideal. The device tree also presents a problem for implementing \kexec. When the kernel boots, it takes over full control of the system from OF, even re-using OF's memory. So, when \kexec comes to boot another kernel, OF is no longer around for the second kernel to query. \section{The Flattened Tree} In May 2005 \benh implemented a new approach to handling the device tree that addresses all these problems. When booting on OF systems, the first thing the kernel runs is a small piece of code in \texttt{prom\_init.c}, which executes in the context of OF. This code walks the device tree using OF calls, and transcribes it into a compact, flattened format. The resulting device tree ``blob'' is then passed to the kernel proper, which eventually unflattens the tree into its runtime form. This blob is the only data communicated between the \texttt{prom\_init.c} bootstrap and the rest of the kernel. When OF isn't available, either because the machine doesn't have it at all or because \kexec has been used, the kernel instead starts directly from the entry point taking a flattened device tree. The device tree blob must be passed in from outside, rather than generated by part of the kernel from OF. For \kexec, the userland \texttt{kexec} tools build the blob from the runtime device tree before invoking the new kernel. For embedded systems the blob can come either from the embedded bootloader, or from a specialised version of the \texttt{zImage} wrapper for the system in question. \subsection{Properties of the flattened tree} The flattened tree format should be easy to handle, both for the kernel that parses it and the bootloader that generates it. In particular, the following properties are desirable: \begin{itemize} \item \emph{relocatable}: the bootloader or kernel should be able to move the blob around as a whole, without needing to parse or adjust its internals. In practice that means we must not use pointers within the blob. \item \emph{insert and delete}: sometimes the bootloader might want to make tweaks to the flattened tree, such as deleting or inserting a node (or whole subtree). It should be possible to do this without having to effectively regenerate the whole flattened tree. In practice this means limiting the use of internal offsets in the blob that need recalculation if a section is inserted or removed with \texttt{memmove()}. \item \emph{compact}: embedded systems are frequently short of resources, particularly RAM and flash memory space. Thus, the tree representation should be kept as small as conveniently possible. \end{itemize} \subsection{Format of the device tree blob} \label{sec:format} \begin{figure}[htb!] \centering \footnotesize \begin{tabular}{r|c|l} \multicolumn{1}{r}{\textbf{Offset}}& \multicolumn{1}{c}{\textbf{Contents}} \\\cline{2-2} \texttt{0x00} & \texttt{0xd00dfeed} & magic number \\\cline{2-2} \texttt{0x04} & \emph{totalsize} \\\cline{2-2} \texttt{0x08} & \emph{off\_struct} & \\\cline{2-2} \texttt{0x0C} & \emph{off\_strs} & \\\cline{2-2} \texttt{0x10} & \emph{off\_rsvmap} & \\\cline{2-2} \texttt{0x14} & \emph{version} \\\cline{2-2} \texttt{0x18} & \emph{last\_comp\_ver} & \\\cline{2-2} \texttt{0x1C} & \emph{boot\_cpu\_id} & \tge v2 only\\\cline{2-2} \texttt{0x20} & \emph{size\_strs} & \tge v3 only\\\cline{2-2} \multicolumn{1}{r}{\vdots} & \multicolumn{1}{c}{\vdots} & \\\cline{2-2} \emph{off\_rsvmap} & \emph{address0} & memory reserve \\ + \texttt{0x04} & ...& table \\\cline{2-2} + \texttt{0x08} & \emph{len0} & \\ + \texttt{0x0C} & ...& \\\cline{2-2} \vdots & \multicolumn{1}{c|}{\vdots} & \\\cline{2-2} & \texttt{0x00000000}- & end marker\\ & \texttt{00000000} & \\\cline{2-2} & \texttt{0x00000000}- & \\ & \texttt{00000000} & \\\cline{2-2} \multicolumn{1}{r}{\vdots} & \multicolumn{1}{c}{\vdots} & \\\cline{2-2} \emph{off\_strs} & \texttt{'n' 'a' 'm' 'e'} & strings block \\ + \texttt{0x04} & \texttt{~0~ 'm' 'o' 'd'} & \\ + \texttt{0x08} & \texttt{'e' 'l' ~0~ \makebox[\widthof{~~~}]{\textrm{...}}} & \\ \vdots & \multicolumn{1}{c|}{\vdots} & \\\cline{2-2} \multicolumn{1}{r}{+ \emph{size\_strs}} \\ \multicolumn{1}{r}{\vdots} & \multicolumn{1}{c}{\vdots} & \\\cline{2-2} \emph{off\_struct} & \dtbeginnode & structure block \\\cline{2-2} + \texttt{0x04} & \texttt{'/' ~0~ ~0~ ~0~} & root node\\\cline{2-2} + \texttt{0x08} & \dtprop & \\\cline{2-2} + \texttt{0x0C} & \texttt{0x00000005} & ``\texttt{model}''\\\cline{2-2} + \texttt{0x10} & \texttt{0x00000008} & \\\cline{2-2} + \texttt{0x14} & \texttt{'M' 'y' 'B' 'o'} & \\ + \texttt{0x18} & \texttt{'a' 'r' 'd' ~0~} & \\\cline{2-2} \vdots & \multicolumn{1}{c|}{\vdots} & \\\cline{2-2} & \texttt{\dtendnode} \\\cline{2-2} & \texttt{\dtend} \\\cline{2-2} \multicolumn{1}{r}{\vdots} & \multicolumn{1}{c}{\vdots} & \\\cline{2-2} \multicolumn{1}{r}{\emph{totalsize}} \\ \end{tabular} \caption{Device tree blob layout} \label{fig:blob-layout} \end{figure} The format for the blob we devised, was first described on the \texttt{linuxppc64-dev} mailing list in \cite{noof1}. The format has since evolved through various revisions, and the current version is included as part of the \dtc (see \S\ref{sec:dtc}) git tree, \cite{dtcgit}. Figure \ref{fig:blob-layout} shows the layout of the blob of data containing the device tree. It has three sections of variable size: the \emph{memory reserve table}, the \emph{structure block} and the \emph{strings block}. A small header gives the blob's size and version and the locations of the three sections, plus a handful of vital parameters used during early boot. The memory reserve map section gives a list of regions of memory that the kernel must not use\footnote{Usually such ranges contain some data structure initialised by the firmware that must be preserved by the kernel.}. The list is represented as a simple array of (address, size) pairs of 64 bit values, terminated by a zero size entry. The strings block is similarly simple, consisting of a number of null-terminated strings appended together, which are referenced from the structure block as described below. The structure block contains the device tree proper. Each node is introduced with a 32-bit \dtbeginnode tag, followed by the node's name as a null-terminated string, padded to a 32-bit boundary. Then follows all of the properties of the node, each introduced with a \dtprop tag, then all of the node's subnodes, each introduced with their own \dtbeginnode tag. The node ends with an \dtendnode tag, and after the \dtendnode for the root node is an \dtend tag, indicating the end of the whole tree\footnote{This is redundant, but included for ease of parsing.}. The structure block starts with the \dtbeginnode introducing the description of the root node (named \texttt{/}). Each property, after the \dtprop, has a 32-bit value giving an offset from the beginning of the strings block at which the property name is stored. Because it's common for many nodes to have properties with the same name, this approach can substantially reduce the total size of the blob. The name offset is followed by the length of the property value (as a 32-bit value) and then the data itself padded to a 32-bit boundary. \subsection{Contents of the tree} \label{sec:treecontents} Having seen how to represent the device tree structure as a flattened blob, what actually goes into the tree? The short answer is ``the same as an OF tree''. On OF systems, the flattened tree is transcribed directly from the OF device tree, so for simplicity we also use OF conventions for the tree on other systems. In many cases a flat tree can be simpler than a typical OF provided device tree. The flattened tree need only provide those nodes and properties that the kernel actually requires; the flattened tree generally need not include devices that the kernel can probe itself. For example, an OF device tree would normally include nodes for each PCI device on the system. A flattened tree need only include nodes for the PCI host bridges; the kernel will scan the buses thus described to find the subsidiary devices. The device tree can include nodes for devices where the kernel needs extra information, though: for example, for ISA devices on a subsidiary PCI/ISA bridge, or for devices with unusual interrupt routing. Where they exist, we follow the IEEE1275 bindings that specify how to describe various buses in the device tree (for example, \cite{IEEE1275-pci} describe how to represent PCI devices). The standard has not been updated for a long time, however, and lacks bindings for many modern buses and devices. In particular, embedded specific devices such as the various System-on-Chip buses are not covered. We intend to create new bindings for such buses, in keeping with the general conventions of IEEE1275 (a simple such binding for a System-on-Chip bus was included in \cite{noof5} a revision of \cite{noof1}). One complication arises for representing ``phandles'' in the flattened tree. In OF, each node in the tree has an associated phandle, a 32-bit integer that uniquely identifies the node\footnote{In practice usually implemented as a pointer or offset within OF memory.}. This handle is used by the various OF calls to query and traverse the tree. Sometimes phandles are also used within the tree to refer to other nodes in the tree. For example, devices that produce interrupts generally have an \texttt{interrupt-parent} property giving the phandle of the interrupt controller that handles interrupts from this device. Parsing these and other interrupt related properties allows the kernel to build a complete representation of the system's interrupt tree, which can be quite different from the tree of bus connections. In the flattened tree, a node's phandle is represented by a special \phandle property. When the kernel generates a flattened tree from OF, it adds a \phandle property to each node, containing the phandle retrieved from OF. When the tree is generated without OF, however, only nodes that are actually referred to by phandle need to have this property. Another complication arises because nodes in an OF tree have two names. First they have the ``unit name'', which is how the node is referred to in an OF path. The unit name generally consists of a device type followed by an \texttt{@} followed by a \emph{unit address}. For example \texttt{/memory@0} is the full path of a memory node at address 0, \texttt{/ht@0,f2000000/pci@1} is the path of a PCI bus node, which is under a HyperTransport\tm bus node. The form of the unit address is bus dependent, but is generally derived from the node's \texttt{reg} property. In addition, nodes have a property, \texttt{name}, whose value is usually equal to the first path of the unit name. For example, the nodes in the previous example would have \texttt{name} properties equal to \texttt{memory} and \texttt{pci}, respectively. To save space in the blob, the current version of the flattened tree format only requires the unit names to be present. When the kernel unflattens the tree, it automatically generates a \texttt{name} property from the node's path name. \section{The Device Tree Compiler} \label{sec:dtc} \begin{figure}[htb!] \centering \begin{lstlisting}[frame=single,basicstyle=\footnotesize\ttfamily, tabsize=3,numbers=left,xleftmargin=2em] /memreserve/ 0x20000000-0x21FFFFFF; / { model = "MyBoard"; compatible = "MyBoardFamily"; #address-cells = <2>; #size-cells = <2>; cpus { #address-cells = <1>; #size-cells = <0>; PowerPC,970@0 { device_type = "cpu"; reg = <0>; clock-frequency = <5f5e1000>; timebase-frequency = <1FCA055>; linux,boot-cpu; i-cache-size = <10000>; d-cache-size = <8000>; }; }; memory@0 { device_type = "memory"; memreg: reg = <00000000 00000000 00000000 20000000>; }; mpic@0x3fffdd08400 { /* Interrupt controller */ /* ... */ }; pci@40000000000000 { /* PCI host bridge */ /* ... */ }; chosen { bootargs = "root=/dev/sda2"; linux,platform = <00000600>; interrupt-controller = < &/mpic@0x3fffdd08400 >; }; }; \end{lstlisting} \caption{Example \dtc source} \label{fig:dts} \end{figure} As we've seen, the flattened device tree format provides a convenient way of communicating device tree information to the kernel. It's simple for the kernel to parse, and simple for bootloaders to manipulate. On OF systems, it's easy to generate the flattened tree by walking the OF maintained tree. However, for embedded systems, the flattened tree must be generated from scratch. Embedded bootloaders are generally built for a particular board. So, it's usually possible to build the device tree blob at compile time and include it in the bootloader image. For minor revisions of the board, the bootloader can contain code to make the necessary tweaks to the tree before passing it to the booted kernel. The device trees for embedded boards are usually quite simple, and it's possible to hand construct the necessary blob by hand, but doing so is tedious. The ``device tree compiler'', \dtc{}\footnote{\dtc can be obtained from \cite{dtcgit}.}, is designed to make creating device tree blobs easier by converting a text representation of the tree into the necessary blob. \subsection{Input and output formats} As well as the normal mode of compiling a device tree blob from text source, \dtc can convert a device tree between a number of representations. It can take its input in one of three different formats: \begin{itemize} \item source, the normal case. The device tree is described in a text form, described in \S\ref{sec:dts}. \item blob (\texttt{dtb}), the flattened tree format described in \S\ref{sec:format}. This mode is useful for checking a pre-existing device tree blob. \item filesystem (\texttt{fs}), input is a directory tree in the layout of \texttt{/proc/device-tree} (roughly, a directory for each node in the device tree, a file for each property). This is useful for building a blob for the device tree in use by the currently running kernel. \end{itemize} In addition, \dtc can output the tree in one of three different formats: \begin{itemize} \item blob (\texttt{dtb}), as in \S\ref{sec:format}. The most straightforward use of \dtc is to compile from ``source'' to ``blob'' format. \item source (\texttt{dts}), as in \S\ref{sec:dts}. If used with blob input, this allows \dtc to act as a ``decompiler''. \item assembler source (\texttt{asm}). \dtc can produce an assembler file, which will assemble into a \texttt{.o} file containing the device tree blob, with symbols giving the beginning of the blob and its various subsections. This can then be linked directly into a bootloader or firmware image. \end{itemize} For maximum applicability, \dtc can both read and write any of the existing revisions of the blob format. When reading, \dtc takes the version from the blob header, and when writing it takes a command line option specifying the desired version. It automatically makes any necessary adjustments to the tree that are necessary for the specified version. For example, formats before 0x10 require each node to have an explicit \texttt{name} property. When \dtc creates such a blob, it will automatically generate \texttt{name} properties from the unit names. \subsection{Source format} \label{sec:dts} The ``source'' format for \dtc is a text description of the device tree in a vaguely C-like form. Figure \ref{fig:dts} shows an example. The file starts with \texttt{/memreserve/} directives, which gives address ranges to add to the output blob's memory reserve table, then the device tree proper is described. Nodes of the tree are introduced with the node name, followed by a \texttt{\{} ... \texttt{\};} block containing the node's properties and subnodes. Properties are given as just {\emph{name} \texttt{=} \emph{value}\texttt{;}}. The property values can be given in any of three forms: \begin{itemize} \item \emph{string} (for example, \texttt{"MyBoard"}). The property value is the given string, including terminating NULL. C-style escapes (\verb+\t+, \verb+\n+, \verb+\0+ and so forth) are allowed. \item \emph{cells} (for example, \texttt{<0 8000 f0000000>}). The property value is made up of a list of 32-bit ``cells'', each given as a hex value. \item \emph{bytestring} (for example, \texttt{[1234abcdef]}). The property value is given as a hex bytestring. \end{itemize} Cell properties can also contain \emph{references}. Instead of a hex number, the source can give an ampersand (\texttt{\&}) followed by the full path to some node in the tree. For example, in Figure \ref{fig:dts}, the \texttt{/chosen} node has an \texttt{interrupt-controller} property referring to the interrupt controller described by the node \texttt{/mpic@0x3fffdd08400}. In the output tree, the value of the referenced node's phandle is included in the property. If that node doesn't have an explicit phandle property, \dtc will automatically create a unique phandle for it. This approach makes it easy to create interrupt trees without having to explicitly assign and remember phandles for the various interrupt controller nodes. The \dtc source can also include ``labels'', which are placed on a particular node or property. For example, Figure \ref{fig:dts} has a label ``\texttt{memreg}'' on the \texttt{reg} property of the node \texttt{/memory@0}. When using assembler output, corresponding labels in the output are generated, which will assemble into symbols addressing the part of the blob with the node or property in question. This is useful for the common case where an embedded board has an essentially fixed device tree with a few variable properties, such as the size of memory. The bootloader for such a board can have a device tree linked in, including a symbol referring to the right place in the blob to update the parameter with the correct value determined at runtime. \subsection{Tree checking} Between reading in the device tree and writing it out in the new format, \dtc performs a number of checks on the tree: \begin{itemize} \item \emph{syntactic structure}: \dtc checks that node and property names contain only allowed characters and meet length restrictions. It checks that a node does not have multiple properties or subnodes with the same name. \item \emph{semantic structure}: In some cases, \dtc checks that properties whose contents are defined by convention have appropriate values. For example, it checks that \texttt{reg} properties have a length that makes sense given the address forms specified by the \texttt{\#address-cells} and \texttt{\#size-cells} properties. It checks that properties such as \texttt{interrupt-parent} contain a valid phandle. \item \emph{Linux requirements}: \dtc checks that the device tree contains those nodes and properties that are required by the Linux kernel to boot correctly. \end{itemize} These checks are useful to catch simple problems with the device tree, rather than having to debug the results on an embedded kernel. With the blob input mode, it can also be used for diagnosing problems with an existing blob. \section{Future Work} \subsection{Board ports} The flattened device tree has always been the only supported way to boot a \texttt{ppc64} kernel on an embedded system. With the merge of \texttt{ppc32} and \texttt{ppc64} code it has also become the only supported way to boot any merged \texttt{powerpc} kernel, 32-bit or 64-bit. In fact, the old \texttt{ppc} architecture exists mainly just to support the old ppc32 embedded ports that have not been migrated to the flattened device tree approach. We plan to remove the \texttt{ppc} architecture eventually, which will mean porting all the various embedded boards to use the flattened device tree. \subsection{\dtc features} While it is already quite usable, there are a number of extra features that \dtc could include to make creating device trees more convenient: \begin{itemize} \item \emph{better tree checking}: Although \dtc already performs a number of checks on the device tree, they are rather haphazard. In many cases \dtc will give up after detecting a minor error early and won't pick up more interesting errors later on. There is a \texttt{-f} parameter that forces \dtc to generate an output tree even if there are errors. At present, this needs to be used more often than one might hope, because \dtc is bad at deciding which errors should really be fatal, and which rate mere warnings. \item \emph{binary include}: Occasionally, it is useful for the device tree to incorporate as a property a block of binary data for some board-specific purpose. For example, many of Apple's device trees incorporate bytecode drivers for certain platform devices. \dtc's source format ought to allow this by letting a property's value be read directly from a binary file. \item \emph{macros}: it might be useful for \dtc to implement some sort of macros so that a tree containing a number of similar devices (for example, multiple identical ethernet controllers or PCI buses) can be written more quickly. At present, this can be accomplished in part by running the source file through CPP before compiling with \dtc. It's not clear whether ``native'' support for macros would be more useful. \end{itemize} \bibliographystyle{amsplain} \bibliography{dtc-paper} \section*{About the authors} David Gibson has been a member of the IBM Linux Technology Center, working from Canberra, Australia, since 2001. Recently he has worked on Linux hugepage support and performance counter support for ppc64, as well as the device tree compiler. In the past, he has worked on bringup for various ppc and ppc64 embedded systems, the orinoco wireless driver, ramfs, and a userspace checkpointing system (\texttt{esky}). Benjamin Herrenschmidt was a MacOS developer for about 10 years, but ultimately saw the light and installed Linux on his Apple PowerPC machine. After writing a bootloader, BootX, for it in 1998, he started contributing to the PowerPC Linux port in various areas, mostly around the support for Apple machines. He became official PowerMac maintainer in 2001. In 2003, he joined the IBM Linux Technology Center in Canberra, Australia, where he ported the 64 bit PowerPC kernel to Apple G5 machines and the Maple embedded board, among others things. He's a member of the ppc64 development ``team'' and one of his current goals is to make the integration of embedded platforms smoother and more maintainable than in the 32-bit PowerPC kernel. \section*{Legal Statement} This work represents the view of the author and does not necessarily represent the view of IBM. IBM, \ppc, \ppc Architecture, POWER5, pSeries and iSeries are trademarks or registered trademarks of International Business Machines Corporation in the United States and/or other countries. Apple and Power Macintosh are a registered trademarks of Apple Computer Inc. in the United States, other countries, or both. Linux is a registered trademark of Linus Torvalds. Other company, product, and service names may be trademarks or service marks of others. \end{document} device-tree-compiler-1.4.0+dfsg.orig/Documentation/manual.txt0000664000000000000000000005435412261525673021141 0ustar Device Tree Compiler Manual =========================== I - "dtc", the device tree compiler 1) Obtaining Sources 1.1) Submitting Patches 2) Description 3) Command Line 4) Source File 4.1) Overview 4.2) Properties 4.3) Labels and References II - The DT block format 1) Header 2) Device tree generalities 3) Device tree "structure" block 4) Device tree "strings" block III - libfdt IV - Utility Tools 1) convert-dtsv0 -- Conversion to Version 1 1) fdtdump I - "dtc", the device tree compiler =================================== 1) Sources Source code for the Device Tree Compiler can be found at jdl.com. The gitweb interface is: http://git.jdl.com/gitweb/ The repository is here: git://www.jdl.com/software/dtc.git http://www.jdl.com/software/dtc.git Tarballs of the 1.0.0 and latest releases are here: http://www.jdl.com/software/dtc-v1.2.0.tgz http://www.jdl.com/software/dtc-latest.tgz 1.1) Submitting Patches Patches should be sent to jdl@jdl.com, and CC'ed to devicetree-discuss@lists.ozlabs.org. 2) Description The Device Tree Compiler, dtc, takes as input a device-tree in a given format and outputs a device-tree in another format. Typically, the input format is "dts", a human readable source format, and creates a "dtb", or binary format as output. The currently supported Input Formats are: - "dtb": "blob" format. A flattened device-tree block with header in one binary blob. - "dts": "source" format. A text file containing a "source" for a device-tree. - "fs" format. A representation equivalent to the output of /proc/device-tree where nodes are directories and properties are files. The currently supported Output Formats are: - "dtb": "blob" format - "dts": "source" format - "asm": assembly language file. A file that can be sourced by gas to generate a device-tree "blob". That file can then simply be added to your Makefile. Additionally, the assembly file exports some symbols that can be used. 3) Command Line The syntax of the dtc command line is: dtc [options] [] Options: The name of the input source file. If no or "-" is given, stdin is used. -b Set the physical boot cpu. -f Force. Try to produce output even if the input tree has errors. -h Emit a brief usage and help message. -I The source input format, as listed above. -o The name of the generated output file. Use "-" for stdout. -O The generated output format, as listed above. -d Generate a dependency file during compilation. -q Quiet: -q suppress warnings, -qq errors, -qqq all -R Make space for reserve map entries Relevant for dtb and asm output only. -S Ensure the blob at least long, adding additional space if needed. -v Print DTC version and exit. -V Generate output conforming to the given . By default the most recent version is generated. Relevant for dtb and asm output only. The defines what version of the "blob" format will be generated. Supported versions are 1, 2, 3, 16 and 17. The default is always the most recent version and is likely the highest number. Additionally, dtc performs various sanity checks on the tree. 4) Device Tree Source file 4.1) Overview Here is a very rough overview of the layout of a DTS source file: sourcefile: list_of_memreserve devicetree memreserve: label 'memreserve' ADDR ADDR ';' | label 'memreserve' ADDR '-' ADDR ';' devicetree: '/' nodedef nodedef: '{' list_of_property list_of_subnode '}' ';' property: label PROPNAME '=' propdata ';' propdata: STRING | '<' list_of_cells '>' | '[' list_of_bytes ']' subnode: label nodename nodedef That structure forms a hierarchical layout of nodes and properties rooted at an initial node as: / { } Both classic C style and C++ style comments are supported. Source files may be directly included using the syntax: /include/ "filename" 4.2) Properties Properties are named, possibly labeled, values. Each value is one of: - A null-teminated C-like string, - A numeric value fitting in 32 bits, - A list of 32-bit values - A byte sequence Here are some example property definitions: - A property containing a 0 terminated string property1 = "string_value"; - A property containing a numerical 32-bit hexadecimal value property2 = <1234abcd>; - A property containing 3 numerical 32-bit hexadecimal values property3 = <12345678 12345678 deadbeef>; - A property whose content is an arbitrary array of bytes property4 = [0a 0b 0c 0d de ea ad be ef]; Node may contain sub-nodes to obtain a hierarchical structure. For example: - A child node named "childnode" whose unit name is "childnode at address". It it turn has a string property called "childprop". childnode@addresss { childprop = "hello\n"; }; By default, all numeric values are hexadecimal. Alternate bases may be specified using a prefix "d#" for decimal, "b#" for binary, and "o#" for octal. Strings support common escape sequences from C: "\n", "\t", "\r", "\(octal value)", "\x(hex value)". 4.3) Labels and References Labels may be applied to nodes or properties. Labels appear before a node name, and are referenced using an ampersand: &label. Absolute node path names are also allowed in node references. In this exmaple, a node is labled "mpic" and then referenced: mpic: interrupt-controller@40000 { ... }; ethernet-phy@3 { interrupt-parent = <&mpic>; ... }; And used in properties, lables may appear before or after any value: randomnode { prop: string = data: "mystring\n" data_end: ; ... }; II - The DT block format ======================== This chapter defines the format of the flattened device-tree passed to the kernel. The actual content of the device tree are described in the kernel documentation in the file linux-2.6/Documentation/powerpc/booting-without-of.txt You can find example of code manipulating that format within the kernel. For example, the file: including arch/powerpc/kernel/prom_init.c will generate a flattened device-tree from the Open Firmware representation. Other utilities such as fs2dt, which is part of the kexec tools, will generate one from a filesystem representation. Some bootloaders such as U-Boot provide a bit more support by using the libfdt code. For booting the kernel, the device tree block has to be in main memory. It has to be accessible in both real mode and virtual mode with no mapping other than main memory. If you are writing a simple flash bootloader, it should copy the block to RAM before passing it to the kernel. 1) Header --------- The kernel is entered with r3 pointing to an area of memory that is roughly described in include/asm-powerpc/prom.h by the structure boot_param_header: struct boot_param_header { u32 magic; /* magic word OF_DT_HEADER */ u32 totalsize; /* total size of DT block */ u32 off_dt_struct; /* offset to structure */ u32 off_dt_strings; /* offset to strings */ u32 off_mem_rsvmap; /* offset to memory reserve map */ u32 version; /* format version */ u32 last_comp_version; /* last compatible version */ /* version 2 fields below */ u32 boot_cpuid_phys; /* Which physical CPU id we're booting on */ /* version 3 fields below */ u32 size_dt_strings; /* size of the strings block */ /* version 17 fields below */ u32 size_dt_struct; /* size of the DT structure block */ }; Along with the constants: /* Definitions used by the flattened device tree */ #define OF_DT_HEADER 0xd00dfeed /* 4: version, 4: total size */ #define OF_DT_BEGIN_NODE 0x1 /* Start node: full name */ #define OF_DT_END_NODE 0x2 /* End node */ #define OF_DT_PROP 0x3 /* Property: name off, size, content */ #define OF_DT_END 0x9 All values in this header are in big endian format, the various fields in this header are defined more precisely below. All "offset" values are in bytes from the start of the header; that is from the value of r3. - magic This is a magic value that "marks" the beginning of the device-tree block header. It contains the value 0xd00dfeed and is defined by the constant OF_DT_HEADER - totalsize This is the total size of the DT block including the header. The "DT" block should enclose all data structures defined in this chapter (who are pointed to by offsets in this header). That is, the device-tree structure, strings, and the memory reserve map. - off_dt_struct This is an offset from the beginning of the header to the start of the "structure" part the device tree. (see 2) device tree) - off_dt_strings This is an offset from the beginning of the header to the start of the "strings" part of the device-tree - off_mem_rsvmap This is an offset from the beginning of the header to the start of the reserved memory map. This map is a list of pairs of 64- bit integers. Each pair is a physical address and a size. The list is terminated by an entry of size 0. This map provides the kernel with a list of physical memory areas that are "reserved" and thus not to be used for memory allocations, especially during early initialization. The kernel needs to allocate memory during boot for things like un-flattening the device-tree, allocating an MMU hash table, etc... Those allocations must be done in such a way to avoid overriding critical things like, on Open Firmware capable machines, the RTAS instance, or on some pSeries, the TCE tables used for the iommu. Typically, the reserve map should contain _at least_ this DT block itself (header,total_size). If you are passing an initrd to the kernel, you should reserve it as well. You do not need to reserve the kernel image itself. The map should be 64-bit aligned. - version This is the version of this structure. Version 1 stops here. Version 2 adds an additional field boot_cpuid_phys. Version 3 adds the size of the strings block, allowing the kernel to reallocate it easily at boot and free up the unused flattened structure after expansion. Version 16 introduces a new more "compact" format for the tree itself that is however not backward compatible. Version 17 adds an additional field, size_dt_struct, allowing it to be reallocated or moved more easily (this is particularly useful for bootloaders which need to make adjustments to a device tree based on probed information). You should always generate a structure of the highest version defined at the time of your implementation. Currently that is version 17, unless you explicitly aim at being backward compatible. - last_comp_version Last compatible version. This indicates down to what version of the DT block you are backward compatible. For example, version 2 is backward compatible with version 1 (that is, a kernel build for version 1 will be able to boot with a version 2 format). You should put a 1 in this field if you generate a device tree of version 1 to 3, or 16 if you generate a tree of version 16 or 17 using the new unit name format. - boot_cpuid_phys This field only exist on version 2 headers. It indicate which physical CPU ID is calling the kernel entry point. This is used, among others, by kexec. If you are on an SMP system, this value should match the content of the "reg" property of the CPU node in the device-tree corresponding to the CPU calling the kernel entry point (see further chapters for more informations on the required device-tree contents) - size_dt_strings This field only exists on version 3 and later headers. It gives the size of the "strings" section of the device tree (which starts at the offset given by off_dt_strings). - size_dt_struct This field only exists on version 17 and later headers. It gives the size of the "structure" section of the device tree (which starts at the offset given by off_dt_struct). So the typical layout of a DT block (though the various parts don't need to be in that order) looks like this (addresses go from top to bottom): ------------------------------ r3 -> | struct boot_param_header | ------------------------------ | (alignment gap) (*) | ------------------------------ | memory reserve map | ------------------------------ | (alignment gap) | ------------------------------ | | | device-tree structure | | | ------------------------------ | (alignment gap) | ------------------------------ | | | device-tree strings | | | -----> ------------------------------ | | --- (r3 + totalsize) (*) The alignment gaps are not necessarily present; their presence and size are dependent on the various alignment requirements of the individual data blocks. 2) Device tree generalities --------------------------- This device-tree itself is separated in two different blocks, a structure block and a strings block. Both need to be aligned to a 4 byte boundary. First, let's quickly describe the device-tree concept before detailing the storage format. This chapter does _not_ describe the detail of the required types of nodes & properties for the kernel, this is done later in chapter III. The device-tree layout is strongly inherited from the definition of the Open Firmware IEEE 1275 device-tree. It's basically a tree of nodes, each node having two or more named properties. A property can have a value or not. It is a tree, so each node has one and only one parent except for the root node who has no parent. A node has 2 names. The actual node name is generally contained in a property of type "name" in the node property list whose value is a zero terminated string and is mandatory for version 1 to 3 of the format definition (as it is in Open Firmware). Version 16 makes it optional as it can generate it from the unit name defined below. There is also a "unit name" that is used to differentiate nodes with the same name at the same level, it is usually made of the node names, the "@" sign, and a "unit address", which definition is specific to the bus type the node sits on. The unit name doesn't exist as a property per-se but is included in the device-tree structure. It is typically used to represent "path" in the device-tree. More details about the actual format of these will be below. The kernel powerpc generic code does not make any formal use of the unit address (though some board support code may do) so the only real requirement here for the unit address is to ensure uniqueness of the node unit name at a given level of the tree. Nodes with no notion of address and no possible sibling of the same name (like /memory or /cpus) may omit the unit address in the context of this specification, or use the "@0" default unit address. The unit name is used to define a node "full path", which is the concatenation of all parent node unit names separated with "/". The root node doesn't have a defined name, and isn't required to have a name property either if you are using version 3 or earlier of the format. It also has no unit address (no @ symbol followed by a unit address). The root node unit name is thus an empty string. The full path to the root node is "/". Every node which actually represents an actual device (that is, a node which isn't only a virtual "container" for more nodes, like "/cpus" is) is also required to have a "device_type" property indicating the type of node . Finally, every node that can be referenced from a property in another node is required to have a "linux,phandle" property. Real open firmware implementations provide a unique "phandle" value for every node that the "prom_init()" trampoline code turns into "linux,phandle" properties. However, this is made optional if the flattened device tree is used directly. An example of a node referencing another node via "phandle" is when laying out the interrupt tree which will be described in a further version of this document. This "linux, phandle" property is a 32-bit value that uniquely identifies a node. You are free to use whatever values or system of values, internal pointers, or whatever to generate these, the only requirement is that every node for which you provide that property has a unique value for it. Here is an example of a simple device-tree. In this example, an "o" designates a node followed by the node unit name. Properties are presented with their name followed by their content. "content" represents an ASCII string (zero terminated) value, while represents a 32-bit hexadecimal value. The various nodes in this example will be discussed in a later chapter. At this point, it is only meant to give you a idea of what a device-tree looks like. I have purposefully kept the "name" and "linux,phandle" properties which aren't necessary in order to give you a better idea of what the tree looks like in practice. / o device-tree |- name = "device-tree" |- model = "MyBoardName" |- compatible = "MyBoardFamilyName" |- #address-cells = <2> |- #size-cells = <2> |- linux,phandle = <0> | o cpus | | - name = "cpus" | | - linux,phandle = <1> | | - #address-cells = <1> | | - #size-cells = <0> | | | o PowerPC,970@0 | |- name = "PowerPC,970" | |- device_type = "cpu" | |- reg = <0> | |- clock-frequency = <5f5e1000> | |- 64-bit | |- linux,phandle = <2> | o memory@0 | |- name = "memory" | |- device_type = "memory" | |- reg = <00000000 00000000 00000000 20000000> | |- linux,phandle = <3> | o chosen |- name = "chosen" |- bootargs = "root=/dev/sda2" |- linux,phandle = <4> This tree is almost a minimal tree. It pretty much contains the minimal set of required nodes and properties to boot a linux kernel; that is, some basic model informations at the root, the CPUs, and the physical memory layout. It also includes misc information passed through /chosen, like in this example, the platform type (mandatory) and the kernel command line arguments (optional). The /cpus/PowerPC,970@0/64-bit property is an example of a property without a value. All other properties have a value. The significance of the #address-cells and #size-cells properties will be explained in chapter IV which defines precisely the required nodes and properties and their content. 3) Device tree "structure" block The structure of the device tree is a linearized tree structure. The "OF_DT_BEGIN_NODE" token starts a new node, and the "OF_DT_END_NODE" ends that node definition. Child nodes are simply defined before "OF_DT_END_NODE" (that is nodes within the node). A 'token' is a 32 bit value. The tree has to be "finished" with a OF_DT_END token Here's the basic structure of a single node: * token OF_DT_BEGIN_NODE (that is 0x00000001) * for version 1 to 3, this is the node full path as a zero terminated string, starting with "/". For version 16 and later, this is the node unit name only (or an empty string for the root node) * [align gap to next 4 bytes boundary] * for each property: * token OF_DT_PROP (that is 0x00000003) * 32-bit value of property value size in bytes (or 0 if no value) * 32-bit value of offset in string block of property name * property value data if any * [align gap to next 4 bytes boundary] * [child nodes if any] * token OF_DT_END_NODE (that is 0x00000002) So the node content can be summarized as a start token, a full path, a list of properties, a list of child nodes, and an end token. Every child node is a full node structure itself as defined above. NOTE: The above definition requires that all property definitions for a particular node MUST precede any subnode definitions for that node. Although the structure would not be ambiguous if properties and subnodes were intermingled, the kernel parser requires that the properties come first (up until at least 2.6.22). Any tools manipulating a flattened tree must take care to preserve this constraint. 4) Device tree "strings" block In order to save space, property names, which are generally redundant, are stored separately in the "strings" block. This block is simply the whole bunch of zero terminated strings for all property names concatenated together. The device-tree property definitions in the structure block will contain offset values from the beginning of the strings block. III - libfdt ============ This library should be merged into dtc proper. This library should likely be worked into U-Boot and the kernel. IV - Utility Tools ================== 1) convert-dtsv0 -- Conversion to Version 1 convert-dtsv0 is a small utility program which converts (DTS) Device Tree Source from the obsolete version 0 to version 1. Version 1 DTS files are marked by line "/dts-v1/;" at the top of the file. The syntax of the convert-dtsv0 command line is: convert-dtsv0 [] Each file passed will be converted to the new /dts-v1/ version by creating a new file with a "v1" appended the filename. Comments, empty lines, etc. are preserved. 2) fdtdump -- Flat Device Tree dumping utility The fdtdump program prints a readable version of a flat device tree file. The syntax of the fdtdump command line is: fdtdump device-tree-compiler-1.4.0+dfsg.orig/Documentation/dtc-paper.bib0000664000000000000000000000237312261525673021452 0ustar @STRING{pub-IEEE = "IEEE Computer Society"} @STRING{pub-IEEE:adr = "345 E. 47th St, New York, NY 10017, USA"} @BOOK{IEEE1275, key = "IEEE1275", title = "{IEEE} {S}tandard for {B}oot ({I}nitialization {C}onfiguration) {F}irmware: {C}ore {R}equirements and {P}ractices", publisher = pub-IEEE, address = pub-IEEE:adr, series = "IEEE Std 1275-1994", year = 1994, } @BOOK{IEEE1275-pci, key = "IEEE1275-pci", title = "{PCI} {B}us {B}inding to: {IEEE} {S}td 1275-1994 {S}tandard for {B}oot ({I}nitialization {C}onfiguration) {F}irmware", publisher = pub-IEEE, address = pub-IEEE:adr, note = "Revision 2.1", year = 1998, } @MISC{noof1, author = "Benjamin Herrenschmidt", title = "Booting the {L}inux/ppc kernel without {O}pen {F}irmware", month = may, year = 2005, note = "v0.1, \url{http://ozlabs.org/pipermail/linuxppc64-dev/2005-May/004073.html}", } @MISC{noof5, author = "Benjamin Herrenschmidt", title = "Booting the {L}inux/ppc kernel without {O}pen {F}irmware", month = nov, year = 2005, note = "v0.5, \url{http://ozlabs.org/pipermail/linuxppc64-dev/2005-December/006994.html}", } @MISC{dtcgit, author = "David Gibson et al.", title = "\dtc{}", howpublished = "git tree", note = "\url{http://ozlabs.org/~dgibson/dtc/dtc.git}", } device-tree-compiler-1.4.0+dfsg.orig/scripts/0000775000000000000000000000000012261525673015766 5ustar device-tree-compiler-1.4.0+dfsg.orig/scripts/setlocalversion0000775000000000000000000000101712261525673021127 0ustar #!/bin/sh # Print additional version information for non-release trees. usage() { echo "Usage: $0 [srctree]" >&2 exit 1 } cd "${1:-.}" || usage # Check for git and a git repo. if head=`git rev-parse --verify HEAD 2>/dev/null`; then # Do we have an untagged version? if git name-rev --tags HEAD | grep -E '^HEAD[[:space:]]+(.*~[0-9]*|undefined)$' > /dev/null; then printf '%s%s' -g `echo "$head" | cut -c1-8` fi # Are there uncommitted changes? if git diff-index HEAD | read dummy; then printf '%s' -dirty fi fi device-tree-compiler-1.4.0+dfsg.orig/treesource.c0000664000000000000000000001373112261525674016631 0ustar /* * (C) Copyright David Gibson , IBM Corporation. 2005. * * * 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 "dtc.h" #include "srcpos.h" extern FILE *yyin; extern int yyparse(void); extern YYLTYPE yylloc; struct boot_info *the_boot_info; int treesource_error; struct boot_info *dt_from_source(const char *fname) { the_boot_info = NULL; treesource_error = 0; srcfile_push(fname); yyin = current_srcfile->f; yylloc.file = current_srcfile; if (yyparse() != 0) die("Unable to parse input tree\n"); if (treesource_error) die("Syntax error parsing input tree\n"); return the_boot_info; } static void write_prefix(FILE *f, int level) { int i; for (i = 0; i < level; i++) fputc('\t', f); } static int isstring(char c) { return (isprint(c) || (c == '\0') || strchr("\a\b\t\n\v\f\r", c)); } static void write_propval_string(FILE *f, struct data val) { const char *str = val.val; int i; struct marker *m = val.markers; assert(str[val.len-1] == '\0'); while (m && (m->offset == 0)) { if (m->type == LABEL) fprintf(f, "%s: ", m->ref); m = m->next; } fprintf(f, "\""); for (i = 0; i < (val.len-1); i++) { char c = str[i]; switch (c) { case '\a': fprintf(f, "\\a"); break; case '\b': fprintf(f, "\\b"); break; case '\t': fprintf(f, "\\t"); break; case '\n': fprintf(f, "\\n"); break; case '\v': fprintf(f, "\\v"); break; case '\f': fprintf(f, "\\f"); break; case '\r': fprintf(f, "\\r"); break; case '\\': fprintf(f, "\\\\"); break; case '\"': fprintf(f, "\\\""); break; case '\0': fprintf(f, "\", "); while (m && (m->offset < i)) { if (m->type == LABEL) { assert(m->offset == (i+1)); fprintf(f, "%s: ", m->ref); } m = m->next; } fprintf(f, "\""); break; default: if (isprint(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02hhx", c); } } fprintf(f, "\""); /* Wrap up any labels at the end of the value */ for_each_marker_of_type(m, LABEL) { assert (m->offset == val.len); fprintf(f, " %s:", m->ref); } } static void write_propval_cells(FILE *f, struct data val) { void *propend = val.val + val.len; cell_t *cp = (cell_t *)val.val; struct marker *m = val.markers; fprintf(f, "<"); for (;;) { while (m && (m->offset <= ((char *)cp - val.val))) { if (m->type == LABEL) { assert(m->offset == ((char *)cp - val.val)); fprintf(f, "%s: ", m->ref); } m = m->next; } fprintf(f, "0x%x", fdt32_to_cpu(*cp++)); if ((void *)cp >= propend) break; fprintf(f, " "); } /* Wrap up any labels at the end of the value */ for_each_marker_of_type(m, LABEL) { assert (m->offset == val.len); fprintf(f, " %s:", m->ref); } fprintf(f, ">"); } static void write_propval_bytes(FILE *f, struct data val) { void *propend = val.val + val.len; const char *bp = val.val; struct marker *m = val.markers; fprintf(f, "["); for (;;) { while (m && (m->offset == (bp-val.val))) { if (m->type == LABEL) fprintf(f, "%s: ", m->ref); m = m->next; } fprintf(f, "%02hhx", *bp++); if ((const void *)bp >= propend) break; fprintf(f, " "); } /* Wrap up any labels at the end of the value */ for_each_marker_of_type(m, LABEL) { assert (m->offset == val.len); fprintf(f, " %s:", m->ref); } fprintf(f, "]"); } static void write_propval(FILE *f, struct property *prop) { int len = prop->val.len; const char *p = prop->val.val; struct marker *m = prop->val.markers; int nnotstring = 0, nnul = 0; int nnotstringlbl = 0, nnotcelllbl = 0; int i; if (len == 0) { fprintf(f, ";\n"); return; } for (i = 0; i < len; i++) { if (! isstring(p[i])) nnotstring++; if (p[i] == '\0') nnul++; } for_each_marker_of_type(m, LABEL) { if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0')) nnotstringlbl++; if ((m->offset % sizeof(cell_t)) != 0) nnotcelllbl++; } fprintf(f, " = "); if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul)) && (nnotstringlbl == 0)) { write_propval_string(f, prop->val); } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) { write_propval_cells(f, prop->val); } else { write_propval_bytes(f, prop->val); } fprintf(f, ";\n"); } static void write_tree_source_node(FILE *f, struct node *tree, int level) { struct property *prop; struct node *child; struct label *l; write_prefix(f, level); for_each_label(tree->labels, l) fprintf(f, "%s: ", l->label); if (tree->name && (*tree->name)) fprintf(f, "%s {\n", tree->name); else fprintf(f, "/ {\n"); for_each_property(tree, prop) { write_prefix(f, level+1); for_each_label(prop->labels, l) fprintf(f, "%s: ", l->label); fprintf(f, "%s", prop->name); write_propval(f, prop); } for_each_child(tree, child) { fprintf(f, "\n"); write_tree_source_node(f, child, level+1); } write_prefix(f, level); fprintf(f, "};\n"); } void dt_to_source(FILE *f, struct boot_info *bi) { struct reserve_info *re; fprintf(f, "/dts-v1/;\n\n"); for (re = bi->reservelist; re; re = re->next) { struct label *l; for_each_label(re->labels, l) fprintf(f, "%s: ", l->label); fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n", (unsigned long long)re->re.address, (unsigned long long)re->re.size); } write_tree_source_node(f, bi->dt, 0); } device-tree-compiler-1.4.0+dfsg.orig/dtc.c0000664000000000000000000001564612261525673015231 0ustar /* * (C) Copyright David Gibson , IBM Corporation. 2005. * * * 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 "dtc.h" #include "srcpos.h" /* * Command line options */ int quiet; /* Level of quietness */ int reservenum; /* Number of memory reservation slots */ int minsize; /* Minimum blob size */ int padsize; /* Additional padding to blob */ int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */ static void fill_fullpaths(struct node *tree, const char *prefix) { struct node *child; const char *unit; tree->fullpath = join_path(prefix, tree->name); unit = strchr(tree->name, '@'); if (unit) tree->basenamelen = unit - tree->name; else tree->basenamelen = strlen(tree->name); for_each_child(tree, child) fill_fullpaths(child, tree->fullpath); } /* Usage related data. */ static const char usage_synopsis[] = "dtc [options] "; static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; static struct option const usage_long_opts[] = { {"quiet", no_argument, NULL, 'q'}, {"in-format", a_argument, NULL, 'I'}, {"out", a_argument, NULL, 'o'}, {"out-format", a_argument, NULL, 'O'}, {"out-version", a_argument, NULL, 'V'}, {"out-dependency", a_argument, NULL, 'd'}, {"reserve", a_argument, NULL, 'R'}, {"space", a_argument, NULL, 'S'}, {"pad", a_argument, NULL, 'p'}, {"boot-cpu", a_argument, NULL, 'b'}, {"force", no_argument, NULL, 'f'}, {"include", a_argument, NULL, 'i'}, {"sort", no_argument, NULL, 's'}, {"phandle", a_argument, NULL, 'H'}, {"warning", a_argument, NULL, 'W'}, {"error", a_argument, NULL, 'E'}, {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'v'}, {NULL, no_argument, NULL, 0x0}, }; static const char * const usage_opts_help[] = { "\n\tQuiet: -q suppress warnings, -qq errors, -qqq all", "\n\tInput formats are:\n" "\t\tdts - device tree source text\n" "\t\tdtb - device tree blob\n" "\t\tfs - /proc/device-tree style directory", "\n\tOutput file", "\n\tOutput formats are:\n" "\t\tdts - device tree source text\n" "\t\tdtb - device tree blob\n" "\t\tasm - assembler source", "\n\tBlob version to produce, defaults to %d (for dtb and asm output)", //, DEFAULT_FDT_VERSION); "\n\tOutput dependency file", "\n\ttMake space for reserve map entries (for dtb and asm output)", "\n\tMake the blob at least long (extra space)", "\n\tAdd padding to the blob of long (extra space)", "\n\tSet the physical boot cpu", "\n\tTry to produce output even if the input tree has errors", "\n\tAdd a path to search for include files", "\n\tSort nodes and properties before outputting (useful for comparing trees)", "\n\tValid phandle formats are:\n" "\t\tlegacy - \"linux,phandle\" properties only\n" "\t\tepapr - \"phandle\" properties only\n" "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", "\n\tEnable/disable warnings (prefix with \"no-\")", "\n\tEnable/disable errors (prefix with \"no-\")", "\n\tPrint this help and exit", "\n\tPrint version and exit", NULL, }; int main(int argc, char *argv[]) { struct boot_info *bi; const char *inform = "dts"; const char *outform = "dts"; const char *outname = "-"; const char *depname = NULL; int force = 0, sort = 0; const char *arg; int opt; FILE *outf = NULL; int outversion = DEFAULT_FDT_VERSION; long long cmdline_boot_cpuid = -1; quiet = 0; reservenum = 0; minsize = 0; padsize = 0; while ((opt = util_getopt_long()) != EOF) { switch (opt) { case 'I': inform = optarg; break; case 'O': outform = optarg; break; case 'o': outname = optarg; break; case 'V': outversion = strtol(optarg, NULL, 0); break; case 'd': depname = optarg; break; case 'R': reservenum = strtol(optarg, NULL, 0); break; case 'S': minsize = strtol(optarg, NULL, 0); break; case 'p': padsize = strtol(optarg, NULL, 0); break; case 'f': force = 1; break; case 'q': quiet++; break; case 'b': cmdline_boot_cpuid = strtoll(optarg, NULL, 0); break; case 'i': srcfile_add_search_path(optarg); break; case 'v': util_version(); case 'H': if (streq(optarg, "legacy")) phandle_format = PHANDLE_LEGACY; else if (streq(optarg, "epapr")) phandle_format = PHANDLE_EPAPR; else if (streq(optarg, "both")) phandle_format = PHANDLE_BOTH; else die("Invalid argument \"%s\" to -H option\n", optarg); break; case 's': sort = 1; break; case 'W': parse_checks_option(true, false, optarg); break; case 'E': parse_checks_option(false, true, optarg); break; case 'h': usage(NULL); default: usage("unknown option"); } } if (argc > (optind+1)) usage("missing files"); else if (argc < (optind+1)) arg = "-"; else arg = argv[optind]; /* minsize and padsize are mutually exclusive */ if (minsize && padsize) die("Can't set both -p and -S\n"); if (depname) { depfile = fopen(depname, "w"); if (!depfile) die("Couldn't open dependency file %s: %s\n", depname, strerror(errno)); fprintf(depfile, "%s:", outname); } if (streq(inform, "dts")) bi = dt_from_source(arg); else if (streq(inform, "fs")) bi = dt_from_fs(arg); else if(streq(inform, "dtb")) bi = dt_from_blob(arg); else die("Unknown input format \"%s\"\n", inform); if (depfile) { fputc('\n', depfile); fclose(depfile); } if (cmdline_boot_cpuid != -1) bi->boot_cpuid_phys = cmdline_boot_cpuid; fill_fullpaths(bi->dt, ""); process_checks(force, bi); if (sort) sort_tree(bi); if (streq(outname, "-")) { outf = stdout; } else { outf = fopen(outname, "w"); if (! outf) die("Couldn't open output file %s: %s\n", outname, strerror(errno)); } if (streq(outform, "dts")) { dt_to_source(outf, bi); } else if (streq(outform, "dtb")) { dt_to_blob(outf, bi, outversion); } else if (streq(outform, "asm")) { dt_to_asm(outf, bi, outversion); } else if (streq(outform, "null")) { /* do nothing */ } else { die("Unknown output format \"%s\"\n", outform); } exit(0); } device-tree-compiler-1.4.0+dfsg.orig/srcpos.h0000664000000000000000000000723512261525673015770 0ustar /* * Copyright 2007 Jon Loeliger, Freescale Semiconductor, Inc. * * 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 */ #ifndef _SRCPOS_H_ #define _SRCPOS_H_ #include struct srcfile_state { FILE *f; char *name; char *dir; int lineno, colno; struct srcfile_state *prev; }; extern FILE *depfile; /* = NULL */ extern struct srcfile_state *current_srcfile; /* = NULL */ /** * Open a source file. * * If the source file is a relative pathname, then it is searched for in the * current directory (the directory of the last source file read) and after * that in the search path. * * We work through the search path in order from the first path specified to * the last. * * If the file is not found, then this function does not return, but calls * die(). * * @param fname Filename to search * @param fullnamep If non-NULL, it is set to the allocated filename of the * file that was opened. The caller is then responsible * for freeing the pointer. * @return pointer to opened FILE */ FILE *srcfile_relative_open(const char *fname, char **fullnamep); void srcfile_push(const char *fname); int srcfile_pop(void); /** * Add a new directory to the search path for input files * * The new path is added at the end of the list. * * @param dirname Directory to add */ void srcfile_add_search_path(const char *dirname); struct srcpos { int first_line; int first_column; int last_line; int last_column; struct srcfile_state *file; }; #define YYLTYPE struct srcpos #define YYLLOC_DEFAULT(Current, Rhs, N) \ do { \ if (N) { \ (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ (Current).file = YYRHSLOC(Rhs, N).file; \ } else { \ (Current).first_line = (Current).last_line = \ YYRHSLOC(Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC(Rhs, 0).last_column; \ (Current).file = YYRHSLOC (Rhs, 0).file; \ } \ } while (0) /* * Fictional source position used for IR nodes that are * created without otherwise knowing a true source position. * For example,constant definitions from the command line. */ extern struct srcpos srcpos_empty; extern void srcpos_update(struct srcpos *pos, const char *text, int len); extern struct srcpos *srcpos_copy(struct srcpos *pos); extern char *srcpos_string(struct srcpos *pos); extern void srcpos_dump(struct srcpos *pos); extern void srcpos_verror(struct srcpos *pos, char const *, va_list va) __attribute__((format(printf, 2, 0))); extern void srcpos_error(struct srcpos *pos, char const *, ...) __attribute__((format(printf, 2, 3))); extern void srcpos_warn(struct srcpos *pos, char const *, ...) __attribute__((format(printf, 2, 3))); extern void srcpos_set_line(char *f, int l); #endif /* _SRCPOS_H_ */ device-tree-compiler-1.4.0+dfsg.orig/flattree.c0000664000000000000000000005354212261525673016262 0ustar /* * (C) Copyright David Gibson , IBM Corporation. 2005. * * * 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 "dtc.h" #include "srcpos.h" #define FTF_FULLPATH 0x1 #define FTF_VARALIGN 0x2 #define FTF_NAMEPROPS 0x4 #define FTF_BOOTCPUID 0x8 #define FTF_STRTABSIZE 0x10 #define FTF_STRUCTSIZE 0x20 #define FTF_NOPS 0x40 static struct version_info { int version; int last_comp_version; int hdr_size; int flags; } version_table[] = { {1, 1, FDT_V1_SIZE, FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS}, {2, 1, FDT_V2_SIZE, FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID}, {3, 1, FDT_V3_SIZE, FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID|FTF_STRTABSIZE}, {16, 16, FDT_V3_SIZE, FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_NOPS}, {17, 16, FDT_V17_SIZE, FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS}, }; struct emitter { void (*cell)(void *, cell_t); void (*string)(void *, char *, int); void (*align)(void *, int); void (*data)(void *, struct data); void (*beginnode)(void *, struct label *labels); void (*endnode)(void *, struct label *labels); void (*property)(void *, struct label *labels); }; static void bin_emit_cell(void *e, cell_t val) { struct data *dtbuf = e; *dtbuf = data_append_cell(*dtbuf, val); } static void bin_emit_string(void *e, char *str, int len) { struct data *dtbuf = e; if (len == 0) len = strlen(str); *dtbuf = data_append_data(*dtbuf, str, len); *dtbuf = data_append_byte(*dtbuf, '\0'); } static void bin_emit_align(void *e, int a) { struct data *dtbuf = e; *dtbuf = data_append_align(*dtbuf, a); } static void bin_emit_data(void *e, struct data d) { struct data *dtbuf = e; *dtbuf = data_append_data(*dtbuf, d.val, d.len); } static void bin_emit_beginnode(void *e, struct label *labels) { bin_emit_cell(e, FDT_BEGIN_NODE); } static void bin_emit_endnode(void *e, struct label *labels) { bin_emit_cell(e, FDT_END_NODE); } static void bin_emit_property(void *e, struct label *labels) { bin_emit_cell(e, FDT_PROP); } static struct emitter bin_emitter = { .cell = bin_emit_cell, .string = bin_emit_string, .align = bin_emit_align, .data = bin_emit_data, .beginnode = bin_emit_beginnode, .endnode = bin_emit_endnode, .property = bin_emit_property, }; static void emit_label(FILE *f, const char *prefix, const char *label) { fprintf(f, "\t.globl\t%s_%s\n", prefix, label); fprintf(f, "%s_%s:\n", prefix, label); fprintf(f, "_%s_%s:\n", prefix, label); } static void emit_offset_label(FILE *f, const char *label, int offset) { fprintf(f, "\t.globl\t%s\n", label); fprintf(f, "%s\t= . + %d\n", label, offset); } #define ASM_EMIT_BELONG(f, fmt, ...) \ { \ fprintf((f), "\t.byte\t((" fmt ") >> 24) & 0xff\n", __VA_ARGS__); \ fprintf((f), "\t.byte\t((" fmt ") >> 16) & 0xff\n", __VA_ARGS__); \ fprintf((f), "\t.byte\t((" fmt ") >> 8) & 0xff\n", __VA_ARGS__); \ fprintf((f), "\t.byte\t(" fmt ") & 0xff\n", __VA_ARGS__); \ } static void asm_emit_cell(void *e, cell_t val) { FILE *f = e; fprintf(f, "\t.byte 0x%02x; .byte 0x%02x; .byte 0x%02x; .byte 0x%02x\n", (val >> 24) & 0xff, (val >> 16) & 0xff, (val >> 8) & 0xff, val & 0xff); } static void asm_emit_string(void *e, char *str, int len) { FILE *f = e; char c = 0; if (len != 0) { /* XXX: ewww */ c = str[len]; str[len] = '\0'; } fprintf(f, "\t.string\t\"%s\"\n", str); if (len != 0) { str[len] = c; } } static void asm_emit_align(void *e, int a) { FILE *f = e; fprintf(f, "\t.balign\t%d, 0\n", a); } static void asm_emit_data(void *e, struct data d) { FILE *f = e; int off = 0; struct marker *m = d.markers; for_each_marker_of_type(m, LABEL) emit_offset_label(f, m->ref, m->offset); while ((d.len - off) >= sizeof(uint32_t)) { asm_emit_cell(e, fdt32_to_cpu(*((uint32_t *)(d.val+off)))); off += sizeof(uint32_t); } while ((d.len - off) >= 1) { fprintf(f, "\t.byte\t0x%hhx\n", d.val[off]); off += 1; } assert(off == d.len); } static void asm_emit_beginnode(void *e, struct label *labels) { FILE *f = e; struct label *l; for_each_label(labels, l) { fprintf(f, "\t.globl\t%s\n", l->label); fprintf(f, "%s:\n", l->label); } fprintf(f, "\t/* FDT_BEGIN_NODE */\n"); asm_emit_cell(e, FDT_BEGIN_NODE); } static void asm_emit_endnode(void *e, struct label *labels) { FILE *f = e; struct label *l; fprintf(f, "\t/* FDT_END_NODE */\n"); asm_emit_cell(e, FDT_END_NODE); for_each_label(labels, l) { fprintf(f, "\t.globl\t%s_end\n", l->label); fprintf(f, "%s_end:\n", l->label); } } static void asm_emit_property(void *e, struct label *labels) { FILE *f = e; struct label *l; for_each_label(labels, l) { fprintf(f, "\t.globl\t%s\n", l->label); fprintf(f, "%s:\n", l->label); } fprintf(f, "\t/* FDT_PROP */\n"); asm_emit_cell(e, FDT_PROP); } static struct emitter asm_emitter = { .cell = asm_emit_cell, .string = asm_emit_string, .align = asm_emit_align, .data = asm_emit_data, .beginnode = asm_emit_beginnode, .endnode = asm_emit_endnode, .property = asm_emit_property, }; static int stringtable_insert(struct data *d, const char *str) { int i; /* FIXME: do this more efficiently? */ for (i = 0; i < d->len; i++) { if (streq(str, d->val + i)) return i; } *d = data_append_data(*d, str, strlen(str)+1); return i; } static void flatten_tree(struct node *tree, struct emitter *emit, void *etarget, struct data *strbuf, struct version_info *vi) { struct property *prop; struct node *child; int seen_name_prop = 0; if (tree->deleted) return; emit->beginnode(etarget, tree->labels); if (vi->flags & FTF_FULLPATH) emit->string(etarget, tree->fullpath, 0); else emit->string(etarget, tree->name, 0); emit->align(etarget, sizeof(cell_t)); for_each_property(tree, prop) { int nameoff; if (streq(prop->name, "name")) seen_name_prop = 1; nameoff = stringtable_insert(strbuf, prop->name); emit->property(etarget, prop->labels); emit->cell(etarget, prop->val.len); emit->cell(etarget, nameoff); if ((vi->flags & FTF_VARALIGN) && (prop->val.len >= 8)) emit->align(etarget, 8); emit->data(etarget, prop->val); emit->align(etarget, sizeof(cell_t)); } if ((vi->flags & FTF_NAMEPROPS) && !seen_name_prop) { emit->property(etarget, NULL); emit->cell(etarget, tree->basenamelen+1); emit->cell(etarget, stringtable_insert(strbuf, "name")); if ((vi->flags & FTF_VARALIGN) && ((tree->basenamelen+1) >= 8)) emit->align(etarget, 8); emit->string(etarget, tree->name, tree->basenamelen); emit->align(etarget, sizeof(cell_t)); } for_each_child(tree, child) { flatten_tree(child, emit, etarget, strbuf, vi); } emit->endnode(etarget, tree->labels); } static struct data flatten_reserve_list(struct reserve_info *reservelist, struct version_info *vi) { struct reserve_info *re; struct data d = empty_data; static struct fdt_reserve_entry null_re = {0,0}; int j; for (re = reservelist; re; re = re->next) { d = data_append_re(d, &re->re); } /* * Add additional reserved slots if the user asked for them. */ for (j = 0; j < reservenum; j++) { d = data_append_re(d, &null_re); } return d; } static void make_fdt_header(struct fdt_header *fdt, struct version_info *vi, int reservesize, int dtsize, int strsize, int boot_cpuid_phys) { int reserve_off; reservesize += sizeof(struct fdt_reserve_entry); memset(fdt, 0xff, sizeof(*fdt)); fdt->magic = cpu_to_fdt32(FDT_MAGIC); fdt->version = cpu_to_fdt32(vi->version); fdt->last_comp_version = cpu_to_fdt32(vi->last_comp_version); /* Reserve map should be doubleword aligned */ reserve_off = ALIGN(vi->hdr_size, 8); fdt->off_mem_rsvmap = cpu_to_fdt32(reserve_off); fdt->off_dt_struct = cpu_to_fdt32(reserve_off + reservesize); fdt->off_dt_strings = cpu_to_fdt32(reserve_off + reservesize + dtsize); fdt->totalsize = cpu_to_fdt32(reserve_off + reservesize + dtsize + strsize); if (vi->flags & FTF_BOOTCPUID) fdt->boot_cpuid_phys = cpu_to_fdt32(boot_cpuid_phys); if (vi->flags & FTF_STRTABSIZE) fdt->size_dt_strings = cpu_to_fdt32(strsize); if (vi->flags & FTF_STRUCTSIZE) fdt->size_dt_struct = cpu_to_fdt32(dtsize); } void dt_to_blob(FILE *f, struct boot_info *bi, int version) { struct version_info *vi = NULL; int i; struct data blob = empty_data; struct data reservebuf = empty_data; struct data dtbuf = empty_data; struct data strbuf = empty_data; struct fdt_header fdt; int padlen = 0; for (i = 0; i < ARRAY_SIZE(version_table); i++) { if (version_table[i].version == version) vi = &version_table[i]; } if (!vi) die("Unknown device tree blob version %d\n", version); flatten_tree(bi->dt, &bin_emitter, &dtbuf, &strbuf, vi); bin_emit_cell(&dtbuf, FDT_END); reservebuf = flatten_reserve_list(bi->reservelist, vi); /* Make header */ make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len, bi->boot_cpuid_phys); /* * If the user asked for more space than is used, adjust the totalsize. */ if (minsize > 0) { padlen = minsize - fdt32_to_cpu(fdt.totalsize); if ((padlen < 0) && (quiet < 1)) fprintf(stderr, "Warning: blob size %d >= minimum size %d\n", fdt32_to_cpu(fdt.totalsize), minsize); } if (padsize > 0) padlen = padsize; if (padlen > 0) { int tsize = fdt32_to_cpu(fdt.totalsize); tsize += padlen; fdt.totalsize = cpu_to_fdt32(tsize); } /* * Assemble the blob: start with the header, add with alignment * the reserve buffer, add the reserve map terminating zeroes, * the device tree itself, and finally the strings. */ blob = data_append_data(blob, &fdt, vi->hdr_size); blob = data_append_align(blob, 8); blob = data_merge(blob, reservebuf); blob = data_append_zeroes(blob, sizeof(struct fdt_reserve_entry)); blob = data_merge(blob, dtbuf); blob = data_merge(blob, strbuf); /* * If the user asked for more space than is used, pad out the blob. */ if (padlen > 0) blob = data_append_zeroes(blob, padlen); if (fwrite(blob.val, blob.len, 1, f) != 1) { if (ferror(f)) die("Error writing device tree blob: %s\n", strerror(errno)); else die("Short write on device tree blob\n"); } /* * data_merge() frees the right-hand element so only the blob * remains to be freed. */ data_free(blob); } static void dump_stringtable_asm(FILE *f, struct data strbuf) { const char *p; int len; p = strbuf.val; while (p < (strbuf.val + strbuf.len)) { len = strlen(p); fprintf(f, "\t.string \"%s\"\n", p); p += len+1; } } void dt_to_asm(FILE *f, struct boot_info *bi, int version) { struct version_info *vi = NULL; int i; struct data strbuf = empty_data; struct reserve_info *re; const char *symprefix = "dt"; for (i = 0; i < ARRAY_SIZE(version_table); i++) { if (version_table[i].version == version) vi = &version_table[i]; } if (!vi) die("Unknown device tree blob version %d\n", version); fprintf(f, "/* autogenerated by dtc, do not edit */\n\n"); emit_label(f, symprefix, "blob_start"); emit_label(f, symprefix, "header"); fprintf(f, "\t/* magic */\n"); asm_emit_cell(f, FDT_MAGIC); fprintf(f, "\t/* totalsize */\n"); ASM_EMIT_BELONG(f, "_%s_blob_abs_end - _%s_blob_start", symprefix, symprefix); fprintf(f, "\t/* off_dt_struct */\n"); ASM_EMIT_BELONG(f, "_%s_struct_start - _%s_blob_start", symprefix, symprefix); fprintf(f, "\t/* off_dt_strings */\n"); ASM_EMIT_BELONG(f, "_%s_strings_start - _%s_blob_start", symprefix, symprefix); fprintf(f, "\t/* off_mem_rsvmap */\n"); ASM_EMIT_BELONG(f, "_%s_reserve_map - _%s_blob_start", symprefix, symprefix); fprintf(f, "\t/* version */\n"); asm_emit_cell(f, vi->version); fprintf(f, "\t/* last_comp_version */\n"); asm_emit_cell(f, vi->last_comp_version); if (vi->flags & FTF_BOOTCPUID) { fprintf(f, "\t/* boot_cpuid_phys */\n"); asm_emit_cell(f, bi->boot_cpuid_phys); } if (vi->flags & FTF_STRTABSIZE) { fprintf(f, "\t/* size_dt_strings */\n"); ASM_EMIT_BELONG(f, "_%s_strings_end - _%s_strings_start", symprefix, symprefix); } if (vi->flags & FTF_STRUCTSIZE) { fprintf(f, "\t/* size_dt_struct */\n"); ASM_EMIT_BELONG(f, "_%s_struct_end - _%s_struct_start", symprefix, symprefix); } /* * Reserve map entries. * Align the reserve map to a doubleword boundary. * Each entry is an (address, size) pair of u64 values. * Always supply a zero-sized temination entry. */ asm_emit_align(f, 8); emit_label(f, symprefix, "reserve_map"); fprintf(f, "/* Memory reserve map from source file */\n"); /* * Use .long on high and low halfs of u64s to avoid .quad * as it appears .quad isn't available in some assemblers. */ for (re = bi->reservelist; re; re = re->next) { struct label *l; for_each_label(re->labels, l) { fprintf(f, "\t.globl\t%s\n", l->label); fprintf(f, "%s:\n", l->label); } ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.address >> 32)); ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.address & 0xffffffff)); ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size >> 32)); ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size & 0xffffffff)); } for (i = 0; i < reservenum; i++) { fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n"); } fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n"); emit_label(f, symprefix, "struct_start"); flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi); fprintf(f, "\t/* FDT_END */\n"); asm_emit_cell(f, FDT_END); emit_label(f, symprefix, "struct_end"); emit_label(f, symprefix, "strings_start"); dump_stringtable_asm(f, strbuf); emit_label(f, symprefix, "strings_end"); emit_label(f, symprefix, "blob_end"); /* * If the user asked for more space than is used, pad it out. */ if (minsize > 0) { fprintf(f, "\t.space\t%d - (_%s_blob_end - _%s_blob_start), 0\n", minsize, symprefix, symprefix); } if (padsize > 0) { fprintf(f, "\t.space\t%d, 0\n", padsize); } emit_label(f, symprefix, "blob_abs_end"); data_free(strbuf); } struct inbuf { char *base, *limit, *ptr; }; static void inbuf_init(struct inbuf *inb, void *base, void *limit) { inb->base = base; inb->limit = limit; inb->ptr = inb->base; } static void flat_read_chunk(struct inbuf *inb, void *p, int len) { if ((inb->ptr + len) > inb->limit) die("Premature end of data parsing flat device tree\n"); memcpy(p, inb->ptr, len); inb->ptr += len; } static uint32_t flat_read_word(struct inbuf *inb) { uint32_t val; assert(((inb->ptr - inb->base) % sizeof(val)) == 0); flat_read_chunk(inb, &val, sizeof(val)); return fdt32_to_cpu(val); } static void flat_realign(struct inbuf *inb, int align) { int off = inb->ptr - inb->base; inb->ptr = inb->base + ALIGN(off, align); if (inb->ptr > inb->limit) die("Premature end of data parsing flat device tree\n"); } static char *flat_read_string(struct inbuf *inb) { int len = 0; const char *p = inb->ptr; char *str; do { if (p >= inb->limit) die("Premature end of data parsing flat device tree\n"); len++; } while ((*p++) != '\0'); str = xstrdup(inb->ptr); inb->ptr += len; flat_realign(inb, sizeof(uint32_t)); return str; } static struct data flat_read_data(struct inbuf *inb, int len) { struct data d = empty_data; if (len == 0) return empty_data; d = data_grow_for(d, len); d.len = len; flat_read_chunk(inb, d.val, len); flat_realign(inb, sizeof(uint32_t)); return d; } static char *flat_read_stringtable(struct inbuf *inb, int offset) { const char *p; p = inb->base + offset; while (1) { if (p >= inb->limit || p < inb->base) die("String offset %d overruns string table\n", offset); if (*p == '\0') break; p++; } return xstrdup(inb->base + offset); } static struct property *flat_read_property(struct inbuf *dtbuf, struct inbuf *strbuf, int flags) { uint32_t proplen, stroff; char *name; struct data val; proplen = flat_read_word(dtbuf); stroff = flat_read_word(dtbuf); name = flat_read_stringtable(strbuf, stroff); if ((flags & FTF_VARALIGN) && (proplen >= 8)) flat_realign(dtbuf, 8); val = flat_read_data(dtbuf, proplen); return build_property(name, val); } static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) { struct reserve_info *reservelist = NULL; struct reserve_info *new; struct fdt_reserve_entry re; /* * Each entry is a pair of u64 (addr, size) values for 4 cell_t's. * List terminates at an entry with size equal to zero. * * First pass, count entries. */ while (1) { flat_read_chunk(inb, &re, sizeof(re)); re.address = fdt64_to_cpu(re.address); re.size = fdt64_to_cpu(re.size); if (re.size == 0) break; new = build_reserve_entry(re.address, re.size); reservelist = add_reserve_entry(reservelist, new); } return reservelist; } static char *nodename_from_path(const char *ppath, const char *cpath) { int plen; plen = strlen(ppath); if (!strneq(ppath, cpath, plen)) die("Path \"%s\" is not valid as a child of \"%s\"\n", cpath, ppath); /* root node is a special case */ if (!streq(ppath, "/")) plen++; return xstrdup(cpath + plen); } static struct node *unflatten_tree(struct inbuf *dtbuf, struct inbuf *strbuf, const char *parent_flatname, int flags) { struct node *node; char *flatname; uint32_t val; node = build_node(NULL, NULL); flatname = flat_read_string(dtbuf); if (flags & FTF_FULLPATH) node->name = nodename_from_path(parent_flatname, flatname); else node->name = flatname; do { struct property *prop; struct node *child; val = flat_read_word(dtbuf); switch (val) { case FDT_PROP: if (node->children) fprintf(stderr, "Warning: Flat tree input has " "subnodes preceding a property.\n"); prop = flat_read_property(dtbuf, strbuf, flags); add_property(node, prop); break; case FDT_BEGIN_NODE: child = unflatten_tree(dtbuf,strbuf, flatname, flags); add_child(node, child); break; case FDT_END_NODE: break; case FDT_END: die("Premature FDT_END in device tree blob\n"); break; case FDT_NOP: if (!(flags & FTF_NOPS)) fprintf(stderr, "Warning: NOP tag found in flat tree" " version <16\n"); /* Ignore */ break; default: die("Invalid opcode word %08x in device tree blob\n", val); } } while (val != FDT_END_NODE); return node; } struct boot_info *dt_from_blob(const char *fname) { FILE *f; uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys; uint32_t off_dt, off_str, off_mem_rsvmap; int rc; char *blob; struct fdt_header *fdt; char *p; struct inbuf dtbuf, strbuf; struct inbuf memresvbuf; int sizeleft; struct reserve_info *reservelist; struct node *tree; uint32_t val; int flags = 0; f = srcfile_relative_open(fname, NULL); rc = fread(&magic, sizeof(magic), 1, f); if (ferror(f)) die("Error reading DT blob magic number: %s\n", strerror(errno)); if (rc < 1) { if (feof(f)) die("EOF reading DT blob magic number\n"); else die("Mysterious short read reading magic number\n"); } magic = fdt32_to_cpu(magic); if (magic != FDT_MAGIC) die("Blob has incorrect magic number\n"); rc = fread(&totalsize, sizeof(totalsize), 1, f); if (ferror(f)) die("Error reading DT blob size: %s\n", strerror(errno)); if (rc < 1) { if (feof(f)) die("EOF reading DT blob size\n"); else die("Mysterious short read reading blob size\n"); } totalsize = fdt32_to_cpu(totalsize); if (totalsize < FDT_V1_SIZE) die("DT blob size (%d) is too small\n", totalsize); blob = xmalloc(totalsize); fdt = (struct fdt_header *)blob; fdt->magic = cpu_to_fdt32(magic); fdt->totalsize = cpu_to_fdt32(totalsize); sizeleft = totalsize - sizeof(magic) - sizeof(totalsize); p = blob + sizeof(magic) + sizeof(totalsize); while (sizeleft) { if (feof(f)) die("EOF before reading %d bytes of DT blob\n", totalsize); rc = fread(p, 1, sizeleft, f); if (ferror(f)) die("Error reading DT blob: %s\n", strerror(errno)); sizeleft -= rc; p += rc; } off_dt = fdt32_to_cpu(fdt->off_dt_struct); off_str = fdt32_to_cpu(fdt->off_dt_strings); off_mem_rsvmap = fdt32_to_cpu(fdt->off_mem_rsvmap); version = fdt32_to_cpu(fdt->version); boot_cpuid_phys = fdt32_to_cpu(fdt->boot_cpuid_phys); if (off_mem_rsvmap >= totalsize) die("Mem Reserve structure offset exceeds total size\n"); if (off_dt >= totalsize) die("DT structure offset exceeds total size\n"); if (off_str > totalsize) die("String table offset exceeds total size\n"); if (version >= 3) { uint32_t size_str = fdt32_to_cpu(fdt->size_dt_strings); if (off_str+size_str > totalsize) die("String table extends past total size\n"); inbuf_init(&strbuf, blob + off_str, blob + off_str + size_str); } else { inbuf_init(&strbuf, blob + off_str, blob + totalsize); } if (version >= 17) { size_dt = fdt32_to_cpu(fdt->size_dt_struct); if (off_dt+size_dt > totalsize) die("Structure block extends past total size\n"); } if (version < 16) { flags |= FTF_FULLPATH | FTF_NAMEPROPS | FTF_VARALIGN; } else { flags |= FTF_NOPS; } inbuf_init(&memresvbuf, blob + off_mem_rsvmap, blob + totalsize); inbuf_init(&dtbuf, blob + off_dt, blob + totalsize); reservelist = flat_read_mem_reserve(&memresvbuf); val = flat_read_word(&dtbuf); if (val != FDT_BEGIN_NODE) die("Device tree blob doesn't begin with FDT_BEGIN_NODE (begins with 0x%08x)\n", val); tree = unflatten_tree(&dtbuf, &strbuf, "", flags); val = flat_read_word(&dtbuf); if (val != FDT_END) die("Device tree blob doesn't end with FDT_END\n"); free(blob); fclose(f); return build_boot_info(reservelist, tree, boot_cpuid_phys); } device-tree-compiler-1.4.0+dfsg.orig/dtc.h0000664000000000000000000001651612261525673015233 0ustar #ifndef _DTC_H #define _DTC_H /* * (C) Copyright David Gibson , IBM Corporation. 2005. * * * 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 #include #include #include #include #include #include #include #include #include #include #include #include "util.h" #ifdef DEBUG #define debug(fmt,args...) printf(fmt, ##args) #else #define debug(fmt,args...) #endif #define DEFAULT_FDT_VERSION 17 /* * Command line options */ extern int quiet; /* Level of quietness */ extern int reservenum; /* Number of memory reservation slots */ extern int minsize; /* Minimum blob size */ extern int padsize; /* Additional padding to blob */ extern int phandle_format; /* Use linux,phandle or phandle properties */ #define PHANDLE_LEGACY 0x1 #define PHANDLE_EPAPR 0x2 #define PHANDLE_BOTH 0x3 typedef uint32_t cell_t; #define streq(a, b) (strcmp((a), (b)) == 0) #define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) /* Data blobs */ enum markertype { REF_PHANDLE, REF_PATH, LABEL, }; struct marker { enum markertype type; int offset; char *ref; struct marker *next; }; struct data { int len; char *val; struct marker *markers; }; #define empty_data ((struct data){ /* all .members = 0 or NULL */ }) #define for_each_marker(m) \ for (; (m); (m) = (m)->next) #define for_each_marker_of_type(m, t) \ for_each_marker(m) \ if ((m)->type == (t)) void data_free(struct data d); struct data data_grow_for(struct data d, int xlen); struct data data_copy_mem(const char *mem, int len); struct data data_copy_escape_string(const char *s, int len); struct data data_copy_file(FILE *f, size_t len); struct data data_append_data(struct data d, const void *p, int len); struct data data_insert_at_marker(struct data d, struct marker *m, const void *p, int len); struct data data_merge(struct data d1, struct data d2); struct data data_append_cell(struct data d, cell_t word); struct data data_append_integer(struct data d, uint64_t word, int bits); struct data data_append_re(struct data d, const struct fdt_reserve_entry *re); struct data data_append_addr(struct data d, uint64_t addr); struct data data_append_byte(struct data d, uint8_t byte); struct data data_append_zeroes(struct data d, int len); struct data data_append_align(struct data d, int align); struct data data_add_marker(struct data d, enum markertype type, char *ref); int data_is_one_string(struct data d); /* DT constraints */ #define MAX_PROPNAME_LEN 31 #define MAX_NODENAME_LEN 31 /* Live trees */ struct label { int deleted; char *label; struct label *next; }; struct property { int deleted; char *name; struct data val; struct property *next; struct label *labels; }; struct node { int deleted; char *name; struct property *proplist; struct node *children; struct node *parent; struct node *next_sibling; char *fullpath; int basenamelen; cell_t phandle; int addr_cells, size_cells; struct label *labels; }; #define for_each_label_withdel(l0, l) \ for ((l) = (l0); (l); (l) = (l)->next) #define for_each_label(l0, l) \ for_each_label_withdel(l0, l) \ if (!(l)->deleted) #define for_each_property_withdel(n, p) \ for ((p) = (n)->proplist; (p); (p) = (p)->next) #define for_each_property(n, p) \ for_each_property_withdel(n, p) \ if (!(p)->deleted) #define for_each_child_withdel(n, c) \ for ((c) = (n)->children; (c); (c) = (c)->next_sibling) #define for_each_child(n, c) \ for_each_child_withdel(n, c) \ if (!(c)->deleted) void add_label(struct label **labels, char *label); void delete_labels(struct label **labels); struct property *build_property(char *name, struct data val); struct property *build_property_delete(char *name); struct property *chain_property(struct property *first, struct property *list); struct property *reverse_properties(struct property *first); struct node *build_node(struct property *proplist, struct node *children); struct node *build_node_delete(void); struct node *name_node(struct node *node, char *name); struct node *chain_node(struct node *first, struct node *list); struct node *merge_nodes(struct node *old_node, struct node *new_node); void add_property(struct node *node, struct property *prop); void delete_property_by_name(struct node *node, char *name); void delete_property(struct property *prop); void add_child(struct node *parent, struct node *child); void delete_node_by_name(struct node *parent, char *name); void delete_node(struct node *node); const char *get_unitname(struct node *node); struct property *get_property(struct node *node, const char *propname); cell_t propval_cell(struct property *prop); struct property *get_property_by_label(struct node *tree, const char *label, struct node **node); struct marker *get_marker_label(struct node *tree, const char *label, struct node **node, struct property **prop); struct node *get_subnode(struct node *node, const char *nodename); struct node *get_node_by_path(struct node *tree, const char *path); struct node *get_node_by_label(struct node *tree, const char *label); struct node *get_node_by_phandle(struct node *tree, cell_t phandle); struct node *get_node_by_ref(struct node *tree, const char *ref); cell_t get_node_phandle(struct node *root, struct node *node); uint32_t guess_boot_cpuid(struct node *tree); /* Boot info (tree plus memreserve information */ struct reserve_info { struct fdt_reserve_entry re; struct reserve_info *next; struct label *labels; }; struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len); struct reserve_info *chain_reserve_entry(struct reserve_info *first, struct reserve_info *list); struct reserve_info *add_reserve_entry(struct reserve_info *list, struct reserve_info *new); struct boot_info { struct reserve_info *reservelist; struct node *dt; /* the device tree */ uint32_t boot_cpuid_phys; }; struct boot_info *build_boot_info(struct reserve_info *reservelist, struct node *tree, uint32_t boot_cpuid_phys); void sort_tree(struct boot_info *bi); /* Checks */ void parse_checks_option(bool warn, bool error, const char *optarg); void process_checks(int force, struct boot_info *bi); /* Flattened trees */ void dt_to_blob(FILE *f, struct boot_info *bi, int version); void dt_to_asm(FILE *f, struct boot_info *bi, int version); struct boot_info *dt_from_blob(const char *fname); /* Tree source */ void dt_to_source(FILE *f, struct boot_info *bi); struct boot_info *dt_from_source(const char *f); /* FS trees */ struct boot_info *dt_from_fs(const char *dirname); #endif /* _DTC_H */ device-tree-compiler-1.4.0+dfsg.orig/dtdiff0000664000000000000000000000117412261525673015465 0ustar #! /bin/bash # This script uses the bash <(...) extension. # If you want to change this to work with a generic /bin/sh, make sure # you fix that. DTC=dtc source_and_sort () { DT="$1" if [ -d "$DT" ]; then IFORMAT=fs elif [ -f "$DT" ]; then case "$DT" in *.dts) IFORMAT=dts ;; *.dtb) IFORMAT=dtb ;; esac fi if [ -z "$IFORMAT" ]; then echo "Unrecognized format for $DT" >&2 exit 2 fi $DTC -I $IFORMAT -O dts -qq -f -s -o - "$DT" } if [ $# != 2 ]; then echo "Usage: dtdiff " >&2 exit 1 fi diff -u <(source_and_sort "$1") <(source_and_sort "$2") device-tree-compiler-1.4.0+dfsg.orig/fstree.c0000664000000000000000000000433612261525673015741 0ustar /* * (C) Copyright David Gibson , IBM Corporation. 2005. * * * 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 "dtc.h" #include #include static struct node *read_fstree(const char *dirname) { DIR *d; struct dirent *de; struct stat st; struct node *tree; d = opendir(dirname); if (!d) die("Couldn't opendir() \"%s\": %s\n", dirname, strerror(errno)); tree = build_node(NULL, NULL); while ((de = readdir(d)) != NULL) { char *tmpnam; if (streq(de->d_name, ".") || streq(de->d_name, "..")) continue; tmpnam = join_path(dirname, de->d_name); if (lstat(tmpnam, &st) < 0) die("stat(%s): %s\n", tmpnam, strerror(errno)); if (S_ISREG(st.st_mode)) { struct property *prop; FILE *pfile; pfile = fopen(tmpnam, "r"); if (! pfile) { fprintf(stderr, "WARNING: Cannot open %s: %s\n", tmpnam, strerror(errno)); } else { prop = build_property(xstrdup(de->d_name), data_copy_file(pfile, st.st_size)); add_property(tree, prop); fclose(pfile); } } else if (S_ISDIR(st.st_mode)) { struct node *newchild; newchild = read_fstree(tmpnam); newchild = name_node(newchild, xstrdup(de->d_name)); add_child(tree, newchild); } free(tmpnam); } closedir(d); return tree; } struct boot_info *dt_from_fs(const char *dirname) { struct node *tree; tree = read_fstree(dirname); tree = name_node(tree, ""); return build_boot_info(NULL, tree, guess_boot_cpuid(tree)); } device-tree-compiler-1.4.0+dfsg.orig/convert-dtsv0-lexer.l0000664000000000000000000001177212261525673020317 0ustar /* * (C) Copyright David Gibson , IBM Corporation. 2005, 2008. * * 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 */ %option noyywrap nounput noinput never-interactive %x INCLUDE %x BYTESTRING %x PROPNODENAME PROPNODECHAR [a-zA-Z0-9,._+*#?@-] PATHCHAR ({PROPNODECHAR}|[/]) LABEL [a-zA-Z_][a-zA-Z0-9_]* STRING \"([^\\"]|\\.)*\" WS [[:space:]] COMMENT "/*"([^*]|\*+[^*/])*\*+"/" LINECOMMENT "//".*\n GAP ({WS}|{COMMENT}|{LINECOMMENT})* %{ #include #include #include #include #include #include #include "srcpos.h" #include "util.h" static int v1_tagged; /* = 0 */ static int cbase = 16; static int saw_hyphen; /* = 0 */ static unsigned long long last_val; static char *last_name; /* = NULL */ const struct { const char *pattern; int obase, width; } guess_table[] = { { "*-frequency", 10, 0 }, { "num-*", 10, 0 }, { "#*-cells", 10, 0 }, { "*cache-line-size", 10, 0 }, { "*cache-block-size", 10, 0 }, { "*cache-size", 10, 0 }, { "*cache-sets", 10, 0 }, { "cell-index", 10, 0 }, { "bank-width", 10, 0 }, { "*-fifo-size", 10, 0 }, { "*-frame-size", 10, 0 }, { "*-channel", 10, 0 }, { "current-speed", 10, 0 }, { "phy-map", 16, 8 }, { "dcr-reg", 16, 3 }, { "reg", 16, 8 }, { "ranges", 16, 8}, }; %} %% <*>"/include/"{GAP}{STRING} ECHO; <*>\"([^\\"]|\\.)*\" ECHO; <*>"/dts-v1/" { die("Input dts file is already version 1\n"); } <*>"/memreserve/" { if (!v1_tagged) { fprintf(yyout, "/dts-v1/;\n\n"); v1_tagged = 1; } ECHO; BEGIN(INITIAL); } <*>{LABEL}: ECHO; [bodh]# { if (*yytext == 'b') cbase = 2; else if (*yytext == 'o') cbase = 8; else if (*yytext == 'd') cbase = 10; else cbase = 16; } [0-9a-fA-F]+ { unsigned long long val; int obase = 16, width = 0; int i; val = strtoull(yytext, NULL, cbase); if (saw_hyphen) val = val - last_val + 1; if (last_name) { for (i = 0; i < ARRAY_SIZE(guess_table); i++) if (fnmatch(guess_table[i].pattern, last_name, 0) == 0) { obase = guess_table[i].obase; width = guess_table[i].width; } } else { obase = 16; width = 16; } if (cbase != 16) obase = cbase; switch (obase) { case 2: case 16: fprintf(yyout, "0x%0*llx", width, val); break; case 8: fprintf(yyout, "0%0*llo", width, val); break; case 10: fprintf(yyout, "%*llu", width, val); break; } cbase = 16; last_val = val; saw_hyphen = 0; } \&{LABEL} ECHO; "&{/"{PATHCHAR}+\} ECHO; "&/"{PATHCHAR}+ fprintf(yyout, "&{/%s}", yytext + 2); [0-9a-fA-F]{2} ECHO; "]" { ECHO; BEGIN(INITIAL); } {PROPNODECHAR}+ { ECHO; last_name = xstrdup(yytext); BEGIN(INITIAL); } <*>{GAP} ECHO; <*>- { /* Hack to convert old style memreserves */ saw_hyphen = 1; fprintf(yyout, " "); } <*>. { if (!v1_tagged) { fprintf(yyout, "/dts-v1/;\n\n"); v1_tagged = 1; } ECHO; if (yytext[0] == '[') { BEGIN(BYTESTRING); } if ((yytext[0] == '{') || (yytext[0] == ';')) { BEGIN(PROPNODENAME); } } %% /* Usage related data. */ static const char usage_synopsis[] = "convert-dtsv0 [options] ..."; static const char usage_short_opts[] = "" USAGE_COMMON_SHORT_OPTS; static struct option const usage_long_opts[] = { USAGE_COMMON_LONG_OPTS }; static const char * const usage_opts_help[] = { USAGE_COMMON_OPTS_HELP }; static void convert_file(const char *fname) { const char suffix[] = "v1"; int len = strlen(fname); char *newname; newname = xmalloc(len + sizeof(suffix)); memcpy(newname, fname, len); memcpy(newname + len, suffix, sizeof(suffix)); yyin = fopen(fname, "r"); if (!yyin) die("Couldn't open input file %s: %s\n", fname, strerror(errno)); yyout = fopen(newname, "w"); if (!yyout) die("Couldn't open output file %s: %s\n", newname, strerror(errno)); while(yylex()) ; } int main(int argc, char *argv[]) { int opt; int i; while ((opt = util_getopt_long()) != EOF) { switch (opt) { case_USAGE_COMMON_FLAGS } } if (argc < 2) usage("missing filename"); for (i = 1; i < argc; i++) { fprintf(stderr, "Converting %s from dts v0 to dts v1\n", argv[i]); convert_file(argv[i]); } exit(0); } device-tree-compiler-1.4.0+dfsg.orig/GPL0000664000000000000000000004311012261525673014643 0ustar GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. device-tree-compiler-1.4.0+dfsg.orig/util.c0000664000000000000000000002132512261525674015424 0ustar /* * Copyright 2011 The Chromium Authors, All Rights Reserved. * Copyright 2008 Jon Loeliger, Freescale Semiconductor, Inc. * * util_is_printable_string contributed by * Pantelis Antoniou * * 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 #include #include #include #include #include #include #include #include #include "libfdt.h" #include "util.h" #include "version_gen.h" char *xstrdup(const char *s) { int len = strlen(s) + 1; char *dup = xmalloc(len); memcpy(dup, s, len); return dup; } char *join_path(const char *path, const char *name) { int lenp = strlen(path); int lenn = strlen(name); int len; int needslash = 1; char *str; len = lenp + lenn + 2; if ((lenp > 0) && (path[lenp-1] == '/')) { needslash = 0; len--; } str = xmalloc(len); memcpy(str, path, lenp); if (needslash) { str[lenp] = '/'; lenp++; } memcpy(str+lenp, name, lenn+1); return str; } int util_is_printable_string(const void *data, int len) { const char *s = data; const char *ss, *se; /* zero length is not */ if (len == 0) return 0; /* must terminate with zero */ if (s[len - 1] != '\0') return 0; se = s + len; while (s < se) { ss = s; while (s < se && *s && isprint(*s)) s++; /* not zero, or not done yet */ if (*s != '\0' || s == ss) return 0; s++; } return 1; } /* * Parse a octal encoded character starting at index i in string s. The * resulting character will be returned and the index i will be updated to * point at the character directly after the end of the encoding, this may be * the '\0' terminator of the string. */ static char get_oct_char(const char *s, int *i) { char x[4]; char *endx; long val; x[3] = '\0'; strncpy(x, s + *i, 3); val = strtol(x, &endx, 8); assert(endx > x); (*i) += endx - x; return val; } /* * Parse a hexadecimal encoded character starting at index i in string s. The * resulting character will be returned and the index i will be updated to * point at the character directly after the end of the encoding, this may be * the '\0' terminator of the string. */ static char get_hex_char(const char *s, int *i) { char x[3]; char *endx; long val; x[2] = '\0'; strncpy(x, s + *i, 2); val = strtol(x, &endx, 16); if (!(endx > x)) die("\\x used with no following hex digits\n"); (*i) += endx - x; return val; } char get_escape_char(const char *s, int *i) { char c = s[*i]; int j = *i + 1; char val; assert(c); switch (c) { case 'a': val = '\a'; break; case 'b': val = '\b'; break; case 't': val = '\t'; break; case 'n': val = '\n'; break; case 'v': val = '\v'; break; case 'f': val = '\f'; break; case 'r': val = '\r'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': j--; /* need to re-read the first digit as * part of the octal value */ val = get_oct_char(s, &j); break; case 'x': val = get_hex_char(s, &j); break; default: val = c; } (*i) = j; return val; } int utilfdt_read_err_len(const char *filename, char **buffp, off_t *len) { int fd = 0; /* assume stdin */ char *buf = NULL; off_t bufsize = 1024, offset = 0; int ret = 0; *buffp = NULL; if (strcmp(filename, "-") != 0) { fd = open(filename, O_RDONLY); if (fd < 0) return errno; } /* Loop until we have read everything */ buf = xmalloc(bufsize); do { /* Expand the buffer to hold the next chunk */ if (offset == bufsize) { bufsize *= 2; buf = xrealloc(buf, bufsize); if (!buf) { ret = ENOMEM; break; } } ret = read(fd, &buf[offset], bufsize - offset); if (ret < 0) { ret = errno; break; } offset += ret; } while (ret != 0); /* Clean up, including closing stdin; return errno on error */ close(fd); if (ret) free(buf); else *buffp = buf; *len = bufsize; return ret; } int utilfdt_read_err(const char *filename, char **buffp) { off_t len; return utilfdt_read_err_len(filename, buffp, &len); } char *utilfdt_read_len(const char *filename, off_t *len) { char *buff; int ret = utilfdt_read_err_len(filename, &buff, len); if (ret) { fprintf(stderr, "Couldn't open blob from '%s': %s\n", filename, strerror(ret)); return NULL; } /* Successful read */ return buff; } char *utilfdt_read(const char *filename) { off_t len; return utilfdt_read_len(filename, &len); } int utilfdt_write_err(const char *filename, const void *blob) { int fd = 1; /* assume stdout */ int totalsize; int offset; int ret = 0; const char *ptr = blob; if (strcmp(filename, "-") != 0) { fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666); if (fd < 0) return errno; } totalsize = fdt_totalsize(blob); offset = 0; while (offset < totalsize) { ret = write(fd, ptr + offset, totalsize - offset); if (ret < 0) { ret = -errno; break; } offset += ret; } /* Close the file/stdin; return errno on error */ if (fd != 1) close(fd); return ret < 0 ? -ret : 0; } int utilfdt_write(const char *filename, const void *blob) { int ret = utilfdt_write_err(filename, blob); if (ret) { fprintf(stderr, "Couldn't write blob to '%s': %s\n", filename, strerror(ret)); } return ret ? -1 : 0; } int utilfdt_decode_type(const char *fmt, int *type, int *size) { int qualifier = 0; if (!*fmt) return -1; /* get the conversion qualifier */ *size = -1; if (strchr("hlLb", *fmt)) { qualifier = *fmt++; if (qualifier == *fmt) { switch (*fmt++) { /* TODO: case 'l': qualifier = 'L'; break;*/ case 'h': qualifier = 'b'; break; } } } /* we should now have a type */ if ((*fmt == '\0') || !strchr("iuxs", *fmt)) return -1; /* convert qualifier (bhL) to byte size */ if (*fmt != 's') *size = qualifier == 'b' ? 1 : qualifier == 'h' ? 2 : qualifier == 'l' ? 4 : -1; *type = *fmt++; /* that should be it! */ if (*fmt) return -1; return 0; } void utilfdt_print_data(const char *data, int len) { int i; const char *p = data; const char *s; /* no data, don't print */ if (len == 0) return; if (util_is_printable_string(data, len)) { printf(" = "); s = data; do { printf("\"%s\"", s); s += strlen(s) + 1; if (s < data + len) printf(", "); } while (s < data + len); } else if ((len % 4) == 0) { const uint32_t *cell = (const uint32_t *)data; printf(" = <"); for (i = 0; i < len; i += 4) printf("0x%08x%s", fdt32_to_cpu(cell[i]), i < (len - 4) ? " " : ""); printf(">"); } else { printf(" = ["); for (i = 0; i < len; i++) printf("%02x%s", *p++, i < len - 1 ? " " : ""); printf("]"); } } void util_version(void) { printf("Version: %s\n", DTC_VERSION); exit(0); } void util_usage(const char *errmsg, const char *synopsis, const char *short_opts, struct option const long_opts[], const char * const opts_help[]) { FILE *fp = errmsg ? stderr : stdout; const char a_arg[] = ""; size_t a_arg_len = strlen(a_arg) + 1; size_t i; int optlen; fprintf(fp, "Usage: %s\n" "\n" "Options: -[%s]\n", synopsis, short_opts); /* prescan the --long opt length to auto-align */ optlen = 0; for (i = 0; long_opts[i].name; ++i) { /* +1 is for space between --opt and help text */ int l = strlen(long_opts[i].name) + 1; if (long_opts[i].has_arg == a_argument) l += a_arg_len; if (optlen < l) optlen = l; } for (i = 0; long_opts[i].name; ++i) { /* helps when adding new applets or options */ assert(opts_help[i] != NULL); /* first output the short flag if it has one */ if (long_opts[i].val > '~') fprintf(fp, " "); else fprintf(fp, " -%c, ", long_opts[i].val); /* then the long flag */ if (long_opts[i].has_arg == no_argument) fprintf(fp, "--%-*s", optlen, long_opts[i].name); else fprintf(fp, "--%s %s%*s", long_opts[i].name, a_arg, (int)(optlen - strlen(long_opts[i].name) - a_arg_len), ""); /* finally the help text */ fprintf(fp, "%s\n", opts_help[i]); } if (errmsg) { fprintf(fp, "\nError: %s\n", errmsg); exit(EXIT_FAILURE); } else exit(EXIT_SUCCESS); } device-tree-compiler-1.4.0+dfsg.orig/data.c0000664000000000000000000001222112261525673015352 0ustar /* * (C) Copyright David Gibson , IBM Corporation. 2005. * * * 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 "dtc.h" void data_free(struct data d) { struct marker *m, *nm; m = d.markers; while (m) { nm = m->next; free(m->ref); free(m); m = nm; } if (d.val) free(d.val); } struct data data_grow_for(struct data d, int xlen) { struct data nd; int newsize; if (xlen == 0) return d; nd = d; newsize = xlen; while ((d.len + xlen) > newsize) newsize *= 2; nd.val = xrealloc(d.val, newsize); return nd; } struct data data_copy_mem(const char *mem, int len) { struct data d; d = data_grow_for(empty_data, len); d.len = len; memcpy(d.val, mem, len); return d; } struct data data_copy_escape_string(const char *s, int len) { int i = 0; struct data d; char *q; d = data_grow_for(empty_data, strlen(s)+1); q = d.val; while (i < len) { char c = s[i++]; if (c == '\\') c = get_escape_char(s, &i); q[d.len++] = c; } q[d.len++] = '\0'; return d; } struct data data_copy_file(FILE *f, size_t maxlen) { struct data d = empty_data; while (!feof(f) && (d.len < maxlen)) { size_t chunksize, ret; if (maxlen == -1) chunksize = 4096; else chunksize = maxlen - d.len; d = data_grow_for(d, chunksize); ret = fread(d.val + d.len, 1, chunksize, f); if (ferror(f)) die("Error reading file into data: %s", strerror(errno)); if (d.len + ret < d.len) die("Overflow reading file into data\n"); d.len += ret; } return d; } struct data data_append_data(struct data d, const void *p, int len) { d = data_grow_for(d, len); memcpy(d.val + d.len, p, len); d.len += len; return d; } struct data data_insert_at_marker(struct data d, struct marker *m, const void *p, int len) { d = data_grow_for(d, len); memmove(d.val + m->offset + len, d.val + m->offset, d.len - m->offset); memcpy(d.val + m->offset, p, len); d.len += len; /* Adjust all markers after the one we're inserting at */ m = m->next; for_each_marker(m) m->offset += len; return d; } static struct data data_append_markers(struct data d, struct marker *m) { struct marker **mp = &d.markers; /* Find the end of the markerlist */ while (*mp) mp = &((*mp)->next); *mp = m; return d; } struct data data_merge(struct data d1, struct data d2) { struct data d; struct marker *m2 = d2.markers; d = data_append_markers(data_append_data(d1, d2.val, d2.len), m2); /* Adjust for the length of d1 */ for_each_marker(m2) m2->offset += d1.len; d2.markers = NULL; /* So data_free() doesn't clobber them */ data_free(d2); return d; } struct data data_append_integer(struct data d, uint64_t value, int bits) { uint8_t value_8; uint16_t value_16; uint32_t value_32; uint64_t value_64; switch (bits) { case 8: value_8 = value; return data_append_data(d, &value_8, 1); case 16: value_16 = cpu_to_fdt16(value); return data_append_data(d, &value_16, 2); case 32: value_32 = cpu_to_fdt32(value); return data_append_data(d, &value_32, 4); case 64: value_64 = cpu_to_fdt64(value); return data_append_data(d, &value_64, 8); default: die("Invalid literal size (%d)\n", bits); } } struct data data_append_re(struct data d, const struct fdt_reserve_entry *re) { struct fdt_reserve_entry bere; bere.address = cpu_to_fdt64(re->address); bere.size = cpu_to_fdt64(re->size); return data_append_data(d, &bere, sizeof(bere)); } struct data data_append_cell(struct data d, cell_t word) { return data_append_integer(d, word, sizeof(word) * 8); } struct data data_append_addr(struct data d, uint64_t addr) { return data_append_integer(d, addr, sizeof(addr) * 8); } struct data data_append_byte(struct data d, uint8_t byte) { return data_append_data(d, &byte, 1); } struct data data_append_zeroes(struct data d, int len) { d = data_grow_for(d, len); memset(d.val + d.len, 0, len); d.len += len; return d; } struct data data_append_align(struct data d, int align) { int newlen = ALIGN(d.len, align); return data_append_zeroes(d, newlen - d.len); } struct data data_add_marker(struct data d, enum markertype type, char *ref) { struct marker *m; m = xmalloc(sizeof(*m)); m->offset = d.len; m->type = type; m->ref = ref; m->next = NULL; return data_append_markers(d, m); } int data_is_one_string(struct data d) { int i; int len = d.len; if (len == 0) return 0; for (i = 0; i < len-1; i++) if (d.val[i] == '\0') return 0; if (d.val[len-1] != '\0') return 0; return 1; } device-tree-compiler-1.4.0+dfsg.orig/libfdt/0000775000000000000000000000000012261525673015543 5ustar device-tree-compiler-1.4.0+dfsg.orig/libfdt/fdt_rw.c0000664000000000000000000003124712261525673017203 0ustar /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. * * libfdt is dual licensed: you can use it either under the terms of * the GPL, or the BSD license, at your option. * * a) This library 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 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 General Public License for more details. * * You should have received a copy of the GNU 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 * * Alternatively, * * b) Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" #include #include #include "libfdt_internal.h" static int _fdt_blocks_misordered(const void *fdt, int mem_rsv_size, int struct_size) { return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8)) || (fdt_off_dt_struct(fdt) < (fdt_off_mem_rsvmap(fdt) + mem_rsv_size)) || (fdt_off_dt_strings(fdt) < (fdt_off_dt_struct(fdt) + struct_size)) || (fdt_totalsize(fdt) < (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); } static int _fdt_rw_check_header(void *fdt) { FDT_CHECK_HEADER(fdt); if (fdt_version(fdt) < 17) return -FDT_ERR_BADVERSION; if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry), fdt_size_dt_struct(fdt))) return -FDT_ERR_BADLAYOUT; if (fdt_version(fdt) > 17) fdt_set_version(fdt, 17); return 0; } #define FDT_RW_CHECK_HEADER(fdt) \ { \ int err; \ if ((err = _fdt_rw_check_header(fdt)) != 0) \ return err; \ } static inline int _fdt_data_size(void *fdt) { return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); } static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen) { char *p = splicepoint; char *end = (char *)fdt + _fdt_data_size(fdt); if (((p + oldlen) < p) || ((p + oldlen) > end)) return -FDT_ERR_BADOFFSET; if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt))) return -FDT_ERR_NOSPACE; memmove(p + newlen, p + oldlen, end - p - oldlen); return 0; } static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p, int oldn, int newn) { int delta = (newn - oldn) * sizeof(*p); int err; err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p)); if (err) return err; fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta); fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta); return 0; } static int _fdt_splice_struct(void *fdt, void *p, int oldlen, int newlen) { int delta = newlen - oldlen; int err; if ((err = _fdt_splice(fdt, p, oldlen, newlen))) return err; fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta); fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta); return 0; } static int _fdt_splice_string(void *fdt, int newlen) { void *p = (char *)fdt + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); int err; if ((err = _fdt_splice(fdt, p, 0, newlen))) return err; fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen); return 0; } static int _fdt_find_add_string(void *fdt, const char *s) { char *strtab = (char *)fdt + fdt_off_dt_strings(fdt); const char *p; char *new; int len = strlen(s) + 1; int err; p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s); if (p) /* found it */ return (p - strtab); new = strtab + fdt_size_dt_strings(fdt); err = _fdt_splice_string(fdt, len); if (err) return err; memcpy(new, s, len); return (new - strtab); } int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) { struct fdt_reserve_entry *re; int err; FDT_RW_CHECK_HEADER(fdt); re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt)); err = _fdt_splice_mem_rsv(fdt, re, 0, 1); if (err) return err; re->address = cpu_to_fdt64(address); re->size = cpu_to_fdt64(size); return 0; } int fdt_del_mem_rsv(void *fdt, int n) { struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n); int err; FDT_RW_CHECK_HEADER(fdt); if (n >= fdt_num_mem_rsv(fdt)) return -FDT_ERR_NOTFOUND; err = _fdt_splice_mem_rsv(fdt, re, 1, 0); if (err) return err; return 0; } static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name, int len, struct fdt_property **prop) { int oldlen; int err; *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); if (! (*prop)) return oldlen; if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), FDT_TAGALIGN(len)))) return err; (*prop)->len = cpu_to_fdt32(len); return 0; } static int _fdt_add_property(void *fdt, int nodeoffset, const char *name, int len, struct fdt_property **prop) { int proplen; int nextoffset; int namestroff; int err; if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0) return nextoffset; namestroff = _fdt_find_add_string(fdt, name); if (namestroff < 0) return namestroff; *prop = _fdt_offset_ptr_w(fdt, nextoffset); proplen = sizeof(**prop) + FDT_TAGALIGN(len); err = _fdt_splice_struct(fdt, *prop, 0, proplen); if (err) return err; (*prop)->tag = cpu_to_fdt32(FDT_PROP); (*prop)->nameoff = cpu_to_fdt32(namestroff); (*prop)->len = cpu_to_fdt32(len); return 0; } int fdt_set_name(void *fdt, int nodeoffset, const char *name) { char *namep; int oldlen, newlen; int err; FDT_RW_CHECK_HEADER(fdt); namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen); if (!namep) return oldlen; newlen = strlen(name); err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1), FDT_TAGALIGN(newlen+1)); if (err) return err; memcpy(namep, name, newlen+1); return 0; } int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val, int len) { struct fdt_property *prop; int err; FDT_RW_CHECK_HEADER(fdt); err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop); if (err == -FDT_ERR_NOTFOUND) err = _fdt_add_property(fdt, nodeoffset, name, len, &prop); if (err) return err; memcpy(prop->data, val, len); return 0; } int fdt_appendprop(void *fdt, int nodeoffset, const char *name, const void *val, int len) { struct fdt_property *prop; int err, oldlen, newlen; FDT_RW_CHECK_HEADER(fdt); prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); if (prop) { newlen = len + oldlen; err = _fdt_splice_struct(fdt, prop->data, FDT_TAGALIGN(oldlen), FDT_TAGALIGN(newlen)); if (err) return err; prop->len = cpu_to_fdt32(newlen); memcpy(prop->data + oldlen, val, len); } else { err = _fdt_add_property(fdt, nodeoffset, name, len, &prop); if (err) return err; memcpy(prop->data, val, len); } return 0; } int fdt_delprop(void *fdt, int nodeoffset, const char *name) { struct fdt_property *prop; int len, proplen; FDT_RW_CHECK_HEADER(fdt); prop = fdt_get_property_w(fdt, nodeoffset, name, &len); if (! prop) return len; proplen = sizeof(*prop) + FDT_TAGALIGN(len); return _fdt_splice_struct(fdt, prop, proplen, 0); } int fdt_add_subnode_namelen(void *fdt, int parentoffset, const char *name, int namelen) { struct fdt_node_header *nh; int offset, nextoffset; int nodelen; int err; uint32_t tag; fdt32_t *endtag; FDT_RW_CHECK_HEADER(fdt); offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); if (offset >= 0) return -FDT_ERR_EXISTS; else if (offset != -FDT_ERR_NOTFOUND) return offset; /* Try to place the new node after the parent's properties */ fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */ do { offset = nextoffset; tag = fdt_next_tag(fdt, offset, &nextoffset); } while ((tag == FDT_PROP) || (tag == FDT_NOP)); nh = _fdt_offset_ptr_w(fdt, offset); nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE; err = _fdt_splice_struct(fdt, nh, 0, nodelen); if (err) return err; nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); memset(nh->name, 0, FDT_TAGALIGN(namelen+1)); memcpy(nh->name, name, namelen); endtag = (fdt32_t *)((char *)nh + nodelen - FDT_TAGSIZE); *endtag = cpu_to_fdt32(FDT_END_NODE); return offset; } int fdt_add_subnode(void *fdt, int parentoffset, const char *name) { return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name)); } int fdt_del_node(void *fdt, int nodeoffset) { int endoffset; FDT_RW_CHECK_HEADER(fdt); endoffset = _fdt_node_end_offset(fdt, nodeoffset); if (endoffset < 0) return endoffset; return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset), endoffset - nodeoffset, 0); } static void _fdt_packblocks(const char *old, char *new, int mem_rsv_size, int struct_size) { int mem_rsv_off, struct_off, strings_off; mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8); struct_off = mem_rsv_off + mem_rsv_size; strings_off = struct_off + struct_size; memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size); fdt_set_off_mem_rsvmap(new, mem_rsv_off); memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size); fdt_set_off_dt_struct(new, struct_off); fdt_set_size_dt_struct(new, struct_size); memmove(new + strings_off, old + fdt_off_dt_strings(old), fdt_size_dt_strings(old)); fdt_set_off_dt_strings(new, strings_off); fdt_set_size_dt_strings(new, fdt_size_dt_strings(old)); } int fdt_open_into(const void *fdt, void *buf, int bufsize) { int err; int mem_rsv_size, struct_size; int newsize; const char *fdtstart = fdt; const char *fdtend = fdtstart + fdt_totalsize(fdt); char *tmp; FDT_CHECK_HEADER(fdt); mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) * sizeof(struct fdt_reserve_entry); if (fdt_version(fdt) >= 17) { struct_size = fdt_size_dt_struct(fdt); } else { struct_size = 0; while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END) ; if (struct_size < 0) return struct_size; } if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) { /* no further work necessary */ err = fdt_move(fdt, buf, bufsize); if (err) return err; fdt_set_version(buf, 17); fdt_set_size_dt_struct(buf, struct_size); fdt_set_totalsize(buf, bufsize); return 0; } /* Need to reorder */ newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size + struct_size + fdt_size_dt_strings(fdt); if (bufsize < newsize) return -FDT_ERR_NOSPACE; /* First attempt to build converted tree at beginning of buffer */ tmp = buf; /* But if that overlaps with the old tree... */ if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) { /* Try right after the old tree instead */ tmp = (char *)(uintptr_t)fdtend; if ((tmp + newsize) > ((char *)buf + bufsize)) return -FDT_ERR_NOSPACE; } _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size); memmove(buf, tmp, newsize); fdt_set_magic(buf, FDT_MAGIC); fdt_set_totalsize(buf, bufsize); fdt_set_version(buf, 17); fdt_set_last_comp_version(buf, 16); fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt)); return 0; } int fdt_pack(void *fdt) { int mem_rsv_size; FDT_RW_CHECK_HEADER(fdt); mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) * sizeof(struct fdt_reserve_entry); _fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); fdt_set_totalsize(fdt, _fdt_data_size(fdt)); return 0; } device-tree-compiler-1.4.0+dfsg.orig/libfdt/fdt_ro.c0000664000000000000000000003330312261525673017166 0ustar /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. * * libfdt is dual licensed: you can use it either under the terms of * the GPL, or the BSD license, at your option. * * a) This library 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 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 General Public License for more details. * * You should have received a copy of the GNU 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 * * Alternatively, * * b) Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" #include #include #include "libfdt_internal.h" static int _fdt_nodename_eq(const void *fdt, int offset, const char *s, int len) { const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1); if (! p) /* short match */ return 0; if (memcmp(p, s, len) != 0) return 0; if (p[len] == '\0') return 1; else if (!memchr(s, '@', len) && (p[len] == '@')) return 1; else return 0; } const char *fdt_string(const void *fdt, int stroffset) { return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; } static int _fdt_string_eq(const void *fdt, int stroffset, const char *s, int len) { const char *p = fdt_string(fdt, stroffset); return (strlen(p) == len) && (memcmp(p, s, len) == 0); } int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) { FDT_CHECK_HEADER(fdt); *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address); *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size); return 0; } int fdt_num_mem_rsv(const void *fdt) { int i = 0; while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0) i++; return i; } static int _nextprop(const void *fdt, int offset) { uint32_t tag; int nextoffset; do { tag = fdt_next_tag(fdt, offset, &nextoffset); switch (tag) { case FDT_END: if (nextoffset >= 0) return -FDT_ERR_BADSTRUCTURE; else return nextoffset; case FDT_PROP: return offset; } offset = nextoffset; } while (tag == FDT_NOP); return -FDT_ERR_NOTFOUND; } int fdt_subnode_offset_namelen(const void *fdt, int offset, const char *name, int namelen) { int depth; FDT_CHECK_HEADER(fdt); for (depth = 0; (offset >= 0) && (depth >= 0); offset = fdt_next_node(fdt, offset, &depth)) if ((depth == 1) && _fdt_nodename_eq(fdt, offset, name, namelen)) return offset; if (depth < 0) return -FDT_ERR_NOTFOUND; return offset; /* error */ } int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name) { return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name)); } int fdt_path_offset(const void *fdt, const char *path) { const char *end = path + strlen(path); const char *p = path; int offset = 0; FDT_CHECK_HEADER(fdt); /* see if we have an alias */ if (*path != '/') { const char *q = strchr(path, '/'); if (!q) q = end; p = fdt_get_alias_namelen(fdt, p, q - p); if (!p) return -FDT_ERR_BADPATH; offset = fdt_path_offset(fdt, p); p = q; } while (*p) { const char *q; while (*p == '/') p++; if (! *p) return offset; q = strchr(p, '/'); if (! q) q = end; offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p); if (offset < 0) return offset; p = q; } return offset; } const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) { const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset); int err; if (((err = fdt_check_header(fdt)) != 0) || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0)) goto fail; if (len) *len = strlen(nh->name); return nh->name; fail: if (len) *len = err; return NULL; } int fdt_first_property_offset(const void *fdt, int nodeoffset) { int offset; if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0) return offset; return _nextprop(fdt, offset); } int fdt_next_property_offset(const void *fdt, int offset) { if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0) return offset; return _nextprop(fdt, offset); } const struct fdt_property *fdt_get_property_by_offset(const void *fdt, int offset, int *lenp) { int err; const struct fdt_property *prop; if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) { if (lenp) *lenp = err; return NULL; } prop = _fdt_offset_ptr(fdt, offset); if (lenp) *lenp = fdt32_to_cpu(prop->len); return prop; } const struct fdt_property *fdt_get_property_namelen(const void *fdt, int offset, const char *name, int namelen, int *lenp) { for (offset = fdt_first_property_offset(fdt, offset); (offset >= 0); (offset = fdt_next_property_offset(fdt, offset))) { const struct fdt_property *prop; if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) { offset = -FDT_ERR_INTERNAL; break; } if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff), name, namelen)) return prop; } if (lenp) *lenp = offset; return NULL; } const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset, const char *name, int *lenp) { return fdt_get_property_namelen(fdt, nodeoffset, name, strlen(name), lenp); } const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, const char *name, int namelen, int *lenp) { const struct fdt_property *prop; prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp); if (! prop) return NULL; return prop->data; } const void *fdt_getprop_by_offset(const void *fdt, int offset, const char **namep, int *lenp) { const struct fdt_property *prop; prop = fdt_get_property_by_offset(fdt, offset, lenp); if (!prop) return NULL; if (namep) *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); return prop->data; } const void *fdt_getprop(const void *fdt, int nodeoffset, const char *name, int *lenp) { return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp); } uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) { const fdt32_t *php; int len; /* FIXME: This is a bit sub-optimal, since we potentially scan * over all the properties twice. */ php = fdt_getprop(fdt, nodeoffset, "phandle", &len); if (!php || (len != sizeof(*php))) { php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len); if (!php || (len != sizeof(*php))) return 0; } return fdt32_to_cpu(*php); } const char *fdt_get_alias_namelen(const void *fdt, const char *name, int namelen) { int aliasoffset; aliasoffset = fdt_path_offset(fdt, "/aliases"); if (aliasoffset < 0) return NULL; return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL); } const char *fdt_get_alias(const void *fdt, const char *name) { return fdt_get_alias_namelen(fdt, name, strlen(name)); } int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) { int pdepth = 0, p = 0; int offset, depth, namelen; const char *name; FDT_CHECK_HEADER(fdt); if (buflen < 2) return -FDT_ERR_NOSPACE; for (offset = 0, depth = 0; (offset >= 0) && (offset <= nodeoffset); offset = fdt_next_node(fdt, offset, &depth)) { while (pdepth > depth) { do { p--; } while (buf[p-1] != '/'); pdepth--; } if (pdepth >= depth) { name = fdt_get_name(fdt, offset, &namelen); if (!name) return namelen; if ((p + namelen + 1) <= buflen) { memcpy(buf + p, name, namelen); p += namelen; buf[p++] = '/'; pdepth++; } } if (offset == nodeoffset) { if (pdepth < (depth + 1)) return -FDT_ERR_NOSPACE; if (p > 1) /* special case so that root path is "/", not "" */ p--; buf[p] = '\0'; return 0; } } if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) return -FDT_ERR_BADOFFSET; else if (offset == -FDT_ERR_BADOFFSET) return -FDT_ERR_BADSTRUCTURE; return offset; /* error from fdt_next_node() */ } int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, int supernodedepth, int *nodedepth) { int offset, depth; int supernodeoffset = -FDT_ERR_INTERNAL; FDT_CHECK_HEADER(fdt); if (supernodedepth < 0) return -FDT_ERR_NOTFOUND; for (offset = 0, depth = 0; (offset >= 0) && (offset <= nodeoffset); offset = fdt_next_node(fdt, offset, &depth)) { if (depth == supernodedepth) supernodeoffset = offset; if (offset == nodeoffset) { if (nodedepth) *nodedepth = depth; if (supernodedepth > depth) return -FDT_ERR_NOTFOUND; else return supernodeoffset; } } if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) return -FDT_ERR_BADOFFSET; else if (offset == -FDT_ERR_BADOFFSET) return -FDT_ERR_BADSTRUCTURE; return offset; /* error from fdt_next_node() */ } int fdt_node_depth(const void *fdt, int nodeoffset) { int nodedepth; int err; err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth); if (err) return (err < 0) ? err : -FDT_ERR_INTERNAL; return nodedepth; } int fdt_parent_offset(const void *fdt, int nodeoffset) { int nodedepth = fdt_node_depth(fdt, nodeoffset); if (nodedepth < 0) return nodedepth; return fdt_supernode_atdepth_offset(fdt, nodeoffset, nodedepth - 1, NULL); } int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, const char *propname, const void *propval, int proplen) { int offset; const void *val; int len; FDT_CHECK_HEADER(fdt); /* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_getprop(), then if that didn't * find what we want, we scan over them again making our way * to the next node. Still it's the easiest to implement * approach; performance can come later. */ for (offset = fdt_next_node(fdt, startoffset, NULL); offset >= 0; offset = fdt_next_node(fdt, offset, NULL)) { val = fdt_getprop(fdt, offset, propname, &len); if (val && (len == proplen) && (memcmp(val, propval, len) == 0)) return offset; } return offset; /* error from fdt_next_node() */ } int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) { int offset; if ((phandle == 0) || (phandle == -1)) return -FDT_ERR_BADPHANDLE; FDT_CHECK_HEADER(fdt); /* FIXME: The algorithm here is pretty horrible: we * potentially scan each property of a node in * fdt_get_phandle(), then if that didn't find what * we want, we scan over them again making our way to the next * node. Still it's the easiest to implement approach; * performance can come later. */ for (offset = fdt_next_node(fdt, -1, NULL); offset >= 0; offset = fdt_next_node(fdt, offset, NULL)) { if (fdt_get_phandle(fdt, offset) == phandle) return offset; } return offset; /* error from fdt_next_node() */ } int fdt_stringlist_contains(const char *strlist, int listlen, const char *str) { int len = strlen(str); const char *p; while (listlen >= len) { if (memcmp(str, strlist, len+1) == 0) return 1; p = memchr(strlist, '\0', listlen); if (!p) return 0; /* malformed strlist.. */ listlen -= (p-strlist) + 1; strlist = p + 1; } return 0; } int fdt_node_check_compatible(const void *fdt, int nodeoffset, const char *compatible) { const void *prop; int len; prop = fdt_getprop(fdt, nodeoffset, "compatible", &len); if (!prop) return len; if (fdt_stringlist_contains(prop, len, compatible)) return 0; else return 1; } int fdt_node_offset_by_compatible(const void *fdt, int startoffset, const char *compatible) { int offset, err; FDT_CHECK_HEADER(fdt); /* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_node_check_compatible(), then if * that didn't find what we want, we scan over them again * making our way to the next node. Still it's the easiest to * implement approach; performance can come later. */ for (offset = fdt_next_node(fdt, startoffset, NULL); offset >= 0; offset = fdt_next_node(fdt, offset, NULL)) { err = fdt_node_check_compatible(fdt, offset, compatible); if ((err < 0) && (err != -FDT_ERR_NOTFOUND)) return err; else if (err == 0) return offset; } return offset; /* error from fdt_next_node() */ } device-tree-compiler-1.4.0+dfsg.orig/libfdt/fdt.c0000664000000000000000000001456212261525673016474 0ustar /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. * * libfdt is dual licensed: you can use it either under the terms of * the GPL, or the BSD license, at your option. * * a) This library 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 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 General Public License for more details. * * You should have received a copy of the GNU 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 * * Alternatively, * * b) Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" #include #include #include "libfdt_internal.h" int fdt_check_header(const void *fdt) { if (fdt_magic(fdt) == FDT_MAGIC) { /* Complete tree */ if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) return -FDT_ERR_BADVERSION; if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) return -FDT_ERR_BADVERSION; } else if (fdt_magic(fdt) == FDT_SW_MAGIC) { /* Unfinished sequential-write blob */ if (fdt_size_dt_struct(fdt) == 0) return -FDT_ERR_BADSTATE; } else { return -FDT_ERR_BADMAGIC; } return 0; } const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) { const char *p; if (fdt_version(fdt) >= 0x11) if (((offset + len) < offset) || ((offset + len) > fdt_size_dt_struct(fdt))) return NULL; p = _fdt_offset_ptr(fdt, offset); if (p + len < p) return NULL; return p; } uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) { const fdt32_t *tagp, *lenp; uint32_t tag; int offset = startoffset; const char *p; *nextoffset = -FDT_ERR_TRUNCATED; tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); if (!tagp) return FDT_END; /* premature end */ tag = fdt32_to_cpu(*tagp); offset += FDT_TAGSIZE; *nextoffset = -FDT_ERR_BADSTRUCTURE; switch (tag) { case FDT_BEGIN_NODE: /* skip name */ do { p = fdt_offset_ptr(fdt, offset++, 1); } while (p && (*p != '\0')); if (!p) return FDT_END; /* premature end */ break; case FDT_PROP: lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); if (!lenp) return FDT_END; /* premature end */ /* skip-name offset, length and value */ offset += sizeof(struct fdt_property) - FDT_TAGSIZE + fdt32_to_cpu(*lenp); break; case FDT_END: case FDT_END_NODE: case FDT_NOP: break; default: return FDT_END; } if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset)) return FDT_END; /* premature end */ *nextoffset = FDT_TAGALIGN(offset); return tag; } int _fdt_check_node_offset(const void *fdt, int offset) { if ((offset < 0) || (offset % FDT_TAGSIZE) || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE)) return -FDT_ERR_BADOFFSET; return offset; } int _fdt_check_prop_offset(const void *fdt, int offset) { if ((offset < 0) || (offset % FDT_TAGSIZE) || (fdt_next_tag(fdt, offset, &offset) != FDT_PROP)) return -FDT_ERR_BADOFFSET; return offset; } int fdt_next_node(const void *fdt, int offset, int *depth) { int nextoffset = 0; uint32_t tag; if (offset >= 0) if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0) return nextoffset; do { offset = nextoffset; tag = fdt_next_tag(fdt, offset, &nextoffset); switch (tag) { case FDT_PROP: case FDT_NOP: break; case FDT_BEGIN_NODE: if (depth) (*depth)++; break; case FDT_END_NODE: if (depth && ((--(*depth)) < 0)) return nextoffset; break; case FDT_END: if ((nextoffset >= 0) || ((nextoffset == -FDT_ERR_TRUNCATED) && !depth)) return -FDT_ERR_NOTFOUND; else return nextoffset; } } while (tag != FDT_BEGIN_NODE); return offset; } int fdt_first_subnode(const void *fdt, int offset) { int depth = 0; offset = fdt_next_node(fdt, offset, &depth); if (offset < 0 || depth != 1) return -FDT_ERR_NOTFOUND; return offset; } int fdt_next_subnode(const void *fdt, int offset) { int depth = 1; /* * With respect to the parent, the depth of the next subnode will be * the same as the last. */ do { offset = fdt_next_node(fdt, offset, &depth); if (offset < 0 || depth < 1) return -FDT_ERR_NOTFOUND; } while (depth > 1); return offset; } const char *_fdt_find_string(const char *strtab, int tabsize, const char *s) { int len = strlen(s) + 1; const char *last = strtab + tabsize - len; const char *p; for (p = strtab; p <= last; p++) if (memcmp(p, s, len) == 0) return p; return NULL; } int fdt_move(const void *fdt, void *buf, int bufsize) { FDT_CHECK_HEADER(fdt); if (fdt_totalsize(fdt) > bufsize) return -FDT_ERR_NOSPACE; memmove(buf, fdt, fdt_totalsize(fdt)); return 0; } device-tree-compiler-1.4.0+dfsg.orig/libfdt/Makefile.libfdt0000664000000000000000000000061212261525673020445 0ustar # Makefile.libfdt # # This is not a complete Makefile of itself. Instead, it is designed to # be easily embeddable into other systems of Makefiles. # LIBFDT_soname = libfdt.$(SHAREDLIB_EXT).1 LIBFDT_INCLUDES = fdt.h libfdt.h libfdt_env.h LIBFDT_VERSION = version.lds LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o) device-tree-compiler-1.4.0+dfsg.orig/libfdt/version.lds0000664000000000000000000000220412261525673017732 0ustar LIBFDT_1.2 { global: fdt_next_node; fdt_check_header; fdt_move; fdt_string; fdt_num_mem_rsv; fdt_get_mem_rsv; fdt_subnode_offset_namelen; fdt_subnode_offset; fdt_path_offset; fdt_get_name; fdt_get_property_namelen; fdt_get_property; fdt_getprop_namelen; fdt_getprop; fdt_get_phandle; fdt_get_alias_namelen; fdt_get_alias; fdt_get_path; fdt_supernode_atdepth_offset; fdt_node_depth; fdt_parent_offset; fdt_node_offset_by_prop_value; fdt_node_offset_by_phandle; fdt_node_check_compatible; fdt_node_offset_by_compatible; fdt_setprop_inplace; fdt_nop_property; fdt_nop_node; fdt_create; fdt_add_reservemap_entry; fdt_finish_reservemap; fdt_begin_node; fdt_property; fdt_end_node; fdt_finish; fdt_open_into; fdt_pack; fdt_add_mem_rsv; fdt_del_mem_rsv; fdt_set_name; fdt_setprop; fdt_delprop; fdt_add_subnode_namelen; fdt_add_subnode; fdt_del_node; fdt_strerror; fdt_offset_ptr; fdt_next_tag; fdt_appendprop; fdt_create_empty_tree; fdt_first_property_offset; fdt_get_property_by_offset; fdt_getprop_by_offset; fdt_next_property_offset; local: *; }; device-tree-compiler-1.4.0+dfsg.orig/libfdt/TODO0000664000000000000000000000012512261525673016231 0ustar - Tree traversal functions - Graft function - Complete libfdt.h documenting comments device-tree-compiler-1.4.0+dfsg.orig/libfdt/fdt_empty_tree.c0000664000000000000000000000552712261525673020732 0ustar /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2012 David Gibson, IBM Corporation. * * libfdt is dual licensed: you can use it either under the terms of * the GPL, or the BSD license, at your option. * * a) This library 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 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 General Public License for more details. * * You should have received a copy of the GNU 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 * * Alternatively, * * b) Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" #include #include #include "libfdt_internal.h" int fdt_create_empty_tree(void *buf, int bufsize) { int err; err = fdt_create(buf, bufsize); if (err) return err; err = fdt_finish_reservemap(buf); if (err) return err; err = fdt_begin_node(buf, ""); if (err) return err; err = fdt_end_node(buf); if (err) return err; err = fdt_finish(buf); if (err) return err; return fdt_open_into(buf, buf, bufsize); } device-tree-compiler-1.4.0+dfsg.orig/libfdt/fdt_strerror.c0000664000000000000000000000651112261525673020431 0ustar /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. * * libfdt is dual licensed: you can use it either under the terms of * the GPL, or the BSD license, at your option. * * a) This library 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 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 General Public License for more details. * * You should have received a copy of the GNU 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 * * Alternatively, * * b) Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" #include #include #include "libfdt_internal.h" struct fdt_errtabent { const char *str; }; #define FDT_ERRTABENT(val) \ [(val)] = { .str = #val, } static struct fdt_errtabent fdt_errtable[] = { FDT_ERRTABENT(FDT_ERR_NOTFOUND), FDT_ERRTABENT(FDT_ERR_EXISTS), FDT_ERRTABENT(FDT_ERR_NOSPACE), FDT_ERRTABENT(FDT_ERR_BADOFFSET), FDT_ERRTABENT(FDT_ERR_BADPATH), FDT_ERRTABENT(FDT_ERR_BADSTATE), FDT_ERRTABENT(FDT_ERR_TRUNCATED), FDT_ERRTABENT(FDT_ERR_BADMAGIC), FDT_ERRTABENT(FDT_ERR_BADVERSION), FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE), FDT_ERRTABENT(FDT_ERR_BADLAYOUT), }; #define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0])) const char *fdt_strerror(int errval) { if (errval > 0) return ""; else if (errval == 0) return ""; else if (errval > -FDT_ERRTABSIZE) { const char *s = fdt_errtable[-errval].str; if (s) return s; } return ""; } device-tree-compiler-1.4.0+dfsg.orig/libfdt/libfdt_env.h0000664000000000000000000000773612261525673020045 0ustar #ifndef _LIBFDT_ENV_H #define _LIBFDT_ENV_H /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. * Copyright 2012 Kim Phillips, Freescale Semiconductor. * * libfdt is dual licensed: you can use it either under the terms of * the GPL, or the BSD license, at your option. * * a) This library 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 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 General Public License for more details. * * You should have received a copy of the GNU 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 * * Alternatively, * * b) Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #ifdef __CHECKER__ #define __force __attribute__((force)) #define __bitwise __attribute__((bitwise)) #else #define __force #define __bitwise #endif typedef uint16_t __bitwise fdt16_t; typedef uint32_t __bitwise fdt32_t; typedef uint64_t __bitwise fdt64_t; #define EXTRACT_BYTE(x, n) ((unsigned long long)((uint8_t *)&x)[n]) #define CPU_TO_FDT16(x) ((EXTRACT_BYTE(x, 0) << 8) | EXTRACT_BYTE(x, 1)) #define CPU_TO_FDT32(x) ((EXTRACT_BYTE(x, 0) << 24) | (EXTRACT_BYTE(x, 1) << 16) | \ (EXTRACT_BYTE(x, 2) << 8) | EXTRACT_BYTE(x, 3)) #define CPU_TO_FDT64(x) ((EXTRACT_BYTE(x, 0) << 56) | (EXTRACT_BYTE(x, 1) << 48) | \ (EXTRACT_BYTE(x, 2) << 40) | (EXTRACT_BYTE(x, 3) << 32) | \ (EXTRACT_BYTE(x, 4) << 24) | (EXTRACT_BYTE(x, 5) << 16) | \ (EXTRACT_BYTE(x, 6) << 8) | EXTRACT_BYTE(x, 7)) static inline uint16_t fdt16_to_cpu(fdt16_t x) { return (__force uint16_t)CPU_TO_FDT16(x); } static inline fdt16_t cpu_to_fdt16(uint16_t x) { return (__force fdt16_t)CPU_TO_FDT16(x); } static inline uint32_t fdt32_to_cpu(fdt32_t x) { return (__force uint32_t)CPU_TO_FDT32(x); } static inline fdt32_t cpu_to_fdt32(uint32_t x) { return (__force fdt32_t)CPU_TO_FDT32(x); } static inline uint64_t fdt64_to_cpu(fdt64_t x) { return (__force uint64_t)CPU_TO_FDT64(x); } static inline fdt64_t cpu_to_fdt64(uint64_t x) { return (__force fdt64_t)CPU_TO_FDT64(x); } #undef CPU_TO_FDT64 #undef CPU_TO_FDT32 #undef CPU_TO_FDT16 #undef EXTRACT_BYTE #endif /* _LIBFDT_ENV_H */ device-tree-compiler-1.4.0+dfsg.orig/libfdt/libfdt.h0000664000000000000000000015543012261525673017170 0ustar #ifndef _LIBFDT_H #define _LIBFDT_H /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. * * libfdt is dual licensed: you can use it either under the terms of * the GPL, or the BSD license, at your option. * * a) This library 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 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 General Public License for more details. * * You should have received a copy of the GNU 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 * * Alternatively, * * b) Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #define FDT_FIRST_SUPPORTED_VERSION 0x10 #define FDT_LAST_SUPPORTED_VERSION 0x11 /* Error codes: informative error codes */ #define FDT_ERR_NOTFOUND 1 /* FDT_ERR_NOTFOUND: The requested node or property does not exist */ #define FDT_ERR_EXISTS 2 /* FDT_ERR_EXISTS: Attemped to create a node or property which * already exists */ #define FDT_ERR_NOSPACE 3 /* FDT_ERR_NOSPACE: Operation needed to expand the device * tree, but its buffer did not have sufficient space to * contain the expanded tree. Use fdt_open_into() to move the * device tree to a buffer with more space. */ /* Error codes: codes for bad parameters */ #define FDT_ERR_BADOFFSET 4 /* FDT_ERR_BADOFFSET: Function was passed a structure block * offset which is out-of-bounds, or which points to an * unsuitable part of the structure for the operation. */ #define FDT_ERR_BADPATH 5 /* FDT_ERR_BADPATH: Function was passed a badly formatted path * (e.g. missing a leading / for a function which requires an * absolute path) */ #define FDT_ERR_BADPHANDLE 6 /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle * value. phandle values of 0 and -1 are not permitted. */ #define FDT_ERR_BADSTATE 7 /* FDT_ERR_BADSTATE: Function was passed an incomplete device * tree created by the sequential-write functions, which is * not sufficiently complete for the requested operation. */ /* Error codes: codes for bad device tree blobs */ #define FDT_ERR_TRUNCATED 8 /* FDT_ERR_TRUNCATED: Structure block of the given device tree * ends without an FDT_END tag. */ #define FDT_ERR_BADMAGIC 9 /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a * device tree at all - it is missing the flattened device * tree magic number. */ #define FDT_ERR_BADVERSION 10 /* FDT_ERR_BADVERSION: Given device tree has a version which * can't be handled by the requested operation. For * read-write functions, this may mean that fdt_open_into() is * required to convert the tree to the expected version. */ #define FDT_ERR_BADSTRUCTURE 11 /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt * structure block or other serious error (e.g. misnested * nodes, or subnodes preceding properties). */ #define FDT_ERR_BADLAYOUT 12 /* FDT_ERR_BADLAYOUT: For read-write functions, the given * device tree has it's sub-blocks in an order that the * function can't handle (memory reserve map, then structure, * then strings). Use fdt_open_into() to reorganize the tree * into a form suitable for the read-write operations. */ /* "Can't happen" error indicating a bug in libfdt */ #define FDT_ERR_INTERNAL 13 /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion. * Should never be returned, if it is, it indicates a bug in * libfdt itself. */ #define FDT_ERR_MAX 13 /**********************************************************************/ /* Low-level functions (you probably don't need these) */ /**********************************************************************/ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen); static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) { return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen); } uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); /**********************************************************************/ /* Traversal functions */ /**********************************************************************/ int fdt_next_node(const void *fdt, int offset, int *depth); /** * fdt_first_subnode() - get offset of first direct subnode * * @fdt: FDT blob * @offset: Offset of node to check * @return offset of first subnode, or -FDT_ERR_NOTFOUND if there is none */ int fdt_first_subnode(const void *fdt, int offset); /** * fdt_next_subnode() - get offset of next direct subnode * * After first calling fdt_first_subnode(), call this function repeatedly to * get direct subnodes of a parent node. * * @fdt: FDT blob * @offset: Offset of previous subnode * @return offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more * subnodes */ int fdt_next_subnode(const void *fdt, int offset); /**********************************************************************/ /* General functions */ /**********************************************************************/ #define fdt_get_header(fdt, field) \ (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field)) #define fdt_magic(fdt) (fdt_get_header(fdt, magic)) #define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) #define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) #define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings)) #define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap)) #define fdt_version(fdt) (fdt_get_header(fdt, version)) #define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) #define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) #define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) #define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) #define __fdt_set_hdr(name) \ static inline void fdt_set_##name(void *fdt, uint32_t val) \ { \ struct fdt_header *fdth = (struct fdt_header*)fdt; \ fdth->name = cpu_to_fdt32(val); \ } __fdt_set_hdr(magic); __fdt_set_hdr(totalsize); __fdt_set_hdr(off_dt_struct); __fdt_set_hdr(off_dt_strings); __fdt_set_hdr(off_mem_rsvmap); __fdt_set_hdr(version); __fdt_set_hdr(last_comp_version); __fdt_set_hdr(boot_cpuid_phys); __fdt_set_hdr(size_dt_strings); __fdt_set_hdr(size_dt_struct); #undef __fdt_set_hdr /** * fdt_check_header - sanity check a device tree or possible device tree * @fdt: pointer to data which might be a flattened device tree * * fdt_check_header() checks that the given buffer contains what * appears to be a flattened device tree with sane information in its * header. * * returns: * 0, if the buffer appears to contain a valid device tree * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, standard meanings, as above */ int fdt_check_header(const void *fdt); /** * fdt_move - move a device tree around in memory * @fdt: pointer to the device tree to move * @buf: pointer to memory where the device is to be moved * @bufsize: size of the memory space at buf * * fdt_move() relocates, if possible, the device tree blob located at * fdt to the buffer at buf of size bufsize. The buffer may overlap * with the existing device tree blob at fdt. Therefore, * fdt_move(fdt, fdt, fdt_totalsize(fdt)) * should always succeed. * * returns: * 0, on success * -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, standard meanings */ int fdt_move(const void *fdt, void *buf, int bufsize); /**********************************************************************/ /* Read-only functions */ /**********************************************************************/ /** * fdt_string - retrieve a string from the strings block of a device tree * @fdt: pointer to the device tree blob * @stroffset: offset of the string within the strings block (native endian) * * fdt_string() retrieves a pointer to a single string from the * strings block of the device tree blob at fdt. * * returns: * a pointer to the string, on success * NULL, if stroffset is out of bounds */ const char *fdt_string(const void *fdt, int stroffset); /** * fdt_num_mem_rsv - retrieve the number of memory reserve map entries * @fdt: pointer to the device tree blob * * Returns the number of entries in the device tree blob's memory * reservation map. This does not include the terminating 0,0 entry * or any other (0,0) entries reserved for expansion. * * returns: * the number of entries */ int fdt_num_mem_rsv(const void *fdt); /** * fdt_get_mem_rsv - retrieve one memory reserve map entry * @fdt: pointer to the device tree blob * @address, @size: pointers to 64-bit variables * * On success, *address and *size will contain the address and size of * the n-th reserve map entry from the device tree blob, in * native-endian format. * * returns: * 0, on success * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, standard meanings */ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size); /** * fdt_subnode_offset_namelen - find a subnode based on substring * @fdt: pointer to the device tree blob * @parentoffset: structure block offset of a node * @name: name of the subnode to locate * @namelen: number of characters of name to consider * * Identical to fdt_subnode_offset(), but only examine the first * namelen characters of name for matching the subnode name. This is * useful for finding subnodes based on a portion of a larger string, * such as a full path. */ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, const char *name, int namelen); /** * fdt_subnode_offset - find a subnode of a given node * @fdt: pointer to the device tree blob * @parentoffset: structure block offset of a node * @name: name of the subnode to locate * * fdt_subnode_offset() finds a subnode of the node at structure block * offset parentoffset with the given name. name may include a unit * address, in which case fdt_subnode_offset() will find the subnode * with that unit address, or the unit address may be omitted, in * which case fdt_subnode_offset() will find an arbitrary subnode * whose name excluding unit address matches the given name. * * returns: * structure block offset of the requested subnode (>=0), on success * -FDT_ERR_NOTFOUND, if the requested subnode does not exist * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings. */ int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name); /** * fdt_path_offset - find a tree node by its full path * @fdt: pointer to the device tree blob * @path: full path of the node to locate * * fdt_path_offset() finds a node of a given path in the device tree. * Each path component may omit the unit address portion, but the * results of this are undefined if any such path component is * ambiguous (that is if there are multiple nodes at the relevant * level matching the given component, differentiated only by unit * address). * * returns: * structure block offset of the node with the requested path (>=0), on success * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid * -FDT_ERR_NOTFOUND, if the requested node does not exist * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings. */ int fdt_path_offset(const void *fdt, const char *path); /** * fdt_get_name - retrieve the name of a given node * @fdt: pointer to the device tree blob * @nodeoffset: structure block offset of the starting node * @lenp: pointer to an integer variable (will be overwritten) or NULL * * fdt_get_name() retrieves the name (including unit address) of the * device tree node at structure block offset nodeoffset. If lenp is * non-NULL, the length of this name is also returned, in the integer * pointed to by lenp. * * returns: * pointer to the node's name, on success * If lenp is non-NULL, *lenp contains the length of that name (>=0) * NULL, on error * if lenp is non-NULL *lenp contains an error code (<0): * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, standard meanings */ const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp); /** * fdt_first_property_offset - find the offset of a node's first property * @fdt: pointer to the device tree blob * @nodeoffset: structure block offset of a node * * fdt_first_property_offset() finds the first property of the node at * the given structure block offset. * * returns: * structure block offset of the property (>=0), on success * -FDT_ERR_NOTFOUND, if the requested node has no properties * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_BEGIN_NODE tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings. */ int fdt_first_property_offset(const void *fdt, int nodeoffset); /** * fdt_next_property_offset - step through a node's properties * @fdt: pointer to the device tree blob * @offset: structure block offset of a property * * fdt_next_property_offset() finds the property immediately after the * one at the given structure block offset. This will be a property * of the same node as the given property. * * returns: * structure block offset of the next property (>=0), on success * -FDT_ERR_NOTFOUND, if the given property is the last in its node * -FDT_ERR_BADOFFSET, if nodeoffset did not point to an FDT_PROP tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings. */ int fdt_next_property_offset(const void *fdt, int offset); /** * fdt_get_property_by_offset - retrieve the property at a given offset * @fdt: pointer to the device tree blob * @offset: offset of the property to retrieve * @lenp: pointer to an integer variable (will be overwritten) or NULL * * fdt_get_property_by_offset() retrieves a pointer to the * fdt_property structure within the device tree blob at the given * offset. If lenp is non-NULL, the length of the property value is * also returned, in the integer pointed to by lenp. * * returns: * pointer to the structure representing the property * if lenp is non-NULL, *lenp contains the length of the property * value (>=0) * NULL, on error * if lenp is non-NULL, *lenp contains an error code (<0): * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings */ const struct fdt_property *fdt_get_property_by_offset(const void *fdt, int offset, int *lenp); /** * fdt_get_property_namelen - find a property based on substring * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to find * @name: name of the property to find * @namelen: number of characters of name to consider * @lenp: pointer to an integer variable (will be overwritten) or NULL * * Identical to fdt_get_property_namelen(), but only examine the first * namelen characters of name for matching the property name. */ const struct fdt_property *fdt_get_property_namelen(const void *fdt, int nodeoffset, const char *name, int namelen, int *lenp); /** * fdt_get_property - find a given property in a given node * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to find * @name: name of the property to find * @lenp: pointer to an integer variable (will be overwritten) or NULL * * fdt_get_property() retrieves a pointer to the fdt_property * structure within the device tree blob corresponding to the property * named 'name' of the node at offset nodeoffset. If lenp is * non-NULL, the length of the property value is also returned, in the * integer pointed to by lenp. * * returns: * pointer to the structure representing the property * if lenp is non-NULL, *lenp contains the length of the property * value (>=0) * NULL, on error * if lenp is non-NULL, *lenp contains an error code (<0): * -FDT_ERR_NOTFOUND, node does not have named property * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings */ const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset, const char *name, int *lenp); static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, const char *name, int *lenp) { return (struct fdt_property *)(uintptr_t) fdt_get_property(fdt, nodeoffset, name, lenp); } /** * fdt_getprop_by_offset - retrieve the value of a property at a given offset * @fdt: pointer to the device tree blob * @ffset: offset of the property to read * @namep: pointer to a string variable (will be overwritten) or NULL * @lenp: pointer to an integer variable (will be overwritten) or NULL * * fdt_getprop_by_offset() retrieves a pointer to the value of the * property at structure block offset 'offset' (this will be a pointer * to within the device blob itself, not a copy of the value). If * lenp is non-NULL, the length of the property value is also * returned, in the integer pointed to by lenp. If namep is non-NULL, * the property's namne will also be returned in the char * pointed to * by namep (this will be a pointer to within the device tree's string * block, not a new copy of the name). * * returns: * pointer to the property's value * if lenp is non-NULL, *lenp contains the length of the property * value (>=0) * if namep is non-NULL *namep contiains a pointer to the property * name. * NULL, on error * if lenp is non-NULL, *lenp contains an error code (<0): * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_PROP tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings */ const void *fdt_getprop_by_offset(const void *fdt, int offset, const char **namep, int *lenp); /** * fdt_getprop_namelen - get property value based on substring * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to find * @name: name of the property to find * @namelen: number of characters of name to consider * @lenp: pointer to an integer variable (will be overwritten) or NULL * * Identical to fdt_getprop(), but only examine the first namelen * characters of name for matching the property name. */ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, const char *name, int namelen, int *lenp); /** * fdt_getprop - retrieve the value of a given property * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to find * @name: name of the property to find * @lenp: pointer to an integer variable (will be overwritten) or NULL * * fdt_getprop() retrieves a pointer to the value of the property * named 'name' of the node at offset nodeoffset (this will be a * pointer to within the device blob itself, not a copy of the value). * If lenp is non-NULL, the length of the property value is also * returned, in the integer pointed to by lenp. * * returns: * pointer to the property's value * if lenp is non-NULL, *lenp contains the length of the property * value (>=0) * NULL, on error * if lenp is non-NULL, *lenp contains an error code (<0): * -FDT_ERR_NOTFOUND, node does not have named property * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings */ const void *fdt_getprop(const void *fdt, int nodeoffset, const char *name, int *lenp); static inline void *fdt_getprop_w(void *fdt, int nodeoffset, const char *name, int *lenp) { return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp); } /** * fdt_get_phandle - retrieve the phandle of a given node * @fdt: pointer to the device tree blob * @nodeoffset: structure block offset of the node * * fdt_get_phandle() retrieves the phandle of the device tree node at * structure block offset nodeoffset. * * returns: * the phandle of the node at nodeoffset, on success (!= 0, != -1) * 0, if the node has no phandle, or another error occurs */ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); /** * fdt_get_alias_namelen - get alias based on substring * @fdt: pointer to the device tree blob * @name: name of the alias th look up * @namelen: number of characters of name to consider * * Identical to fdt_get_alias(), but only examine the first namelen * characters of name for matching the alias name. */ const char *fdt_get_alias_namelen(const void *fdt, const char *name, int namelen); /** * fdt_get_alias - retreive the path referenced by a given alias * @fdt: pointer to the device tree blob * @name: name of the alias th look up * * fdt_get_alias() retrieves the value of a given alias. That is, the * value of the property named 'name' in the node /aliases. * * returns: * a pointer to the expansion of the alias named 'name', if it exists * NULL, if the given alias or the /aliases node does not exist */ const char *fdt_get_alias(const void *fdt, const char *name); /** * fdt_get_path - determine the full path of a node * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose path to find * @buf: character buffer to contain the returned path (will be overwritten) * @buflen: size of the character buffer at buf * * fdt_get_path() computes the full path of the node at offset * nodeoffset, and records that path in the buffer at buf. * * NOTE: This function is expensive, as it must scan the device tree * structure from the start to nodeoffset. * * returns: * 0, on success * buf contains the absolute path of the node at * nodeoffset, as a NUL-terminated string. * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1) * characters and will not fit in the given buffer. * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, standard meanings */ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen); /** * fdt_supernode_atdepth_offset - find a specific ancestor of a node * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose parent to find * @supernodedepth: depth of the ancestor to find * @nodedepth: pointer to an integer variable (will be overwritten) or NULL * * fdt_supernode_atdepth_offset() finds an ancestor of the given node * at a specific depth from the root (where the root itself has depth * 0, its immediate subnodes depth 1 and so forth). So * fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL); * will always return 0, the offset of the root node. If the node at * nodeoffset has depth D, then: * fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL); * will return nodeoffset itself. * * NOTE: This function is expensive, as it must scan the device tree * structure from the start to nodeoffset. * * returns: * structure block offset of the node at node offset's ancestor * of depth supernodedepth (>=0), on success * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag * -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, standard meanings */ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, int supernodedepth, int *nodedepth); /** * fdt_node_depth - find the depth of a given node * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose parent to find * * fdt_node_depth() finds the depth of a given node. The root node * has depth 0, its immediate subnodes depth 1 and so forth. * * NOTE: This function is expensive, as it must scan the device tree * structure from the start to nodeoffset. * * returns: * depth of the node at nodeoffset (>=0), on success * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, standard meanings */ int fdt_node_depth(const void *fdt, int nodeoffset); /** * fdt_parent_offset - find the parent of a given node * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose parent to find * * fdt_parent_offset() locates the parent node of a given node (that * is, it finds the offset of the node which contains the node at * nodeoffset as a subnode). * * NOTE: This function is expensive, as it must scan the device tree * structure from the start to nodeoffset, *twice*. * * returns: * structure block offset of the parent of the node at nodeoffset * (>=0), on success * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, standard meanings */ int fdt_parent_offset(const void *fdt, int nodeoffset); /** * fdt_node_offset_by_prop_value - find nodes with a given property value * @fdt: pointer to the device tree blob * @startoffset: only find nodes after this offset * @propname: property name to check * @propval: property value to search for * @proplen: length of the value in propval * * fdt_node_offset_by_prop_value() returns the offset of the first * node after startoffset, which has a property named propname whose * value is of length proplen and has value equal to propval; or if * startoffset is -1, the very first such node in the tree. * * To iterate through all nodes matching the criterion, the following * idiom can be used: * offset = fdt_node_offset_by_prop_value(fdt, -1, propname, * propval, proplen); * while (offset != -FDT_ERR_NOTFOUND) { * // other code here * offset = fdt_node_offset_by_prop_value(fdt, offset, propname, * propval, proplen); * } * * Note the -1 in the first call to the function, if 0 is used here * instead, the function will never locate the root node, even if it * matches the criterion. * * returns: * structure block offset of the located node (>= 0, >startoffset), * on success * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the * tree after startoffset * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, standard meanings */ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, const char *propname, const void *propval, int proplen); /** * fdt_node_offset_by_phandle - find the node with a given phandle * @fdt: pointer to the device tree blob * @phandle: phandle value * * fdt_node_offset_by_phandle() returns the offset of the node * which has the given phandle value. If there is more than one node * in the tree with the given phandle (an invalid tree), results are * undefined. * * returns: * structure block offset of the located node (>= 0), on success * -FDT_ERR_NOTFOUND, no node with that phandle exists * -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1) * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, standard meanings */ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle); /** * fdt_node_check_compatible: check a node's compatible property * @fdt: pointer to the device tree blob * @nodeoffset: offset of a tree node * @compatible: string to match against * * * fdt_node_check_compatible() returns 0 if the given node contains a * 'compatible' property with the given string as one of its elements, * it returns non-zero otherwise, or on error. * * returns: * 0, if the node has a 'compatible' property listing the given string * 1, if the node has a 'compatible' property, but it does not list * the given string * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, standard meanings */ int fdt_node_check_compatible(const void *fdt, int nodeoffset, const char *compatible); /** * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value * @fdt: pointer to the device tree blob * @startoffset: only find nodes after this offset * @compatible: 'compatible' string to match against * * fdt_node_offset_by_compatible() returns the offset of the first * node after startoffset, which has a 'compatible' property which * lists the given compatible string; or if startoffset is -1, the * very first such node in the tree. * * To iterate through all nodes matching the criterion, the following * idiom can be used: * offset = fdt_node_offset_by_compatible(fdt, -1, compatible); * while (offset != -FDT_ERR_NOTFOUND) { * // other code here * offset = fdt_node_offset_by_compatible(fdt, offset, compatible); * } * * Note the -1 in the first call to the function, if 0 is used here * instead, the function will never locate the root node, even if it * matches the criterion. * * returns: * structure block offset of the located node (>= 0, >startoffset), * on success * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the * tree after startoffset * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, standard meanings */ int fdt_node_offset_by_compatible(const void *fdt, int startoffset, const char *compatible); /** * fdt_stringlist_contains - check a string list property for a string * @strlist: Property containing a list of strings to check * @listlen: Length of property * @str: String to search for * * This is a utility function provided for convenience. The list contains * one or more strings, each terminated by \0, as is found in a device tree * "compatible" property. * * @return: 1 if the string is found in the list, 0 not found, or invalid list */ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str); /**********************************************************************/ /* Write-in-place functions */ /**********************************************************************/ /** * fdt_setprop_inplace - change a property's value, but not its size * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to change * @name: name of the property to change * @val: pointer to data to replace the property value with * @len: length of the property value * * fdt_setprop_inplace() replaces the value of a given property with * the data in val, of length len. This function cannot change the * size of a property, and so will only work if len is equal to the * current length of the property. * * This function will alter only the bytes in the blob which contain * the given property value, and will not alter or move any other part * of the tree. * * returns: * 0, on success * -FDT_ERR_NOSPACE, if len is not equal to the property's current length * -FDT_ERR_NOTFOUND, node does not have the named property * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings */ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, const void *val, int len); /** * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to change * @name: name of the property to change * @val: 32-bit integer value to replace the property with * * fdt_setprop_inplace_u32() replaces the value of a given property * with the 32-bit integer value in val, converting val to big-endian * if necessary. This function cannot change the size of a property, * and so will only work if the property already exists and has length * 4. * * This function will alter only the bytes in the blob which contain * the given property value, and will not alter or move any other part * of the tree. * * returns: * 0, on success * -FDT_ERR_NOSPACE, if the property's length is not equal to 4 * -FDT_ERR_NOTFOUND, node does not have the named property * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings */ static inline int fdt_setprop_inplace_u32(void *fdt, int nodeoffset, const char *name, uint32_t val) { fdt32_t tmp = cpu_to_fdt32(val); return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp)); } /** * fdt_setprop_inplace_u64 - change the value of a 64-bit integer property * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to change * @name: name of the property to change * @val: 64-bit integer value to replace the property with * * fdt_setprop_inplace_u64() replaces the value of a given property * with the 64-bit integer value in val, converting val to big-endian * if necessary. This function cannot change the size of a property, * and so will only work if the property already exists and has length * 8. * * This function will alter only the bytes in the blob which contain * the given property value, and will not alter or move any other part * of the tree. * * returns: * 0, on success * -FDT_ERR_NOSPACE, if the property's length is not equal to 8 * -FDT_ERR_NOTFOUND, node does not have the named property * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings */ static inline int fdt_setprop_inplace_u64(void *fdt, int nodeoffset, const char *name, uint64_t val) { fdt64_t tmp = cpu_to_fdt64(val); return fdt_setprop_inplace(fdt, nodeoffset, name, &tmp, sizeof(tmp)); } /** * fdt_setprop_inplace_cell - change the value of a single-cell property * * This is an alternative name for fdt_setprop_inplace_u32() */ static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset, const char *name, uint32_t val) { return fdt_setprop_inplace_u32(fdt, nodeoffset, name, val); } /** * fdt_nop_property - replace a property with nop tags * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to nop * @name: name of the property to nop * * fdt_nop_property() will replace a given property's representation * in the blob with FDT_NOP tags, effectively removing it from the * tree. * * This function will alter only the bytes in the blob which contain * the property, and will not alter or move any other part of the * tree. * * returns: * 0, on success * -FDT_ERR_NOTFOUND, node does not have the named property * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings */ int fdt_nop_property(void *fdt, int nodeoffset, const char *name); /** * fdt_nop_node - replace a node (subtree) with nop tags * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node to nop * * fdt_nop_node() will replace a given node's representation in the * blob, including all its subnodes, if any, with FDT_NOP tags, * effectively removing it from the tree. * * This function will alter only the bytes in the blob which contain * the node and its properties and subnodes, and will not alter or * move any other part of the tree. * * returns: * 0, on success * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings */ int fdt_nop_node(void *fdt, int nodeoffset); /**********************************************************************/ /* Sequential write functions */ /**********************************************************************/ int fdt_create(void *buf, int bufsize); int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size); int fdt_finish_reservemap(void *fdt); int fdt_begin_node(void *fdt, const char *name); int fdt_property(void *fdt, const char *name, const void *val, int len); static inline int fdt_property_u32(void *fdt, const char *name, uint32_t val) { fdt32_t tmp = cpu_to_fdt32(val); return fdt_property(fdt, name, &tmp, sizeof(tmp)); } static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val) { fdt64_t tmp = cpu_to_fdt64(val); return fdt_property(fdt, name, &tmp, sizeof(tmp)); } static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) { return fdt_property_u32(fdt, name, val); } #define fdt_property_string(fdt, name, str) \ fdt_property(fdt, name, str, strlen(str)+1) int fdt_end_node(void *fdt); int fdt_finish(void *fdt); /**********************************************************************/ /* Read-write functions */ /**********************************************************************/ int fdt_create_empty_tree(void *buf, int bufsize); int fdt_open_into(const void *fdt, void *buf, int bufsize); int fdt_pack(void *fdt); /** * fdt_add_mem_rsv - add one memory reserve map entry * @fdt: pointer to the device tree blob * @address, @size: 64-bit values (native endian) * * Adds a reserve map entry to the given blob reserving a region at * address address of length size. * * This function will insert data into the reserve map and will * therefore change the indexes of some entries in the table. * * returns: * 0, on success * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to * contain the new reservation entry * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_BADLAYOUT, * -FDT_ERR_TRUNCATED, standard meanings */ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size); /** * fdt_del_mem_rsv - remove a memory reserve map entry * @fdt: pointer to the device tree blob * @n: entry to remove * * fdt_del_mem_rsv() removes the n-th memory reserve map entry from * the blob. * * This function will delete data from the reservation table and will * therefore change the indexes of some entries in the table. * * returns: * 0, on success * -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there * are less than n+1 reserve map entries) * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_BADLAYOUT, * -FDT_ERR_TRUNCATED, standard meanings */ int fdt_del_mem_rsv(void *fdt, int n); /** * fdt_set_name - change the name of a given node * @fdt: pointer to the device tree blob * @nodeoffset: structure block offset of a node * @name: name to give the node * * fdt_set_name() replaces the name (including unit address, if any) * of the given node with the given string. NOTE: this function can't * efficiently check if the new name is unique amongst the given * node's siblings; results are undefined if this function is invoked * with a name equal to one of the given node's siblings. * * This function may insert or delete data from the blob, and will * therefore change the offsets of some existing nodes. * * returns: * 0, on success * -FDT_ERR_NOSPACE, there is insufficient free space in the blob * to contain the new name * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, standard meanings */ int fdt_set_name(void *fdt, int nodeoffset, const char *name); /** * fdt_setprop - create or change a property * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to change * @name: name of the property to change * @val: pointer to data to set the property value to * @len: length of the property value * * fdt_setprop() sets the value of the named property in the given * node to the given value and length, creating the property if it * does not already exist. * * This function may insert or delete data from the blob, and will * therefore change the offsets of some existing nodes. * * returns: * 0, on success * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to * contain the new property value * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADLAYOUT, * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_BADLAYOUT, * -FDT_ERR_TRUNCATED, standard meanings */ int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val, int len); /** * fdt_setprop_u32 - set a property to a 32-bit integer * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to change * @name: name of the property to change * @val: 32-bit integer value for the property (native endian) * * fdt_setprop_u32() sets the value of the named property in the given * node to the given 32-bit integer value (converting to big-endian if * necessary), or creates a new property with that value if it does * not already exist. * * This function may insert or delete data from the blob, and will * therefore change the offsets of some existing nodes. * * returns: * 0, on success * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to * contain the new property value * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADLAYOUT, * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_BADLAYOUT, * -FDT_ERR_TRUNCATED, standard meanings */ static inline int fdt_setprop_u32(void *fdt, int nodeoffset, const char *name, uint32_t val) { fdt32_t tmp = cpu_to_fdt32(val); return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); } /** * fdt_setprop_u64 - set a property to a 64-bit integer * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to change * @name: name of the property to change * @val: 64-bit integer value for the property (native endian) * * fdt_setprop_u64() sets the value of the named property in the given * node to the given 64-bit integer value (converting to big-endian if * necessary), or creates a new property with that value if it does * not already exist. * * This function may insert or delete data from the blob, and will * therefore change the offsets of some existing nodes. * * returns: * 0, on success * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to * contain the new property value * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADLAYOUT, * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_BADLAYOUT, * -FDT_ERR_TRUNCATED, standard meanings */ static inline int fdt_setprop_u64(void *fdt, int nodeoffset, const char *name, uint64_t val) { fdt64_t tmp = cpu_to_fdt64(val); return fdt_setprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); } /** * fdt_setprop_cell - set a property to a single cell value * * This is an alternative name for fdt_setprop_u32() */ static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, uint32_t val) { return fdt_setprop_u32(fdt, nodeoffset, name, val); } /** * fdt_setprop_string - set a property to a string value * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to change * @name: name of the property to change * @str: string value for the property * * fdt_setprop_string() sets the value of the named property in the * given node to the given string value (using the length of the * string to determine the new length of the property), or creates a * new property with that value if it does not already exist. * * This function may insert or delete data from the blob, and will * therefore change the offsets of some existing nodes. * * returns: * 0, on success * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to * contain the new property value * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADLAYOUT, * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_BADLAYOUT, * -FDT_ERR_TRUNCATED, standard meanings */ #define fdt_setprop_string(fdt, nodeoffset, name, str) \ fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) /** * fdt_appendprop - append to or create a property * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to change * @name: name of the property to append to * @val: pointer to data to append to the property value * @len: length of the data to append to the property value * * fdt_appendprop() appends the value to the named property in the * given node, creating the property if it does not already exist. * * This function may insert data into the blob, and will therefore * change the offsets of some existing nodes. * * returns: * 0, on success * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to * contain the new property value * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADLAYOUT, * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_BADLAYOUT, * -FDT_ERR_TRUNCATED, standard meanings */ int fdt_appendprop(void *fdt, int nodeoffset, const char *name, const void *val, int len); /** * fdt_appendprop_u32 - append a 32-bit integer value to a property * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to change * @name: name of the property to change * @val: 32-bit integer value to append to the property (native endian) * * fdt_appendprop_u32() appends the given 32-bit integer value * (converting to big-endian if necessary) to the value of the named * property in the given node, or creates a new property with that * value if it does not already exist. * * This function may insert data into the blob, and will therefore * change the offsets of some existing nodes. * * returns: * 0, on success * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to * contain the new property value * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADLAYOUT, * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_BADLAYOUT, * -FDT_ERR_TRUNCATED, standard meanings */ static inline int fdt_appendprop_u32(void *fdt, int nodeoffset, const char *name, uint32_t val) { fdt32_t tmp = cpu_to_fdt32(val); return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); } /** * fdt_appendprop_u64 - append a 64-bit integer value to a property * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to change * @name: name of the property to change * @val: 64-bit integer value to append to the property (native endian) * * fdt_appendprop_u64() appends the given 64-bit integer value * (converting to big-endian if necessary) to the value of the named * property in the given node, or creates a new property with that * value if it does not already exist. * * This function may insert data into the blob, and will therefore * change the offsets of some existing nodes. * * returns: * 0, on success * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to * contain the new property value * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADLAYOUT, * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_BADLAYOUT, * -FDT_ERR_TRUNCATED, standard meanings */ static inline int fdt_appendprop_u64(void *fdt, int nodeoffset, const char *name, uint64_t val) { fdt64_t tmp = cpu_to_fdt64(val); return fdt_appendprop(fdt, nodeoffset, name, &tmp, sizeof(tmp)); } /** * fdt_appendprop_cell - append a single cell value to a property * * This is an alternative name for fdt_appendprop_u32() */ static inline int fdt_appendprop_cell(void *fdt, int nodeoffset, const char *name, uint32_t val) { return fdt_appendprop_u32(fdt, nodeoffset, name, val); } /** * fdt_appendprop_string - append a string to a property * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to change * @name: name of the property to change * @str: string value to append to the property * * fdt_appendprop_string() appends the given string to the value of * the named property in the given node, or creates a new property * with that value if it does not already exist. * * This function may insert data into the blob, and will therefore * change the offsets of some existing nodes. * * returns: * 0, on success * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to * contain the new property value * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADLAYOUT, * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_BADLAYOUT, * -FDT_ERR_TRUNCATED, standard meanings */ #define fdt_appendprop_string(fdt, nodeoffset, name, str) \ fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) /** * fdt_delprop - delete a property * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to nop * @name: name of the property to nop * * fdt_del_property() will delete the given property. * * This function will delete data from the blob, and will therefore * change the offsets of some existing nodes. * * returns: * 0, on success * -FDT_ERR_NOTFOUND, node does not have the named property * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADLAYOUT, * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings */ int fdt_delprop(void *fdt, int nodeoffset, const char *name); /** * fdt_add_subnode_namelen - creates a new node based on substring * @fdt: pointer to the device tree blob * @parentoffset: structure block offset of a node * @name: name of the subnode to locate * @namelen: number of characters of name to consider * * Identical to fdt_add_subnode(), but use only the first namelen * characters of name as the name of the new node. This is useful for * creating subnodes based on a portion of a larger string, such as a * full path. */ int fdt_add_subnode_namelen(void *fdt, int parentoffset, const char *name, int namelen); /** * fdt_add_subnode - creates a new node * @fdt: pointer to the device tree blob * @parentoffset: structure block offset of a node * @name: name of the subnode to locate * * fdt_add_subnode() creates a new node as a subnode of the node at * structure block offset parentoffset, with the given name (which * should include the unit address, if any). * * This function will insert data into the blob, and will therefore * change the offsets of some existing nodes. * returns: * structure block offset of the created nodeequested subnode (>=0), on success * -FDT_ERR_NOTFOUND, if the requested subnode does not exist * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag * -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of * the given name * -FDT_ERR_NOSPACE, if there is insufficient free space in the * blob to contain the new node * -FDT_ERR_NOSPACE * -FDT_ERR_BADLAYOUT * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings. */ int fdt_add_subnode(void *fdt, int parentoffset, const char *name); /** * fdt_del_node - delete a node (subtree) * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node to nop * * fdt_del_node() will remove the given node, including all its * subnodes if any, from the blob. * * This function will delete data from the blob, and will therefore * change the offsets of some existing nodes. * * returns: * 0, on success * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag * -FDT_ERR_BADLAYOUT, * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, * -FDT_ERR_BADSTATE, * -FDT_ERR_BADSTRUCTURE, * -FDT_ERR_TRUNCATED, standard meanings */ int fdt_del_node(void *fdt, int nodeoffset); /**********************************************************************/ /* Debugging / informational functions */ /**********************************************************************/ const char *fdt_strerror(int errval); #endif /* _LIBFDT_H */ device-tree-compiler-1.4.0+dfsg.orig/libfdt/libfdt_internal.h0000664000000000000000000000712412261525673021060 0ustar #ifndef _LIBFDT_INTERNAL_H #define _LIBFDT_INTERNAL_H /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. * * libfdt is dual licensed: you can use it either under the terms of * the GPL, or the BSD license, at your option. * * a) This library 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 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 General Public License for more details. * * You should have received a copy of the GNU 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 * * Alternatively, * * b) Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) #define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE)) #define FDT_CHECK_HEADER(fdt) \ { \ int err; \ if ((err = fdt_check_header(fdt)) != 0) \ return err; \ } int _fdt_check_node_offset(const void *fdt, int offset); int _fdt_check_prop_offset(const void *fdt, int offset); const char *_fdt_find_string(const char *strtab, int tabsize, const char *s); int _fdt_node_end_offset(void *fdt, int nodeoffset); static inline const void *_fdt_offset_ptr(const void *fdt, int offset) { return (const char *)fdt + fdt_off_dt_struct(fdt) + offset; } static inline void *_fdt_offset_ptr_w(void *fdt, int offset) { return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset); } static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n) { const struct fdt_reserve_entry *rsv_table = (const struct fdt_reserve_entry *) ((const char *)fdt + fdt_off_mem_rsvmap(fdt)); return rsv_table + n; } static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n) { return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n); } #define FDT_SW_MAGIC (~FDT_MAGIC) #endif /* _LIBFDT_INTERNAL_H */ device-tree-compiler-1.4.0+dfsg.orig/libfdt/fdt_sw.c0000664000000000000000000001575612261525673017213 0ustar /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. * * libfdt is dual licensed: you can use it either under the terms of * the GPL, or the BSD license, at your option. * * a) This library 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 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 General Public License for more details. * * You should have received a copy of the GNU 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 * * Alternatively, * * b) Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" #include #include #include "libfdt_internal.h" static int _fdt_sw_check_header(void *fdt) { if (fdt_magic(fdt) != FDT_SW_MAGIC) return -FDT_ERR_BADMAGIC; /* FIXME: should check more details about the header state */ return 0; } #define FDT_SW_CHECK_HEADER(fdt) \ { \ int err; \ if ((err = _fdt_sw_check_header(fdt)) != 0) \ return err; \ } static void *_fdt_grab_space(void *fdt, size_t len) { int offset = fdt_size_dt_struct(fdt); int spaceleft; spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt) - fdt_size_dt_strings(fdt); if ((offset + len < offset) || (offset + len > spaceleft)) return NULL; fdt_set_size_dt_struct(fdt, offset + len); return _fdt_offset_ptr_w(fdt, offset); } int fdt_create(void *buf, int bufsize) { void *fdt = buf; if (bufsize < sizeof(struct fdt_header)) return -FDT_ERR_NOSPACE; memset(buf, 0, bufsize); fdt_set_magic(fdt, FDT_SW_MAGIC); fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION); fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION); fdt_set_totalsize(fdt, bufsize); fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header), sizeof(struct fdt_reserve_entry))); fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt)); fdt_set_off_dt_strings(fdt, bufsize); return 0; } int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size) { struct fdt_reserve_entry *re; int offset; FDT_SW_CHECK_HEADER(fdt); if (fdt_size_dt_struct(fdt)) return -FDT_ERR_BADSTATE; offset = fdt_off_dt_struct(fdt); if ((offset + sizeof(*re)) > fdt_totalsize(fdt)) return -FDT_ERR_NOSPACE; re = (struct fdt_reserve_entry *)((char *)fdt + offset); re->address = cpu_to_fdt64(addr); re->size = cpu_to_fdt64(size); fdt_set_off_dt_struct(fdt, offset + sizeof(*re)); return 0; } int fdt_finish_reservemap(void *fdt) { return fdt_add_reservemap_entry(fdt, 0, 0); } int fdt_begin_node(void *fdt, const char *name) { struct fdt_node_header *nh; int namelen = strlen(name) + 1; FDT_SW_CHECK_HEADER(fdt); nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen)); if (! nh) return -FDT_ERR_NOSPACE; nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); memcpy(nh->name, name, namelen); return 0; } int fdt_end_node(void *fdt) { fdt32_t *en; FDT_SW_CHECK_HEADER(fdt); en = _fdt_grab_space(fdt, FDT_TAGSIZE); if (! en) return -FDT_ERR_NOSPACE; *en = cpu_to_fdt32(FDT_END_NODE); return 0; } static int _fdt_find_add_string(void *fdt, const char *s) { char *strtab = (char *)fdt + fdt_totalsize(fdt); const char *p; int strtabsize = fdt_size_dt_strings(fdt); int len = strlen(s) + 1; int struct_top, offset; p = _fdt_find_string(strtab - strtabsize, strtabsize, s); if (p) return p - strtab; /* Add it */ offset = -strtabsize - len; struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); if (fdt_totalsize(fdt) + offset < struct_top) return 0; /* no more room :( */ memcpy(strtab + offset, s, len); fdt_set_size_dt_strings(fdt, strtabsize + len); return offset; } int fdt_property(void *fdt, const char *name, const void *val, int len) { struct fdt_property *prop; int nameoff; FDT_SW_CHECK_HEADER(fdt); nameoff = _fdt_find_add_string(fdt, name); if (nameoff == 0) return -FDT_ERR_NOSPACE; prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len)); if (! prop) return -FDT_ERR_NOSPACE; prop->tag = cpu_to_fdt32(FDT_PROP); prop->nameoff = cpu_to_fdt32(nameoff); prop->len = cpu_to_fdt32(len); memcpy(prop->data, val, len); return 0; } int fdt_finish(void *fdt) { char *p = (char *)fdt; fdt32_t *end; int oldstroffset, newstroffset; uint32_t tag; int offset, nextoffset; FDT_SW_CHECK_HEADER(fdt); /* Add terminator */ end = _fdt_grab_space(fdt, sizeof(*end)); if (! end) return -FDT_ERR_NOSPACE; *end = cpu_to_fdt32(FDT_END); /* Relocate the string table */ oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt); newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt)); fdt_set_off_dt_strings(fdt, newstroffset); /* Walk the structure, correcting string offsets */ offset = 0; while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) { if (tag == FDT_PROP) { struct fdt_property *prop = _fdt_offset_ptr_w(fdt, offset); int nameoff; nameoff = fdt32_to_cpu(prop->nameoff); nameoff += fdt_size_dt_strings(fdt); prop->nameoff = cpu_to_fdt32(nameoff); } offset = nextoffset; } if (nextoffset < 0) return nextoffset; /* Finally, adjust the header */ fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt)); fdt_set_magic(fdt, FDT_MAGIC); return 0; } device-tree-compiler-1.4.0+dfsg.orig/libfdt/fdt_wip.c0000664000000000000000000000712412261525673017347 0ustar /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. * * libfdt is dual licensed: you can use it either under the terms of * the GPL, or the BSD license, at your option. * * a) This library 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 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 General Public License for more details. * * You should have received a copy of the GNU 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 * * Alternatively, * * b) Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" #include #include #include "libfdt_internal.h" int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, const void *val, int len) { void *propval; int proplen; propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen); if (! propval) return proplen; if (proplen != len) return -FDT_ERR_NOSPACE; memcpy(propval, val, len); return 0; } static void _fdt_nop_region(void *start, int len) { fdt32_t *p; for (p = start; (char *)p < ((char *)start + len); p++) *p = cpu_to_fdt32(FDT_NOP); } int fdt_nop_property(void *fdt, int nodeoffset, const char *name) { struct fdt_property *prop; int len; prop = fdt_get_property_w(fdt, nodeoffset, name, &len); if (! prop) return len; _fdt_nop_region(prop, len + sizeof(*prop)); return 0; } int _fdt_node_end_offset(void *fdt, int offset) { int depth = 0; while ((offset >= 0) && (depth >= 0)) offset = fdt_next_node(fdt, offset, &depth); return offset; } int fdt_nop_node(void *fdt, int nodeoffset) { int endoffset; endoffset = _fdt_node_end_offset(fdt, nodeoffset); if (endoffset < 0) return endoffset; _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0), endoffset - nodeoffset); return 0; } device-tree-compiler-1.4.0+dfsg.orig/libfdt/fdt.h0000664000000000000000000000766612261525673016510 0ustar #ifndef _FDT_H #define _FDT_H /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. * Copyright 2012 Kim Phillips, Freescale Semiconductor. * * libfdt is dual licensed: you can use it either under the terms of * the GPL, or the BSD license, at your option. * * a) This library 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 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 General Public License for more details. * * You should have received a copy of the GNU 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 * * Alternatively, * * b) Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ASSEMBLY__ struct fdt_header { fdt32_t magic; /* magic word FDT_MAGIC */ fdt32_t totalsize; /* total size of DT block */ fdt32_t off_dt_struct; /* offset to structure */ fdt32_t off_dt_strings; /* offset to strings */ fdt32_t off_mem_rsvmap; /* offset to memory reserve map */ fdt32_t version; /* format version */ fdt32_t last_comp_version; /* last compatible version */ /* version 2 fields below */ fdt32_t boot_cpuid_phys; /* Which physical CPU id we're booting on */ /* version 3 fields below */ fdt32_t size_dt_strings; /* size of the strings block */ /* version 17 fields below */ fdt32_t size_dt_struct; /* size of the structure block */ }; struct fdt_reserve_entry { fdt64_t address; fdt64_t size; }; struct fdt_node_header { fdt32_t tag; char name[0]; }; struct fdt_property { fdt32_t tag; fdt32_t len; fdt32_t nameoff; char data[0]; }; #endif /* !__ASSEMBLY */ #define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ #define FDT_TAGSIZE sizeof(fdt32_t) #define FDT_BEGIN_NODE 0x1 /* Start node: full name */ #define FDT_END_NODE 0x2 /* End node */ #define FDT_PROP 0x3 /* Property: name off, size, content */ #define FDT_NOP 0x4 /* nop */ #define FDT_END 0x9 #define FDT_V1_SIZE (7*sizeof(fdt32_t)) #define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t)) #define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t)) #define FDT_V16_SIZE FDT_V3_SIZE #define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t)) #endif /* _FDT_H */ device-tree-compiler-1.4.0+dfsg.orig/.gitignore0000664000000000000000000000020212261525673016261 0ustar *.o *.d *.a *.patch *.so *~ *.tab.[ch] lex.yy.c *.lex.c /dtc /fdtdump /convert-dtsv0 /version_gen.h /fdtget /fdtput /patches /.pc device-tree-compiler-1.4.0+dfsg.orig/fdtdump.c0000664000000000000000000001257312261525673016116 0ustar /* * fdtdump.c - Contributed by Pantelis Antoniou */ #include #include #include #include #include #include #include #include #include #include "util.h" #define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) #define PALIGN(p, a) ((void *)(ALIGN((unsigned long)(p), (a)))) #define GET_CELL(p) (p += 4, *((const uint32_t *)(p-4))) static const char *tagname(uint32_t tag) { static const char * const names[] = { #define TN(t) [t] #t TN(FDT_BEGIN_NODE), TN(FDT_END_NODE), TN(FDT_PROP), TN(FDT_NOP), TN(FDT_END), #undef TN }; if (tag < ARRAY_SIZE(names)) if (names[tag]) return names[tag]; return "FDT_???"; } #define dumpf(fmt, args...) \ do { if (debug) printf("// " fmt, ## args); } while (0) static void dump_blob(void *blob, bool debug) { uintptr_t blob_off = (uintptr_t)blob; struct fdt_header *bph = blob; uint32_t off_mem_rsvmap = fdt32_to_cpu(bph->off_mem_rsvmap); uint32_t off_dt = fdt32_to_cpu(bph->off_dt_struct); uint32_t off_str = fdt32_to_cpu(bph->off_dt_strings); struct fdt_reserve_entry *p_rsvmap = (struct fdt_reserve_entry *)((char *)blob + off_mem_rsvmap); const char *p_struct = (const char *)blob + off_dt; const char *p_strings = (const char *)blob + off_str; uint32_t version = fdt32_to_cpu(bph->version); uint32_t totalsize = fdt32_to_cpu(bph->totalsize); uint32_t tag; const char *p, *s, *t; int depth, sz, shift; int i; uint64_t addr, size; depth = 0; shift = 4; printf("/dts-v1/;\n"); printf("// magic:\t\t0x%x\n", fdt32_to_cpu(bph->magic)); printf("// totalsize:\t\t0x%x (%d)\n", totalsize, totalsize); printf("// off_dt_struct:\t0x%x\n", off_dt); printf("// off_dt_strings:\t0x%x\n", off_str); printf("// off_mem_rsvmap:\t0x%x\n", off_mem_rsvmap); printf("// version:\t\t%d\n", version); printf("// last_comp_version:\t%d\n", fdt32_to_cpu(bph->last_comp_version)); if (version >= 2) printf("// boot_cpuid_phys:\t0x%x\n", fdt32_to_cpu(bph->boot_cpuid_phys)); if (version >= 3) printf("// size_dt_strings:\t0x%x\n", fdt32_to_cpu(bph->size_dt_strings)); if (version >= 17) printf("// size_dt_struct:\t0x%x\n", fdt32_to_cpu(bph->size_dt_struct)); printf("\n"); for (i = 0; ; i++) { addr = fdt64_to_cpu(p_rsvmap[i].address); size = fdt64_to_cpu(p_rsvmap[i].size); if (addr == 0 && size == 0) break; printf("/memreserve/ %llx %llx;\n", (unsigned long long)addr, (unsigned long long)size); } p = p_struct; while ((tag = fdt32_to_cpu(GET_CELL(p))) != FDT_END) { dumpf("%04zx: tag: 0x%08x (%s)\n", (uintptr_t)p - blob_off - 4, tag, tagname(tag)); if (tag == FDT_BEGIN_NODE) { s = p; p = PALIGN(p + strlen(s) + 1, 4); if (*s == '\0') s = "/"; printf("%*s%s {\n", depth * shift, "", s); depth++; continue; } if (tag == FDT_END_NODE) { depth--; printf("%*s};\n", depth * shift, ""); continue; } if (tag == FDT_NOP) { printf("%*s// [NOP]\n", depth * shift, ""); continue; } if (tag != FDT_PROP) { fprintf(stderr, "%*s ** Unknown tag 0x%08x\n", depth * shift, "", tag); break; } sz = fdt32_to_cpu(GET_CELL(p)); s = p_strings + fdt32_to_cpu(GET_CELL(p)); if (version < 16 && sz >= 8) p = PALIGN(p, 8); t = p; p = PALIGN(p + sz, 4); dumpf("%04zx: string: %s\n", (uintptr_t)s - blob_off, s); dumpf("%04zx: value\n", (uintptr_t)t - blob_off); printf("%*s%s", depth * shift, "", s); utilfdt_print_data(t, sz); printf(";\n"); } } /* Usage related data. */ static const char usage_synopsis[] = "fdtdump [options] "; static const char usage_short_opts[] = "ds" USAGE_COMMON_SHORT_OPTS; static struct option const usage_long_opts[] = { {"debug", no_argument, NULL, 'd'}, {"scan", no_argument, NULL, 's'}, USAGE_COMMON_LONG_OPTS }; static const char * const usage_opts_help[] = { "Dump debug information while decoding the file", "Scan for an embedded fdt in file", USAGE_COMMON_OPTS_HELP }; int main(int argc, char *argv[]) { int opt; const char *file; char *buf; bool debug = false; bool scan = false; off_t len; while ((opt = util_getopt_long()) != EOF) { switch (opt) { case_USAGE_COMMON_FLAGS case 'd': debug = true; break; case 's': scan = true; break; } } if (optind != argc - 1) usage("missing input filename"); file = argv[optind]; buf = utilfdt_read_len(file, &len); if (!buf) die("could not read: %s\n", file); /* try and locate an embedded fdt in a bigger blob */ if (scan) { unsigned char smagic[4]; char *p = buf; char *endp = buf + len; fdt_set_magic(smagic, FDT_MAGIC); /* poor man's memmem */ while (true) { p = memchr(p, smagic[0], endp - p - 4); if (!p) break; if (fdt_magic(p) == FDT_MAGIC) { /* try and validate the main struct */ off_t this_len = endp - p; fdt32_t max_version = 17; if (fdt_version(p) <= max_version && fdt_last_comp_version(p) < max_version && fdt_totalsize(p) < this_len && fdt_off_dt_struct(p) < this_len && fdt_off_dt_strings(p) < this_len) break; if (debug) printf("%s: skipping fdt magic at offset %#zx\n", file, p - buf); } ++p; } if (!p) die("%s: could not locate fdt magic\n", file); printf("%s: found fdt at offset %#zx\n", file, p - buf); buf = p; } dump_blob(buf, debug); return 0; } device-tree-compiler-1.4.0+dfsg.orig/fdtput.c0000664000000000000000000002313612261525673015756 0ustar /* * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. * * 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 #include #include #include #include #include #include #include "util.h" /* These are the operations we support */ enum oper_type { OPER_WRITE_PROP, /* Write a property in a node */ OPER_CREATE_NODE, /* Create a new node */ }; struct display_info { enum oper_type oper; /* operation to perform */ int type; /* data type (s/i/u/x or 0 for default) */ int size; /* data size (1/2/4) */ int verbose; /* verbose output */ int auto_path; /* automatically create all path components */ }; /** * Report an error with a particular node. * * @param name Node name to report error on * @param namelen Length of node name, or -1 to use entire string * @param err Error number to report (-FDT_ERR_...) */ static void report_error(const char *name, int namelen, int err) { if (namelen == -1) namelen = strlen(name); fprintf(stderr, "Error at '%1.*s': %s\n", namelen, name, fdt_strerror(err)); } /** * Encode a series of arguments in a property value. * * @param disp Display information / options * @param arg List of arguments from command line * @param arg_count Number of arguments (may be 0) * @param valuep Returns buffer containing value * @param *value_len Returns length of value encoded */ static int encode_value(struct display_info *disp, char **arg, int arg_count, char **valuep, int *value_len) { char *value = NULL; /* holding area for value */ int value_size = 0; /* size of holding area */ char *ptr; /* pointer to current value position */ int len; /* length of this cell/string/byte */ int ival; int upto; /* the number of bytes we have written to buf */ char fmt[3]; upto = 0; if (disp->verbose) fprintf(stderr, "Decoding value:\n"); fmt[0] = '%'; fmt[1] = disp->type ? disp->type : 'd'; fmt[2] = '\0'; for (; arg_count > 0; arg++, arg_count--, upto += len) { /* assume integer unless told otherwise */ if (disp->type == 's') len = strlen(*arg) + 1; else len = disp->size == -1 ? 4 : disp->size; /* enlarge our value buffer by a suitable margin if needed */ if (upto + len > value_size) { value_size = (upto + len) + 500; value = realloc(value, value_size); if (!value) { fprintf(stderr, "Out of mmory: cannot alloc " "%d bytes\n", value_size); return -1; } } ptr = value + upto; if (disp->type == 's') { memcpy(ptr, *arg, len); if (disp->verbose) fprintf(stderr, "\tstring: '%s'\n", ptr); } else { int *iptr = (int *)ptr; sscanf(*arg, fmt, &ival); if (len == 4) *iptr = cpu_to_fdt32(ival); else *ptr = (uint8_t)ival; if (disp->verbose) { fprintf(stderr, "\t%s: %d\n", disp->size == 1 ? "byte" : disp->size == 2 ? "short" : "int", ival); } } } *value_len = upto; *valuep = value; if (disp->verbose) fprintf(stderr, "Value size %d\n", upto); return 0; } #define ALIGN(x) (((x) + (FDT_TAGSIZE) - 1) & ~((FDT_TAGSIZE) - 1)) static char *_realloc_fdt(char *fdt, int delta) { int new_sz = fdt_totalsize(fdt) + delta; fdt = xrealloc(fdt, new_sz); fdt_open_into(fdt, fdt, new_sz); return fdt; } static char *realloc_node(char *fdt, const char *name) { int delta; /* FDT_BEGIN_NODE, node name in off_struct and FDT_END_NODE */ delta = sizeof(struct fdt_node_header) + ALIGN(strlen(name) + 1) + FDT_TAGSIZE; return _realloc_fdt(fdt, delta); } static char *realloc_property(char *fdt, int nodeoffset, const char *name, int newlen) { int delta = 0; int oldlen = 0; if (!fdt_get_property(fdt, nodeoffset, name, &oldlen)) /* strings + property header */ delta = sizeof(struct fdt_property) + strlen(name) + 1; if (newlen > oldlen) /* actual value in off_struct */ delta += ALIGN(newlen) - ALIGN(oldlen); return _realloc_fdt(fdt, delta); } static int store_key_value(char **blob, const char *node_name, const char *property, const char *buf, int len) { int node; int err; node = fdt_path_offset(*blob, node_name); if (node < 0) { report_error(node_name, -1, node); return -1; } err = fdt_setprop(*blob, node, property, buf, len); if (err == -FDT_ERR_NOSPACE) { *blob = realloc_property(*blob, node, property, len); err = fdt_setprop(*blob, node, property, buf, len); } if (err) { report_error(property, -1, err); return -1; } return 0; } /** * Create paths as needed for all components of a path * * Any components of the path that do not exist are created. Errors are * reported. * * @param blob FDT blob to write into * @param in_path Path to process * @return 0 if ok, -1 on error */ static int create_paths(char **blob, const char *in_path) { const char *path = in_path; const char *sep; int node, offset = 0; /* skip leading '/' */ while (*path == '/') path++; for (sep = path; *sep; path = sep + 1, offset = node) { /* equivalent to strchrnul(), but it requires _GNU_SOURCE */ sep = strchr(path, '/'); if (!sep) sep = path + strlen(path); node = fdt_subnode_offset_namelen(*blob, offset, path, sep - path); if (node == -FDT_ERR_NOTFOUND) { *blob = realloc_node(*blob, path); node = fdt_add_subnode_namelen(*blob, offset, path, sep - path); } if (node < 0) { report_error(path, sep - path, node); return -1; } } return 0; } /** * Create a new node in the fdt. * * This will overwrite the node_name string. Any error is reported. * * TODO: Perhaps create fdt_path_offset_namelen() so we don't need to do this. * * @param blob FDT blob to write into * @param node_name Name of node to create * @return new node offset if found, or -1 on failure */ static int create_node(char **blob, const char *node_name) { int node = 0; char *p; p = strrchr(node_name, '/'); if (!p) { report_error(node_name, -1, -FDT_ERR_BADPATH); return -1; } *p = '\0'; *blob = realloc_node(*blob, p + 1); if (p > node_name) { node = fdt_path_offset(*blob, node_name); if (node < 0) { report_error(node_name, -1, node); return -1; } } node = fdt_add_subnode(*blob, node, p + 1); if (node < 0) { report_error(p + 1, -1, node); return -1; } return 0; } static int do_fdtput(struct display_info *disp, const char *filename, char **arg, int arg_count) { char *value; char *blob; int len, ret = 0; blob = utilfdt_read(filename); if (!blob) return -1; switch (disp->oper) { case OPER_WRITE_PROP: /* * Convert the arguments into a single binary value, then * store them into the property. */ assert(arg_count >= 2); if (disp->auto_path && create_paths(&blob, *arg)) return -1; if (encode_value(disp, arg + 2, arg_count - 2, &value, &len) || store_key_value(&blob, *arg, arg[1], value, len)) ret = -1; break; case OPER_CREATE_NODE: for (; ret >= 0 && arg_count--; arg++) { if (disp->auto_path) ret = create_paths(&blob, *arg); else ret = create_node(&blob, *arg); } break; } if (ret >= 0) { fdt_pack(blob); ret = utilfdt_write(filename, blob); } free(blob); return ret; } /* Usage related data. */ static const char usage_synopsis[] = "write a property value to a device tree\n" " fdtput
[...]\n" " fdtput -c
[...]\n" "\n" "The command line arguments are joined together into a single value.\n" USAGE_TYPE_MSG; static const char usage_short_opts[] = "cpt:v" USAGE_COMMON_SHORT_OPTS; static struct option const usage_long_opts[] = { {"create", no_argument, NULL, 'c'}, {"auto-path", no_argument, NULL, 'p'}, {"type", a_argument, NULL, 't'}, {"verbose", no_argument, NULL, 'v'}, USAGE_COMMON_LONG_OPTS, }; static const char * const usage_opts_help[] = { "Create nodes if they don't already exist", "Automatically create nodes as needed for the node path", "Type of data", "Display each value decoded from command line", USAGE_COMMON_OPTS_HELP }; int main(int argc, char *argv[]) { int opt; struct display_info disp; char *filename = NULL; memset(&disp, '\0', sizeof(disp)); disp.size = -1; disp.oper = OPER_WRITE_PROP; while ((opt = util_getopt_long()) != EOF) { /* * TODO: add options to: * - delete property * - delete node (optionally recursively) * - rename node * - pack fdt before writing * - set amount of free space when writing */ switch (opt) { case_USAGE_COMMON_FLAGS case 'c': disp.oper = OPER_CREATE_NODE; break; case 'p': disp.auto_path = 1; break; case 't': if (utilfdt_decode_type(optarg, &disp.type, &disp.size)) usage("Invalid type string"); break; case 'v': disp.verbose = 1; break; } } if (optind < argc) filename = argv[optind++]; if (!filename) usage("missing filename"); argv += optind; argc -= optind; if (disp.oper == OPER_WRITE_PROP) { if (argc < 1) usage("missing node"); if (argc < 2) usage("missing property"); } if (do_fdtput(&disp, filename, argv, argc)) return 1; return 0; }