[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