diff --git a/dtc-lexer.l b/dtc-lexer.l index 0821bde..5c9969f 100644 --- a/dtc-lexer.l +++ b/dtc-lexer.l @@ -193,7 +193,7 @@ static void lexical_error(const char *fmt, ...); return DT_REF; } -<*>"&{/"{PATHCHAR}+\} { /* new-style path reference */ +<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */ yytext[yyleng-1] = '\0'; DPRINT("Ref: %s\n", yytext+2); yylval.labelref = xstrdup(yytext+2); diff --git a/livetree.c b/livetree.c index b61465f..e229b84 100644 --- a/livetree.c +++ b/livetree.c @@ -511,7 +511,9 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle) struct node *get_node_by_ref(struct node *tree, const char *ref) { - if (ref[0] == '/') + if (streq(ref, "/")) + return tree; + else if (ref[0] == '/') return get_node_by_path(tree, ref); else return get_node_by_label(tree, ref); diff --git a/tests/multilabel.dts b/tests/multilabel.dts index 31116ce..77da06c 100644 --- a/tests/multilabel.dts +++ b/tests/multilabel.dts @@ -5,6 +5,8 @@ m1: mq: /memreserve/ 0 0x1000; / { p0: pw: prop = "foo"; + rref = <&{/}>; + /* Explicit phandles */ n1: nx: node1 { linux,phandle = <0x2000>; diff --git a/tests/multilabel_merge.dts b/tests/multilabel_merge.dts index 1632300..3e80298 100644 --- a/tests/multilabel_merge.dts +++ b/tests/multilabel_merge.dts @@ -64,3 +64,7 @@ m1: mq: /memreserve/ 0 0x1000; }; }; + +/ { + rref = <&{/}>; +}; diff --git a/tests/path-references.c b/tests/path-references.c index 0746b3f..c8d25fb 100644 --- a/tests/path-references.c +++ b/tests/path-references.c @@ -47,6 +47,20 @@ static void check_ref(const void *fdt, int node, const char *checkpath) node, p, checkpath); } +static void check_rref(const void *fdt) +{ + const char *p; + int len; + + /* Check reference to root node */ + p = fdt_getprop(fdt, 0, "rref", &len); + if (!p) + FAIL("fdt_getprop(0, \"rref\"): %s", fdt_strerror(len)); + if (!streq(p, "/")) + FAIL("'rref' in root node has value \"%s\" instead of \"/\"", + p); +} + int main(int argc, char *argv[]) { void *fdt; @@ -78,5 +92,7 @@ int main(int argc, char *argv[]) if ((!streq(p, "/node1") || !streq(p + strlen("/node1") + 1, "/node2"))) FAIL("multiref has wrong value"); + check_rref(fdt); + PASS(); } diff --git a/tests/path-references.dts b/tests/path-references.dts index 91e7ef7..b00fd79 100644 --- a/tests/path-references.dts +++ b/tests/path-references.dts @@ -1,6 +1,7 @@ /dts-v1/; / { + rref = &{/}; /* Check multiple references case */ multiref = &n1 , &n2; n1: node1 { diff --git a/tests/references.c b/tests/references.c index c9d05a2..46662fc 100644 --- a/tests/references.c +++ b/tests/references.c @@ -56,6 +56,23 @@ static void check_ref(const void *fdt, int node, uint32_t checkref) node, ref, checkref); } +static void check_rref(const void *fdt) +{ + const uint32_t *p; + uint32_t ref; + int len; + + p = fdt_getprop(fdt, 0, "rref", &len); + if (!p) + FAIL("fdt_getprop(0, \"rref\"): %s", fdt_strerror(len)); + if (len != sizeof(*p)) + FAIL("'rref' in root node has wrong size (%d instead of %zd)", + len, sizeof(*p)); + ref = fdt32_to_cpu(*p); + if (ref != fdt_get_phandle(fdt, 0)) + FAIL("'rref' in root node has value 0x%x instead of 0x0", ref); +} + int main(int argc, char *argv[]) { void *fdt; @@ -104,5 +121,7 @@ int main(int argc, char *argv[]) check_ref(fdt, n2, h1); check_ref(fdt, n3, h4); + check_rref(fdt); + PASS(); } diff --git a/tests/references.dts b/tests/references.dts index 640c931..f783e8b 100644 --- a/tests/references.dts +++ b/tests/references.dts @@ -1,6 +1,8 @@ /dts-v1/; / { + rref = <&{/}>; + /* Explicit phandles */ n1: node1 { linux,phandle = <0x2000>;