devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Benoit Cousson <bcousson-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
To: olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	tomasz.figa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
	swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org,
	grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org,
	rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org
Cc: khilman-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
	linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	fparent-rdvid1DuHRBWk0Htik3J/w@public.gmane.org,
	Benoit Cousson <bcousson-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
Subject: [RFC 03/15] scripts/dtc: validate each nodes and properties
Date: Tue, 24 Sep 2013 18:52:09 +0200	[thread overview]
Message-ID: <1380041541-17529-4-git-send-email-bcousson@baylibre.com> (raw)
In-Reply-To: <1380041541-17529-1-git-send-email-bcousson-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>

From: Fabien Parent <fparent-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>

Add support to navigate through the device tree and try to validate each node
which has an associated schema in the schema index. So far, only the framework
is added and no validation is really done yet.

Signed-off-by: Fabien Parent <fparent-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
Signed-off-by: Benoit Cousson <bcousson-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
---
 scripts/dtc/schema.c | 234 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 233 insertions(+), 1 deletion(-)

diff --git a/scripts/dtc/schema.c b/scripts/dtc/schema.c
index dd134d6..a797821 100644
--- a/scripts/dtc/schema.c
+++ b/scripts/dtc/schema.c
@@ -9,9 +9,21 @@ static const char *const SCHEMA_EXT = ".schema";
 static const char *const VALUE_PROPNAME = "value";
 static int exit_on_failure = 0;
 
+struct node_list {
+	struct node *n;
+	struct node_list *next;
+};
+
+struct prop_constraints {
+	const char *name;
+};
+
 struct node_constraints {
 	pcre *re_compat;
 	char *filepath;
+	struct boot_info *bi;
+	struct node *dt;
+
 	const char *compatible;
 };
 
@@ -54,6 +66,34 @@ static int get_next_string_offset(struct property *p, int offset)
 	return -1;
 }
 
+static struct property *get_property_matching_pattern(struct property **list,
+						      const char *pattern)
+{
+	struct property *p;
+	pcre *re;
+	int is_matching;
+
+	assert(list);
+	assert(pattern);
+
+	re = compile_pattern(pattern);
+	if (!re)
+		die("Invalid pattern: %s\n", pattern);
+
+	for (p = *list; p; p = p->next) {
+		assert(p->name);
+		is_matching = pcre_exec(re, 0, p->name, strlen(p->name),
+					0, 0, NULL, 0) >= 0;
+		if (is_matching) {
+			*list = p->next;
+			break;
+		}
+	}
+
+	pcre_free(re);
+	return p;
+}
+
 static int is_prop_value(const char *p)
 {
 	int is_value = 1;
@@ -70,12 +110,203 @@ static int is_prop_value(const char *p)
 
 /** Schema Validation */
 
+static void free_property_constraints(struct prop_constraints *pc)
+{
+	if (!pc)
+		return;
+
+	free(pc);
+}
+
+static struct prop_constraints*
+load_property_constraints(struct node *schema)
+{
+	struct property *p;
+	struct prop_constraints *pc;
+
+	assert(schema);
+
+	pc = xmalloc(sizeof(*pc));
+	memset(pc, 0, sizeof(*pc));
+
+	p = get_property(schema, "name");
+	if (p)
+		pc->name = p->val.val;
+
+	return pc;
+}
+
+static int validate_properties(struct node *n,
+			       struct node *schema,
+			       struct node_list *path);
+
+static int validate_property(struct node *n,
+			     struct property *p,
+			     struct prop_constraints *pc,
+			     struct node *schema,
+			     struct node_list *path)
+{
+	int ret = 1;
+
+	assert(n);
+	assert(schema);
+	assert(pc);
+	assert(path);
+
+	free_property_constraints(pc);
+	return ret;
+}
+
+static int validate_properties(struct node *n,
+			       struct node *schema,
+			       struct node_list *path)
+{
+	struct property *p;
+	struct property *iter;
+	struct prop_constraints *pc;
+	int ret = 1;
+
+	assert(n);
+	assert(schema);
+	assert(path);
+
+	pc = load_property_constraints(schema);
+	assert(pc);
+
+	iter = n->proplist;
+	p = get_property_matching_pattern(&iter, pc->name ?: schema->name);
+	ret &= validate_property(n, p, pc, schema, path);
+
+	/* if other properties match the pattern */
+	while (iter && p) {
+		p = get_property_matching_pattern(&iter, schema->name);
+		if (p)
+			ret &= validate_property(n, p, pc, schema, path);
+		else
+			break;
+	}
+
+	return ret;
+}
+
+static int validate_node(struct node *n,
+			 struct node_constraints *nc,
+			 struct node_list *path)
+{
+	struct node *iter;
+	int ret = 1;
+
+	assert(n);
+	assert(path);
+	assert(nc);
+	assert(nc->dt);
+
+	for (iter = nc->dt->children; iter; iter = iter->next_sibling)
+		ret &= validate_properties(n, iter, path);
+
+	return ret;
+}
+
+static struct node_constraints *get_node_constraints_of(struct schema_db *db,
+							const char *compat,
+							int *i)
+{
+	int has_match;
+	struct node_constraints *n;
+
+	assert(db);
+	assert(compat);
+	assert(i);
+
+	for (; *i < db->size; (*i)++) {
+		n = &db->buffer[*i];
+
+		has_match = pcre_exec(n->re_compat, 0, compat,
+				      strlen(compat), 0, 0, NULL, 0) >= 0;
+		if (!has_match)
+			continue;
+
+		if (!n->bi) {
+			n->bi = dt_from_source(n->filepath);
+			n->dt = n->bi->dt;
+		}
+		(*i)++;
+		return n;
+	}
+
+	return NULL;
+}
+
+static int for_each_compatible_validate(struct schema_db *db,
+					struct property *p,
+					struct node *node,
+					struct node_list *path)
+{
+	struct node_constraints *nc;
+	int i;
+	int offset = 0;
+	int ret = 1;
+
+	assert(db);
+	assert(node);
+	assert(p);
+
+	while (offset >= 0 && offset < p->val.len) {
+		i = 0;
+		while ((nc = get_node_constraints_of(db, p->val.val + offset,
+						     &i)) != NULL) {
+			ret &= validate_node(node, nc, path);
+		}
+
+		offset = get_next_string_offset(p, offset);
+	}
+
+	return ret;
+}
+
+static int validate_nodes(struct schema_db *db,
+			  struct node *n,
+			  struct node_list *path)
+{
+	struct property *p;
+	struct node *iter;
+	struct node_list *head_path = NULL;
+	int ret = 1;
+
+	assert(db);
+
+	if (!n)
+		return ret;
+
+	head_path = xmalloc(sizeof(*iter));
+	head_path->next = path;
+
+	for (iter = n; iter; iter = iter->next_sibling) {
+		/* Build the path to this node */
+		head_path->n = iter;
+
+		/* Validate children nodes */
+		ret &= validate_nodes(db, iter->children, head_path);
+
+		p = get_property(iter, "compatible");
+		if (!p)
+			continue;
+
+		/* Validate node */
+		ret &= for_each_compatible_validate(db, p, iter, head_path);
+	}
+
+	free(head_path);
+	return ret;
+}
+
 int validate_dt(struct schema_db *db, struct boot_info *bi)
 {
 	assert(bi);
+	assert(bi->dt);
 	assert(db);
 
-	return 1;
+	return validate_nodes(db, bi->dt, NULL);
 }
 
 void exit_on_schema_validation_failure(int exit)
@@ -270,6 +501,7 @@ static void free_node_constraints(struct node_constraints *nc)
 		return;
 
 	pcre_free(nc->re_compat);
+	free_dt(nc->bi);
 	free(nc->filepath);
 }
 
-- 
1.8.1.2

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  parent reply	other threads:[~2013-09-24 16:52 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-24 16:52 [RFC 00/15] Device Tree schemas and validation Benoit Cousson
2013-09-24 16:52 ` [RFC 01/15] scripts/dtc: fix most memory leaks in dtc Benoit Cousson
     [not found]   ` <1380041541-17529-2-git-send-email-bcousson-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
2013-10-02 12:59     ` David Gibson
     [not found]       ` <CAOwMV_zAZG3vvWS6pkyK-FbOEg_32KRO-k1SmFSh-pc9+0JiPA@mail.gmail.com>
2013-10-03 14:26         ` Fabien Parent
2013-09-24 16:52 ` [RFC 04/15] scripts/dtc: add procedure to handle dts errors Benoit Cousson
2013-09-24 16:52 ` [RFC 05/15] scripts/dtc: check type on properties Benoit Cousson
2013-09-24 16:52 ` [RFC 07/15] scripts/dtc: can inherit properties Benoit Cousson
     [not found] ` <1380041541-17529-1-git-send-email-bcousson-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
2013-09-24 16:52   ` [RFC 02/15] scripts/dtc: build schema index for dts validation Benoit Cousson
2013-09-24 16:52   ` Benoit Cousson [this message]
2013-09-24 16:52   ` [RFC 06/15] scripts/dtc: check for required properties Benoit Cousson
2013-09-24 16:52   ` [RFC 08/15] scripts/dtc: check array size Benoit Cousson
2013-09-24 16:52   ` [RFC 09/15] scripts/dtc: check value of properties Benoit Cousson
2013-09-24 16:52   ` [RFC 10/15] scripts/dtc: add count limit on nodes Benoit Cousson
2013-10-01 22:22   ` [RFC 00/15] Device Tree schemas and validation Stephen Warren
     [not found]     ` <524B4B20.4020002-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-10-02 14:29       ` David Gibson
     [not found]         ` <20131002142914.GI6506-RXTfZT5YzpxwFLYp8hBm2A@public.gmane.org>
2013-10-03 13:53           ` Benoit Cousson
2013-10-06  3:02             ` Chaiken, Alison
2013-10-03 13:17     ` Benoit Cousson
2013-09-24 16:52 ` [RFC 11/15] scripts/dtc: check for children nodes Benoit Cousson
2013-09-24 16:52 ` [RFC 12/15] scripts/dtc: check constraints on parents Benoit Cousson
2013-09-24 16:52 ` [RFC 13/15] bindings: OMAP: add new schema files Benoit Cousson
2013-09-24 16:52 ` [RFC 14/15] scripts/dtc: validate dts against schema bindings Benoit Cousson
2013-09-24 16:52 ` [RFC 15/15] scripts/dtc: add verbose options Benoit Cousson
2013-10-01  8:06 ` [RFC 00/15] Device Tree schemas and validation Benoit Cousson
     [not found]   ` <524A8289.3050107-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
2013-10-01 13:17     ` Rob Herring
     [not found]       ` <524ACB76.1010001-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2013-10-01 15:06         ` Benoit Cousson
2013-10-01 15:17           ` Jon Loeliger
2013-10-02  8:24             ` David Gibson
2013-10-02  9:25             ` Benoit Cousson
     [not found]               ` <524BE66D.7060308-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
2013-10-02 13:22                 ` Jon Loeliger
     [not found]           ` <524AE4FB.4080906-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
2013-10-01 20:54             ` Rob Herring
     [not found]               ` <CAL_JsqJ31TGFJCSeSOqgee=OLVfSUTAYdF4nSn7X2DiCequVAw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-10-02 13:54                 ` David Gibson
2013-10-02 18:08                   ` Mark Brown
2013-10-02 23:38                     ` David Gibson
2013-10-03  6:52                   ` Benoit Cousson
2013-10-02 13:52         ` David Gibson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1380041541-17529-4-git-send-email-bcousson@baylibre.com \
    --to=bcousson-rdvid1duhrbwk0htik3j/w@public.gmane.org \
    --cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=fparent-rdvid1DuHRBWk0Htik3J/w@public.gmane.org \
    --cc=grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org \
    --cc=khilman-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
    --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org \
    --cc=rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org \
    --cc=swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org \
    --cc=tomasz.figa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).