* dtc: Allow multiple labels on nodes and properties
@ 2010-02-24 1:03 David Gibson
2010-02-24 2:10 ` Grant Likely
2010-02-24 7:22 ` dtc: Allow multiple labels on nodes and properties (v2) David Gibson
0 siblings, 2 replies; 5+ messages in thread
From: David Gibson @ 2010-02-24 1:03 UTC (permalink / raw)
To: Jon Loeliger; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
At present, both the grammar and our internal data structures mean
that there can be only one label on a node, property or memreserve
entry. This is a fairly arbitrary constraint, given that any number
of value labels can appear at the same point, and that in C you can
have any number of labels on the same statement.
This is pretty much a non-issue now, but it may become important with
some of the extensions that Grant and I have in mind. It's not that
hard to change, so this patch does so, allowing an arbitrary number of
labels on any given node or property. As usual a testcase is added
too.
Signed-off-by: David Gibson <david-xT8FGy+AXnRB3Ne2BGzF6laj5H9X9Tb+@public.gmane.org>
Index: dtc/tests/multilabel.dts
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ dtc/tests/multilabel.dts 2010-02-23 21:22:00.392145072 +1100
@@ -0,0 +1,38 @@
+/dts-v1/;
+
+m1: mq: /memreserve/ 0 0x1000;
+
+/ {
+ p1: px: prop = "foo";
+
+ /* Explicit phandles */
+ n1: nx: node1 {
+ linux,phandle = <0x2000>;
+ ref = <&{/node2}>; /* reference precedes target */
+ lref = <&ny>;
+ };
+ ny: n2: node2 {
+ phandle = <0x1>;
+ ref = <&{/node1}>; /* reference after target */
+ lref = <&nx>;
+ };
+
+ /* Implicit phandles */
+ n3: node3 {
+ ref = <&{/node4}>;
+ lref = <&n4>;
+ };
+ n4: node4 {
+ };
+
+ /* Explicit phandle with implicit value */
+ /* This self-reference is the standard way to tag a node as requiring
+ * a phandle (perhaps for reference by nodes that will be dynamically
+ * added) without explicitly allocating it a phandle.
+ * The self-reference requires some special internal handling, though
+ * so check it actually works */
+ n5: nz: node5 {
+ linux,phandle = <&n5>;
+ phandle = <&nz>;
+ };
+};
Index: dtc/tests/run_tests.sh
===================================================================
--- dtc.orig/tests/run_tests.sh 2010-02-23 20:25:38.708956748 +1100
+++ dtc/tests/run_tests.sh 2010-02-23 20:26:12.371978082 +1100
@@ -222,6 +222,9 @@ dtc_tests () {
run_test phandle_format dtc_references.test.$f.dtb $f
done
+ run_dtc_test -I dts -O dtb -o multilabel.test.dtb multilabel.dts
+ run_test references multilabel.test.dtb
+
run_dtc_test -I dts -O dtb -o dtc_comments.test.dtb comments.dts
run_dtc_test -I dts -O dtb -o dtc_comments-cmp.test.dtb comments-cmp.dts
run_test dtbs_equal_ordered dtc_comments.test.dtb dtc_comments-cmp.test.dtb
Index: dtc/dtc-parser.y
===================================================================
--- dtc.orig/dtc-parser.y 2010-02-23 20:19:37.315975392 +1100
+++ dtc/dtc-parser.y 2010-02-23 21:27:31.104219098 +1100
@@ -78,7 +78,6 @@ static unsigned long long eval_literal(c
%type <node> nodedef
%type <node> subnode
%type <nodelist> subnodes
-%type <labelref> label
%%
@@ -102,9 +101,14 @@ memreserves:
;
memreserve:
- label DT_MEMRESERVE addr addr ';'
+ DT_MEMRESERVE addr addr ';'
{
- $$ = build_reserve_entry($3, $4, $1);
+ $$ = build_reserve_entry($2, $3);
+ }
+ | DT_LABEL memreserve
+ {
+ add_label(&$2->labels, $1);
+ $$ = $2;
}
;
@@ -118,7 +122,7 @@ addr:
devicetree:
'/' nodedef
{
- $$ = name_node($2, "", NULL);
+ $$ = name_node($2, "");
}
;
@@ -141,13 +145,18 @@ proplist:
;
propdef:
- label DT_PROPNODENAME '=' propdata ';'
+ DT_PROPNODENAME '=' propdata ';'
+ {
+ $$ = build_property($1, $3);
+ }
+ | DT_PROPNODENAME ';'
{
- $$ = build_property($2, $4, $1);
+ $$ = build_property($1, empty_data);
}
- | label DT_PROPNODENAME ';'
+ | DT_LABEL propdef
{
- $$ = build_property($2, empty_data, $1);
+ add_label(&$2->labels, $1);
+ $$ = $2;
}
;
@@ -264,7 +273,7 @@ subnodes:
{
$$ = NULL;
}
- | subnode subnodes
+ | subnode subnodes
{
$$ = chain_node($1, $2);
}
@@ -276,20 +285,14 @@ subnodes:
;
subnode:
- label DT_PROPNODENAME nodedef
+ DT_PROPNODENAME nodedef
{
- $$ = name_node($3, $2, $1);
+ $$ = name_node($2, $1);
}
- ;
-
-label:
- /* empty */
+ | DT_LABEL subnode
{
- $$ = NULL;
- }
- | DT_LABEL
- {
- $$ = $1;
+ add_label(&$2->labels, $1);
+ $$ = $2;
}
;
Index: dtc/dtc.h
===================================================================
--- dtc.orig/dtc.h 2010-02-23 20:19:37.287957166 +1100
+++ dtc/dtc.h 2010-02-23 21:26:04.067960304 +1100
@@ -125,13 +125,18 @@ int data_is_one_string(struct data d);
#define MAX_NODENAME_LEN 31
/* Live trees */
+struct label {
+ char *label;
+ struct label *next;
+};
+
struct property {
char *name;
struct data val;
struct property *next;
- char *label;
+ struct label *labels;
};
struct node {
@@ -148,21 +153,26 @@ struct node {
cell_t phandle;
int addr_cells, size_cells;
- char *label;
+ struct label *labels;
};
+#define for_each_label(l0, l) \
+ for ((l) = (l0); (l); (l) = (l)->next)
+
#define for_each_property(n, p) \
for ((p) = (n)->proplist; (p); (p) = (p)->next)
#define for_each_child(n, c) \
for ((c) = (n)->children; (c); (c) = (c)->next_sibling)
-struct property *build_property(char *name, struct data val, char *label);
+void add_label(struct label **labels, char *label);
+
+struct property *build_property(char *name, struct data val);
struct property *chain_property(struct property *first, struct property *list);
struct property *reverse_properties(struct property *first);
struct node *build_node(struct property *proplist, struct node *children);
-struct node *name_node(struct node *node, char *name, char *label);
+struct node *name_node(struct node *node, char *name);
struct node *chain_node(struct node *first, struct node *list);
void add_property(struct node *node, struct property *prop);
@@ -191,10 +201,10 @@ struct reserve_info {
struct reserve_info *next;
- char *label;
+ struct label *labels;
};
-struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len, char *label);
+struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len);
struct reserve_info *chain_reserve_entry(struct reserve_info *first,
struct reserve_info *list);
struct reserve_info *add_reserve_entry(struct reserve_info *list,
Index: dtc/flattree.c
===================================================================
--- dtc.orig/flattree.c 2010-02-23 20:19:37.327957222 +1100
+++ dtc/flattree.c 2010-02-23 21:22:38.223958196 +1100
@@ -52,9 +52,9 @@ struct emitter {
void (*string)(void *, char *, int);
void (*align)(void *, int);
void (*data)(void *, struct data);
- void (*beginnode)(void *, const char *);
- void (*endnode)(void *, const char *);
- void (*property)(void *, const char *);
+ void (*beginnode)(void *, struct label *labels);
+ void (*endnode)(void *, struct label *labels);
+ void (*property)(void *, struct label *labels);
};
static void bin_emit_cell(void *e, cell_t val)
@@ -89,17 +89,17 @@ static void bin_emit_data(void *e, struc
*dtbuf = data_append_data(*dtbuf, d.val, d.len);
}
-static void bin_emit_beginnode(void *e, const char *label)
+static void bin_emit_beginnode(void *e, struct label *labels)
{
bin_emit_cell(e, FDT_BEGIN_NODE);
}
-static void bin_emit_endnode(void *e, const char *label)
+static void bin_emit_endnode(void *e, struct label *labels)
{
bin_emit_cell(e, FDT_END_NODE);
}
-static void bin_emit_property(void *e, const char *label)
+static void bin_emit_property(void *e, struct label *labels)
{
bin_emit_cell(e, FDT_PROP);
}
@@ -191,37 +191,40 @@ static void asm_emit_data(void *e, struc
assert(off == d.len);
}
-static void asm_emit_beginnode(void *e, const char *label)
+static void asm_emit_beginnode(void *e, struct label *labels)
{
FILE *f = e;
+ struct label *l;
- if (label) {
- fprintf(f, "\t.globl\t%s\n", label);
- fprintf(f, "%s:\n", label);
+ for_each_label(labels, l) {
+ fprintf(f, "\t.globl\t%s\n", l->label);
+ fprintf(f, "%s:\n", l->label);
}
fprintf(f, "\t/* FDT_BEGIN_NODE */\n");
asm_emit_cell(e, FDT_BEGIN_NODE);
}
-static void asm_emit_endnode(void *e, const char *label)
+static void asm_emit_endnode(void *e, struct label *labels)
{
FILE *f = e;
+ struct label *l;
fprintf(f, "\t/* FDT_END_NODE */\n");
asm_emit_cell(e, FDT_END_NODE);
- if (label) {
- fprintf(f, "\t.globl\t%s_end\n", label);
- fprintf(f, "%s_end:\n", label);
+ for_each_label(labels, l) {
+ fprintf(f, "\t.globl\t%s_end\n", l->label);
+ fprintf(f, "%s_end:\n", l->label);
}
}
-static void asm_emit_property(void *e, const char *label)
+static void asm_emit_property(void *e, struct label *labels)
{
FILE *f = e;
+ struct label *l;
- if (label) {
- fprintf(f, "\t.globl\t%s\n", label);
- fprintf(f, "%s:\n", label);
+ for_each_label(labels, l) {
+ fprintf(f, "\t.globl\t%s\n", l->label);
+ fprintf(f, "%s:\n", l->label);
}
fprintf(f, "\t/* FDT_PROP */\n");
asm_emit_cell(e, FDT_PROP);
@@ -260,7 +263,7 @@ static void flatten_tree(struct node *tr
struct node *child;
int seen_name_prop = 0;
- emit->beginnode(etarget, tree->label);
+ emit->beginnode(etarget, tree->labels);
if (vi->flags & FTF_FULLPATH)
emit->string(etarget, tree->fullpath, 0);
@@ -277,7 +280,7 @@ static void flatten_tree(struct node *tr
nameoff = stringtable_insert(strbuf, prop->name);
- emit->property(etarget, prop->label);
+ emit->property(etarget, prop->labels);
emit->cell(etarget, prop->val.len);
emit->cell(etarget, nameoff);
@@ -304,7 +307,7 @@ static void flatten_tree(struct node *tr
flatten_tree(child, emit, etarget, strbuf, vi);
}
- emit->endnode(etarget, tree->label);
+ emit->endnode(etarget, tree->labels);
}
static struct data flatten_reserve_list(struct reserve_info *reservelist,
@@ -525,9 +528,11 @@ void dt_to_asm(FILE *f, struct boot_info
* as it appears .quad isn't available in some assemblers.
*/
for (re = bi->reservelist; re; re = re->next) {
- if (re->label) {
- fprintf(f, "\t.globl\t%s\n", re->label);
- fprintf(f, "%s:\n", re->label);
+ 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",
@@ -684,7 +689,7 @@ static struct property *flat_read_proper
val = flat_read_data(dtbuf, proplen);
- return build_property(name, val, NULL);
+ return build_property(name, val);
}
@@ -709,7 +714,7 @@ static struct reserve_info *flat_read_me
if (re.size == 0)
break;
- new = build_reserve_entry(re.address, re.size, NULL);
+ new = build_reserve_entry(re.address, re.size);
reservelist = add_reserve_entry(reservelist, new);
}
Index: dtc/fstree.c
===================================================================
--- dtc.orig/fstree.c 2010-02-23 20:19:37.295956576 +1100
+++ dtc/fstree.c 2010-02-23 20:26:42.703959114 +1100
@@ -60,8 +60,7 @@ static struct node *read_fstree(const ch
} else {
prop = build_property(xstrdup(de->d_name),
data_copy_file(pfile,
- st.st_size),
- NULL);
+ st.st_size));
add_property(tree, prop);
fclose(pfile);
}
@@ -69,8 +68,7 @@ static struct node *read_fstree(const ch
struct node *newchild;
newchild = read_fstree(tmpnam);
- newchild = name_node(newchild, xstrdup(de->d_name),
- NULL);
+ newchild = name_node(newchild, xstrdup(de->d_name));
add_child(tree, newchild);
}
@@ -85,7 +83,7 @@ struct boot_info *dt_from_fs(const char
struct node *tree;
tree = read_fstree(dirname);
- tree = name_node(tree, "", NULL);
+ tree = name_node(tree, "");
return build_boot_info(NULL, tree, guess_boot_cpuid(tree));
}
Index: dtc/livetree.c
===================================================================
--- dtc.orig/livetree.c 2010-02-23 20:27:00.423956836 +1100
+++ dtc/livetree.c 2010-02-23 21:25:44.091960558 +1100
@@ -24,17 +24,24 @@
* Tree building functions
*/
-struct property *build_property(char *name, struct data val, char *label)
+void add_label(struct label **labels, char *label)
+{
+ struct label *new = xmalloc(sizeof(*new));
+
+ new->label = label;
+ new->next = *labels;
+ *labels = new;
+}
+
+struct property *build_property(char *name, struct data val)
{
struct property *new = xmalloc(sizeof(*new));
+ memset(new, 0, sizeof(*new));
+
new->name = name;
new->val = val;
- new->next = NULL;
-
- new->label = label;
-
return new;
}
@@ -78,14 +85,12 @@ struct node *build_node(struct property
return new;
}
-struct node *name_node(struct node *node, char *name, char * label)
+struct node *name_node(struct node *node, char *name)
{
assert(node->name == NULL);
node->name = name;
- node->label = label;
-
return node;
}
@@ -124,8 +129,7 @@ void add_child(struct node *parent, stru
*p = child;
}
-struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size,
- char *label)
+struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
{
struct reserve_info *new = xmalloc(sizeof(*new));
@@ -134,8 +138,6 @@ struct reserve_info *build_reserve_entry
new->next = NULL;
- new->label = label;
-
return new;
}
@@ -217,8 +219,11 @@ struct property *get_property_by_label(s
*node = tree;
for_each_property(tree, prop) {
- if (prop->label && streq(prop->label, label))
- return prop;
+ struct label *l;
+
+ for_each_label(prop->labels, l)
+ if (streq(l->label, label))
+ return prop;
}
for_each_child(tree, c) {
@@ -296,11 +301,13 @@ struct node *get_node_by_path(struct nod
struct node *get_node_by_label(struct node *tree, const char *label)
{
struct node *child, *node;
+ struct label *l;
assert(label && (strlen(label) > 0));
- if (tree->label && streq(tree->label, label))
- return tree;
+ for_each_label(tree->labels, l)
+ if (streq(l->label, label))
+ return tree;
for_each_child(tree, child) {
node = get_node_by_label(child, label);
@@ -353,15 +360,13 @@ cell_t get_node_phandle(struct node *roo
&& (phandle_format & PHANDLE_LEGACY))
add_property(node,
build_property("linux,phandle",
- data_append_cell(empty_data, phandle),
- NULL));
+ data_append_cell(empty_data, phandle)));
if (!get_property(node, "phandle")
&& (phandle_format & PHANDLE_EPAPR))
add_property(node,
build_property("phandle",
- data_append_cell(empty_data, phandle),
- NULL));
+ data_append_cell(empty_data, phandle)));
/* If the node *does* have a phandle property, we must
* be dealing with a self-referencing phandle, which will be
Index: dtc/checks.c
===================================================================
--- dtc.orig/checks.c 2010-02-23 20:36:00.637005770 +1100
+++ dtc/checks.c 2010-02-23 20:48:07.763956954 +1100
@@ -314,16 +314,19 @@ static void check_duplicate_label(struct
static void check_duplicate_label_node(struct check *c, struct node *dt,
struct node *node)
{
- if (node->label)
- check_duplicate_label(c, dt, node->label, node, NULL, NULL);
+ struct label *l;
+
+ 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;
- if (prop->label)
- check_duplicate_label(c, dt, prop->label, node, prop, NULL);
+ for_each_label(prop->labels, l)
+ check_duplicate_label(c, dt, l->label, node, prop, NULL);
for_each_marker_of_type(m, LABEL)
check_duplicate_label(c, dt, m->ref, node, prop, m);
Index: dtc/treesource.c
===================================================================
--- dtc.orig/treesource.c 2010-02-23 20:46:05.111977449 +1100
+++ dtc/treesource.c 2010-02-23 21:23:10.720754157 +1100
@@ -235,10 +235,11 @@ static void write_tree_source_node(FILE
{
struct property *prop;
struct node *child;
+ struct label *l;
write_prefix(f, level);
- if (tree->label)
- fprintf(f, "%s: ", tree->label);
+ for_each_label(tree->labels, l)
+ fprintf(f, "%s: ", l->label);
if (tree->name && (*tree->name))
fprintf(f, "%s {\n", tree->name);
else
@@ -246,8 +247,8 @@ static void write_tree_source_node(FILE
for_each_property(tree, prop) {
write_prefix(f, level+1);
- if (prop->label)
- fprintf(f, "%s: ", prop->label);
+ for_each_label(prop->labels, l)
+ fprintf(f, "%s: ", l->label);
fprintf(f, "%s", prop->name);
write_propval(f, prop);
}
@@ -267,8 +268,10 @@ void dt_to_source(FILE *f, struct boot_i
fprintf(f, "/dts-v1/;\n\n");
for (re = bi->reservelist; re; re = re->next) {
- if (re->label)
- fprintf(f, "%s: ", re->label);
+ 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);
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: dtc: Allow multiple labels on nodes and properties
2010-02-24 1:03 dtc: Allow multiple labels on nodes and properties David Gibson
@ 2010-02-24 2:10 ` Grant Likely
2010-02-24 7:22 ` dtc: Allow multiple labels on nodes and properties (v2) David Gibson
1 sibling, 0 replies; 5+ messages in thread
From: Grant Likely @ 2010-02-24 2:10 UTC (permalink / raw)
To: David Gibson; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
On Tue, Feb 23, 2010 at 6:03 PM, David Gibson
<david-xT8FGy+AXnRB3Ne2BGzF6laj5H9X9Tb+@public.gmane.org> wrote:
> At present, both the grammar and our internal data structures mean
> that there can be only one label on a node, property or memreserve
> entry. This is a fairly arbitrary constraint, given that any number
> of value labels can appear at the same point, and that in C you can
> have any number of labels on the same statement.
>
> This is pretty much a non-issue now, but it may become important with
> some of the extensions that Grant and I have in mind. It's not that
> hard to change, so this patch does so, allowing an arbitrary number of
> labels on any given node or property. As usual a testcase is added
> too.
>
> Signed-off-by: David Gibson <david-xT8FGy+AXnRB3Ne2BGzF6laj5H9X9Tb+@public.gmane.org>
As little as I know about the dtc; this looks sane to me. FWIW...
Acked-by: Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>
>
> Index: dtc/tests/multilabel.dts
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ dtc/tests/multilabel.dts 2010-02-23 21:22:00.392145072 +1100
> @@ -0,0 +1,38 @@
> +/dts-v1/;
> +
> +m1: mq: /memreserve/ 0 0x1000;
> +
> +/ {
> + p1: px: prop = "foo";
> +
> + /* Explicit phandles */
> + n1: nx: node1 {
> + linux,phandle = <0x2000>;
> + ref = <&{/node2}>; /* reference precedes target */
> + lref = <&ny>;
> + };
> + ny: n2: node2 {
> + phandle = <0x1>;
> + ref = <&{/node1}>; /* reference after target */
> + lref = <&nx>;
> + };
> +
> + /* Implicit phandles */
> + n3: node3 {
> + ref = <&{/node4}>;
> + lref = <&n4>;
> + };
> + n4: node4 {
> + };
> +
> + /* Explicit phandle with implicit value */
> + /* This self-reference is the standard way to tag a node as requiring
> + * a phandle (perhaps for reference by nodes that will be dynamically
> + * added) without explicitly allocating it a phandle.
> + * The self-reference requires some special internal handling, though
> + * so check it actually works */
> + n5: nz: node5 {
> + linux,phandle = <&n5>;
> + phandle = <&nz>;
> + };
> +};
> Index: dtc/tests/run_tests.sh
> ===================================================================
> --- dtc.orig/tests/run_tests.sh 2010-02-23 20:25:38.708956748 +1100
> +++ dtc/tests/run_tests.sh 2010-02-23 20:26:12.371978082 +1100
> @@ -222,6 +222,9 @@ dtc_tests () {
> run_test phandle_format dtc_references.test.$f.dtb $f
> done
>
> + run_dtc_test -I dts -O dtb -o multilabel.test.dtb multilabel.dts
> + run_test references multilabel.test.dtb
> +
> run_dtc_test -I dts -O dtb -o dtc_comments.test.dtb comments.dts
> run_dtc_test -I dts -O dtb -o dtc_comments-cmp.test.dtb comments-cmp.dts
> run_test dtbs_equal_ordered dtc_comments.test.dtb dtc_comments-cmp.test.dtb
> Index: dtc/dtc-parser.y
> ===================================================================
> --- dtc.orig/dtc-parser.y 2010-02-23 20:19:37.315975392 +1100
> +++ dtc/dtc-parser.y 2010-02-23 21:27:31.104219098 +1100
> @@ -78,7 +78,6 @@ static unsigned long long eval_literal(c
> %type <node> nodedef
> %type <node> subnode
> %type <nodelist> subnodes
> -%type <labelref> label
>
> %%
>
> @@ -102,9 +101,14 @@ memreserves:
> ;
>
> memreserve:
> - label DT_MEMRESERVE addr addr ';'
> + DT_MEMRESERVE addr addr ';'
> {
> - $$ = build_reserve_entry($3, $4, $1);
> + $$ = build_reserve_entry($2, $3);
> + }
> + | DT_LABEL memreserve
> + {
> + add_label(&$2->labels, $1);
> + $$ = $2;
> }
> ;
>
> @@ -118,7 +122,7 @@ addr:
> devicetree:
> '/' nodedef
> {
> - $$ = name_node($2, "", NULL);
> + $$ = name_node($2, "");
> }
> ;
>
> @@ -141,13 +145,18 @@ proplist:
> ;
>
> propdef:
> - label DT_PROPNODENAME '=' propdata ';'
> + DT_PROPNODENAME '=' propdata ';'
> + {
> + $$ = build_property($1, $3);
> + }
> + | DT_PROPNODENAME ';'
> {
> - $$ = build_property($2, $4, $1);
> + $$ = build_property($1, empty_data);
> }
> - | label DT_PROPNODENAME ';'
> + | DT_LABEL propdef
> {
> - $$ = build_property($2, empty_data, $1);
> + add_label(&$2->labels, $1);
> + $$ = $2;
> }
> ;
>
> @@ -264,7 +273,7 @@ subnodes:
> {
> $$ = NULL;
> }
> - | subnode subnodes
> + | subnode subnodes
> {
> $$ = chain_node($1, $2);
> }
> @@ -276,20 +285,14 @@ subnodes:
> ;
>
> subnode:
> - label DT_PROPNODENAME nodedef
> + DT_PROPNODENAME nodedef
> {
> - $$ = name_node($3, $2, $1);
> + $$ = name_node($2, $1);
> }
> - ;
> -
> -label:
> - /* empty */
> + | DT_LABEL subnode
> {
> - $$ = NULL;
> - }
> - | DT_LABEL
> - {
> - $$ = $1;
> + add_label(&$2->labels, $1);
> + $$ = $2;
> }
> ;
>
> Index: dtc/dtc.h
> ===================================================================
> --- dtc.orig/dtc.h 2010-02-23 20:19:37.287957166 +1100
> +++ dtc/dtc.h 2010-02-23 21:26:04.067960304 +1100
> @@ -125,13 +125,18 @@ int data_is_one_string(struct data d);
> #define MAX_NODENAME_LEN 31
>
> /* Live trees */
> +struct label {
> + char *label;
> + struct label *next;
> +};
> +
> struct property {
> char *name;
> struct data val;
>
> struct property *next;
>
> - char *label;
> + struct label *labels;
> };
>
> struct node {
> @@ -148,21 +153,26 @@ struct node {
> cell_t phandle;
> int addr_cells, size_cells;
>
> - char *label;
> + struct label *labels;
> };
>
> +#define for_each_label(l0, l) \
> + for ((l) = (l0); (l); (l) = (l)->next)
> +
> #define for_each_property(n, p) \
> for ((p) = (n)->proplist; (p); (p) = (p)->next)
>
> #define for_each_child(n, c) \
> for ((c) = (n)->children; (c); (c) = (c)->next_sibling)
>
> -struct property *build_property(char *name, struct data val, char *label);
> +void add_label(struct label **labels, char *label);
> +
> +struct property *build_property(char *name, struct data val);
> struct property *chain_property(struct property *first, struct property *list);
> struct property *reverse_properties(struct property *first);
>
> struct node *build_node(struct property *proplist, struct node *children);
> -struct node *name_node(struct node *node, char *name, char *label);
> +struct node *name_node(struct node *node, char *name);
> struct node *chain_node(struct node *first, struct node *list);
>
> void add_property(struct node *node, struct property *prop);
> @@ -191,10 +201,10 @@ struct reserve_info {
>
> struct reserve_info *next;
>
> - char *label;
> + struct label *labels;
> };
>
> -struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len, char *label);
> +struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len);
> struct reserve_info *chain_reserve_entry(struct reserve_info *first,
> struct reserve_info *list);
> struct reserve_info *add_reserve_entry(struct reserve_info *list,
> Index: dtc/flattree.c
> ===================================================================
> --- dtc.orig/flattree.c 2010-02-23 20:19:37.327957222 +1100
> +++ dtc/flattree.c 2010-02-23 21:22:38.223958196 +1100
> @@ -52,9 +52,9 @@ struct emitter {
> void (*string)(void *, char *, int);
> void (*align)(void *, int);
> void (*data)(void *, struct data);
> - void (*beginnode)(void *, const char *);
> - void (*endnode)(void *, const char *);
> - void (*property)(void *, const char *);
> + void (*beginnode)(void *, struct label *labels);
> + void (*endnode)(void *, struct label *labels);
> + void (*property)(void *, struct label *labels);
> };
>
> static void bin_emit_cell(void *e, cell_t val)
> @@ -89,17 +89,17 @@ static void bin_emit_data(void *e, struc
> *dtbuf = data_append_data(*dtbuf, d.val, d.len);
> }
>
> -static void bin_emit_beginnode(void *e, const char *label)
> +static void bin_emit_beginnode(void *e, struct label *labels)
> {
> bin_emit_cell(e, FDT_BEGIN_NODE);
> }
>
> -static void bin_emit_endnode(void *e, const char *label)
> +static void bin_emit_endnode(void *e, struct label *labels)
> {
> bin_emit_cell(e, FDT_END_NODE);
> }
>
> -static void bin_emit_property(void *e, const char *label)
> +static void bin_emit_property(void *e, struct label *labels)
> {
> bin_emit_cell(e, FDT_PROP);
> }
> @@ -191,37 +191,40 @@ static void asm_emit_data(void *e, struc
> assert(off == d.len);
> }
>
> -static void asm_emit_beginnode(void *e, const char *label)
> +static void asm_emit_beginnode(void *e, struct label *labels)
> {
> FILE *f = e;
> + struct label *l;
>
> - if (label) {
> - fprintf(f, "\t.globl\t%s\n", label);
> - fprintf(f, "%s:\n", label);
> + for_each_label(labels, l) {
> + fprintf(f, "\t.globl\t%s\n", l->label);
> + fprintf(f, "%s:\n", l->label);
> }
> fprintf(f, "\t/* FDT_BEGIN_NODE */\n");
> asm_emit_cell(e, FDT_BEGIN_NODE);
> }
>
> -static void asm_emit_endnode(void *e, const char *label)
> +static void asm_emit_endnode(void *e, struct label *labels)
> {
> FILE *f = e;
> + struct label *l;
>
> fprintf(f, "\t/* FDT_END_NODE */\n");
> asm_emit_cell(e, FDT_END_NODE);
> - if (label) {
> - fprintf(f, "\t.globl\t%s_end\n", label);
> - fprintf(f, "%s_end:\n", label);
> + for_each_label(labels, l) {
> + fprintf(f, "\t.globl\t%s_end\n", l->label);
> + fprintf(f, "%s_end:\n", l->label);
> }
> }
>
> -static void asm_emit_property(void *e, const char *label)
> +static void asm_emit_property(void *e, struct label *labels)
> {
> FILE *f = e;
> + struct label *l;
>
> - if (label) {
> - fprintf(f, "\t.globl\t%s\n", label);
> - fprintf(f, "%s:\n", label);
> + for_each_label(labels, l) {
> + fprintf(f, "\t.globl\t%s\n", l->label);
> + fprintf(f, "%s:\n", l->label);
> }
> fprintf(f, "\t/* FDT_PROP */\n");
> asm_emit_cell(e, FDT_PROP);
> @@ -260,7 +263,7 @@ static void flatten_tree(struct node *tr
> struct node *child;
> int seen_name_prop = 0;
>
> - emit->beginnode(etarget, tree->label);
> + emit->beginnode(etarget, tree->labels);
>
> if (vi->flags & FTF_FULLPATH)
> emit->string(etarget, tree->fullpath, 0);
> @@ -277,7 +280,7 @@ static void flatten_tree(struct node *tr
>
> nameoff = stringtable_insert(strbuf, prop->name);
>
> - emit->property(etarget, prop->label);
> + emit->property(etarget, prop->labels);
> emit->cell(etarget, prop->val.len);
> emit->cell(etarget, nameoff);
>
> @@ -304,7 +307,7 @@ static void flatten_tree(struct node *tr
> flatten_tree(child, emit, etarget, strbuf, vi);
> }
>
> - emit->endnode(etarget, tree->label);
> + emit->endnode(etarget, tree->labels);
> }
>
> static struct data flatten_reserve_list(struct reserve_info *reservelist,
> @@ -525,9 +528,11 @@ void dt_to_asm(FILE *f, struct boot_info
> * as it appears .quad isn't available in some assemblers.
> */
> for (re = bi->reservelist; re; re = re->next) {
> - if (re->label) {
> - fprintf(f, "\t.globl\t%s\n", re->label);
> - fprintf(f, "%s:\n", re->label);
> + 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",
> @@ -684,7 +689,7 @@ static struct property *flat_read_proper
>
> val = flat_read_data(dtbuf, proplen);
>
> - return build_property(name, val, NULL);
> + return build_property(name, val);
> }
>
>
> @@ -709,7 +714,7 @@ static struct reserve_info *flat_read_me
> if (re.size == 0)
> break;
>
> - new = build_reserve_entry(re.address, re.size, NULL);
> + new = build_reserve_entry(re.address, re.size);
> reservelist = add_reserve_entry(reservelist, new);
> }
>
> Index: dtc/fstree.c
> ===================================================================
> --- dtc.orig/fstree.c 2010-02-23 20:19:37.295956576 +1100
> +++ dtc/fstree.c 2010-02-23 20:26:42.703959114 +1100
> @@ -60,8 +60,7 @@ static struct node *read_fstree(const ch
> } else {
> prop = build_property(xstrdup(de->d_name),
> data_copy_file(pfile,
> - st.st_size),
> - NULL);
> + st.st_size));
> add_property(tree, prop);
> fclose(pfile);
> }
> @@ -69,8 +68,7 @@ static struct node *read_fstree(const ch
> struct node *newchild;
>
> newchild = read_fstree(tmpnam);
> - newchild = name_node(newchild, xstrdup(de->d_name),
> - NULL);
> + newchild = name_node(newchild, xstrdup(de->d_name));
> add_child(tree, newchild);
> }
>
> @@ -85,7 +83,7 @@ struct boot_info *dt_from_fs(const char
> struct node *tree;
>
> tree = read_fstree(dirname);
> - tree = name_node(tree, "", NULL);
> + tree = name_node(tree, "");
>
> return build_boot_info(NULL, tree, guess_boot_cpuid(tree));
> }
> Index: dtc/livetree.c
> ===================================================================
> --- dtc.orig/livetree.c 2010-02-23 20:27:00.423956836 +1100
> +++ dtc/livetree.c 2010-02-23 21:25:44.091960558 +1100
> @@ -24,17 +24,24 @@
> * Tree building functions
> */
>
> -struct property *build_property(char *name, struct data val, char *label)
> +void add_label(struct label **labels, char *label)
> +{
> + struct label *new = xmalloc(sizeof(*new));
> +
> + new->label = label;
> + new->next = *labels;
> + *labels = new;
> +}
> +
> +struct property *build_property(char *name, struct data val)
> {
> struct property *new = xmalloc(sizeof(*new));
>
> + memset(new, 0, sizeof(*new));
> +
> new->name = name;
> new->val = val;
>
> - new->next = NULL;
> -
> - new->label = label;
> -
> return new;
> }
>
> @@ -78,14 +85,12 @@ struct node *build_node(struct property
> return new;
> }
>
> -struct node *name_node(struct node *node, char *name, char * label)
> +struct node *name_node(struct node *node, char *name)
> {
> assert(node->name == NULL);
>
> node->name = name;
>
> - node->label = label;
> -
> return node;
> }
>
> @@ -124,8 +129,7 @@ void add_child(struct node *parent, stru
> *p = child;
> }
>
> -struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size,
> - char *label)
> +struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
> {
> struct reserve_info *new = xmalloc(sizeof(*new));
>
> @@ -134,8 +138,6 @@ struct reserve_info *build_reserve_entry
>
> new->next = NULL;
>
> - new->label = label;
> -
> return new;
> }
>
> @@ -217,8 +219,11 @@ struct property *get_property_by_label(s
> *node = tree;
>
> for_each_property(tree, prop) {
> - if (prop->label && streq(prop->label, label))
> - return prop;
> + struct label *l;
> +
> + for_each_label(prop->labels, l)
> + if (streq(l->label, label))
> + return prop;
> }
>
> for_each_child(tree, c) {
> @@ -296,11 +301,13 @@ struct node *get_node_by_path(struct nod
> struct node *get_node_by_label(struct node *tree, const char *label)
> {
> struct node *child, *node;
> + struct label *l;
>
> assert(label && (strlen(label) > 0));
>
> - if (tree->label && streq(tree->label, label))
> - return tree;
> + for_each_label(tree->labels, l)
> + if (streq(l->label, label))
> + return tree;
>
> for_each_child(tree, child) {
> node = get_node_by_label(child, label);
> @@ -353,15 +360,13 @@ cell_t get_node_phandle(struct node *roo
> && (phandle_format & PHANDLE_LEGACY))
> add_property(node,
> build_property("linux,phandle",
> - data_append_cell(empty_data, phandle),
> - NULL));
> + data_append_cell(empty_data, phandle)));
>
> if (!get_property(node, "phandle")
> && (phandle_format & PHANDLE_EPAPR))
> add_property(node,
> build_property("phandle",
> - data_append_cell(empty_data, phandle),
> - NULL));
> + data_append_cell(empty_data, phandle)));
>
> /* If the node *does* have a phandle property, we must
> * be dealing with a self-referencing phandle, which will be
> Index: dtc/checks.c
> ===================================================================
> --- dtc.orig/checks.c 2010-02-23 20:36:00.637005770 +1100
> +++ dtc/checks.c 2010-02-23 20:48:07.763956954 +1100
> @@ -314,16 +314,19 @@ static void check_duplicate_label(struct
> static void check_duplicate_label_node(struct check *c, struct node *dt,
> struct node *node)
> {
> - if (node->label)
> - check_duplicate_label(c, dt, node->label, node, NULL, NULL);
> + struct label *l;
> +
> + 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;
>
> - if (prop->label)
> - check_duplicate_label(c, dt, prop->label, node, prop, NULL);
> + for_each_label(prop->labels, l)
> + check_duplicate_label(c, dt, l->label, node, prop, NULL);
>
> for_each_marker_of_type(m, LABEL)
> check_duplicate_label(c, dt, m->ref, node, prop, m);
> Index: dtc/treesource.c
> ===================================================================
> --- dtc.orig/treesource.c 2010-02-23 20:46:05.111977449 +1100
> +++ dtc/treesource.c 2010-02-23 21:23:10.720754157 +1100
> @@ -235,10 +235,11 @@ static void write_tree_source_node(FILE
> {
> struct property *prop;
> struct node *child;
> + struct label *l;
>
> write_prefix(f, level);
> - if (tree->label)
> - fprintf(f, "%s: ", tree->label);
> + for_each_label(tree->labels, l)
> + fprintf(f, "%s: ", l->label);
> if (tree->name && (*tree->name))
> fprintf(f, "%s {\n", tree->name);
> else
> @@ -246,8 +247,8 @@ static void write_tree_source_node(FILE
>
> for_each_property(tree, prop) {
> write_prefix(f, level+1);
> - if (prop->label)
> - fprintf(f, "%s: ", prop->label);
> + for_each_label(prop->labels, l)
> + fprintf(f, "%s: ", l->label);
> fprintf(f, "%s", prop->name);
> write_propval(f, prop);
> }
> @@ -267,8 +268,10 @@ void dt_to_source(FILE *f, struct boot_i
> fprintf(f, "/dts-v1/;\n\n");
>
> for (re = bi->reservelist; re; re = re->next) {
> - if (re->label)
> - fprintf(f, "%s: ", re->label);
> + 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);
>
>
> --
> David Gibson | I'll have my music baroque, and my code
> david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
> | _way_ _around_!
> http://www.ozlabs.org/~dgibson
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: dtc: Allow multiple labels on nodes and properties (v2)
2010-02-24 1:03 dtc: Allow multiple labels on nodes and properties David Gibson
2010-02-24 2:10 ` Grant Likely
@ 2010-02-24 7:22 ` David Gibson
2010-02-24 14:57 ` Jon Loeliger
1 sibling, 1 reply; 5+ messages in thread
From: David Gibson @ 2010-02-24 7:22 UTC (permalink / raw)
To: Jon Loeliger; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
Oops, don't apply that one, it has an uninitialized variable bug.
Here's a fixed version.
dtc: Allow multiple labels on nodes and properties
At present, both the grammar and our internal data structures mean
that there can be only one label on a node or property. This is a
fairly arbitrary constraint, given that any number of value labels can
appear at the same point, and that in C you can have any number of
labels on the same statement.
This is pretty much a non-issue now, but it may become important with
some of the extensions that Grant and I have in mind. It's not that
hard to change, so this patch does so, allowing an arbitrary number of
labels on any given node or property. As usual a testcase is added
too.
Signed-off-by: David Gibson <david-xT8FGy+AXnRB3Ne2BGzF6laj5H9X9Tb+@public.gmane.org>
Index: dtc/tests/multilabel.dts
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ dtc/tests/multilabel.dts 2010-02-24 17:57:12.736958851 +1100
@@ -0,0 +1,38 @@
+/dts-v1/;
+
+m1: mq: /memreserve/ 0 0x1000;
+
+/ {
+ p1: px: prop = "foo";
+
+ /* Explicit phandles */
+ n1: nx: node1 {
+ linux,phandle = <0x2000>;
+ ref = <&{/node2}>; /* reference precedes target */
+ lref = <&ny>;
+ };
+ ny: n2: node2 {
+ phandle = <0x1>;
+ ref = <&{/node1}>; /* reference after target */
+ lref = <&nx>;
+ };
+
+ /* Implicit phandles */
+ n3: node3 {
+ ref = <&{/node4}>;
+ lref = <&n4>;
+ };
+ n4: node4 {
+ };
+
+ /* Explicit phandle with implicit value */
+ /* This self-reference is the standard way to tag a node as requiring
+ * a phandle (perhaps for reference by nodes that will be dynamically
+ * added) without explicitly allocating it a phandle.
+ * The self-reference requires some special internal handling, though
+ * so check it actually works */
+ n5: nz: node5 {
+ linux,phandle = <&n5>;
+ phandle = <&nz>;
+ };
+};
Index: dtc/tests/run_tests.sh
===================================================================
--- dtc.orig/tests/run_tests.sh 2010-02-24 17:57:09.799958623 +1100
+++ dtc/tests/run_tests.sh 2010-02-24 18:19:49.104958482 +1100
@@ -222,6 +222,9 @@ dtc_tests () {
run_test phandle_format dtc_references.test.$f.dtb $f
done
+ run_dtc_test -I dts -O dtb -o multilabel.test.dtb multilabel.dts
+ run_test references multilabel.test.dtb
+
run_dtc_test -I dts -O dtb -o dtc_comments.test.dtb comments.dts
run_dtc_test -I dts -O dtb -o dtc_comments-cmp.test.dtb comments-cmp.dts
run_test dtbs_equal_ordered dtc_comments.test.dtb dtc_comments-cmp.test.dtb
Index: dtc/dtc-parser.y
===================================================================
--- dtc.orig/dtc-parser.y 2010-02-24 17:57:09.771961279 +1100
+++ dtc/dtc-parser.y 2010-02-24 17:57:12.740957125 +1100
@@ -78,7 +78,6 @@ static unsigned long long eval_literal(c
%type <node> nodedef
%type <node> subnode
%type <nodelist> subnodes
-%type <labelref> label
%%
@@ -102,9 +101,14 @@ memreserves:
;
memreserve:
- label DT_MEMRESERVE addr addr ';'
+ DT_MEMRESERVE addr addr ';'
{
- $$ = build_reserve_entry($3, $4, $1);
+ $$ = build_reserve_entry($2, $3);
+ }
+ | DT_LABEL memreserve
+ {
+ add_label(&$2->labels, $1);
+ $$ = $2;
}
;
@@ -118,7 +122,7 @@ addr:
devicetree:
'/' nodedef
{
- $$ = name_node($2, "", NULL);
+ $$ = name_node($2, "");
}
;
@@ -141,13 +145,18 @@ proplist:
;
propdef:
- label DT_PROPNODENAME '=' propdata ';'
+ DT_PROPNODENAME '=' propdata ';'
+ {
+ $$ = build_property($1, $3);
+ }
+ | DT_PROPNODENAME ';'
{
- $$ = build_property($2, $4, $1);
+ $$ = build_property($1, empty_data);
}
- | label DT_PROPNODENAME ';'
+ | DT_LABEL propdef
{
- $$ = build_property($2, empty_data, $1);
+ add_label(&$2->labels, $1);
+ $$ = $2;
}
;
@@ -264,7 +273,7 @@ subnodes:
{
$$ = NULL;
}
- | subnode subnodes
+ | subnode subnodes
{
$$ = chain_node($1, $2);
}
@@ -276,20 +285,14 @@ subnodes:
;
subnode:
- label DT_PROPNODENAME nodedef
+ DT_PROPNODENAME nodedef
{
- $$ = name_node($3, $2, $1);
+ $$ = name_node($2, $1);
}
- ;
-
-label:
- /* empty */
+ | DT_LABEL subnode
{
- $$ = NULL;
- }
- | DT_LABEL
- {
- $$ = $1;
+ add_label(&$2->labels, $1);
+ $$ = $2;
}
;
Index: dtc/dtc.h
===================================================================
--- dtc.orig/dtc.h 2010-02-24 17:57:09.647957591 +1100
+++ dtc/dtc.h 2010-02-24 17:57:12.740957125 +1100
@@ -125,13 +125,18 @@ int data_is_one_string(struct data d);
#define MAX_NODENAME_LEN 31
/* Live trees */
+struct label {
+ char *label;
+ struct label *next;
+};
+
struct property {
char *name;
struct data val;
struct property *next;
- char *label;
+ struct label *labels;
};
struct node {
@@ -148,21 +153,26 @@ struct node {
cell_t phandle;
int addr_cells, size_cells;
- char *label;
+ struct label *labels;
};
+#define for_each_label(l0, l) \
+ for ((l) = (l0); (l); (l) = (l)->next)
+
#define for_each_property(n, p) \
for ((p) = (n)->proplist; (p); (p) = (p)->next)
#define for_each_child(n, c) \
for ((c) = (n)->children; (c); (c) = (c)->next_sibling)
-struct property *build_property(char *name, struct data val, char *label);
+void add_label(struct label **labels, char *label);
+
+struct property *build_property(char *name, struct data val);
struct property *chain_property(struct property *first, struct property *list);
struct property *reverse_properties(struct property *first);
struct node *build_node(struct property *proplist, struct node *children);
-struct node *name_node(struct node *node, char *name, char *label);
+struct node *name_node(struct node *node, char *name);
struct node *chain_node(struct node *first, struct node *list);
void add_property(struct node *node, struct property *prop);
@@ -191,10 +201,10 @@ struct reserve_info {
struct reserve_info *next;
- char *label;
+ struct label *labels;
};
-struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len, char *label);
+struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len);
struct reserve_info *chain_reserve_entry(struct reserve_info *first,
struct reserve_info *list);
struct reserve_info *add_reserve_entry(struct reserve_info *list,
Index: dtc/flattree.c
===================================================================
--- dtc.orig/flattree.c 2010-02-24 17:57:09.851957689 +1100
+++ dtc/flattree.c 2010-02-24 17:57:12.740957125 +1100
@@ -52,9 +52,9 @@ struct emitter {
void (*string)(void *, char *, int);
void (*align)(void *, int);
void (*data)(void *, struct data);
- void (*beginnode)(void *, const char *);
- void (*endnode)(void *, const char *);
- void (*property)(void *, const char *);
+ void (*beginnode)(void *, struct label *labels);
+ void (*endnode)(void *, struct label *labels);
+ void (*property)(void *, struct label *labels);
};
static void bin_emit_cell(void *e, cell_t val)
@@ -89,17 +89,17 @@ static void bin_emit_data(void *e, struc
*dtbuf = data_append_data(*dtbuf, d.val, d.len);
}
-static void bin_emit_beginnode(void *e, const char *label)
+static void bin_emit_beginnode(void *e, struct label *labels)
{
bin_emit_cell(e, FDT_BEGIN_NODE);
}
-static void bin_emit_endnode(void *e, const char *label)
+static void bin_emit_endnode(void *e, struct label *labels)
{
bin_emit_cell(e, FDT_END_NODE);
}
-static void bin_emit_property(void *e, const char *label)
+static void bin_emit_property(void *e, struct label *labels)
{
bin_emit_cell(e, FDT_PROP);
}
@@ -191,37 +191,40 @@ static void asm_emit_data(void *e, struc
assert(off == d.len);
}
-static void asm_emit_beginnode(void *e, const char *label)
+static void asm_emit_beginnode(void *e, struct label *labels)
{
FILE *f = e;
+ struct label *l;
- if (label) {
- fprintf(f, "\t.globl\t%s\n", label);
- fprintf(f, "%s:\n", label);
+ for_each_label(labels, l) {
+ fprintf(f, "\t.globl\t%s\n", l->label);
+ fprintf(f, "%s:\n", l->label);
}
fprintf(f, "\t/* FDT_BEGIN_NODE */\n");
asm_emit_cell(e, FDT_BEGIN_NODE);
}
-static void asm_emit_endnode(void *e, const char *label)
+static void asm_emit_endnode(void *e, struct label *labels)
{
FILE *f = e;
+ struct label *l;
fprintf(f, "\t/* FDT_END_NODE */\n");
asm_emit_cell(e, FDT_END_NODE);
- if (label) {
- fprintf(f, "\t.globl\t%s_end\n", label);
- fprintf(f, "%s_end:\n", label);
+ for_each_label(labels, l) {
+ fprintf(f, "\t.globl\t%s_end\n", l->label);
+ fprintf(f, "%s_end:\n", l->label);
}
}
-static void asm_emit_property(void *e, const char *label)
+static void asm_emit_property(void *e, struct label *labels)
{
FILE *f = e;
+ struct label *l;
- if (label) {
- fprintf(f, "\t.globl\t%s\n", label);
- fprintf(f, "%s:\n", label);
+ for_each_label(labels, l) {
+ fprintf(f, "\t.globl\t%s\n", l->label);
+ fprintf(f, "%s:\n", l->label);
}
fprintf(f, "\t/* FDT_PROP */\n");
asm_emit_cell(e, FDT_PROP);
@@ -260,7 +263,7 @@ static void flatten_tree(struct node *tr
struct node *child;
int seen_name_prop = 0;
- emit->beginnode(etarget, tree->label);
+ emit->beginnode(etarget, tree->labels);
if (vi->flags & FTF_FULLPATH)
emit->string(etarget, tree->fullpath, 0);
@@ -277,7 +280,7 @@ static void flatten_tree(struct node *tr
nameoff = stringtable_insert(strbuf, prop->name);
- emit->property(etarget, prop->label);
+ emit->property(etarget, prop->labels);
emit->cell(etarget, prop->val.len);
emit->cell(etarget, nameoff);
@@ -304,7 +307,7 @@ static void flatten_tree(struct node *tr
flatten_tree(child, emit, etarget, strbuf, vi);
}
- emit->endnode(etarget, tree->label);
+ emit->endnode(etarget, tree->labels);
}
static struct data flatten_reserve_list(struct reserve_info *reservelist,
@@ -525,9 +528,11 @@ void dt_to_asm(FILE *f, struct boot_info
* as it appears .quad isn't available in some assemblers.
*/
for (re = bi->reservelist; re; re = re->next) {
- if (re->label) {
- fprintf(f, "\t.globl\t%s\n", re->label);
- fprintf(f, "%s:\n", re->label);
+ 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",
@@ -684,7 +689,7 @@ static struct property *flat_read_proper
val = flat_read_data(dtbuf, proplen);
- return build_property(name, val, NULL);
+ return build_property(name, val);
}
@@ -709,7 +714,7 @@ static struct reserve_info *flat_read_me
if (re.size == 0)
break;
- new = build_reserve_entry(re.address, re.size, NULL);
+ new = build_reserve_entry(re.address, re.size);
reservelist = add_reserve_entry(reservelist, new);
}
Index: dtc/fstree.c
===================================================================
--- dtc.orig/fstree.c 2010-02-24 17:57:09.691957110 +1100
+++ dtc/fstree.c 2010-02-24 17:57:12.744957075 +1100
@@ -60,8 +60,7 @@ static struct node *read_fstree(const ch
} else {
prop = build_property(xstrdup(de->d_name),
data_copy_file(pfile,
- st.st_size),
- NULL);
+ st.st_size));
add_property(tree, prop);
fclose(pfile);
}
@@ -69,8 +68,7 @@ static struct node *read_fstree(const ch
struct node *newchild;
newchild = read_fstree(tmpnam);
- newchild = name_node(newchild, xstrdup(de->d_name),
- NULL);
+ newchild = name_node(newchild, xstrdup(de->d_name));
add_child(tree, newchild);
}
@@ -85,7 +83,7 @@ struct boot_info *dt_from_fs(const char
struct node *tree;
tree = read_fstree(dirname);
- tree = name_node(tree, "", NULL);
+ tree = name_node(tree, "");
return build_boot_info(NULL, tree, guess_boot_cpuid(tree));
}
Index: dtc/livetree.c
===================================================================
--- dtc.orig/livetree.c 2010-02-24 17:57:09.683978721 +1100
+++ dtc/livetree.c 2010-02-24 18:20:25.684957337 +1100
@@ -24,17 +24,24 @@
* Tree building functions
*/
-struct property *build_property(char *name, struct data val, char *label)
+void add_label(struct label **labels, char *label)
+{
+ struct label *new = xmalloc(sizeof(*new));
+
+ new->label = label;
+ new->next = *labels;
+ *labels = new;
+}
+
+struct property *build_property(char *name, struct data val)
{
struct property *new = xmalloc(sizeof(*new));
+ memset(new, 0, sizeof(*new));
+
new->name = name;
new->val = val;
- new->next = NULL;
-
- new->label = label;
-
return new;
}
@@ -78,14 +85,12 @@ struct node *build_node(struct property
return new;
}
-struct node *name_node(struct node *node, char *name, char * label)
+struct node *name_node(struct node *node, char *name)
{
assert(node->name == NULL);
node->name = name;
- node->label = label;
-
return node;
}
@@ -124,18 +129,15 @@ void add_child(struct node *parent, stru
*p = child;
}
-struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size,
- char *label)
+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->next = NULL;
-
- new->label = label;
-
return new;
}
@@ -217,8 +219,11 @@ struct property *get_property_by_label(s
*node = tree;
for_each_property(tree, prop) {
- if (prop->label && streq(prop->label, label))
- return prop;
+ struct label *l;
+
+ for_each_label(prop->labels, l)
+ if (streq(l->label, label))
+ return prop;
}
for_each_child(tree, c) {
@@ -296,11 +301,13 @@ struct node *get_node_by_path(struct nod
struct node *get_node_by_label(struct node *tree, const char *label)
{
struct node *child, *node;
+ struct label *l;
assert(label && (strlen(label) > 0));
- if (tree->label && streq(tree->label, label))
- return tree;
+ for_each_label(tree->labels, l)
+ if (streq(l->label, label))
+ return tree;
for_each_child(tree, child) {
node = get_node_by_label(child, label);
@@ -353,15 +360,13 @@ cell_t get_node_phandle(struct node *roo
&& (phandle_format & PHANDLE_LEGACY))
add_property(node,
build_property("linux,phandle",
- data_append_cell(empty_data, phandle),
- NULL));
+ data_append_cell(empty_data, phandle)));
if (!get_property(node, "phandle")
&& (phandle_format & PHANDLE_EPAPR))
add_property(node,
build_property("phandle",
- data_append_cell(empty_data, phandle),
- NULL));
+ data_append_cell(empty_data, phandle)));
/* If the node *does* have a phandle property, we must
* be dealing with a self-referencing phandle, which will be
Index: dtc/checks.c
===================================================================
--- dtc.orig/checks.c 2010-02-24 17:57:09.611978088 +1100
+++ dtc/checks.c 2010-02-24 17:57:12.744957075 +1100
@@ -314,16 +314,19 @@ static void check_duplicate_label(struct
static void check_duplicate_label_node(struct check *c, struct node *dt,
struct node *node)
{
- if (node->label)
- check_duplicate_label(c, dt, node->label, node, NULL, NULL);
+ struct label *l;
+
+ 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;
- if (prop->label)
- check_duplicate_label(c, dt, prop->label, node, prop, NULL);
+ for_each_label(prop->labels, l)
+ check_duplicate_label(c, dt, l->label, node, prop, NULL);
for_each_marker_of_type(m, LABEL)
check_duplicate_label(c, dt, m->ref, node, prop, m);
Index: dtc/treesource.c
===================================================================
--- dtc.orig/treesource.c 2010-02-24 17:57:09.823956925 +1100
+++ dtc/treesource.c 2010-02-24 17:57:12.744957075 +1100
@@ -235,10 +235,11 @@ static void write_tree_source_node(FILE
{
struct property *prop;
struct node *child;
+ struct label *l;
write_prefix(f, level);
- if (tree->label)
- fprintf(f, "%s: ", tree->label);
+ for_each_label(tree->labels, l)
+ fprintf(f, "%s: ", l->label);
if (tree->name && (*tree->name))
fprintf(f, "%s {\n", tree->name);
else
@@ -246,8 +247,8 @@ static void write_tree_source_node(FILE
for_each_property(tree, prop) {
write_prefix(f, level+1);
- if (prop->label)
- fprintf(f, "%s: ", prop->label);
+ for_each_label(prop->labels, l)
+ fprintf(f, "%s: ", l->label);
fprintf(f, "%s", prop->name);
write_propval(f, prop);
}
@@ -267,8 +268,10 @@ void dt_to_source(FILE *f, struct boot_i
fprintf(f, "/dts-v1/;\n\n");
for (re = bi->reservelist; re; re = re->next) {
- if (re->label)
- fprintf(f, "%s: ", re->label);
+ 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);
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: dtc: Allow multiple labels on nodes and properties (v2)
2010-02-24 7:22 ` dtc: Allow multiple labels on nodes and properties (v2) David Gibson
@ 2010-02-24 14:57 ` Jon Loeliger
[not found] ` <E1NkIfh-0005pc-R0-CYoMK+44s/E@public.gmane.org>
0 siblings, 1 reply; 5+ messages in thread
From: Jon Loeliger @ 2010-02-24 14:57 UTC (permalink / raw)
To: David Gibson; +Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
> Oops, don't apply that one, it has an uninitialized variable bug.
> Here's a fixed version.
>
> dtc: Allow multiple labels on nodes and properties
>
> At present, both the grammar and our internal data structures mean
> that there can be only one label on a node or property. This is a
> fairly arbitrary constraint, given that any number of value labels can
> appear at the same point, and that in C you can have any number of
> labels on the same statement.
>
> This is pretty much a non-issue now, but it may become important with
> some of the extensions that Grant and I have in mind. It's not that
> hard to change, so this patch does so, allowing an arbitrary number of
> labels on any given node or property. As usual a testcase is added
> too.
>
> Signed-off-by: David Gibson <david-xT8FGy+AXnRB3Ne2BGzF6laj5H9X9Tb+@public.gmane.org>
>
> Index: dtc/tests/multilabel.dts
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ dtc/tests/multilabel.dts 2010-02-24 17:57:12.736958851 +1100
> @@ -0,0 +1,38 @@
So, I applied this. But I had to make an extra amend step to
fix three things after applying it:
- Remove the meta-comment, (placed after triple dash line)
- Remove the extraneous "(v2)", (placed in Subject brackets)
- Remove the duplicate Subject: line, (not repeated in body)
If instead the patch were formatted thusly, it would all just work:
To: David Gibson <david-xT8FGy+AXnRB3Ne2BGzF6laj5H9X9Tb+@public.gmane.org>
cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
Subject: [PATCH v2] dtc: Allow multiple labels on nodes and properties
At present, both the grammar and our internal data structures mean
that there can be only one label on a node or property. This is a
fairly arbitrary constraint, given that any number of value labels can
appear at the same point, and that in C you can have any number of
labels on the same statement.
This is pretty much a non-issue now, but it may become important with
some of the extensions that Grant and I have in mind. It's not that
hard to change, so this patch does so, allowing an arbitrary number of
labels on any given node or property. As usual a testcase is added
too.
Signed-off-by: David Gibson <david-xT8FGy+AXnRB3Ne2BGzF6laj5H9X9Tb+@public.gmane.org>
---
Oops, don't apply that one, it has an uninitialized variable bug.
Here's a fixed version.
Index: dtc/tests/multilabel.dts
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ dtc/tests/multilabel.dts 2010-02-24 17:57:12.736958851 +1100
@@ -0,0 +1,38 @@
Thanks,
jdl
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2010-02-24 21:58 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-24 1:03 dtc: Allow multiple labels on nodes and properties David Gibson
2010-02-24 2:10 ` Grant Likely
2010-02-24 7:22 ` dtc: Allow multiple labels on nodes and properties (v2) David Gibson
2010-02-24 14:57 ` Jon Loeliger
[not found] ` <E1NkIfh-0005pc-R0-CYoMK+44s/E@public.gmane.org>
2010-02-24 21:58 ` David Gibson
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.