* [PATCH 1/2] scripts/dtc: Update to upstream version 1.4.6
@ 2018-06-05 22:49 Pascal Vizeli
2018-06-07 7:25 ` Sascha Hauer
0 siblings, 1 reply; 2+ messages in thread
From: Pascal Vizeli @ 2018-06-05 22:49 UTC (permalink / raw)
To: barebox; +Cc: Pascal Vizeli
Signed-off-by: Pascal Vizeli <pvizeli@syshack.ch>
---
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@au1.ibm.com>, 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@au1.ibm.com>, 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@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH 1/2] scripts/dtc: Update to upstream version 1.4.6
2018-06-05 22:49 [PATCH 1/2] scripts/dtc: Update to upstream version 1.4.6 Pascal Vizeli
@ 2018-06-07 7:25 ` Sascha Hauer
0 siblings, 0 replies; 2+ messages in thread
From: Sascha Hauer @ 2018-06-07 7:25 UTC (permalink / raw)
To: Pascal Vizeli; +Cc: barebox
On Tue, Jun 05, 2018 at 10:49:11PM +0000, Pascal Vizeli wrote:
> Signed-off-by: Pascal Vizeli <pvizeli@syshack.ch>
> ---
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@au1.ibm.com>, 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@au1.ibm.com>, 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@lists.infradead.org
> 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@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-06-07 7:25 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-05 22:49 [PATCH 1/2] scripts/dtc: Update to upstream version 1.4.6 Pascal Vizeli
2018-06-07 7:25 ` Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox