On Tue, Jun 05, 2018 at 10:49:11PM +0000, Pascal Vizeli wrote: > Signed-off-by: Pascal Vizeli <pvizeli@xxxxxxxxxx> > --- I still need some time to look at the overlay code, but for now applied this one so we have this done already. Sascha > scripts/dtc/.gitignore | 1 - > scripts/dtc/Makefile | 8 +- > scripts/dtc/checks.c | 1194 +++++++++++++++++++++----- > scripts/dtc/data.c | 16 +- > scripts/dtc/dtc-lexer.l | 63 +- > scripts/dtc/dtc-lexer.lex.c_shipped | 894 +++++++++---------- > scripts/dtc/dtc-parser.tab.c_shipped | 813 ++++++++++-------- > scripts/dtc/dtc-parser.tab.h_shipped | 54 +- > scripts/dtc/dtc-parser.y | 91 +- > scripts/dtc/dtc.c | 139 ++- > scripts/dtc/dtc.h | 62 +- > scripts/dtc/fdt.c | 24 +- > scripts/dtc/fdt.h | 6 +- > scripts/dtc/fdt_empty_tree.c | 1 - > scripts/dtc/fdt_overlay.c | 912 ++++++++++++++++++++ > scripts/dtc/fdt_ro.c | 288 ++++++- > scripts/dtc/fdt_rw.c | 121 +-- > scripts/dtc/fdt_strerror.c | 6 + > scripts/dtc/fdt_sw.c | 40 +- > scripts/dtc/fdt_wip.c | 43 +- > scripts/dtc/fdtdump.c | 136 +-- > scripts/dtc/fdtget.c | 60 +- > scripts/dtc/fdtput.c | 142 ++- > scripts/dtc/flattree.c | 105 +-- > scripts/dtc/fstree.c | 5 +- > scripts/dtc/libfdt.h | 429 +++++++-- > scripts/dtc/libfdt_env.h | 60 +- > scripts/dtc/libfdt_internal.h | 32 +- > scripts/dtc/livetree.c | 356 +++++++- > scripts/dtc/srcpos.c | 42 +- > scripts/dtc/srcpos.h | 18 +- > scripts/dtc/treesource.c | 20 +- > scripts/dtc/update-dtc-source.sh | 46 +- > scripts/dtc/util.c | 44 +- > scripts/dtc/util.h | 33 +- > scripts/dtc/version_gen.h | 2 +- > 36 files changed, 4578 insertions(+), 1728 deletions(-) > create mode 100644 scripts/dtc/fdt_overlay.c > > diff --git a/scripts/dtc/.gitignore b/scripts/dtc/.gitignore > index 80f6b50fd..cdabdc95a 100644 > --- a/scripts/dtc/.gitignore > +++ b/scripts/dtc/.gitignore > @@ -2,4 +2,3 @@ dtc > dtc-lexer.lex.c > dtc-parser.tab.c > dtc-parser.tab.h > -fdtget > diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile > index 05973b12a..06aaa8c55 100644 > --- a/scripts/dtc/Makefile > +++ b/scripts/dtc/Makefile > @@ -1,17 +1,15 @@ > # scripts/dtc makefile > > -hostprogs-y := dtc fdtget > +hostprogs-y := dtc > always := $(hostprogs-y) > > dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \ > srcpos.o checks.o util.o > dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o > > -libfdt-objs = fdt.o fdt_ro.o fdt_strerror.o fdt_wip.o > +libfdt-objs = fdt.o fdt_ro.o fdt_strerror.o fdt_wip.o fdt_overlay.o > libfdt-objs += fdt_empty_tree.o fdt_rw.o fdt_sw.o > > -fdtget-objs += fdtget.o $(libfdt-objs) util.o > - > # Source files need to get at the userspace version of libfdt_env.h to compile > > HOSTCFLAGS_DTC := -I$(src) > @@ -33,7 +31,7 @@ HOSTCFLAGS_fdt_wip.o := $(HOSTCFLAGS_DTC) > HOSTCFLAGS_fdt_empty_tree.o := $(HOSTCFLAGS_DTC) > HOSTCFLAGS_fdt_rw.o := $(HOSTCFLAGS_DTC) > HOSTCFLAGS_fdt_sw.o := $(HOSTCFLAGS_DTC) > -HOSTCFLAGS_fdtget.o := $(HOSTCFLAGS_DTC) > +HOSTCFLAGS_fdt_overlay.o := $(HOSTCFLAGS_DTC) > > HOSTCFLAGS_dtc-lexer.lex.o := $(HOSTCFLAGS_DTC) > HOSTCFLAGS_dtc-parser.tab.o := $(HOSTCFLAGS_DTC) > diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c > index 3bf0fa4a4..815eaf140 100644 > --- a/scripts/dtc/checks.c > +++ b/scripts/dtc/checks.c > @@ -40,16 +40,11 @@ enum checkstatus { > > 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); > +typedef void (*check_fn)(struct check *c, struct dt_info *dti, struct node *node); > > struct check { > const char *name; > - tree_check_fn tree_fn; > - node_check_fn node_fn; > - prop_check_fn prop_fn; > + check_fn fn; > void *data; > bool warn, error; > enum checkstatus status; > @@ -58,91 +53,80 @@ struct check { > 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), \ > +#define CHECK_ENTRY(nm_, fn_, d_, w_, e_, ...) \ > + static struct check *nm_##_prereqs[] = { __VA_ARGS__ }; \ > + static struct check nm_ = { \ > + .name = #nm_, \ > + .fn = (fn_), \ > + .data = (d_), \ > + .warn = (w_), \ > + .error = (e_), \ > .status = UNCHECKED, \ > - .num_prereqs = ARRAY_SIZE(nm##_prereqs), \ > - .prereq = nm##_prereqs, \ > + .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, ...) > +#define WARNING(nm_, fn_, d_, ...) \ > + CHECK_ENTRY(nm_, fn_, d_, true, false, __VA_ARGS__) > +#define ERROR(nm_, fn_, d_, ...) \ > + CHECK_ENTRY(nm_, fn_, d_, false, true, __VA_ARGS__) > +#define CHECK(nm_, fn_, d_, ...) \ > + CHECK_ENTRY(nm_, fn_, d_, false, false, __VA_ARGS__) > + > +static inline void PRINTF(5, 6) check_msg(struct check *c, struct dt_info *dti, > + struct node *node, > + struct property *prop, > + const char *fmt, ...) > { > va_list ap; > va_start(ap, fmt); > > if ((c->warn && (quiet < 1)) > || (c->error && (quiet < 2))) { > - fprintf(stderr, "%s (%s): ", > + fprintf(stderr, "%s: %s (%s): ", > + strcmp(dti->outname, "-") ? dti->outname : "<stdout>", > (c->error) ? "ERROR" : "Warning", c->name); > + if (node) { > + fprintf(stderr, "%s", node->fullpath); > + if (prop) > + fprintf(stderr, ":%s", prop->name); > + fputs(": ", stderr); > + } > vfprintf(stderr, fmt, ap); > fprintf(stderr, "\n"); > } > + va_end(ap); > } > > -#define FAIL(c, ...) \ > - do { \ > - TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ > - (c)->status = FAILED; \ > - check_msg((c), __VA_ARGS__); \ > +#define FAIL(c, dti, node, ...) \ > + do { \ > + TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ > + (c)->status = FAILED; \ > + check_msg((c), dti, node, NULL, __VA_ARGS__); \ > } while (0) > > -static void check_nodes_props(struct check *c, struct node *dt, struct node *node) > +#define FAIL_PROP(c, dti, node, prop, ...) \ > + do { \ > + TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ > + (c)->status = FAILED; \ > + check_msg((c), dti, node, prop, __VA_ARGS__); \ > + } while (0) > + > + > +static void check_nodes_props(struct check *c, struct dt_info *dti, 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); > - } > + if (c->fn) > + c->fn(c, dti, node); > > for_each_child(node, child) > - check_nodes_props(c, dt, child); > + check_nodes_props(c, dti, child); > } > > -static bool run_check(struct check *c, struct node *dt) > +static bool run_check(struct check *c, struct dt_info *dti) > { > + struct node *dt = dti->dt; > bool error = false; > int i; > > @@ -155,10 +139,10 @@ static bool run_check(struct check *c, struct node *dt) > > for (i = 0; i < c->num_prereqs; i++) { > struct check *prq = c->prereq[i]; > - error = error || run_check(prq, dt); > + error = error || run_check(prq, dti); > if (prq->status != PASSED) { > c->status = PREREQ; > - check_msg(c, "Failed prerequisite '%s'", > + check_msg(c, dti, NULL, NULL, "Failed prerequisite '%s'", > c->prereq[i]->name); > } > } > @@ -166,11 +150,8 @@ static bool run_check(struct check *c, struct node *dt) > if (c->status != UNCHECKED) > goto out; > > - if (c->node_fn || c->prop_fn) > - check_nodes_props(c, dt, dt); > + check_nodes_props(c, dti, dt); > > - if (c->tree_fn) > - c->tree_fn(c, dt); > if (c->status == UNCHECKED) > c->status = PASSED; > > @@ -188,13 +169,14 @@ out: > */ > > /* A check which always fails, for testing purposes only */ > -static inline void check_always_fail(struct check *c, struct node *dt) > +static inline void check_always_fail(struct check *c, struct dt_info *dti, > + struct node *node) > { > - FAIL(c, "always_fail check"); > + FAIL(c, dti, node, "always_fail check"); > } > -TREE_CHECK(always_fail, NULL); > +CHECK(always_fail, check_always_fail, NULL); > > -static void check_is_string(struct check *c, struct node *root, > +static void check_is_string(struct check *c, struct dt_info *dti, > struct node *node) > { > struct property *prop; > @@ -205,15 +187,43 @@ static void check_is_string(struct check *c, struct node *root, > 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); > + FAIL_PROP(c, dti, node, prop, "property is not a string"); > } > #define WARNING_IF_NOT_STRING(nm, propname) \ > - WARNING(nm, NULL, check_is_string, NULL, (propname)) > + WARNING(nm, check_is_string, (propname)) > #define ERROR_IF_NOT_STRING(nm, propname) \ > - ERROR(nm, NULL, check_is_string, NULL, (propname)) > + ERROR(nm, check_is_string, (propname)) > + > +static void check_is_string_list(struct check *c, struct dt_info *dti, > + struct node *node) > +{ > + int rem, l; > + struct property *prop; > + char *propname = c->data; > + char *str; > + > + prop = get_property(node, propname); > + if (!prop) > + return; /* Not present, assumed ok */ > + > + str = prop->val.val; > + rem = prop->val.len; > + while (rem > 0) { > + l = strnlen(str, rem); > + if (l == rem) { > + FAIL_PROP(c, dti, node, prop, "property is not a string list"); > + break; > + } > + rem -= l + 1; > + str += l + 1; > + } > +} > +#define WARNING_IF_NOT_STRING_LIST(nm, propname) \ > + WARNING(nm, check_is_string_list, (propname)) > +#define ERROR_IF_NOT_STRING_LIST(nm, propname) \ > + ERROR(nm, check_is_string_list, (propname)) > > -static void check_is_cell(struct check *c, struct node *root, > +static void check_is_cell(struct check *c, struct dt_info *dti, > struct node *node) > { > struct property *prop; > @@ -224,19 +234,18 @@ static void check_is_cell(struct check *c, struct node *root, > 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); > + FAIL_PROP(c, dti, node, prop, "property is not a single cell"); > } > #define WARNING_IF_NOT_CELL(nm, propname) \ > - WARNING(nm, NULL, check_is_cell, NULL, (propname)) > + WARNING(nm, check_is_cell, (propname)) > #define ERROR_IF_NOT_CELL(nm, propname) \ > - ERROR(nm, NULL, check_is_cell, NULL, (propname)) > + ERROR(nm, check_is_cell, (propname)) > > /* > * Structural check functions > */ > > -static void check_duplicate_node_names(struct check *c, struct node *dt, > +static void check_duplicate_node_names(struct check *c, struct dt_info *dti, > struct node *node) > { > struct node *child, *child2; > @@ -246,12 +255,11 @@ static void check_duplicate_node_names(struct check *c, struct node *dt, > child2; > child2 = child2->next_sibling) > if (streq(child->name, child2->name)) > - FAIL(c, "Duplicate node name %s", > - child->fullpath); > + FAIL(c, dti, node, "Duplicate node name"); > } > -NODE_ERROR(duplicate_node_names, NULL); > +ERROR(duplicate_node_names, check_duplicate_node_names, NULL); > > -static void check_duplicate_property_names(struct check *c, struct node *dt, > +static void check_duplicate_property_names(struct check *c, struct dt_info *dti, > struct node *node) > { > struct property *prop, *prop2; > @@ -261,48 +269,116 @@ static void check_duplicate_property_names(struct check *c, struct node *dt, > if (prop2->deleted) > continue; > if (streq(prop->name, prop2->name)) > - FAIL(c, "Duplicate property name %s in %s", > - prop->name, node->fullpath); > + FAIL_PROP(c, dti, node, prop, "Duplicate property name"); > } > } > } > -NODE_ERROR(duplicate_property_names, NULL); > +ERROR(duplicate_property_names, check_duplicate_property_names, NULL); > > #define LOWERCASE "abcdefghijklmnopqrstuvwxyz" > #define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ" > #define DIGITS "0123456789" > #define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-" > +#define PROPNODECHARSSTRICT LOWERCASE UPPERCASE DIGITS ",-" > > -static void check_node_name_chars(struct check *c, struct node *dt, > +static void check_node_name_chars(struct check *c, struct dt_info *dti, > 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); > + FAIL(c, dti, node, "Bad character '%c' in node name", > + node->name[n]); > } > -NODE_ERROR(node_name_chars, PROPNODECHARS "@"); > +ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@"); > > -static void check_node_name_format(struct check *c, struct node *dt, > +static void check_node_name_chars_strict(struct check *c, struct dt_info *dti, > + struct node *node) > +{ > + int n = strspn(node->name, c->data); > + > + if (n < node->basenamelen) > + FAIL(c, dti, node, "Character '%c' not recommended in node name", > + node->name[n]); > +} > +CHECK(node_name_chars_strict, check_node_name_chars_strict, PROPNODECHARSSTRICT); > + > +static void check_node_name_format(struct check *c, struct dt_info *dti, > struct node *node) > { > if (strchr(get_unitname(node), '@')) > - FAIL(c, "Node %s has multiple '@' characters in name", > - node->fullpath); > + FAIL(c, dti, node, "multiple '@' characters in node name"); > +} > +ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars); > + > +static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti, > + struct node *node) > +{ > + const char *unitname = get_unitname(node); > + struct property *prop = get_property(node, "reg"); > + > + if (!prop) { > + prop = get_property(node, "ranges"); > + if (prop && !prop->val.len) > + prop = NULL; > + } > + > + if (prop) { > + if (!unitname[0]) > + FAIL(c, dti, node, "node has a reg or ranges property, but no unit name"); > + } else { > + if (unitname[0]) > + FAIL(c, dti, node, "node has a unit name, but no reg property"); > + } > +} > +WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL); > + > +static void check_property_name_chars(struct check *c, struct dt_info *dti, > + struct node *node) > +{ > + struct property *prop; > + > + for_each_property(node, prop) { > + int n = strspn(prop->name, c->data); > + > + if (n < strlen(prop->name)) > + FAIL_PROP(c, dti, node, prop, "Bad character '%c' in property name", > + prop->name[n]); > + } > } > -NODE_ERROR(node_name_format, NULL, &node_name_chars); > +ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS); > > -static void check_property_name_chars(struct check *c, struct node *dt, > - struct node *node, struct property *prop) > +static void check_property_name_chars_strict(struct check *c, > + struct dt_info *dti, > + struct node *node) > { > - int n = strspn(prop->name, c->data); > + struct property *prop; > + > + for_each_property(node, prop) { > + const char *name = prop->name; > + int n = strspn(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); > + if (n == strlen(prop->name)) > + continue; > + > + /* Certain names are whitelisted */ > + if (streq(name, "device_type")) > + continue; > + > + /* > + * # is only allowed at the beginning of property names not counting > + * the vendor prefix. > + */ > + if (name[n] == '#' && ((n == 0) || (name[n-1] == ','))) { > + name += n + 1; > + n = strspn(name, c->data); > + } > + if (n < strlen(name)) > + FAIL_PROP(c, dti, node, prop, "Character '%c' not recommended in property name", > + name[n]); > + } > } > -PROP_ERROR(property_name_chars, PROPNODECHARS); > +CHECK(property_name_chars_strict, check_property_name_chars_strict, PROPNODECHARSSTRICT); > > #define DESCLABEL_FMT "%s%s%s%s%s" > #define DESCLABEL_ARGS(node,prop,mark) \ > @@ -311,10 +387,11 @@ PROP_ERROR(property_name_chars, PROPNODECHARS); > ((prop) ? (prop)->name : ""), \ > ((prop) ? "' in " : ""), (node)->fullpath > > -static void check_duplicate_label(struct check *c, struct node *dt, > +static void check_duplicate_label(struct check *c, struct dt_info *dti, > const char *label, struct node *node, > struct property *prop, struct marker *mark) > { > + struct node *dt = dti->dt; > struct node *othernode = NULL; > struct property *otherprop = NULL; > struct marker *othermark = NULL; > @@ -331,50 +408,49 @@ static void check_duplicate_label(struct check *c, struct node *dt, > return; > > if ((othernode != node) || (otherprop != prop) || (othermark != mark)) > - FAIL(c, "Duplicate label '%s' on " DESCLABEL_FMT > + FAIL(c, dti, node, "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, > +static void check_duplicate_label_node(struct check *c, struct dt_info *dti, > struct node *node) > { > struct label *l; > + struct property *prop; > > 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; > + check_duplicate_label(c, dti, l->label, node, NULL, NULL); > + > + for_each_property(node, prop) { > + struct marker *m = prop->val.markers; > > - for_each_label(prop->labels, l) > - check_duplicate_label(c, dt, l->label, node, prop, NULL); > + for_each_label(prop->labels, l) > + check_duplicate_label(c, dti, l->label, node, prop, NULL); > > - for_each_marker_of_type(m, LABEL) > - check_duplicate_label(c, dt, m->ref, node, prop, m); > + for_each_marker_of_type(m, LABEL) > + check_duplicate_label(c, dti, m->ref, node, prop, m); > + } > } > -ERROR(duplicate_label, NULL, check_duplicate_label_node, > - check_duplicate_label_prop, NULL); > +ERROR(duplicate_label, check_duplicate_label_node, NULL); > > -static void check_explicit_phandles(struct check *c, struct node *root, > - struct node *node, struct property *prop) > +static cell_t check_phandle_prop(struct check *c, struct dt_info *dti, > + struct node *node, const char *propname) > { > + struct node *root = dti->dt; > + struct property *prop; > struct marker *m; > - struct node *other; > cell_t phandle; > > - if (!streq(prop->name, "phandle") > - && !streq(prop->name, "linux,phandle")) > - return; > + prop = get_property(node, propname); > + if (!prop) > + return 0; > > if (prop->val.len != sizeof(cell_t)) { > - FAIL(c, "%s has bad length (%d) %s property", > - node->fullpath, prop->val.len, prop->name); > - return; > + FAIL_PROP(c, dti, node, prop, "bad length (%d) %s property", > + prop->val.len, prop->name); > + return 0; > } > > m = prop->val.markers; > @@ -384,42 +460,65 @@ static void check_explicit_phandles(struct check *c, struct node *root, > /* "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; > + FAIL(c, dti, node, "%s is a reference to another node", > + prop->name); > } > /* 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; > + * we treat it as having no phandle data for now. */ > + return 0; > } > > 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; > + FAIL_PROP(c, dti, node, prop, "bad value (0x%x) in %s property", > + phandle, prop->name); > + return 0; > } > > - if (node->phandle && (node->phandle != phandle)) > - FAIL(c, "%s has %s property which replaces existing phandle information", > - node->fullpath, prop->name); > + return phandle; > +} > + > +static void check_explicit_phandles(struct check *c, struct dt_info *dti, > + struct node *node) > +{ > + struct node *root = dti->dt; > + struct node *other; > + cell_t phandle, linux_phandle; > + > + /* Nothing should have assigned phandles yet */ > + assert(!node->phandle); > + > + phandle = check_phandle_prop(c, dti, node, "phandle"); > + > + linux_phandle = check_phandle_prop(c, dti, node, "linux,phandle"); > + > + if (!phandle && !linux_phandle) > + /* No valid phandles; nothing further to check */ > + return; > + > + if (linux_phandle && phandle && (phandle != linux_phandle)) > + FAIL(c, dti, node, "mismatching 'phandle' and 'linux,phandle'" > + " properties"); > + > + if (linux_phandle && !phandle) > + phandle = linux_phandle; > > 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); > + FAIL(c, dti, node, "duplicated phandle 0x%x (seen before at %s)", > + phandle, other->fullpath); > return; > } > > node->phandle = phandle; > } > -PROP_ERROR(explicit_phandles, NULL); > +ERROR(explicit_phandles, check_explicit_phandles, NULL); > > -static void check_name_properties(struct check *c, struct node *root, > +static void check_name_properties(struct check *c, struct dt_info *dti, > struct node *node) > { > struct property **pp, *prop = NULL; > @@ -435,8 +534,8 @@ static void check_name_properties(struct check *c, struct node *root, > > 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); > + FAIL(c, dti, node, "\"name\" property is incorrect (\"%s\" instead" > + " of base node name)", prop->val.val); > } else { > /* The name property is correct, and therefore redundant. > * Delete it */ > @@ -447,60 +546,73 @@ static void check_name_properties(struct check *c, struct node *root, > } > } > ERROR_IF_NOT_STRING(name_is_string, "name"); > -NODE_ERROR(name_properties, NULL, &name_is_string); > +ERROR(name_properties, check_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) > +static void fixup_phandle_references(struct check *c, struct dt_info *dti, > + struct node *node) > { > - struct marker *m = prop->val.markers; > - struct node *refnode; > - cell_t phandle; > + struct node *dt = dti->dt; > + struct property *prop; > > - for_each_marker_of_type(m, REF_PHANDLE) { > - assert(m->offset + sizeof(cell_t) <= prop->val.len); > + for_each_property(node, 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) { > + if (!(dti->dtsflags & DTSF_PLUGIN)) > + FAIL(c, dti, node, "Reference to non-existent node or " > + "label \"%s\"\n", m->ref); > + else /* mark the entry as unresolved */ > + *((fdt32_t *)(prop->val.val + m->offset)) = > + cpu_to_fdt32(0xffffffff); > + continue; > + } > > - 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); > + *((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); > } > - > - 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, > +ERROR(phandle_references, 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) > +static void fixup_path_references(struct check *c, struct dt_info *dti, > + struct node *node) > { > - struct marker *m = prop->val.markers; > - struct node *refnode; > - char *path; > + struct node *dt = dti->dt; > + struct property *prop; > > - for_each_marker_of_type(m, REF_PATH) { > - assert(m->offset <= prop->val.len); > + for_each_property(node, prop) { > + struct marker *m = prop->val.markers; > + struct node *refnode; > + char *path; > > - refnode = get_node_by_ref(dt, m->ref); > - if (!refnode) { > - FAIL(c, "Reference to non-existent node or label \"%s\"\n", > - m->ref); > - continue; > - } > + for_each_marker_of_type(m, REF_PATH) { > + assert(m->offset <= prop->val.len); > > - path = refnode->fullpath; > - prop->val = data_insert_at_marker(prop->val, m, path, > - strlen(path) + 1); > + refnode = get_node_by_ref(dt, m->ref); > + if (!refnode) { > + FAIL(c, dti, node, "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); > +ERROR(path_references, fixup_path_references, NULL, &duplicate_node_names); > > /* > * Semantic checks > @@ -512,8 +624,47 @@ 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"); > +WARNING_IF_NOT_STRING(label_is_string, "label"); > + > +WARNING_IF_NOT_STRING_LIST(compatible_is_string_list, "compatible"); > + > +static void check_names_is_string_list(struct check *c, struct dt_info *dti, > + struct node *node) > +{ > + struct property *prop; > + > + for_each_property(node, prop) { > + const char *s = strrchr(prop->name, '-'); > + if (!s || !streq(s, "-names")) > + continue; > + > + c->data = prop->name; > + check_is_string_list(c, dti, node); > + } > +} > +WARNING(names_is_string_list, check_names_is_string_list, NULL); > + > +static void check_alias_paths(struct check *c, struct dt_info *dti, > + struct node *node) > +{ > + struct property *prop; > > -static void fixup_addr_size_cells(struct check *c, struct node *dt, > + if (!streq(node->name, "aliases")) > + return; > + > + for_each_property(node, prop) { > + if (!prop->val.val || !get_node_by_path(dti->dt, prop->val.val)) { > + FAIL_PROP(c, dti, node, prop, "aliases property is not a valid node (%s)", > + prop->val.val); > + continue; > + } > + if (strspn(prop->name, LOWERCASE DIGITS "-") != strlen(prop->name)) > + FAIL(c, dti, node, "aliases property name must include only lowercase and '-'"); > + } > +} > +WARNING(alias_paths, check_alias_paths, NULL); > + > +static void fixup_addr_size_cells(struct check *c, struct dt_info *dti, > struct node *node) > { > struct property *prop; > @@ -529,7 +680,7 @@ static void fixup_addr_size_cells(struct check *c, struct node *dt, > if (prop) > node->size_cells = propval_cell(prop); > } > -WARNING(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL, > +WARNING(addr_size_cells, fixup_addr_size_cells, NULL, > &address_cells_is_cell, &size_cells_is_cell); > > #define node_addr_cells(n) \ > @@ -537,7 +688,7 @@ WARNING(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL, > #define node_size_cells(n) \ > (((n)->size_cells == -1) ? 1 : (n)->size_cells) > > -static void check_reg_format(struct check *c, struct node *dt, > +static void check_reg_format(struct check *c, struct dt_info *dti, > struct node *node) > { > struct property *prop; > @@ -548,25 +699,25 @@ static void check_reg_format(struct check *c, struct node *dt, > return; /* No "reg", that's fine */ > > if (!node->parent) { > - FAIL(c, "Root node has a \"reg\" property"); > + FAIL(c, dti, node, "Root node has a \"reg\" property"); > return; > } > > if (prop->val.len == 0) > - FAIL(c, "\"reg\" property in %s is empty", node->fullpath); > + FAIL_PROP(c, dti, node, prop, "property is empty"); > > 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); > + if (!entrylen || (prop->val.len % entrylen) != 0) > + FAIL_PROP(c, dti, node, prop, "property has invalid length (%d bytes) " > + "(#address-cells == %d, #size-cells == %d)", > + prop->val.len, addr_cells, size_cells); > } > -NODE_WARNING(reg_format, NULL, &addr_size_cells); > +WARNING(reg_format, check_reg_format, NULL, &addr_size_cells); > > -static void check_ranges_format(struct check *c, struct node *dt, > +static void check_ranges_format(struct check *c, struct dt_info *dti, > struct node *node) > { > struct property *prop; > @@ -577,7 +728,7 @@ static void check_ranges_format(struct check *c, struct node *dt, > return; > > if (!node->parent) { > - FAIL(c, "Root node has a \"ranges\" property"); > + FAIL_PROP(c, dti, node, prop, "Root node has a \"ranges\" property"); > return; > } > > @@ -589,28 +740,237 @@ static void check_ranges_format(struct check *c, struct node *dt, > > 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); > + FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its " > + "#address-cells (%d) differs from %s (%d)", > + 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); > + FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its " > + "#size-cells (%d) differs from %s (%d)", > + 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); > + FAIL_PROP(c, dti, node, prop, "\"ranges\" property has invalid length (%d bytes) " > + "(parent #address-cells == %d, child #address-cells == %d, " > + "#size-cells == %d)", prop->val.len, > + p_addr_cells, c_addr_cells, c_size_cells); > + } > +} > +WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells); > + > +static const struct bus_type pci_bus = { > + .name = "PCI", > +}; > + > +static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node *node) > +{ > + struct property *prop; > + cell_t *cells; > + > + prop = get_property(node, "device_type"); > + if (!prop || !streq(prop->val.val, "pci")) > + return; > + > + node->bus = &pci_bus; > + > + if (!strprefixeq(node->name, node->basenamelen, "pci") && > + !strprefixeq(node->name, node->basenamelen, "pcie")) > + FAIL(c, dti, node, "node name is not \"pci\" or \"pcie\""); > + > + prop = get_property(node, "ranges"); > + if (!prop) > + FAIL(c, dti, node, "missing ranges for PCI bridge (or not a bridge)"); > + > + if (node_addr_cells(node) != 3) > + FAIL(c, dti, node, "incorrect #address-cells for PCI bridge"); > + if (node_size_cells(node) != 2) > + FAIL(c, dti, node, "incorrect #size-cells for PCI bridge"); > + > + prop = get_property(node, "bus-range"); > + if (!prop) > + return; > + > + if (prop->val.len != (sizeof(cell_t) * 2)) { > + FAIL_PROP(c, dti, node, prop, "value must be 2 cells"); > + return; > + } > + cells = (cell_t *)prop->val.val; > + if (fdt32_to_cpu(cells[0]) > fdt32_to_cpu(cells[1])) > + FAIL_PROP(c, dti, node, prop, "1st cell must be less than or equal to 2nd cell"); > + if (fdt32_to_cpu(cells[1]) > 0xff) > + FAIL_PROP(c, dti, node, prop, "maximum bus number must be less than 256"); > +} > +WARNING(pci_bridge, check_pci_bridge, NULL, > + &device_type_is_string, &addr_size_cells); > + > +static void check_pci_device_bus_num(struct check *c, struct dt_info *dti, struct node *node) > +{ > + struct property *prop; > + unsigned int bus_num, min_bus, max_bus; > + cell_t *cells; > + > + if (!node->parent || (node->parent->bus != &pci_bus)) > + return; > + > + prop = get_property(node, "reg"); > + if (!prop) > + return; > + > + cells = (cell_t *)prop->val.val; > + bus_num = (fdt32_to_cpu(cells[0]) & 0x00ff0000) >> 16; > + > + prop = get_property(node->parent, "bus-range"); > + if (!prop) { > + min_bus = max_bus = 0; > + } else { > + cells = (cell_t *)prop->val.val; > + min_bus = fdt32_to_cpu(cells[0]); > + max_bus = fdt32_to_cpu(cells[0]); > + } > + if ((bus_num < min_bus) || (bus_num > max_bus)) > + FAIL_PROP(c, dti, node, prop, "PCI bus number %d out of range, expected (%d - %d)", > + bus_num, min_bus, max_bus); > +} > +WARNING(pci_device_bus_num, check_pci_device_bus_num, NULL, ®_format, &pci_bridge); > + > +static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct node *node) > +{ > + struct property *prop; > + const char *unitname = get_unitname(node); > + char unit_addr[5]; > + unsigned int dev, func, reg; > + cell_t *cells; > + > + if (!node->parent || (node->parent->bus != &pci_bus)) > + return; > + > + prop = get_property(node, "reg"); > + if (!prop) { > + FAIL(c, dti, node, "missing PCI reg property"); > + return; > + } > + > + cells = (cell_t *)prop->val.val; > + if (cells[1] || cells[2]) > + FAIL_PROP(c, dti, node, prop, "PCI reg config space address cells 2 and 3 must be 0"); > + > + reg = fdt32_to_cpu(cells[0]); > + dev = (reg & 0xf800) >> 11; > + func = (reg & 0x700) >> 8; > + > + if (reg & 0xff000000) > + FAIL_PROP(c, dti, node, prop, "PCI reg address is not configuration space"); > + if (reg & 0x000000ff) > + FAIL_PROP(c, dti, node, prop, "PCI reg config space address register number must be 0"); > + > + if (func == 0) { > + snprintf(unit_addr, sizeof(unit_addr), "%x", dev); > + if (streq(unitname, unit_addr)) > + return; > + } > + > + snprintf(unit_addr, sizeof(unit_addr), "%x,%x", dev, func); > + if (streq(unitname, unit_addr)) > + return; > + > + FAIL(c, dti, node, "PCI unit address format error, expected \"%s\"", > + unit_addr); > +} > +WARNING(pci_device_reg, check_pci_device_reg, NULL, ®_format, &pci_bridge); > + > +static const struct bus_type simple_bus = { > + .name = "simple-bus", > +}; > + > +static bool node_is_compatible(struct node *node, const char *compat) > +{ > + struct property *prop; > + const char *str, *end; > + > + prop = get_property(node, "compatible"); > + if (!prop) > + return false; > + > + for (str = prop->val.val, end = str + prop->val.len; str < end; > + str += strnlen(str, end - str) + 1) { > + if (strprefixeq(str, end - str, compat)) > + return true; > } > + return false; > +} > + > +static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct node *node) > +{ > + if (node_is_compatible(node, "simple-bus")) > + node->bus = &simple_bus; > } > -NODE_WARNING(ranges_format, NULL, &addr_size_cells); > +WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL, &addr_size_cells); > + > +static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node) > +{ > + struct property *prop; > + const char *unitname = get_unitname(node); > + char unit_addr[17]; > + unsigned int size; > + uint64_t reg = 0; > + cell_t *cells = NULL; > + > + if (!node->parent || (node->parent->bus != &simple_bus)) > + return; > + > + prop = get_property(node, "reg"); > + if (prop) > + cells = (cell_t *)prop->val.val; > + else { > + prop = get_property(node, "ranges"); > + if (prop && prop->val.len) > + /* skip of child address */ > + cells = ((cell_t *)prop->val.val) + node_addr_cells(node); > + } > + > + if (!cells) { > + if (node->parent->parent && !(node->bus == &simple_bus)) > + FAIL(c, dti, node, "missing or empty reg/ranges property"); > + return; > + } > + > + size = node_addr_cells(node->parent); > + while (size--) > + reg = (reg << 32) | fdt32_to_cpu(*(cells++)); > + > + snprintf(unit_addr, sizeof(unit_addr), "%"PRIx64, reg); > + if (!streq(unitname, unit_addr)) > + FAIL(c, dti, node, "simple-bus unit address format error, expected \"%s\"", > + unit_addr); > +} > +WARNING(simple_bus_reg, check_simple_bus_reg, NULL, ®_format, &simple_bus_bridge); > + > +static void check_unit_address_format(struct check *c, struct dt_info *dti, > + struct node *node) > +{ > + const char *unitname = get_unitname(node); > + > + if (node->parent && node->parent->bus) > + return; > + > + if (!unitname[0]) > + return; > + > + if (!strncmp(unitname, "0x", 2)) { > + FAIL(c, dti, node, "unit name should not have leading \"0x\""); > + /* skip over 0x for next test */ > + unitname += 2; > + } > + if (unitname[0] == '0' && isxdigit(unitname[1])) > + FAIL(c, dti, node, "unit name should not have leading 0s"); > +} > +WARNING(unit_address_format, check_unit_address_format, NULL, > + &node_name_format, &pci_bridge, &simple_bus_bridge); > > /* > * Style checks > */ > -static void check_avoid_default_addr_size(struct check *c, struct node *dt, > +static void check_avoid_default_addr_size(struct check *c, struct dt_info *dti, > struct node *node) > { > struct property *reg, *ranges; > @@ -625,31 +985,377 @@ static void check_avoid_default_addr_size(struct check *c, struct node *dt, > return; > > if (node->parent->addr_cells == -1) > - FAIL(c, "Relying on default #address-cells value for %s", > - node->fullpath); > + FAIL(c, dti, node, "Relying on default #address-cells value"); > > if (node->parent->size_cells == -1) > - FAIL(c, "Relying on default #size-cells value for %s", > - node->fullpath); > + FAIL(c, dti, node, "Relying on default #size-cells value"); > +} > +WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL, > + &addr_size_cells); > + > +static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *dti, > + struct node *node) > +{ > + struct property *prop; > + struct node *child; > + bool has_reg = false; > + > + if (!node->parent || node->addr_cells < 0 || node->size_cells < 0) > + return; > + > + if (get_property(node, "ranges") || !node->children) > + return; > + > + for_each_child(node, child) { > + prop = get_property(child, "reg"); > + if (prop) > + has_reg = true; > + } > + > + if (!has_reg) > + FAIL(c, dti, node, "unnecessary #address-cells/#size-cells without \"ranges\" or child \"reg\" property"); > } > -NODE_WARNING(avoid_default_addr_size, NULL, &addr_size_cells); > +WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size); > > static void check_obsolete_chosen_interrupt_controller(struct check *c, > - struct node *dt) > + struct dt_info *dti, > + struct node *node) > { > + struct node *dt = dti->dt; > struct node *chosen; > struct property *prop; > > + if (node != dt) > + return; > + > + > 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"); > + FAIL_PROP(c, dti, node, prop, > + "/chosen has obsolete \"interrupt-controller\" property"); > +} > +WARNING(obsolete_chosen_interrupt_controller, > + check_obsolete_chosen_interrupt_controller, NULL); > + > +static void check_chosen_node_is_root(struct check *c, struct dt_info *dti, > + struct node *node) > +{ > + if (!streq(node->name, "chosen")) > + return; > + > + if (node->parent != dti->dt) > + FAIL(c, dti, node, "chosen node must be at root node"); > } > -TREE_WARNING(obsolete_chosen_interrupt_controller, NULL); > +WARNING(chosen_node_is_root, check_chosen_node_is_root, NULL); > + > +static void check_chosen_node_bootargs(struct check *c, struct dt_info *dti, > + struct node *node) > +{ > + struct property *prop; > + > + if (!streq(node->name, "chosen")) > + return; > + > + prop = get_property(node, "bootargs"); > + if (!prop) > + return; > + > + c->data = prop->name; > + check_is_string(c, dti, node); > +} > +WARNING(chosen_node_bootargs, check_chosen_node_bootargs, NULL); > + > +static void check_chosen_node_stdout_path(struct check *c, struct dt_info *dti, > + struct node *node) > +{ > + struct property *prop; > + > + if (!streq(node->name, "chosen")) > + return; > + > + prop = get_property(node, "stdout-path"); > + if (!prop) { > + prop = get_property(node, "linux,stdout-path"); > + if (!prop) > + return; > + FAIL_PROP(c, dti, node, prop, "Use 'stdout-path' instead"); > + } > + > + c->data = prop->name; > + check_is_string(c, dti, node); > +} > +WARNING(chosen_node_stdout_path, check_chosen_node_stdout_path, NULL); > + > +struct provider { > + const char *prop_name; > + const char *cell_name; > + bool optional; > +}; > + > +static void check_property_phandle_args(struct check *c, > + struct dt_info *dti, > + struct node *node, > + struct property *prop, > + const struct provider *provider) > +{ > + struct node *root = dti->dt; > + int cell, cellsize = 0; > + > + if (prop->val.len % sizeof(cell_t)) { > + FAIL_PROP(c, dti, node, prop, > + "property size (%d) is invalid, expected multiple of %zu", > + prop->val.len, sizeof(cell_t)); > + return; > + } > + > + for (cell = 0; cell < prop->val.len / sizeof(cell_t); cell += cellsize + 1) { > + struct node *provider_node; > + struct property *cellprop; > + int phandle; > + > + phandle = propval_cell_n(prop, cell); > + /* > + * Some bindings use a cell value 0 or -1 to skip over optional > + * entries when each index position has a specific definition. > + */ > + if (phandle == 0 || phandle == -1) { > + /* Give up if this is an overlay with external references */ > + if (dti->dtsflags & DTSF_PLUGIN) > + break; > + > + cellsize = 0; > + continue; > + } > + > + /* If we have markers, verify the current cell is a phandle */ > + if (prop->val.markers) { > + struct marker *m = prop->val.markers; > + for_each_marker_of_type(m, REF_PHANDLE) { > + if (m->offset == (cell * sizeof(cell_t))) > + break; > + } > + if (!m) > + FAIL_PROP(c, dti, node, prop, > + "cell %d is not a phandle reference", > + cell); > + } > + > + provider_node = get_node_by_phandle(root, phandle); > + if (!provider_node) { > + FAIL_PROP(c, dti, node, prop, > + "Could not get phandle node for (cell %d)", > + cell); > + break; > + } > + > + cellprop = get_property(provider_node, provider->cell_name); > + if (cellprop) { > + cellsize = propval_cell(cellprop); > + } else if (provider->optional) { > + cellsize = 0; > + } else { > + FAIL(c, dti, node, "Missing property '%s' in node %s or bad phandle (referred from %s[%d])", > + provider->cell_name, > + provider_node->fullpath, > + prop->name, cell); > + break; > + } > + > + if (prop->val.len < ((cell + cellsize + 1) * sizeof(cell_t))) { > + FAIL_PROP(c, dti, node, prop, > + "property size (%d) too small for cell size %d", > + prop->val.len, cellsize); > + } > + } > +} > + > +static void check_provider_cells_property(struct check *c, > + struct dt_info *dti, > + struct node *node) > +{ > + struct provider *provider = c->data; > + struct property *prop; > + > + prop = get_property(node, provider->prop_name); > + if (!prop) > + return; > + > + check_property_phandle_args(c, dti, node, prop, provider); > +} > +#define WARNING_PROPERTY_PHANDLE_CELLS(nm, propname, cells_name, ...) \ > + static struct provider nm##_provider = { (propname), (cells_name), __VA_ARGS__ }; \ > + WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &phandle_references); > + > +WARNING_PROPERTY_PHANDLE_CELLS(clocks, "clocks", "#clock-cells"); > +WARNING_PROPERTY_PHANDLE_CELLS(cooling_device, "cooling-device", "#cooling-cells"); > +WARNING_PROPERTY_PHANDLE_CELLS(dmas, "dmas", "#dma-cells"); > +WARNING_PROPERTY_PHANDLE_CELLS(hwlocks, "hwlocks", "#hwlock-cells"); > +WARNING_PROPERTY_PHANDLE_CELLS(interrupts_extended, "interrupts-extended", "#interrupt-cells"); > +WARNING_PROPERTY_PHANDLE_CELLS(io_channels, "io-channels", "#io-channel-cells"); > +WARNING_PROPERTY_PHANDLE_CELLS(iommus, "iommus", "#iommu-cells"); > +WARNING_PROPERTY_PHANDLE_CELLS(mboxes, "mboxes", "#mbox-cells"); > +WARNING_PROPERTY_PHANDLE_CELLS(msi_parent, "msi-parent", "#msi-cells", true); > +WARNING_PROPERTY_PHANDLE_CELLS(mux_controls, "mux-controls", "#mux-control-cells"); > +WARNING_PROPERTY_PHANDLE_CELLS(phys, "phys", "#phy-cells"); > +WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells"); > +WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells"); > +WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells"); > +WARNING_PROPERTY_PHANDLE_CELLS(sound_dai, "sound-dai", "#sound-dai-cells"); > +WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells"); > + > +static bool prop_is_gpio(struct property *prop) > +{ > + char *str; > + > + /* > + * *-gpios and *-gpio can appear in property names, > + * so skip over any false matches (only one known ATM) > + */ > + if (strstr(prop->name, "nr-gpio")) > + return false; > + > + str = strrchr(prop->name, '-'); > + if (str) > + str++; > + else > + str = prop->name; > + if (!(streq(str, "gpios") || streq(str, "gpio"))) > + return false; > + > + return true; > +} > + > +static void check_gpios_property(struct check *c, > + struct dt_info *dti, > + struct node *node) > +{ > + struct property *prop; > + > + /* Skip GPIO hog nodes which have 'gpios' property */ > + if (get_property(node, "gpio-hog")) > + return; > + > + for_each_property(node, prop) { > + struct provider provider; > + > + if (!prop_is_gpio(prop)) > + continue; > + > + provider.prop_name = prop->name; > + provider.cell_name = "#gpio-cells"; > + provider.optional = false; > + check_property_phandle_args(c, dti, node, prop, &provider); > + } > + > +} > +WARNING(gpios_property, check_gpios_property, NULL, &phandle_references); > + > +static void check_deprecated_gpio_property(struct check *c, > + struct dt_info *dti, > + struct node *node) > +{ > + struct property *prop; > + > + for_each_property(node, prop) { > + char *str; > + > + if (!prop_is_gpio(prop)) > + continue; > + > + str = strstr(prop->name, "gpio"); > + if (!streq(str, "gpio")) > + continue; > + > + FAIL_PROP(c, dti, node, prop, > + "'[*-]gpio' is deprecated, use '[*-]gpios' instead"); > + } > + > +} > +CHECK(deprecated_gpio_property, check_deprecated_gpio_property, NULL); > + > +static bool node_is_interrupt_provider(struct node *node) > +{ > + struct property *prop; > + > + prop = get_property(node, "interrupt-controller"); > + if (prop) > + return true; > + > + prop = get_property(node, "interrupt-map"); > + if (prop) > + return true; > + > + return false; > +} > +static void check_interrupts_property(struct check *c, > + struct dt_info *dti, > + struct node *node) > +{ > + struct node *root = dti->dt; > + struct node *irq_node = NULL, *parent = node; > + struct property *irq_prop, *prop = NULL; > + int irq_cells, phandle; > + > + irq_prop = get_property(node, "interrupts"); > + if (!irq_prop) > + return; > + > + if (irq_prop->val.len % sizeof(cell_t)) > + FAIL_PROP(c, dti, node, irq_prop, "size (%d) is invalid, expected multiple of %zu", > + irq_prop->val.len, sizeof(cell_t)); > + > + while (parent && !prop) { > + if (parent != node && node_is_interrupt_provider(parent)) { > + irq_node = parent; > + break; > + } > + > + prop = get_property(parent, "interrupt-parent"); > + if (prop) { > + phandle = propval_cell(prop); > + /* Give up if this is an overlay with external references */ > + if ((phandle == 0 || phandle == -1) && > + (dti->dtsflags & DTSF_PLUGIN)) > + return; > + > + irq_node = get_node_by_phandle(root, phandle); > + if (!irq_node) { > + FAIL_PROP(c, dti, parent, prop, "Bad phandle"); > + return; > + } > + if (!node_is_interrupt_provider(irq_node)) > + FAIL(c, dti, irq_node, > + "Missing interrupt-controller or interrupt-map property"); > + > + break; > + } > + > + parent = parent->parent; > + } > + > + if (!irq_node) { > + FAIL(c, dti, node, "Missing interrupt-parent"); > + return; > + } > + > + prop = get_property(irq_node, "#interrupt-cells"); > + if (!prop) { > + FAIL(c, dti, irq_node, "Missing #interrupt-cells in interrupt-parent"); > + return; > + } > + > + irq_cells = propval_cell(prop); > + if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) { > + FAIL_PROP(c, dti, node, prop, > + "size is (%d), expected multiple of %d", > + irq_prop->val.len, (int)(irq_cells * sizeof(cell_t))); > + } > +} > +WARNING(interrupts_property, check_interrupts_property, &phandle_references); > > static struct check *check_table[] = { > &duplicate_node_names, &duplicate_property_names, > @@ -663,11 +1369,52 @@ static struct check *check_table[] = { > > &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell, > &device_type_is_string, &model_is_string, &status_is_string, > + &label_is_string, > + > + &compatible_is_string_list, &names_is_string_list, > + > + &property_name_chars_strict, > + &node_name_chars_strict, > > &addr_size_cells, ®_format, &ranges_format, > > + &unit_address_vs_reg, > + &unit_address_format, > + > + &pci_bridge, > + &pci_device_reg, > + &pci_device_bus_num, > + > + &simple_bus_bridge, > + &simple_bus_reg, > + > &avoid_default_addr_size, > + &avoid_unnecessary_addr_size, > &obsolete_chosen_interrupt_controller, > + &chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path, > + > + &clocks_property, > + &cooling_device_property, > + &dmas_property, > + &hwlocks_property, > + &interrupts_extended_property, > + &io_channels_property, > + &iommus_property, > + &mboxes_property, > + &msi_parent_property, > + &mux_controls_property, > + &phys_property, > + &power_domains_property, > + &pwms_property, > + &resets_property, > + &sound_dai_property, > + &thermal_sensors_property, > + > + &deprecated_gpio_property, > + &gpios_property, > + &interrupts_property, > + > + &alias_paths, > > &always_fail, > }; > @@ -733,9 +1480,8 @@ void parse_checks_option(bool warn, bool error, const char *arg) > die("Unrecognized check name \"%s\"\n", name); > } > > -void process_checks(bool force, struct boot_info *bi) > +void process_checks(bool force, struct dt_info *dti) > { > - struct node *dt = bi->dt; > int i; > int error = 0; > > @@ -743,7 +1489,7 @@ void process_checks(bool force, struct boot_info *bi) > struct check *c = check_table[i]; > > if (c->warn || c->error) > - error = error || run_check(c, dt); > + error = error || run_check(c, dti); > } > > if (error) { > diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c > index 8cae23746..aa37a16c8 100644 > --- a/scripts/dtc/data.c > +++ b/scripts/dtc/data.c > @@ -171,9 +171,9 @@ struct data data_merge(struct data d1, struct data d2) > 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; > + fdt16_t value_16; > + fdt32_t value_32; > + fdt64_t value_64; > > switch (bits) { > case 8: > @@ -197,14 +197,14 @@ struct data data_append_integer(struct data d, uint64_t value, int bits) > } > } > > -struct data data_append_re(struct data d, const struct fdt_reserve_entry *re) > +struct data data_append_re(struct data d, uint64_t address, uint64_t size) > { > - struct fdt_reserve_entry bere; > + struct fdt_reserve_entry re; > > - bere.address = cpu_to_fdt64(re->address); > - bere.size = cpu_to_fdt64(re->size); > + re.address = cpu_to_fdt64(address); > + re.size = cpu_to_fdt64(size); > > - return data_append_data(d, &bere, sizeof(bere)); > + return data_append_data(d, &re, sizeof(re)); > } > > struct data data_append_cell(struct data d, cell_t word) > diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l > index 0ee1caf03..fd825ebba 100644 > --- a/scripts/dtc/dtc-lexer.l > +++ b/scripts/dtc/dtc-lexer.l > @@ -62,7 +62,8 @@ static int dts_version = 1; > > static void push_input_file(const char *filename); > static bool pop_input_file(void); > -static void lexical_error(const char *fmt, ...); > +static void PRINTF(1, 2) lexical_error(const char *fmt, ...); > + > %} > > %% > @@ -73,24 +74,32 @@ static void lexical_error(const char *fmt, ...); > } > > <*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t]+[0-9]+)? { > - char *line, *tmp, *fn; > + char *line, *fnstart, *fnend; > + struct data fn; > /* skip text before line # */ > line = yytext; > while (!isdigit((unsigned char)*line)) > line++; > - /* skip digits in line # */ > - tmp = line; > - while (!isspace((unsigned char)*tmp)) > - tmp++; > - /* "NULL"-terminate line # */ > - *tmp = '\0'; > - /* start of filename */ > - fn = strchr(tmp + 1, '"') + 1; > - /* strip trailing " from filename */ > - tmp = strchr(fn, '"'); > - *tmp = 0; > + > + /* regexp ensures that first and list " > + * in the whole yytext are those at > + * beginning and end of the filename string */ > + fnstart = memchr(yytext, '"', yyleng); > + for (fnend = yytext + yyleng - 1; > + *fnend != '"'; fnend--) > + ; > + assert(fnstart && fnend && (fnend > fnstart)); > + > + fn = data_copy_escape_string(fnstart + 1, > + fnend - fnstart - 1); > + > + /* Don't allow nuls in filenames */ > + if (memchr(fn.val, '\0', fn.len - 1)) > + lexical_error("nul in line number directive"); > + > /* -1 since #line is the number of the next line */ > - srcpos_set_line(xstrdup(fn), atoi(line) - 1); > + srcpos_set_line(xstrdup(fn.val), atoi(line) - 1); > + data_free(fn); > } > > <*><<EOF>> { > @@ -113,6 +122,11 @@ static void lexical_error(const char *fmt, ...); > return DT_V1; > } > > +<*>"/plugin/" { > + DPRINT("Keyword: /plugin/\n"); > + return DT_PLUGIN; > + } > + > <*>"/memreserve/" { > DPRINT("Keyword: /memreserve/\n"); > BEGIN_DEFAULT(); > @@ -153,7 +167,10 @@ static void lexical_error(const char *fmt, ...); > errno = 0; > yylval.integer = strtoull(yytext, &e, 0); > > - assert(!(*e) || !e[strspn(e, "UL")]); > + if (*e && e[strspn(e, "UL")]) { > + lexical_error("Bad integer literal '%s'", > + yytext); > + } > > if (errno == ERANGE) > lexical_error("Integer literal '%s' out of range", > @@ -173,16 +190,16 @@ static void lexical_error(const char *fmt, ...); > if (d.len == 1) { > lexical_error("Empty character literal"); > yylval.integer = 0; > - return DT_CHAR_LITERAL; > - } > - > - yylval.integer = (unsigned char)d.val[0]; > + } else { > + yylval.integer = (unsigned char)d.val[0]; > > - if (d.len > 2) > - lexical_error("Character literal has %d" > - " characters instead of 1", > - d.len - 1); > + if (d.len > 2) > + lexical_error("Character literal has %d" > + " characters instead of 1", > + d.len - 1); > + } > > + data_free(d); > return DT_CHAR_LITERAL; > } > > diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped > index 11cd78e72..f032b24b2 100644 > --- a/scripts/dtc/dtc-lexer.lex.c_shipped > +++ b/scripts/dtc/dtc-lexer.lex.c_shipped > @@ -1,6 +1,6 @@ > -#line 2 "dtc-lexer.lex.c" > +#line 2 "dtc-lexer.l.c" > > -#line 4 "dtc-lexer.lex.c" > +#line 4 "dtc-lexer.l.c" > > #define YY_INT_ALIGNED short int > > @@ -8,8 +8,8 @@ > > #define FLEX_SCANNER > #define YY_FLEX_MAJOR_VERSION 2 > -#define YY_FLEX_MINOR_VERSION 5 > -#define YY_FLEX_SUBMINOR_VERSION 39 > +#define YY_FLEX_MINOR_VERSION 6 > +#define YY_FLEX_SUBMINOR_VERSION 4 > #if YY_FLEX_SUBMINOR_VERSION > 0 > #define FLEX_BETA > #endif > @@ -84,60 +84,48 @@ typedef unsigned int flex_uint32_t; > #define UINT32_MAX (4294967295U) > #endif > > +#ifndef SIZE_MAX > +#define SIZE_MAX (~(size_t)0) > +#endif > + > #endif /* ! C99 */ > > #endif /* ! FLEXINT_H */ > > -#ifdef __cplusplus > - > -/* The "const" storage-class-modifier is valid. */ > -#define YY_USE_CONST > - > -#else /* ! __cplusplus */ > - > -/* C99 requires __STDC__ to be defined as 1. */ > -#if defined (__STDC__) > - > -#define YY_USE_CONST > +/* begin standard C++ headers. */ > > -#endif /* defined (__STDC__) */ > -#endif /* ! __cplusplus */ > - > -#ifdef YY_USE_CONST > +/* TODO: this is always defined, so inline it */ > #define yyconst const > + > +#if defined(__GNUC__) && __GNUC__ >= 3 > +#define yynoreturn __attribute__((__noreturn__)) > #else > -#define yyconst > +#define yynoreturn > #endif > > /* Returned upon end-of-file. */ > #define YY_NULL 0 > > -/* Promotes a possibly negative, possibly signed char to an unsigned > - * integer for use as an array index. If the signed char is negative, > - * we want to instead treat it as an 8-bit unsigned char, hence the > - * double cast. > +/* Promotes a possibly negative, possibly signed char to an > + * integer in range [0..255] for use as an array index. > */ > -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) > +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) > > /* Enter a start condition. This macro really ought to take a parameter, > * but we do it the disgusting crufty way forced on us by the ()-less > * definition of BEGIN. > */ > #define BEGIN (yy_start) = 1 + 2 * > - > /* Translate the current start state into a value that can be later handed > * to BEGIN to return to the state. The YYSTATE alias is for lex > * compatibility. > */ > #define YY_START (((yy_start) - 1) / 2) > #define YYSTATE YY_START > - > /* Action number for EOF rule of a given start state. */ > #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) > - > /* Special action meaning "start processing a new file". */ > -#define YY_NEW_FILE yyrestart(yyin ) > - > +#define YY_NEW_FILE yyrestart( yyin ) > #define YY_END_OF_BUFFER_CHAR 0 > > /* Size of default input buffer. */ > @@ -167,14 +155,14 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; > typedef size_t yy_size_t; > #endif > > -extern yy_size_t yyleng; > +extern int yyleng; > > extern FILE *yyin, *yyout; > > #define EOB_ACT_CONTINUE_SCAN 0 > #define EOB_ACT_END_OF_FILE 1 > #define EOB_ACT_LAST_MATCH 2 > - > + > #define YY_LESS_LINENO(n) > #define YY_LINENO_REWIND_TO(ptr) > > @@ -191,7 +179,6 @@ extern FILE *yyin, *yyout; > YY_DO_BEFORE_ACTION; /* set up yytext again */ \ > } \ > while ( 0 ) > - > #define unput(c) yyunput( c, (yytext_ptr) ) > > #ifndef YY_STRUCT_YY_BUFFER_STATE > @@ -206,12 +193,12 @@ struct yy_buffer_state > /* Size of input buffer in bytes, not including room for EOB > * characters. > */ > - yy_size_t yy_buf_size; > + int yy_buf_size; > > /* Number of characters read into yy_ch_buf, not including EOB > * characters. > */ > - yy_size_t yy_n_chars; > + int yy_n_chars; > > /* Whether we "own" the buffer - i.e., we know we created it, > * and can realloc() it to grow it, and should free() it to > @@ -234,7 +221,7 @@ struct yy_buffer_state > > int yy_bs_lineno; /**< The line count. */ > int yy_bs_column; /**< The column count. */ > - > + > /* Whether to try to fill the input buffer when we reach the > * end of it. > */ > @@ -262,7 +249,7 @@ struct yy_buffer_state > /* Stack of input buffers. */ > static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ > static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ > -static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ > +static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ > > /* We provide macros for accessing buffer states in case in the > * future we want to put the buffer states in a more general > @@ -273,7 +260,6 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ > #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ > ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ > : NULL) > - > /* Same as previous macro, but useful when we know that the buffer stack is not > * NULL or when we need an lvalue. For internal use only. > */ > @@ -281,11 +267,11 @@ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ > > /* yy_hold_char holds the character lost when yytext is formed. */ > static char yy_hold_char; > -static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ > -yy_size_t yyleng; > +static int yy_n_chars; /* number of characters read into yy_ch_buf */ > +int yyleng; > > /* Points to current character in buffer. */ > -static char *yy_c_buf_p = (char *) 0; > +static char *yy_c_buf_p = NULL; > static int yy_init = 0; /* whether we need to initialize */ > static int yy_start = 0; /* start state number */ > > @@ -294,87 +280,83 @@ static int yy_start = 0; /* start state number */ > */ > static int yy_did_buffer_switch_on_eof; > > -void yyrestart (FILE *input_file ); > -void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); > -YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); > -void yy_delete_buffer (YY_BUFFER_STATE b ); > -void yy_flush_buffer (YY_BUFFER_STATE b ); > -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); > -void yypop_buffer_state (void ); > - > -static void yyensure_buffer_stack (void ); > -static void yy_load_buffer_state (void ); > -static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); > +void yyrestart ( FILE *input_file ); > +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); > +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); > +void yy_delete_buffer ( YY_BUFFER_STATE b ); > +void yy_flush_buffer ( YY_BUFFER_STATE b ); > +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); > +void yypop_buffer_state ( void ); > > -#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) > +static void yyensure_buffer_stack ( void ); > +static void yy_load_buffer_state ( void ); > +static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); > +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) > > -YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); > -YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); > -YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); > +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); > +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); > +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); > > -void *yyalloc (yy_size_t ); > -void *yyrealloc (void *,yy_size_t ); > -void yyfree (void * ); > +void *yyalloc ( yy_size_t ); > +void *yyrealloc ( void *, yy_size_t ); > +void yyfree ( void * ); > > #define yy_new_buffer yy_create_buffer > - > #define yy_set_interactive(is_interactive) \ > { \ > if ( ! YY_CURRENT_BUFFER ){ \ > yyensure_buffer_stack (); \ > YY_CURRENT_BUFFER_LVALUE = \ > - yy_create_buffer(yyin,YY_BUF_SIZE ); \ > + yy_create_buffer( yyin, YY_BUF_SIZE ); \ > } \ > YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ > } > - > #define yy_set_bol(at_bol) \ > { \ > if ( ! YY_CURRENT_BUFFER ){\ > yyensure_buffer_stack (); \ > YY_CURRENT_BUFFER_LVALUE = \ > - yy_create_buffer(yyin,YY_BUF_SIZE ); \ > + yy_create_buffer( yyin, YY_BUF_SIZE ); \ > } \ > YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ > } > - > #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) > > /* Begin user sect3 */ > > -#define yywrap() 1 > +#define yywrap() (/*CONSTCOND*/1) > #define YY_SKIP_YYWRAP > +typedef flex_uint8_t YY_CHAR; > > -typedef unsigned char YY_CHAR; > - > -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; > +FILE *yyin = NULL, *yyout = NULL; > > typedef int yy_state_type; > > extern int yylineno; > - > int yylineno = 1; > > extern char *yytext; > +#ifdef yytext_ptr > +#undef yytext_ptr > +#endif > #define yytext_ptr yytext > > -static yy_state_type yy_get_previous_state (void ); > -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); > -static int yy_get_next_buffer (void ); > -static void yy_fatal_error (yyconst char msg[] ); > +static yy_state_type yy_get_previous_state ( void ); > +static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); > +static int yy_get_next_buffer ( void ); > +static void yynoreturn yy_fatal_error ( const char* msg ); > > /* Done after the current pattern has been matched and before the > * corresponding action - sets up yytext. > */ > #define YY_DO_BEFORE_ACTION \ > (yytext_ptr) = yy_bp; \ > - yyleng = (size_t) (yy_cp - yy_bp); \ > + yyleng = (int) (yy_cp - yy_bp); \ > (yy_hold_char) = *yy_cp; \ > *yy_cp = '\0'; \ > (yy_c_buf_p) = yy_cp; > - > -#define YY_NUM_RULES 30 > -#define YY_END_OF_BUFFER 31 > +#define YY_NUM_RULES 31 > +#define YY_END_OF_BUFFER 32 > /* This struct is not used in this scanner, > but its presence is necessary. */ > struct yy_trans_info > @@ -382,28 +364,29 @@ struct yy_trans_info > flex_int32_t yy_verify; > flex_int32_t yy_nxt; > }; > -static yyconst flex_int16_t yy_accept[159] = > +static const flex_int16_t yy_accept[166] = > { 0, > - 0, 0, 0, 0, 0, 0, 0, 0, 31, 29, > - 18, 18, 29, 29, 29, 29, 29, 29, 29, 29, > - 29, 29, 29, 29, 29, 29, 15, 16, 16, 29, > - 16, 10, 10, 18, 26, 0, 3, 0, 27, 12, > - 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, > - 21, 23, 25, 24, 22, 0, 9, 28, 0, 0, > - 0, 14, 14, 16, 16, 16, 10, 10, 10, 0, > - 12, 0, 11, 0, 0, 0, 20, 0, 0, 0, > - 0, 0, 0, 0, 0, 16, 10, 10, 10, 0, > - 13, 19, 0, 0, 0, 0, 0, 0, 0, 0, > - > - 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, > - 0, 16, 6, 0, 0, 0, 0, 0, 0, 2, > - 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, > - 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, > - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, > - 5, 8, 0, 0, 0, 0, 7, 0 > + 0, 0, 0, 0, 0, 0, 0, 0, 32, 30, > + 19, 19, 30, 30, 30, 30, 30, 30, 30, 30, > + 30, 30, 30, 30, 30, 30, 16, 17, 17, 30, > + 17, 11, 11, 19, 27, 0, 3, 0, 28, 13, > + 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, > + 0, 22, 24, 26, 25, 23, 0, 10, 29, 0, > + 0, 0, 15, 15, 17, 17, 17, 11, 11, 11, > + 0, 13, 0, 12, 0, 0, 0, 21, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 17, 11, 11, > + 11, 0, 14, 20, 0, 0, 0, 0, 0, 0, > + > + 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 17, 7, 0, 0, 0, > + 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, > + 0, 0, 0, 0, 4, 18, 0, 0, 5, 2, > + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > + 0, 0, 1, 0, 0, 0, 0, 6, 9, 0, > + 0, 0, 0, 8, 0 > } ; > > -static yyconst flex_int32_t yy_ec[256] = > +static const YY_CHAR yy_ec[256] = > { 0, > 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, > 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, > @@ -416,9 +399,9 @@ static yyconst flex_int32_t yy_ec[256] = > 22, 22, 22, 22, 24, 22, 22, 25, 22, 22, > 1, 26, 27, 1, 22, 1, 21, 28, 29, 30, > > - 31, 21, 22, 22, 32, 22, 22, 33, 34, 35, > - 36, 37, 22, 38, 39, 40, 41, 42, 22, 25, > - 43, 22, 44, 45, 46, 1, 1, 1, 1, 1, > + 31, 21, 32, 22, 33, 22, 22, 34, 35, 36, > + 37, 38, 22, 39, 40, 41, 42, 43, 22, 25, > + 44, 22, 45, 46, 47, 1, 1, 1, 1, 1, > 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, > 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, > 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, > @@ -435,163 +418,165 @@ static yyconst flex_int32_t yy_ec[256] = > 1, 1, 1, 1, 1 > } ; > > -static yyconst flex_int32_t yy_meta[47] = > +static const YY_CHAR yy_meta[48] = > { 0, > 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, > 2, 2, 4, 5, 5, 5, 6, 1, 1, 1, > 7, 8, 8, 8, 8, 1, 1, 7, 7, 7, > 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, > - 8, 8, 8, 3, 1, 4 > + 8, 8, 8, 8, 3, 1, 4 > } ; > > -static yyconst flex_int16_t yy_base[173] = > +static const flex_int16_t yy_base[180] = > { 0, > - 0, 383, 34, 382, 65, 381, 37, 105, 387, 391, > - 54, 111, 367, 110, 109, 109, 112, 41, 366, 104, > - 367, 338, 124, 117, 0, 144, 391, 0, 121, 0, > - 135, 155, 140, 179, 391, 160, 391, 379, 391, 0, > - 368, 141, 391, 167, 370, 376, 346, 103, 342, 345, > - 391, 391, 391, 391, 391, 358, 391, 391, 175, 342, > - 338, 391, 355, 0, 185, 339, 184, 347, 346, 0, > - 0, 322, 175, 357, 175, 363, 352, 324, 330, 323, > - 332, 326, 201, 324, 329, 322, 391, 333, 181, 309, > - 391, 341, 340, 313, 320, 338, 178, 311, 146, 317, > - > - 314, 315, 335, 331, 303, 300, 309, 299, 308, 188, > - 336, 335, 391, 305, 320, 281, 283, 271, 203, 288, > - 281, 271, 266, 264, 245, 242, 208, 104, 391, 391, > - 244, 218, 204, 219, 206, 224, 201, 212, 204, 229, > - 215, 208, 207, 200, 219, 391, 233, 221, 200, 181, > - 391, 391, 149, 122, 86, 41, 391, 391, 245, 251, > - 259, 263, 267, 273, 280, 284, 292, 300, 304, 310, > - 318, 326 > + 0, 393, 35, 392, 66, 391, 38, 107, 397, 401, > + 55, 113, 377, 112, 111, 111, 114, 42, 376, 106, > + 377, 347, 126, 120, 0, 147, 401, 0, 124, 0, > + 137, 158, 170, 163, 401, 153, 401, 389, 401, 0, > + 378, 120, 401, 131, 380, 386, 355, 139, 351, 355, > + 351, 401, 401, 401, 401, 401, 367, 401, 401, 185, > + 350, 346, 401, 364, 0, 185, 347, 189, 356, 355, > + 0, 0, 330, 180, 366, 141, 372, 361, 332, 338, > + 331, 341, 334, 326, 205, 331, 337, 329, 401, 341, > + 167, 316, 401, 349, 348, 320, 328, 346, 180, 318, > + > + 324, 209, 324, 320, 322, 342, 338, 309, 306, 315, > + 305, 315, 312, 192, 342, 341, 401, 293, 306, 282, > + 268, 252, 255, 203, 285, 282, 272, 268, 252, 233, > + 232, 239, 208, 107, 401, 401, 238, 211, 401, 211, > + 212, 208, 228, 203, 215, 207, 233, 222, 212, 211, > + 203, 227, 401, 237, 225, 204, 185, 401, 401, 149, > + 128, 88, 42, 401, 401, 253, 259, 267, 271, 275, > + 281, 288, 292, 300, 308, 312, 318, 326, 334 > } ; > > -static yyconst flex_int16_t yy_def[173] = > +static const flex_int16_t yy_def[180] = > { 0, > - 158, 1, 1, 3, 158, 5, 1, 1, 158, 158, > - 158, 158, 158, 159, 160, 161, 158, 158, 158, 158, > - 162, 158, 158, 158, 163, 162, 158, 164, 165, 164, > - 164, 158, 158, 158, 158, 159, 158, 159, 158, 166, > - 158, 161, 158, 161, 167, 168, 158, 158, 158, 158, > - 158, 158, 158, 158, 158, 162, 158, 158, 158, 158, > - 158, 158, 162, 164, 165, 164, 158, 158, 158, 169, > - 166, 170, 161, 167, 167, 168, 158, 158, 158, 158, > - 158, 158, 158, 158, 158, 164, 158, 158, 169, 170, > - 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, > - > - 158, 164, 158, 158, 158, 158, 158, 158, 158, 171, > - 158, 164, 158, 158, 158, 158, 158, 158, 171, 158, > - 171, 158, 158, 158, 158, 158, 158, 158, 158, 158, > - 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, > - 172, 158, 158, 158, 172, 158, 172, 158, 158, 158, > - 158, 158, 158, 158, 158, 158, 158, 0, 158, 158, > - 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, > - 158, 158 > + 165, 1, 1, 3, 165, 5, 1, 1, 165, 165, > + 165, 165, 165, 166, 167, 168, 165, 165, 165, 165, > + 169, 165, 165, 165, 170, 169, 165, 171, 172, 171, > + 171, 165, 165, 165, 165, 166, 165, 166, 165, 173, > + 165, 168, 165, 168, 174, 175, 165, 165, 165, 165, > + 165, 165, 165, 165, 165, 165, 169, 165, 165, 165, > + 165, 165, 165, 169, 171, 172, 171, 165, 165, 165, > + 176, 173, 177, 168, 174, 174, 175, 165, 165, 165, > + 165, 165, 165, 165, 165, 165, 165, 171, 165, 165, > + 176, 177, 165, 165, 165, 165, 165, 165, 165, 165, > + > + 165, 165, 165, 165, 171, 165, 165, 165, 165, 165, > + 165, 165, 165, 178, 165, 171, 165, 165, 165, 165, > + 165, 165, 165, 178, 165, 178, 165, 165, 165, 165, > + 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, > + 165, 165, 165, 165, 165, 165, 165, 179, 165, 165, > + 165, 179, 165, 179, 165, 165, 165, 165, 165, 165, > + 165, 165, 165, 165, 0, 165, 165, 165, 165, 165, > + 165, 165, 165, 165, 165, 165, 165, 165, 165 > } ; > > -static yyconst flex_int16_t yy_nxt[438] = > +static const flex_int16_t yy_nxt[449] = > { 0, > 10, 11, 12, 11, 13, 14, 10, 15, 16, 10, > 10, 10, 17, 10, 10, 10, 10, 18, 19, 20, > 21, 21, 21, 21, 21, 10, 10, 21, 21, 21, > 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, > - 21, 21, 21, 10, 22, 10, 24, 25, 25, 25, > - 32, 33, 33, 157, 26, 34, 34, 34, 51, 52, > - 27, 26, 26, 26, 26, 10, 11, 12, 11, 13, > - 14, 28, 15, 16, 28, 28, 28, 24, 28, 28, > - 28, 10, 18, 19, 20, 29, 29, 29, 29, 29, > - 30, 10, 29, 29, 29, 29, 29, 29, 29, 29, > - > - 29, 29, 29, 29, 29, 29, 29, 29, 10, 22, > - 10, 23, 34, 34, 34, 37, 39, 43, 32, 33, > - 33, 45, 54, 55, 46, 59, 45, 64, 156, 46, > - 64, 64, 64, 79, 44, 38, 59, 57, 134, 47, > - 135, 48, 80, 49, 47, 50, 48, 99, 61, 43, > - 50, 110, 41, 67, 67, 67, 60, 63, 63, 63, > - 57, 155, 68, 69, 63, 37, 44, 66, 67, 67, > - 67, 63, 63, 63, 63, 73, 59, 68, 69, 70, > - 34, 34, 34, 43, 75, 38, 154, 92, 83, 83, > - 83, 64, 44, 120, 64, 64, 64, 67, 67, 67, > - > - 44, 57, 99, 68, 69, 107, 68, 69, 120, 127, > - 108, 153, 152, 121, 83, 83, 83, 133, 133, 133, > - 146, 133, 133, 133, 146, 140, 140, 140, 121, 141, > - 140, 140, 140, 151, 141, 158, 150, 149, 148, 144, > - 147, 143, 142, 139, 147, 36, 36, 36, 36, 36, > - 36, 36, 36, 40, 138, 137, 136, 40, 40, 42, > - 42, 42, 42, 42, 42, 42, 42, 56, 56, 56, > - 56, 62, 132, 62, 64, 131, 130, 64, 129, 64, > - 64, 65, 128, 158, 65, 65, 65, 65, 71, 127, > - 71, 71, 74, 74, 74, 74, 74, 74, 74, 74, > - > - 76, 76, 76, 76, 76, 76, 76, 76, 89, 126, > - 89, 90, 125, 90, 90, 124, 90, 90, 119, 119, > - 119, 119, 119, 119, 119, 119, 145, 145, 145, 145, > - 145, 145, 145, 145, 123, 122, 59, 59, 118, 117, > - 116, 115, 114, 113, 45, 112, 108, 111, 109, 106, > - 105, 104, 46, 103, 91, 87, 102, 101, 100, 98, > - 97, 96, 95, 94, 93, 77, 75, 91, 88, 87, > - 86, 57, 85, 84, 57, 82, 81, 78, 77, 75, > - 72, 158, 58, 57, 53, 35, 158, 31, 23, 23, > - 9, 158, 158, 158, 158, 158, 158, 158, 158, 158, > - > - 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, > - 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, > - 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, > - 158, 158, 158, 158, 158, 158, 158 > + 21, 21, 21, 21, 10, 22, 10, 24, 25, 25, > + 25, 32, 33, 33, 164, 26, 34, 34, 34, 52, > + 53, 27, 26, 26, 26, 26, 10, 11, 12, 11, > + 13, 14, 28, 15, 16, 28, 28, 28, 24, 28, > + 28, 28, 10, 18, 19, 20, 29, 29, 29, 29, > + 29, 30, 10, 29, 29, 29, 29, 29, 29, 29, > + > + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, > + 10, 22, 10, 23, 34, 34, 34, 37, 39, 43, > + 32, 33, 33, 45, 55, 56, 46, 60, 43, 45, > + 65, 163, 46, 65, 65, 65, 44, 38, 60, 74, > + 58, 47, 141, 48, 142, 44, 49, 47, 50, 48, > + 76, 51, 62, 94, 50, 41, 44, 51, 37, 61, > + 64, 64, 64, 58, 34, 34, 34, 64, 162, 80, > + 67, 68, 68, 68, 64, 64, 64, 64, 38, 81, > + 69, 70, 71, 68, 68, 68, 60, 161, 43, 69, > + 70, 65, 69, 70, 65, 65, 65, 125, 85, 85, > + > + 85, 58, 68, 68, 68, 44, 102, 110, 125, 133, > + 102, 69, 70, 111, 114, 160, 159, 126, 85, 85, > + 85, 140, 140, 140, 140, 140, 140, 153, 126, 147, > + 147, 147, 153, 148, 147, 147, 147, 158, 148, 165, > + 157, 156, 155, 151, 150, 149, 146, 154, 145, 144, > + 143, 139, 154, 36, 36, 36, 36, 36, 36, 36, > + 36, 40, 138, 137, 136, 40, 40, 42, 42, 42, > + 42, 42, 42, 42, 42, 57, 57, 57, 57, 63, > + 135, 63, 65, 134, 165, 65, 133, 65, 65, 66, > + 132, 131, 66, 66, 66, 66, 72, 130, 72, 72, > + > + 75, 75, 75, 75, 75, 75, 75, 75, 77, 77, > + 77, 77, 77, 77, 77, 77, 91, 129, 91, 92, > + 128, 92, 92, 127, 92, 92, 124, 124, 124, 124, > + 124, 124, 124, 124, 152, 152, 152, 152, 152, 152, > + 152, 152, 60, 60, 123, 122, 121, 120, 119, 118, > + 117, 45, 116, 111, 115, 113, 112, 109, 108, 107, > + 46, 106, 93, 89, 105, 104, 103, 101, 100, 99, > + 98, 97, 96, 95, 78, 76, 93, 90, 89, 88, > + 58, 87, 86, 58, 84, 83, 82, 79, 78, 76, > + 73, 165, 59, 58, 54, 35, 165, 31, 23, 23, > + > + 9, 165, 165, 165, 165, 165, 165, 165, 165, 165, > + 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, > + 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, > + 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, > + 165, 165, 165, 165, 165, 165, 165, 165 > } ; > > -static yyconst flex_int16_t yy_chk[438] = > +static const flex_int16_t yy_chk[449] = > { 0, > 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, > 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, > 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, > 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, > - 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, > - 7, 7, 7, 156, 3, 11, 11, 11, 18, 18, > - 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, > + 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, > + 3, 7, 7, 7, 163, 3, 11, 11, 11, 18, > + 18, 3, 3, 3, 3, 3, 5, 5, 5, 5, > 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, > 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, > 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, > > 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, > - 5, 8, 12, 12, 12, 14, 15, 16, 8, 8, > - 8, 17, 20, 20, 17, 23, 24, 29, 155, 24, > - 29, 29, 29, 48, 16, 14, 31, 29, 128, 17, > - 128, 17, 48, 17, 24, 17, 24, 99, 24, 42, > - 24, 99, 15, 33, 33, 33, 23, 26, 26, 26, > - 26, 154, 33, 33, 26, 36, 42, 31, 32, 32, > - 32, 26, 26, 26, 26, 44, 59, 32, 32, 32, > - 34, 34, 34, 73, 75, 36, 153, 75, 59, 59, > - 59, 65, 44, 110, 65, 65, 65, 67, 67, 67, > - > - 73, 65, 83, 89, 89, 97, 67, 67, 119, 127, > - 97, 150, 149, 110, 83, 83, 83, 133, 133, 133, > - 141, 127, 127, 127, 145, 136, 136, 136, 119, 136, > - 140, 140, 140, 148, 140, 147, 144, 143, 142, 139, > - 141, 138, 137, 135, 145, 159, 159, 159, 159, 159, > - 159, 159, 159, 160, 134, 132, 131, 160, 160, 161, > - 161, 161, 161, 161, 161, 161, 161, 162, 162, 162, > - 162, 163, 126, 163, 164, 125, 124, 164, 123, 164, > - 164, 165, 122, 121, 165, 165, 165, 165, 166, 120, > - 166, 166, 167, 167, 167, 167, 167, 167, 167, 167, > - > - 168, 168, 168, 168, 168, 168, 168, 168, 169, 118, > - 169, 170, 117, 170, 170, 116, 170, 170, 171, 171, > - 171, 171, 171, 171, 171, 171, 172, 172, 172, 172, > - 172, 172, 172, 172, 115, 114, 112, 111, 109, 108, > - 107, 106, 105, 104, 103, 102, 101, 100, 98, 96, > - 95, 94, 93, 92, 90, 88, 86, 85, 84, 82, > - 81, 80, 79, 78, 77, 76, 74, 72, 69, 68, > - 66, 63, 61, 60, 56, 50, 49, 47, 46, 45, > + 5, 5, 5, 8, 12, 12, 12, 14, 15, 16, > + 8, 8, 8, 17, 20, 20, 17, 23, 42, 24, > + 29, 162, 24, 29, 29, 29, 16, 14, 31, 44, > + 29, 17, 134, 17, 134, 42, 17, 24, 17, 24, > + 76, 17, 24, 76, 24, 15, 44, 24, 36, 23, > + 26, 26, 26, 26, 34, 34, 34, 26, 161, 48, > + 31, 32, 32, 32, 26, 26, 26, 26, 36, 48, > + 32, 32, 32, 33, 33, 33, 60, 160, 74, 91, > + 91, 66, 33, 33, 66, 66, 66, 114, 60, 60, > + > + 60, 66, 68, 68, 68, 74, 85, 99, 124, 133, > + 102, 68, 68, 99, 102, 157, 156, 114, 85, 85, > + 85, 133, 133, 133, 140, 140, 140, 148, 124, 143, > + 143, 143, 152, 143, 147, 147, 147, 155, 147, 154, > + 151, 150, 149, 146, 145, 144, 142, 148, 141, 138, > + 137, 132, 152, 166, 166, 166, 166, 166, 166, 166, > + 166, 167, 131, 130, 129, 167, 167, 168, 168, 168, > + 168, 168, 168, 168, 168, 169, 169, 169, 169, 170, > + 128, 170, 171, 127, 126, 171, 125, 171, 171, 172, > + 123, 122, 172, 172, 172, 172, 173, 121, 173, 173, > + > + 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, > + 175, 175, 175, 175, 175, 175, 176, 120, 176, 177, > + 119, 177, 177, 118, 177, 177, 178, 178, 178, 178, > + 178, 178, 178, 178, 179, 179, 179, 179, 179, 179, > + 179, 179, 116, 115, 113, 112, 111, 110, 109, 108, > + 107, 106, 105, 104, 103, 101, 100, 98, 97, 96, > + 95, 94, 92, 90, 88, 87, 86, 84, 83, 82, > + 81, 80, 79, 78, 77, 75, 73, 70, 69, 67, > + 64, 62, 61, 57, 51, 50, 49, 47, 46, 45, > 41, 38, 22, 21, 19, 13, 9, 6, 4, 2, > - 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, > > - 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, > - 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, > - 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, > - 158, 158, 158, 158, 158, 158, 158 > + 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, > + 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, > + 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, > + 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, > + 165, 165, 165, 165, 165, 165, 165, 165 > } ; > > static yy_state_type yy_last_accepting_state; > @@ -608,7 +593,7 @@ int yy_flex_debug = 0; > #define YY_MORE_ADJ 0 > #define YY_RESTORE_YY_MORE_OFFSET > char *yytext; > -#line 1 "dtc-lexer.l" > +#line 1 "<stdin>" > /* > * (C) Copyright David Gibson <dwg@xxxxxxxxxxx>, IBM Corporation. 2005. > * > @@ -632,7 +617,7 @@ char *yytext; > > > > -#line 37 "dtc-lexer.l" > +#line 37 "<stdin>" > #include "dtc.h" > #include "srcpos.h" > #include "dtc-parser.tab.h" > @@ -661,8 +646,10 @@ static int dts_version = 1; > > static void push_input_file(const char *filename); > static bool pop_input_file(void); > -static void lexical_error(const char *fmt, ...); > -#line 666 "dtc-lexer.lex.c" > +static void PRINTF(1, 2) lexical_error(const char *fmt, ...); > + > +#line 652 "dtc-lexer.l.c" > +#line 653 "dtc-lexer.l.c" > > #define INITIAL 0 > #define BYTESTRING 1 > @@ -681,36 +668,36 @@ static void lexical_error(const char *fmt, ...); > #define YY_EXTRA_TYPE void * > #endif > > -static int yy_init_globals (void ); > +static int yy_init_globals ( void ); > > /* Accessor methods to globals. > These are made visible to non-reentrant scanners for convenience. */ > > -int yylex_destroy (void ); > +int yylex_destroy ( void ); > > -int yyget_debug (void ); > +int yyget_debug ( void ); > > -void yyset_debug (int debug_flag ); > +void yyset_debug ( int debug_flag ); > > -YY_EXTRA_TYPE yyget_extra (void ); > +YY_EXTRA_TYPE yyget_extra ( void ); > > -void yyset_extra (YY_EXTRA_TYPE user_defined ); > +void yyset_extra ( YY_EXTRA_TYPE user_defined ); > > -FILE *yyget_in (void ); > +FILE *yyget_in ( void ); > > -void yyset_in (FILE * in_str ); > +void yyset_in ( FILE * _in_str ); > > -FILE *yyget_out (void ); > +FILE *yyget_out ( void ); > > -void yyset_out (FILE * out_str ); > +void yyset_out ( FILE * _out_str ); > > -yy_size_t yyget_leng (void ); > + int yyget_leng ( void ); > > -char *yyget_text (void ); > +char *yyget_text ( void ); > > -int yyget_lineno (void ); > +int yyget_lineno ( void ); > > -void yyset_lineno (int line_number ); > +void yyset_lineno ( int _line_number ); > > /* Macros after this point can all be overridden by user definitions in > * section 1. > @@ -718,26 +705,29 @@ void yyset_lineno (int line_number ); > > #ifndef YY_SKIP_YYWRAP > #ifdef __cplusplus > -extern "C" int yywrap (void ); > +extern "C" int yywrap ( void ); > #else > -extern int yywrap (void ); > +extern int yywrap ( void ); > +#endif > #endif > + > +#ifndef YY_NO_UNPUT > + > #endif > > #ifndef yytext_ptr > -static void yy_flex_strncpy (char *,yyconst char *,int ); > +static void yy_flex_strncpy ( char *, const char *, int ); > #endif > > #ifdef YY_NEED_STRLEN > -static int yy_flex_strlen (yyconst char * ); > +static int yy_flex_strlen ( const char * ); > #endif > > #ifndef YY_NO_INPUT > - > #ifdef __cplusplus > -static int yyinput (void ); > +static int yyinput ( void ); > #else > -static int input (void ); > +static int input ( void ); > #endif > > #endif > @@ -757,7 +747,7 @@ static int input (void ); > /* This used to be an fputs(), but since the string might contain NUL's, > * we now use fwrite(). > */ > -#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) > +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) > #endif > > /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, > @@ -768,7 +758,7 @@ static int input (void ); > if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ > { \ > int c = '*'; \ > - size_t n; \ > + int n; \ > for ( n = 0; n < max_size && \ > (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ > buf[n] = (char) c; \ > @@ -781,7 +771,7 @@ static int input (void ); > else \ > { \ > errno=0; \ > - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ > + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ > { \ > if( errno != EINTR) \ > { \ > @@ -836,7 +826,7 @@ extern int yylex (void); > > /* Code executed at the end of each rule. */ > #ifndef YY_BREAK > -#define YY_BREAK break; > +#define YY_BREAK /*LINTED*/break; > #endif > > #define YY_RULE_SETUP \ > @@ -849,9 +839,9 @@ extern int yylex (void); > */ > YY_DECL > { > - register yy_state_type yy_current_state; > - register char *yy_cp, *yy_bp; > - register int yy_act; > + yy_state_type yy_current_state; > + char *yy_cp, *yy_bp; > + int yy_act; > > if ( !(yy_init) ) > { > @@ -873,18 +863,18 @@ YY_DECL > if ( ! YY_CURRENT_BUFFER ) { > yyensure_buffer_stack (); > YY_CURRENT_BUFFER_LVALUE = > - yy_create_buffer(yyin,YY_BUF_SIZE ); > + yy_create_buffer( yyin, YY_BUF_SIZE ); > } > > - yy_load_buffer_state( ); > + yy_load_buffer_state( ); > } > > { > -#line 68 "dtc-lexer.l" > +#line 69 "<stdin>" > > -#line 886 "dtc-lexer.lex.c" > +#line 876 "dtc-lexer.l.c" > > - while ( 1 ) /* loops until end-of-file is reached */ > + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ > { > yy_cp = (yy_c_buf_p); > > @@ -901,7 +891,7 @@ YY_DECL > yy_match: > do > { > - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; > + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; > if ( yy_accept[yy_current_state] ) > { > (yy_last_accepting_state) = yy_current_state; > @@ -910,13 +900,13 @@ yy_match: > while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) > { > yy_current_state = (int) yy_def[yy_current_state]; > - if ( yy_current_state >= 159 ) > - yy_c = yy_meta[(unsigned int) yy_c]; > + if ( yy_current_state >= 166 ) > + yy_c = yy_meta[yy_c]; > } > - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; > + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; > ++yy_cp; > } > - while ( yy_current_state != 158 ); > + while ( yy_current_state != 165 ); > yy_cp = (yy_last_accepting_cpos); > yy_current_state = (yy_last_accepting_state); > > @@ -939,7 +929,7 @@ do_action: /* This label is used only to access EOF actions. */ > case 1: > /* rule 1 can match eol */ > YY_RULE_SETUP > -#line 69 "dtc-lexer.l" > +#line 70 "<stdin>" > { > char *name = strchr(yytext, '\"') + 1; > yytext[yyleng-1] = '\0'; > @@ -949,33 +939,41 @@ YY_RULE_SETUP > case 2: > /* rule 2 can match eol */ > YY_RULE_SETUP > -#line 75 "dtc-lexer.l" > +#line 76 "<stdin>" > { > - char *line, *tmp, *fn; > + char *line, *fnstart, *fnend; > + struct data fn; > /* skip text before line # */ > line = yytext; > while (!isdigit((unsigned char)*line)) > line++; > - /* skip digits in line # */ > - tmp = line; > - while (!isspace((unsigned char)*tmp)) > - tmp++; > - /* "NULL"-terminate line # */ > - *tmp = '\0'; > - /* start of filename */ > - fn = strchr(tmp + 1, '"') + 1; > - /* strip trailing " from filename */ > - tmp = strchr(fn, '"'); > - *tmp = 0; > + > + /* regexp ensures that first and list " > + * in the whole yytext are those at > + * beginning and end of the filename string */ > + fnstart = memchr(yytext, '"', yyleng); > + for (fnend = yytext + yyleng - 1; > + *fnend != '"'; fnend--) > + ; > + assert(fnstart && fnend && (fnend > fnstart)); > + > + fn = data_copy_escape_string(fnstart + 1, > + fnend - fnstart - 1); > + > + /* Don't allow nuls in filenames */ > + if (memchr(fn.val, '\0', fn.len - 1)) > + lexical_error("nul in line number directive"); > + > /* -1 since #line is the number of the next line */ > - srcpos_set_line(xstrdup(fn), atoi(line) - 1); > + srcpos_set_line(xstrdup(fn.val), atoi(line) - 1); > + data_free(fn); > } > YY_BREAK > case YY_STATE_EOF(INITIAL): > case YY_STATE_EOF(BYTESTRING): > case YY_STATE_EOF(PROPNODENAME): > case YY_STATE_EOF(V1): > -#line 96 "dtc-lexer.l" > +#line 105 "<stdin>" > { > if (!pop_input_file()) { > yyterminate(); > @@ -985,7 +983,7 @@ case YY_STATE_EOF(V1): > case 3: > /* rule 3 can match eol */ > YY_RULE_SETUP > -#line 102 "dtc-lexer.l" > +#line 111 "<stdin>" > { > DPRINT("String: %s\n", yytext); > yylval.data = data_copy_escape_string(yytext+1, > @@ -995,7 +993,7 @@ YY_RULE_SETUP > YY_BREAK > case 4: > YY_RULE_SETUP > -#line 109 "dtc-lexer.l" > +#line 118 "<stdin>" > { > DPRINT("Keyword: /dts-v1/\n"); > dts_version = 1; > @@ -1005,25 +1003,33 @@ YY_RULE_SETUP > YY_BREAK > case 5: > YY_RULE_SETUP > -#line 116 "dtc-lexer.l" > +#line 125 "<stdin>" > +{ > + DPRINT("Keyword: /plugin/\n"); > + return DT_PLUGIN; > + } > + YY_BREAK > +case 6: > +YY_RULE_SETUP > +#line 130 "<stdin>" > { > DPRINT("Keyword: /memreserve/\n"); > BEGIN_DEFAULT(); > return DT_MEMRESERVE; > } > YY_BREAK > -case 6: > +case 7: > YY_RULE_SETUP > -#line 122 "dtc-lexer.l" > +#line 136 "<stdin>" > { > DPRINT("Keyword: /bits/\n"); > BEGIN_DEFAULT(); > return DT_BITS; > } > YY_BREAK > -case 7: > +case 8: > YY_RULE_SETUP > -#line 128 "dtc-lexer.l" > +#line 142 "<stdin>" > { > DPRINT("Keyword: /delete-property/\n"); > DPRINT("<PROPNODENAME>\n"); > @@ -1031,9 +1037,9 @@ YY_RULE_SETUP > return DT_DEL_PROP; > } > YY_BREAK > -case 8: > +case 9: > YY_RULE_SETUP > -#line 135 "dtc-lexer.l" > +#line 149 "<stdin>" > { > DPRINT("Keyword: /delete-node/\n"); > DPRINT("<PROPNODENAME>\n"); > @@ -1041,9 +1047,9 @@ YY_RULE_SETUP > return DT_DEL_NODE; > } > YY_BREAK > -case 9: > +case 10: > YY_RULE_SETUP > -#line 142 "dtc-lexer.l" > +#line 156 "<stdin>" > { > DPRINT("Label: %s\n", yytext); > yylval.labelref = xstrdup(yytext); > @@ -1051,9 +1057,9 @@ YY_RULE_SETUP > return DT_LABEL; > } > YY_BREAK > -case 10: > +case 11: > YY_RULE_SETUP > -#line 149 "dtc-lexer.l" > +#line 163 "<stdin>" > { > char *e; > DPRINT("Integer Literal: '%s'\n", yytext); > @@ -1061,7 +1067,10 @@ YY_RULE_SETUP > errno = 0; > yylval.integer = strtoull(yytext, &e, 0); > > - assert(!(*e) || !e[strspn(e, "UL")]); > + if (*e && e[strspn(e, "UL")]) { > + lexical_error("Bad integer literal '%s'", > + yytext); > + } > > if (errno == ERANGE) > lexical_error("Integer literal '%s' out of range", > @@ -1073,10 +1082,10 @@ YY_RULE_SETUP > return DT_LITERAL; > } > YY_BREAK > -case 11: > -/* rule 11 can match eol */ > +case 12: > +/* rule 12 can match eol */ > YY_RULE_SETUP > -#line 168 "dtc-lexer.l" > +#line 185 "<stdin>" > { > struct data d; > DPRINT("Character literal: %s\n", yytext); > @@ -1085,31 +1094,31 @@ YY_RULE_SETUP > if (d.len == 1) { > lexical_error("Empty character literal"); > yylval.integer = 0; > - return DT_CHAR_LITERAL; > - } > + } else { > + yylval.integer = (unsigned char)d.val[0]; > > - yylval.integer = (unsigned char)d.val[0]; > - > - if (d.len > 2) > - lexical_error("Character literal has %d" > - " characters instead of 1", > - d.len - 1); > + if (d.len > 2) > + lexical_error("Character literal has %d" > + " characters instead of 1", > + d.len - 1); > + } > > + data_free(d); > return DT_CHAR_LITERAL; > } > YY_BREAK > -case 12: > +case 13: > YY_RULE_SETUP > -#line 189 "dtc-lexer.l" > +#line 206 "<stdin>" > { /* label reference */ > DPRINT("Ref: %s\n", yytext+1); > yylval.labelref = xstrdup(yytext+1); > return DT_REF; > } > YY_BREAK > -case 13: > +case 14: > YY_RULE_SETUP > -#line 195 "dtc-lexer.l" > +#line 212 "<stdin>" > { /* new-style path reference */ > yytext[yyleng-1] = '\0'; > DPRINT("Ref: %s\n", yytext+2); > @@ -1117,27 +1126,27 @@ YY_RULE_SETUP > return DT_REF; > } > YY_BREAK > -case 14: > +case 15: > YY_RULE_SETUP > -#line 202 "dtc-lexer.l" > +#line 219 "<stdin>" > { > yylval.byte = strtol(yytext, NULL, 16); > DPRINT("Byte: %02x\n", (int)yylval.byte); > return DT_BYTE; > } > YY_BREAK > -case 15: > +case 16: > YY_RULE_SETUP > -#line 208 "dtc-lexer.l" > +#line 225 "<stdin>" > { > DPRINT("/BYTESTRING\n"); > BEGIN_DEFAULT(); > return ']'; > } > YY_BREAK > -case 16: > +case 17: > YY_RULE_SETUP > -#line 214 "dtc-lexer.l" > +#line 231 "<stdin>" > { > DPRINT("PropNodeName: %s\n", yytext); > yylval.propnodename = xstrdup((yytext[0] == '\\') ? > @@ -1146,75 +1155,75 @@ YY_RULE_SETUP > return DT_PROPNODENAME; > } > YY_BREAK > -case 17: > +case 18: > YY_RULE_SETUP > -#line 222 "dtc-lexer.l" > +#line 239 "<stdin>" > { > DPRINT("Binary Include\n"); > return DT_INCBIN; > } > YY_BREAK > -case 18: > -/* rule 18 can match eol */ > -YY_RULE_SETUP > -#line 227 "dtc-lexer.l" > -/* eat whitespace */ > - YY_BREAK > case 19: > /* rule 19 can match eol */ > YY_RULE_SETUP > -#line 228 "dtc-lexer.l" > -/* eat C-style comments */ > +#line 244 "<stdin>" > +/* eat whitespace */ > YY_BREAK > case 20: > /* rule 20 can match eol */ > YY_RULE_SETUP > -#line 229 "dtc-lexer.l" > -/* eat C++-style comments */ > +#line 245 "<stdin>" > +/* eat C-style comments */ > YY_BREAK > case 21: > +/* rule 21 can match eol */ > YY_RULE_SETUP > -#line 231 "dtc-lexer.l" > -{ return DT_LSHIFT; }; > +#line 246 "<stdin>" > +/* eat C++-style comments */ > YY_BREAK > case 22: > YY_RULE_SETUP > -#line 232 "dtc-lexer.l" > -{ return DT_RSHIFT; }; > +#line 248 "<stdin>" > +{ return DT_LSHIFT; }; > YY_BREAK > case 23: > YY_RULE_SETUP > -#line 233 "dtc-lexer.l" > -{ return DT_LE; }; > +#line 249 "<stdin>" > +{ return DT_RSHIFT; }; > YY_BREAK > case 24: > YY_RULE_SETUP > -#line 234 "dtc-lexer.l" > -{ return DT_GE; }; > +#line 250 "<stdin>" > +{ return DT_LE; }; > YY_BREAK > case 25: > YY_RULE_SETUP > -#line 235 "dtc-lexer.l" > -{ return DT_EQ; }; > +#line 251 "<stdin>" > +{ return DT_GE; }; > YY_BREAK > case 26: > YY_RULE_SETUP > -#line 236 "dtc-lexer.l" > -{ return DT_NE; }; > +#line 252 "<stdin>" > +{ return DT_EQ; }; > YY_BREAK > case 27: > YY_RULE_SETUP > -#line 237 "dtc-lexer.l" > -{ return DT_AND; }; > +#line 253 "<stdin>" > +{ return DT_NE; }; > YY_BREAK > case 28: > YY_RULE_SETUP > -#line 238 "dtc-lexer.l" > -{ return DT_OR; }; > +#line 254 "<stdin>" > +{ return DT_AND; }; > YY_BREAK > case 29: > YY_RULE_SETUP > -#line 240 "dtc-lexer.l" > +#line 255 "<stdin>" > +{ return DT_OR; }; > + YY_BREAK > +case 30: > +YY_RULE_SETUP > +#line 257 "<stdin>" > { > DPRINT("Char: %c (\\x%02x)\n", yytext[0], > (unsigned)yytext[0]); > @@ -1230,12 +1239,12 @@ YY_RULE_SETUP > return yytext[0]; > } > YY_BREAK > -case 30: > +case 31: > YY_RULE_SETUP > -#line 255 "dtc-lexer.l" > +#line 272 "<stdin>" > ECHO; > YY_BREAK > -#line 1239 "dtc-lexer.lex.c" > +#line 1248 "dtc-lexer.l.c" > > case YY_END_OF_BUFFER: > { > @@ -1312,7 +1321,7 @@ ECHO; > { > (yy_did_buffer_switch_on_eof) = 0; > > - if ( yywrap( ) ) > + if ( yywrap( ) ) > { > /* Note: because we've taken care in > * yy_get_next_buffer() to have set up > @@ -1377,9 +1386,9 @@ ECHO; > */ > static int yy_get_next_buffer (void) > { > - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; > - register char *source = (yytext_ptr); > - register int number_to_move, i; > + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; > + char *source = (yytext_ptr); > + int number_to_move, i; > int ret_val; > > if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) > @@ -1408,7 +1417,7 @@ static int yy_get_next_buffer (void) > /* Try to read more data. */ > > /* First move last chars to start of buffer. */ > - number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; > + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); > > for ( i = 0; i < number_to_move; ++i ) > *(dest++) = *(source++); > @@ -1421,7 +1430,7 @@ static int yy_get_next_buffer (void) > > else > { > - yy_size_t num_to_read = > + int num_to_read = > YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; > > while ( num_to_read <= 0 ) > @@ -1435,7 +1444,7 @@ static int yy_get_next_buffer (void) > > if ( b->yy_is_our_buffer ) > { > - yy_size_t new_size = b->yy_buf_size * 2; > + int new_size = b->yy_buf_size * 2; > > if ( new_size <= 0 ) > b->yy_buf_size += b->yy_buf_size / 8; > @@ -1444,11 +1453,12 @@ static int yy_get_next_buffer (void) > > b->yy_ch_buf = (char *) > /* Include room in for 2 EOB chars. */ > - yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); > + yyrealloc( (void *) b->yy_ch_buf, > + (yy_size_t) (b->yy_buf_size + 2) ); > } > else > /* Can't grow it, we don't own it. */ > - b->yy_ch_buf = 0; > + b->yy_ch_buf = NULL; > > if ( ! b->yy_ch_buf ) > YY_FATAL_ERROR( > @@ -1476,7 +1486,7 @@ static int yy_get_next_buffer (void) > if ( number_to_move == YY_MORE_ADJ ) > { > ret_val = EOB_ACT_END_OF_FILE; > - yyrestart(yyin ); > + yyrestart( yyin ); > } > > else > @@ -1490,12 +1500,15 @@ static int yy_get_next_buffer (void) > else > ret_val = EOB_ACT_CONTINUE_SCAN; > > - if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { > + if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { > /* Extend the array by 50%, plus the number we really need. */ > - yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); > - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); > + int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); > + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( > + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); > if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) > YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); > + /* "- 2" to take care of EOB's */ > + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); > } > > (yy_n_chars) += number_to_move; > @@ -1511,15 +1524,15 @@ static int yy_get_next_buffer (void) > > static yy_state_type yy_get_previous_state (void) > { > - register yy_state_type yy_current_state; > - register char *yy_cp; > + yy_state_type yy_current_state; > + char *yy_cp; > > yy_current_state = (yy_start); > yy_current_state += YY_AT_BOL(); > > for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) > { > - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); > + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); > if ( yy_accept[yy_current_state] ) > { > (yy_last_accepting_state) = yy_current_state; > @@ -1528,10 +1541,10 @@ static int yy_get_next_buffer (void) > while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) > { > yy_current_state = (int) yy_def[yy_current_state]; > - if ( yy_current_state >= 159 ) > - yy_c = yy_meta[(unsigned int) yy_c]; > + if ( yy_current_state >= 166 ) > + yy_c = yy_meta[yy_c]; > } > - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; > + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; > } > > return yy_current_state; > @@ -1544,10 +1557,10 @@ static int yy_get_next_buffer (void) > */ > static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) > { > - register int yy_is_jam; > - register char *yy_cp = (yy_c_buf_p); > + int yy_is_jam; > + char *yy_cp = (yy_c_buf_p); > > - register YY_CHAR yy_c = 1; > + YY_CHAR yy_c = 1; > if ( yy_accept[yy_current_state] ) > { > (yy_last_accepting_state) = yy_current_state; > @@ -1556,15 +1569,19 @@ static int yy_get_next_buffer (void) > while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) > { > yy_current_state = (int) yy_def[yy_current_state]; > - if ( yy_current_state >= 159 ) > - yy_c = yy_meta[(unsigned int) yy_c]; > + if ( yy_current_state >= 166 ) > + yy_c = yy_meta[yy_c]; > } > - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; > - yy_is_jam = (yy_current_state == 158); > + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; > + yy_is_jam = (yy_current_state == 165); > > return yy_is_jam ? 0 : yy_current_state; > } > > +#ifndef YY_NO_UNPUT > + > +#endif > + > #ifndef YY_NO_INPUT > #ifdef __cplusplus > static int yyinput (void) > @@ -1589,7 +1606,7 @@ static int yy_get_next_buffer (void) > > else > { /* need more input */ > - yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); > + int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); > ++(yy_c_buf_p); > > switch ( yy_get_next_buffer( ) ) > @@ -1606,14 +1623,14 @@ static int yy_get_next_buffer (void) > */ > > /* Reset buffer status. */ > - yyrestart(yyin ); > + yyrestart( yyin ); > > /*FALLTHROUGH*/ > > case EOB_ACT_END_OF_FILE: > { > - if ( yywrap( ) ) > - return EOF; > + if ( yywrap( ) ) > + return 0; > > if ( ! (yy_did_buffer_switch_on_eof) ) > YY_NEW_FILE; > @@ -1652,11 +1669,11 @@ static int yy_get_next_buffer (void) > if ( ! YY_CURRENT_BUFFER ){ > yyensure_buffer_stack (); > YY_CURRENT_BUFFER_LVALUE = > - yy_create_buffer(yyin,YY_BUF_SIZE ); > + yy_create_buffer( yyin, YY_BUF_SIZE ); > } > > - yy_init_buffer(YY_CURRENT_BUFFER,input_file ); > - yy_load_buffer_state( ); > + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); > + yy_load_buffer_state( ); > } > > /** Switch to a different input buffer. > @@ -1684,7 +1701,7 @@ static int yy_get_next_buffer (void) > } > > YY_CURRENT_BUFFER_LVALUE = new_buffer; > - yy_load_buffer_state( ); > + yy_load_buffer_state( ); > > /* We don't actually know whether we did this switch during > * EOF (yywrap()) processing, but the only time this flag > @@ -1712,7 +1729,7 @@ static void yy_load_buffer_state (void) > { > YY_BUFFER_STATE b; > > - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); > + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); > if ( ! b ) > YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); > > @@ -1721,13 +1738,13 @@ static void yy_load_buffer_state (void) > /* yy_ch_buf has to be 2 characters longer than the size given because > * we need to put in 2 end-of-buffer characters. > */ > - b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); > + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); > if ( ! b->yy_ch_buf ) > YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); > > b->yy_is_our_buffer = 1; > > - yy_init_buffer(b,file ); > + yy_init_buffer( b, file ); > > return b; > } > @@ -1746,9 +1763,9 @@ static void yy_load_buffer_state (void) > YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; > > if ( b->yy_is_our_buffer ) > - yyfree((void *) b->yy_ch_buf ); > + yyfree( (void *) b->yy_ch_buf ); > > - yyfree((void *) b ); > + yyfree( (void *) b ); > } > > /* Initializes or reinitializes a buffer. > @@ -1760,7 +1777,7 @@ static void yy_load_buffer_state (void) > { > int oerrno = errno; > > - yy_flush_buffer(b ); > + yy_flush_buffer( b ); > > b->yy_input_file = file; > b->yy_fill_buffer = 1; > @@ -1803,7 +1820,7 @@ static void yy_load_buffer_state (void) > b->yy_buffer_status = YY_BUFFER_NEW; > > if ( b == YY_CURRENT_BUFFER ) > - yy_load_buffer_state( ); > + yy_load_buffer_state( ); > } > > /** Pushes the new state onto the stack. The new state becomes > @@ -1834,7 +1851,7 @@ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) > YY_CURRENT_BUFFER_LVALUE = new_buffer; > > /* copied from yy_switch_to_buffer. */ > - yy_load_buffer_state( ); > + yy_load_buffer_state( ); > (yy_did_buffer_switch_on_eof) = 1; > } > > @@ -1853,7 +1870,7 @@ void yypop_buffer_state (void) > --(yy_buffer_stack_top); > > if (YY_CURRENT_BUFFER) { > - yy_load_buffer_state( ); > + yy_load_buffer_state( ); > (yy_did_buffer_switch_on_eof) = 1; > } > } > @@ -1871,15 +1888,15 @@ static void yyensure_buffer_stack (void) > * scanner will even need a stack. We use 2 instead of 1 to avoid an > * immediate realloc on the next call. > */ > - num_to_alloc = 1; > + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ > (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc > (num_to_alloc * sizeof(struct yy_buffer_state*) > ); > if ( ! (yy_buffer_stack) ) > YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); > - > + > memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); > - > + > (yy_buffer_stack_max) = num_to_alloc; > (yy_buffer_stack_top) = 0; > return; > @@ -1888,7 +1905,7 @@ static void yyensure_buffer_stack (void) > if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ > > /* Increase the buffer to prepare for a possible push. */ > - int grow_size = 8 /* arbitrary grow size */; > + yy_size_t grow_size = 8 /* arbitrary grow size */; > > num_to_alloc = (yy_buffer_stack_max) + grow_size; > (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc > @@ -1908,7 +1925,7 @@ static void yyensure_buffer_stack (void) > * @param base the character buffer > * @param size the size in bytes of the character buffer > * > - * @return the newly allocated buffer state object. > + * @return the newly allocated buffer state object. > */ > YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) > { > @@ -1918,23 +1935,23 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) > base[size-2] != YY_END_OF_BUFFER_CHAR || > base[size-1] != YY_END_OF_BUFFER_CHAR ) > /* They forgot to leave room for the EOB's. */ > - return 0; > + return NULL; > > - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); > + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); > if ( ! b ) > YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); > > - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ > + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ > b->yy_buf_pos = b->yy_ch_buf = base; > b->yy_is_our_buffer = 0; > - b->yy_input_file = 0; > + b->yy_input_file = NULL; > b->yy_n_chars = b->yy_buf_size; > b->yy_is_interactive = 0; > b->yy_at_bol = 1; > b->yy_fill_buffer = 0; > b->yy_buffer_status = YY_BUFFER_NEW; > > - yy_switch_to_buffer(b ); > + yy_switch_to_buffer( b ); > > return b; > } > @@ -1947,10 +1964,10 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) > * @note If you want to scan bytes that may contain NUL values, then use > * yy_scan_bytes() instead. > */ > -YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) > +YY_BUFFER_STATE yy_scan_string (const char * yystr ) > { > > - return yy_scan_bytes(yystr,strlen(yystr) ); > + return yy_scan_bytes( yystr, (int) strlen(yystr) ); > } > > /** Setup the input buffer state to scan the given bytes. The next call to yylex() will > @@ -1960,16 +1977,16 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) > * > * @return the newly allocated buffer state object. > */ > -YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) > +YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) > { > YY_BUFFER_STATE b; > char *buf; > yy_size_t n; > - yy_size_t i; > + int i; > > /* Get memory for full buffer, including space for trailing EOB's. */ > - n = _yybytes_len + 2; > - buf = (char *) yyalloc(n ); > + n = (yy_size_t) (_yybytes_len + 2); > + buf = (char *) yyalloc( n ); > if ( ! buf ) > YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); > > @@ -1978,7 +1995,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len > > buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; > > - b = yy_scan_buffer(buf,n ); > + b = yy_scan_buffer( buf, n ); > if ( ! b ) > YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); > > @@ -1994,9 +2011,9 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len > #define YY_EXIT_FAILURE 2 > #endif > > -static void yy_fatal_error (yyconst char* msg ) > +static void yynoreturn yy_fatal_error (const char* msg ) > { > - (void) fprintf( stderr, "%s\n", msg ); > + fprintf( stderr, "%s\n", msg ); > exit( YY_EXIT_FAILURE ); > } > > @@ -2024,7 +2041,7 @@ static void yy_fatal_error (yyconst char* msg ) > */ > int yyget_lineno (void) > { > - > + > return yylineno; > } > > @@ -2047,7 +2064,7 @@ FILE *yyget_out (void) > /** Get the length of the current token. > * > */ > -yy_size_t yyget_leng (void) > +int yyget_leng (void) > { > return yyleng; > } > @@ -2062,29 +2079,29 @@ char *yyget_text (void) > } > > /** Set the current line number. > - * @param line_number > + * @param _line_number line number > * > */ > -void yyset_lineno (int line_number ) > +void yyset_lineno (int _line_number ) > { > > - yylineno = line_number; > + yylineno = _line_number; > } > > /** Set the input stream. This does not discard the current > * input buffer. > - * @param in_str A readable stream. > + * @param _in_str A readable stream. > * > * @see yy_switch_to_buffer > */ > -void yyset_in (FILE * in_str ) > +void yyset_in (FILE * _in_str ) > { > - yyin = in_str ; > + yyin = _in_str ; > } > > -void yyset_out (FILE * out_str ) > +void yyset_out (FILE * _out_str ) > { > - yyout = out_str ; > + yyout = _out_str ; > } > > int yyget_debug (void) > @@ -2092,9 +2109,9 @@ int yyget_debug (void) > return yy_flex_debug; > } > > -void yyset_debug (int bdebug ) > +void yyset_debug (int _bdebug ) > { > - yy_flex_debug = bdebug ; > + yy_flex_debug = _bdebug ; > } > > static int yy_init_globals (void) > @@ -2103,10 +2120,10 @@ static int yy_init_globals (void) > * This function is called from yylex_destroy(), so don't allocate here. > */ > > - (yy_buffer_stack) = 0; > + (yy_buffer_stack) = NULL; > (yy_buffer_stack_top) = 0; > (yy_buffer_stack_max) = 0; > - (yy_c_buf_p) = (char *) 0; > + (yy_c_buf_p) = NULL; > (yy_init) = 0; > (yy_start) = 0; > > @@ -2115,8 +2132,8 @@ static int yy_init_globals (void) > yyin = stdin; > yyout = stdout; > #else > - yyin = (FILE *) 0; > - yyout = (FILE *) 0; > + yyin = NULL; > + yyout = NULL; > #endif > > /* For future reference: Set errno on error, since we are called by > @@ -2131,7 +2148,7 @@ int yylex_destroy (void) > > /* Pop the buffer stack, destroying each element. */ > while(YY_CURRENT_BUFFER){ > - yy_delete_buffer(YY_CURRENT_BUFFER ); > + yy_delete_buffer( YY_CURRENT_BUFFER ); > YY_CURRENT_BUFFER_LVALUE = NULL; > yypop_buffer_state(); > } > @@ -2152,18 +2169,19 @@ int yylex_destroy (void) > */ > > #ifndef yytext_ptr > -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) > +static void yy_flex_strncpy (char* s1, const char * s2, int n ) > { > - register int i; > + > + int i; > for ( i = 0; i < n; ++i ) > s1[i] = s2[i]; > } > #endif > > #ifdef YY_NEED_STRLEN > -static int yy_flex_strlen (yyconst char * s ) > +static int yy_flex_strlen (const char * s ) > { > - register int n; > + int n; > for ( n = 0; s[n]; ++n ) > ; > > @@ -2173,11 +2191,12 @@ static int yy_flex_strlen (yyconst char * s ) > > void *yyalloc (yy_size_t size ) > { > - return (void *) malloc( size ); > + return malloc(size); > } > > void *yyrealloc (void * ptr, yy_size_t size ) > { > + > /* The cast to (char *) in the following accommodates both > * implementations that use char* generic pointers, and those > * that use void* generic pointers. It works with the latter > @@ -2185,18 +2204,17 @@ void *yyrealloc (void * ptr, yy_size_t size ) > * any pointer type to void*, and deal with argument conversions > * as though doing an assignment. > */ > - return (void *) realloc( (char *) ptr, size ); > + return realloc(ptr, size); > } > > void yyfree (void * ptr ) > { > - free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ > + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ > } > > #define YYTABLES_NAME "yytables" > > -#line 254 "dtc-lexer.l" > - > +#line 272 "<stdin>" > > > static void push_input_file(const char *filename) > @@ -2207,7 +2225,7 @@ static void push_input_file(const char *filename) > > yyin = current_srcfile->f; > > - yypush_buffer_state(yy_create_buffer(yyin,YY_BUF_SIZE)); > + yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE)); > } > > > diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped > index 27fac4b9c..06a6e9414 100644 > --- a/scripts/dtc/dtc-parser.tab.c_shipped > +++ b/scripts/dtc/dtc-parser.tab.c_shipped > @@ -1,8 +1,8 @@ > -/* A Bison parser, made by GNU Bison 3.0.2. */ > +/* A Bison parser, made by GNU Bison 3.0.4. */ > > /* Bison implementation for Yacc-like parsers in C > > - Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. > + Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, 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 > @@ -44,7 +44,7 @@ > #define YYBISON 1 > > /* Bison version. */ > -#define YYBISON_VERSION "3.0.2" > +#define YYBISON_VERSION "3.0.4" > > /* Skeleton name. */ > #define YYSKELETON_NAME "yacc.c" > @@ -65,6 +65,7 @@ > #line 20 "dtc-parser.y" /* yacc.c:339 */ > > #include <stdio.h> > +#include <inttypes.h> > > #include "dtc.h" > #include "srcpos.h" > @@ -77,10 +78,10 @@ extern void yyerror(char const *s); > treesource_error = true; \ > } while (0) > > -extern struct boot_info *the_boot_info; > +extern struct dt_info *parser_output; > extern bool treesource_error; > > -#line 84 "dtc-parser.tab.c" /* yacc.c:339 */ > +#line 85 "dtc-parser.tab.c" /* yacc.c:339 */ > > # ifndef YY_NULLPTR > # if defined __cplusplus && 201103L <= __cplusplus > @@ -116,35 +117,36 @@ extern int yydebug; > enum yytokentype > { > DT_V1 = 258, > - DT_MEMRESERVE = 259, > - DT_LSHIFT = 260, > - DT_RSHIFT = 261, > - DT_LE = 262, > - DT_GE = 263, > - DT_EQ = 264, > - DT_NE = 265, > - DT_AND = 266, > - DT_OR = 267, > - DT_BITS = 268, > - DT_DEL_PROP = 269, > - DT_DEL_NODE = 270, > - DT_PROPNODENAME = 271, > - DT_LITERAL = 272, > - DT_CHAR_LITERAL = 273, > - DT_BYTE = 274, > - DT_STRING = 275, > - DT_LABEL = 276, > - DT_REF = 277, > - DT_INCBIN = 278 > + DT_PLUGIN = 259, > + DT_MEMRESERVE = 260, > + DT_LSHIFT = 261, > + DT_RSHIFT = 262, > + DT_LE = 263, > + DT_GE = 264, > + DT_EQ = 265, > + DT_NE = 266, > + DT_AND = 267, > + DT_OR = 268, > + DT_BITS = 269, > + DT_DEL_PROP = 270, > + DT_DEL_NODE = 271, > + DT_PROPNODENAME = 272, > + DT_LITERAL = 273, > + DT_CHAR_LITERAL = 274, > + DT_BYTE = 275, > + DT_STRING = 276, > + DT_LABEL = 277, > + DT_REF = 278, > + DT_INCBIN = 279 > }; > #endif > > /* Value type. */ > #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED > -typedef union YYSTYPE YYSTYPE; > + > union YYSTYPE > { > -#line 38 "dtc-parser.y" /* yacc.c:355 */ > +#line 39 "dtc-parser.y" /* yacc.c:355 */ > > char *propnodename; > char *labelref; > @@ -162,9 +164,12 @@ union YYSTYPE > struct node *nodelist; > struct reserve_info *re; > uint64_t integer; > + unsigned int flags; > > -#line 167 "dtc-parser.tab.c" /* yacc.c:355 */ > +#line 170 "dtc-parser.tab.c" /* yacc.c:355 */ > }; > + > +typedef union YYSTYPE YYSTYPE; > # define YYSTYPE_IS_TRIVIAL 1 > # define YYSTYPE_IS_DECLARED 1 > #endif > @@ -192,7 +197,7 @@ int yyparse (void); > > /* Copy the second part of user declarations. */ > > -#line 196 "dtc-parser.tab.c" /* yacc.c:358 */ > +#line 201 "dtc-parser.tab.c" /* yacc.c:358 */ > > #ifdef short > # undef short > @@ -434,23 +439,23 @@ union yyalloc > #endif /* !YYCOPY_NEEDED */ > > /* YYFINAL -- State number of the termination state. */ > -#define YYFINAL 4 > +#define YYFINAL 6 > /* YYLAST -- Last index in YYTABLE. */ > -#define YYLAST 133 > +#define YYLAST 140 > > /* YYNTOKENS -- Number of terminals. */ > -#define YYNTOKENS 47 > +#define YYNTOKENS 48 > /* YYNNTS -- Number of nonterminals. */ > -#define YYNNTS 28 > +#define YYNNTS 30 > /* YYNRULES -- Number of rules. */ > -#define YYNRULES 79 > +#define YYNRULES 85 > /* YYNSTATES -- Number of states. */ > -#define YYNSTATES 141 > +#define YYNSTATES 151 > > /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned > by yylex, with out-of-bounds checking. */ > #define YYUNDEFTOK 2 > -#define YYMAXUTOK 278 > +#define YYMAXUTOK 279 > > #define YYTRANSLATE(YYX) \ > ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) > @@ -462,16 +467,16 @@ static const yytype_uint8 yytranslate[] = > 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, > 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, > 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, > - 2, 2, 2, 46, 2, 2, 2, 44, 40, 2, > - 32, 34, 43, 41, 33, 42, 2, 25, 2, 2, > - 2, 2, 2, 2, 2, 2, 2, 2, 37, 24, > - 35, 28, 29, 36, 2, 2, 2, 2, 2, 2, > + 2, 2, 2, 47, 2, 2, 2, 45, 41, 2, > + 33, 35, 44, 42, 34, 43, 2, 26, 2, 2, > + 2, 2, 2, 2, 2, 2, 2, 2, 38, 25, > + 36, 29, 30, 37, 2, 2, 2, 2, 2, 2, > 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, > 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, > - 2, 30, 2, 31, 39, 2, 2, 2, 2, 2, > + 2, 31, 2, 32, 40, 2, 2, 2, 2, 2, > 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, > 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, > - 2, 2, 2, 26, 38, 27, 45, 2, 2, 2, > + 2, 2, 2, 27, 39, 28, 46, 2, 2, 2, > 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, > 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, > 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, > @@ -486,21 +491,22 @@ static const yytype_uint8 yytranslate[] = > 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, > 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, > 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, > - 15, 16, 17, 18, 19, 20, 21, 22, 23 > + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 > }; > > #if YYDEBUG > /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ > static const yytype_uint16 yyrline[] = > { > - 0, 104, 104, 113, 116, 123, 127, 135, 139, 143, > - 153, 168, 176, 179, 186, 190, 194, 198, 206, 210, > - 214, 218, 222, 238, 248, 256, 259, 263, 270, 286, > - 291, 310, 324, 331, 332, 333, 340, 344, 345, 349, > - 350, 354, 355, 359, 360, 364, 365, 369, 370, 374, > - 375, 376, 380, 381, 382, 383, 384, 388, 389, 390, > - 394, 395, 396, 400, 401, 402, 403, 407, 408, 409, > - 410, 415, 418, 422, 430, 433, 437, 445, 449, 453 > + 0, 109, 109, 117, 121, 128, 129, 139, 142, 149, > + 153, 161, 165, 169, 180, 191, 210, 225, 233, 236, > + 243, 247, 251, 255, 263, 267, 271, 275, 279, 295, > + 305, 313, 316, 320, 327, 343, 348, 367, 381, 388, > + 389, 390, 397, 401, 402, 406, 407, 411, 412, 416, > + 417, 421, 422, 426, 427, 431, 432, 433, 437, 438, > + 439, 440, 441, 445, 446, 447, 451, 452, 453, 457, > + 458, 467, 476, 480, 481, 482, 483, 488, 491, 495, > + 503, 506, 510, 518, 522, 526 > }; > #endif > > @@ -509,19 +515,20 @@ static const yytype_uint16 yyrline[] = > First, the terminals, then, starting at YYNTOKENS, nonterminals. */ > static const char *const yytname[] = > { > - "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", "DT_LSHIFT", > - "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", "DT_OR", > - "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", "DT_LITERAL", > - "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", > - "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", "']'", > - "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", "'+'", > - "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", > - "memreserves", "memreserve", "devicetree", "nodedef", "proplist", > - "propdef", "propdata", "propdataprefix", "arrayprefix", "integer_prim", > - "integer_expr", "integer_trinary", "integer_or", "integer_and", > - "integer_bitor", "integer_bitxor", "integer_bitand", "integer_eq", > - "integer_rela", "integer_shift", "integer_add", "integer_mul", > - "integer_unary", "bytestring", "subnodes", "subnode", YY_NULLPTR > + "$end", "error", "$undefined", "DT_V1", "DT_PLUGIN", "DT_MEMRESERVE", > + "DT_LSHIFT", "DT_RSHIFT", "DT_LE", "DT_GE", "DT_EQ", "DT_NE", "DT_AND", > + "DT_OR", "DT_BITS", "DT_DEL_PROP", "DT_DEL_NODE", "DT_PROPNODENAME", > + "DT_LITERAL", "DT_CHAR_LITERAL", "DT_BYTE", "DT_STRING", "DT_LABEL", > + "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='", "'>'", "'['", > + "']'", "'('", "','", "')'", "'<'", "'?'", "':'", "'|'", "'^'", "'&'", > + "'+'", "'-'", "'*'", "'%'", "'~'", "'!'", "$accept", "sourcefile", > + "header", "headers", "memreserves", "memreserve", "devicetree", > + "nodedef", "proplist", "propdef", "propdata", "propdataprefix", > + "arrayprefix", "integer_prim", "integer_expr", "integer_trinary", > + "integer_or", "integer_and", "integer_bitor", "integer_bitxor", > + "integer_bitand", "integer_eq", "integer_rela", "integer_shift", > + "integer_add", "integer_mul", "integer_unary", "bytestring", "subnodes", > + "subnode", YY_NULLPTR > }; > #endif > > @@ -532,16 +539,16 @@ static const yytype_uint16 yytoknum[] = > { > 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, > 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, > - 275, 276, 277, 278, 59, 47, 123, 125, 61, 62, > - 91, 93, 40, 44, 41, 60, 63, 58, 124, 94, > - 38, 43, 45, 42, 37, 126, 33 > + 275, 276, 277, 278, 279, 59, 47, 123, 125, 61, > + 62, 91, 93, 40, 44, 41, 60, 63, 58, 124, > + 94, 38, 43, 45, 42, 37, 126, 33 > }; > # endif > > -#define YYPACT_NINF -38 > +#define YYPACT_NINF -81 > > #define yypact_value_is_default(Yystate) \ > - (!!((Yystate) == (-38))) > + (!!((Yystate) == (-81))) > > #define YYTABLE_NINF -1 > > @@ -552,21 +559,22 @@ static const yytype_uint16 yytoknum[] = > STATE-NUM. */ > static const yytype_int8 yypact[] = > { > - 21, 11, 45, 10, -38, 9, 10, 15, 10, -38, > - -38, -9, 9, -38, 56, 40, -38, -9, -9, -9, > - -38, 51, -38, -6, 75, 49, 52, 48, 50, 3, > - 66, 33, 0, -38, 65, -38, -38, 68, 56, 56, > - -38, -38, -38, -38, -9, -9, -9, -9, -9, -9, > - -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, > - -9, -9, -9, -38, 42, 69, -38, -38, 75, 55, > - 49, 52, 48, 50, 3, 3, 66, 66, 66, 66, > - 33, 33, 0, 0, -38, -38, -38, 78, 79, -11, > - 42, -38, 70, 42, -38, -9, 72, 74, -38, -38, > - -38, -38, -38, 76, -38, -38, -38, -38, -38, 18, > - -1, -38, -38, -38, -38, 82, -38, -38, -38, 71, > - -38, -38, 32, 67, 81, -3, -38, -38, -38, -38, > - -38, 43, -38, -38, -38, 9, -38, 73, 9, 77, > - -38 > + 11, 17, 23, 11, 10, 56, -81, -81, 21, 10, > + -5, 10, 39, -81, -81, -13, 21, -81, 44, 44, > + 43, -81, -81, -13, -13, -13, -81, 38, -81, -2, > + 67, 53, 55, 57, 41, 1, 75, 42, -19, -81, > + 58, -81, -81, -81, 73, 74, 44, 44, -81, -81, > + -81, -81, -13, -13, -13, -13, -13, -13, -13, -13, > + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, > + -13, -81, 46, 76, 44, -81, -81, 67, 61, 53, > + 55, 57, 41, 1, 1, 75, 75, 75, 75, 42, > + 42, -19, -19, -81, -81, -81, 83, 85, 45, 46, > + -81, 77, 46, -81, -81, -13, 78, 79, -81, -81, > + -81, -81, -81, 81, -81, -81, -81, -81, -81, 16, > + 22, -81, -81, -81, -81, 89, -81, -81, -81, 80, > + -81, -81, -6, 72, 88, 35, -81, -81, -81, -81, > + -81, 52, -81, -81, -81, 21, -81, 82, 21, 84, > + -81 > }; > > /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. > @@ -574,37 +582,38 @@ static const yytype_int8 yypact[] = > means the default is an error. */ > static const yytype_uint8 yydefact[] = > { > - 0, 0, 0, 3, 1, 0, 0, 0, 3, 33, > - 34, 0, 0, 6, 0, 2, 4, 0, 0, 0, > - 67, 0, 36, 37, 39, 41, 43, 45, 47, 49, > - 52, 59, 62, 66, 0, 12, 7, 0, 0, 0, > - 68, 69, 70, 35, 0, 0, 0, 0, 0, 0, > + 0, 0, 0, 5, 7, 3, 1, 6, 0, 0, > + 0, 7, 0, 39, 40, 0, 0, 10, 0, 0, > + 2, 8, 4, 0, 0, 0, 73, 0, 42, 43, > + 45, 47, 49, 51, 53, 55, 58, 65, 68, 72, > + 0, 18, 13, 11, 0, 0, 0, 0, 74, 75, > + 76, 41, 0, 0, 0, 0, 0, 0, 0, 0, > 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > - 0, 0, 0, 5, 74, 0, 9, 8, 40, 0, > - 42, 44, 46, 48, 50, 51, 55, 56, 54, 53, > - 57, 58, 60, 61, 64, 63, 65, 0, 0, 0, > - 0, 13, 0, 74, 10, 0, 0, 0, 15, 25, > - 77, 17, 79, 0, 76, 75, 38, 16, 78, 0, > - 0, 11, 24, 14, 26, 0, 18, 27, 21, 0, > - 71, 29, 0, 0, 0, 0, 32, 31, 19, 30, > - 28, 0, 72, 73, 20, 0, 23, 0, 0, 0, > - 22 > + 0, 9, 80, 0, 0, 15, 12, 46, 0, 48, > + 50, 52, 54, 56, 57, 61, 62, 60, 59, 63, > + 64, 66, 67, 70, 69, 71, 0, 0, 0, 0, > + 19, 0, 80, 16, 14, 0, 0, 0, 21, 31, > + 83, 23, 85, 0, 82, 81, 44, 22, 84, 0, > + 0, 17, 30, 20, 32, 0, 24, 33, 27, 0, > + 77, 35, 0, 0, 0, 0, 38, 37, 25, 36, > + 34, 0, 78, 79, 26, 0, 29, 0, 0, 0, > + 28 > }; > > /* YYPGOTO[NTERM-NUM]. */ > static const yytype_int8 yypgoto[] = > { > - -38, -38, 96, 99, -38, -37, -38, -20, -38, -38, > - -38, -5, 62, 13, -38, 80, 63, 84, 64, 61, > - 28, 14, 24, 25, -14, -38, 20, 26 > + -81, -81, -81, 107, 100, 103, -81, -18, -81, -80, > + -81, -81, -81, -8, 62, 9, -81, 65, 64, 66, > + 69, 63, 30, 15, 26, 27, -21, -81, 20, 24 > }; > > /* YYDEFGOTO[NTERM-NUM]. */ > -static const yytype_int8 yydefgoto[] = > +static const yytype_int16 yydefgoto[] = > { > - -1, 2, 7, 8, 15, 36, 64, 91, 109, 110, > - 122, 20, 21, 22, 23, 24, 25, 26, 27, 28, > - 29, 30, 31, 32, 33, 125, 92, 93 > + -1, 2, 3, 4, 10, 11, 20, 42, 72, 100, > + 119, 120, 132, 26, 27, 28, 29, 30, 31, 32, > + 33, 34, 35, 36, 37, 38, 39, 135, 101, 102 > }; > > /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If > @@ -612,85 +621,90 @@ static const yytype_int8 yydefgoto[] = > number is the opposite. If YYTABLE_NINF, syntax error. */ > static const yytype_uint8 yytable[] = > { > - 12, 66, 67, 40, 41, 42, 44, 34, 9, 10, > - 52, 53, 115, 98, 5, 35, 132, 99, 133, 116, > - 117, 118, 119, 11, 1, 60, 9, 10, 134, 120, > - 45, 6, 54, 17, 121, 3, 18, 19, 55, 112, > - 14, 11, 113, 61, 62, 4, 84, 85, 86, 9, > - 10, 114, 100, 126, 127, 37, 87, 88, 89, 50, > - 51, 128, 38, 90, 11, 39, 76, 77, 78, 79, > - 101, 56, 57, 104, 58, 59, 135, 136, 74, 75, > - 80, 81, 35, 82, 83, 43, 46, 47, 49, 63, > - 65, 48, 95, 94, 96, 97, 107, 103, 108, 123, > - 111, 131, 130, 124, 16, 13, 138, 69, 106, 70, > - 73, 140, 72, 105, 0, 0, 102, 129, 0, 0, > - 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, > - 137, 71, 0, 139 > + 16, 43, 48, 49, 50, 13, 14, 68, 40, 60, > + 61, 52, 13, 14, 1, 8, 136, 137, 18, 111, > + 15, 19, 114, 6, 138, 69, 70, 15, 75, 76, > + 23, 62, 9, 24, 25, 53, 125, 63, 122, 13, > + 14, 123, 5, 126, 127, 128, 129, 93, 94, 95, > + 124, 58, 59, 130, 15, 142, 104, 143, 131, 44, > + 12, 96, 97, 98, 22, 45, 46, 144, 99, 47, > + 108, 41, 41, 51, 109, 85, 86, 87, 88, 54, > + 110, 64, 65, 71, 66, 67, 145, 146, 83, 84, > + 89, 90, 55, 91, 92, 56, 73, 74, 57, 105, > + 106, 103, 107, 117, 118, 113, 121, 133, 140, 141, > + 7, 21, 17, 134, 116, 78, 148, 77, 79, 150, > + 82, 80, 115, 112, 139, 81, 0, 0, 0, 0, > + 0, 0, 0, 0, 0, 0, 0, 147, 0, 0, > + 149 > }; > > static const yytype_int16 yycheck[] = > { > - 5, 38, 39, 17, 18, 19, 12, 12, 17, 18, > - 7, 8, 13, 24, 4, 26, 19, 28, 21, 20, > - 21, 22, 23, 32, 3, 25, 17, 18, 31, 30, > - 36, 21, 29, 42, 35, 24, 45, 46, 35, 21, > - 25, 32, 24, 43, 44, 0, 60, 61, 62, 17, > - 18, 33, 89, 21, 22, 15, 14, 15, 16, 9, > - 10, 29, 22, 21, 32, 25, 52, 53, 54, 55, > - 90, 5, 6, 93, 41, 42, 33, 34, 50, 51, > - 56, 57, 26, 58, 59, 34, 11, 38, 40, 24, > - 22, 39, 37, 24, 16, 16, 24, 27, 24, 17, > - 24, 20, 35, 32, 8, 6, 33, 45, 95, 46, > - 49, 34, 48, 93, -1, -1, 90, 122, -1, -1, > - -1, -1, -1, -1, 44, -1, -1, -1, -1, -1, > - 135, 47, -1, 138 > + 8, 19, 23, 24, 25, 18, 19, 26, 16, 8, > + 9, 13, 18, 19, 3, 5, 22, 23, 23, 99, > + 33, 26, 102, 0, 30, 44, 45, 33, 46, 47, > + 43, 30, 22, 46, 47, 37, 14, 36, 22, 18, > + 19, 25, 25, 21, 22, 23, 24, 68, 69, 70, > + 34, 10, 11, 31, 33, 20, 74, 22, 36, 16, > + 4, 15, 16, 17, 25, 22, 23, 32, 22, 26, > + 25, 27, 27, 35, 29, 60, 61, 62, 63, 12, > + 98, 6, 7, 25, 42, 43, 34, 35, 58, 59, > + 64, 65, 39, 66, 67, 40, 23, 23, 41, 38, > + 17, 25, 17, 25, 25, 28, 25, 18, 36, 21, > + 3, 11, 9, 33, 105, 53, 34, 52, 54, 35, > + 57, 55, 102, 99, 132, 56, -1, -1, -1, -1, > + -1, -1, -1, -1, -1, -1, -1, 145, -1, -1, > + 148 > }; > > /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing > symbol of state STATE-NUM. */ > static const yytype_uint8 yystos[] = > { > - 0, 3, 48, 24, 0, 4, 21, 49, 50, 17, > - 18, 32, 58, 50, 25, 51, 49, 42, 45, 46, > - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, > - 68, 69, 70, 71, 58, 26, 52, 15, 22, 25, > - 71, 71, 71, 34, 12, 36, 11, 38, 39, 40, > - 9, 10, 7, 8, 29, 35, 5, 6, 41, 42, > - 25, 43, 44, 24, 53, 22, 52, 52, 62, 59, > - 63, 64, 65, 66, 67, 67, 68, 68, 68, 68, > - 69, 69, 70, 70, 71, 71, 71, 14, 15, 16, > - 21, 54, 73, 74, 24, 37, 16, 16, 24, 28, > - 52, 54, 74, 27, 54, 73, 60, 24, 24, 55, > - 56, 24, 21, 24, 33, 13, 20, 21, 22, 23, > - 30, 35, 57, 17, 32, 72, 21, 22, 29, 58, > - 35, 20, 19, 21, 31, 33, 34, 58, 33, 58, > - 34 > + 0, 3, 49, 50, 51, 25, 0, 51, 5, 22, > + 52, 53, 4, 18, 19, 33, 61, 53, 23, 26, > + 54, 52, 25, 43, 46, 47, 61, 62, 63, 64, > + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, > + 61, 27, 55, 55, 16, 22, 23, 26, 74, 74, > + 74, 35, 13, 37, 12, 39, 40, 41, 10, 11, > + 8, 9, 30, 36, 6, 7, 42, 43, 26, 44, > + 45, 25, 56, 23, 23, 55, 55, 65, 62, 66, > + 67, 68, 69, 70, 70, 71, 71, 71, 71, 72, > + 72, 73, 73, 74, 74, 74, 15, 16, 17, 22, > + 57, 76, 77, 25, 55, 38, 17, 17, 25, 29, > + 55, 57, 77, 28, 57, 76, 63, 25, 25, 58, > + 59, 25, 22, 25, 34, 14, 21, 22, 23, 24, > + 31, 36, 60, 18, 33, 75, 22, 23, 30, 61, > + 36, 21, 20, 22, 32, 34, 35, 61, 34, 61, > + 35 > }; > > /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ > static const yytype_uint8 yyr1[] = > { > - 0, 47, 48, 49, 49, 50, 50, 51, 51, 51, > - 51, 52, 53, 53, 54, 54, 54, 54, 55, 55, > - 55, 55, 55, 55, 55, 56, 56, 56, 57, 57, > - 57, 57, 57, 58, 58, 58, 59, 60, 60, 61, > - 61, 62, 62, 63, 63, 64, 64, 65, 65, 66, > - 66, 66, 67, 67, 67, 67, 67, 68, 68, 68, > - 69, 69, 69, 70, 70, 70, 70, 71, 71, 71, > - 71, 72, 72, 72, 73, 73, 73, 74, 74, 74 > + 0, 48, 49, 50, 50, 51, 51, 52, 52, 53, > + 53, 54, 54, 54, 54, 54, 54, 55, 56, 56, > + 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, > + 58, 59, 59, 59, 60, 60, 60, 60, 60, 61, > + 61, 61, 62, 63, 63, 64, 64, 65, 65, 66, > + 66, 67, 67, 68, 68, 69, 69, 69, 70, 70, > + 70, 70, 70, 71, 71, 71, 72, 72, 72, 73, > + 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, > + 76, 76, 76, 77, 77, 77 > }; > > /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ > static const yytype_uint8 yyr2[] = > { > - 0, 2, 4, 0, 2, 4, 2, 2, 3, 3, > - 4, 5, 0, 2, 4, 2, 3, 2, 2, 3, > - 4, 2, 9, 5, 2, 0, 2, 2, 3, 1, > - 2, 2, 2, 1, 1, 3, 1, 1, 5, 1, > - 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, > - 3, 3, 1, 3, 3, 3, 3, 3, 3, 1, > - 3, 3, 1, 3, 3, 3, 1, 1, 2, 2, > - 2, 0, 2, 2, 0, 2, 2, 2, 3, 2 > + 0, 2, 3, 2, 4, 1, 2, 0, 2, 4, > + 2, 2, 3, 2, 4, 3, 4, 5, 0, 2, > + 4, 2, 3, 2, 2, 3, 4, 2, 9, 5, > + 2, 0, 2, 2, 3, 1, 2, 2, 2, 1, > + 1, 3, 1, 1, 5, 1, 3, 1, 3, 1, > + 3, 1, 3, 1, 3, 1, 3, 3, 1, 3, > + 3, 3, 3, 3, 3, 1, 3, 3, 1, 3, > + 3, 3, 1, 1, 2, 2, 2, 0, 2, 2, > + 0, 2, 2, 2, 3, 2 > }; > > > @@ -1460,79 +1474,144 @@ yyreduce: > switch (yyn) > { > case 2: > -#line 105 "dtc-parser.y" /* yacc.c:1646 */ > +#line 110 "dtc-parser.y" /* yacc.c:1646 */ > { > - the_boot_info = build_boot_info((yyvsp[-1].re), (yyvsp[0].node), > - guess_boot_cpuid((yyvsp[0].node))); > + parser_output = build_dt_info((yyvsp[-2].flags), (yyvsp[-1].re), (yyvsp[0].node), > + guess_boot_cpuid((yyvsp[0].node))); > } > -#line 1469 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1483 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > case 3: > -#line 113 "dtc-parser.y" /* yacc.c:1646 */ > +#line 118 "dtc-parser.y" /* yacc.c:1646 */ > { > - (yyval.re) = NULL; > + (yyval.flags) = DTSF_V1; > } > -#line 1477 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1491 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > case 4: > -#line 117 "dtc-parser.y" /* yacc.c:1646 */ > +#line 122 "dtc-parser.y" /* yacc.c:1646 */ > + { > + (yyval.flags) = DTSF_V1 | DTSF_PLUGIN; > + } > +#line 1499 "dtc-parser.tab.c" /* yacc.c:1646 */ > + break; > + > + case 6: > +#line 130 "dtc-parser.y" /* yacc.c:1646 */ > + { > + if ((yyvsp[0].flags) != (yyvsp[-1].flags)) > + ERROR(&(yylsp[0]), "Header flags don't match earlier ones"); > + (yyval.flags) = (yyvsp[-1].flags); > + } > +#line 1509 "dtc-parser.tab.c" /* yacc.c:1646 */ > + break; > + > + case 7: > +#line 139 "dtc-parser.y" /* yacc.c:1646 */ > + { > + (yyval.re) = NULL; > + } > +#line 1517 "dtc-parser.tab.c" /* yacc.c:1646 */ > + break; > + > + case 8: > +#line 143 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.re) = chain_reserve_entry((yyvsp[-1].re), (yyvsp[0].re)); > } > -#line 1485 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1525 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 5: > -#line 124 "dtc-parser.y" /* yacc.c:1646 */ > + case 9: > +#line 150 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.re) = build_reserve_entry((yyvsp[-2].integer), (yyvsp[-1].integer)); > } > -#line 1493 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1533 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 6: > -#line 128 "dtc-parser.y" /* yacc.c:1646 */ > + case 10: > +#line 154 "dtc-parser.y" /* yacc.c:1646 */ > { > add_label(&(yyvsp[0].re)->labels, (yyvsp[-1].labelref)); > (yyval.re) = (yyvsp[0].re); > } > -#line 1502 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1542 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 7: > -#line 136 "dtc-parser.y" /* yacc.c:1646 */ > + case 11: > +#line 162 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.node) = name_node((yyvsp[0].node), ""); > } > -#line 1510 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1550 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 8: > -#line 140 "dtc-parser.y" /* yacc.c:1646 */ > + case 12: > +#line 166 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.node) = merge_nodes((yyvsp[-2].node), (yyvsp[0].node)); > } > -#line 1518 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1558 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 9: > -#line 144 "dtc-parser.y" /* yacc.c:1646 */ > + case 13: > +#line 170 "dtc-parser.y" /* yacc.c:1646 */ > { > - struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); > + /* > + * We rely on the rule being always: > + * versioninfo plugindecl memreserves devicetree > + * so $-1 is what we want (plugindecl) > + */ > + if (!((yyvsp[(-1) - (2)].flags) & DTSF_PLUGIN)) > + ERROR(&(yylsp[0]), "Label or path %s not found", (yyvsp[-1].labelref)); > + (yyval.node) = add_orphan_node(name_node(build_node(NULL, NULL), ""), (yyvsp[0].node), (yyvsp[-1].labelref)); > + } > +#line 1573 "dtc-parser.tab.c" /* yacc.c:1646 */ > + break; > > - if (target) > + case 14: > +#line 181 "dtc-parser.y" /* yacc.c:1646 */ > + { > + struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); > + > + if (target) { > + add_label(&target->labels, (yyvsp[-2].labelref)); > merge_nodes(target, (yyvsp[0].node)); > - else > + } else > ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); > + (yyval.node) = (yyvsp[-3].node); > + } > +#line 1588 "dtc-parser.tab.c" /* yacc.c:1646 */ > + break; > + > + case 15: > +#line 192 "dtc-parser.y" /* yacc.c:1646 */ > + { > + struct node *target = get_node_by_ref((yyvsp[-2].node), (yyvsp[-1].labelref)); > + > + if (target) { > + merge_nodes(target, (yyvsp[0].node)); > + } else { > + /* > + * We rely on the rule being always: > + * versioninfo plugindecl memreserves devicetree > + * so $-1 is what we want (plugindecl) > + */ > + if ((yyvsp[(-1) - (3)].flags) & DTSF_PLUGIN) > + add_orphan_node((yyvsp[-2].node), (yyvsp[0].node), (yyvsp[-1].labelref)); > + else > + ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); > + } > (yyval.node) = (yyvsp[-2].node); > } > -#line 1532 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1611 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 10: > -#line 154 "dtc-parser.y" /* yacc.c:1646 */ > + case 16: > +#line 211 "dtc-parser.y" /* yacc.c:1646 */ > { > struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); > > @@ -1544,100 +1623,100 @@ yyreduce: > > (yyval.node) = (yyvsp[-3].node); > } > -#line 1548 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1627 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 11: > -#line 169 "dtc-parser.y" /* yacc.c:1646 */ > + case 17: > +#line 226 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.node) = build_node((yyvsp[-3].proplist), (yyvsp[-2].nodelist)); > } > -#line 1556 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1635 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 12: > -#line 176 "dtc-parser.y" /* yacc.c:1646 */ > + case 18: > +#line 233 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.proplist) = NULL; > } > -#line 1564 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1643 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 13: > -#line 180 "dtc-parser.y" /* yacc.c:1646 */ > + case 19: > +#line 237 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.proplist) = chain_property((yyvsp[0].prop), (yyvsp[-1].proplist)); > } > -#line 1572 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1651 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 14: > -#line 187 "dtc-parser.y" /* yacc.c:1646 */ > + case 20: > +#line 244 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.prop) = build_property((yyvsp[-3].propnodename), (yyvsp[-1].data)); > } > -#line 1580 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1659 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 15: > -#line 191 "dtc-parser.y" /* yacc.c:1646 */ > + case 21: > +#line 248 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.prop) = build_property((yyvsp[-1].propnodename), empty_data); > } > -#line 1588 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1667 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 16: > -#line 195 "dtc-parser.y" /* yacc.c:1646 */ > + case 22: > +#line 252 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.prop) = build_property_delete((yyvsp[-1].propnodename)); > } > -#line 1596 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1675 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 17: > -#line 199 "dtc-parser.y" /* yacc.c:1646 */ > + case 23: > +#line 256 "dtc-parser.y" /* yacc.c:1646 */ > { > add_label(&(yyvsp[0].prop)->labels, (yyvsp[-1].labelref)); > (yyval.prop) = (yyvsp[0].prop); > } > -#line 1605 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1684 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 18: > -#line 207 "dtc-parser.y" /* yacc.c:1646 */ > + case 24: > +#line 264 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.data) = data_merge((yyvsp[-1].data), (yyvsp[0].data)); > } > -#line 1613 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1692 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 19: > -#line 211 "dtc-parser.y" /* yacc.c:1646 */ > + case 25: > +#line 268 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.data) = data_merge((yyvsp[-2].data), (yyvsp[-1].array).data); > } > -#line 1621 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1700 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 20: > -#line 215 "dtc-parser.y" /* yacc.c:1646 */ > + case 26: > +#line 272 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.data) = data_merge((yyvsp[-3].data), (yyvsp[-1].data)); > } > -#line 1629 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1708 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 21: > -#line 219 "dtc-parser.y" /* yacc.c:1646 */ > + case 27: > +#line 276 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.data) = data_add_marker((yyvsp[-1].data), REF_PATH, (yyvsp[0].labelref)); > } > -#line 1637 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1716 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 22: > -#line 223 "dtc-parser.y" /* yacc.c:1646 */ > + case 28: > +#line 280 "dtc-parser.y" /* yacc.c:1646 */ > { > FILE *f = srcfile_relative_open((yyvsp[-5].data).val, NULL); > struct data d; > @@ -1653,11 +1732,11 @@ yyreduce: > (yyval.data) = data_merge((yyvsp[-8].data), d); > fclose(f); > } > -#line 1657 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1736 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 23: > -#line 239 "dtc-parser.y" /* yacc.c:1646 */ > + case 29: > +#line 296 "dtc-parser.y" /* yacc.c:1646 */ > { > FILE *f = srcfile_relative_open((yyvsp[-1].data).val, NULL); > struct data d = empty_data; > @@ -1667,43 +1746,43 @@ yyreduce: > (yyval.data) = data_merge((yyvsp[-4].data), d); > fclose(f); > } > -#line 1671 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1750 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 24: > -#line 249 "dtc-parser.y" /* yacc.c:1646 */ > + case 30: > +#line 306 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); > } > -#line 1679 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1758 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 25: > -#line 256 "dtc-parser.y" /* yacc.c:1646 */ > + case 31: > +#line 313 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.data) = empty_data; > } > -#line 1687 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1766 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 26: > -#line 260 "dtc-parser.y" /* yacc.c:1646 */ > + case 32: > +#line 317 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.data) = (yyvsp[-1].data); > } > -#line 1695 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1774 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 27: > -#line 264 "dtc-parser.y" /* yacc.c:1646 */ > + case 33: > +#line 321 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); > } > -#line 1703 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1782 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 28: > -#line 271 "dtc-parser.y" /* yacc.c:1646 */ > + case 34: > +#line 328 "dtc-parser.y" /* yacc.c:1646 */ > { > unsigned long long bits; > > @@ -1719,20 +1798,20 @@ yyreduce: > (yyval.array).data = empty_data; > (yyval.array).bits = bits; > } > -#line 1723 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1802 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 29: > -#line 287 "dtc-parser.y" /* yacc.c:1646 */ > + case 35: > +#line 344 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.array).data = empty_data; > (yyval.array).bits = 32; > } > -#line 1732 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1811 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 30: > -#line 292 "dtc-parser.y" /* yacc.c:1646 */ > + case 36: > +#line 349 "dtc-parser.y" /* yacc.c:1646 */ > { > if ((yyvsp[-1].array).bits < 64) { > uint64_t mask = (1ULL << (yyvsp[-1].array).bits) - 1; > @@ -1751,11 +1830,11 @@ yyreduce: > > (yyval.array).data = data_append_integer((yyvsp[-1].array).data, (yyvsp[0].integer), (yyvsp[-1].array).bits); > } > -#line 1755 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1834 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 31: > -#line 311 "dtc-parser.y" /* yacc.c:1646 */ > + case 37: > +#line 368 "dtc-parser.y" /* yacc.c:1646 */ > { > uint64_t val = ~0ULL >> (64 - (yyvsp[-1].array).bits); > > @@ -1769,233 +1848,247 @@ yyreduce: > > (yyval.array).data = data_append_integer((yyvsp[-1].array).data, val, (yyvsp[-1].array).bits); > } > -#line 1773 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1852 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 32: > -#line 325 "dtc-parser.y" /* yacc.c:1646 */ > + case 38: > +#line 382 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.array).data = data_add_marker((yyvsp[-1].array).data, LABEL, (yyvsp[0].labelref)); > } > -#line 1781 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1860 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 35: > -#line 334 "dtc-parser.y" /* yacc.c:1646 */ > + case 41: > +#line 391 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.integer) = (yyvsp[-1].integer); > } > -#line 1789 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1868 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 38: > -#line 345 "dtc-parser.y" /* yacc.c:1646 */ > + case 44: > +#line 402 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = (yyvsp[-4].integer) ? (yyvsp[-2].integer) : (yyvsp[0].integer); } > -#line 1795 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1874 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 40: > -#line 350 "dtc-parser.y" /* yacc.c:1646 */ > + case 46: > +#line 407 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = (yyvsp[-2].integer) || (yyvsp[0].integer); } > -#line 1801 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1880 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 42: > -#line 355 "dtc-parser.y" /* yacc.c:1646 */ > + case 48: > +#line 412 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = (yyvsp[-2].integer) && (yyvsp[0].integer); } > -#line 1807 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1886 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 44: > -#line 360 "dtc-parser.y" /* yacc.c:1646 */ > + case 50: > +#line 417 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = (yyvsp[-2].integer) | (yyvsp[0].integer); } > -#line 1813 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1892 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 46: > -#line 365 "dtc-parser.y" /* yacc.c:1646 */ > + case 52: > +#line 422 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = (yyvsp[-2].integer) ^ (yyvsp[0].integer); } > -#line 1819 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1898 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 48: > -#line 370 "dtc-parser.y" /* yacc.c:1646 */ > + case 54: > +#line 427 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = (yyvsp[-2].integer) & (yyvsp[0].integer); } > -#line 1825 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1904 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 50: > -#line 375 "dtc-parser.y" /* yacc.c:1646 */ > + case 56: > +#line 432 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = (yyvsp[-2].integer) == (yyvsp[0].integer); } > -#line 1831 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1910 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 51: > -#line 376 "dtc-parser.y" /* yacc.c:1646 */ > + case 57: > +#line 433 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = (yyvsp[-2].integer) != (yyvsp[0].integer); } > -#line 1837 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1916 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 53: > -#line 381 "dtc-parser.y" /* yacc.c:1646 */ > + case 59: > +#line 438 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = (yyvsp[-2].integer) < (yyvsp[0].integer); } > -#line 1843 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1922 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 54: > -#line 382 "dtc-parser.y" /* yacc.c:1646 */ > + case 60: > +#line 439 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = (yyvsp[-2].integer) > (yyvsp[0].integer); } > -#line 1849 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1928 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 55: > -#line 383 "dtc-parser.y" /* yacc.c:1646 */ > + case 61: > +#line 440 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = (yyvsp[-2].integer) <= (yyvsp[0].integer); } > -#line 1855 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1934 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 56: > -#line 384 "dtc-parser.y" /* yacc.c:1646 */ > + case 62: > +#line 441 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = (yyvsp[-2].integer) >= (yyvsp[0].integer); } > -#line 1861 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1940 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 57: > -#line 388 "dtc-parser.y" /* yacc.c:1646 */ > + case 63: > +#line 445 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = (yyvsp[-2].integer) << (yyvsp[0].integer); } > -#line 1867 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1946 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 58: > -#line 389 "dtc-parser.y" /* yacc.c:1646 */ > + case 64: > +#line 446 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = (yyvsp[-2].integer) >> (yyvsp[0].integer); } > -#line 1873 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1952 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 60: > -#line 394 "dtc-parser.y" /* yacc.c:1646 */ > + case 66: > +#line 451 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = (yyvsp[-2].integer) + (yyvsp[0].integer); } > -#line 1879 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1958 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 61: > -#line 395 "dtc-parser.y" /* yacc.c:1646 */ > + case 67: > +#line 452 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = (yyvsp[-2].integer) - (yyvsp[0].integer); } > -#line 1885 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1964 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 63: > -#line 400 "dtc-parser.y" /* yacc.c:1646 */ > + case 69: > +#line 457 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = (yyvsp[-2].integer) * (yyvsp[0].integer); } > -#line 1891 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 1970 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 64: > -#line 401 "dtc-parser.y" /* yacc.c:1646 */ > - { (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); } > -#line 1897 "dtc-parser.tab.c" /* yacc.c:1646 */ > + case 70: > +#line 459 "dtc-parser.y" /* yacc.c:1646 */ > + { > + if ((yyvsp[0].integer) != 0) { > + (yyval.integer) = (yyvsp[-2].integer) / (yyvsp[0].integer); > + } else { > + ERROR(&(yyloc), "Division by zero"); > + (yyval.integer) = 0; > + } > + } > +#line 1983 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 65: > -#line 402 "dtc-parser.y" /* yacc.c:1646 */ > - { (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); } > -#line 1903 "dtc-parser.tab.c" /* yacc.c:1646 */ > + case 71: > +#line 468 "dtc-parser.y" /* yacc.c:1646 */ > + { > + if ((yyvsp[0].integer) != 0) { > + (yyval.integer) = (yyvsp[-2].integer) % (yyvsp[0].integer); > + } else { > + ERROR(&(yyloc), "Division by zero"); > + (yyval.integer) = 0; > + } > + } > +#line 1996 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 68: > -#line 408 "dtc-parser.y" /* yacc.c:1646 */ > + case 74: > +#line 481 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = -(yyvsp[0].integer); } > -#line 1909 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 2002 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 69: > -#line 409 "dtc-parser.y" /* yacc.c:1646 */ > + case 75: > +#line 482 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = ~(yyvsp[0].integer); } > -#line 1915 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 2008 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 70: > -#line 410 "dtc-parser.y" /* yacc.c:1646 */ > + case 76: > +#line 483 "dtc-parser.y" /* yacc.c:1646 */ > { (yyval.integer) = !(yyvsp[0].integer); } > -#line 1921 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 2014 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 71: > -#line 415 "dtc-parser.y" /* yacc.c:1646 */ > + case 77: > +#line 488 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.data) = empty_data; > } > -#line 1929 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 2022 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 72: > -#line 419 "dtc-parser.y" /* yacc.c:1646 */ > + case 78: > +#line 492 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.data) = data_append_byte((yyvsp[-1].data), (yyvsp[0].byte)); > } > -#line 1937 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 2030 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 73: > -#line 423 "dtc-parser.y" /* yacc.c:1646 */ > + case 79: > +#line 496 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.data) = data_add_marker((yyvsp[-1].data), LABEL, (yyvsp[0].labelref)); > } > -#line 1945 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 2038 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 74: > -#line 430 "dtc-parser.y" /* yacc.c:1646 */ > + case 80: > +#line 503 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.nodelist) = NULL; > } > -#line 1953 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 2046 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 75: > -#line 434 "dtc-parser.y" /* yacc.c:1646 */ > + case 81: > +#line 507 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.nodelist) = chain_node((yyvsp[-1].node), (yyvsp[0].nodelist)); > } > -#line 1961 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 2054 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 76: > -#line 438 "dtc-parser.y" /* yacc.c:1646 */ > + case 82: > +#line 511 "dtc-parser.y" /* yacc.c:1646 */ > { > ERROR(&(yylsp[0]), "Properties must precede subnodes"); > YYERROR; > } > -#line 1970 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 2063 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 77: > -#line 446 "dtc-parser.y" /* yacc.c:1646 */ > + case 83: > +#line 519 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.node) = name_node((yyvsp[0].node), (yyvsp[-1].propnodename)); > } > -#line 1978 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 2071 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 78: > -#line 450 "dtc-parser.y" /* yacc.c:1646 */ > + case 84: > +#line 523 "dtc-parser.y" /* yacc.c:1646 */ > { > (yyval.node) = name_node(build_node_delete(), (yyvsp[-1].propnodename)); > } > -#line 1986 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 2079 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > - case 79: > -#line 454 "dtc-parser.y" /* yacc.c:1646 */ > + case 85: > +#line 527 "dtc-parser.y" /* yacc.c:1646 */ > { > add_label(&(yyvsp[0].node)->labels, (yyvsp[-1].labelref)); > (yyval.node) = (yyvsp[0].node); > } > -#line 1995 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 2088 "dtc-parser.tab.c" /* yacc.c:1646 */ > break; > > > -#line 1999 "dtc-parser.tab.c" /* yacc.c:1646 */ > +#line 2092 "dtc-parser.tab.c" /* yacc.c:1646 */ > default: break; > } > /* User semantic actions sometimes alter yychar, and that requires > @@ -2230,7 +2323,7 @@ yyreturn: > #endif > return yyresult; > } > -#line 460 "dtc-parser.y" /* yacc.c:1906 */ > +#line 533 "dtc-parser.y" /* yacc.c:1906 */ > > > void yyerror(char const *s) > diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped > index 30867c688..6aa512c1b 100644 > --- a/scripts/dtc/dtc-parser.tab.h_shipped > +++ b/scripts/dtc/dtc-parser.tab.h_shipped > @@ -1,8 +1,8 @@ > -/* A Bison parser, made by GNU Bison 3.0.2. */ > +/* A Bison parser, made by GNU Bison 3.0.4. */ > > /* Bison interface for Yacc-like parsers in C > > - Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. > + Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, 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 > @@ -46,35 +46,36 @@ extern int yydebug; > enum yytokentype > { > DT_V1 = 258, > - DT_MEMRESERVE = 259, > - DT_LSHIFT = 260, > - DT_RSHIFT = 261, > - DT_LE = 262, > - DT_GE = 263, > - DT_EQ = 264, > - DT_NE = 265, > - DT_AND = 266, > - DT_OR = 267, > - DT_BITS = 268, > - DT_DEL_PROP = 269, > - DT_DEL_NODE = 270, > - DT_PROPNODENAME = 271, > - DT_LITERAL = 272, > - DT_CHAR_LITERAL = 273, > - DT_BYTE = 274, > - DT_STRING = 275, > - DT_LABEL = 276, > - DT_REF = 277, > - DT_INCBIN = 278 > + DT_PLUGIN = 259, > + DT_MEMRESERVE = 260, > + DT_LSHIFT = 261, > + DT_RSHIFT = 262, > + DT_LE = 263, > + DT_GE = 264, > + DT_EQ = 265, > + DT_NE = 266, > + DT_AND = 267, > + DT_OR = 268, > + DT_BITS = 269, > + DT_DEL_PROP = 270, > + DT_DEL_NODE = 271, > + DT_PROPNODENAME = 272, > + DT_LITERAL = 273, > + DT_CHAR_LITERAL = 274, > + DT_BYTE = 275, > + DT_STRING = 276, > + DT_LABEL = 277, > + DT_REF = 278, > + DT_INCBIN = 279 > }; > #endif > > /* Value type. */ > #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED > -typedef union YYSTYPE YYSTYPE; > + > union YYSTYPE > { > -#line 38 "dtc-parser.y" /* yacc.c:1909 */ > +#line 39 "dtc-parser.y" /* yacc.c:1909 */ > > char *propnodename; > char *labelref; > @@ -92,9 +93,12 @@ union YYSTYPE > struct node *nodelist; > struct reserve_info *re; > uint64_t integer; > + unsigned int flags; > > -#line 97 "dtc-parser.tab.h" /* yacc.c:1909 */ > +#line 99 "dtc-parser.tab.h" /* yacc.c:1909 */ > }; > + > +typedef union YYSTYPE YYSTYPE; > # define YYSTYPE_IS_TRIVIAL 1 > # define YYSTYPE_IS_DECLARED 1 > #endif > diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y > index ea57e0a05..44af170ab 100644 > --- a/scripts/dtc/dtc-parser.y > +++ b/scripts/dtc/dtc-parser.y > @@ -19,6 +19,7 @@ > */ > %{ > #include <stdio.h> > +#include <inttypes.h> > > #include "dtc.h" > #include "srcpos.h" > @@ -31,7 +32,7 @@ extern void yyerror(char const *s); > treesource_error = true; \ > } while (0) > > -extern struct boot_info *the_boot_info; > +extern struct dt_info *parser_output; > extern bool treesource_error; > %} > > @@ -52,9 +53,11 @@ extern bool treesource_error; > struct node *nodelist; > struct reserve_info *re; > uint64_t integer; > + unsigned int flags; > } > > %token DT_V1 > +%token DT_PLUGIN > %token DT_MEMRESERVE > %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR > %token DT_BITS > @@ -71,6 +74,8 @@ extern bool treesource_error; > > %type <data> propdata > %type <data> propdataprefix > +%type <flags> header > +%type <flags> headers > %type <re> memreserve > %type <re> memreserves > %type <array> arrayprefix > @@ -101,10 +106,31 @@ extern bool treesource_error; > %% > > sourcefile: > - DT_V1 ';' memreserves devicetree > + headers memreserves devicetree > { > - the_boot_info = build_boot_info($3, $4, > - guess_boot_cpuid($4)); > + parser_output = build_dt_info($1, $2, $3, > + guess_boot_cpuid($3)); > + } > + ; > + > +header: > + DT_V1 ';' > + { > + $$ = DTSF_V1; > + } > + | DT_V1 ';' DT_PLUGIN ';' > + { > + $$ = DTSF_V1 | DTSF_PLUGIN; > + } > + ; > + > +headers: > + header > + | header headers > + { > + if ($2 != $1) > + ERROR(&@2, "Header flags don't match earlier ones"); > + $$ = $1; > } > ; > > @@ -140,14 +166,45 @@ devicetree: > { > $$ = merge_nodes($1, $3); > } > + | DT_REF nodedef > + { > + /* > + * We rely on the rule being always: > + * versioninfo plugindecl memreserves devicetree > + * so $-1 is what we want (plugindecl) > + */ > + if (!($<flags>-1 & DTSF_PLUGIN)) > + ERROR(&@2, "Label or path %s not found", $1); > + $$ = add_orphan_node(name_node(build_node(NULL, NULL), ""), $2, $1); > + } > + | devicetree DT_LABEL DT_REF nodedef > + { > + struct node *target = get_node_by_ref($1, $3); > + > + if (target) { > + add_label(&target->labels, $2); > + merge_nodes(target, $4); > + } else > + ERROR(&@3, "Label or path %s not found", $3); > + $$ = $1; > + } > | devicetree DT_REF nodedef > { > struct node *target = get_node_by_ref($1, $2); > > - if (target) > + if (target) { > merge_nodes(target, $3); > - else > - ERROR(&@2, "Label or path %s not found", $2); > + } else { > + /* > + * We rely on the rule being always: > + * versioninfo plugindecl memreserves devicetree > + * so $-1 is what we want (plugindecl) > + */ > + if ($<flags>-1 & DTSF_PLUGIN) > + add_orphan_node($1, $3, $2); > + else > + ERROR(&@2, "Label or path %s not found", $2); > + } > $$ = $1; > } > | devicetree DT_DEL_NODE DT_REF ';' > @@ -398,8 +455,24 @@ integer_add: > > integer_mul: > integer_mul '*' integer_unary { $$ = $1 * $3; } > - | integer_mul '/' integer_unary { $$ = $1 / $3; } > - | integer_mul '%' integer_unary { $$ = $1 % $3; } > + | integer_mul '/' integer_unary > + { > + if ($3 != 0) { > + $$ = $1 / $3; > + } else { > + ERROR(&@$, "Division by zero"); > + $$ = 0; > + } > + } > + | integer_mul '%' integer_unary > + { > + if ($3 != 0) { > + $$ = $1 % $3; > + } else { > + ERROR(&@$, "Division by zero"); > + $$ = 0; > + } > + } > | integer_unary > ; > > diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c > index 8c4add69a..c36994e6e 100644 > --- a/scripts/dtc/dtc.c > +++ b/scripts/dtc/dtc.c > @@ -18,6 +18,8 @@ > * USA > */ > > +#include <sys/stat.h> > + > #include "dtc.h" > #include "srcpos.h" > > @@ -28,7 +30,16 @@ 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 */ > +int alignsize; /* Additional padding to blob accroding to the alignsize */ > +int phandle_format = PHANDLE_EPAPR; /* Use linux,phandle or phandle properties */ > +int generate_symbols; /* enable symbols & fixup support */ > +int generate_fixups; /* suppress generation of fixups on symbol support */ > +int auto_label_aliases; /* auto generate labels -> aliases */ > + > +static int is_power_of_2(int x) > +{ > + return (x > 0) && ((x & (x - 1)) == 0); > +} > > static void fill_fullpaths(struct node *tree, const char *prefix) > { > @@ -48,10 +59,8 @@ static void fill_fullpaths(struct node *tree, const char *prefix) > } > > /* Usage related data. */ > -#define FDT_VERSION(version) _FDT_VERSION(version) > -#define _FDT_VERSION(version) #version > static const char usage_synopsis[] = "dtc [options] <input file>"; > -static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv"; > +static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:a:fb:i:H:sW:E:@Ahv"; > static struct option const usage_long_opts[] = { > {"quiet", no_argument, NULL, 'q'}, > {"in-format", a_argument, NULL, 'I'}, > @@ -62,6 +71,7 @@ static struct option const usage_long_opts[] = { > {"reserve", a_argument, NULL, 'R'}, > {"space", a_argument, NULL, 'S'}, > {"pad", a_argument, NULL, 'p'}, > + {"align", a_argument, NULL, 'a'}, > {"boot-cpu", a_argument, NULL, 'b'}, > {"force", no_argument, NULL, 'f'}, > {"include", a_argument, NULL, 'i'}, > @@ -69,6 +79,8 @@ static struct option const usage_long_opts[] = { > {"phandle", a_argument, NULL, 'H'}, > {"warning", a_argument, NULL, 'W'}, > {"error", a_argument, NULL, 'E'}, > + {"symbols", no_argument, NULL, '@'}, > + {"auto-alias", no_argument, NULL, 'A'}, > {"help", no_argument, NULL, 'h'}, > {"version", no_argument, NULL, 'v'}, > {NULL, no_argument, NULL, 0x0}, > @@ -84,11 +96,12 @@ static const char * const usage_opts_help[] = { > "\t\tdts - device tree source text\n" > "\t\tdtb - device tree blob\n" > "\t\tasm - assembler source", > - "\n\tBlob version to produce, defaults to "FDT_VERSION(DEFAULT_FDT_VERSION)" (for dtb and asm output)", > + "\n\tBlob version to produce, defaults to "stringify(DEFAULT_FDT_VERSION)" (for dtb and asm output)", > "\n\tOutput dependency file", > "\n\tMake space for <number> reserve map entries (for dtb and asm output)", > "\n\tMake the blob at least <bytes> long (extra space)", > "\n\tAdd padding to the blob of <bytes> long (extra space)", > + "\n\tMake the blob align to the <bytes> (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", > @@ -99,16 +112,62 @@ static const char * const usage_opts_help[] = { > "\t\tboth - Both \"linux,phandle\" and \"phandle\" properties", > "\n\tEnable/disable warnings (prefix with \"no-\")", > "\n\tEnable/disable errors (prefix with \"no-\")", > + "\n\tEnable generation of symbols", > + "\n\tEnable auto-alias of labels", > "\n\tPrint this help and exit", > "\n\tPrint version and exit", > NULL, > }; > > +static const char *guess_type_by_name(const char *fname, const char *fallback) > +{ > + const char *s; > + > + s = strrchr(fname, '.'); > + if (s == NULL) > + return fallback; > + if (!strcasecmp(s, ".dts")) > + return "dts"; > + if (!strcasecmp(s, ".dtb")) > + return "dtb"; > + return fallback; > +} > + > +static const char *guess_input_format(const char *fname, const char *fallback) > +{ > + struct stat statbuf; > + fdt32_t magic; > + FILE *f; > + > + if (stat(fname, &statbuf) != 0) > + return fallback; > + > + if (S_ISDIR(statbuf.st_mode)) > + return "fs"; > + > + if (!S_ISREG(statbuf.st_mode)) > + return fallback; > + > + f = fopen(fname, "r"); > + if (f == NULL) > + return fallback; > + if (fread(&magic, 4, 1, f) != 1) { > + fclose(f); > + return fallback; > + } > + fclose(f); > + > + if (fdt32_to_cpu(magic) == FDT_MAGIC) > + return "dtb"; > + > + return guess_type_by_name(fname, fallback); > +} > + > int main(int argc, char *argv[]) > { > - struct boot_info *bi; > - const char *inform = "dts"; > - const char *outform = "dts"; > + struct dt_info *dti; > + const char *inform = NULL; > + const char *outform = NULL; > const char *outname = "-"; > const char *depname = NULL; > bool force = false, sort = false; > @@ -122,6 +181,7 @@ int main(int argc, char *argv[]) > reservenum = 0; > minsize = 0; > padsize = 0; > + alignsize = 0; > > while ((opt = util_getopt_long()) != EOF) { > switch (opt) { > @@ -149,6 +209,12 @@ int main(int argc, char *argv[]) > case 'p': > padsize = strtol(optarg, NULL, 0); > break; > + case 'a': > + alignsize = strtol(optarg, NULL, 0); > + if (!is_power_of_2(alignsize)) > + die("Invalid argument \"%d\" to -a option\n", > + alignsize); > + break; > case 'f': > force = true; > break; > @@ -187,6 +253,13 @@ int main(int argc, char *argv[]) > parse_checks_option(false, true, optarg); > break; > > + case '@': > + generate_symbols = 1; > + break; > + case 'A': > + auto_label_aliases = 1; > + break; > + > case 'h': > usage(NULL); > default: > @@ -213,28 +286,58 @@ int main(int argc, char *argv[]) > fprintf(depfile, "%s:", outname); > } > > + if (inform == NULL) > + inform = guess_input_format(arg, "dts"); > + if (outform == NULL) { > + outform = guess_type_by_name(outname, NULL); > + if (outform == NULL) { > + if (streq(inform, "dts")) > + outform = "dtb"; > + else > + outform = "dts"; > + } > + } > if (streq(inform, "dts")) > - bi = dt_from_source(arg); > + dti = dt_from_source(arg); > else if (streq(inform, "fs")) > - bi = dt_from_fs(arg); > + dti = dt_from_fs(arg); > else if(streq(inform, "dtb")) > - bi = dt_from_blob(arg); > + dti = dt_from_blob(arg); > else > die("Unknown input format \"%s\"\n", inform); > > + dti->outname = outname; > + > if (depfile) { > fputc('\n', depfile); > fclose(depfile); > } > > if (cmdline_boot_cpuid != -1) > - bi->boot_cpuid_phys = cmdline_boot_cpuid; > + dti->boot_cpuid_phys = cmdline_boot_cpuid; > + > + fill_fullpaths(dti->dt, ""); > + > + /* on a plugin, generate by default */ > + if (dti->dtsflags & DTSF_PLUGIN) { > + generate_fixups = 1; > + } > > - fill_fullpaths(bi->dt, ""); > - process_checks(force, bi); > + process_checks(force, dti); > + > + if (auto_label_aliases) > + generate_label_tree(dti, "aliases", false); > + > + if (generate_symbols) > + generate_label_tree(dti, "__symbols__", true); > + > + if (generate_fixups) { > + generate_fixups_tree(dti, "__fixups__"); > + generate_local_fixups_tree(dti, "__local_fixups__"); > + } > > if (sort) > - sort_tree(bi); > + sort_tree(dti); > > if (streq(outname, "-")) { > outf = stdout; > @@ -246,11 +349,11 @@ int main(int argc, char *argv[]) > } > > if (streq(outform, "dts")) { > - dt_to_source(outf, bi); > + dt_to_source(outf, dti); > } else if (streq(outform, "dtb")) { > - dt_to_blob(outf, bi, outversion); > + dt_to_blob(outf, dti, outversion); > } else if (streq(outform, "asm")) { > - dt_to_asm(outf, bi, outversion); > + dt_to_asm(outf, dti, outversion); > } else if (streq(outform, "null")) { > /* do nothing */ > } else { > diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h > index 56212c8df..3b18a42b8 100644 > --- a/scripts/dtc/dtc.h > +++ b/scripts/dtc/dtc.h > @@ -1,5 +1,5 @@ > -#ifndef _DTC_H > -#define _DTC_H > +#ifndef DTC_H > +#define DTC_H > > /* > * (C) Copyright David Gibson <dwg@xxxxxxxxxxx>, IBM Corporation. 2005. > @@ -31,6 +31,7 @@ > #include <ctype.h> > #include <errno.h> > #include <unistd.h> > +#include <inttypes.h> > > #include <libfdt_env.h> > #include <fdt.h> > @@ -43,7 +44,6 @@ > #define debug(...) > #endif > > - > #define DEFAULT_FDT_VERSION 17 > > /* > @@ -53,7 +53,11 @@ 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 alignsize; /* Additional padding to blob accroding to the alignsize */ > extern int phandle_format; /* Use linux,phandle or phandle properties */ > +extern int generate_symbols; /* generate symbols for nodes with labels */ > +extern int generate_fixups; /* generate fixups */ > +extern int auto_label_aliases; /* auto generate labels -> aliases */ > > #define PHANDLE_LEGACY 0x1 > #define PHANDLE_EPAPR 0x2 > @@ -63,7 +67,8 @@ typedef uint32_t cell_t; > > > #define streq(a, b) (strcmp((a), (b)) == 0) > -#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) > +#define strstarts(s, prefix) (strncmp((s), (prefix), strlen(prefix)) == 0) > +#define strprefixeq(a, n, b) (strlen(b) == (n) && (memcmp(a, b, n) == 0)) > > #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) > > @@ -110,7 +115,7 @@ struct data data_insert_at_marker(struct data d, struct marker *m, > 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_re(struct data d, uint64_t address, uint64_t size); > 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); > @@ -132,6 +137,10 @@ struct label { > struct label *next; > }; > > +struct bus_type { > + const char *name; > +}; > + > struct property { > bool deleted; > char *name; > @@ -158,6 +167,7 @@ struct node { > int addr_cells, size_cells; > > struct label *labels; > + const struct bus_type *bus; > }; > > #define for_each_label_withdel(l0, l) \ > @@ -194,6 +204,7 @@ 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); > +struct node *add_orphan_node(struct node *old_node, struct node *new_node, char *ref); > > void add_property(struct node *node, struct property *prop); > void delete_property_by_name(struct node *node, char *name); > @@ -201,10 +212,13 @@ 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); > +void append_to_property(struct node *node, > + char *name, const void *data, int len); > > const char *get_unitname(struct node *node); > struct property *get_property(struct node *node, const char *propname); > cell_t propval_cell(struct property *prop); > +cell_t propval_cell_n(struct property *prop, int n); > 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, > @@ -221,7 +235,7 @@ uint32_t guess_boot_cpuid(struct node *tree); > /* Boot info (tree plus memreserve information */ > > struct reserve_info { > - struct fdt_reserve_entry re; > + uint64_t address, size; > > struct reserve_info *next; > > @@ -235,35 +249,45 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list, > struct reserve_info *new); > > > -struct boot_info { > +struct dt_info { > + unsigned int dtsflags; > struct reserve_info *reservelist; > - struct node *dt; /* the device tree */ > uint32_t boot_cpuid_phys; > + struct node *dt; /* the device tree */ > + const char *outname; /* filename being written to, "-" for stdout */ > }; > > -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); > +/* DTS version flags definitions */ > +#define DTSF_V1 0x0001 /* /dts-v1/ */ > +#define DTSF_PLUGIN 0x0002 /* /plugin/ */ > + > +struct dt_info *build_dt_info(unsigned int dtsflags, > + struct reserve_info *reservelist, > + struct node *tree, uint32_t boot_cpuid_phys); > +void sort_tree(struct dt_info *dti); > +void generate_label_tree(struct dt_info *dti, char *name, bool allocph); > +void generate_fixups_tree(struct dt_info *dti, char *name); > +void generate_local_fixups_tree(struct dt_info *dti, char *name); > > /* Checks */ > > void parse_checks_option(bool warn, bool error, const char *arg); > -void process_checks(bool force, struct boot_info *bi); > +void process_checks(bool force, struct dt_info *dti); > > /* 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); > +void dt_to_blob(FILE *f, struct dt_info *dti, int version); > +void dt_to_asm(FILE *f, struct dt_info *dti, int version); > > -struct boot_info *dt_from_blob(const char *fname); > +struct dt_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); > +void dt_to_source(FILE *f, struct dt_info *dti); > +struct dt_info *dt_from_source(const char *f); > > /* FS trees */ > > -struct boot_info *dt_from_fs(const char *dirname); > +struct dt_info *dt_from_fs(const char *dirname); > > -#endif /* _DTC_H */ > +#endif /* DTC_H */ > diff --git a/scripts/dtc/fdt.c b/scripts/dtc/fdt.c > index 2ce6a4417..7855a1787 100644 > --- a/scripts/dtc/fdt.c > +++ b/scripts/dtc/fdt.c > @@ -76,18 +76,19 @@ int fdt_check_header(const void *fdt) > > const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) > { > - const char *p; > + unsigned absoffset = offset + fdt_off_dt_struct(fdt); > + > + if ((absoffset < offset) > + || ((absoffset + len) < absoffset) > + || (absoffset + len) > fdt_totalsize(fdt)) > + return NULL; > > 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; > + return fdt_offset_ptr_(fdt, offset); > } > > uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) > @@ -122,6 +123,9 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) > /* skip-name offset, length and value */ > offset += sizeof(struct fdt_property) - FDT_TAGSIZE > + fdt32_to_cpu(*lenp); > + if (fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 && > + ((offset - fdt32_to_cpu(*lenp)) % 8) != 0) > + offset += 4; > break; > > case FDT_END: > @@ -140,7 +144,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) > return tag; > } > > -int _fdt_check_node_offset(const void *fdt, int offset) > +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)) > @@ -149,7 +153,7 @@ int _fdt_check_node_offset(const void *fdt, int offset) > return offset; > } > > -int _fdt_check_prop_offset(const void *fdt, int 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)) > @@ -164,7 +168,7 @@ int fdt_next_node(const void *fdt, int offset, int *depth) > uint32_t tag; > > if (offset >= 0) > - if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0) > + if ((nextoffset = fdt_check_node_offset_(fdt, offset)) < 0) > return nextoffset; > > do { > @@ -226,7 +230,7 @@ int fdt_next_subnode(const void *fdt, int offset) > return offset; > } > > -const char *_fdt_find_string(const char *strtab, int tabsize, const char *s) > +const char *fdt_find_string_(const char *strtab, int tabsize, const char *s) > { > int len = strlen(s) + 1; > const char *last = strtab + tabsize - len; > diff --git a/scripts/dtc/fdt.h b/scripts/dtc/fdt.h > index 526aedb51..74961f902 100644 > --- a/scripts/dtc/fdt.h > +++ b/scripts/dtc/fdt.h > @@ -1,5 +1,5 @@ > -#ifndef _FDT_H > -#define _FDT_H > +#ifndef FDT_H > +#define FDT_H > /* > * libfdt - Flat Device Tree manipulation > * Copyright (C) 2006 David Gibson, IBM Corporation. > @@ -108,4 +108,4 @@ struct fdt_property { > #define FDT_V16_SIZE FDT_V3_SIZE > #define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t)) > > -#endif /* _FDT_H */ > +#endif /* FDT_H */ > diff --git a/scripts/dtc/fdt_empty_tree.c b/scripts/dtc/fdt_empty_tree.c > index f72d13b1d..f2ae9b77c 100644 > --- a/scripts/dtc/fdt_empty_tree.c > +++ b/scripts/dtc/fdt_empty_tree.c > @@ -81,4 +81,3 @@ int fdt_create_empty_tree(void *buf, int bufsize) > > return fdt_open_into(buf, buf, bufsize); > } > - > diff --git a/scripts/dtc/fdt_overlay.c b/scripts/dtc/fdt_overlay.c > new file mode 100644 > index 000000000..bf75388ec > --- /dev/null > +++ b/scripts/dtc/fdt_overlay.c > @@ -0,0 +1,912 @@ > +/* > + * libfdt - Flat Device Tree manipulation > + * Copyright (C) 2016 Free Electrons > + * Copyright (C) 2016 NextThing Co. > + * > + * 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 <fdt.h> > +#include <libfdt.h> > + > +#include "libfdt_internal.h" > + > +/** > + * overlay_get_target_phandle - retrieves the target phandle of a fragment > + * @fdto: pointer to the device tree overlay blob > + * @fragment: node offset of the fragment in the overlay > + * > + * overlay_get_target_phandle() retrieves the target phandle of an > + * overlay fragment when that fragment uses a phandle (target > + * property) instead of a path (target-path property). > + * > + * returns: > + * the phandle pointed by the target property > + * 0, if the phandle was not found > + * -1, if the phandle was malformed > + */ > +static uint32_t overlay_get_target_phandle(const void *fdto, int fragment) > +{ > + const fdt32_t *val; > + int len; > + > + val = fdt_getprop(fdto, fragment, "target", &len); > + if (!val) > + return 0; > + > + if ((len != sizeof(*val)) || (fdt32_to_cpu(*val) == (uint32_t)-1)) > + return (uint32_t)-1; > + > + return fdt32_to_cpu(*val); > +} > + > +/** > + * overlay_get_target - retrieves the offset of a fragment's target > + * @fdt: Base device tree blob > + * @fdto: Device tree overlay blob > + * @fragment: node offset of the fragment in the overlay > + * @pathp: pointer which receives the path of the target (or NULL) > + * > + * overlay_get_target() retrieves the target offset in the base > + * device tree of a fragment, no matter how the actual targetting is > + * done (through a phandle or a path) > + * > + * returns: > + * the targetted node offset in the base device tree > + * Negative error code on error > + */ > +static int overlay_get_target(const void *fdt, const void *fdto, > + int fragment, char const **pathp) > +{ > + uint32_t phandle; > + const char *path = NULL; > + int path_len = 0, ret; > + > + /* Try first to do a phandle based lookup */ > + phandle = overlay_get_target_phandle(fdto, fragment); > + if (phandle == (uint32_t)-1) > + return -FDT_ERR_BADPHANDLE; > + > + /* no phandle, try path */ > + if (!phandle) { > + /* And then a path based lookup */ > + path = fdt_getprop(fdto, fragment, "target-path", &path_len); > + if (path) > + ret = fdt_path_offset(fdt, path); > + else > + ret = path_len; > + } else > + ret = fdt_node_offset_by_phandle(fdt, phandle); > + > + /* > + * If we haven't found either a target or a > + * target-path property in a node that contains a > + * __overlay__ subnode (we wouldn't be called > + * otherwise), consider it a improperly written > + * overlay > + */ > + if (ret < 0 && path_len == -FDT_ERR_NOTFOUND) > + ret = -FDT_ERR_BADOVERLAY; > + > + /* return on error */ > + if (ret < 0) > + return ret; > + > + /* return pointer to path (if available) */ > + if (pathp) > + *pathp = path ? path : NULL; > + > + return ret; > +} > + > +/** > + * overlay_phandle_add_offset - Increases a phandle by an offset > + * @fdt: Base device tree blob > + * @node: Device tree overlay blob > + * @name: Name of the property to modify (phandle or linux,phandle) > + * @delta: offset to apply > + * > + * overlay_phandle_add_offset() increments a node phandle by a given > + * offset. > + * > + * returns: > + * 0 on success. > + * Negative error code on error > + */ > +static int overlay_phandle_add_offset(void *fdt, int node, > + const char *name, uint32_t delta) > +{ > + const fdt32_t *val; > + uint32_t adj_val; > + int len; > + > + val = fdt_getprop(fdt, node, name, &len); > + if (!val) > + return len; > + > + if (len != sizeof(*val)) > + return -FDT_ERR_BADPHANDLE; > + > + adj_val = fdt32_to_cpu(*val); > + if ((adj_val + delta) < adj_val) > + return -FDT_ERR_NOPHANDLES; > + > + adj_val += delta; > + if (adj_val == (uint32_t)-1) > + return -FDT_ERR_NOPHANDLES; > + > + return fdt_setprop_inplace_u32(fdt, node, name, adj_val); > +} > + > +/** > + * overlay_adjust_node_phandles - Offsets the phandles of a node > + * @fdto: Device tree overlay blob > + * @node: Offset of the node we want to adjust > + * @delta: Offset to shift the phandles of > + * > + * overlay_adjust_node_phandles() adds a constant to all the phandles > + * of a given node. This is mainly use as part of the overlay > + * application process, when we want to update all the overlay > + * phandles to not conflict with the overlays of the base device tree. > + * > + * returns: > + * 0 on success > + * Negative error code on failure > + */ > +static int overlay_adjust_node_phandles(void *fdto, int node, > + uint32_t delta) > +{ > + int child; > + int ret; > + > + ret = overlay_phandle_add_offset(fdto, node, "phandle", delta); > + if (ret && ret != -FDT_ERR_NOTFOUND) > + return ret; > + > + ret = overlay_phandle_add_offset(fdto, node, "linux,phandle", delta); > + if (ret && ret != -FDT_ERR_NOTFOUND) > + return ret; > + > + fdt_for_each_subnode(child, fdto, node) { > + ret = overlay_adjust_node_phandles(fdto, child, delta); > + if (ret) > + return ret; > + } > + > + return 0; > +} > + > +/** > + * overlay_adjust_local_phandles - Adjust the phandles of a whole overlay > + * @fdto: Device tree overlay blob > + * @delta: Offset to shift the phandles of > + * > + * overlay_adjust_local_phandles() adds a constant to all the > + * phandles of an overlay. This is mainly use as part of the overlay > + * application process, when we want to update all the overlay > + * phandles to not conflict with the overlays of the base device tree. > + * > + * returns: > + * 0 on success > + * Negative error code on failure > + */ > +static int overlay_adjust_local_phandles(void *fdto, uint32_t delta) > +{ > + /* > + * Start adjusting the phandles from the overlay root > + */ > + return overlay_adjust_node_phandles(fdto, 0, delta); > +} > + > +/** > + * overlay_update_local_node_references - Adjust the overlay references > + * @fdto: Device tree overlay blob > + * @tree_node: Node offset of the node to operate on > + * @fixup_node: Node offset of the matching local fixups node > + * @delta: Offset to shift the phandles of > + * > + * overlay_update_local_nodes_references() update the phandles > + * pointing to a node within the device tree overlay by adding a > + * constant delta. > + * > + * This is mainly used as part of a device tree application process, > + * where you want the device tree overlays phandles to not conflict > + * with the ones from the base device tree before merging them. > + * > + * returns: > + * 0 on success > + * Negative error code on failure > + */ > +static int overlay_update_local_node_references(void *fdto, > + int tree_node, > + int fixup_node, > + uint32_t delta) > +{ > + int fixup_prop; > + int fixup_child; > + int ret; > + > + fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) { > + const fdt32_t *fixup_val; > + const char *tree_val; > + const char *name; > + int fixup_len; > + int tree_len; > + int i; > + > + fixup_val = fdt_getprop_by_offset(fdto, fixup_prop, > + &name, &fixup_len); > + if (!fixup_val) > + return fixup_len; > + > + if (fixup_len % sizeof(uint32_t)) > + return -FDT_ERR_BADOVERLAY; > + > + tree_val = fdt_getprop(fdto, tree_node, name, &tree_len); > + if (!tree_val) { > + if (tree_len == -FDT_ERR_NOTFOUND) > + return -FDT_ERR_BADOVERLAY; > + > + return tree_len; > + } > + > + for (i = 0; i < (fixup_len / sizeof(uint32_t)); i++) { > + fdt32_t adj_val; > + uint32_t poffset; > + > + poffset = fdt32_to_cpu(fixup_val[i]); > + > + /* > + * phandles to fixup can be unaligned. > + * > + * Use a memcpy for the architectures that do > + * not support unaligned accesses. > + */ > + memcpy(&adj_val, tree_val + poffset, sizeof(adj_val)); > + > + adj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta); > + > + ret = fdt_setprop_inplace_namelen_partial(fdto, > + tree_node, > + name, > + strlen(name), > + poffset, > + &adj_val, > + sizeof(adj_val)); > + if (ret == -FDT_ERR_NOSPACE) > + return -FDT_ERR_BADOVERLAY; > + > + if (ret) > + return ret; > + } > + } > + > + fdt_for_each_subnode(fixup_child, fdto, fixup_node) { > + const char *fixup_child_name = fdt_get_name(fdto, fixup_child, > + NULL); > + int tree_child; > + > + tree_child = fdt_subnode_offset(fdto, tree_node, > + fixup_child_name); > + if (tree_child == -FDT_ERR_NOTFOUND) > + return -FDT_ERR_BADOVERLAY; > + if (tree_child < 0) > + return tree_child; > + > + ret = overlay_update_local_node_references(fdto, > + tree_child, > + fixup_child, > + delta); > + if (ret) > + return ret; > + } > + > + return 0; > +} > + > +/** > + * overlay_update_local_references - Adjust the overlay references > + * @fdto: Device tree overlay blob > + * @delta: Offset to shift the phandles of > + * > + * overlay_update_local_references() update all the phandles pointing > + * to a node within the device tree overlay by adding a constant > + * delta to not conflict with the base overlay. > + * > + * This is mainly used as part of a device tree application process, > + * where you want the device tree overlays phandles to not conflict > + * with the ones from the base device tree before merging them. > + * > + * returns: > + * 0 on success > + * Negative error code on failure > + */ > +static int overlay_update_local_references(void *fdto, uint32_t delta) > +{ > + int fixups; > + > + fixups = fdt_path_offset(fdto, "/__local_fixups__"); > + if (fixups < 0) { > + /* There's no local phandles to adjust, bail out */ > + if (fixups == -FDT_ERR_NOTFOUND) > + return 0; > + > + return fixups; > + } > + > + /* > + * Update our local references from the root of the tree > + */ > + return overlay_update_local_node_references(fdto, 0, fixups, > + delta); > +} > + > +/** > + * overlay_fixup_one_phandle - Set an overlay phandle to the base one > + * @fdt: Base Device Tree blob > + * @fdto: Device tree overlay blob > + * @symbols_off: Node offset of the symbols node in the base device tree > + * @path: Path to a node holding a phandle in the overlay > + * @path_len: number of path characters to consider > + * @name: Name of the property holding the phandle reference in the overlay > + * @name_len: number of name characters to consider > + * @poffset: Offset within the overlay property where the phandle is stored > + * @label: Label of the node referenced by the phandle > + * > + * overlay_fixup_one_phandle() resolves an overlay phandle pointing to > + * a node in the base device tree. > + * > + * This is part of the device tree overlay application process, when > + * you want all the phandles in the overlay to point to the actual > + * base dt nodes. > + * > + * returns: > + * 0 on success > + * Negative error code on failure > + */ > +static int overlay_fixup_one_phandle(void *fdt, void *fdto, > + int symbols_off, > + const char *path, uint32_t path_len, > + const char *name, uint32_t name_len, > + int poffset, const char *label) > +{ > + const char *symbol_path; > + uint32_t phandle; > + fdt32_t phandle_prop; > + int symbol_off, fixup_off; > + int prop_len; > + > + if (symbols_off < 0) > + return symbols_off; > + > + symbol_path = fdt_getprop(fdt, symbols_off, label, > + &prop_len); > + if (!symbol_path) > + return prop_len; > + > + symbol_off = fdt_path_offset(fdt, symbol_path); > + if (symbol_off < 0) > + return symbol_off; > + > + phandle = fdt_get_phandle(fdt, symbol_off); > + if (!phandle) > + return -FDT_ERR_NOTFOUND; > + > + fixup_off = fdt_path_offset_namelen(fdto, path, path_len); > + if (fixup_off == -FDT_ERR_NOTFOUND) > + return -FDT_ERR_BADOVERLAY; > + if (fixup_off < 0) > + return fixup_off; > + > + phandle_prop = cpu_to_fdt32(phandle); > + return fdt_setprop_inplace_namelen_partial(fdto, fixup_off, > + name, name_len, poffset, > + &phandle_prop, > + sizeof(phandle_prop)); > +}; > + > +/** > + * overlay_fixup_phandle - Set an overlay phandle to the base one > + * @fdt: Base Device Tree blob > + * @fdto: Device tree overlay blob > + * @symbols_off: Node offset of the symbols node in the base device tree > + * @property: Property offset in the overlay holding the list of fixups > + * > + * overlay_fixup_phandle() resolves all the overlay phandles pointed > + * to in a __fixups__ property, and updates them to match the phandles > + * in use in the base device tree. > + * > + * This is part of the device tree overlay application process, when > + * you want all the phandles in the overlay to point to the actual > + * base dt nodes. > + * > + * returns: > + * 0 on success > + * Negative error code on failure > + */ > +static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off, > + int property) > +{ > + const char *value; > + const char *label; > + int len; > + > + value = fdt_getprop_by_offset(fdto, property, > + &label, &len); > + if (!value) { > + if (len == -FDT_ERR_NOTFOUND) > + return -FDT_ERR_INTERNAL; > + > + return len; > + } > + > + do { > + const char *path, *name, *fixup_end; > + const char *fixup_str = value; > + uint32_t path_len, name_len; > + uint32_t fixup_len; > + char *sep, *endptr; > + int poffset, ret; > + > + fixup_end = memchr(value, '\0', len); > + if (!fixup_end) > + return -FDT_ERR_BADOVERLAY; > + fixup_len = fixup_end - fixup_str; > + > + len -= fixup_len + 1; > + value += fixup_len + 1; > + > + path = fixup_str; > + sep = memchr(fixup_str, ':', fixup_len); > + if (!sep || *sep != ':') > + return -FDT_ERR_BADOVERLAY; > + > + path_len = sep - path; > + if (path_len == (fixup_len - 1)) > + return -FDT_ERR_BADOVERLAY; > + > + fixup_len -= path_len + 1; > + name = sep + 1; > + sep = memchr(name, ':', fixup_len); > + if (!sep || *sep != ':') > + return -FDT_ERR_BADOVERLAY; > + > + name_len = sep - name; > + if (!name_len) > + return -FDT_ERR_BADOVERLAY; > + > + poffset = strtoul(sep + 1, &endptr, 10); > + if ((*endptr != '\0') || (endptr <= (sep + 1))) > + return -FDT_ERR_BADOVERLAY; > + > + ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off, > + path, path_len, name, name_len, > + poffset, label); > + if (ret) > + return ret; > + } while (len > 0); > + > + return 0; > +} > + > +/** > + * overlay_fixup_phandles - Resolve the overlay phandles to the base > + * device tree > + * @fdt: Base Device Tree blob > + * @fdto: Device tree overlay blob > + * > + * overlay_fixup_phandles() resolves all the overlay phandles pointing > + * to nodes in the base device tree. > + * > + * This is one of the steps of the device tree overlay application > + * process, when you want all the phandles in the overlay to point to > + * the actual base dt nodes. > + * > + * returns: > + * 0 on success > + * Negative error code on failure > + */ > +static int overlay_fixup_phandles(void *fdt, void *fdto) > +{ > + int fixups_off, symbols_off; > + int property; > + > + /* We can have overlays without any fixups */ > + fixups_off = fdt_path_offset(fdto, "/__fixups__"); > + if (fixups_off == -FDT_ERR_NOTFOUND) > + return 0; /* nothing to do */ > + if (fixups_off < 0) > + return fixups_off; > + > + /* And base DTs without symbols */ > + symbols_off = fdt_path_offset(fdt, "/__symbols__"); > + if ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND))) > + return symbols_off; > + > + fdt_for_each_property_offset(property, fdto, fixups_off) { > + int ret; > + > + ret = overlay_fixup_phandle(fdt, fdto, symbols_off, property); > + if (ret) > + return ret; > + } > + > + return 0; > +} > + > +/** > + * overlay_apply_node - Merges a node into the base device tree > + * @fdt: Base Device Tree blob > + * @target: Node offset in the base device tree to apply the fragment to > + * @fdto: Device tree overlay blob > + * @node: Node offset in the overlay holding the changes to merge > + * > + * overlay_apply_node() merges a node into a target base device tree > + * node pointed. > + * > + * This is part of the final step in the device tree overlay > + * application process, when all the phandles have been adjusted and > + * resolved and you just have to merge overlay into the base device > + * tree. > + * > + * returns: > + * 0 on success > + * Negative error code on failure > + */ > +static int overlay_apply_node(void *fdt, int target, > + void *fdto, int node) > +{ > + int property; > + int subnode; > + > + fdt_for_each_property_offset(property, fdto, node) { > + const char *name; > + const void *prop; > + int prop_len; > + int ret; > + > + prop = fdt_getprop_by_offset(fdto, property, &name, > + &prop_len); > + if (prop_len == -FDT_ERR_NOTFOUND) > + return -FDT_ERR_INTERNAL; > + if (prop_len < 0) > + return prop_len; > + > + ret = fdt_setprop(fdt, target, name, prop, prop_len); > + if (ret) > + return ret; > + } > + > + fdt_for_each_subnode(subnode, fdto, node) { > + const char *name = fdt_get_name(fdto, subnode, NULL); > + int nnode; > + int ret; > + > + nnode = fdt_add_subnode(fdt, target, name); > + if (nnode == -FDT_ERR_EXISTS) { > + nnode = fdt_subnode_offset(fdt, target, name); > + if (nnode == -FDT_ERR_NOTFOUND) > + return -FDT_ERR_INTERNAL; > + } > + > + if (nnode < 0) > + return nnode; > + > + ret = overlay_apply_node(fdt, nnode, fdto, subnode); > + if (ret) > + return ret; > + } > + > + return 0; > +} > + > +/** > + * overlay_merge - Merge an overlay into its base device tree > + * @fdt: Base Device Tree blob > + * @fdto: Device tree overlay blob > + * > + * overlay_merge() merges an overlay into its base device tree. > + * > + * This is the next to last step in the device tree overlay application > + * process, when all the phandles have been adjusted and resolved and > + * you just have to merge overlay into the base device tree. > + * > + * returns: > + * 0 on success > + * Negative error code on failure > + */ > +static int overlay_merge(void *fdt, void *fdto) > +{ > + int fragment; > + > + fdt_for_each_subnode(fragment, fdto, 0) { > + int overlay; > + int target; > + int ret; > + > + /* > + * Each fragments will have an __overlay__ node. If > + * they don't, it's not supposed to be merged > + */ > + overlay = fdt_subnode_offset(fdto, fragment, "__overlay__"); > + if (overlay == -FDT_ERR_NOTFOUND) > + continue; > + > + if (overlay < 0) > + return overlay; > + > + target = overlay_get_target(fdt, fdto, fragment, NULL); > + if (target < 0) > + return target; > + > + ret = overlay_apply_node(fdt, target, fdto, overlay); > + if (ret) > + return ret; > + } > + > + return 0; > +} > + > +static int get_path_len(const void *fdt, int nodeoffset) > +{ > + int len = 0, namelen; > + const char *name; > + > + FDT_CHECK_HEADER(fdt); > + > + for (;;) { > + name = fdt_get_name(fdt, nodeoffset, &namelen); > + if (!name) > + return namelen; > + > + /* root? we're done */ > + if (namelen == 0) > + break; > + > + nodeoffset = fdt_parent_offset(fdt, nodeoffset); > + if (nodeoffset < 0) > + return nodeoffset; > + len += namelen + 1; > + } > + > + /* in case of root pretend it's "/" */ > + if (len == 0) > + len++; > + return len; > +} > + > +/** > + * overlay_symbol_update - Update the symbols of base tree after a merge > + * @fdt: Base Device Tree blob > + * @fdto: Device tree overlay blob > + * > + * overlay_symbol_update() updates the symbols of the base tree with the > + * symbols of the applied overlay > + * > + * This is the last step in the device tree overlay application > + * process, allowing the reference of overlay symbols by subsequent > + * overlay operations. > + * > + * returns: > + * 0 on success > + * Negative error code on failure > + */ > +static int overlay_symbol_update(void *fdt, void *fdto) > +{ > + int root_sym, ov_sym, prop, path_len, fragment, target; > + int len, frag_name_len, ret, rel_path_len; > + const char *s, *e; > + const char *path; > + const char *name; > + const char *frag_name; > + const char *rel_path; > + const char *target_path; > + char *buf; > + void *p; > + > + ov_sym = fdt_subnode_offset(fdto, 0, "__symbols__"); > + > + /* if no overlay symbols exist no problem */ > + if (ov_sym < 0) > + return 0; > + > + root_sym = fdt_subnode_offset(fdt, 0, "__symbols__"); > + > + /* it no root symbols exist we should create them */ > + if (root_sym == -FDT_ERR_NOTFOUND) > + root_sym = fdt_add_subnode(fdt, 0, "__symbols__"); > + > + /* any error is fatal now */ > + if (root_sym < 0) > + return root_sym; > + > + /* iterate over each overlay symbol */ > + fdt_for_each_property_offset(prop, fdto, ov_sym) { > + path = fdt_getprop_by_offset(fdto, prop, &name, &path_len); > + if (!path) > + return path_len; > + > + /* verify it's a string property (terminated by a single \0) */ > + if (path_len < 1 || memchr(path, '\0', path_len) != &path[path_len - 1]) > + return -FDT_ERR_BADVALUE; > + > + /* keep end marker to avoid strlen() */ > + e = path + path_len; > + > + /* format: /<fragment-name>/__overlay__/<relative-subnode-path> */ > + > + if (*path != '/') > + return -FDT_ERR_BADVALUE; > + > + /* get fragment name first */ > + s = strchr(path + 1, '/'); > + if (!s) > + return -FDT_ERR_BADOVERLAY; > + > + frag_name = path + 1; > + frag_name_len = s - path - 1; > + > + /* verify format; safe since "s" lies in \0 terminated prop */ > + len = sizeof("/__overlay__/") - 1; > + if ((e - s) < len || memcmp(s, "/__overlay__/", len)) > + return -FDT_ERR_BADOVERLAY; > + > + rel_path = s + len; > + rel_path_len = e - rel_path; > + > + /* find the fragment index in which the symbol lies */ > + ret = fdt_subnode_offset_namelen(fdto, 0, frag_name, > + frag_name_len); > + /* not found? */ > + if (ret < 0) > + return -FDT_ERR_BADOVERLAY; > + fragment = ret; > + > + /* an __overlay__ subnode must exist */ > + ret = fdt_subnode_offset(fdto, fragment, "__overlay__"); > + if (ret < 0) > + return -FDT_ERR_BADOVERLAY; > + > + /* get the target of the fragment */ > + ret = overlay_get_target(fdt, fdto, fragment, &target_path); > + if (ret < 0) > + return ret; > + target = ret; > + > + /* if we have a target path use */ > + if (!target_path) { > + ret = get_path_len(fdt, target); > + if (ret < 0) > + return ret; > + len = ret; > + } else { > + len = strlen(target_path); > + } > + > + ret = fdt_setprop_placeholder(fdt, root_sym, name, > + len + (len > 1) + rel_path_len + 1, &p); > + if (ret < 0) > + return ret; > + > + if (!target_path) { > + /* again in case setprop_placeholder changed it */ > + ret = overlay_get_target(fdt, fdto, fragment, &target_path); > + if (ret < 0) > + return ret; > + target = ret; > + } > + > + buf = p; > + if (len > 1) { /* target is not root */ > + if (!target_path) { > + ret = fdt_get_path(fdt, target, buf, len + 1); > + if (ret < 0) > + return ret; > + } else > + memcpy(buf, target_path, len + 1); > + > + } else > + len--; > + > + buf[len] = '/'; > + memcpy(buf + len + 1, rel_path, rel_path_len); > + buf[len + 1 + rel_path_len] = '\0'; > + } > + > + return 0; > +} > + > +int fdt_overlay_apply(void *fdt, void *fdto) > +{ > + uint32_t delta = fdt_get_max_phandle(fdt); > + int ret; > + > + FDT_CHECK_HEADER(fdt); > + FDT_CHECK_HEADER(fdto); > + > + ret = overlay_adjust_local_phandles(fdto, delta); > + if (ret) > + goto err; > + > + ret = overlay_update_local_references(fdto, delta); > + if (ret) > + goto err; > + > + ret = overlay_fixup_phandles(fdt, fdto); > + if (ret) > + goto err; > + > + ret = overlay_merge(fdt, fdto); > + if (ret) > + goto err; > + > + ret = overlay_symbol_update(fdt, fdto); > + if (ret) > + goto err; > + > + /* > + * The overlay has been damaged, erase its magic. > + */ > + fdt_set_magic(fdto, ~0); > + > + return 0; > + > +err: > + /* > + * The overlay might have been damaged, erase its magic. > + */ > + fdt_set_magic(fdto, ~0); > + > + /* > + * The base device tree might have been damaged, erase its > + * magic. > + */ > + fdt_set_magic(fdt, ~0); > + > + return ret; > +} > diff --git a/scripts/dtc/fdt_ro.c b/scripts/dtc/fdt_ro.c > index 50007f61c..dfb3236da 100644 > --- a/scripts/dtc/fdt_ro.c > +++ b/scripts/dtc/fdt_ro.c > @@ -55,12 +55,13 @@ > > #include "libfdt_internal.h" > > -static int _fdt_nodename_eq(const void *fdt, int offset, > +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); > + int olen; > + const char *p = fdt_get_name(fdt, offset, &olen); > > - if (! p) > + if (!p || olen < len) > /* short match */ > return 0; > > @@ -80,7 +81,7 @@ 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, > +static int fdt_string_eq_(const void *fdt, int stroffset, > const char *s, int len) > { > const char *p = fdt_string(fdt, stroffset); > @@ -88,11 +89,37 @@ static int _fdt_string_eq(const void *fdt, int stroffset, > return (strlen(p) == len) && (memcmp(p, s, len) == 0); > } > > +uint32_t fdt_get_max_phandle(const void *fdt) > +{ > + uint32_t max_phandle = 0; > + int offset; > + > + for (offset = fdt_next_node(fdt, -1, NULL);; > + offset = fdt_next_node(fdt, offset, NULL)) { > + uint32_t phandle; > + > + if (offset == -FDT_ERR_NOTFOUND) > + return max_phandle; > + > + if (offset < 0) > + return (uint32_t)-1; > + > + phandle = fdt_get_phandle(fdt, offset); > + if (phandle == (uint32_t)-1) > + continue; > + > + if (phandle > max_phandle) > + max_phandle = phandle; > + } > + > + return 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); > + *address = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->address); > + *size = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->size); > return 0; > } > > @@ -100,12 +127,12 @@ int fdt_num_mem_rsv(const void *fdt) > { > int i = 0; > > - while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0) > + while (fdt64_to_cpu(fdt_mem_rsv_(fdt, i)->size) != 0) > i++; > return i; > } > > -static int _nextprop(const void *fdt, int offset) > +static int nextprop_(const void *fdt, int offset) > { > uint32_t tag; > int nextoffset; > @@ -140,7 +167,7 @@ int fdt_subnode_offset_namelen(const void *fdt, int offset, > (offset >= 0) && (depth >= 0); > offset = fdt_next_node(fdt, offset, &depth)) > if ((depth == 1) > - && _fdt_nodename_eq(fdt, offset, name, namelen)) > + && fdt_nodename_eq_(fdt, offset, name, namelen)) > return offset; > > if (depth < 0) > @@ -154,9 +181,9 @@ int fdt_subnode_offset(const void *fdt, int parentoffset, > return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name)); > } > > -int fdt_path_offset(const void *fdt, const char *path) > +int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen) > { > - const char *end = path + strlen(path); > + const char *end = path + namelen; > const char *p = path; > int offset = 0; > > @@ -164,7 +191,7 @@ int fdt_path_offset(const void *fdt, const char *path) > > /* see if we have an alias */ > if (*path != '/') { > - const char *q = strchr(path, '/'); > + const char *q = memchr(path, '/', end - p); > > if (!q) > q = end; > @@ -177,14 +204,15 @@ int fdt_path_offset(const void *fdt, const char *path) > p = q; > } > > - while (*p) { > + while (p < end) { > const char *q; > > - while (*p == '/') > + while (*p == '/') { > p++; > - if (! *p) > - return offset; > - q = strchr(p, '/'); > + if (p == end) > + return offset; > + } > + q = memchr(p, '/', end - p); > if (! q) > q = end; > > @@ -198,19 +226,42 @@ int fdt_path_offset(const void *fdt, const char *path) > return offset; > } > > +int fdt_path_offset(const void *fdt, const char *path) > +{ > + return fdt_path_offset_namelen(fdt, path, strlen(path)); > +} > + > const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) > { > - const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset); > + const struct fdt_node_header *nh = fdt_offset_ptr_(fdt, nodeoffset); > + const char *nameptr; > int err; > > if (((err = fdt_check_header(fdt)) != 0) > - || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0)) > + || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0)) > goto fail; > > + nameptr = nh->name; > + > + if (fdt_version(fdt) < 0x10) { > + /* > + * For old FDT versions, match the naming conventions of V16: > + * give only the leaf name (after all /). The actual tree > + * contents are loosely checked. > + */ > + const char *leaf; > + leaf = strrchr(nameptr, '/'); > + if (leaf == NULL) { > + err = -FDT_ERR_BADSTRUCTURE; > + goto fail; > + } > + nameptr = leaf+1; > + } > + > if (len) > - *len = strlen(nh->name); > + *len = strlen(nameptr); > > - return nh->name; > + return nameptr; > > fail: > if (len) > @@ -222,34 +273,34 @@ int fdt_first_property_offset(const void *fdt, int nodeoffset) > { > int offset; > > - if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0) > + if ((offset = fdt_check_node_offset_(fdt, nodeoffset)) < 0) > return offset; > > - return _nextprop(fdt, offset); > + return nextprop_(fdt, offset); > } > > int fdt_next_property_offset(const void *fdt, int offset) > { > - if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0) > + if ((offset = fdt_check_prop_offset_(fdt, offset)) < 0) > return offset; > > - return _nextprop(fdt, offset); > + return nextprop_(fdt, offset); > } > > -const struct fdt_property *fdt_get_property_by_offset(const void *fdt, > - int offset, > - int *lenp) > +static 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 ((err = fdt_check_prop_offset_(fdt, offset)) < 0) { > if (lenp) > *lenp = err; > return NULL; > } > > - prop = _fdt_offset_ptr(fdt, offset); > + prop = fdt_offset_ptr_(fdt, offset); > > if (lenp) > *lenp = fdt32_to_cpu(prop->len); > @@ -257,23 +308,44 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt, > return prop; > } > > -const struct fdt_property *fdt_get_property_namelen(const void *fdt, > - int offset, > - const char *name, > - int namelen, int *lenp) > +const struct fdt_property *fdt_get_property_by_offset(const void *fdt, > + int offset, > + int *lenp) > +{ > + /* Prior to version 16, properties may need realignment > + * and this API does not work. fdt_getprop_*() will, however. */ > + > + if (fdt_version(fdt) < 0x10) { > + if (lenp) > + *lenp = -FDT_ERR_BADVERSION; > + return NULL; > + } > + > + return fdt_get_property_by_offset_(fdt, offset, lenp); > +} > + > +static const struct fdt_property *fdt_get_property_namelen_(const void *fdt, > + int offset, > + const char *name, > + int namelen, > + int *lenp, > + int *poffset) > { > 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))) { > + 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)) > + if (fdt_string_eq_(fdt, fdt32_to_cpu(prop->nameoff), > + name, namelen)) { > + if (poffset) > + *poffset = offset; > return prop; > + } > } > > if (lenp) > @@ -281,6 +353,25 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt, > return NULL; > } > > + > +const struct fdt_property *fdt_get_property_namelen(const void *fdt, > + int offset, > + const char *name, > + int namelen, int *lenp) > +{ > + /* Prior to version 16, properties may need realignment > + * and this API does not work. fdt_getprop_*() will, however. */ > + if (fdt_version(fdt) < 0x10) { > + if (lenp) > + *lenp = -FDT_ERR_BADVERSION; > + return NULL; > + } > + > + return fdt_get_property_namelen_(fdt, offset, name, namelen, lenp, > + NULL); > +} > + > + > const struct fdt_property *fdt_get_property(const void *fdt, > int nodeoffset, > const char *name, int *lenp) > @@ -292,12 +383,18 @@ const struct fdt_property *fdt_get_property(const void *fdt, > const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, > const char *name, int namelen, int *lenp) > { > + int poffset; > const struct fdt_property *prop; > > - prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp); > - if (! prop) > + prop = fdt_get_property_namelen_(fdt, nodeoffset, name, namelen, lenp, > + &poffset); > + if (!prop) > return NULL; > > + /* Handle realignment */ > + if (fdt_version(fdt) < 0x10 && (poffset + sizeof(*prop)) % 8 && > + fdt32_to_cpu(prop->len) >= 8) > + return prop->data + 4; > return prop->data; > } > > @@ -306,11 +403,16 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset, > { > const struct fdt_property *prop; > > - prop = fdt_get_property_by_offset(fdt, offset, lenp); > + prop = fdt_get_property_by_offset_(fdt, offset, lenp); > if (!prop) > return NULL; > if (namep) > *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); > + > + /* Handle realignment */ > + if (fdt_version(fdt) < 0x10 && (offset + sizeof(*prop)) % 8 && > + fdt32_to_cpu(prop->len) >= 8) > + return prop->data + 4; > return prop->data; > } > > @@ -532,6 +634,106 @@ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str) > return 0; > } > > +int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property) > +{ > + const char *list, *end; > + int length, count = 0; > + > + list = fdt_getprop(fdt, nodeoffset, property, &length); > + if (!list) > + return length; > + > + end = list + length; > + > + while (list < end) { > + length = strnlen(list, end - list) + 1; > + > + /* Abort if the last string isn't properly NUL-terminated. */ > + if (list + length > end) > + return -FDT_ERR_BADVALUE; > + > + list += length; > + count++; > + } > + > + return count; > +} > + > +int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property, > + const char *string) > +{ > + int length, len, idx = 0; > + const char *list, *end; > + > + list = fdt_getprop(fdt, nodeoffset, property, &length); > + if (!list) > + return length; > + > + len = strlen(string) + 1; > + end = list + length; > + > + while (list < end) { > + length = strnlen(list, end - list) + 1; > + > + /* Abort if the last string isn't properly NUL-terminated. */ > + if (list + length > end) > + return -FDT_ERR_BADVALUE; > + > + if (length == len && memcmp(list, string, length) == 0) > + return idx; > + > + list += length; > + idx++; > + } > + > + return -FDT_ERR_NOTFOUND; > +} > + > +const char *fdt_stringlist_get(const void *fdt, int nodeoffset, > + const char *property, int idx, > + int *lenp) > +{ > + const char *list, *end; > + int length; > + > + list = fdt_getprop(fdt, nodeoffset, property, &length); > + if (!list) { > + if (lenp) > + *lenp = length; > + > + return NULL; > + } > + > + end = list + length; > + > + while (list < end) { > + length = strnlen(list, end - list) + 1; > + > + /* Abort if the last string isn't properly NUL-terminated. */ > + if (list + length > end) { > + if (lenp) > + *lenp = -FDT_ERR_BADVALUE; > + > + return NULL; > + } > + > + if (idx == 0) { > + if (lenp) > + *lenp = length - 1; > + > + return list; > + } > + > + list += length; > + idx--; > + } > + > + if (lenp) > + *lenp = -FDT_ERR_NOTFOUND; > + > + return NULL; > +} > + > int fdt_node_check_compatible(const void *fdt, int nodeoffset, > const char *compatible) > { > @@ -541,10 +743,8 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset, > prop = fdt_getprop(fdt, nodeoffset, "compatible", &len); > if (!prop) > return len; > - if (fdt_stringlist_contains(prop, len, compatible)) > - return 0; > - else > - return 1; > + > + return !fdt_stringlist_contains(prop, len, compatible); > } > > int fdt_node_offset_by_compatible(const void *fdt, int startoffset, > diff --git a/scripts/dtc/fdt_rw.c b/scripts/dtc/fdt_rw.c > index 70adec6c3..9b829051e 100644 > --- a/scripts/dtc/fdt_rw.c > +++ b/scripts/dtc/fdt_rw.c > @@ -55,8 +55,8 @@ > > #include "libfdt_internal.h" > > -static int _fdt_blocks_misordered(const void *fdt, > - int mem_rsv_size, int struct_size) > +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) < > @@ -67,13 +67,13 @@ static int _fdt_blocks_misordered(const void *fdt, > (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); > } > > -static int _fdt_rw_check_header(void *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), > + if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry), > fdt_size_dt_struct(fdt))) > return -FDT_ERR_BADLAYOUT; > if (fdt_version(fdt) > 17) > @@ -84,35 +84,37 @@ static int _fdt_rw_check_header(void *fdt) > > #define FDT_RW_CHECK_HEADER(fdt) \ > { \ > - int __err; \ > - if ((__err = _fdt_rw_check_header(fdt)) != 0) \ > - return __err; \ > + int err_; \ > + if ((err_ = fdt_rw_check_header_(fdt)) != 0) \ > + return err_; \ > } > > -static inline int _fdt_data_size(void *fdt) > +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) > +static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen) > { > char *p = splicepoint; > - char *end = (char *)fdt + _fdt_data_size(fdt); > + char *end = (char *)fdt + fdt_data_size_(fdt); > > if (((p + oldlen) < p) || ((p + oldlen) > end)) > return -FDT_ERR_BADOFFSET; > + if ((p < (char *)fdt) || ((end - oldlen + newlen) < (char *)fdt)) > + 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, > +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)); > + 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); > @@ -120,13 +122,13 @@ static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p, > return 0; > } > > -static int _fdt_splice_struct(void *fdt, void *p, > +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))) > + if ((err = fdt_splice_(fdt, p, oldlen, newlen))) > return err; > > fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta); > @@ -134,20 +136,20 @@ static int _fdt_splice_struct(void *fdt, void *p, > return 0; > } > > -static int _fdt_splice_string(void *fdt, int newlen) > +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))) > + 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) > +static int fdt_find_add_string_(void *fdt, const char *s) > { > char *strtab = (char *)fdt + fdt_off_dt_strings(fdt); > const char *p; > @@ -155,13 +157,13 @@ static int _fdt_find_add_string(void *fdt, const char *s) > int len = strlen(s) + 1; > int err; > > - p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s); > + 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); > + err = fdt_splice_string_(fdt, len); > if (err) > return err; > > @@ -176,8 +178,8 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) > > 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); > + re = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt)); > + err = fdt_splice_mem_rsv_(fdt, re, 0, 1); > if (err) > return err; > > @@ -188,31 +190,27 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) > > int fdt_del_mem_rsv(void *fdt, int n) > { > - struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n); > - int err; > + struct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n); > > 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; > + return fdt_splice_mem_rsv_(fdt, re, 1, 0); > } > > -static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name, > +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)) > + if (!*prop) > return oldlen; > > - if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), > + if ((err = fdt_splice_struct_(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), > FDT_TAGALIGN(len)))) > return err; > > @@ -220,7 +218,7 @@ static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name, > return 0; > } > > -static int _fdt_add_property(void *fdt, int nodeoffset, const char *name, > +static int fdt_add_property_(void *fdt, int nodeoffset, const char *name, > int len, struct fdt_property **prop) > { > int proplen; > @@ -228,17 +226,17 @@ static int _fdt_add_property(void *fdt, int nodeoffset, const char *name, > int namestroff; > int err; > > - if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0) > + if ((nextoffset = fdt_check_node_offset_(fdt, nodeoffset)) < 0) > return nextoffset; > > - namestroff = _fdt_find_add_string(fdt, name); > + namestroff = fdt_find_add_string_(fdt, name); > if (namestroff < 0) > return namestroff; > > - *prop = _fdt_offset_ptr_w(fdt, nextoffset); > + *prop = fdt_offset_ptr_w_(fdt, nextoffset); > proplen = sizeof(**prop) + FDT_TAGALIGN(len); > > - err = _fdt_splice_struct(fdt, *prop, 0, proplen); > + err = fdt_splice_struct_(fdt, *prop, 0, proplen); > if (err) > return err; > > @@ -262,7 +260,7 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name) > > newlen = strlen(name); > > - err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1), > + err = fdt_splice_struct_(fdt, namep, FDT_TAGALIGN(oldlen+1), > FDT_TAGALIGN(newlen+1)); > if (err) > return err; > @@ -271,21 +269,36 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name) > return 0; > } > > -int fdt_setprop(void *fdt, int nodeoffset, const char *name, > - const void *val, int len) > +int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name, > + int len, void **prop_data) > { > struct fdt_property *prop; > int err; > > FDT_RW_CHECK_HEADER(fdt); > > - err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop); > + err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop); > if (err == -FDT_ERR_NOTFOUND) > - err = _fdt_add_property(fdt, nodeoffset, name, len, &prop); > + err = fdt_add_property_(fdt, nodeoffset, name, len, &prop); > + if (err) > + return err; > + > + *prop_data = prop->data; > + return 0; > +} > + > +int fdt_setprop(void *fdt, int nodeoffset, const char *name, > + const void *val, int len) > +{ > + void *prop_data; > + int err; > + > + err = fdt_setprop_placeholder(fdt, nodeoffset, name, len, &prop_data); > if (err) > return err; > > - memcpy(prop->data, val, len); > + if (len) > + memcpy(prop_data, val, len); > return 0; > } > > @@ -300,7 +313,7 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name, > prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); > if (prop) { > newlen = len + oldlen; > - err = _fdt_splice_struct(fdt, prop->data, > + err = fdt_splice_struct_(fdt, prop->data, > FDT_TAGALIGN(oldlen), > FDT_TAGALIGN(newlen)); > if (err) > @@ -308,7 +321,7 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name, > prop->len = cpu_to_fdt32(newlen); > memcpy(prop->data + oldlen, val, len); > } else { > - err = _fdt_add_property(fdt, nodeoffset, name, len, &prop); > + err = fdt_add_property_(fdt, nodeoffset, name, len, &prop); > if (err) > return err; > memcpy(prop->data, val, len); > @@ -324,11 +337,11 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name) > FDT_RW_CHECK_HEADER(fdt); > > prop = fdt_get_property_w(fdt, nodeoffset, name, &len); > - if (! prop) > + if (!prop) > return len; > > proplen = sizeof(*prop) + FDT_TAGALIGN(len); > - return _fdt_splice_struct(fdt, prop, proplen, 0); > + return fdt_splice_struct_(fdt, prop, proplen, 0); > } > > int fdt_add_subnode_namelen(void *fdt, int parentoffset, > @@ -356,10 +369,10 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, > tag = fdt_next_tag(fdt, offset, &nextoffset); > } while ((tag == FDT_PROP) || (tag == FDT_NOP)); > > - nh = _fdt_offset_ptr_w(fdt, offset); > + nh = fdt_offset_ptr_w_(fdt, offset); > nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE; > > - err = _fdt_splice_struct(fdt, nh, 0, nodelen); > + err = fdt_splice_struct_(fdt, nh, 0, nodelen); > if (err) > return err; > > @@ -383,15 +396,15 @@ int fdt_del_node(void *fdt, int nodeoffset) > > FDT_RW_CHECK_HEADER(fdt); > > - endoffset = _fdt_node_end_offset(fdt, nodeoffset); > + endoffset = fdt_node_end_offset_(fdt, nodeoffset); > if (endoffset < 0) > return endoffset; > > - return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset), > + return fdt_splice_struct_(fdt, fdt_offset_ptr_w_(fdt, nodeoffset), > endoffset - nodeoffset, 0); > } > > -static void _fdt_packblocks(const char *old, char *new, > +static void fdt_packblocks_(const char *old, char *new, > int mem_rsv_size, int struct_size) > { > int mem_rsv_off, struct_off, strings_off; > @@ -437,7 +450,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) > return struct_size; > } > > - if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) { > + if (!fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) { > /* no further work necessary */ > err = fdt_move(fdt, buf, bufsize); > if (err) > @@ -465,7 +478,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) > return -FDT_ERR_NOSPACE; > } > > - _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size); > + fdt_packblocks_(fdt, tmp, mem_rsv_size, struct_size); > memmove(buf, tmp, newsize); > > fdt_set_magic(buf, FDT_MAGIC); > @@ -485,8 +498,8 @@ int fdt_pack(void *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)); > + fdt_packblocks_(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); > + fdt_set_totalsize(fdt, fdt_data_size_(fdt)); > > return 0; > } > diff --git a/scripts/dtc/fdt_strerror.c b/scripts/dtc/fdt_strerror.c > index e6c3ceee8..9677a1887 100644 > --- a/scripts/dtc/fdt_strerror.c > +++ b/scripts/dtc/fdt_strerror.c > @@ -69,6 +69,7 @@ static struct fdt_errtabent fdt_errtable[] = { > > FDT_ERRTABENT(FDT_ERR_BADOFFSET), > FDT_ERRTABENT(FDT_ERR_BADPATH), > + FDT_ERRTABENT(FDT_ERR_BADPHANDLE), > FDT_ERRTABENT(FDT_ERR_BADSTATE), > > FDT_ERRTABENT(FDT_ERR_TRUNCATED), > @@ -76,6 +77,11 @@ static struct fdt_errtabent fdt_errtable[] = { > FDT_ERRTABENT(FDT_ERR_BADVERSION), > FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE), > FDT_ERRTABENT(FDT_ERR_BADLAYOUT), > + FDT_ERRTABENT(FDT_ERR_INTERNAL), > + FDT_ERRTABENT(FDT_ERR_BADNCELLS), > + FDT_ERRTABENT(FDT_ERR_BADVALUE), > + FDT_ERRTABENT(FDT_ERR_BADOVERLAY), > + FDT_ERRTABENT(FDT_ERR_NOPHANDLES), > }; > #define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0])) > > diff --git a/scripts/dtc/fdt_sw.c b/scripts/dtc/fdt_sw.c > index 6a804859f..6d33cc29d 100644 > --- a/scripts/dtc/fdt_sw.c > +++ b/scripts/dtc/fdt_sw.c > @@ -55,7 +55,7 @@ > > #include "libfdt_internal.h" > > -static int _fdt_sw_check_header(void *fdt) > +static int fdt_sw_check_header_(void *fdt) > { > if (fdt_magic(fdt) != FDT_SW_MAGIC) > return -FDT_ERR_BADMAGIC; > @@ -66,11 +66,11 @@ static int _fdt_sw_check_header(void *fdt) > #define FDT_SW_CHECK_HEADER(fdt) \ > { \ > int err; \ > - if ((err = _fdt_sw_check_header(fdt)) != 0) \ > + if ((err = fdt_sw_check_header_(fdt)) != 0) \ > return err; \ > } > > -static void *_fdt_grab_space(void *fdt, size_t len) > +static void *fdt_grab_space_(void *fdt, size_t len) > { > int offset = fdt_size_dt_struct(fdt); > int spaceleft; > @@ -82,7 +82,7 @@ static void *_fdt_grab_space(void *fdt, size_t len) > return NULL; > > fdt_set_size_dt_struct(fdt, offset + len); > - return _fdt_offset_ptr_w(fdt, offset); > + return fdt_offset_ptr_w_(fdt, offset); > } > > int fdt_create(void *buf, int bufsize) > @@ -174,7 +174,7 @@ int fdt_begin_node(void *fdt, const char *name) > > FDT_SW_CHECK_HEADER(fdt); > > - nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen)); > + nh = fdt_grab_space_(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen)); > if (! nh) > return -FDT_ERR_NOSPACE; > > @@ -189,7 +189,7 @@ int fdt_end_node(void *fdt) > > FDT_SW_CHECK_HEADER(fdt); > > - en = _fdt_grab_space(fdt, FDT_TAGSIZE); > + en = fdt_grab_space_(fdt, FDT_TAGSIZE); > if (! en) > return -FDT_ERR_NOSPACE; > > @@ -197,7 +197,7 @@ int fdt_end_node(void *fdt) > return 0; > } > > -static int _fdt_find_add_string(void *fdt, const char *s) > +static int fdt_find_add_string_(void *fdt, const char *s) > { > char *strtab = (char *)fdt + fdt_totalsize(fdt); > const char *p; > @@ -205,7 +205,7 @@ static int _fdt_find_add_string(void *fdt, const char *s) > int len = strlen(s) + 1; > int struct_top, offset; > > - p = _fdt_find_string(strtab - strtabsize, strtabsize, s); > + p = fdt_find_string_(strtab - strtabsize, strtabsize, s); > if (p) > return p - strtab; > > @@ -220,25 +220,37 @@ static int _fdt_find_add_string(void *fdt, const char *s) > return offset; > } > > -int fdt_property(void *fdt, const char *name, const void *val, int len) > +int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp) > { > struct fdt_property *prop; > int nameoff; > > FDT_SW_CHECK_HEADER(fdt); > > - nameoff = _fdt_find_add_string(fdt, name); > + nameoff = fdt_find_add_string_(fdt, name); > if (nameoff == 0) > return -FDT_ERR_NOSPACE; > > - prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len)); > + 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); > + *valp = prop->data; > + return 0; > +} > + > +int fdt_property(void *fdt, const char *name, const void *val, int len) > +{ > + void *ptr; > + int ret; > + > + ret = fdt_property_placeholder(fdt, name, len, &ptr); > + if (ret) > + return ret; > + memcpy(ptr, val, len); > return 0; > } > > @@ -253,7 +265,7 @@ int fdt_finish(void *fdt) > FDT_SW_CHECK_HEADER(fdt); > > /* Add terminator */ > - end = _fdt_grab_space(fdt, sizeof(*end)); > + end = fdt_grab_space_(fdt, sizeof(*end)); > if (! end) > return -FDT_ERR_NOSPACE; > *end = cpu_to_fdt32(FDT_END); > @@ -269,7 +281,7 @@ int fdt_finish(void *fdt) > while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) { > if (tag == FDT_PROP) { > struct fdt_property *prop = > - _fdt_offset_ptr_w(fdt, offset); > + fdt_offset_ptr_w_(fdt, offset); > int nameoff; > > nameoff = fdt32_to_cpu(prop->nameoff); > diff --git a/scripts/dtc/fdt_wip.c b/scripts/dtc/fdt_wip.c > index c5bbb68d3..534c1cbbb 100644 > --- a/scripts/dtc/fdt_wip.c > +++ b/scripts/dtc/fdt_wip.c > @@ -55,24 +55,45 @@ > > #include "libfdt_internal.h" > > +int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset, > + const char *name, int namelen, > + uint32_t idx, const void *val, > + int len) > +{ > + void *propval; > + int proplen; > + > + propval = fdt_getprop_namelen_w(fdt, nodeoffset, name, namelen, > + &proplen); > + if (!propval) > + return proplen; > + > + if (proplen < (len + idx)) > + return -FDT_ERR_NOSPACE; > + > + memcpy((char *)propval + idx, val, len); > + return 0; > +} > + > int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, > const void *val, int len) > { > - void *propval; > + const void *propval; > int proplen; > > - propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen); > - if (! propval) > + propval = fdt_getprop(fdt, nodeoffset, name, &proplen); > + if (!propval) > return proplen; > > if (proplen != len) > return -FDT_ERR_NOSPACE; > > - memcpy(propval, val, len); > - return 0; > + return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name, > + strlen(name), 0, > + val, len); > } > > -static void _fdt_nop_region(void *start, int len) > +static void fdt_nop_region_(void *start, int len) > { > fdt32_t *p; > > @@ -86,15 +107,15 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name) > int len; > > prop = fdt_get_property_w(fdt, nodeoffset, name, &len); > - if (! prop) > + if (!prop) > return len; > > - _fdt_nop_region(prop, len + sizeof(*prop)); > + fdt_nop_region_(prop, len + sizeof(*prop)); > > return 0; > } > > -int _fdt_node_end_offset(void *fdt, int offset) > +int fdt_node_end_offset_(void *fdt, int offset) > { > int depth = 0; > > @@ -108,11 +129,11 @@ int fdt_nop_node(void *fdt, int nodeoffset) > { > int endoffset; > > - endoffset = _fdt_node_end_offset(fdt, nodeoffset); > + endoffset = fdt_node_end_offset_(fdt, nodeoffset); > if (endoffset < 0) > return endoffset; > > - _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0), > + fdt_nop_region_(fdt_offset_ptr_w(fdt, nodeoffset, 0), > endoffset - nodeoffset); > return 0; > } > diff --git a/scripts/dtc/fdtdump.c b/scripts/dtc/fdtdump.c > index 95a6a2016..7d460a50b 100644 > --- a/scripts/dtc/fdtdump.c > +++ b/scripts/dtc/fdtdump.c > @@ -1,17 +1,16 @@ > +// SPDX-License-Identifier: GPL-2.0 > /* > * fdtdump.c - Contributed by Pantelis Antoniou <pantelis.antoniou AT gmail.com> > */ > > -#include <stdbool.h> > #include <stdint.h> > #include <stdio.h> > #include <stdlib.h> > #include <string.h> > #include <ctype.h> > > -#include <libfdt.h> > -#include <libfdt_env.h> > #include <fdt.h> > +#include <libfdt_env.h> > > #include "util.h" > > @@ -19,29 +18,33 @@ > #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 void print_data(const char *data, int len) > { > - 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_???"; > + int i; > + const char *p = data; > + > + /* no data, don't print */ > + if (len == 0) > + return; > + > + if (util_is_printable_string(data, len)) { > + printf(" = \"%s\"", (const char *)data); > + } else if ((len % 4) == 0) { > + printf(" = <"); > + for (i = 0; i < len; i += 4) > + printf("0x%08x%s", fdt32_to_cpu(GET_CELL(p)), > + i < (len - 4) ? " " : ""); > + printf(">"); > + } else { > + printf(" = ["); > + for (i = 0; i < len; i++) > + printf("%02x%s", *p++, i < len - 1 ? " " : ""); > + printf("]"); > + } > } > > -#define dumpf(fmt, args...) \ > - do { if (debug) printf("// " fmt, ## args); } while (0) > - > -static void dump_blob(void *blob, bool debug) > +static void dump_blob(void *blob) > { > - 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); > @@ -88,15 +91,14 @@ static void dump_blob(void *blob, bool debug) > if (addr == 0 && size == 0) > break; > > - printf("/memreserve/ %#llx %#llx;\n", > + 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)); > + /* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */ > > if (tag == FDT_BEGIN_NODE) { > s = p; > @@ -135,93 +137,27 @@ static void dump_blob(void *blob, bool debug) > > 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); > + print_data(t, sz); > printf(";\n"); > } > } > > -/* Usage related data. */ > -static const char usage_synopsis[] = "fdtdump [options] <file>"; > -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; > + if (argc < 2) { > + fprintf(stderr, "supply input filename\n"); > + return 5; > } > > - dump_blob(buf, debug); > + buf = utilfdt_read(argv[1]); > + if (buf) > + dump_blob(buf); > + else > + return 10; > > return 0; > } > diff --git a/scripts/dtc/fdtget.c b/scripts/dtc/fdtget.c > index 437741922..c2fbab2a5 100644 > --- a/scripts/dtc/fdtget.c > +++ b/scripts/dtc/fdtget.c > @@ -277,33 +277,33 @@ static int do_fdtget(struct display_info *disp, const char *filename, > return 0; > } > > -/* Usage related data. */ > -static const char usage_synopsis[] = > - "read values from device tree\n" > +static const char *usage_msg = > + "fdtget - read values from device tree\n" > + "\n" > + "Each value is printed on a new line.\n\n" > + "Usage:\n" > " fdtget <options> <dt file> [<node> <property>]...\n" > " fdtget -p <options> <dt file> [<node> ]...\n" > - "\n" > - "Each value is printed on a new line.\n" > + "Options:\n" > + "\t-t <type>\tType of data\n" > + "\t-p\t\tList properties for each node\n" > + "\t-l\t\tList subnodes for each node\n" > + "\t-d\t\tDefault value to display when the property is " > + "missing\n" > + "\t-h\t\tPrint this help\n\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 > -}; > + > +static void usage(const char *msg) > +{ > + if (msg) > + fprintf(stderr, "Error: %s\n\n", msg); > + > + fprintf(stderr, "%s", usage_msg); > + exit(2); > +} > > int main(int argc, char *argv[]) > { > - int opt; > char *filename = NULL; > struct display_info disp; > int args_per_step = 2; > @@ -312,14 +312,20 @@ int main(int argc, char *argv[]) > 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 > + for (;;) { > + int c = getopt(argc, argv, "d:hlpt:"); > + if (c == -1) > + break; > + > + switch (c) { > + case 'h': > + case '?': > + usage(NULL); > > case 't': > if (utilfdt_decode_type(optarg, &disp.type, > &disp.size)) > - usage("invalid type string"); > + usage("Invalid type string"); > break; > > case 'p': > @@ -341,7 +347,7 @@ int main(int argc, char *argv[]) > if (optind < argc) > filename = argv[optind++]; > if (!filename) > - usage("missing filename"); > + usage("Missing filename"); > > argv += optind; > argc -= optind; > @@ -352,7 +358,7 @@ int main(int argc, char *argv[]) > > /* Check for node, property arguments */ > if (args_per_step == 2 && (argc % 2)) > - usage("must have an even number of arguments"); > + usage("Must have an even number of arguments"); > > if (do_fdtget(&disp, filename, argv, argc, args_per_step)) > return 1; > diff --git a/scripts/dtc/fdtput.c b/scripts/dtc/fdtput.c > index 2a8d67447..f2197f519 100644 > --- a/scripts/dtc/fdtput.c > +++ b/scripts/dtc/fdtput.c > @@ -96,7 +96,12 @@ static int encode_value(struct display_info *disp, char **arg, int arg_count, > /* enlarge our value buffer by a suitable margin if needed */ > if (upto + len > value_size) { > value_size = (upto + len) + 500; > - value = xrealloc(value, value_size); > + value = realloc(value, value_size); > + if (!value) { > + fprintf(stderr, "Out of mmory: cannot alloc " > + "%d bytes\n", value_size); > + return -1; > + } > } > > ptr = value + upto; > @@ -126,59 +131,19 @@ static int encode_value(struct display_info *disp, char **arg, int arg_count, > 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, > +static int store_key_value(void *blob, const char *node_name, > const char *property, const char *buf, int len) > { > int node; > int err; > > - node = fdt_path_offset(*blob, node_name); > + 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); > - } > + err = fdt_setprop(blob, node, property, buf, len); > if (err) { > report_error(property, -1, err); > return -1; > @@ -196,7 +161,7 @@ static int store_key_value(char **blob, const char *node_name, > * @param in_path Path to process > * @return 0 if ok, -1 on error > */ > -static int create_paths(char **blob, const char *in_path) > +static int create_paths(void *blob, const char *in_path) > { > const char *path = in_path; > const char *sep; > @@ -212,11 +177,10 @@ static int create_paths(char **blob, const char *in_path) > if (!sep) > sep = path + strlen(path); > > - node = fdt_subnode_offset_namelen(*blob, offset, 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, > + node = fdt_add_subnode_namelen(blob, offset, path, > sep - path); > } > if (node < 0) { > @@ -239,7 +203,7 @@ static int create_paths(char **blob, const char *in_path) > * @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) > +static int create_node(void *blob, const char *node_name) > { > int node = 0; > char *p; > @@ -251,17 +215,15 @@ static int create_node(char **blob, const char *node_name) > } > *p = '\0'; > > - *blob = realloc_node(*blob, p + 1); > - > if (p > node_name) { > - node = fdt_path_offset(*blob, 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); > + node = fdt_add_subnode(blob, node, p + 1); > if (node < 0) { > report_error(p + 1, -1, node); > return -1; > @@ -288,64 +250,66 @@ static int do_fdtput(struct display_info *disp, const char *filename, > * store them into the property. > */ > assert(arg_count >= 2); > - if (disp->auto_path && create_paths(&blob, *arg)) > + 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)) > + 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); > + ret = create_paths(blob, *arg); > else > - ret = create_node(&blob, *arg); > + ret = create_node(blob, *arg); > } > break; > } > - if (ret >= 0) { > - fdt_pack(blob); > + if (ret >= 0) > 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 <options> <dt file> <node> <property> [<value>...]\n" > - " fdtput -c <options> <dt file> [<node>...]\n" > +static const char *usage_msg = > + "fdtput - write a property value to a device tree\n" > "\n" > "The command line arguments are joined together into a single value.\n" > + "\n" > + "Usage:\n" > + " fdtput <options> <dt file> <node> <property> [<value>...]\n" > + " fdtput -c <options> <dt file> [<node>...]\n" > + "Options:\n" > + "\t-c\t\tCreate nodes if they don't already exist\n" > + "\t-p\t\tAutomatically create nodes as needed for the node path\n" > + "\t-t <type>\tType of data\n" > + "\t-v\t\tVerbose: display each value decoded from command line\n" > + "\t-h\t\tPrint this help\n\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 > -}; > + > +static void usage(const char *msg) > +{ > + if (msg) > + fprintf(stderr, "Error: %s\n\n", msg); > + > + fprintf(stderr, "%s", usage_msg); > + exit(2); > +} > > 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) { > + for (;;) { > + int c = getopt(argc, argv, "chpt:v"); > + if (c == -1) > + break; > + > /* > * TODO: add options to: > * - delete property > @@ -353,13 +317,15 @@ int main(int argc, char *argv[]) > * - rename node > * - pack fdt before writing > * - set amount of free space when writing > + * - expand fdt if value doesn't fit > */ > - switch (opt) { > - case_USAGE_COMMON_FLAGS > - > + switch (c) { > case 'c': > disp.oper = OPER_CREATE_NODE; > break; > + case 'h': > + case '?': > + usage(NULL); > case 'p': > disp.auto_path = 1; > break; > @@ -378,16 +344,16 @@ int main(int argc, char *argv[]) > if (optind < argc) > filename = argv[optind++]; > if (!filename) > - usage("missing filename"); > + usage("Missing filename"); > > argv += optind; > argc -= optind; > > if (disp.oper == OPER_WRITE_PROP) { > if (argc < 1) > - usage("missing node"); > + usage("Missing node"); > if (argc < 2) > - usage("missing property"); > + usage("Missing property"); > } > > if (do_fdtput(&disp, filename, argv, argc)) > diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c > index bd99fa2d3..8d268fb78 100644 > --- a/scripts/dtc/flattree.c > +++ b/scripts/dtc/flattree.c > @@ -49,7 +49,7 @@ static struct version_info { > > struct emitter { > void (*cell)(void *, cell_t); > - void (*string)(void *, char *, int); > + void (*string)(void *, const char *, int); > void (*align)(void *, int); > void (*data)(void *, struct data); > void (*beginnode)(void *, struct label *labels); > @@ -64,7 +64,7 @@ static void bin_emit_cell(void *e, cell_t val) > *dtbuf = data_append_cell(*dtbuf, val); > } > > -static void bin_emit_string(void *e, char *str, int len) > +static void bin_emit_string(void *e, const char *str, int len) > { > struct data *dtbuf = e; > > @@ -144,22 +144,14 @@ static void asm_emit_cell(void *e, cell_t val) > (val >> 8) & 0xff, val & 0xff); > } > > -static void asm_emit_string(void *e, char *str, int len) > +static void asm_emit_string(void *e, const 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; > - } > + if (len != 0) > + fprintf(f, "\t.string\t\"%.*s\"\n", len, str); > + else > + fprintf(f, "\t.string\t\"%s\"\n", str); > } > > static void asm_emit_align(void *e, int a) > @@ -179,7 +171,7 @@ static void asm_emit_data(void *e, struct data d) > 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)))); > + asm_emit_cell(e, fdt32_to_cpu(*((fdt32_t *)(d.val+off)))); > off += sizeof(uint32_t); > } > > @@ -318,17 +310,16 @@ static struct data flatten_reserve_list(struct reserve_info *reservelist, > { > 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); > + d = data_append_re(d, re->address, re->size); > } > /* > * Add additional reserved slots if the user asked for them. > */ > for (j = 0; j < reservenum; j++) { > - d = data_append_re(d, &null_re); > + d = data_append_re(d, 0, 0); > } > > return d; > @@ -366,7 +357,7 @@ static void make_fdt_header(struct fdt_header *fdt, > fdt->size_dt_struct = cpu_to_fdt32(dtsize); > } > > -void dt_to_blob(FILE *f, struct boot_info *bi, int version) > +void dt_to_blob(FILE *f, struct dt_info *dti, int version) > { > struct version_info *vi = NULL; > int i; > @@ -384,29 +375,36 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version) > if (!vi) > die("Unknown device tree blob version %d\n", version); > > - flatten_tree(bi->dt, &bin_emitter, &dtbuf, &strbuf, vi); > + flatten_tree(dti->dt, &bin_emitter, &dtbuf, &strbuf, vi); > bin_emit_cell(&dtbuf, FDT_END); > > - reservebuf = flatten_reserve_list(bi->reservelist, vi); > + reservebuf = flatten_reserve_list(dti->reservelist, vi); > > /* Make header */ > make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len, > - bi->boot_cpuid_phys); > + dti->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 (padlen < 0) { > + padlen = 0; > + if (quiet < 1) > + fprintf(stderr, > + "Warning: blob size %d >= minimum size %d\n", > + fdt32_to_cpu(fdt.totalsize), minsize); > + } > } > > if (padsize > 0) > padlen = padsize; > > + if (alignsize > 0) > + padlen = ALIGN(fdt32_to_cpu(fdt.totalsize) + padlen, alignsize) > + - fdt32_to_cpu(fdt.totalsize); > + > if (padlen > 0) { > int tsize = fdt32_to_cpu(fdt.totalsize); > tsize += padlen; > @@ -460,7 +458,7 @@ static void dump_stringtable_asm(FILE *f, struct data strbuf) > } > } > > -void dt_to_asm(FILE *f, struct boot_info *bi, int version) > +void dt_to_asm(FILE *f, struct dt_info *dti, int version) > { > struct version_info *vi = NULL; > int i; > @@ -500,7 +498,7 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) > > if (vi->flags & FTF_BOOTCPUID) { > fprintf(f, "\t/* boot_cpuid_phys */\n"); > - asm_emit_cell(f, bi->boot_cpuid_phys); > + asm_emit_cell(f, dti->boot_cpuid_phys); > } > > if (vi->flags & FTF_STRTABSIZE) { > @@ -530,18 +528,18 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) > * 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) { > + for (re = dti->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->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)); > + (unsigned int)(re->address & 0xffffffff)); > + ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->size >> 32)); > + ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->size & 0xffffffff)); > } > for (i = 0; i < reservenum; i++) { > fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n"); > @@ -550,7 +548,7 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) > 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); > + flatten_tree(dti->dt, &asm_emitter, f, &strbuf, vi); > > fprintf(f, "\t/* FDT_END */\n"); > asm_emit_cell(f, FDT_END); > @@ -572,6 +570,8 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version) > if (padsize > 0) { > fprintf(f, "\t.space\t%d, 0\n", padsize); > } > + if (alignsize > 0) > + asm_emit_align(f, alignsize); > emit_label(f, symprefix, "blob_abs_end"); > > data_free(strbuf); > @@ -600,7 +600,7 @@ static void flat_read_chunk(struct inbuf *inb, void *p, int len) > > static uint32_t flat_read_word(struct inbuf *inb) > { > - uint32_t val; > + fdt32_t val; > > assert(((inb->ptr - inb->base) % sizeof(val)) == 0); > > @@ -709,13 +709,15 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) > * First pass, count entries. > */ > while (1) { > + uint64_t address, size; > + > 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) > + address = fdt64_to_cpu(re.address); > + size = fdt64_to_cpu(re.size); > + if (size == 0) > break; > > - new = build_reserve_entry(re.address, re.size); > + new = build_reserve_entry(address, size); > reservelist = add_reserve_entry(reservelist, new); > } > > @@ -729,7 +731,7 @@ static char *nodename_from_path(const char *ppath, const char *cpath) > > plen = strlen(ppath); > > - if (!strneq(ppath, cpath, plen)) > + if (!strstarts(cpath, ppath)) > die("Path \"%s\" is not valid as a child of \"%s\"\n", > cpath, ppath); > > @@ -797,13 +799,18 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, > } > } while (val != FDT_END_NODE); > > + if (node->name != flatname) { > + free(flatname); > + } > + > return node; > } > > > -struct boot_info *dt_from_blob(const char *fname) > +struct dt_info *dt_from_blob(const char *fname) > { > FILE *f; > + fdt32_t magic_buf, totalsize_buf; > uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys; > uint32_t off_dt, off_str, off_mem_rsvmap; > int rc; > @@ -820,7 +827,7 @@ struct boot_info *dt_from_blob(const char *fname) > > f = srcfile_relative_open(fname, NULL); > > - rc = fread(&magic, sizeof(magic), 1, f); > + rc = fread(&magic_buf, sizeof(magic_buf), 1, f); > if (ferror(f)) > die("Error reading DT blob magic number: %s\n", > strerror(errno)); > @@ -831,11 +838,11 @@ struct boot_info *dt_from_blob(const char *fname) > die("Mysterious short read reading magic number\n"); > } > > - magic = fdt32_to_cpu(magic); > + magic = fdt32_to_cpu(magic_buf); > if (magic != FDT_MAGIC) > die("Blob has incorrect magic number\n"); > > - rc = fread(&totalsize, sizeof(totalsize), 1, f); > + rc = fread(&totalsize_buf, sizeof(totalsize_buf), 1, f); > if (ferror(f)) > die("Error reading DT blob size: %s\n", strerror(errno)); > if (rc < 1) { > @@ -845,7 +852,7 @@ struct boot_info *dt_from_blob(const char *fname) > die("Mysterious short read reading blob size\n"); > } > > - totalsize = fdt32_to_cpu(totalsize); > + totalsize = fdt32_to_cpu(totalsize_buf); > if (totalsize < FDT_V1_SIZE) > die("DT blob size (%d) is too small\n", totalsize); > > @@ -889,7 +896,7 @@ struct boot_info *dt_from_blob(const char *fname) > > if (version >= 3) { > uint32_t size_str = fdt32_to_cpu(fdt->size_dt_strings); > - if (off_str+size_str > totalsize) > + if ((off_str+size_str < off_str) || (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 { > @@ -898,7 +905,7 @@ struct boot_info *dt_from_blob(const char *fname) > > if (version >= 17) { > size_dt = fdt32_to_cpu(fdt->size_dt_struct); > - if (off_dt+size_dt > totalsize) > + if ((off_dt+size_dt < off_dt) || (off_dt+size_dt > totalsize)) > die("Structure block extends past total size\n"); > } > > @@ -929,5 +936,5 @@ struct boot_info *dt_from_blob(const char *fname) > > fclose(f); > > - return build_boot_info(reservelist, tree, boot_cpuid_phys); > + return build_dt_info(DTSF_V1, reservelist, tree, boot_cpuid_phys); > } > diff --git a/scripts/dtc/fstree.c b/scripts/dtc/fstree.c > index 6d1beec95..ae7d06c3c 100644 > --- a/scripts/dtc/fstree.c > +++ b/scripts/dtc/fstree.c > @@ -79,13 +79,12 @@ static struct node *read_fstree(const char *dirname) > return tree; > } > > -struct boot_info *dt_from_fs(const char *dirname) > +struct dt_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)); > + return build_dt_info(DTSF_V1, NULL, tree, guess_boot_cpuid(tree)); > } > - > diff --git a/scripts/dtc/libfdt.h b/scripts/dtc/libfdt.h > index 32d52276d..1e27780e1 100644 > --- a/scripts/dtc/libfdt.h > +++ b/scripts/dtc/libfdt.h > @@ -1,5 +1,5 @@ > -#ifndef _LIBFDT_H > -#define _LIBFDT_H > +#ifndef LIBFDT_H > +#define LIBFDT_H > /* > * libfdt - Flat Device Tree manipulation > * Copyright (C) 2006 David Gibson, IBM Corporation. > @@ -51,17 +51,17 @@ > * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > */ > > -#include <libfdt_env.h> > -#include <fdt.h> > +#include "libfdt_env.h" > +#include "fdt.h" > > -#define FDT_FIRST_SUPPORTED_VERSION 0x10 > +#define FDT_FIRST_SUPPORTED_VERSION 0x02 > #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 > + /* FDT_ERR_EXISTS: Attempted to create a node or property which > * already exists */ > #define FDT_ERR_NOSPACE 3 > /* FDT_ERR_NOSPACE: Operation needed to expand the device > @@ -79,8 +79,10 @@ > * (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. */ > + /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle. > + * This can be caused either by an invalid phandle property > + * length, or the phandle value was either 0 or -1, which 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 > @@ -121,13 +123,29 @@ > /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells > * or similar property with a bad format or value */ > > -#define FDT_ERR_MAX 14 > +#define FDT_ERR_BADVALUE 15 > + /* FDT_ERR_BADVALUE: Device tree has a property with an unexpected > + * value. For example: a property expected to contain a string list > + * is not NUL-terminated within the length of its value. */ > + > +#define FDT_ERR_BADOVERLAY 16 > + /* FDT_ERR_BADOVERLAY: The device tree overlay, while > + * correctly structured, cannot be applied due to some > + * unexpected or missing value, property or node. */ > + > +#define FDT_ERR_NOPHANDLES 17 > + /* FDT_ERR_NOPHANDLES: The device tree doesn't have any > + * phandle available anymore without causing an overflow */ > + > +#define FDT_ERR_MAX 17 > > /**********************************************************************/ > /* Low-level functions (you probably don't need these) */ > /**********************************************************************/ > > +#ifndef SWIG /* This function is not useful in Python */ > const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen); > +#endif > static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) > { > return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen); > @@ -163,40 +181,67 @@ int fdt_first_subnode(const void *fdt, int offset); > */ > int fdt_next_subnode(const void *fdt, int offset); > > +/** > + * fdt_for_each_subnode - iterate over all subnodes of a parent > + * > + * @node: child node (int, lvalue) > + * @fdt: FDT blob (const void *) > + * @parent: parent node (int) > + * > + * This is actually a wrapper around a for loop and would be used like so: > + * > + * fdt_for_each_subnode(node, fdt, parent) { > + * Use node > + * ... > + * } > + * > + * if ((node < 0) && (node != -FDT_ERR_NOT_FOUND)) { > + * Error handling > + * } > + * > + * Note that this is implemented as a macro and @node is used as > + * iterator in the loop. The parent variable be constant or even a > + * literal. > + * > + */ > +#define fdt_for_each_subnode(node, fdt, parent) \ > + for (node = fdt_first_subnode(fdt, parent); \ > + node >= 0; \ > + node = fdt_next_subnode(fdt, node)) > + > /**********************************************************************/ > /* 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_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_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) \ > +#define fdt_set_hdr_(name) \ > static inline void fdt_set_##name(void *fdt, uint32_t val) \ > { \ > - struct fdt_header *fdth = (struct fdt_header*)fdt; \ > + 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_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 > @@ -253,6 +298,21 @@ int fdt_move(const void *fdt, void *buf, int bufsize); > */ > const char *fdt_string(const void *fdt, int stroffset); > > +/** > + * fdt_get_max_phandle - retrieves the highest phandle in a tree > + * @fdt: pointer to the device tree blob > + * > + * fdt_get_max_phandle retrieves the highest phandle in the given > + * device tree. This will ignore badly formatted phandles, or phandles > + * with a value of 0 or -1. > + * > + * returns: > + * the highest phandle on success > + * 0, if no phandle was found in the device tree > + * -1, if an error occurred > + */ > +uint32_t fdt_get_max_phandle(const void *fdt); > + > /** > * fdt_num_mem_rsv - retrieve the number of memory reserve map entries > * @fdt: pointer to the device tree blob > @@ -295,8 +355,10 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size); > * useful for finding subnodes based on a portion of a larger string, > * such as a full path. > */ > +#ifndef SWIG /* Not available in Python */ > int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, > const char *name, int namelen); > +#endif > /** > * fdt_subnode_offset - find a subnode of a given node > * @fdt: pointer to the device tree blob > @@ -313,8 +375,9 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, > * 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_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE > + * tag > + * -FDT_ERR_BADMAGIC, > * -FDT_ERR_BADVERSION, > * -FDT_ERR_BADSTATE, > * -FDT_ERR_BADSTRUCTURE, > @@ -322,6 +385,19 @@ int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, > */ > int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name); > > +/** > + * fdt_path_offset_namelen - find a tree node by its full path > + * @fdt: pointer to the device tree blob > + * @path: full path of the node to locate > + * @namelen: number of characters of path to consider > + * > + * Identical to fdt_path_offset(), but only consider the first namelen > + * characters of path as the path name. > + */ > +#ifndef SWIG /* Not available in Python */ > +int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen); > +#endif > + > /** > * fdt_path_offset - find a tree node by its full path > * @fdt: pointer to the device tree blob > @@ -335,7 +411,8 @@ int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name); > * address). > * > * returns: > - * structure block offset of the node with the requested path (>=0), on success > + * 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, > @@ -359,10 +436,12 @@ int fdt_path_offset(const void *fdt, const char *path); > * > * returns: > * pointer to the node's name, on success > - * If lenp is non-NULL, *lenp contains the length of that name (>=0) > + * 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_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE > + * tag > * -FDT_ERR_BADMAGIC, > * -FDT_ERR_BADVERSION, > * -FDT_ERR_BADSTATE, standard meanings > @@ -410,6 +489,33 @@ int fdt_first_property_offset(const void *fdt, int nodeoffset); > */ > int fdt_next_property_offset(const void *fdt, int offset); > > +/** > + * fdt_for_each_property_offset - iterate over all properties of a node > + * > + * @property_offset: property offset (int, lvalue) > + * @fdt: FDT blob (const void *) > + * @node: node offset (int) > + * > + * This is actually a wrapper around a for loop and would be used like so: > + * > + * fdt_for_each_property_offset(property, fdt, node) { > + * Use property > + * ... > + * } > + * > + * if ((property < 0) && (property != -FDT_ERR_NOT_FOUND)) { > + * Error handling > + * } > + * > + * Note that this is implemented as a macro and property is used as > + * iterator in the loop. The node variable can be constant or even a > + * literal. > + */ > +#define fdt_for_each_property_offset(property, fdt, node) \ > + for (property = fdt_first_property_offset(fdt, node); \ > + property >= 0; \ > + property = fdt_next_property_offset(fdt, property)) > + > /** > * fdt_get_property_by_offset - retrieve the property at a given offset > * @fdt: pointer to the device tree blob > @@ -421,6 +527,9 @@ int fdt_next_property_offset(const void *fdt, int offset); > * offset. If lenp is non-NULL, the length of the property value is > * also returned, in the integer pointed to by lenp. > * > + * Note that this code only works on device tree versions >= 16. fdt_getprop() > + * works on all versions. > + * > * returns: > * pointer to the structure representing the property > * if lenp is non-NULL, *lenp contains the length of the property > @@ -446,13 +555,15 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt, > * @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. > + * Identical to fdt_get_property(), but only examine the first namelen > + * characters of name for matching the property name. > */ > +#ifndef SWIG /* Not available in Python */ > const struct fdt_property *fdt_get_property_namelen(const void *fdt, > int nodeoffset, > const char *name, > int namelen, int *lenp); > +#endif > > /** > * fdt_get_property - find a given property in a given node > @@ -474,7 +585,8 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt, > * 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_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE > + * tag > * -FDT_ERR_BADMAGIC, > * -FDT_ERR_BADVERSION, > * -FDT_ERR_BADSTATE, > @@ -522,8 +634,10 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, > * -FDT_ERR_BADSTRUCTURE, > * -FDT_ERR_TRUNCATED, standard meanings > */ > +#ifndef SWIG /* This function is not useful in Python */ > const void *fdt_getprop_by_offset(const void *fdt, int offset, > const char **namep, int *lenp); > +#endif > > /** > * fdt_getprop_namelen - get property value based on substring > @@ -536,8 +650,17 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset, > * Identical to fdt_getprop(), but only examine the first namelen > * characters of name for matching the property name. > */ > +#ifndef SWIG /* Not available in Python */ > const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, > const char *name, int namelen, int *lenp); > +static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset, > + const char *name, int namelen, > + int *lenp) > +{ > + return (void *)(uintptr_t)fdt_getprop_namelen(fdt, nodeoffset, name, > + namelen, lenp); > +} > +#endif > > /** > * fdt_getprop - retrieve the value of a given property > @@ -559,7 +682,8 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, > * 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_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE > + * tag > * -FDT_ERR_BADMAGIC, > * -FDT_ERR_BADVERSION, > * -FDT_ERR_BADSTATE, > @@ -597,11 +721,13 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); > * Identical to fdt_get_alias(), but only examine the first namelen > * characters of name for matching the alias name. > */ > +#ifndef SWIG /* Not available in Python */ > const char *fdt_get_alias_namelen(const void *fdt, > const char *name, int namelen); > +#endif > > /** > - * fdt_get_alias - retreive the path referenced by a given alias > + * fdt_get_alias - retrieve the path referenced by a given alias > * @fdt: pointer to the device tree blob > * @name: name of the alias th look up > * > @@ -631,7 +757,7 @@ const char *fdt_get_alias(const void *fdt, const char *name); > * 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_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, > @@ -661,11 +787,11 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen); > * 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_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, > @@ -687,7 +813,7 @@ int fdt_supernode_atdepth_offset(const void *fdt, int 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_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag > * -FDT_ERR_BADMAGIC, > * -FDT_ERR_BADVERSION, > * -FDT_ERR_BADSTATE, > @@ -710,7 +836,7 @@ int fdt_node_depth(const void *fdt, int nodeoffset); > * 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_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag > * -FDT_ERR_BADMAGIC, > * -FDT_ERR_BADVERSION, > * -FDT_ERR_BADSTATE, > @@ -750,7 +876,7 @@ int fdt_parent_offset(const void *fdt, int nodeoffset); > * 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_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag > * -FDT_ERR_BADMAGIC, > * -FDT_ERR_BADVERSION, > * -FDT_ERR_BADSTATE, > @@ -797,7 +923,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle); > * 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_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag > * -FDT_ERR_BADMAGIC, > * -FDT_ERR_BADVERSION, > * -FDT_ERR_BADSTATE, > @@ -834,7 +960,7 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset, > * 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_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag > * -FDT_ERR_BADMAGIC, > * -FDT_ERR_BADVERSION, > * -FDT_ERR_BADSTATE, > @@ -857,6 +983,68 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset, > */ > int fdt_stringlist_contains(const char *strlist, int listlen, const char *str); > > +/** > + * fdt_stringlist_count - count the number of strings in a string list > + * @fdt: pointer to the device tree blob > + * @nodeoffset: offset of a tree node > + * @property: name of the property containing the string list > + * @return: > + * the number of strings in the given property > + * -FDT_ERR_BADVALUE if the property value is not NUL-terminated > + * -FDT_ERR_NOTFOUND if the property does not exist > + */ > +int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property); > + > +/** > + * fdt_stringlist_search - find a string in a string list and return its index > + * @fdt: pointer to the device tree blob > + * @nodeoffset: offset of a tree node > + * @property: name of the property containing the string list > + * @string: string to look up in the string list > + * > + * Note that it is possible for this function to succeed on property values > + * that are not NUL-terminated. That's because the function will stop after > + * finding the first occurrence of @string. This can for example happen with > + * small-valued cell properties, such as #address-cells, when searching for > + * the empty string. > + * > + * @return: > + * the index of the string in the list of strings > + * -FDT_ERR_BADVALUE if the property value is not NUL-terminated > + * -FDT_ERR_NOTFOUND if the property does not exist or does not contain > + * the given string > + */ > +int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property, > + const char *string); > + > +/** > + * fdt_stringlist_get() - obtain the string at a given index in a string list > + * @fdt: pointer to the device tree blob > + * @nodeoffset: offset of a tree node > + * @property: name of the property containing the string list > + * @index: index of the string to return > + * @lenp: return location for the string length or an error code on failure > + * > + * Note that this will successfully extract strings from properties with > + * non-NUL-terminated values. For example on small-valued cell properties > + * this function will return the empty string. > + * > + * If non-NULL, the length of the string (on success) or a negative error-code > + * (on failure) will be stored in the integer pointer to by lenp. > + * > + * @return: > + * A pointer to the string at the given index in the string list or NULL on > + * failure. On success the length of the string will be stored in the memory > + * location pointed to by the lenp parameter, if non-NULL. On failure one of > + * the following negative error codes will be returned in the lenp parameter > + * (if non-NULL): > + * -FDT_ERR_BADVALUE if the property value is not NUL-terminated > + * -FDT_ERR_NOTFOUND if the property does not exist > + */ > +const char *fdt_stringlist_get(const void *fdt, int nodeoffset, > + const char *property, int index, > + int *lenp); > + > /**********************************************************************/ > /* Read-only functions (addressing related) */ > /**********************************************************************/ > @@ -882,7 +1070,8 @@ int fdt_stringlist_contains(const char *strlist, int listlen, const char *str); > * returns: > * 0 <= n < FDT_MAX_NCELLS, on success > * 2, if the node has no #address-cells property > - * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid #address-cells property > + * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid > + * #address-cells property > * -FDT_ERR_BADMAGIC, > * -FDT_ERR_BADVERSION, > * -FDT_ERR_BADSTATE, > @@ -902,7 +1091,8 @@ int fdt_address_cells(const void *fdt, int nodeoffset); > * returns: > * 0 <= n < FDT_MAX_NCELLS, on success > * 2, if the node has no #address-cells property > - * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid #size-cells property > + * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid > + * #size-cells property > * -FDT_ERR_BADMAGIC, > * -FDT_ERR_BADVERSION, > * -FDT_ERR_BADSTATE, > @@ -916,6 +1106,29 @@ int fdt_size_cells(const void *fdt, int nodeoffset); > /* Write-in-place functions */ > /**********************************************************************/ > > +/** > + * fdt_setprop_inplace_namelen_partial - 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 > + * @namelen: number of characters of name to consider > + * @idx: index of the property to change in the array > + * @val: pointer to data to replace the property value with > + * @len: length of the property value > + * > + * Identical to fdt_setprop_inplace(), but modifies the given property > + * starting from the given index, and using only the first characters > + * of the name. It is useful when you want to manipulate only one value of > + * an array and you have a string that doesn't end with \0. > + */ > +#ifndef SWIG /* Not available in Python */ > +int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset, > + const char *name, int namelen, > + uint32_t idx, const void *val, > + int len); > +#endif > + > /** > * fdt_setprop_inplace - change a property's value, but not its size > * @fdt: pointer to the device tree blob > @@ -944,8 +1157,10 @@ int fdt_size_cells(const void *fdt, int nodeoffset); > * -FDT_ERR_BADSTRUCTURE, > * -FDT_ERR_TRUNCATED, standard meanings > */ > +#ifndef SWIG /* Not available in Python */ > int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, > const void *val, int len); > +#endif > > /** > * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property > @@ -1102,6 +1317,22 @@ static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) > { > return fdt_property_u32(fdt, name, val); > } > + > +/** > + * fdt_property_placeholder - add a new property and return a ptr to its value > + * > + * @fdt: pointer to the device tree blob > + * @name: name of property to add > + * @len: length of property value in bytes > + * @valp: returns a pointer to where where the value should be placed > + * > + * returns: > + * 0, on success > + * -FDT_ERR_BADMAGIC, > + * -FDT_ERR_NOSPACE, standard meanings > + */ > +int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp); > + > #define fdt_property_string(fdt, name, str) \ > fdt_property(fdt, name, str, strlen(str)+1) > int fdt_end_node(void *fdt); > @@ -1220,6 +1451,37 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name); > int fdt_setprop(void *fdt, int nodeoffset, const char *name, > const void *val, int len); > > +/** > + * fdt_setprop_placeholder - allocate space for 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 > + * @len: length of the property value > + * @prop_data: return pointer to property data > + * > + * fdt_setprop_placeholer() allocates the named property in the given node. > + * If the property exists it is resized. In either case a pointer to the > + * property data is returned. > + * > + * 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_placeholder(void *fdt, int nodeoffset, const char *name, > + int len, void **prop_data); > + > /** > * fdt_setprop_u32 - set a property to a 32-bit integer > * @fdt: pointer to the device tree blob > @@ -1332,6 +1594,36 @@ static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, > #define fdt_setprop_string(fdt, nodeoffset, name, str) \ > fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) > > + > +/** > + * fdt_setprop_empty - set a property to an empty value > + * @fdt: pointer to the device tree blob > + * @nodeoffset: offset of the node whose property to change > + * @name: name of the property to change > + * > + * fdt_setprop_empty() sets the value of the named property in the > + * given node to an empty (zero length) value, or creates a new empty > + * 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 > + */ > +#define fdt_setprop_empty(fdt, nodeoffset, name) \ > + fdt_setprop((fdt), (nodeoffset), (name), NULL, 0) > + > /** > * fdt_appendprop - append to or create a property > * @fdt: pointer to the device tree blob > @@ -1509,8 +1801,10 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name); > * creating subnodes based on a portion of a larger string, such as a > * full path. > */ > +#ifndef SWIG /* Not available in Python */ > int fdt_add_subnode_namelen(void *fdt, int parentoffset, > const char *name, int namelen); > +#endif > > /** > * fdt_add_subnode - creates a new node > @@ -1526,9 +1820,11 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, > * change the offsets of some existing nodes. > > * returns: > - * structure block offset of the created nodeequested subnode (>=0), on success > + * 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_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 > @@ -1566,10 +1862,41 @@ int fdt_add_subnode(void *fdt, int parentoffset, const char *name); > */ > int fdt_del_node(void *fdt, int nodeoffset); > > +/** > + * fdt_overlay_apply - Applies a DT overlay on a base DT > + * @fdt: pointer to the base device tree blob > + * @fdto: pointer to the device tree overlay blob > + * > + * fdt_overlay_apply() will apply the given device tree overlay on the > + * given base device tree. > + * > + * Expect the base device tree to be modified, even if the function > + * returns an error. > + * > + * returns: > + * 0, on success > + * -FDT_ERR_NOSPACE, there's not enough space in the base device tree > + * -FDT_ERR_NOTFOUND, the overlay points to some inexistant nodes or > + * properties in the base DT > + * -FDT_ERR_BADPHANDLE, > + * -FDT_ERR_BADOVERLAY, > + * -FDT_ERR_NOPHANDLES, > + * -FDT_ERR_INTERNAL, > + * -FDT_ERR_BADLAYOUT, > + * -FDT_ERR_BADMAGIC, > + * -FDT_ERR_BADOFFSET, > + * -FDT_ERR_BADPATH, > + * -FDT_ERR_BADVERSION, > + * -FDT_ERR_BADSTRUCTURE, > + * -FDT_ERR_BADSTATE, > + * -FDT_ERR_TRUNCATED, standard meanings > + */ > +int fdt_overlay_apply(void *fdt, void *fdto); > + > /**********************************************************************/ > /* Debugging / informational functions */ > /**********************************************************************/ > > const char *fdt_strerror(int errval); > > -#endif /* _LIBFDT_H */ > +#endif /* LIBFDT_H */ > diff --git a/scripts/dtc/libfdt_env.h b/scripts/dtc/libfdt_env.h > index 9dea97dff..bd2474628 100644 > --- a/scripts/dtc/libfdt_env.h > +++ b/scripts/dtc/libfdt_env.h > @@ -1,5 +1,5 @@ > -#ifndef _LIBFDT_ENV_H > -#define _LIBFDT_ENV_H > +#ifndef LIBFDT_ENV_H > +#define LIBFDT_ENV_H > /* > * libfdt - Flat Device Tree manipulation > * Copyright (C) 2006 David Gibson, IBM Corporation. > @@ -54,19 +54,20 @@ > > #include <stddef.h> > #include <stdint.h> > +#include <stdlib.h> > #include <string.h> > > #ifdef __CHECKER__ > -#define __force __attribute__((force)) > -#define __bitwise __attribute__((bitwise)) > +#define FDT_FORCE __attribute__((force)) > +#define FDT_BITWISE __attribute__((bitwise)) > #else > -#define __force > -#define __bitwise > +#define FDT_FORCE > +#define FDT_BITWISE > #endif > > -typedef uint16_t __bitwise fdt16_t; > -typedef uint32_t __bitwise fdt32_t; > -typedef uint64_t __bitwise fdt64_t; > +typedef uint16_t FDT_BITWISE fdt16_t; > +typedef uint32_t FDT_BITWISE fdt32_t; > +typedef uint64_t FDT_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)) > @@ -79,33 +80,60 @@ typedef uint64_t __bitwise fdt64_t; > > static inline uint16_t fdt16_to_cpu(fdt16_t x) > { > - return (__force uint16_t)CPU_TO_FDT16(x); > + return (FDT_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); > + return (FDT_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); > + return (FDT_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); > + return (FDT_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); > + return (FDT_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); > + return (FDT_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 */ > +#ifdef __APPLE__ > +#include <AvailabilityMacros.h> > + > +/* strnlen() is not available on Mac OS < 10.7 */ > +# if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < \ > + MAC_OS_X_VERSION_10_7) > + > +#define strnlen fdt_strnlen > + > +/* > + * fdt_strnlen: returns the length of a string or max_count - which ever is > + * smallest. > + * Input 1 string: the string whose size is to be determined > + * Input 2 max_count: the maximum value returned by this function > + * Output: length of the string or max_count (the smallest of the two) > + */ > +static inline size_t fdt_strnlen(const char *string, size_t max_count) > +{ > + const char *p = memchr(string, 0, max_count); > + return p ? p - string : max_count; > +} > + > +#endif /* !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < > + MAC_OS_X_VERSION_10_7) */ > + > +#endif /* __APPLE__ */ > + > +#endif /* LIBFDT_ENV_H */ > diff --git a/scripts/dtc/libfdt_internal.h b/scripts/dtc/libfdt_internal.h > index 02cfa6fb6..7681e1922 100644 > --- a/scripts/dtc/libfdt_internal.h > +++ b/scripts/dtc/libfdt_internal.h > @@ -1,5 +1,5 @@ > -#ifndef _LIBFDT_INTERNAL_H > -#define _LIBFDT_INTERNAL_H > +#ifndef LIBFDT_INTERNAL_H > +#define LIBFDT_INTERNAL_H > /* > * libfdt - Flat Device Tree manipulation > * Copyright (C) 2006 David Gibson, IBM Corporation. > @@ -57,27 +57,27 @@ > > #define FDT_CHECK_HEADER(fdt) \ > { \ > - int __err; \ > - if ((__err = fdt_check_header(fdt)) != 0) \ > - return __err; \ > + 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); > +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) > +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) > +static inline void *fdt_offset_ptr_w_(void *fdt, int offset) > { > - return (void *)(uintptr_t)_fdt_offset_ptr(fdt, 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) > +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 *) > @@ -85,11 +85,11 @@ static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int > > return rsv_table + n; > } > -static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n) > +static inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n) > { > - return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n); > + return (void *)(uintptr_t)fdt_mem_rsv_(fdt, n); > } > > #define FDT_SW_MAGIC (~FDT_MAGIC) > > -#endif /* _LIBFDT_INTERNAL_H */ > +#endif /* LIBFDT_INTERNAL_H */ > diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c > index e229b8443..57b7db2ed 100644 > --- a/scripts/dtc/livetree.c > +++ b/scripts/dtc/livetree.c > @@ -204,7 +204,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node) > } > } > > - /* if no collision occured, add child to the old node. */ > + /* if no collision occurred, add child to the old node. */ > if (new_child) > add_child(old_node, new_child); > } > @@ -216,6 +216,29 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node) > return old_node; > } > > +struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref) > +{ > + static unsigned int next_orphan_fragment = 0; > + struct node *node; > + struct property *p; > + struct data d = empty_data; > + char *name; > + > + d = data_add_marker(d, REF_PHANDLE, ref); > + d = data_append_integer(d, 0xffffffff, 32); > + > + p = build_property("target", d); > + > + xasprintf(&name, "fragment@%u", > + next_orphan_fragment++); > + name_node(new_node, "__overlay__"); > + node = build_node(p, new_node); > + name_node(node, name); > + > + add_child(dt, node); > + return dt; > +} > + > struct node *chain_node(struct node *first, struct node *list) > { > assert(first->next_sibling == NULL); > @@ -242,7 +265,7 @@ void delete_property_by_name(struct node *node, char *name) > struct property *prop = node->proplist; > > while (prop) { > - if (!strcmp(prop->name, name)) { > + if (streq(prop->name, name)) { > delete_property(prop); > return; > } > @@ -275,7 +298,7 @@ void delete_node_by_name(struct node *parent, char *name) > struct node *node = parent->children; > > while (node) { > - if (!strcmp(node->name, name)) { > + if (streq(node->name, name)) { > delete_node(node); > return; > } > @@ -296,14 +319,31 @@ void delete_node(struct node *node) > delete_labels(&node->labels); > } > > +void append_to_property(struct node *node, > + char *name, const void *data, int len) > +{ > + struct data d; > + struct property *p; > + > + p = get_property(node, name); > + if (p) { > + d = data_append_data(p->val, data, len); > + p->val = d; > + } else { > + d = data_append_data(empty_data, data, len); > + p = build_property(name, d); > + add_property(node, p); > + } > +} > + > 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; > + new->address = address; > + new->size = size; > > return new; > } > @@ -335,17 +375,19 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list, > return list; > } > > -struct boot_info *build_boot_info(struct reserve_info *reservelist, > - struct node *tree, uint32_t boot_cpuid_phys) > +struct dt_info *build_dt_info(unsigned int dtsflags, > + struct reserve_info *reservelist, > + struct node *tree, uint32_t boot_cpuid_phys) > { > - struct boot_info *bi; > + struct dt_info *dti; > > - bi = xmalloc(sizeof(*bi)); > - bi->reservelist = reservelist; > - bi->dt = tree; > - bi->boot_cpuid_phys = boot_cpuid_phys; > + dti = xmalloc(sizeof(*dti)); > + dti->dtsflags = dtsflags; > + dti->reservelist = reservelist; > + dti->dt = tree; > + dti->boot_cpuid_phys = boot_cpuid_phys; > > - return bi; > + return dti; > } > > /* > @@ -374,7 +416,13 @@ struct property *get_property(struct node *node, const char *propname) > cell_t propval_cell(struct property *prop) > { > assert(prop->val.len == sizeof(cell_t)); > - return fdt32_to_cpu(*((cell_t *)prop->val.val)); > + return fdt32_to_cpu(*((fdt32_t *)prop->val.val)); > +} > + > +cell_t propval_cell_n(struct property *prop, int n) > +{ > + assert(prop->val.len / sizeof(cell_t) >= n); > + return fdt32_to_cpu(*((fdt32_t *)prop->val.val + n)); > } > > struct property *get_property_by_label(struct node *tree, const char *label, > @@ -459,7 +507,8 @@ struct node *get_node_by_path(struct node *tree, const char *path) > p = strchr(path, '/'); > > for_each_child(tree, child) { > - if (p && strneq(path, child->name, p-path)) > + if (p && (strlen(child->name) == p-path) && > + strprefixeq(path, p - path, child->name)) > return get_node_by_path(child, p+1); > else if (!p && streq(path, child->name)) > return child; > @@ -492,7 +541,10 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle) > { > struct node *child, *node; > > - assert((phandle != 0) && (phandle != -1)); > + if ((phandle == 0) || (phandle == -1)) { > + assert(generate_fixups); > + return NULL; > + } > > if (tree->phandle == phandle) { > if (tree->deleted) > @@ -580,24 +632,24 @@ static int cmp_reserve_info(const void *ax, const void *bx) > a = *((const struct reserve_info * const *)ax); > b = *((const struct reserve_info * const *)bx); > > - if (a->re.address < b->re.address) > + if (a->address < b->address) > return -1; > - else if (a->re.address > b->re.address) > + else if (a->address > b->address) > return 1; > - else if (a->re.size < b->re.size) > + else if (a->size < b->size) > return -1; > - else if (a->re.size > b->re.size) > + else if (a->size > b->size) > return 1; > else > return 0; > } > > -static void sort_reserve_entries(struct boot_info *bi) > +static void sort_reserve_entries(struct dt_info *dti) > { > struct reserve_info *ri, **tbl; > int n = 0, i = 0; > > - for (ri = bi->reservelist; > + for (ri = dti->reservelist; > ri; > ri = ri->next) > n++; > @@ -607,14 +659,14 @@ static void sort_reserve_entries(struct boot_info *bi) > > tbl = xmalloc(n * sizeof(*tbl)); > > - for (ri = bi->reservelist; > + for (ri = dti->reservelist; > ri; > ri = ri->next) > tbl[i++] = ri; > > qsort(tbl, n, sizeof(*tbl), cmp_reserve_info); > > - bi->reservelist = tbl[0]; > + dti->reservelist = tbl[0]; > for (i = 0; i < (n-1); i++) > tbl[i]->next = tbl[i+1]; > tbl[n-1]->next = NULL; > @@ -704,8 +756,258 @@ static void sort_node(struct node *node) > sort_node(c); > } > > -void sort_tree(struct boot_info *bi) > +void sort_tree(struct dt_info *dti) > +{ > + sort_reserve_entries(dti); > + sort_node(dti->dt); > +} > + > +/* utility helper to avoid code duplication */ > +static struct node *build_and_name_child_node(struct node *parent, char *name) > +{ > + struct node *node; > + > + node = build_node(NULL, NULL); > + name_node(node, xstrdup(name)); > + add_child(parent, node); > + > + return node; > +} > + > +static struct node *build_root_node(struct node *dt, char *name) > +{ > + struct node *an; > + > + an = get_subnode(dt, name); > + if (!an) > + an = build_and_name_child_node(dt, name); > + > + if (!an) > + die("Could not build root node /%s\n", name); > + > + return an; > +} > + > +static bool any_label_tree(struct dt_info *dti, struct node *node) > +{ > + struct node *c; > + > + if (node->labels) > + return true; > + > + for_each_child(node, c) > + if (any_label_tree(dti, c)) > + return true; > + > + return false; > +} > + > +static void generate_label_tree_internal(struct dt_info *dti, > + struct node *an, struct node *node, > + bool allocph) > { > - sort_reserve_entries(bi); > - sort_node(bi->dt); > + struct node *dt = dti->dt; > + struct node *c; > + struct property *p; > + struct label *l; > + > + /* if there are labels */ > + if (node->labels) { > + > + /* now add the label in the node */ > + for_each_label(node->labels, l) { > + > + /* check whether the label already exists */ > + p = get_property(an, l->label); > + if (p) { > + fprintf(stderr, "WARNING: label %s already" > + " exists in /%s", l->label, > + an->name); > + continue; > + } > + > + /* insert it */ > + p = build_property(l->label, > + data_copy_mem(node->fullpath, > + strlen(node->fullpath) + 1)); > + add_property(an, p); > + } > + > + /* force allocation of a phandle for this node */ > + if (allocph) > + (void)get_node_phandle(dt, node); > + } > + > + for_each_child(node, c) > + generate_label_tree_internal(dti, an, c, allocph); > +} > + > +static bool any_fixup_tree(struct dt_info *dti, struct node *node) > +{ > + struct node *c; > + struct property *prop; > + struct marker *m; > + > + for_each_property(node, prop) { > + m = prop->val.markers; > + for_each_marker_of_type(m, REF_PHANDLE) { > + if (!get_node_by_ref(dti->dt, m->ref)) > + return true; > + } > + } > + > + for_each_child(node, c) { > + if (any_fixup_tree(dti, c)) > + return true; > + } > + > + return false; > +} > + > +static void add_fixup_entry(struct dt_info *dti, struct node *fn, > + struct node *node, struct property *prop, > + struct marker *m) > +{ > + char *entry; > + > + /* m->ref can only be a REF_PHANDLE, but check anyway */ > + assert(m->type == REF_PHANDLE); > + > + /* there shouldn't be any ':' in the arguments */ > + if (strchr(node->fullpath, ':') || strchr(prop->name, ':')) > + die("arguments should not contain ':'\n"); > + > + xasprintf(&entry, "%s:%s:%u", > + node->fullpath, prop->name, m->offset); > + append_to_property(fn, m->ref, entry, strlen(entry) + 1); > + > + free(entry); > +} > + > +static void generate_fixups_tree_internal(struct dt_info *dti, > + struct node *fn, > + struct node *node) > +{ > + struct node *dt = dti->dt; > + struct node *c; > + struct property *prop; > + struct marker *m; > + struct node *refnode; > + > + for_each_property(node, prop) { > + m = prop->val.markers; > + for_each_marker_of_type(m, REF_PHANDLE) { > + refnode = get_node_by_ref(dt, m->ref); > + if (!refnode) > + add_fixup_entry(dti, fn, node, prop, m); > + } > + } > + > + for_each_child(node, c) > + generate_fixups_tree_internal(dti, fn, c); > +} > + > +static bool any_local_fixup_tree(struct dt_info *dti, struct node *node) > +{ > + struct node *c; > + struct property *prop; > + struct marker *m; > + > + for_each_property(node, prop) { > + m = prop->val.markers; > + for_each_marker_of_type(m, REF_PHANDLE) { > + if (get_node_by_ref(dti->dt, m->ref)) > + return true; > + } > + } > + > + for_each_child(node, c) { > + if (any_local_fixup_tree(dti, c)) > + return true; > + } > + > + return false; > +} > + > +static void add_local_fixup_entry(struct dt_info *dti, > + struct node *lfn, struct node *node, > + struct property *prop, struct marker *m, > + struct node *refnode) > +{ > + struct node *wn, *nwn; /* local fixup node, walk node, new */ > + fdt32_t value_32; > + char **compp; > + int i, depth; > + > + /* walk back retreiving depth */ > + depth = 0; > + for (wn = node; wn; wn = wn->parent) > + depth++; > + > + /* allocate name array */ > + compp = xmalloc(sizeof(*compp) * depth); > + > + /* store names in the array */ > + for (wn = node, i = depth - 1; wn; wn = wn->parent, i--) > + compp[i] = wn->name; > + > + /* walk the path components creating nodes if they don't exist */ > + for (wn = lfn, i = 1; i < depth; i++, wn = nwn) { > + /* if no node exists, create it */ > + nwn = get_subnode(wn, compp[i]); > + if (!nwn) > + nwn = build_and_name_child_node(wn, compp[i]); > + } > + > + free(compp); > + > + value_32 = cpu_to_fdt32(m->offset); > + append_to_property(wn, prop->name, &value_32, sizeof(value_32)); > +} > + > +static void generate_local_fixups_tree_internal(struct dt_info *dti, > + struct node *lfn, > + struct node *node) > +{ > + struct node *dt = dti->dt; > + struct node *c; > + struct property *prop; > + struct marker *m; > + struct node *refnode; > + > + for_each_property(node, prop) { > + m = prop->val.markers; > + for_each_marker_of_type(m, REF_PHANDLE) { > + refnode = get_node_by_ref(dt, m->ref); > + if (refnode) > + add_local_fixup_entry(dti, lfn, node, prop, m, refnode); > + } > + } > + > + for_each_child(node, c) > + generate_local_fixups_tree_internal(dti, lfn, c); > +} > + > +void generate_label_tree(struct dt_info *dti, char *name, bool allocph) > +{ > + if (!any_label_tree(dti, dti->dt)) > + return; > + generate_label_tree_internal(dti, build_root_node(dti->dt, name), > + dti->dt, allocph); > +} > + > +void generate_fixups_tree(struct dt_info *dti, char *name) > +{ > + if (!any_fixup_tree(dti, dti->dt)) > + return; > + generate_fixups_tree_internal(dti, build_root_node(dti->dt, name), > + dti->dt); > +} > + > +void generate_local_fixups_tree(struct dt_info *dti, char *name) > +{ > + if (!any_local_fixup_tree(dti, dti->dt)) > + return; > + generate_local_fixups_tree_internal(dti, build_root_node(dti->dt, name), > + dti->dt); > } > diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c > index f534c22a8..cb6ed0e3e 100644 > --- a/scripts/dtc/srcpos.c > +++ b/scripts/dtc/srcpos.c > @@ -209,8 +209,6 @@ struct srcpos srcpos_empty = { > .file = NULL, > }; > > -#define TAB_SIZE 8 > - > void srcpos_update(struct srcpos *pos, const char *text, int len) > { > int i; > @@ -224,9 +222,6 @@ void srcpos_update(struct srcpos *pos, const char *text, int len) > 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++; > } > @@ -246,46 +241,27 @@ srcpos_copy(struct srcpos *pos) > return pos_new; > } > > - > - > -void > -srcpos_dump(struct srcpos *pos) > -{ > - printf("file : \"%s\"\n", > - pos->file ? (char *) pos->file : "<no 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 = "<no-file>"; > char *pos_str; > - int rc; > > - if (pos) > + if (pos->file && pos->file->name) > 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); > + xasprintf(&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); > + xasprintf(&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"); > + xasprintf(&pos_str, "%s:%d.%d", fname, > + pos->first_line, pos->first_column); > > return pos_str; > } > diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h > index f81827bd6..9ded12a38 100644 > --- a/scripts/dtc/srcpos.h > +++ b/scripts/dtc/srcpos.h > @@ -17,11 +17,12 @@ > * USA > */ > > -#ifndef _SRCPOS_H_ > -#define _SRCPOS_H_ > +#ifndef SRCPOS_H > +#define SRCPOS_H > > #include <stdio.h> > #include <stdbool.h> > +#include "util.h" > > struct srcfile_state { > FILE *f; > @@ -105,15 +106,12 @@ 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, const char *prefix, > - const char *fmt, va_list va) > - __attribute__((format(printf, 3, 0))); > -extern void srcpos_error(struct srcpos *pos, const char *prefix, > - const char *fmt, ...) > - __attribute__((format(printf, 3, 4))); > +extern void PRINTF(3, 0) srcpos_verror(struct srcpos *pos, const char *prefix, > + const char *fmt, va_list va); > +extern void PRINTF(3, 4) srcpos_error(struct srcpos *pos, const char *prefix, > + const char *fmt, ...); > > extern void srcpos_set_line(char *f, int l); > > -#endif /* _SRCPOS_H_ */ > +#endif /* SRCPOS_H */ > diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c > index a55d1d128..2461a3d06 100644 > --- a/scripts/dtc/treesource.c > +++ b/scripts/dtc/treesource.c > @@ -25,12 +25,12 @@ extern FILE *yyin; > extern int yyparse(void); > extern YYLTYPE yylloc; > > -struct boot_info *the_boot_info; > +struct dt_info *parser_output; > bool treesource_error; > > -struct boot_info *dt_from_source(const char *fname) > +struct dt_info *dt_from_source(const char *fname) > { > - the_boot_info = NULL; > + parser_output = NULL; > treesource_error = false; > > srcfile_push(fname); > @@ -43,7 +43,7 @@ struct boot_info *dt_from_source(const char *fname) > if (treesource_error) > die("Syntax error parsing input tree\n"); > > - return the_boot_info; > + return parser_output; > } > > static void write_prefix(FILE *f, int level) > @@ -137,7 +137,7 @@ static void write_propval_string(FILE *f, struct data val) > static void write_propval_cells(FILE *f, struct data val) > { > void *propend = val.val + val.len; > - cell_t *cp = (cell_t *)val.val; > + fdt32_t *cp = (fdt32_t *)val.val; > struct marker *m = val.markers; > > fprintf(f, "<"); > @@ -263,22 +263,22 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level) > } > > > -void dt_to_source(FILE *f, struct boot_info *bi) > +void dt_to_source(FILE *f, struct dt_info *dti) > { > struct reserve_info *re; > > fprintf(f, "/dts-v1/;\n\n"); > > - for (re = bi->reservelist; re; re = re->next) { > + for (re = dti->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); > + (unsigned long long)re->address, > + (unsigned long long)re->size); > } > > - write_tree_source_node(f, bi->dt, 0); > + write_tree_source_node(f, dti->dt, 0); > } > > diff --git a/scripts/dtc/update-dtc-source.sh b/scripts/dtc/update-dtc-source.sh > index 075d1d7af..1a009fd19 100755 > --- a/scripts/dtc/update-dtc-source.sh > +++ b/scripts/dtc/update-dtc-source.sh > @@ -1,9 +1,10 @@ > #!/bin/sh > +# SPDX-License-Identifier: GPL-2.0 > # Simple script to update the version of DTC carried by the Linux kernel > # > # This script assumes that the dtc and the linux git trees are in the > # same directory. After building dtc in the dtc directory, it copies the > -# source files and generated source files into the scripts/dtc directory > +# source files and generated source file(s) into the scripts/dtc directory > # in the kernel and creates a git commit updating them to the new > # version. > # > @@ -32,16 +33,24 @@ DTC_LINUX_PATH=`pwd`/scripts/dtc > > DTC_SOURCE="checks.c data.c dtc.c dtc.h flattree.c fstree.c livetree.c srcpos.c \ > srcpos.h treesource.c util.c util.h version_gen.h Makefile.dtc \ > - dtc-lexer.l dtc-parser.y fdtdump.c fdtput.c fdtget.c" > -DTC_LIB="fdt.c fdt.h fdt_addresses.c fdt_empty_tree.c fdt_ro.c fdt_rw.c \ > - fdt_strerror.c fdt_sw.c fdt_wip.c libfdt.h libfdt_env.h \ > - libfdt_internal.h" > -DTC_GENERATED="dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h" > + dtc-lexer.l dtc-parser.y" > +LIBFDT_SOURCE="Makefile.libfdt fdt.c fdt.h fdt_addresses.c fdt_empty_tree.c \ > + fdt_overlay.c fdt_ro.c fdt_rw.c fdt_strerror.c fdt_sw.c \ > + fdt_wip.c libfdt.h libfdt_env.h libfdt_internal.h" > + > +get_last_dtc_version() { > + git log --oneline scripts/dtc/ | grep 'upstream' | head -1 | sed -e 's/^.* \(.*\)/\1/' > +} > + > +last_dtc_ver=$(get_last_dtc_version) > > # Build DTC > cd $DTC_UPSTREAM_PATH > make clean > make check > +dtc_version=$(git describe HEAD) > +dtc_log=$(git log --oneline ${last_dtc_ver}..) > + > > # Copy the files into the Linux tree > cd $DTC_LINUX_PATH > @@ -49,13 +58,22 @@ for f in $DTC_SOURCE; do > cp ${DTC_UPSTREAM_PATH}/${f} ${f} > git add ${f} > done > -for f in $DTC_LIB; do > - cp ${DTC_UPSTREAM_PATH}/libfdt/${f} ${f} > - git add ${f} > -done > -for f in $DTC_GENERATED; do > - cp ${DTC_UPSTREAM_PATH}/$f ${f}_shipped > - git add ${f}_shipped > +for f in $LIBFDT_SOURCE; do > + cp ${DTC_UPSTREAM_PATH}/libfdt/${f} libfdt/${f} > + git add libfdt/${f} > done > > -git commit -e -v -m "scripts/dtc: Update to upstream version [CHANGEME]" > +sed -i -- 's/#include <libfdt_env.h>/#include "libfdt_env.h"/g' ./libfdt/libfdt.h > +sed -i -- 's/#include <fdt.h>/#include "fdt.h"/g' ./libfdt/libfdt.h > +git add ./libfdt/libfdt.h > + > +commit_msg=$(cat << EOF > +scripts/dtc: Update to upstream version ${dtc_version} > + > +This adds the following commits from upstream: > + > +${dtc_log} > +EOF > +) > + > +git commit -e -v -s -m "${commit_msg}" > diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c > index 9d65226df..9953c32a0 100644 > --- a/scripts/dtc/util.c > +++ b/scripts/dtc/util.c > @@ -46,6 +46,36 @@ char *xstrdup(const char *s) > return d; > } > > +/* based in part from (3) vsnprintf */ > +int xasprintf(char **strp, const char *fmt, ...) > +{ > + int n, size = 128; /* start with 128 bytes */ > + char *p; > + va_list ap; > + > + /* initial pointer is NULL making the fist realloc to be malloc */ > + p = NULL; > + while (1) { > + p = xrealloc(p, size); > + > + /* Try to print in the allocated space. */ > + va_start(ap, fmt); > + n = vsnprintf(p, size, fmt, ap); > + va_end(ap); > + > + /* If that worked, return the string. */ > + if (n > -1 && n < size) > + break; > + /* Else try again with more space. */ > + if (n > -1) /* glibc 2.1 */ > + size = n + 1; /* precisely what is needed */ > + else /* glibc 2.0 */ > + size *= 2; /* twice the old size */ > + } > + *strp = p; > + return strlen(p); > +} > + > char *join_path(const char *path, const char *name) > { > int lenp = strlen(path); > @@ -152,7 +182,6 @@ char get_escape_char(const char *s, int *i) > int j = *i + 1; > char val; > > - assert(c); > switch (c) { > case 'a': > val = '\a'; > @@ -349,7 +378,6 @@ int utilfdt_decode_type(const char *fmt, int *type, int *size) > void utilfdt_print_data(const char *data, int len) > { > int i; > - const char *p = data; > const char *s; > > /* no data, don't print */ > @@ -368,7 +396,7 @@ void utilfdt_print_data(const char *data, int len) > } while (s < data + len); > > } else if ((len % 4) == 0) { > - const uint32_t *cell = (const uint32_t *)data; > + const fdt32_t *cell = (const fdt32_t *)data; > > printf(" = <"); > for (i = 0, len /= 4; i < len; i++) > @@ -376,6 +404,7 @@ void utilfdt_print_data(const char *data, int len) > i < (len - 1) ? " " : ""); > printf(">"); > } else { > + const unsigned char *p = (const unsigned char *)data; > printf(" = ["); > for (i = 0; i < len; i++) > printf("%02x%s", *p++, i < len - 1 ? " " : ""); > @@ -383,15 +412,16 @@ void utilfdt_print_data(const char *data, int len) > } > } > > -void util_version(void) > +void NORETURN 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[]) > +void NORETURN 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[] = "<arg>"; > diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h > index ccfdf4b12..66fba8ea7 100644 > --- a/scripts/dtc/util.h > +++ b/scripts/dtc/util.h > @@ -1,5 +1,5 @@ > -#ifndef _UTIL_H > -#define _UTIL_H > +#ifndef UTIL_H > +#define UTIL_H > > #include <stdarg.h> > #include <stdbool.h> > @@ -25,15 +25,27 @@ > * USA > */ > > +#ifdef __GNUC__ > +#define PRINTF(i, j) __attribute__((format (printf, i, j))) > +#define NORETURN __attribute__((noreturn)) > +#else > +#define PRINTF(i, j) > +#define NORETURN > +#endif > + > #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) > > -static inline void __attribute__((noreturn)) die(const char *str, ...) > +#define stringify(s) stringify_(s) > +#define stringify_(s) #s > + > +static inline void NORETURN PRINTF(1, 2) die(const char *str, ...) > { > va_list ap; > > va_start(ap, str); > fprintf(stderr, "FATAL ERROR: "); > vfprintf(stderr, str, ap); > + va_end(ap); > exit(1); > } > > @@ -52,12 +64,14 @@ static inline void *xrealloc(void *p, size_t len) > void *new = realloc(p, len); > > if (!new) > - die("realloc() failed (len=%d)\n", len); > + die("realloc() failed (len=%zd)\n", len); > > return new; > } > > extern char *xstrdup(const char *s); > + > +extern int PRINTF(2, 3) xasprintf(char **strp, const char *fmt, ...); > extern char *join_path(const char *path, const char *name); > > /** > @@ -186,7 +200,7 @@ void utilfdt_print_data(const char *data, int len); > /** > * Show source version and exit > */ > -void util_version(void) __attribute__((noreturn)); > +void NORETURN util_version(void); > > /** > * Show usage and exit > @@ -200,9 +214,10 @@ void util_version(void) __attribute__((noreturn)); > * @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)); > +void NORETURN util_usage(const char *errmsg, const char *synopsis, > + const char *short_opts, > + struct option const long_opts[], > + const char * const opts_help[]); > > /** > * Show usage and exit > @@ -248,4 +263,4 @@ void util_usage(const char *errmsg, const char *synopsis, > case 'V': util_version(); \ > case '?': usage("unknown option"); > > -#endif /* _UTIL_H */ > +#endif /* UTIL_H */ > diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h > index 607afac1c..89d4e0ad1 100644 > --- a/scripts/dtc/version_gen.h > +++ b/scripts/dtc/version_gen.h > @@ -1 +1 @@ > -#define DTC_VERSION "DTC 1.4.1" > +#define DTC_VERSION "DTC 1.4.6" > -- > 2.17.0 > > > _______________________________________________ > barebox mailing list > barebox@xxxxxxxxxxxxxxxxxxx > http://lists.infradead.org/mailman/listinfo/barebox > -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox