Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f05afcb authored by Rob Herring's avatar Rob Herring
Browse files

scripts/dtc: Update to upstream version 0931cea3ba20



Sync to upstream dtc commit 0931cea3ba20 ("dtc: fdtdump: check fdt if
not in scanning mode"). In particular, this pulls in dtc overlay
support.

This adds the following commits from upstream:

f88865469b65 dtc: Fix memory leak in character literal parsing
00fbb8696b66 Rename boot_info
1ef86ad2c24f dtc: Clean up /dts-v1/ and /plugin/ handling in grammar
e3c769aa9c16 dtc: Don't always generate __symbols__ for plugins
c96cb3c0169e tests: Don't use -@ on plugin de/recompile tests
66381538ce24 tests: Remove "suppression of fixups" tests
ba765b273f0f tests: Clarify dtc overlay tests
6ea8cd944fcd tests: More thorough tests of libfdt overlay application without dtc
7d8ef6e1db97 tests: Correct fdt handling of overlays without fixups and base trees without symbols
b4dc0ed8b127 tests: Fix double expansion bugs in test code
3ea879dc0c8f tests: Split overlay tests into those with do/don't exercise dtc plugin generation
47b4d66a2f11 tests: Test auto-alias generation on base tree, not overlay
72e1ad811523 tests: Make overlay/plugin tests unconditional
e7b3c3b5951b tests: Add overlay tests
9637e3f772a9 tests: Add check_path test
20f29d8d41f6 dtc: Plugin and fixup support
a2c92cac53f8 dtc: Document the dynamic plugin internals
8f70ac39801d checks: Pass boot_info instead of root node
ea10f953878f libfdt: add missing errors to fdt_strerror()
daa75e8fa594 libfdt: fix fdt_stringlist_search()
e28eff5b787a libfdt: fix fdt_stringlist_count()
ae97c7722840 tests: overlay: Rename the device tree blobs to be more explicit
96162d2bd9cb tests: overlay: Add test suffix to the compiled blobs
5ce8634733b7 libfdt: Add fdt_overlay_apply to the exported symbols
804a9db90ad2 fdt: strerr: Remove spurious BADOVERLAY
e8c3a1a493fa tests: overlay: Move back the bad fixup tests
7a72d89d3f81 libfdt: overlay: Fix symbols and fixups nodes condition
cabbaa972cdd libfdt: overlay: Report a bad overlay for mismatching local fixups
deb0a5c1aeaa libfdt: Add BADPHANDLE error string
7b7a6be9ba15 libfdt: Don't use 'index' as a local variable name
aea8860d831e tests: Add tests cases for the overlay code
0cdd06c5135b libfdt: Add overlay application function
39240cc865cf libfdt: Extend the reach of FDT_ERR_BADPHANDLE
4aa3a6f5e6d9 libfdt: Add new errors for the overlay code
6d1832c9e64b dtc: Remove "home page" link
45fd440a9561 Fix some typing errors in libfdt.h and livetree.c
a59be4939c13 Merge tag 'v1.4.2'
a34bb721caca dtc: Fix assorted problems in the testcases for the -a option
874f40588d3e Implement the -a option to pad dtb aligned
ec02b34c05be dtc: Makefile improvements for release uploading
1ed45d40a137 dtc: Bump version to 1.4.2
36fd7331fb11 libfdt: simplify fdt_del_mem_rsv()
d877364e4a0f libfdt: Add fdt_setprop_inplace_namelen_partial
3e9037aaad44 libfdt: Add fdt_getprop_namelen_w
84e0e1346c68 libfdt: Add max phandle retrieval function
d29126c90acb libfdt: Add iterator over properties
902d0f0953d0 libfdt: Add a subnodes iterator macro
c539075ba8ba fdtput.c: Fix memory leak.
f79ddb83e185 fdtget.c: Fix memory leak
1074ee54b63f convert-dtsv0-lexer.l: fix memory leak
e24d39a024e6 fdtdump.c: make sure size_t argument to memchr is always unsigned.
44a59713cf05 Remove unused srcpos_dump() function
cb9241ae3453 DTC: Fix memory leak on flatname.
1ee0ae24ea09 Simplify check field and macro names
9d97527a8621 Remove property check functions
2e709d158e11 Remove tree check functions
c4cb12e193e3 Alter grammar to allow multiple /dts-v1/ tags
d71d25d76012 Use xasprintf() in srcpos
9dc404958e9c util: Add xasprintf portable asprintf variant
beef80b8b55f Correct a missing space in a fdt_header cast
68d43cec1253 Correct line lengths in libfdt.h
b0dbceafd49a Correct space-after-tab in libfdt.h

Signed-off-by: default avatarRob Herring <robh@kernel.org>
parent 0c744ea4
Loading
Loading
Loading
Loading
+181 −168
Original line number Original line Diff line number Diff line
@@ -40,16 +40,11 @@ enum checkstatus {


struct check;
struct check;


typedef void (*tree_check_fn)(struct check *c, struct node *dt);
typedef void (*check_fn)(struct check *c, struct dt_info *dti, struct node *node);
typedef void (*node_check_fn)(struct check *c, struct node *dt, struct node *node);
typedef void (*prop_check_fn)(struct check *c, struct node *dt,
			      struct node *node, struct property *prop);


struct check {
struct check {
	const char *name;
	const char *name;
	tree_check_fn tree_fn;
	check_fn fn;
	node_check_fn node_fn;
	prop_check_fn prop_fn;
	void *data;
	void *data;
	bool warn, error;
	bool warn, error;
	enum checkstatus status;
	enum checkstatus status;
@@ -58,45 +53,24 @@ struct check {
	struct check **prereq;
	struct check **prereq;
};
};


#define CHECK_ENTRY(nm, tfn, nfn, pfn, d, w, e, ...)	       \
#define CHECK_ENTRY(_nm, _fn, _d, _w, _e, ...)	       \
	static struct check *nm##_prereqs[] = { __VA_ARGS__ }; \
	static struct check *_nm##_prereqs[] = { __VA_ARGS__ }; \
	static struct check nm = { \
	static struct check _nm = { \
		.name = #nm, \
		.name = #_nm, \
		.tree_fn = (tfn), \
		.fn = (_fn), \
		.node_fn = (nfn), \
		.data = (_d), \
		.prop_fn = (pfn), \
		.warn = (_w), \
		.data = (d), \
		.error = (_e), \
		.warn = (w), \
		.error = (e), \
		.status = UNCHECKED, \
		.status = UNCHECKED, \
		.num_prereqs = ARRAY_SIZE(nm##_prereqs), \
		.num_prereqs = ARRAY_SIZE(_nm##_prereqs), \
		.prereq = nm##_prereqs, \
		.prereq = _nm##_prereqs, \
	};
	};
#define WARNING(nm, tfn, nfn, pfn, d, ...) \
#define WARNING(_nm, _fn, _d, ...) \
	CHECK_ENTRY(nm, tfn, nfn, pfn, d, true, false, __VA_ARGS__)
	CHECK_ENTRY(_nm, _fn, _d, true, false, __VA_ARGS__)
#define ERROR(nm, tfn, nfn, pfn, d, ...) \
#define ERROR(_nm, _fn, _d, ...) \
	CHECK_ENTRY(nm, tfn, nfn, pfn, d, false, true, __VA_ARGS__)
	CHECK_ENTRY(_nm, _fn, _d, false, true, __VA_ARGS__)
#define CHECK(nm, tfn, nfn, pfn, d, ...) \
#define CHECK(_nm, _fn, _d, ...) \
	CHECK_ENTRY(nm, tfn, nfn, pfn, d, false, false, __VA_ARGS__)
	CHECK_ENTRY(_nm, _fn, _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__
#ifdef __GNUC__
static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
@@ -123,27 +97,21 @@ static inline void check_msg(struct check *c, const char *fmt, ...)
		check_msg((c), __VA_ARGS__); \
		check_msg((c), __VA_ARGS__); \
	} while (0)
	} while (0)


static void check_nodes_props(struct check *c, struct node *dt, struct node *node)
static void check_nodes_props(struct check *c, struct dt_info *dti, struct node *node)
{
{
	struct node *child;
	struct node *child;
	struct property *prop;


	TRACE(c, "%s", node->fullpath);
	TRACE(c, "%s", node->fullpath);
	if (c->node_fn)
	if (c->fn)
		c->node_fn(c, dt, node);
		c->fn(c, dti, node);

	if (c->prop_fn)
		for_each_property(node, prop) {
			TRACE(c, "%s\t'%s'", node->fullpath, prop->name);
			c->prop_fn(c, dt, node, prop);
		}


	for_each_child(node, child)
	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;
	bool error = false;
	int i;
	int i;


@@ -156,7 +124,7 @@ static bool run_check(struct check *c, struct node *dt)


	for (i = 0; i < c->num_prereqs; i++) {
	for (i = 0; i < c->num_prereqs; i++) {
		struct check *prq = c->prereq[i];
		struct check *prq = c->prereq[i];
		error = error || run_check(prq, dt);
		error = error || run_check(prq, dti);
		if (prq->status != PASSED) {
		if (prq->status != PASSED) {
			c->status = PREREQ;
			c->status = PREREQ;
			check_msg(c, "Failed prerequisite '%s'",
			check_msg(c, "Failed prerequisite '%s'",
@@ -167,11 +135,8 @@ static bool run_check(struct check *c, struct node *dt)
	if (c->status != UNCHECKED)
	if (c->status != UNCHECKED)
		goto out;
		goto out;


	if (c->node_fn || c->prop_fn)
	check_nodes_props(c, dti, dt);
		check_nodes_props(c, dt, dt);


	if (c->tree_fn)
		c->tree_fn(c, dt);
	if (c->status == UNCHECKED)
	if (c->status == UNCHECKED)
		c->status = PASSED;
		c->status = PASSED;


@@ -189,13 +154,14 @@ static bool run_check(struct check *c, struct node *dt)
 */
 */


/* A check which always fails, for testing purposes only */
/* 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, "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 node *node)
{
{
	struct property *prop;
	struct property *prop;
@@ -210,11 +176,11 @@ static void check_is_string(struct check *c, struct node *root,
		     propname, node->fullpath);
		     propname, node->fullpath);
}
}
#define WARNING_IF_NOT_STRING(nm, propname) \
#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) \
#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_cell(struct check *c, struct node *root,
static void check_is_cell(struct check *c, struct dt_info *dti,
			  struct node *node)
			  struct node *node)
{
{
	struct property *prop;
	struct property *prop;
@@ -229,15 +195,15 @@ static void check_is_cell(struct check *c, struct node *root,
		     propname, node->fullpath);
		     propname, node->fullpath);
}
}
#define WARNING_IF_NOT_CELL(nm, propname) \
#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) \
#define ERROR_IF_NOT_CELL(nm, propname) \
	ERROR(nm, NULL, check_is_cell, NULL, (propname))
	ERROR(nm, check_is_cell, (propname))


/*
/*
 * Structural check functions
 * 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 *node)
{
{
	struct node *child, *child2;
	struct node *child, *child2;
@@ -250,9 +216,9 @@ static void check_duplicate_node_names(struct check *c, struct node *dt,
				FAIL(c, "Duplicate node name %s",
				FAIL(c, "Duplicate node name %s",
				     child->fullpath);
				     child->fullpath);
}
}
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 node *node)
{
{
	struct property *prop, *prop2;
	struct property *prop, *prop2;
@@ -267,14 +233,14 @@ static void check_duplicate_property_names(struct check *c, struct node *dt,
		}
		}
	}
	}
}
}
NODE_ERROR(duplicate_property_names, NULL);
ERROR(duplicate_property_names, check_duplicate_property_names, NULL);


#define LOWERCASE	"abcdefghijklmnopqrstuvwxyz"
#define LOWERCASE	"abcdefghijklmnopqrstuvwxyz"
#define UPPERCASE	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define UPPERCASE	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define DIGITS		"0123456789"
#define DIGITS		"0123456789"
#define PROPNODECHARS	LOWERCASE UPPERCASE DIGITS ",._+*#?-"
#define PROPNODECHARS	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)
				  struct node *node)
{
{
	int n = strspn(node->name, c->data);
	int n = strspn(node->name, c->data);
@@ -283,18 +249,18 @@ static void check_node_name_chars(struct check *c, struct node *dt,
		FAIL(c, "Bad character '%c' in node %s",
		FAIL(c, "Bad character '%c' in node %s",
		     node->name[n], node->fullpath);
		     node->name[n], node->fullpath);
}
}
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_format(struct check *c, struct dt_info *dti,
				   struct node *node)
				   struct node *node)
{
{
	if (strchr(get_unitname(node), '@'))
	if (strchr(get_unitname(node), '@'))
		FAIL(c, "Node %s has multiple '@' characters in name",
		FAIL(c, "Node %s has multiple '@' characters in name",
		     node->fullpath);
		     node->fullpath);
}
}
NODE_ERROR(node_name_format, NULL, &node_name_chars);
ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars);


static void check_unit_address_vs_reg(struct check *c, struct node *dt,
static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti,
				      struct node *node)
				      struct node *node)
{
{
	const char *unitname = get_unitname(node);
	const char *unitname = get_unitname(node);
@@ -316,18 +282,22 @@ static void check_unit_address_vs_reg(struct check *c, struct node *dt,
			    node->fullpath);
			    node->fullpath);
	}
	}
}
}
NODE_WARNING(unit_address_vs_reg, NULL);
WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL);


static void check_property_name_chars(struct check *c, struct node *dt,
static void check_property_name_chars(struct check *c, struct dt_info *dti,
				      struct node *node, struct property *prop)
				      struct node *node)
{
{
	struct property *prop;

	for_each_property(node, prop) {
		int n = strspn(prop->name, c->data);
		int n = strspn(prop->name, c->data);


		if (n < strlen(prop->name))
		if (n < strlen(prop->name))
			FAIL(c, "Bad character '%c' in property name \"%s\", node %s",
			FAIL(c, "Bad character '%c' in property name \"%s\", node %s",
			     prop->name[n], prop->name, node->fullpath);
			     prop->name[n], prop->name, node->fullpath);
	}
	}
PROP_ERROR(property_name_chars, PROPNODECHARS);
}
ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS);


#define DESCLABEL_FMT	"%s%s%s%s%s"
#define DESCLABEL_FMT	"%s%s%s%s%s"
#define DESCLABEL_ARGS(node,prop,mark)		\
#define DESCLABEL_ARGS(node,prop,mark)		\
@@ -336,10 +306,11 @@ PROP_ERROR(property_name_chars, PROPNODECHARS);
	((prop) ? (prop)->name : ""), \
	((prop) ? (prop)->name : ""), \
	((prop) ? "' in " : ""), (node)->fullpath
	((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,
				  const char *label, struct node *node,
				  struct property *prop, struct marker *mark)
				  struct property *prop, struct marker *mark)
{
{
	struct node *dt = dti->dt;
	struct node *othernode = NULL;
	struct node *othernode = NULL;
	struct property *otherprop = NULL;
	struct property *otherprop = NULL;
	struct marker *othermark = NULL;
	struct marker *othermark = NULL;
@@ -362,44 +333,43 @@ static void check_duplicate_label(struct check *c, struct node *dt,
		     DESCLABEL_ARGS(othernode, otherprop, othermark));
		     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 node *node)
{
{
	struct label *l;
	struct label *l;
	struct property *prop;


	for_each_label(node->labels, l)
	for_each_label(node->labels, l)
		check_duplicate_label(c, dt, l->label, node, NULL, NULL);
		check_duplicate_label(c, dti, l->label, node, NULL, NULL);
}

static void check_duplicate_label_prop(struct check *c, struct node *dt,
	for_each_property(node, prop) {
				       struct node *node, struct property *prop)
{
		struct marker *m = prop->val.markers;
		struct marker *m = prop->val.markers;
	struct label *l;


		for_each_label(prop->labels, l)
		for_each_label(prop->labels, l)
		check_duplicate_label(c, dt, l->label, node, prop, NULL);
			check_duplicate_label(c, dti, l->label, node, prop, NULL);


		for_each_marker_of_type(m, LABEL)
		for_each_marker_of_type(m, LABEL)
		check_duplicate_label(c, dt, m->ref, node, prop, m);
			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,
static cell_t check_phandle_prop(struct check *c, struct dt_info *dti,
				    struct node *node, struct property *prop)
				 struct node *node, const char *propname)
{
{
	struct node *root = dti->dt;
	struct property *prop;
	struct marker *m;
	struct marker *m;
	struct node *other;
	cell_t phandle;
	cell_t phandle;


	if (!streq(prop->name, "phandle")
	prop = get_property(node, propname);
	    && !streq(prop->name, "linux,phandle"))
	if (!prop)
		return;
		return 0;


	if (prop->val.len != sizeof(cell_t)) {
	if (prop->val.len != sizeof(cell_t)) {
		FAIL(c, "%s has bad length (%d) %s property",
		FAIL(c, "%s has bad length (%d) %s property",
		     node->fullpath, prop->val.len, prop->name);
		     node->fullpath, prop->val.len, prop->name);
		return;
		return 0;
	}
	}


	m = prop->val.markers;
	m = prop->val.markers;
@@ -411,14 +381,13 @@ static void check_explicit_phandles(struct check *c, struct node *root,
			 * by construction. */ {
			 * by construction. */ {
			FAIL(c, "%s in %s is a reference to another node",
			FAIL(c, "%s in %s is a reference to another node",
			     prop->name, node->fullpath);
			     prop->name, node->fullpath);
			return;
		}
		}
		/* But setting this node's phandle equal to its own
		/* But setting this node's phandle equal to its own
		 * phandle is allowed - that means allocate a unique
		 * phandle is allowed - that means allocate a unique
		 * phandle for this node, even if it's not otherwise
		 * phandle for this node, even if it's not otherwise
		 * referenced.  The value will be filled in later, so
		 * referenced.  The value will be filled in later, so
		 * no further checking for now. */
		 * we treat it as having no phandle data for now. */
		return;
		return 0;
	}
	}


	phandle = propval_cell(prop);
	phandle = propval_cell(prop);
@@ -426,12 +395,36 @@ static void check_explicit_phandles(struct check *c, struct node *root,
	if ((phandle == 0) || (phandle == -1)) {
	if ((phandle == 0) || (phandle == -1)) {
		FAIL(c, "%s has bad value (0x%x) in %s property",
		FAIL(c, "%s has bad value (0x%x) in %s property",
		     node->fullpath, phandle, prop->name);
		     node->fullpath, phandle, prop->name);
		return;
		return 0;
	}

	return phandle;
}
}


	if (node->phandle && (node->phandle != phandle))
static void check_explicit_phandles(struct check *c, struct dt_info *dti,
		FAIL(c, "%s has %s property which replaces existing phandle information",
				    struct node *node)
		     node->fullpath, prop->name);
{
	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, "%s has mismatching 'phandle' and 'linux,phandle'"
		     " properties", node->fullpath);

	if (linux_phandle && !phandle)
		phandle = linux_phandle;


	other = get_node_by_phandle(root, phandle);
	other = get_node_by_phandle(root, phandle);
	if (other && (other != node)) {
	if (other && (other != node)) {
@@ -442,9 +435,9 @@ static void check_explicit_phandles(struct check *c, struct node *root,


	node->phandle = phandle;
	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 node *node)
{
{
	struct property **pp, *prop = NULL;
	struct property **pp, *prop = NULL;
@@ -472,15 +465,19 @@ static void check_name_properties(struct check *c, struct node *root,
	}
	}
}
}
ERROR_IF_NOT_STRING(name_is_string, "name");
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
 * Reference fixup functions
 */
 */


static void fixup_phandle_references(struct check *c, struct node *dt,
static void fixup_phandle_references(struct check *c, struct dt_info *dti,
				     struct node *node, struct property *prop)
				     struct node *node)
{
{
	struct node *dt = dti->dt;
	struct property *prop;

	for_each_property(node, prop) {
		struct marker *m = prop->val.markers;
		struct marker *m = prop->val.markers;
		struct node *refnode;
		struct node *refnode;
		cell_t phandle;
		cell_t phandle;
@@ -490,8 +487,12 @@ static void fixup_phandle_references(struct check *c, struct node *dt,


			refnode = get_node_by_ref(dt, m->ref);
			refnode = get_node_by_ref(dt, m->ref);
			if (! refnode) {
			if (! refnode) {
			FAIL(c, "Reference to non-existent node or label \"%s\"\n",
				if (!(dti->dtsflags & DTSF_PLUGIN))
			     m->ref);
					FAIL(c, "Reference to non-existent node or "
							"label \"%s\"\n", m->ref);
				else /* mark the entry as unresolved */
					*((cell_t *)(prop->val.val + m->offset)) =
						cpu_to_fdt32(0xffffffff);
				continue;
				continue;
			}
			}


@@ -499,12 +500,17 @@ static void fixup_phandle_references(struct check *c, struct node *dt,
			*((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
			*((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);
      &duplicate_node_names, &explicit_phandles);


static void fixup_path_references(struct check *c, struct node *dt,
static void fixup_path_references(struct check *c, struct dt_info *dti,
				  struct node *node, struct property *prop)
				  struct node *node)
{
{
	struct node *dt = dti->dt;
	struct property *prop;

	for_each_property(node, prop) {
		struct marker *m = prop->val.markers;
		struct marker *m = prop->val.markers;
		struct node *refnode;
		struct node *refnode;
		char *path;
		char *path;
@@ -524,8 +530,8 @@ static void fixup_path_references(struct check *c, struct node *dt,
							  strlen(path) + 1);
							  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
 * Semantic checks
@@ -538,7 +544,7 @@ WARNING_IF_NOT_STRING(device_type_is_string, "device_type");
WARNING_IF_NOT_STRING(model_is_string, "model");
WARNING_IF_NOT_STRING(model_is_string, "model");
WARNING_IF_NOT_STRING(status_is_string, "status");
WARNING_IF_NOT_STRING(status_is_string, "status");


static void fixup_addr_size_cells(struct check *c, struct node *dt,
static void fixup_addr_size_cells(struct check *c, struct dt_info *dti,
				  struct node *node)
				  struct node *node)
{
{
	struct property *prop;
	struct property *prop;
@@ -554,7 +560,7 @@ static void fixup_addr_size_cells(struct check *c, struct node *dt,
	if (prop)
	if (prop)
		node->size_cells = propval_cell(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);
	&address_cells_is_cell, &size_cells_is_cell);


#define node_addr_cells(n) \
#define node_addr_cells(n) \
@@ -562,7 +568,7 @@ WARNING(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL,
#define node_size_cells(n) \
#define node_size_cells(n) \
	(((n)->size_cells == -1) ? 1 : (n)->size_cells)
	(((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 node *node)
{
{
	struct property *prop;
	struct property *prop;
@@ -589,9 +595,9 @@ static void check_reg_format(struct check *c, struct node *dt,
		     "(#address-cells == %d, #size-cells == %d)",
		     "(#address-cells == %d, #size-cells == %d)",
		     node->fullpath, prop->val.len, addr_cells, size_cells);
		     node->fullpath, 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 node *node)
{
{
	struct property *prop;
	struct property *prop;
@@ -630,12 +636,12 @@ static void check_ranges_format(struct check *c, struct node *dt,
		     p_addr_cells, c_addr_cells, c_size_cells);
		     p_addr_cells, c_addr_cells, c_size_cells);
	}
	}
}
}
NODE_WARNING(ranges_format, NULL, &addr_size_cells);
WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells);


/*
/*
 * Style checks
 * 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 node *node)
{
{
	struct property *reg, *ranges;
	struct property *reg, *ranges;
@@ -657,14 +663,21 @@ static void check_avoid_default_addr_size(struct check *c, struct node *dt,
		FAIL(c, "Relying on default #size-cells value for %s",
		FAIL(c, "Relying on default #size-cells value for %s",
		     node->fullpath);
		     node->fullpath);
}
}
NODE_WARNING(avoid_default_addr_size, NULL, &addr_size_cells);
WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL,
	&addr_size_cells);


static void check_obsolete_chosen_interrupt_controller(struct check *c,
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 node *chosen;
	struct property *prop;
	struct property *prop;


	if (node != dt)
		return;


	chosen = get_node_by_path(dt, "/chosen");
	chosen = get_node_by_path(dt, "/chosen");
	if (!chosen)
	if (!chosen)
		return;
		return;
@@ -674,7 +687,8 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c,
		FAIL(c, "/chosen has obsolete \"interrupt-controller\" "
		FAIL(c, "/chosen has obsolete \"interrupt-controller\" "
		     "property");
		     "property");
}
}
TREE_WARNING(obsolete_chosen_interrupt_controller, NULL);
WARNING(obsolete_chosen_interrupt_controller,
	check_obsolete_chosen_interrupt_controller, NULL);


static struct check *check_table[] = {
static struct check *check_table[] = {
	&duplicate_node_names, &duplicate_property_names,
	&duplicate_node_names, &duplicate_property_names,
@@ -760,9 +774,8 @@ void parse_checks_option(bool warn, bool error, const char *arg)
	die("Unrecognized check name \"%s\"\n", name);
	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 i;
	int error = 0;
	int error = 0;


@@ -770,7 +783,7 @@ void process_checks(bool force, struct boot_info *bi)
		struct check *c = check_table[i];
		struct check *c = check_table[i];


		if (c->warn || c->error)
		if (c->warn || c->error)
			error = error || run_check(c, dt);
			error = error || run_check(c, dti);
	}
	}


	if (error) {
	if (error) {
+13 −8
Original line number Original line Diff line number Diff line
@@ -121,6 +121,11 @@ static void lexical_error(const char *fmt, ...);
			return DT_V1;
			return DT_V1;
		}
		}


<*>"/plugin/"	{
			DPRINT("Keyword: /plugin/\n");
			return DT_PLUGIN;
		}

<*>"/memreserve/"	{
<*>"/memreserve/"	{
			DPRINT("Keyword: /memreserve/\n");
			DPRINT("Keyword: /memreserve/\n");
			BEGIN_DEFAULT();
			BEGIN_DEFAULT();
@@ -184,16 +189,16 @@ static void lexical_error(const char *fmt, ...);
			if (d.len == 1) {
			if (d.len == 1) {
				lexical_error("Empty character literal");
				lexical_error("Empty character literal");
				yylval.integer = 0;
				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)
				if (d.len > 2)
					lexical_error("Character literal has %d"
					lexical_error("Character literal has %d"
						      " characters instead of 1",
						      " characters instead of 1",
						      d.len - 1);
						      d.len - 1);
			}


			data_free(d);
			return DT_CHAR_LITERAL;
			return DT_CHAR_LITERAL;
		}
		}


+331 −319

File changed.

Preview size limit exceeded, changes collapsed.

+392 −360

File changed.

Preview size limit exceeded, changes collapsed.

+29 −25
Original line number Original line Diff line number Diff line
/* 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
/* 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
   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
   it under the terms of the GNU General Public License as published by
@@ -46,35 +46,36 @@ extern int yydebug;
  enum yytokentype
  enum yytokentype
  {
  {
    DT_V1 = 258,
    DT_V1 = 258,
    DT_MEMRESERVE = 259,
    DT_PLUGIN = 259,
    DT_LSHIFT = 260,
    DT_MEMRESERVE = 260,
    DT_RSHIFT = 261,
    DT_LSHIFT = 261,
    DT_LE = 262,
    DT_RSHIFT = 262,
    DT_GE = 263,
    DT_LE = 263,
    DT_EQ = 264,
    DT_GE = 264,
    DT_NE = 265,
    DT_EQ = 265,
    DT_AND = 266,
    DT_NE = 266,
    DT_OR = 267,
    DT_AND = 267,
    DT_BITS = 268,
    DT_OR = 268,
    DT_DEL_PROP = 269,
    DT_BITS = 269,
    DT_DEL_NODE = 270,
    DT_DEL_PROP = 270,
    DT_PROPNODENAME = 271,
    DT_DEL_NODE = 271,
    DT_LITERAL = 272,
    DT_PROPNODENAME = 272,
    DT_CHAR_LITERAL = 273,
    DT_LITERAL = 273,
    DT_BYTE = 274,
    DT_CHAR_LITERAL = 274,
    DT_STRING = 275,
    DT_BYTE = 275,
    DT_LABEL = 276,
    DT_STRING = 276,
    DT_REF = 277,
    DT_LABEL = 277,
    DT_INCBIN = 278
    DT_REF = 278,
    DT_INCBIN = 279
  };
  };
#endif
#endif


/* Value type.  */
/* Value type.  */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE YYSTYPE;

union YYSTYPE
union YYSTYPE
{
{
#line 38 "dtc-parser.y" /* yacc.c:1909  */
#line 39 "dtc-parser.y" /* yacc.c:1909  */


	char *propnodename;
	char *propnodename;
	char *labelref;
	char *labelref;
@@ -92,9 +93,12 @@ union YYSTYPE
	struct node *nodelist;
	struct node *nodelist;
	struct reserve_info *re;
	struct reserve_info *re;
	uint64_t integer;
	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_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_DECLARED 1
#endif
#endif
Loading