[Crosstoolchain-logs] [device-tree-compiler] 03/357: Rudimentary phandle reference support.

Hector Oron zumbi at moszumanska.debian.org
Thu Dec 8 17:05:41 UTC 2016


This is an automated email from the git hooks/post-receive script.

zumbi pushed a commit to branch upstream/1.3.x
in repository device-tree-compiler.

commit 81f2e89c7551ef44a6203ab1cbb8228d09202572
Author: David Gibson <dgibson at sneetch.(none)>
Date:   Thu Jun 16 17:04:00 2005 +1000

    Rudimentary phandle reference support.
---
 data.c       | 34 +++++++++++++++++++++
 dtc-lexer.l  | 64 +++++++++++++++++----------------------
 dtc-parser.y |  4 +++
 dtc.h        | 15 +++++++++-
 flattree.c   |  2 +-
 livetree.c   | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 test.dts     | 11 ++++---
 7 files changed, 175 insertions(+), 52 deletions(-)

diff --git a/data.c b/data.c
index aef8c36..3c7de18 100644
--- a/data.c
+++ b/data.c
@@ -38,8 +38,25 @@ struct data data_ref_string(char *str)
 }
 #endif
 
+void fixup_free(struct fixup *f)
+{
+	free(f->ref);
+	free(f);
+}
+
 void data_free(struct data d)
 {
+	struct fixup *f;
+
+	f = d.refs;
+	while (f) {
+		struct fixup *nf;
+
+		nf = f->next;
+		fixup_free(f);
+		f = nf;
+	}
+
 	assert(!d.val || d.asize);
 
 	if (d.val)
@@ -65,6 +82,7 @@ struct data data_grow_for(struct data d, int xlen)
 	nd.asize = newsize;
 	nd.val = xrealloc(d.val, newsize);
 	nd.len = d.len;
+	nd.refs = d.refs;
 
 	assert(nd.asize >= (d.len + xlen));
 
@@ -231,6 +249,22 @@ struct data data_append_align(struct data d, int align)
 	return data_append_zeroes(d, newlen - d.len);
 }
 
+struct data data_add_fixup(struct data d, char *ref)
+{
+	struct fixup *f;
+	struct data nd;
+
+	f = xmalloc(sizeof(*f));
+	f->offset = d.len;
+	f->ref = ref;
+	f->next = d.refs;
+
+	nd = d;
+	nd.refs = f;
+
+	return nd;
+}
+
 int data_is_one_string(struct data d)
 {
 	int i;
diff --git a/dtc-lexer.l b/dtc-lexer.l
index 4819e54..58fe27c 100644
--- a/dtc-lexer.l
+++ b/dtc-lexer.l
@@ -27,6 +27,8 @@ PROPCHAR	[a-zA-Z0-9,._+*#?-]
 UNITCHAR	[0-9a-f,]
 WS		[ \t\n]
 
+REFCHAR		({PROPCHAR}|{UNITCHAR}|[/@])
+
 %%
 
 %{
@@ -34,14 +36,18 @@ WS		[ \t\n]
 
 #include "dtc-parser.tab.h"
 
-/*#define LEXDEBUG	1 */
+/*#define LEXDEBUG	1*/
+
+#ifdef LEXDEBUG
+#define DPRINT(fmt, ...)	fprintf(stderr, fmt, ##__VA_ARGS__)
+#else
+#define DPRINT(fmt, ...)	do { } while (0)
+#endif
 
 %}
 
 \"[^"]*\"	{
-#ifdef LEXDEBUG
-			fprintf(stderr, "String: %s\n", yytext);
-#endif
+			DPRINT("String: %s\n", yytext);
 			yylval.data = data_copy_escape_string(yytext+1,
 					yyleng-2);
 			return DT_STRING;
@@ -53,57 +59,49 @@ WS		[ \t\n]
 					"Cell value %s too long\n", yytext);
 			}
 			yylval.cval = strtol(yytext, NULL, 16);
-#ifdef LEXDEBUG
-			fprintf(stderr, "Cell: %x\n", yylval.cval);
-#endif
+			DPRINT("Cell: %x\n", yylval.cval);
 			return DT_CELL;
 		}
 
 <CELLDATA>">"	{
-#ifdef LEXDEBUG
-			fprintf(stderr, "/CELLDATA\n");
-#endif
+			DPRINT("/CELLDATA\n");
 			BEGIN(INITIAL);
 			return '>';
 		}
 
+<CELLDATA>\&{REFCHAR}*	{
+			DPRINT("Ref: %s\n", yytext+1);
+			yylval.str = strdup(yytext+1);
+			return DT_REF;
+		}
+
 <BYTESTRING>[0-9a-fA-F]{2} {
 			yylval.byte = strtol(yytext, NULL, 16);
-#ifdef LEXDEBUG
-			fprintf(stderr, "Byte: %02x\n", (int)yylval.byte);
-#endif
+			DPRINT("Byte: %02x\n", (int)yylval.byte);
 			return DT_BYTE;
 		}
 
 <BYTESTRING>"]"	{
-#ifdef LEXDEBUG
-			fprintf(stderr, "/BYTESTRING\n");
-#endif
+			DPRINT("/BYTESTRING\n");
 			BEGIN(INITIAL);
 			return ']';
 		}
 
 {PROPCHAR}+	{
-#ifdef LEXDEBUG
-			fprintf(stderr, "PropName: %s\n", yytext);
-#endif
+			DPRINT("PropName: %s\n", yytext);
 			yylval.str = strdup(yytext);
 			return DT_PROPNAME;
 		}
 
 {PROPCHAR}+(@{UNITCHAR}+)? {
-#ifdef LEXDEBUG
-			fprintf(stderr, "NodeName: %s\n", yytext);
-#endif
+			DPRINT("NodeName: %s\n", yytext);
 			yylval.str = strdup(yytext);
 			return DT_NODENAME;
 		}
 
 
 [a-zA-Z_][a-zA-Z0-9_]*:	{
-#ifdef LEXDEBUG
-			fprintf(stderr, "Label: %s\n", yytext);
-#endif
+			DPRINT("Label: %s\n", yytext);
 			yylval.str = strdup(yytext);
 			yylval.str[yyleng-1] = '\0';
 			return DT_LABEL;
@@ -112,10 +110,8 @@ WS		[ \t\n]
 <*>{WS}+	/* eat whitespace */
 
 <*>"/*"([^*]|\*+[^*/])*\*+"/"	{
-#ifdef LEXDEBUG
-			fprintf(stderr, "Comment: %s\n", yytext);
+			DPRINT("Comment: %s\n", yytext);
 			/* eat comments */
-#endif
 		}
 
 <*>"//".*\n	/* eat line comments */
@@ -123,23 +119,17 @@ WS		[ \t\n]
 .		{
 			switch (yytext[0]) {
 				case '<':
-#ifdef LEXDEBUG
-					fprintf(stderr, "CELLDATA\n");
-#endif
+					DPRINT("CELLDATA\n");
 					BEGIN(CELLDATA);
 					break;
 				case '[':
-#ifdef LEXDEBUG
-					fprintf(stderr, "BYTESTRING\n");
-#endif
+					DPRINT("BYTESTRING\n");
 					BEGIN(BYTESTRING);
 					break;
 				default:
 
-#ifdef LEXDEBUG
-			fprintf(stderr, "Char: %c (\\x%02x)\n", yytext[0],
+			DPRINT("Char: %c (\\x%02x)\n", yytext[0],
 				(unsigned)yytext[0]);
-#endif
 					break;
 			}
 
diff --git a/dtc-parser.y b/dtc-parser.y
index 785acd1..ade5dea 100644
--- a/dtc-parser.y
+++ b/dtc-parser.y
@@ -48,6 +48,7 @@ extern struct node *device_tree;
 %token <data> DT_STRING
 %token <str> DT_UNIT
 %token <str> DT_LABEL
+%token <str> DT_REF
 
 %type <data> propdata
 %type <data> celllist
@@ -97,6 +98,9 @@ propdata:	DT_STRING { $$ = $1; }
 	;
 
 celllist:	celllist DT_CELL { $$ = data_append_cell($1, $2); }
+	|	celllist DT_REF	{
+			$$ = data_append_cell(data_add_fixup($1, $2), -1);
+		}
 	|	/* empty */ { $$ = empty_data; }
 	;
 
diff --git a/dtc.h b/dtc.h
index cbd5eb7..0a190d8 100644
--- a/dtc.h
+++ b/dtc.h
@@ -76,18 +76,29 @@ typedef u32 cell_t;
 
 
 #define streq(a, b)	(strcmp((a), (b)) == 0)
+#define strneq(a, b, n)	(strncmp((a), (b), (n)) == 0)
+
 #define ALIGN(x, a)	(((x) + (a) - 1) & ~((a) - 1))
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
 /* Data blobs */
+struct fixup {
+	int offset;
+	char *ref;
+	struct fixup *next;
+};
+
 struct data {
 	int len;
 	char *val;
 	int asize;
+	struct fixup *refs;
 };
 
-#define empty_data ((struct data){.len = 0, .val = NULL, .asize = 0})
+#define empty_data \
+	((struct data){.len = 0, .val = NULL, .asize = 0, .refs = NULL})
 
+void fixup_free(struct fixup *f);
 void data_free(struct data d);
 
 struct data data_grow_for(struct data d, int xlen);
@@ -102,6 +113,8 @@ struct data data_append_byte(struct data d, uint8_t byte);
 struct data data_append_zeroes(struct data d, int len);
 struct data data_append_align(struct data d, int align);
 
+struct data data_add_fixup(struct data d, char *ref);
+
 int data_is_one_string(struct data d);
 
 /* DT constraints */
diff --git a/flattree.c b/flattree.c
index f5b7ca1..28427ab 100644
--- a/flattree.c
+++ b/flattree.c
@@ -598,7 +598,7 @@ static char *nodename_from_path(char *ppath, char *cpath)
 	if ((plen == 0) && streq(ppath, "/"))
 		return strdup(lslash+1);
 
-	if (strncmp(ppath, cpath, plen) != 0)
+	if (! strneq(ppath, cpath, plen))
 		return NULL;
 	
 	return strdup(lslash+1);
diff --git a/livetree.c b/livetree.c
index 04f5228..93387c4 100644
--- a/livetree.c
+++ b/livetree.c
@@ -43,9 +43,7 @@ struct property *build_empty_property(char *name, char *label)
 	struct property *new = xmalloc(sizeof(*new));
 
 	new->name = name;
-	new->val.len = 0;
-	new->val.val = NULL;
-
+	new->val = empty_data;
 	new->next = NULL;
 
 	new->label = label;
@@ -141,8 +139,30 @@ static struct node *get_subnode(struct node *node, char *nodename)
 {
 	struct node *child;
 
-	for_each_child(node, child) {
-		if (strcmp(child->name, nodename) == 0)
+	for_each_child(node, child)
+		if (streq(child->name, nodename))
+			return child;
+
+	return NULL;
+}
+
+static struct node *get_node_by_path(struct node *tree, char *path)
+{
+	char *p;
+	struct node *child;
+
+	if (!path || ! (*path))
+		return tree;
+
+	while (path[0] == '/')
+		path++;
+
+	p = strchr(path, '/');
+
+	for_each_child(tree, child) {
+		if (p && strneq(path, child->name, p-path))
+			return get_node_by_path(child, p+1);
+		else if (!p && streq(path, child->name))
 			return child;
 	}
 
@@ -209,7 +229,7 @@ static int must_be_string(struct property *prop, struct node *node)
 static int name_prop_check(struct property *prop, struct node *node)
 {
 	if ((prop->val.len != node->basenamelen+1)
-	    || (strncmp(prop->val.val, node->name, node->basenamelen) != 0)) {
+	    || !strneq(prop->val.val, node->name, node->basenamelen)) {
 		ERRMSG("name property \"%s\" does not match node basename in %s\n",
 		       prop->val.val,
 		       node->fullpath);
@@ -469,7 +489,7 @@ static int check_memory(struct node *root)
 	int ok = 1;
 
 	for_each_child(root, mem) {
-		if (strncmp(mem->name, "memory", mem->basenamelen) != 0)
+		if (! strneq(mem->name, "memory", mem->basenamelen))
 			continue;
 
 		nnodes++;
@@ -573,6 +593,67 @@ static int check_phandles(struct node *root, struct node *node)
 	return 1;
 }
 
+static cell_t get_node_phandle(struct node *root, struct node *node)
+{
+	static cell_t phandle = 1; /* FIXME: ick, static local */
+
+	fprintf(stderr, "get_node_phandle(%s)   phandle=%x\n",
+		node->fullpath, node->phandle);
+
+	if ((node->phandle != 0) && (node->phandle != -1))
+		return node->phandle;
+
+	assert(! get_property(node, "linux,phandle"));
+
+	while (get_node_by_phandle(root, phandle))
+		phandle++;
+
+	node->phandle = phandle;
+	add_property(node,
+		     build_property("linux,phandle",
+				    data_append_cell(empty_data, phandle),
+				    NULL));
+
+	return node->phandle;
+}
+
+static void apply_fixup(struct node *root, struct property *prop,
+			struct fixup *f)
+{
+	struct node *refnode;
+	cell_t phandle;
+
+	refnode = get_node_by_path(root, f->ref);
+	if (! refnode)
+		die("Reference to non-existent node \"%s\"\n", f->ref);
+
+	phandle = get_node_phandle(root, refnode);
+
+	assert(f->offset + sizeof(cell_t) <= prop->val.len);
+
+	*((cell_t *)(prop->val.val + f->offset)) = cpu_to_be32(phandle);
+}
+
+static void fixup_phandles(struct node *root, struct node *node)
+{
+	struct property *prop;
+	struct node *child;
+
+	for_each_property(node, prop) {
+		struct fixup *f = prop->val.refs;
+
+		while (f) {
+			apply_fixup(root, prop, f);
+			prop->val.refs = f->next;
+			fixup_free(f);
+			f = prop->val.refs;
+		}
+	}
+
+	for_each_child(node, child)
+		fixup_phandles(root, child);
+}
+
 int check_device_tree(struct node *dt)
 {
 	int ok = 1;
@@ -583,6 +664,8 @@ int check_device_tree(struct node *dt)
 	ok = ok && check_addr_size_reg(dt, -1, -1);
 	ok = ok && check_phandles(dt, dt);
 
+	fixup_phandles(dt, dt);
+
 	if (! ok)
 		return 0;
 
diff --git a/test.dts b/test.dts
index dce7c52..e89632c 100644
--- a/test.dts
+++ b/test.dts
@@ -2,19 +2,19 @@
 	model = "MyBoardName";
 	compatible = "MyBoardFamilyName";
 	#address-cells = <2>;
-	label1: #size-cells = <2>;
+	#size-cells = <2>;
 
-	label2: cpus {
+	cpus {
 		linux,phandle = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		PowerPC,970 at 0 {
+			linux,phandle = <3>;
 			name = "PowerPC,970";
 			device_type = "cpu";
 			reg = <0>;
 			clock-frequency = <5f5e1000>;
 			linux,boot-cpu;
-			linux,phandle = <2>;
 			i-cache-size = <10000>;
 			d-cache-size = <8000>;
 		};
@@ -24,18 +24,17 @@
 	randomnode {
 		string = "\xff\0stuffstuff\t\t\t\n\n\n";
 		blob = [0a 0b 0c 0d de ea ad be ef];
+		ref = < &/memory at 0 >;
 	};
 
 	memory at 0 {
 		device_type = "memory";
-		reg = <00000000 00000000 00000000 20000000>;
-		linux,phandle = <3>;
+		memreg: reg = <00000000 00000000 00000000 20000000>;
 	};
 
 	chosen {
 		bootargs = "root=/dev/sda2";
 		linux,platform = <00000600>;
-		linux,phandle = <4>;
 	};
 
 };

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/crosstoolchain/device-tree-compiler.git



More information about the Crosstoolchain-logs mailing list