aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/boot/dtc-src/Makefile.dtc18
-rw-r--r--arch/powerpc/boot/dtc-src/checks.c305
-rw-r--r--arch/powerpc/boot/dtc-src/data.c62
-rw-r--r--arch/powerpc/boot/dtc-src/dtc-lexer.l120
-rw-r--r--arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped445
-rw-r--r--arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped387
-rw-r--r--arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped12
-rw-r--r--arch/powerpc/boot/dtc-src/dtc-parser.y67
-rw-r--r--arch/powerpc/boot/dtc-src/dtc.c41
-rw-r--r--arch/powerpc/boot/dtc-src/dtc.h43
-rw-r--r--arch/powerpc/boot/dtc-src/flattree.c232
-rw-r--r--arch/powerpc/boot/dtc-src/fstree.c8
-rw-r--r--arch/powerpc/boot/dtc-src/libfdt_env.h23
-rw-r--r--arch/powerpc/boot/dtc-src/livetree.c9
-rw-r--r--arch/powerpc/boot/dtc-src/srcpos.c121
-rw-r--r--arch/powerpc/boot/dtc-src/srcpos.h30
-rw-r--r--arch/powerpc/boot/dtc-src/treesource.c15
-rw-r--r--arch/powerpc/boot/dtc-src/version_gen.h2
-rw-r--r--arch/powerpc/boot/libfdt/Makefile.libfdt8
-rw-r--r--arch/powerpc/boot/libfdt/fdt.c61
-rw-r--r--arch/powerpc/boot/libfdt/fdt_ro.c329
-rw-r--r--arch/powerpc/boot/libfdt/fdt_rw.c200
-rw-r--r--arch/powerpc/boot/libfdt/fdt_strerror.c34
-rw-r--r--arch/powerpc/boot/libfdt/fdt_sw.c55
-rw-r--r--arch/powerpc/boot/libfdt/fdt_wip.c9
-rw-r--r--arch/powerpc/boot/libfdt/libfdt.h383
-rw-r--r--arch/powerpc/boot/libfdt/libfdt_internal.h24
-rw-r--r--arch/powerpc/boot/libfdt_env.h1
28 files changed, 1615 insertions, 1429 deletions
diff --git a/arch/powerpc/boot/dtc-src/Makefile.dtc b/arch/powerpc/boot/dtc-src/Makefile.dtc
index d607fdb8df8d..6ddf9ecac669 100644
--- a/arch/powerpc/boot/dtc-src/Makefile.dtc
+++ b/arch/powerpc/boot/dtc-src/Makefile.dtc
@@ -5,21 +5,5 @@
5# 5#
6DTC_SRCS = dtc.c flattree.c fstree.c data.c livetree.c treesource.c srcpos.c \ 6DTC_SRCS = dtc.c flattree.c fstree.c data.c livetree.c treesource.c srcpos.c \
7 checks.c 7 checks.c
8DTC_EXTRA = dtc.h srcpos.h 8DTC_GEN_SRCS = dtc-lexer.lex.c dtc-parser.tab.c
9DTC_LEXFILES = dtc-lexer.l
10DTC_BISONFILES = dtc-parser.y
11
12DTC_LEX_SRCS = $(DTC_LEXFILES:%.l=%.lex.c)
13DTC_BISON_SRCS = $(DTC_BISONFILES:%.y=%.tab.c)
14DTC_BISON_INCLUDES = $(DTC_BISONFILES:%.y=%.tab.h)
15
16DTC_GEN_SRCS = $(DTC_LEX_SRCS) $(DTC_BISON_SRCS)
17DTC_GEN_ALL = $(DTC_GEN_SRCS) $(DTC_BISON_INCLUDES)
18DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o) 9DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o)
19
20DTC_CLEANFILES = $(DTC_GEN_ALL)
21
22# We assume the containing Makefile system can do auto-dependencies for most
23# things, but we supply the dependencies on generated header files explicitly
24
25$(addprefix $(DTC_objdir)/,$(DTC_GEN_SRCS:%.c=%.o)): $(addprefix $(DTC_objdir)/,$(DTC_BISON_INCLUDES))
diff --git a/arch/powerpc/boot/dtc-src/checks.c b/arch/powerpc/boot/dtc-src/checks.c
index 2ce961cd414d..95485796f253 100644
--- a/arch/powerpc/boot/dtc-src/checks.c
+++ b/arch/powerpc/boot/dtc-src/checks.c
@@ -242,6 +242,42 @@ static void check_duplicate_property_names(struct check *c, struct node *dt,
242} 242}
243NODE_CHECK(duplicate_property_names, NULL, ERROR); 243NODE_CHECK(duplicate_property_names, NULL, ERROR);
244 244
245#define LOWERCASE "abcdefghijklmnopqrstuvwxyz"
246#define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
247#define DIGITS "0123456789"
248#define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-"
249
250static void check_node_name_chars(struct check *c, struct node *dt,
251 struct node *node)
252{
253 int n = strspn(node->name, c->data);
254
255 if (n < strlen(node->name))
256 FAIL(c, "Bad character '%c' in node %s",
257 node->name[n], node->fullpath);
258}
259NODE_CHECK(node_name_chars, PROPNODECHARS "@", ERROR);
260
261static void check_node_name_format(struct check *c, struct node *dt,
262 struct node *node)
263{
264 if (strchr(get_unitname(node), '@'))
265 FAIL(c, "Node %s has multiple '@' characters in name",
266 node->fullpath);
267}
268NODE_CHECK(node_name_format, NULL, ERROR, &node_name_chars);
269
270static void check_property_name_chars(struct check *c, struct node *dt,
271 struct node *node, struct property *prop)
272{
273 int n = strspn(prop->name, c->data);
274
275 if (n < strlen(prop->name))
276 FAIL(c, "Bad character '%c' in property name \"%s\", node %s",
277 prop->name[n], prop->name, node->fullpath);
278}
279PROP_CHECK(property_name_chars, PROPNODECHARS, ERROR);
280
245static void check_explicit_phandles(struct check *c, struct node *root, 281static void check_explicit_phandles(struct check *c, struct node *root,
246 struct node *node) 282 struct node *node)
247{ 283{
@@ -280,16 +316,29 @@ NODE_CHECK(explicit_phandles, NULL, ERROR);
280static void check_name_properties(struct check *c, struct node *root, 316static void check_name_properties(struct check *c, struct node *root,
281 struct node *node) 317 struct node *node)
282{ 318{
283 struct property *prop; 319 struct property **pp, *prop = NULL;
320
321 for (pp = &node->proplist; *pp; pp = &((*pp)->next))
322 if (streq((*pp)->name, "name")) {
323 prop = *pp;
324 break;
325 }
284 326
285 prop = get_property(node, "name");
286 if (!prop) 327 if (!prop)
287 return; /* No name property, that's fine */ 328 return; /* No name property, that's fine */
288 329
289 if ((prop->val.len != node->basenamelen+1) 330 if ((prop->val.len != node->basenamelen+1)
290 || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) 331 || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) {
291 FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead" 332 FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead"
292 " of base node name)", node->fullpath, prop->val.val); 333 " of base node name)", node->fullpath, prop->val.val);
334 } else {
335 /* The name property is correct, and therefore redundant.
336 * Delete it */
337 *pp = prop->next;
338 free(prop->name);
339 data_free(prop->val);
340 free(prop);
341 }
293} 342}
294CHECK_IS_STRING(name_is_string, "name", ERROR); 343CHECK_IS_STRING(name_is_string, "name", ERROR);
295NODE_CHECK(name_properties, NULL, ERROR, &name_is_string); 344NODE_CHECK(name_properties, NULL, ERROR, &name_is_string);
@@ -301,23 +350,23 @@ NODE_CHECK(name_properties, NULL, ERROR, &name_is_string);
301static void fixup_phandle_references(struct check *c, struct node *dt, 350static void fixup_phandle_references(struct check *c, struct node *dt,
302 struct node *node, struct property *prop) 351 struct node *node, struct property *prop)
303{ 352{
304 struct marker *m = prop->val.markers; 353 struct marker *m = prop->val.markers;
305 struct node *refnode; 354 struct node *refnode;
306 cell_t phandle; 355 cell_t phandle;
307 356
308 for_each_marker_of_type(m, REF_PHANDLE) { 357 for_each_marker_of_type(m, REF_PHANDLE) {
309 assert(m->offset + sizeof(cell_t) <= prop->val.len); 358 assert(m->offset + sizeof(cell_t) <= prop->val.len);
310 359
311 refnode = get_node_by_ref(dt, m->ref); 360 refnode = get_node_by_ref(dt, m->ref);
312 if (! refnode) { 361 if (! refnode) {
313 FAIL(c, "Reference to non-existent node or label \"%s\"\n", 362 FAIL(c, "Reference to non-existent node or label \"%s\"\n",
314 m->ref); 363 m->ref);
315 continue; 364 continue;
316 } 365 }
317 366
318 phandle = get_node_phandle(dt, refnode); 367 phandle = get_node_phandle(dt, refnode);
319 *((cell_t *)(prop->val.val + m->offset)) = cpu_to_be32(phandle); 368 *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
320 } 369 }
321} 370}
322CHECK(phandle_references, NULL, NULL, fixup_phandle_references, NULL, ERROR, 371CHECK(phandle_references, NULL, NULL, fixup_phandle_references, NULL, ERROR,
323 &duplicate_node_names, &explicit_phandles); 372 &duplicate_node_names, &explicit_phandles);
@@ -498,6 +547,7 @@ TREE_CHECK(obsolete_chosen_interrupt_controller, NULL, WARN);
498 547
499static struct check *check_table[] = { 548static struct check *check_table[] = {
500 &duplicate_node_names, &duplicate_property_names, 549 &duplicate_node_names, &duplicate_property_names,
550 &node_name_chars, &node_name_format, &property_name_chars,
501 &name_is_string, &name_properties, 551 &name_is_string, &name_properties,
502 &explicit_phandles, 552 &explicit_phandles,
503 &phandle_references, &path_references, 553 &phandle_references, &path_references,
@@ -511,10 +561,7 @@ static struct check *check_table[] = {
511 &obsolete_chosen_interrupt_controller, 561 &obsolete_chosen_interrupt_controller,
512}; 562};
513 563
514int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys); 564void process_checks(int force, struct boot_info *bi)
515
516void process_checks(int force, struct boot_info *bi,
517 int checkflag, int outversion, int boot_cpuid_phys)
518{ 565{
519 struct node *dt = bi->dt; 566 struct node *dt = bi->dt;
520 int i; 567 int i;
@@ -537,214 +584,4 @@ void process_checks(int force, struct boot_info *bi,
537 "output forced\n"); 584 "output forced\n");
538 } 585 }
539 } 586 }
540
541 if (checkflag) {
542 if (error) {
543 fprintf(stderr, "Warning: Skipping semantic checks due to structural errors\n");
544 } else {
545 if (!check_semantics(bi->dt, outversion,
546 boot_cpuid_phys))
547 fprintf(stderr, "Warning: Input tree has semantic errors\n");
548 }
549 }
550}
551
552/*
553 * Semantic check functions
554 */
555
556#define ERRMSG(...) if (quiet < 2) fprintf(stderr, "ERROR: " __VA_ARGS__)
557#define WARNMSG(...) if (quiet < 1) fprintf(stderr, "Warning: " __VA_ARGS__)
558
559#define DO_ERR(...) do {ERRMSG(__VA_ARGS__); ok = 0; } while (0)
560
561#define CHECK_HAVE(node, propname) \
562 do { \
563 if (! (prop = get_property((node), (propname)))) \
564 DO_ERR("Missing \"%s\" property in %s\n", (propname), \
565 (node)->fullpath); \
566 } while (0);
567
568#define CHECK_HAVE_WARN(node, propname) \
569 do { \
570 if (! (prop = get_property((node), (propname)))) \
571 WARNMSG("%s has no \"%s\" property\n", \
572 (node)->fullpath, (propname)); \
573 } while (0)
574
575#define CHECK_HAVE_STRING(node, propname) \
576 do { \
577 CHECK_HAVE((node), (propname)); \
578 if (prop && !data_is_one_string(prop->val)) \
579 DO_ERR("\"%s\" property in %s is not a string\n", \
580 (propname), (node)->fullpath); \
581 } while (0)
582
583#define CHECK_HAVE_STREQ(node, propname, value) \
584 do { \
585 CHECK_HAVE_STRING((node), (propname)); \
586 if (prop && !streq(prop->val.val, (value))) \
587 DO_ERR("%s has wrong %s, %s (should be %s\n", \
588 (node)->fullpath, (propname), \
589 prop->val.val, (value)); \
590 } while (0)
591
592#define CHECK_HAVE_ONECELL(node, propname) \
593 do { \
594 CHECK_HAVE((node), (propname)); \
595 if (prop && (prop->val.len != sizeof(cell_t))) \
596 DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \
597 } while (0)
598
599#define CHECK_HAVE_WARN_ONECELL(node, propname) \
600 do { \
601 CHECK_HAVE_WARN((node), (propname)); \
602 if (prop && (prop->val.len != sizeof(cell_t))) \
603 DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \
604 } while (0)
605
606#define CHECK_HAVE_WARN_PHANDLE(xnode, propname, root) \
607 do { \
608 struct node *ref; \
609 CHECK_HAVE_WARN_ONECELL((xnode), (propname)); \
610 if (prop) {\
611 cell_t phandle = propval_cell(prop); \
612 if ((phandle == 0) || (phandle == -1)) { \
613 DO_ERR("\"%s\" property in %s contains an invalid phandle %x\n", (propname), (xnode)->fullpath, phandle); \
614 } else { \
615 ref = get_node_by_phandle((root), propval_cell(prop)); \
616 if (! ref) \
617 DO_ERR("\"%s\" property in %s refers to non-existant phandle %x\n", (propname), (xnode)->fullpath, propval_cell(prop)); \
618 } \
619 } \
620 } while (0)
621
622#define CHECK_HAVE_WARN_STRING(node, propname) \
623 do { \
624 CHECK_HAVE_WARN((node), (propname)); \
625 if (prop && !data_is_one_string(prop->val)) \
626 DO_ERR("\"%s\" property in %s is not a string\n", \
627 (propname), (node)->fullpath); \
628 } while (0)
629
630static int check_root(struct node *root)
631{
632 struct property *prop;
633 int ok = 1;
634
635 CHECK_HAVE_STRING(root, "model");
636 CHECK_HAVE_WARN(root, "compatible");
637
638 return ok;
639}
640
641static int check_cpus(struct node *root, int outversion, int boot_cpuid_phys)
642{
643 struct node *cpus, *cpu;
644 struct property *prop;
645 struct node *bootcpu = NULL;
646 int ok = 1;
647
648 cpus = get_subnode(root, "cpus");
649 if (! cpus) {
650 ERRMSG("Missing /cpus node\n");
651 return 0;
652 }
653
654 if (cpus->addr_cells != 1)
655 DO_ERR("%s has bad #address-cells value %d (should be 1)\n",
656 cpus->fullpath, cpus->addr_cells);
657 if (cpus->size_cells != 0)
658 DO_ERR("%s has bad #size-cells value %d (should be 0)\n",
659 cpus->fullpath, cpus->size_cells);
660
661 for_each_child(cpus, cpu) {
662 CHECK_HAVE_STREQ(cpu, "device_type", "cpu");
663
664 CHECK_HAVE_ONECELL(cpu, "reg");
665 if (prop) {
666 cell_t unitnum;
667 char *eptr;
668
669 unitnum = strtol(get_unitname(cpu), &eptr, 16);
670 if (*eptr) {
671 WARNMSG("%s has bad format unit name %s (should be CPU number\n",
672 cpu->fullpath, get_unitname(cpu));
673 } else if (unitnum != propval_cell(prop)) {
674 WARNMSG("%s unit name \"%s\" does not match \"reg\" property <%x>\n",
675 cpu->fullpath, get_unitname(cpu),
676 propval_cell(prop));
677 }
678 }
679
680/* CHECK_HAVE_ONECELL(cpu, "d-cache-line-size"); */
681/* CHECK_HAVE_ONECELL(cpu, "i-cache-line-size"); */
682 CHECK_HAVE_ONECELL(cpu, "d-cache-size");
683 CHECK_HAVE_ONECELL(cpu, "i-cache-size");
684
685 CHECK_HAVE_WARN_ONECELL(cpu, "clock-frequency");
686 CHECK_HAVE_WARN_ONECELL(cpu, "timebase-frequency");
687
688 prop = get_property(cpu, "linux,boot-cpu");
689 if (prop) {
690 if (prop->val.len)
691 WARNMSG("\"linux,boot-cpu\" property in %s is non-empty\n",
692 cpu->fullpath);
693 if (bootcpu)
694 DO_ERR("Multiple boot cpus (%s and %s)\n",
695 bootcpu->fullpath, cpu->fullpath);
696 else
697 bootcpu = cpu;
698 }
699 }
700
701 if (outversion < 2) {
702 if (! bootcpu)
703 WARNMSG("No cpu has \"linux,boot-cpu\" property\n");
704 } else {
705 if (bootcpu)
706 WARNMSG("\"linux,boot-cpu\" property is deprecated in blob version 2 or higher\n");
707 if (boot_cpuid_phys == 0xfeedbeef)
708 WARNMSG("physical boot CPU not set. Use -b option to set\n");
709 }
710
711 return ok;
712}
713
714static int check_memory(struct node *root)
715{
716 struct node *mem;
717 struct property *prop;
718 int nnodes = 0;
719 int ok = 1;
720
721 for_each_child(root, mem) {
722 if (! strneq(mem->name, "memory", mem->basenamelen))
723 continue;
724
725 nnodes++;
726
727 CHECK_HAVE_STREQ(mem, "device_type", "memory");
728 CHECK_HAVE(mem, "reg");
729 }
730
731 if (nnodes == 0) {
732 ERRMSG("No memory nodes\n");
733 return 0;
734 }
735
736 return ok;
737}
738
739int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys)
740{
741 int ok = 1;
742
743 ok = ok && check_root(dt);
744 ok = ok && check_cpus(dt, outversion, boot_cpuid_phys);
745 ok = ok && check_memory(dt);
746 if (! ok)
747 return 0;
748
749 return 1;
750} 587}
diff --git a/arch/powerpc/boot/dtc-src/data.c b/arch/powerpc/boot/dtc-src/data.c
index a94718c731a9..dd2e3d39d4c1 100644
--- a/arch/powerpc/boot/dtc-src/data.c
+++ b/arch/powerpc/boot/dtc-src/data.c
@@ -32,8 +32,6 @@ void data_free(struct data d)
32 m = nm; 32 m = nm;
33 } 33 }
34 34
35 assert(!d.val || d.asize);
36
37 if (d.val) 35 if (d.val)
38 free(d.val); 36 free(d.val);
39} 37}
@@ -43,9 +41,6 @@ struct data data_grow_for(struct data d, int xlen)
43 struct data nd; 41 struct data nd;
44 int newsize; 42 int newsize;
45 43
46 /* we must start with an allocated datum */
47 assert(!d.val || d.asize);
48
49 if (xlen == 0) 44 if (xlen == 0)
50 return d; 45 return d;
51 46
@@ -56,11 +51,8 @@ struct data data_grow_for(struct data d, int xlen)
56 while ((d.len + xlen) > newsize) 51 while ((d.len + xlen) > newsize)
57 newsize *= 2; 52 newsize *= 2;
58 53
59 nd.asize = newsize;
60 nd.val = xrealloc(d.val, newsize); 54 nd.val = xrealloc(d.val, newsize);
61 55
62 assert(nd.asize >= (d.len + xlen));
63
64 return nd; 56 return nd;
65} 57}
66 58
@@ -83,16 +75,11 @@ static char get_oct_char(const char *s, int *i)
83 long val; 75 long val;
84 76
85 x[3] = '\0'; 77 x[3] = '\0';
86 x[0] = s[(*i)]; 78 strncpy(x, s + *i, 3);
87 if (x[0]) {
88 x[1] = s[(*i)+1];
89 if (x[1])
90 x[2] = s[(*i)+2];
91 }
92 79
93 val = strtol(x, &endx, 8); 80 val = strtol(x, &endx, 8);
94 if ((endx - x) == 0) 81
95 fprintf(stderr, "Empty \\nnn escape\n"); 82 assert(endx > x);
96 83
97 (*i) += endx - x; 84 (*i) += endx - x;
98 return val; 85 return val;
@@ -105,13 +92,11 @@ static char get_hex_char(const char *s, int *i)
105 long val; 92 long val;
106 93
107 x[2] = '\0'; 94 x[2] = '\0';
108 x[0] = s[(*i)]; 95 strncpy(x, s + *i, 2);
109 if (x[0])
110 x[1] = s[(*i)+1];
111 96
112 val = strtol(x, &endx, 16); 97 val = strtol(x, &endx, 16);
113 if ((endx - x) == 0) 98 if (!(endx > x))
114 fprintf(stderr, "Empty \\x escape\n"); 99 die("\\x used with no following hex digits\n");
115 100
116 (*i) += endx - x; 101 (*i) += endx - x;
117 return val; 102 return val;
@@ -182,14 +167,29 @@ struct data data_copy_escape_string(const char *s, int len)
182 return d; 167 return d;
183} 168}
184 169
185struct data data_copy_file(FILE *f, size_t len) 170struct data data_copy_file(FILE *f, size_t maxlen)
186{ 171{
187 struct data d; 172 struct data d = empty_data;
188 173
189 d = data_grow_for(empty_data, len); 174 while (!feof(f) && (d.len < maxlen)) {
175 size_t chunksize, ret;
190 176
191 d.len = len; 177 if (maxlen == -1)
192 fread(d.val, len, 1, f); 178 chunksize = 4096;
179 else
180 chunksize = maxlen - d.len;
181
182 d = data_grow_for(d, chunksize);
183 ret = fread(d.val + d.len, 1, chunksize, f);
184
185 if (ferror(f))
186 die("Error reading file into data: %s", strerror(errno));
187
188 if (d.len + ret < d.len)
189 die("Overflow reading file into data\n");
190
191 d.len += ret;
192 }
193 193
194 return d; 194 return d;
195} 195}
@@ -247,7 +247,7 @@ struct data data_merge(struct data d1, struct data d2)
247 247
248struct data data_append_cell(struct data d, cell_t word) 248struct data data_append_cell(struct data d, cell_t word)
249{ 249{
250 cell_t beword = cpu_to_be32(word); 250 cell_t beword = cpu_to_fdt32(word);
251 251
252 return data_append_data(d, &beword, sizeof(beword)); 252 return data_append_data(d, &beword, sizeof(beword));
253} 253}
@@ -256,15 +256,15 @@ struct data data_append_re(struct data d, const struct fdt_reserve_entry *re)
256{ 256{
257 struct fdt_reserve_entry bere; 257 struct fdt_reserve_entry bere;
258 258
259 bere.address = cpu_to_be64(re->address); 259 bere.address = cpu_to_fdt64(re->address);
260 bere.size = cpu_to_be64(re->size); 260 bere.size = cpu_to_fdt64(re->size);
261 261
262 return data_append_data(d, &bere, sizeof(bere)); 262 return data_append_data(d, &bere, sizeof(bere));
263} 263}
264 264
265struct data data_append_addr(struct data d, u64 addr) 265struct data data_append_addr(struct data d, uint64_t addr)
266{ 266{
267 u64 beaddr = cpu_to_be64(addr); 267 uint64_t beaddr = cpu_to_fdt64(addr);
268 268
269 return data_append_data(d, &beaddr, sizeof(beaddr)); 269 return data_append_data(d, &beaddr, sizeof(beaddr));
270} 270}
diff --git a/arch/powerpc/boot/dtc-src/dtc-lexer.l b/arch/powerpc/boot/dtc-src/dtc-lexer.l
index c811b221b31e..44dbfd3f0976 100644
--- a/arch/powerpc/boot/dtc-src/dtc-lexer.l
+++ b/arch/powerpc/boot/dtc-src/dtc-lexer.l
@@ -28,6 +28,10 @@
28PROPNODECHAR [a-zA-Z0-9,._+*#?@-] 28PROPNODECHAR [a-zA-Z0-9,._+*#?@-]
29PATHCHAR ({PROPNODECHAR}|[/]) 29PATHCHAR ({PROPNODECHAR}|[/])
30LABEL [a-zA-Z_][a-zA-Z0-9_]* 30LABEL [a-zA-Z_][a-zA-Z0-9_]*
31STRING \"([^\\"]|\\.)*\"
32WS [[:space:]]
33COMMENT "/*"([^*]|\*+[^*/])*\*+"/"
34LINECOMMENT "//".*\n
31 35
32%{ 36%{
33#include "dtc.h" 37#include "dtc.h"
@@ -52,29 +56,26 @@ static int dts_version; /* = 0 */
52 DPRINT("<V1>\n"); \ 56 DPRINT("<V1>\n"); \
53 BEGIN(V1); \ 57 BEGIN(V1); \
54 } 58 }
59
60static void push_input_file(const char *filename);
61static int pop_input_file(void);
55%} 62%}
56 63
57%% 64%%
58<*>"/include/" BEGIN(INCLUDE); 65<*>"/include/"{WS}*{STRING} {
59 66 char *name = strchr(yytext, '\"') + 1;
60<INCLUDE>\"[^"\n]*\" { 67 yytext[yyleng-1] = '\0';
61 yytext[strlen(yytext) - 1] = 0; 68 push_input_file(name);
62 if (!push_input_file(yytext + 1)) {
63 /* Some unrecoverable error.*/
64 exit(1);
65 }
66 BEGIN_DEFAULT();
67 } 69 }
68 70
69
70<*><<EOF>> { 71<*><<EOF>> {
71 if (!pop_input_file()) { 72 if (!pop_input_file()) {
72 yyterminate(); 73 yyterminate();
73 } 74 }
74 } 75 }
75 76
76<*>\"([^\\"]|\\.)*\" { 77<*>{STRING} {
77 yylloc.filenum = srcpos_filenum; 78 yylloc.file = srcpos_file;
78 yylloc.first_line = yylineno; 79 yylloc.first_line = yylineno;
79 DPRINT("String: %s\n", yytext); 80 DPRINT("String: %s\n", yytext);
80 yylval.data = data_copy_escape_string(yytext+1, 81 yylval.data = data_copy_escape_string(yytext+1,
@@ -84,7 +85,7 @@ static int dts_version; /* = 0 */
84 } 85 }
85 86
86<*>"/dts-v1/" { 87<*>"/dts-v1/" {
87 yylloc.filenum = srcpos_filenum; 88 yylloc.file = srcpos_file;
88 yylloc.first_line = yylineno; 89 yylloc.first_line = yylineno;
89 DPRINT("Keyword: /dts-v1/\n"); 90 DPRINT("Keyword: /dts-v1/\n");
90 dts_version = 1; 91 dts_version = 1;
@@ -93,7 +94,7 @@ static int dts_version; /* = 0 */
93 } 94 }
94 95
95<*>"/memreserve/" { 96<*>"/memreserve/" {
96 yylloc.filenum = srcpos_filenum; 97 yylloc.file = srcpos_file;
97 yylloc.first_line = yylineno; 98 yylloc.first_line = yylineno;
98 DPRINT("Keyword: /memreserve/\n"); 99 DPRINT("Keyword: /memreserve/\n");
99 BEGIN_DEFAULT(); 100 BEGIN_DEFAULT();
@@ -101,7 +102,7 @@ static int dts_version; /* = 0 */
101 } 102 }
102 103
103<*>{LABEL}: { 104<*>{LABEL}: {
104 yylloc.filenum = srcpos_filenum; 105 yylloc.file = srcpos_file;
105 yylloc.first_line = yylineno; 106 yylloc.first_line = yylineno;
106 DPRINT("Label: %s\n", yytext); 107 DPRINT("Label: %s\n", yytext);
107 yylval.labelref = strdup(yytext); 108 yylval.labelref = strdup(yytext);
@@ -110,7 +111,7 @@ static int dts_version; /* = 0 */
110 } 111 }
111 112
112<INITIAL>[bodh]# { 113<INITIAL>[bodh]# {
113 yylloc.filenum = srcpos_filenum; 114 yylloc.file = srcpos_file;
114 yylloc.first_line = yylineno; 115 yylloc.first_line = yylineno;
115 if (*yytext == 'b') 116 if (*yytext == 'b')
116 yylval.cbase = 2; 117 yylval.cbase = 2;
@@ -125,7 +126,7 @@ static int dts_version; /* = 0 */
125 } 126 }
126 127
127<INITIAL>[0-9a-fA-F]+ { 128<INITIAL>[0-9a-fA-F]+ {
128 yylloc.filenum = srcpos_filenum; 129 yylloc.file = srcpos_file;
129 yylloc.first_line = yylineno; 130 yylloc.first_line = yylineno;
130 yylval.literal = strdup(yytext); 131 yylval.literal = strdup(yytext);
131 DPRINT("Literal: '%s'\n", yylval.literal); 132 DPRINT("Literal: '%s'\n", yylval.literal);
@@ -133,7 +134,7 @@ static int dts_version; /* = 0 */
133 } 134 }
134 135
135<V1>[0-9]+|0[xX][0-9a-fA-F]+ { 136<V1>[0-9]+|0[xX][0-9a-fA-F]+ {
136 yylloc.filenum = srcpos_filenum; 137 yylloc.file = srcpos_file;
137 yylloc.first_line = yylineno; 138 yylloc.first_line = yylineno;
138 yylval.literal = strdup(yytext); 139 yylval.literal = strdup(yytext);
139 DPRINT("Literal: '%s'\n", yylval.literal); 140 DPRINT("Literal: '%s'\n", yylval.literal);
@@ -141,7 +142,7 @@ static int dts_version; /* = 0 */
141 } 142 }
142 143
143\&{LABEL} { /* label reference */ 144\&{LABEL} { /* label reference */
144 yylloc.filenum = srcpos_filenum; 145 yylloc.file = srcpos_file;
145 yylloc.first_line = yylineno; 146 yylloc.first_line = yylineno;
146 DPRINT("Ref: %s\n", yytext+1); 147 DPRINT("Ref: %s\n", yytext+1);
147 yylval.labelref = strdup(yytext+1); 148 yylval.labelref = strdup(yytext+1);
@@ -149,7 +150,7 @@ static int dts_version; /* = 0 */
149 } 150 }
150 151
151"&{/"{PATHCHAR}+\} { /* new-style path reference */ 152"&{/"{PATHCHAR}+\} { /* new-style path reference */
152 yylloc.filenum = srcpos_filenum; 153 yylloc.file = srcpos_file;
153 yylloc.first_line = yylineno; 154 yylloc.first_line = yylineno;
154 yytext[yyleng-1] = '\0'; 155 yytext[yyleng-1] = '\0';
155 DPRINT("Ref: %s\n", yytext+2); 156 DPRINT("Ref: %s\n", yytext+2);
@@ -158,7 +159,7 @@ static int dts_version; /* = 0 */
158 } 159 }
159 160
160<INITIAL>"&/"{PATHCHAR}+ { /* old-style path reference */ 161<INITIAL>"&/"{PATHCHAR}+ { /* old-style path reference */
161 yylloc.filenum = srcpos_filenum; 162 yylloc.file = srcpos_file;
162 yylloc.first_line = yylineno; 163 yylloc.first_line = yylineno;
163 DPRINT("Ref: %s\n", yytext+1); 164 DPRINT("Ref: %s\n", yytext+1);
164 yylval.labelref = strdup(yytext+1); 165 yylval.labelref = strdup(yytext+1);
@@ -166,7 +167,7 @@ static int dts_version; /* = 0 */
166 } 167 }
167 168
168<BYTESTRING>[0-9a-fA-F]{2} { 169<BYTESTRING>[0-9a-fA-F]{2} {
169 yylloc.filenum = srcpos_filenum; 170 yylloc.file = srcpos_file;
170 yylloc.first_line = yylineno; 171 yylloc.first_line = yylineno;
171 yylval.byte = strtol(yytext, NULL, 16); 172 yylval.byte = strtol(yytext, NULL, 16);
172 DPRINT("Byte: %02x\n", (int)yylval.byte); 173 DPRINT("Byte: %02x\n", (int)yylval.byte);
@@ -174,7 +175,7 @@ static int dts_version; /* = 0 */
174 } 175 }
175 176
176<BYTESTRING>"]" { 177<BYTESTRING>"]" {
177 yylloc.filenum = srcpos_filenum; 178 yylloc.file = srcpos_file;
178 yylloc.first_line = yylineno; 179 yylloc.first_line = yylineno;
179 DPRINT("/BYTESTRING\n"); 180 DPRINT("/BYTESTRING\n");
180 BEGIN_DEFAULT(); 181 BEGIN_DEFAULT();
@@ -182,7 +183,7 @@ static int dts_version; /* = 0 */
182 } 183 }
183 184
184<PROPNODENAME>{PROPNODECHAR}+ { 185<PROPNODENAME>{PROPNODECHAR}+ {
185 yylloc.filenum = srcpos_filenum; 186 yylloc.file = srcpos_file;
186 yylloc.first_line = yylineno; 187 yylloc.first_line = yylineno;
187 DPRINT("PropNodeName: %s\n", yytext); 188 DPRINT("PropNodeName: %s\n", yytext);
188 yylval.propnodename = strdup(yytext); 189 yylval.propnodename = strdup(yytext);
@@ -190,20 +191,19 @@ static int dts_version; /* = 0 */
190 return DT_PROPNODENAME; 191 return DT_PROPNODENAME;
191 } 192 }
192 193
193 194"/incbin/" {
194<*>[[:space:]]+ /* eat whitespace */ 195 yylloc.file = srcpos_file;
195
196<*>"/*"([^*]|\*+[^*/])*\*+"/" {
197 yylloc.filenum = srcpos_filenum;
198 yylloc.first_line = yylineno; 196 yylloc.first_line = yylineno;
199 DPRINT("Comment: %s\n", yytext); 197 DPRINT("Binary Include\n");
200 /* eat comments */ 198 return DT_INCBIN;
201 } 199 }
202 200
203<*>"//".*\n /* eat line comments */ 201<*>{WS}+ /* eat whitespace */
202<*>{COMMENT}+ /* eat C-style comments */
203<*>{LINECOMMENT}+ /* eat C++-style comments */
204 204
205<*>. { 205<*>. {
206 yylloc.filenum = srcpos_filenum; 206 yylloc.file = srcpos_file;
207 yylloc.first_line = yylineno; 207 yylloc.first_line = yylineno;
208 DPRINT("Char: %c (\\x%02x)\n", yytext[0], 208 DPRINT("Char: %c (\\x%02x)\n", yytext[0],
209 (unsigned)yytext[0]); 209 (unsigned)yytext[0]);
@@ -227,14 +227,13 @@ static int dts_version; /* = 0 */
227 */ 227 */
228 228
229struct incl_file { 229struct incl_file {
230 int filenum; 230 struct dtc_file *file;
231 FILE *file;
232 YY_BUFFER_STATE yy_prev_buf; 231 YY_BUFFER_STATE yy_prev_buf;
233 int yy_prev_lineno; 232 int yy_prev_lineno;
234 struct incl_file *prev; 233 struct incl_file *prev;
235}; 234};
236 235
237struct incl_file *incl_file_stack; 236static struct incl_file *incl_file_stack;
238 237
239 238
240/* 239/*
@@ -245,36 +244,34 @@ struct incl_file *incl_file_stack;
245static int incl_depth = 0; 244static int incl_depth = 0;
246 245
247 246
248int push_input_file(const char *filename) 247static void push_input_file(const char *filename)
249{ 248{
250 FILE *f;
251 struct incl_file *incl_file; 249 struct incl_file *incl_file;
250 struct dtc_file *newfile;
251 struct search_path search, *searchptr = NULL;
252 252
253 if (!filename) { 253 assert(filename);
254 yyerror("No include file name given.");
255 return 0;
256 }
257 254
258 if (incl_depth++ >= MAX_INCLUDE_DEPTH) { 255 if (incl_depth++ >= MAX_INCLUDE_DEPTH)
259 yyerror("Includes nested too deeply"); 256 die("Includes nested too deeply");
260 return 0; 257
258 if (srcpos_file) {
259 search.dir = srcpos_file->dir;
260 search.next = NULL;
261 search.prev = NULL;
262 searchptr = &search;
261 } 263 }
262 264
263 f = dtc_open_file(filename); 265 newfile = dtc_open_file(filename, searchptr);
264 266
265 incl_file = malloc(sizeof(struct incl_file)); 267 incl_file = xmalloc(sizeof(struct incl_file));
266 if (!incl_file) {
267 yyerror("Can not allocate include file space.");
268 return 0;
269 }
270 268
271 /* 269 /*
272 * Save current context. 270 * Save current context.
273 */ 271 */
274 incl_file->yy_prev_buf = YY_CURRENT_BUFFER; 272 incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
275 incl_file->yy_prev_lineno = yylineno; 273 incl_file->yy_prev_lineno = yylineno;
276 incl_file->filenum = srcpos_filenum; 274 incl_file->file = srcpos_file;
277 incl_file->file = yyin;
278 incl_file->prev = incl_file_stack; 275 incl_file->prev = incl_file_stack;
279 276
280 incl_file_stack = incl_file; 277 incl_file_stack = incl_file;
@@ -282,23 +279,21 @@ int push_input_file(const char *filename)
282 /* 279 /*
283 * Establish new context. 280 * Establish new context.
284 */ 281 */
285 srcpos_filenum = lookup_file_name(filename, 0); 282 srcpos_file = newfile;
286 yylineno = 1; 283 yylineno = 1;
287 yyin = f; 284 yyin = newfile->file;
288 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); 285 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
289
290 return 1;
291} 286}
292 287
293 288
294int pop_input_file(void) 289static int pop_input_file(void)
295{ 290{
296 struct incl_file *incl_file; 291 struct incl_file *incl_file;
297 292
298 if (incl_file_stack == 0) 293 if (incl_file_stack == 0)
299 return 0; 294 return 0;
300 295
301 fclose(yyin); 296 dtc_close_file(srcpos_file);
302 297
303 /* 298 /*
304 * Pop. 299 * Pop.
@@ -313,16 +308,13 @@ int pop_input_file(void)
313 yy_delete_buffer(YY_CURRENT_BUFFER); 308 yy_delete_buffer(YY_CURRENT_BUFFER);
314 yy_switch_to_buffer(incl_file->yy_prev_buf); 309 yy_switch_to_buffer(incl_file->yy_prev_buf);
315 yylineno = incl_file->yy_prev_lineno; 310 yylineno = incl_file->yy_prev_lineno;
316 srcpos_filenum = incl_file->filenum; 311 srcpos_file = incl_file->file;
317 yyin = incl_file->file; 312 yyin = incl_file->file ? incl_file->file->file : NULL;
318 313
319 /* 314 /*
320 * Free old state. 315 * Free old state.
321 */ 316 */
322 free(incl_file); 317 free(incl_file);
323 318
324 if (YY_CURRENT_BUFFER == 0)
325 return 0;
326
327 return 1; 319 return 1;
328} 320}
diff --git a/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped b/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped
index d0f742460f92..ac392cb040f6 100644
--- a/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped
+++ b/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped
@@ -9,7 +9,7 @@
9#define FLEX_SCANNER 9#define FLEX_SCANNER
10#define YY_FLEX_MAJOR_VERSION 2 10#define YY_FLEX_MAJOR_VERSION 2
11#define YY_FLEX_MINOR_VERSION 5 11#define YY_FLEX_MINOR_VERSION 5
12#define YY_FLEX_SUBMINOR_VERSION 33 12#define YY_FLEX_SUBMINOR_VERSION 34
13#if YY_FLEX_SUBMINOR_VERSION > 0 13#if YY_FLEX_SUBMINOR_VERSION > 0
14#define FLEX_BETA 14#define FLEX_BETA
15#endif 15#endif
@@ -31,7 +31,7 @@
31 31
32/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ 32/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
33 33
34#if __STDC_VERSION__ >= 199901L 34#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
35 35
36/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, 36/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
37 * if you want the limit (max/min) macros for int types. 37 * if you want the limit (max/min) macros for int types.
@@ -94,11 +94,12 @@ typedef unsigned int flex_uint32_t;
94 94
95#else /* ! __cplusplus */ 95#else /* ! __cplusplus */
96 96
97#if __STDC__ 97/* C99 requires __STDC__ to be defined as 1. */
98#if defined (__STDC__)
98 99
99#define YY_USE_CONST 100#define YY_USE_CONST
100 101
101#endif /* __STDC__ */ 102#endif /* defined (__STDC__) */
102#endif /* ! __cplusplus */ 103#endif /* ! __cplusplus */
103 104
104#ifdef YY_USE_CONST 105#ifdef YY_USE_CONST
@@ -194,11 +195,13 @@ extern FILE *yyin, *yyout;
194/* The following is because we cannot portably get our hands on size_t 195/* The following is because we cannot portably get our hands on size_t
195 * (without autoconf's help, which isn't available because we want 196 * (without autoconf's help, which isn't available because we want
196 * flex-generated scanners to compile on their own). 197 * flex-generated scanners to compile on their own).
198 * Given that the standard has decreed that size_t exists since 1989,
199 * I guess we can afford to depend on it. Manoj.
197 */ 200 */
198 201
199#ifndef YY_TYPEDEF_YY_SIZE_T 202#ifndef YY_TYPEDEF_YY_SIZE_T
200#define YY_TYPEDEF_YY_SIZE_T 203#define YY_TYPEDEF_YY_SIZE_T
201typedef unsigned int yy_size_t; 204typedef size_t yy_size_t;
202#endif 205#endif
203 206
204#ifndef YY_STRUCT_YY_BUFFER_STATE 207#ifndef YY_STRUCT_YY_BUFFER_STATE
@@ -349,7 +352,7 @@ void yyfree (void * );
349 352
350/* Begin user sect3 */ 353/* Begin user sect3 */
351 354
352#define yywrap() 1 355#define yywrap(n) 1
353#define YY_SKIP_YYWRAP 356#define YY_SKIP_YYWRAP
354 357
355typedef unsigned char YY_CHAR; 358typedef unsigned char YY_CHAR;
@@ -389,19 +392,20 @@ struct yy_trans_info
389 flex_int32_t yy_verify; 392 flex_int32_t yy_verify;
390 flex_int32_t yy_nxt; 393 flex_int32_t yy_nxt;
391 }; 394 };
392static yyconst flex_int16_t yy_accept[94] = 395static yyconst flex_int16_t yy_accept[104] =
393 { 0, 396 { 0,
394 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 397 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
395 21, 19, 16, 16, 19, 19, 19, 8, 8, 19, 398 21, 19, 16, 16, 19, 19, 19, 7, 7, 19,
396 8, 19, 19, 19, 19, 14, 15, 15, 19, 9, 399 7, 19, 19, 19, 19, 13, 14, 14, 19, 8,
397 9, 16, 0, 3, 0, 0, 10, 0, 0, 0, 400 8, 16, 0, 2, 0, 0, 9, 0, 0, 0,
398 0, 0, 0, 8, 8, 6, 0, 7, 0, 2, 401 0, 0, 0, 7, 7, 5, 0, 6, 0, 12,
399 0, 13, 13, 15, 15, 9, 0, 12, 10, 0, 402 12, 14, 14, 8, 0, 11, 9, 0, 0, 0,
400 0, 0, 0, 18, 0, 0, 0, 2, 9, 0, 403 0, 18, 0, 0, 0, 0, 8, 0, 17, 0,
401 17, 0, 0, 0, 11, 0, 0, 0, 0, 0, 404 0, 0, 0, 0, 10, 0, 0, 0, 0, 0,
402 0, 0, 0, 0, 4, 0, 0, 1, 0, 0, 405 0, 0, 0, 0, 0, 0, 0, 0, 3, 15,
403 0, 5, 0 406 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
404 407
408 0, 4, 0
405 } ; 409 } ;
406 410
407static yyconst flex_int32_t yy_ec[256] = 411static yyconst flex_int32_t yy_ec[256] =
@@ -444,122 +448,126 @@ static yyconst flex_int32_t yy_meta[36] =
444 7, 7, 7, 8, 1 448 7, 7, 7, 8, 1
445 } ; 449 } ;
446 450
447static yyconst flex_int16_t yy_base[107] = 451static yyconst flex_int16_t yy_base[117] =
448 { 0, 452 { 0,
449 0, 0, 32, 0, 53, 0, 76, 0, 108, 111, 453 0, 0, 30, 0, 44, 0, 67, 0, 97, 105,
450 280, 288, 37, 39, 33, 36, 106, 0, 123, 146, 454 302, 303, 35, 44, 40, 94, 112, 0, 129, 152,
451 255, 251, 45, 0, 159, 288, 0, 53, 108, 172, 455 296, 295, 159, 0, 176, 303, 0, 116, 95, 165,
452 114, 127, 158, 288, 245, 0, 0, 234, 235, 236, 456 49, 46, 102, 303, 296, 0, 0, 288, 290, 293,
453 197, 195, 199, 0, 0, 288, 0, 288, 160, 288, 457 264, 266, 270, 0, 0, 303, 0, 303, 264, 303,
454 183, 288, 0, 0, 183, 182, 0, 0, 0, 0, 458 0, 0, 195, 101, 0, 0, 0, 0, 284, 125,
455 204, 189, 207, 288, 179, 187, 180, 194, 0, 171, 459 277, 265, 225, 230, 216, 218, 0, 202, 224, 221,
456 288, 196, 178, 174, 288, 169, 169, 177, 165, 153, 460 217, 107, 196, 188, 303, 206, 179, 186, 178, 185,
457 143, 155, 137, 118, 288, 122, 42, 288, 36, 36, 461 183, 162, 161, 150, 169, 160, 145, 125, 303, 303,
458 40, 288, 288, 212, 218, 223, 229, 234, 239, 245, 462 137, 109, 190, 103, 203, 167, 108, 197, 303, 123,
459 463
460 251, 255, 262, 270, 275, 280 464 29, 303, 303, 215, 221, 226, 229, 234, 240, 246,
465 250, 257, 265, 270, 275, 282
461 } ; 466 } ;
462 467
463static yyconst flex_int16_t yy_def[107] = 468static yyconst flex_int16_t yy_def[117] =
464 { 0, 469 { 0,
465 93, 1, 1, 3, 3, 5, 93, 7, 3, 3, 470 103, 1, 1, 3, 3, 5, 103, 7, 3, 3,
466 93, 93, 93, 93, 94, 95, 93, 96, 93, 19, 471 103, 103, 103, 103, 104, 105, 103, 106, 103, 19,
467 19, 20, 97, 98, 20, 93, 99, 100, 95, 93, 472 19, 20, 103, 107, 20, 103, 108, 109, 105, 103,
468 93, 93, 94, 93, 94, 101, 102, 93, 103, 104, 473 103, 103, 104, 103, 104, 110, 111, 103, 112, 113,
469 93, 93, 93, 96, 19, 93, 20, 93, 97, 93, 474 103, 103, 103, 106, 19, 103, 20, 103, 103, 103,
470 97, 93, 20, 99, 100, 93, 105, 101, 102, 106, 475 20, 108, 109, 103, 114, 110, 111, 115, 112, 112,
471 103, 103, 104, 93, 93, 93, 93, 94, 105, 106, 476 113, 103, 103, 103, 103, 103, 114, 115, 103, 103,
472 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 477 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
473 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 478 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
474 93, 93, 0, 93, 93, 93, 93, 93, 93, 93, 479 103, 103, 103, 103, 103, 116, 103, 116, 103, 116,
475 480
476 93, 93, 93, 93, 93, 93 481 103, 103, 0, 103, 103, 103, 103, 103, 103, 103,
482 103, 103, 103, 103, 103, 103
477 } ; 483 } ;
478 484
479static yyconst flex_int16_t yy_nxt[324] = 485static yyconst flex_int16_t yy_nxt[339] =
480 { 0, 486 { 0,
481 12, 13, 14, 15, 12, 16, 12, 12, 12, 17, 487 12, 13, 14, 15, 12, 16, 12, 12, 12, 17,
482 18, 18, 18, 12, 19, 20, 20, 12, 12, 21, 488 18, 18, 18, 12, 19, 20, 20, 12, 12, 21,
483 19, 21, 19, 22, 20, 20, 20, 20, 20, 20, 489 19, 21, 19, 22, 20, 20, 20, 20, 20, 20,
484 20, 20, 20, 12, 12, 23, 34, 12, 32, 32, 490 20, 20, 20, 12, 12, 12, 32, 32, 102, 23,
485 32, 32, 12, 12, 12, 36, 20, 33, 50, 92, 491 12, 12, 12, 34, 20, 32, 32, 32, 32, 20,
486 35, 20, 20, 20, 20, 20, 15, 54, 91, 54, 492 20, 20, 20, 20, 24, 24, 24, 35, 25, 54,
487 54, 54, 51, 24, 24, 24, 46, 25, 90, 38, 493 54, 54, 26, 25, 25, 25, 25, 12, 13, 14,
488 89, 26, 25, 25, 25, 25, 12, 13, 14, 15, 494 15, 27, 12, 27, 27, 27, 23, 27, 27, 27,
489 27, 12, 27, 27, 27, 17, 27, 27, 27, 12, 495 12, 28, 28, 28, 12, 12, 28, 28, 28, 28,
490 28, 28, 28, 12, 12, 28, 28, 28, 28, 28, 496 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
491 497
492 28, 28, 28, 28, 28, 28, 28, 28, 28, 12, 498 12, 12, 29, 36, 103, 34, 17, 30, 31, 31,
493 12, 15, 39, 29, 15, 40, 29, 93, 30, 31, 499 29, 54, 54, 54, 17, 30, 31, 31, 39, 35,
494 31, 30, 31, 31, 56, 56, 56, 41, 32, 32, 500 52, 40, 52, 52, 52, 103, 78, 38, 38, 46,
495 42, 88, 43, 45, 45, 45, 46, 45, 47, 47, 501 101, 60, 79, 41, 69, 97, 42, 94, 43, 45,
496 87, 38, 45, 45, 45, 45, 47, 47, 47, 47, 502 45, 45, 46, 45, 47, 47, 93, 92, 45, 45,
497 47, 47, 47, 47, 47, 47, 47, 47, 47, 86, 503 45, 45, 47, 47, 47, 47, 47, 47, 47, 47,
498 47, 34, 33, 50, 85, 47, 47, 47, 47, 53, 504 47, 47, 47, 47, 47, 39, 47, 91, 40, 90,
499 53, 53, 84, 53, 83, 35, 82, 51, 53, 53, 505 99, 47, 47, 47, 47, 54, 54, 54, 89, 88,
500 53, 53, 56, 56, 56, 93, 68, 54, 57, 54, 506 41, 55, 87, 49, 100, 43, 51, 51, 51, 86,
501 54, 54, 56, 56, 56, 62, 46, 34, 71, 81, 507 51, 95, 95, 96, 85, 51, 51, 51, 51, 52,
502 508
503 80, 79, 78, 77, 76, 75, 74, 73, 72, 64, 509 99, 52, 52, 52, 95, 95, 96, 84, 46, 83,
504 62, 35, 33, 33, 33, 33, 33, 33, 33, 33, 510 82, 81, 39, 79, 100, 33, 33, 33, 33, 33,
505 37, 67, 66, 37, 37, 37, 44, 65, 44, 49, 511 33, 33, 33, 37, 80, 77, 37, 37, 37, 44,
506 49, 49, 49, 49, 49, 49, 49, 52, 64, 52, 512 40, 44, 50, 76, 50, 52, 75, 52, 74, 52,
507 54, 62, 54, 60, 54, 54, 55, 93, 55, 55, 513 52, 53, 73, 53, 53, 53, 53, 56, 56, 56,
508 55, 55, 58, 58, 58, 48, 58, 58, 59, 48, 514 72, 56, 56, 57, 71, 57, 57, 59, 59, 59,
509 59, 59, 61, 61, 61, 61, 61, 61, 61, 61, 515 59, 59, 59, 59, 59, 61, 61, 61, 61, 61,
510 63, 63, 63, 63, 63, 63, 63, 63, 69, 93, 516 61, 61, 61, 67, 70, 67, 68, 68, 68, 62,
511 69, 70, 70, 70, 93, 70, 70, 11, 93, 93, 517 68, 68, 98, 98, 98, 98, 98, 98, 98, 98,
512 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 518 60, 66, 65, 64, 63, 62, 60, 58, 103, 48,
513 519
514 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 520 48, 103, 11, 103, 103, 103, 103, 103, 103, 103,
515 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 521 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
516 93, 93, 93 522 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
523 103, 103, 103, 103, 103, 103, 103, 103
517 } ; 524 } ;
518 525
519static yyconst flex_int16_t yy_chk[324] = 526static yyconst flex_int16_t yy_chk[339] =
520 { 0, 527 { 0,
521 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 528 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
522 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 529 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
523 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 530 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
524 1, 1, 1, 1, 1, 3, 15, 3, 13, 13, 531 1, 1, 1, 1, 1, 3, 13, 13, 101, 3,
525 14, 14, 3, 3, 3, 16, 3, 23, 23, 91, 532 3, 3, 3, 15, 3, 14, 14, 32, 32, 3,
526 15, 3, 3, 3, 3, 3, 5, 28, 90, 28, 533 3, 3, 3, 3, 5, 5, 5, 15, 5, 31,
527 28, 28, 23, 5, 5, 5, 28, 5, 89, 16, 534 31, 31, 5, 5, 5, 5, 5, 7, 7, 7,
528 87, 5, 5, 5, 5, 5, 7, 7, 7, 7,
529 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 535 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
530 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 536 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
531
532 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 537 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
533 7, 9, 17, 9, 10, 17, 10, 29, 9, 9, 538
534 9, 10, 10, 10, 31, 31, 31, 17, 32, 32, 539 7, 7, 9, 16, 29, 33, 9, 9, 9, 9,
535 17, 86, 17, 19, 19, 19, 19, 19, 19, 19, 540 10, 54, 54, 54, 10, 10, 10, 10, 17, 33,
536 84, 29, 19, 19, 19, 19, 19, 19, 19, 19, 541 28, 17, 28, 28, 28, 100, 72, 16, 29, 28,
537 19, 19, 19, 19, 19, 19, 20, 20, 20, 83, 542 97, 60, 72, 17, 60, 94, 17, 92, 17, 19,
538 20, 33, 49, 49, 82, 20, 20, 20, 20, 25, 543 19, 19, 19, 19, 19, 19, 91, 88, 19, 19,
539 25, 25, 81, 25, 80, 33, 79, 49, 25, 25, 544 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
540 25, 25, 30, 30, 30, 51, 51, 55, 30, 55, 545 19, 19, 20, 20, 20, 23, 20, 87, 23, 86,
541 55, 55, 56, 56, 56, 62, 55, 68, 62, 78, 546 96, 20, 20, 20, 20, 30, 30, 30, 85, 84,
542 547 23, 30, 83, 23, 96, 23, 25, 25, 25, 82,
543 77, 76, 74, 73, 72, 70, 67, 66, 65, 63, 548 25, 93, 93, 93, 81, 25, 25, 25, 25, 53,
544 61, 68, 94, 94, 94, 94, 94, 94, 94, 94, 549
545 95, 43, 42, 95, 95, 95, 96, 41, 96, 97, 550 98, 53, 53, 53, 95, 95, 95, 80, 53, 79,
546 97, 97, 97, 97, 97, 97, 97, 98, 40, 98, 551 78, 77, 76, 74, 98, 104, 104, 104, 104, 104,
547 99, 39, 99, 38, 99, 99, 100, 35, 100, 100, 552 104, 104, 104, 105, 73, 71, 105, 105, 105, 106,
548 100, 100, 101, 101, 101, 22, 101, 101, 102, 21, 553 70, 106, 107, 69, 107, 108, 68, 108, 66, 108,
549 102, 102, 103, 103, 103, 103, 103, 103, 103, 103, 554 108, 109, 65, 109, 109, 109, 109, 110, 110, 110,
550 104, 104, 104, 104, 104, 104, 104, 104, 105, 11, 555 64, 110, 110, 111, 63, 111, 111, 112, 112, 112,
551 105, 106, 106, 106, 0, 106, 106, 93, 93, 93, 556 112, 112, 112, 112, 112, 113, 113, 113, 113, 113,
552 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 557 113, 113, 113, 114, 62, 114, 115, 115, 115, 61,
553 558 115, 115, 116, 116, 116, 116, 116, 116, 116, 116,
554 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 559 59, 49, 43, 42, 41, 40, 39, 38, 35, 22,
555 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 560
556 93, 93, 93 561 21, 11, 103, 103, 103, 103, 103, 103, 103, 103,
562 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
563 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
564 103, 103, 103, 103, 103, 103, 103, 103
557 } ; 565 } ;
558 566
559/* Table of booleans, true if rule could match eol. */ 567/* Table of booleans, true if rule could match eol. */
560static yyconst flex_int32_t yy_rule_can_match_eol[21] = 568static yyconst flex_int32_t yy_rule_can_match_eol[21] =
561 { 0, 569 { 0,
5620, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 5701, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
563 0, }; 571 0, };
564 572
565static yy_state_type yy_last_accepting_state; 573static yy_state_type yy_last_accepting_state;
@@ -600,7 +608,7 @@ char *yytext;
600 608
601 609
602 610
603#line 33 "dtc-lexer.l" 611#line 37 "dtc-lexer.l"
604#include "dtc.h" 612#include "dtc.h"
605#include "srcpos.h" 613#include "srcpos.h"
606#include "dtc-parser.tab.h" 614#include "dtc-parser.tab.h"
@@ -623,7 +631,10 @@ static int dts_version; /* = 0 */
623 DPRINT("<V1>\n"); \ 631 DPRINT("<V1>\n"); \
624 BEGIN(V1); \ 632 BEGIN(V1); \
625 } 633 }
626#line 627 "dtc-lexer.lex.c" 634
635static void push_input_file(const char *filename);
636static int pop_input_file(void);
637#line 638 "dtc-lexer.lex.c"
627 638
628#define INITIAL 0 639#define INITIAL 0
629#define INCLUDE 1 640#define INCLUDE 1
@@ -685,7 +696,7 @@ static int input (void );
685/* This used to be an fputs(), but since the string might contain NUL's, 696/* This used to be an fputs(), but since the string might contain NUL's,
686 * we now use fwrite(). 697 * we now use fwrite().
687 */ 698 */
688#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) 699#define ECHO fwrite( yytext, yyleng, 1, yyout )
689#endif 700#endif
690 701
691/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, 702/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
@@ -696,7 +707,7 @@ static int input (void );
696 if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ 707 if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
697 { \ 708 { \
698 int c = '*'; \ 709 int c = '*'; \
699 size_t n; \ 710 int n; \
700 for ( n = 0; n < max_size && \ 711 for ( n = 0; n < max_size && \
701 (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ 712 (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
702 buf[n] = (char) c; \ 713 buf[n] = (char) c; \
@@ -778,9 +789,9 @@ YY_DECL
778 register char *yy_cp, *yy_bp; 789 register char *yy_cp, *yy_bp;
779 register int yy_act; 790 register int yy_act;
780 791
781#line 57 "dtc-lexer.l" 792#line 64 "dtc-lexer.l"
782 793
783#line 784 "dtc-lexer.lex.c" 794#line 795 "dtc-lexer.lex.c"
784 795
785 if ( !(yy_init) ) 796 if ( !(yy_init) )
786 { 797 {
@@ -833,13 +844,13 @@ yy_match:
833 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 844 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
834 { 845 {
835 yy_current_state = (int) yy_def[yy_current_state]; 846 yy_current_state = (int) yy_def[yy_current_state];
836 if ( yy_current_state >= 94 ) 847 if ( yy_current_state >= 104 )
837 yy_c = yy_meta[(unsigned int) yy_c]; 848 yy_c = yy_meta[(unsigned int) yy_c];
838 } 849 }
839 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; 850 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
840 ++yy_cp; 851 ++yy_cp;
841 } 852 }
842 while ( yy_base[yy_current_state] != 288 ); 853 while ( yy_base[yy_current_state] != 303 );
843 854
844yy_find_action: 855yy_find_action:
845 yy_act = yy_accept[yy_current_state]; 856 yy_act = yy_accept[yy_current_state];
@@ -874,20 +885,13 @@ do_action: /* This label is used only to access EOF actions. */
874 goto yy_find_action; 885 goto yy_find_action;
875 886
876case 1: 887case 1:
888/* rule 1 can match eol */
877YY_RULE_SETUP 889YY_RULE_SETUP
878#line 58 "dtc-lexer.l" 890#line 65 "dtc-lexer.l"
879BEGIN(INCLUDE);
880 YY_BREAK
881case 2:
882YY_RULE_SETUP
883#line 60 "dtc-lexer.l"
884{ 891{
885 yytext[strlen(yytext) - 1] = 0; 892 char *name = strchr(yytext, '\"') + 1;
886 if (!push_input_file(yytext + 1)) { 893 yytext[yyleng-1] = '\0';
887 /* Some unrecoverable error.*/ 894 push_input_file(name);
888 exit(1);
889 }
890 BEGIN_DEFAULT();
891 } 895 }
892 YY_BREAK 896 YY_BREAK
893case YY_STATE_EOF(INITIAL): 897case YY_STATE_EOF(INITIAL):
@@ -895,19 +899,19 @@ case YY_STATE_EOF(INCLUDE):
895case YY_STATE_EOF(BYTESTRING): 899case YY_STATE_EOF(BYTESTRING):
896case YY_STATE_EOF(PROPNODENAME): 900case YY_STATE_EOF(PROPNODENAME):
897case YY_STATE_EOF(V1): 901case YY_STATE_EOF(V1):
898#line 70 "dtc-lexer.l" 902#line 71 "dtc-lexer.l"
899{ 903{
900 if (!pop_input_file()) { 904 if (!pop_input_file()) {
901 yyterminate(); 905 yyterminate();
902 } 906 }
903 } 907 }
904 YY_BREAK 908 YY_BREAK
905case 3: 909case 2:
906/* rule 3 can match eol */ 910/* rule 2 can match eol */
907YY_RULE_SETUP 911YY_RULE_SETUP
908#line 76 "dtc-lexer.l" 912#line 77 "dtc-lexer.l"
909{ 913{
910 yylloc.filenum = srcpos_filenum; 914 yylloc.file = srcpos_file;
911 yylloc.first_line = yylineno; 915 yylloc.first_line = yylineno;
912 DPRINT("String: %s\n", yytext); 916 DPRINT("String: %s\n", yytext);
913 yylval.data = data_copy_escape_string(yytext+1, 917 yylval.data = data_copy_escape_string(yytext+1,
@@ -916,11 +920,11 @@ YY_RULE_SETUP
916 return DT_STRING; 920 return DT_STRING;
917 } 921 }
918 YY_BREAK 922 YY_BREAK
919case 4: 923case 3:
920YY_RULE_SETUP 924YY_RULE_SETUP
921#line 86 "dtc-lexer.l" 925#line 87 "dtc-lexer.l"
922{ 926{
923 yylloc.filenum = srcpos_filenum; 927 yylloc.file = srcpos_file;
924 yylloc.first_line = yylineno; 928 yylloc.first_line = yylineno;
925 DPRINT("Keyword: /dts-v1/\n"); 929 DPRINT("Keyword: /dts-v1/\n");
926 dts_version = 1; 930 dts_version = 1;
@@ -928,22 +932,22 @@ YY_RULE_SETUP
928 return DT_V1; 932 return DT_V1;
929 } 933 }
930 YY_BREAK 934 YY_BREAK
931case 5: 935case 4:
932YY_RULE_SETUP 936YY_RULE_SETUP
933#line 95 "dtc-lexer.l" 937#line 96 "dtc-lexer.l"
934{ 938{
935 yylloc.filenum = srcpos_filenum; 939 yylloc.file = srcpos_file;
936 yylloc.first_line = yylineno; 940 yylloc.first_line = yylineno;
937 DPRINT("Keyword: /memreserve/\n"); 941 DPRINT("Keyword: /memreserve/\n");
938 BEGIN_DEFAULT(); 942 BEGIN_DEFAULT();
939 return DT_MEMRESERVE; 943 return DT_MEMRESERVE;
940 } 944 }
941 YY_BREAK 945 YY_BREAK
942case 6: 946case 5:
943YY_RULE_SETUP 947YY_RULE_SETUP
944#line 103 "dtc-lexer.l" 948#line 104 "dtc-lexer.l"
945{ 949{
946 yylloc.filenum = srcpos_filenum; 950 yylloc.file = srcpos_file;
947 yylloc.first_line = yylineno; 951 yylloc.first_line = yylineno;
948 DPRINT("Label: %s\n", yytext); 952 DPRINT("Label: %s\n", yytext);
949 yylval.labelref = strdup(yytext); 953 yylval.labelref = strdup(yytext);
@@ -951,11 +955,11 @@ YY_RULE_SETUP
951 return DT_LABEL; 955 return DT_LABEL;
952 } 956 }
953 YY_BREAK 957 YY_BREAK
954case 7: 958case 6:
955YY_RULE_SETUP 959YY_RULE_SETUP
956#line 112 "dtc-lexer.l" 960#line 113 "dtc-lexer.l"
957{ 961{
958 yylloc.filenum = srcpos_filenum; 962 yylloc.file = srcpos_file;
959 yylloc.first_line = yylineno; 963 yylloc.first_line = yylineno;
960 if (*yytext == 'b') 964 if (*yytext == 'b')
961 yylval.cbase = 2; 965 yylval.cbase = 2;
@@ -969,44 +973,44 @@ YY_RULE_SETUP
969 return DT_BASE; 973 return DT_BASE;
970 } 974 }
971 YY_BREAK 975 YY_BREAK
972case 8: 976case 7:
973YY_RULE_SETUP 977YY_RULE_SETUP
974#line 127 "dtc-lexer.l" 978#line 128 "dtc-lexer.l"
975{ 979{
976 yylloc.filenum = srcpos_filenum; 980 yylloc.file = srcpos_file;
977 yylloc.first_line = yylineno; 981 yylloc.first_line = yylineno;
978 yylval.literal = strdup(yytext); 982 yylval.literal = strdup(yytext);
979 DPRINT("Literal: '%s'\n", yylval.literal); 983 DPRINT("Literal: '%s'\n", yylval.literal);
980 return DT_LEGACYLITERAL; 984 return DT_LEGACYLITERAL;
981 } 985 }
982 YY_BREAK 986 YY_BREAK
983case 9: 987case 8:
984YY_RULE_SETUP 988YY_RULE_SETUP
985#line 135 "dtc-lexer.l" 989#line 136 "dtc-lexer.l"
986{ 990{
987 yylloc.filenum = srcpos_filenum; 991 yylloc.file = srcpos_file;
988 yylloc.first_line = yylineno; 992 yylloc.first_line = yylineno;
989 yylval.literal = strdup(yytext); 993 yylval.literal = strdup(yytext);
990 DPRINT("Literal: '%s'\n", yylval.literal); 994 DPRINT("Literal: '%s'\n", yylval.literal);
991 return DT_LITERAL; 995 return DT_LITERAL;
992 } 996 }
993 YY_BREAK 997 YY_BREAK
994case 10: 998case 9:
995YY_RULE_SETUP 999YY_RULE_SETUP
996#line 143 "dtc-lexer.l" 1000#line 144 "dtc-lexer.l"
997{ /* label reference */ 1001{ /* label reference */
998 yylloc.filenum = srcpos_filenum; 1002 yylloc.file = srcpos_file;
999 yylloc.first_line = yylineno; 1003 yylloc.first_line = yylineno;
1000 DPRINT("Ref: %s\n", yytext+1); 1004 DPRINT("Ref: %s\n", yytext+1);
1001 yylval.labelref = strdup(yytext+1); 1005 yylval.labelref = strdup(yytext+1);
1002 return DT_REF; 1006 return DT_REF;
1003 } 1007 }
1004 YY_BREAK 1008 YY_BREAK
1005case 11: 1009case 10:
1006YY_RULE_SETUP 1010YY_RULE_SETUP
1007#line 151 "dtc-lexer.l" 1011#line 152 "dtc-lexer.l"
1008{ /* new-style path reference */ 1012{ /* new-style path reference */
1009 yylloc.filenum = srcpos_filenum; 1013 yylloc.file = srcpos_file;
1010 yylloc.first_line = yylineno; 1014 yylloc.first_line = yylineno;
1011 yytext[yyleng-1] = '\0'; 1015 yytext[yyleng-1] = '\0';
1012 DPRINT("Ref: %s\n", yytext+2); 1016 DPRINT("Ref: %s\n", yytext+2);
@@ -1014,44 +1018,44 @@ YY_RULE_SETUP
1014 return DT_REF; 1018 return DT_REF;
1015 } 1019 }
1016 YY_BREAK 1020 YY_BREAK
1017case 12: 1021case 11:
1018YY_RULE_SETUP 1022YY_RULE_SETUP
1019#line 160 "dtc-lexer.l" 1023#line 161 "dtc-lexer.l"
1020{ /* old-style path reference */ 1024{ /* old-style path reference */
1021 yylloc.filenum = srcpos_filenum; 1025 yylloc.file = srcpos_file;
1022 yylloc.first_line = yylineno; 1026 yylloc.first_line = yylineno;
1023 DPRINT("Ref: %s\n", yytext+1); 1027 DPRINT("Ref: %s\n", yytext+1);
1024 yylval.labelref = strdup(yytext+1); 1028 yylval.labelref = strdup(yytext+1);
1025 return DT_REF; 1029 return DT_REF;
1026 } 1030 }
1027 YY_BREAK 1031 YY_BREAK
1028case 13: 1032case 12:
1029YY_RULE_SETUP 1033YY_RULE_SETUP
1030#line 168 "dtc-lexer.l" 1034#line 169 "dtc-lexer.l"
1031{ 1035{
1032 yylloc.filenum = srcpos_filenum; 1036 yylloc.file = srcpos_file;
1033 yylloc.first_line = yylineno; 1037 yylloc.first_line = yylineno;
1034 yylval.byte = strtol(yytext, NULL, 16); 1038 yylval.byte = strtol(yytext, NULL, 16);
1035 DPRINT("Byte: %02x\n", (int)yylval.byte); 1039 DPRINT("Byte: %02x\n", (int)yylval.byte);
1036 return DT_BYTE; 1040 return DT_BYTE;
1037 } 1041 }
1038 YY_BREAK 1042 YY_BREAK
1039case 14: 1043case 13:
1040YY_RULE_SETUP 1044YY_RULE_SETUP
1041#line 176 "dtc-lexer.l" 1045#line 177 "dtc-lexer.l"
1042{ 1046{
1043 yylloc.filenum = srcpos_filenum; 1047 yylloc.file = srcpos_file;
1044 yylloc.first_line = yylineno; 1048 yylloc.first_line = yylineno;
1045 DPRINT("/BYTESTRING\n"); 1049 DPRINT("/BYTESTRING\n");
1046 BEGIN_DEFAULT(); 1050 BEGIN_DEFAULT();
1047 return ']'; 1051 return ']';
1048 } 1052 }
1049 YY_BREAK 1053 YY_BREAK
1050case 15: 1054case 14:
1051YY_RULE_SETUP 1055YY_RULE_SETUP
1052#line 184 "dtc-lexer.l" 1056#line 185 "dtc-lexer.l"
1053{ 1057{
1054 yylloc.filenum = srcpos_filenum; 1058 yylloc.file = srcpos_file;
1055 yylloc.first_line = yylineno; 1059 yylloc.first_line = yylineno;
1056 DPRINT("PropNodeName: %s\n", yytext); 1060 DPRINT("PropNodeName: %s\n", yytext);
1057 yylval.propnodename = strdup(yytext); 1061 yylval.propnodename = strdup(yytext);
@@ -1059,34 +1063,39 @@ YY_RULE_SETUP
1059 return DT_PROPNODENAME; 1063 return DT_PROPNODENAME;
1060 } 1064 }
1061 YY_BREAK 1065 YY_BREAK
1066case 15:
1067YY_RULE_SETUP
1068#line 194 "dtc-lexer.l"
1069{
1070 yylloc.file = srcpos_file;
1071 yylloc.first_line = yylineno;
1072 DPRINT("Binary Include\n");
1073 return DT_INCBIN;
1074 }
1075 YY_BREAK
1062case 16: 1076case 16:
1063/* rule 16 can match eol */ 1077/* rule 16 can match eol */
1064YY_RULE_SETUP 1078YY_RULE_SETUP
1065#line 194 "dtc-lexer.l" 1079#line 201 "dtc-lexer.l"
1066/* eat whitespace */ 1080/* eat whitespace */
1067 YY_BREAK 1081 YY_BREAK
1068case 17: 1082case 17:
1069/* rule 17 can match eol */ 1083/* rule 17 can match eol */
1070YY_RULE_SETUP 1084YY_RULE_SETUP
1071#line 196 "dtc-lexer.l" 1085#line 202 "dtc-lexer.l"
1072{ 1086/* eat C-style comments */
1073 yylloc.filenum = srcpos_filenum;
1074 yylloc.first_line = yylineno;
1075 DPRINT("Comment: %s\n", yytext);
1076 /* eat comments */
1077 }
1078 YY_BREAK 1087 YY_BREAK
1079case 18: 1088case 18:
1080/* rule 18 can match eol */ 1089/* rule 18 can match eol */
1081YY_RULE_SETUP 1090YY_RULE_SETUP
1082#line 203 "dtc-lexer.l" 1091#line 203 "dtc-lexer.l"
1083/* eat line comments */ 1092/* eat C++-style comments */
1084 YY_BREAK 1093 YY_BREAK
1085case 19: 1094case 19:
1086YY_RULE_SETUP 1095YY_RULE_SETUP
1087#line 205 "dtc-lexer.l" 1096#line 205 "dtc-lexer.l"
1088{ 1097{
1089 yylloc.filenum = srcpos_filenum; 1098 yylloc.file = srcpos_file;
1090 yylloc.first_line = yylineno; 1099 yylloc.first_line = yylineno;
1091 DPRINT("Char: %c (\\x%02x)\n", yytext[0], 1100 DPRINT("Char: %c (\\x%02x)\n", yytext[0],
1092 (unsigned)yytext[0]); 1101 (unsigned)yytext[0]);
@@ -1107,7 +1116,7 @@ YY_RULE_SETUP
1107#line 222 "dtc-lexer.l" 1116#line 222 "dtc-lexer.l"
1108ECHO; 1117ECHO;
1109 YY_BREAK 1118 YY_BREAK
1110#line 1111 "dtc-lexer.lex.c" 1119#line 1120 "dtc-lexer.lex.c"
1111 1120
1112 case YY_END_OF_BUFFER: 1121 case YY_END_OF_BUFFER:
1113 { 1122 {
@@ -1360,6 +1369,14 @@ static int yy_get_next_buffer (void)
1360 else 1369 else
1361 ret_val = EOB_ACT_CONTINUE_SCAN; 1370 ret_val = EOB_ACT_CONTINUE_SCAN;
1362 1371
1372 if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
1373 /* Extend the array by 50%, plus the number we really need. */
1374 yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
1375 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
1376 if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
1377 YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
1378 }
1379
1363 (yy_n_chars) += number_to_move; 1380 (yy_n_chars) += number_to_move;
1364 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; 1381 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
1365 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; 1382 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
@@ -1389,7 +1406,7 @@ static int yy_get_next_buffer (void)
1389 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 1406 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1390 { 1407 {
1391 yy_current_state = (int) yy_def[yy_current_state]; 1408 yy_current_state = (int) yy_def[yy_current_state];
1392 if ( yy_current_state >= 94 ) 1409 if ( yy_current_state >= 104 )
1393 yy_c = yy_meta[(unsigned int) yy_c]; 1410 yy_c = yy_meta[(unsigned int) yy_c];
1394 } 1411 }
1395 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; 1412 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1417,11 +1434,11 @@ static int yy_get_next_buffer (void)
1417 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) 1434 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1418 { 1435 {
1419 yy_current_state = (int) yy_def[yy_current_state]; 1436 yy_current_state = (int) yy_def[yy_current_state];
1420 if ( yy_current_state >= 94 ) 1437 if ( yy_current_state >= 104 )
1421 yy_c = yy_meta[(unsigned int) yy_c]; 1438 yy_c = yy_meta[(unsigned int) yy_c];
1422 } 1439 }
1423 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; 1440 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
1424 yy_is_jam = (yy_current_state == 93); 1441 yy_is_jam = (yy_current_state == 103);
1425 1442
1426 return yy_is_jam ? 0 : yy_current_state; 1443 return yy_is_jam ? 0 : yy_current_state;
1427} 1444}
@@ -1743,7 +1760,9 @@ static void yyensure_buffer_stack (void)
1743 (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc 1760 (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
1744 (num_to_alloc * sizeof(struct yy_buffer_state*) 1761 (num_to_alloc * sizeof(struct yy_buffer_state*)
1745 ); 1762 );
1746 1763 if ( ! (yy_buffer_stack) )
1764 YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
1765
1747 memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); 1766 memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
1748 1767
1749 (yy_buffer_stack_max) = num_to_alloc; 1768 (yy_buffer_stack_max) = num_to_alloc;
@@ -1761,6 +1780,8 @@ static void yyensure_buffer_stack (void)
1761 ((yy_buffer_stack), 1780 ((yy_buffer_stack),
1762 num_to_alloc * sizeof(struct yy_buffer_state*) 1781 num_to_alloc * sizeof(struct yy_buffer_state*)
1763 ); 1782 );
1783 if ( ! (yy_buffer_stack) )
1784 YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
1764 1785
1765 /* zero only the new slots.*/ 1786 /* zero only the new slots.*/
1766 memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); 1787 memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
@@ -2072,14 +2093,13 @@ void yyfree (void * ptr )
2072 */ 2093 */
2073 2094
2074struct incl_file { 2095struct incl_file {
2075 int filenum; 2096 struct dtc_file *file;
2076 FILE *file;
2077 YY_BUFFER_STATE yy_prev_buf; 2097 YY_BUFFER_STATE yy_prev_buf;
2078 int yy_prev_lineno; 2098 int yy_prev_lineno;
2079 struct incl_file *prev; 2099 struct incl_file *prev;
2080}; 2100};
2081 2101
2082struct incl_file *incl_file_stack; 2102static struct incl_file *incl_file_stack;
2083 2103
2084 2104
2085/* 2105/*
@@ -2090,36 +2110,34 @@ struct incl_file *incl_file_stack;
2090static int incl_depth = 0; 2110static int incl_depth = 0;
2091 2111
2092 2112
2093int push_input_file(const char *filename) 2113static void push_input_file(const char *filename)
2094{ 2114{
2095 FILE *f;
2096 struct incl_file *incl_file; 2115 struct incl_file *incl_file;
2116 struct dtc_file *newfile;
2117 struct search_path search, *searchptr = NULL;
2097 2118
2098 if (!filename) { 2119 assert(filename);
2099 yyerror("No include file name given.");
2100 return 0;
2101 }
2102 2120
2103 if (incl_depth++ >= MAX_INCLUDE_DEPTH) { 2121 if (incl_depth++ >= MAX_INCLUDE_DEPTH)
2104 yyerror("Includes nested too deeply"); 2122 die("Includes nested too deeply");
2105 return 0; 2123
2124 if (srcpos_file) {
2125 search.dir = srcpos_file->dir;
2126 search.next = NULL;
2127 search.prev = NULL;
2128 searchptr = &search;
2106 } 2129 }
2107 2130
2108 f = dtc_open_file(filename); 2131 newfile = dtc_open_file(filename, searchptr);
2109 2132
2110 incl_file = malloc(sizeof(struct incl_file)); 2133 incl_file = xmalloc(sizeof(struct incl_file));
2111 if (!incl_file) {
2112 yyerror("Can not allocate include file space.");
2113 return 0;
2114 }
2115 2134
2116 /* 2135 /*
2117 * Save current context. 2136 * Save current context.
2118 */ 2137 */
2119 incl_file->yy_prev_buf = YY_CURRENT_BUFFER; 2138 incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
2120 incl_file->yy_prev_lineno = yylineno; 2139 incl_file->yy_prev_lineno = yylineno;
2121 incl_file->filenum = srcpos_filenum; 2140 incl_file->file = srcpos_file;
2122 incl_file->file = yyin;
2123 incl_file->prev = incl_file_stack; 2141 incl_file->prev = incl_file_stack;
2124 2142
2125 incl_file_stack = incl_file; 2143 incl_file_stack = incl_file;
@@ -2127,23 +2145,21 @@ int push_input_file(const char *filename)
2127 /* 2145 /*
2128 * Establish new context. 2146 * Establish new context.
2129 */ 2147 */
2130 srcpos_filenum = lookup_file_name(filename, 0); 2148 srcpos_file = newfile;
2131 yylineno = 1; 2149 yylineno = 1;
2132 yyin = f; 2150 yyin = newfile->file;
2133 yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE)); 2151 yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE));
2134
2135 return 1;
2136} 2152}
2137 2153
2138 2154
2139int pop_input_file(void) 2155static int pop_input_file(void)
2140{ 2156{
2141 struct incl_file *incl_file; 2157 struct incl_file *incl_file;
2142 2158
2143 if (incl_file_stack == 0) 2159 if (incl_file_stack == 0)
2144 return 0; 2160 return 0;
2145 2161
2146 fclose(yyin); 2162 dtc_close_file(srcpos_file);
2147 2163
2148 /* 2164 /*
2149 * Pop. 2165 * Pop.
@@ -2158,17 +2174,14 @@ int pop_input_file(void)
2158 yy_delete_buffer(YY_CURRENT_BUFFER); 2174 yy_delete_buffer(YY_CURRENT_BUFFER);
2159 yy_switch_to_buffer(incl_file->yy_prev_buf); 2175 yy_switch_to_buffer(incl_file->yy_prev_buf);
2160 yylineno = incl_file->yy_prev_lineno; 2176 yylineno = incl_file->yy_prev_lineno;
2161 srcpos_filenum = incl_file->filenum; 2177 srcpos_file = incl_file->file;
2162 yyin = incl_file->file; 2178 yyin = incl_file->file ? incl_file->file->file : NULL;
2163 2179
2164 /* 2180 /*
2165 * Free old state. 2181 * Free old state.
2166 */ 2182 */
2167 free(incl_file); 2183 free(incl_file);
2168 2184
2169 if (YY_CURRENT_BUFFER == 0)
2170 return 0;
2171
2172 return 1; 2185 return 1;
2173} 2186}
2174 2187
diff --git a/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped b/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped
index 28e6ec0296a1..27129377e5d2 100644
--- a/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped
+++ b/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped
@@ -75,7 +75,8 @@
75 DT_BYTE = 264, 75 DT_BYTE = 264,
76 DT_STRING = 265, 76 DT_STRING = 265,
77 DT_LABEL = 266, 77 DT_LABEL = 266,
78 DT_REF = 267 78 DT_REF = 267,
79 DT_INCBIN = 268
79 }; 80 };
80#endif 81#endif
81/* Tokens. */ 82/* Tokens. */
@@ -89,6 +90,7 @@
89#define DT_STRING 265 90#define DT_STRING 265
90#define DT_LABEL 266 91#define DT_LABEL 266
91#define DT_REF 267 92#define DT_REF 267
93#define DT_INCBIN 268
92 94
93 95
94 96
@@ -96,14 +98,17 @@
96/* Copy the first part of user declarations. */ 98/* Copy the first part of user declarations. */
97#line 23 "dtc-parser.y" 99#line 23 "dtc-parser.y"
98 100
101#include <stdio.h>
102
99#include "dtc.h" 103#include "dtc.h"
100#include "srcpos.h" 104#include "srcpos.h"
101 105
102int yylex(void); 106extern int yylex(void);
103unsigned long long eval_literal(const char *s, int base, int bits);
104 107
105extern struct boot_info *the_boot_info; 108extern struct boot_info *the_boot_info;
109extern int treesource_error;
106 110
111static unsigned long long eval_literal(const char *s, int base, int bits);
107 112
108 113
109/* Enabling traces. */ 114/* Enabling traces. */
@@ -126,16 +131,16 @@ extern struct boot_info *the_boot_info;
126 131
127#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 132#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
128typedef union YYSTYPE 133typedef union YYSTYPE
129#line 34 "dtc-parser.y" 134#line 37 "dtc-parser.y"
130{ 135{
131 char *propnodename; 136 char *propnodename;
132 char *literal; 137 char *literal;
133 char *labelref; 138 char *labelref;
134 unsigned int cbase; 139 unsigned int cbase;
135 u8 byte; 140 uint8_t byte;
136 struct data data; 141 struct data data;
137 142
138 u64 addr; 143 uint64_t addr;
139 cell_t cell; 144 cell_t cell;
140 struct property *prop; 145 struct property *prop;
141 struct property *proplist; 146 struct property *proplist;
@@ -144,7 +149,7 @@ typedef union YYSTYPE
144 struct reserve_info *re; 149 struct reserve_info *re;
145} 150}
146/* Line 187 of yacc.c. */ 151/* Line 187 of yacc.c. */
147#line 148 "dtc-parser.tab.c" 152#line 153 "dtc-parser.tab.c"
148 YYSTYPE; 153 YYSTYPE;
149# define yystype YYSTYPE /* obsolescent; will be withdrawn */ 154# define yystype YYSTYPE /* obsolescent; will be withdrawn */
150# define YYSTYPE_IS_DECLARED 1 155# define YYSTYPE_IS_DECLARED 1
@@ -169,7 +174,7 @@ typedef struct YYLTYPE
169 174
170 175
171/* Line 216 of yacc.c. */ 176/* Line 216 of yacc.c. */
172#line 173 "dtc-parser.tab.c" 177#line 178 "dtc-parser.tab.c"
173 178
174#ifdef short 179#ifdef short
175# undef short 180# undef short
@@ -386,20 +391,20 @@ union yyalloc
386/* YYFINAL -- State number of the termination state. */ 391/* YYFINAL -- State number of the termination state. */
387#define YYFINAL 9 392#define YYFINAL 9
388/* YYLAST -- Last index in YYTABLE. */ 393/* YYLAST -- Last index in YYTABLE. */
389#define YYLAST 60 394#define YYLAST 73
390 395
391/* YYNTOKENS -- Number of terminals. */ 396/* YYNTOKENS -- Number of terminals. */
392#define YYNTOKENS 24 397#define YYNTOKENS 27
393/* YYNNTS -- Number of nonterminals. */ 398/* YYNNTS -- Number of nonterminals. */
394#define YYNNTS 20 399#define YYNNTS 20
395/* YYNRULES -- Number of rules. */ 400/* YYNRULES -- Number of rules. */
396#define YYNRULES 43 401#define YYNRULES 45
397/* YYNRULES -- Number of states. */ 402/* YYNRULES -- Number of states. */
398#define YYNSTATES 67 403#define YYNSTATES 76
399 404
400/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ 405/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
401#define YYUNDEFTOK 2 406#define YYUNDEFTOK 2
402#define YYMAXUTOK 267 407#define YYMAXUTOK 268
403 408
404#define YYTRANSLATE(YYX) \ 409#define YYTRANSLATE(YYX) \
405 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) 410 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -411,15 +416,15 @@ static const yytype_uint8 yytranslate[] =
411 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 416 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
412 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 417 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
413 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 418 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
414 2, 2, 2, 2, 23, 14, 2, 15, 2, 2, 419 24, 26, 2, 2, 25, 15, 2, 16, 2, 2,
415 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 420 2, 2, 2, 2, 2, 2, 2, 2, 2, 14,
416 19, 18, 20, 2, 2, 2, 2, 2, 2, 2, 421 20, 19, 21, 2, 2, 2, 2, 2, 2, 2,
417 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 422 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
418 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 423 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
419 2, 21, 2, 22, 2, 2, 2, 2, 2, 2, 424 2, 22, 2, 23, 2, 2, 2, 2, 2, 2,
420 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 425 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
421 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 426 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
422 2, 2, 2, 16, 2, 17, 2, 2, 2, 2, 427 2, 2, 2, 17, 2, 18, 2, 2, 2, 2,
423 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 428 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
424 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 429 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
425 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 430 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -433,7 +438,7 @@ static const yytype_uint8 yytranslate[] =
433 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 438 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
434 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 439 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
435 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 440 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
436 5, 6, 7, 8, 9, 10, 11, 12 441 5, 6, 7, 8, 9, 10, 11, 12, 13
437}; 442};
438 443
439#if YYDEBUG 444#if YYDEBUG
@@ -443,37 +448,39 @@ static const yytype_uint8 yyprhs[] =
443{ 448{
444 0, 0, 3, 8, 11, 12, 15, 21, 22, 25, 449 0, 0, 3, 8, 11, 12, 15, 21, 22, 25,
445 27, 34, 36, 38, 41, 47, 48, 51, 57, 61, 450 27, 34, 36, 38, 41, 47, 48, 51, 57, 61,
446 64, 69, 74, 77, 80, 81, 84, 87, 88, 91, 451 64, 69, 74, 77, 87, 93, 96, 97, 100, 103,
447 94, 97, 98, 100, 102, 105, 106, 109, 112, 113, 452 104, 107, 110, 113, 114, 116, 118, 121, 122, 125,
448 116, 119, 123, 124 453 128, 129, 132, 135, 139, 140
449}; 454};
450 455
451/* YYRHS -- A `-1'-separated list of the rules' RHS. */ 456/* YYRHS -- A `-1'-separated list of the rules' RHS. */
452static const yytype_int8 yyrhs[] = 457static const yytype_int8 yyrhs[] =
453{ 458{
454 25, 0, -1, 3, 13, 26, 31, -1, 28, 31, 459 28, 0, -1, 3, 14, 29, 34, -1, 31, 34,
455 -1, -1, 27, 26, -1, 43, 4, 30, 30, 13, 460 -1, -1, 30, 29, -1, 46, 4, 33, 33, 14,
456 -1, -1, 29, 28, -1, 27, -1, 43, 4, 30, 461 -1, -1, 32, 31, -1, 30, -1, 46, 4, 33,
457 14, 30, 13, -1, 6, -1, 7, -1, 15, 32, 462 15, 33, 14, -1, 6, -1, 7, -1, 16, 35,
458 -1, 16, 33, 41, 17, 13, -1, -1, 33, 34, 463 -1, 17, 36, 44, 18, 14, -1, -1, 36, 37,
459 -1, 43, 5, 18, 35, 13, -1, 43, 5, 13, 464 -1, 46, 5, 19, 38, 14, -1, 46, 5, 14,
460 -1, 36, 10, -1, 36, 19, 37, 20, -1, 36, 465 -1, 39, 10, -1, 39, 20, 40, 21, -1, 39,
461 21, 40, 22, -1, 36, 12, -1, 35, 11, -1, 466 22, 43, 23, -1, 39, 12, -1, 39, 13, 24,
462 -1, 35, 23, -1, 36, 11, -1, -1, 37, 39, 467 10, 25, 33, 25, 33, 26, -1, 39, 13, 24,
463 -1, 37, 12, -1, 37, 11, -1, -1, 8, -1, 468 10, 26, -1, 38, 11, -1, -1, 38, 25, -1,
464 6, -1, 38, 7, -1, -1, 40, 9, -1, 40, 469 39, 11, -1, -1, 40, 42, -1, 40, 12, -1,
465 11, -1, -1, 42, 41, -1, 42, 34, -1, 43, 470 40, 11, -1, -1, 8, -1, 6, -1, 41, 7,
466 5, 32, -1, -1, 11, -1 471 -1, -1, 43, 9, -1, 43, 11, -1, -1, 45,
472 44, -1, 45, 37, -1, 46, 5, 35, -1, -1,
473 11, -1
467}; 474};
468 475
469/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ 476/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
470static const yytype_uint16 yyrline[] = 477static const yytype_uint16 yyrline[] =
471{ 478{
472 0, 85, 85, 89, 97, 100, 107, 115, 118, 125, 479 0, 89, 89, 93, 101, 104, 111, 119, 122, 129,
473 129, 136, 140, 147, 154, 162, 165, 172, 176, 183, 480 133, 140, 144, 151, 158, 166, 169, 176, 180, 187,
474 187, 191, 195, 199, 207, 210, 214, 222, 225, 229, 481 191, 195, 199, 203, 220, 231, 239, 242, 246, 254,
475 234, 242, 245, 249, 253, 261, 264, 268, 276, 279, 482 257, 261, 266, 274, 277, 281, 285, 293, 296, 300,
476 283, 291, 299, 302 483 308, 311, 315, 323, 331, 334
477}; 484};
478#endif 485#endif
479 486
@@ -484,12 +491,12 @@ static const char *const yytname[] =
484{ 491{
485 "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", 492 "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE",
486 "DT_PROPNODENAME", "DT_LITERAL", "DT_LEGACYLITERAL", "DT_BASE", 493 "DT_PROPNODENAME", "DT_LITERAL", "DT_LEGACYLITERAL", "DT_BASE",
487 "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", "';'", "'-'", "'/'", "'{'", 494 "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", "DT_INCBIN", "';'", "'-'",
488 "'}'", "'='", "'<'", "'>'", "'['", "']'", "','", "$accept", "sourcefile", 495 "'/'", "'{'", "'}'", "'='", "'<'", "'>'", "'['", "']'", "'('", "','",
489 "memreserves", "memreserve", "v0_memreserves", "v0_memreserve", "addr", 496 "')'", "$accept", "sourcefile", "memreserves", "memreserve",
490 "devicetree", "nodedef", "proplist", "propdef", "propdata", 497 "v0_memreserves", "v0_memreserve", "addr", "devicetree", "nodedef",
491 "propdataprefix", "celllist", "cellbase", "cellval", "bytestring", 498 "proplist", "propdef", "propdata", "propdataprefix", "celllist",
492 "subnodes", "subnode", "label", 0 499 "cellbase", "cellval", "bytestring", "subnodes", "subnode", "label", 0
493}; 500};
494#endif 501#endif
495 502
@@ -499,19 +506,19 @@ static const char *const yytname[] =
499static const yytype_uint16 yytoknum[] = 506static const yytype_uint16 yytoknum[] =
500{ 507{
501 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 508 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
502 265, 266, 267, 59, 45, 47, 123, 125, 61, 60, 509 265, 266, 267, 268, 59, 45, 47, 123, 125, 61,
503 62, 91, 93, 44 510 60, 62, 91, 93, 40, 44, 41
504}; 511};
505# endif 512# endif
506 513
507/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ 514/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
508static const yytype_uint8 yyr1[] = 515static const yytype_uint8 yyr1[] =
509{ 516{
510 0, 24, 25, 25, 26, 26, 27, 28, 28, 29, 517 0, 27, 28, 28, 29, 29, 30, 31, 31, 32,
511 29, 30, 30, 31, 32, 33, 33, 34, 34, 35, 518 32, 33, 33, 34, 35, 36, 36, 37, 37, 38,
512 35, 35, 35, 35, 36, 36, 36, 37, 37, 37, 519 38, 38, 38, 38, 38, 38, 39, 39, 39, 40,
513 37, 38, 38, 39, 39, 40, 40, 40, 41, 41, 520 40, 40, 40, 41, 41, 42, 42, 43, 43, 43,
514 41, 42, 43, 43 521 44, 44, 44, 45, 46, 46
515}; 522};
516 523
517/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ 524/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
@@ -519,9 +526,9 @@ static const yytype_uint8 yyr2[] =
519{ 526{
520 0, 2, 4, 2, 0, 2, 5, 0, 2, 1, 527 0, 2, 4, 2, 0, 2, 5, 0, 2, 1,
521 6, 1, 1, 2, 5, 0, 2, 5, 3, 2, 528 6, 1, 1, 2, 5, 0, 2, 5, 3, 2,
522 4, 4, 2, 2, 0, 2, 2, 0, 2, 2, 529 4, 4, 2, 9, 5, 2, 0, 2, 2, 0,
523 2, 0, 1, 1, 2, 0, 2, 2, 0, 2, 530 2, 2, 2, 0, 1, 1, 2, 0, 2, 2,
524 2, 3, 0, 1 531 0, 2, 2, 3, 0, 1
525}; 532};
526 533
527/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state 534/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -529,81 +536,86 @@ static const yytype_uint8 yyr2[] =
529 means the default is an error. */ 536 means the default is an error. */
530static const yytype_uint8 yydefact[] = 537static const yytype_uint8 yydefact[] =
531{ 538{
532 7, 0, 43, 0, 9, 0, 7, 0, 4, 1, 539 7, 0, 45, 0, 9, 0, 7, 0, 4, 1,
533 0, 3, 8, 0, 0, 4, 0, 15, 13, 11, 540 0, 3, 8, 0, 0, 4, 0, 15, 13, 11,
534 12, 0, 2, 5, 0, 38, 0, 0, 0, 16, 541 12, 0, 2, 5, 0, 40, 0, 0, 0, 16,
535 0, 38, 0, 0, 6, 0, 40, 39, 0, 10, 542 0, 40, 0, 0, 6, 0, 42, 41, 0, 10,
536 14, 18, 24, 41, 0, 0, 23, 17, 25, 19, 543 14, 18, 26, 43, 0, 0, 25, 17, 27, 19,
537 26, 22, 27, 35, 31, 0, 33, 32, 30, 29, 544 28, 22, 0, 29, 37, 0, 33, 0, 0, 35,
538 20, 0, 28, 36, 37, 21, 34 545 34, 32, 31, 20, 0, 30, 38, 39, 21, 0,
546 24, 36, 0, 0, 0, 23
539}; 547};
540 548
541/* YYDEFGOTO[NTERM-NUM]. */ 549/* YYDEFGOTO[NTERM-NUM]. */
542static const yytype_int8 yydefgoto[] = 550static const yytype_int8 yydefgoto[] =
543{ 551{
544 -1, 3, 14, 4, 5, 6, 27, 11, 18, 25, 552 -1, 3, 14, 4, 5, 6, 27, 11, 18, 25,
545 29, 44, 45, 54, 61, 62, 55, 30, 31, 7 553 29, 44, 45, 56, 64, 65, 57, 30, 31, 7
546}; 554};
547 555
548/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing 556/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
549 STATE-NUM. */ 557 STATE-NUM. */
550#define YYPACT_NINF -13 558#define YYPACT_NINF -14
551static const yytype_int8 yypact[] = 559static const yytype_int8 yypact[] =
552{ 560{
553 23, 11, -13, 37, -13, -4, 18, 39, 18, -13, 561 30, -11, -14, 7, -14, -1, 27, 13, 27, -14,
554 28, -13, -13, 34, -4, 18, 41, -13, -13, -13, 562 8, -14, -14, 40, -1, 27, 35, -14, -14, -14,
555 -13, 25, -13, -13, 34, -3, 34, 33, 34, -13, 563 -14, 21, -14, -14, 40, 24, 40, 28, 40, -14,
556 30, -3, 43, 36, -13, 38, -13, -13, 20, -13, 564 32, 24, 46, 38, -14, 39, -14, -14, 26, -14,
557 -13, -13, -13, -13, 2, 9, -13, -13, -13, -13, 565 -14, -14, -14, -14, -9, 10, -14, -14, -14, -14,
558 -13, -13, -13, -13, -2, -6, -13, -13, -13, -13, 566 -14, -14, 31, -14, -14, 44, -2, 3, 23, -14,
559 -13, 45, -13, -13, -13, -13, -13 567 -14, -14, -14, -14, 50, -14, -14, -14, -14, 40,
568 -14, -14, 33, 40, 36, -14
560}; 569};
561 570
562/* YYPGOTO[NTERM-NUM]. */ 571/* YYPGOTO[NTERM-NUM]. */
563static const yytype_int8 yypgoto[] = 572static const yytype_int8 yypgoto[] =
564{ 573{
565 -13, -13, 35, 27, 47, -13, -12, 40, 17, -13, 574 -14, -14, 48, 29, 53, -14, -13, 47, 34, -14,
566 26, -13, -13, -13, -13, -13, -13, 29, -13, -8 575 37, -14, -14, -14, -14, -14, -14, 42, -14, -7
567}; 576};
568 577
569/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If 578/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
570 positive, shift that token. If negative, reduce the rule which 579 positive, shift that token. If negative, reduce the rule which
571 number is the opposite. If zero, do what YYDEFACT says. 580 number is the opposite. If zero, do what YYDEFACT says.
572 If YYTABLE_NINF, syntax error. */ 581 If YYTABLE_NINF, syntax error. */
573#define YYTABLE_NINF -43 582#define YYTABLE_NINF -45
574static const yytype_int8 yytable[] = 583static const yytype_int8 yytable[] =
575{ 584{
576 16, 21, -42, 63, 56, 64, 57, 16, 2, 58, 585 21, 16, 46, 8, 59, 47, 60, 9, 16, 61,
577 59, 10, 28, 46, 33, 47, 65, 32, 60, 49, 586 62, 28, 66, 33, 67, 10, 48, 13, 32, 63,
578 50, 51, -42, 32, 8, 48, 1, -42, 52, 2, 587 49, 50, 51, 52, 32, 17, 68, 19, 20, -44,
579 53, 19, 20, 41, 2, 15, 17, 9, 42, 26, 588 53, -44, 54, 1, -44, 2, 26, 15, 2, 24,
580 19, 20, 15, 13, 17, 24, 34, 35, 38, 39, 589 41, 2, 34, 17, 15, 42, 19, 20, 69, 70,
581 23, 40, 66, 12, 22, 43, 0, 36, 0, 0, 590 35, 38, 39, 40, 58, 55, 72, 71, 73, 12,
582 37 591 74, 22, 75, 23, 0, 0, 0, 0, 36, 0,
592 0, 0, 43, 37
583}; 593};
584 594
585static const yytype_int8 yycheck[] = 595static const yytype_int8 yycheck[] =
586{ 596{
587 8, 13, 5, 9, 6, 11, 8, 15, 11, 11, 597 13, 8, 11, 14, 6, 14, 8, 0, 15, 11,
588 12, 15, 24, 11, 26, 13, 22, 25, 20, 10, 598 12, 24, 9, 26, 11, 16, 25, 4, 25, 21,
589 11, 12, 4, 31, 13, 23, 3, 4, 19, 11, 599 10, 11, 12, 13, 31, 17, 23, 6, 7, 5,
590 21, 6, 7, 13, 11, 8, 16, 0, 18, 14, 600 20, 4, 22, 3, 4, 11, 15, 8, 11, 4,
591 6, 7, 15, 4, 16, 4, 13, 17, 5, 13, 601 14, 11, 14, 17, 15, 19, 6, 7, 25, 26,
592 15, 13, 7, 6, 14, 38, -1, 31, -1, -1, 602 18, 5, 14, 14, 10, 24, 69, 7, 25, 6,
593 31 603 73, 14, 26, 15, -1, -1, -1, -1, 31, -1,
604 -1, -1, 38, 31
594}; 605};
595 606
596/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing 607/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
597 symbol of state STATE-NUM. */ 608 symbol of state STATE-NUM. */
598static const yytype_uint8 yystos[] = 609static const yytype_uint8 yystos[] =
599{ 610{
600 0, 3, 11, 25, 27, 28, 29, 43, 13, 0, 611 0, 3, 11, 28, 30, 31, 32, 46, 14, 0,
601 15, 31, 28, 4, 26, 27, 43, 16, 32, 6, 612 16, 34, 31, 4, 29, 30, 46, 17, 35, 6,
602 7, 30, 31, 26, 4, 33, 14, 30, 30, 34, 613 7, 33, 34, 29, 4, 36, 15, 33, 33, 37,
603 41, 42, 43, 30, 13, 17, 34, 41, 5, 13, 614 44, 45, 46, 33, 14, 18, 37, 44, 5, 14,
604 13, 13, 18, 32, 35, 36, 11, 13, 23, 10, 615 14, 14, 19, 35, 38, 39, 11, 14, 25, 10,
605 11, 12, 19, 21, 37, 40, 6, 8, 11, 12, 616 11, 12, 13, 20, 22, 24, 40, 43, 10, 6,
606 20, 38, 39, 9, 11, 22, 7 617 8, 11, 12, 21, 41, 42, 9, 11, 23, 25,
618 26, 7, 33, 25, 33, 26
607}; 619};
608 620
609#define yyerrok (yyerrstatus = 0) 621#define yyerrok (yyerrstatus = 0)
@@ -1440,289 +1452,323 @@ yyreduce:
1440 switch (yyn) 1452 switch (yyn)
1441 { 1453 {
1442 case 2: 1454 case 2:
1443#line 86 "dtc-parser.y" 1455#line 90 "dtc-parser.y"
1444 { 1456 {
1445 the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node)); 1457 the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node), 0);
1446 ;} 1458 ;}
1447 break; 1459 break;
1448 1460
1449 case 3: 1461 case 3:
1450#line 90 "dtc-parser.y" 1462#line 94 "dtc-parser.y"
1451 { 1463 {
1452 the_boot_info = build_boot_info((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].node)); 1464 the_boot_info = build_boot_info((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].node), 0);
1453 ;} 1465 ;}
1454 break; 1466 break;
1455 1467
1456 case 4: 1468 case 4:
1457#line 97 "dtc-parser.y" 1469#line 101 "dtc-parser.y"
1458 { 1470 {
1459 (yyval.re) = NULL; 1471 (yyval.re) = NULL;
1460 ;} 1472 ;}
1461 break; 1473 break;
1462 1474
1463 case 5: 1475 case 5:
1464#line 101 "dtc-parser.y" 1476#line 105 "dtc-parser.y"
1465 { 1477 {
1466 (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); 1478 (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
1467 ;} 1479 ;}
1468 break; 1480 break;
1469 1481
1470 case 6: 1482 case 6:
1471#line 108 "dtc-parser.y" 1483#line 112 "dtc-parser.y"
1472 { 1484 {
1473 (yyval.re) = build_reserve_entry((yyvsp[(3) - (5)].addr), (yyvsp[(4) - (5)].addr), (yyvsp[(1) - (5)].labelref)); 1485 (yyval.re) = build_reserve_entry((yyvsp[(3) - (5)].addr), (yyvsp[(4) - (5)].addr), (yyvsp[(1) - (5)].labelref));
1474 ;} 1486 ;}
1475 break; 1487 break;
1476 1488
1477 case 7: 1489 case 7:
1478#line 115 "dtc-parser.y" 1490#line 119 "dtc-parser.y"
1479 { 1491 {
1480 (yyval.re) = NULL; 1492 (yyval.re) = NULL;
1481 ;} 1493 ;}
1482 break; 1494 break;
1483 1495
1484 case 8: 1496 case 8:
1485#line 119 "dtc-parser.y" 1497#line 123 "dtc-parser.y"
1486 { 1498 {
1487 (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); 1499 (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
1488 ;} 1500 ;}
1489 break; 1501 break;
1490 1502
1491 case 9: 1503 case 9:
1492#line 126 "dtc-parser.y" 1504#line 130 "dtc-parser.y"
1493 { 1505 {
1494 (yyval.re) = (yyvsp[(1) - (1)].re); 1506 (yyval.re) = (yyvsp[(1) - (1)].re);
1495 ;} 1507 ;}
1496 break; 1508 break;
1497 1509
1498 case 10: 1510 case 10:
1499#line 130 "dtc-parser.y" 1511#line 134 "dtc-parser.y"
1500 { 1512 {
1501 (yyval.re) = build_reserve_entry((yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].addr) - (yyvsp[(3) - (6)].addr) + 1, (yyvsp[(1) - (6)].labelref)); 1513 (yyval.re) = build_reserve_entry((yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].addr) - (yyvsp[(3) - (6)].addr) + 1, (yyvsp[(1) - (6)].labelref));
1502 ;} 1514 ;}
1503 break; 1515 break;
1504 1516
1505 case 11: 1517 case 11:
1506#line 137 "dtc-parser.y" 1518#line 141 "dtc-parser.y"
1507 { 1519 {
1508 (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64); 1520 (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64);
1509 ;} 1521 ;}
1510 break; 1522 break;
1511 1523
1512 case 12: 1524 case 12:
1513#line 141 "dtc-parser.y" 1525#line 145 "dtc-parser.y"
1514 { 1526 {
1515 (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 16, 64); 1527 (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 16, 64);
1516 ;} 1528 ;}
1517 break; 1529 break;
1518 1530
1519 case 13: 1531 case 13:
1520#line 148 "dtc-parser.y" 1532#line 152 "dtc-parser.y"
1521 { 1533 {
1522 (yyval.node) = name_node((yyvsp[(2) - (2)].node), "", NULL); 1534 (yyval.node) = name_node((yyvsp[(2) - (2)].node), "", NULL);
1523 ;} 1535 ;}
1524 break; 1536 break;
1525 1537
1526 case 14: 1538 case 14:
1527#line 155 "dtc-parser.y" 1539#line 159 "dtc-parser.y"
1528 { 1540 {
1529 (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); 1541 (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist));
1530 ;} 1542 ;}
1531 break; 1543 break;
1532 1544
1533 case 15: 1545 case 15:
1534#line 162 "dtc-parser.y" 1546#line 166 "dtc-parser.y"
1535 { 1547 {
1536 (yyval.proplist) = NULL; 1548 (yyval.proplist) = NULL;
1537 ;} 1549 ;}
1538 break; 1550 break;
1539 1551
1540 case 16: 1552 case 16:
1541#line 166 "dtc-parser.y" 1553#line 170 "dtc-parser.y"
1542 { 1554 {
1543 (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); 1555 (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist));
1544 ;} 1556 ;}
1545 break; 1557 break;
1546 1558
1547 case 17: 1559 case 17:
1548#line 173 "dtc-parser.y" 1560#line 177 "dtc-parser.y"
1549 { 1561 {
1550 (yyval.prop) = build_property((yyvsp[(2) - (5)].propnodename), (yyvsp[(4) - (5)].data), (yyvsp[(1) - (5)].labelref)); 1562 (yyval.prop) = build_property((yyvsp[(2) - (5)].propnodename), (yyvsp[(4) - (5)].data), (yyvsp[(1) - (5)].labelref));
1551 ;} 1563 ;}
1552 break; 1564 break;
1553 1565
1554 case 18: 1566 case 18:
1555#line 177 "dtc-parser.y" 1567#line 181 "dtc-parser.y"
1556 { 1568 {
1557 (yyval.prop) = build_property((yyvsp[(2) - (3)].propnodename), empty_data, (yyvsp[(1) - (3)].labelref)); 1569 (yyval.prop) = build_property((yyvsp[(2) - (3)].propnodename), empty_data, (yyvsp[(1) - (3)].labelref));
1558 ;} 1570 ;}
1559 break; 1571 break;
1560 1572
1561 case 19: 1573 case 19:
1562#line 184 "dtc-parser.y" 1574#line 188 "dtc-parser.y"
1563 { 1575 {
1564 (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); 1576 (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data));
1565 ;} 1577 ;}
1566 break; 1578 break;
1567 1579
1568 case 20: 1580 case 20:
1569#line 188 "dtc-parser.y" 1581#line 192 "dtc-parser.y"
1570 { 1582 {
1571 (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); 1583 (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
1572 ;} 1584 ;}
1573 break; 1585 break;
1574 1586
1575 case 21: 1587 case 21:
1576#line 192 "dtc-parser.y" 1588#line 196 "dtc-parser.y"
1577 { 1589 {
1578 (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); 1590 (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
1579 ;} 1591 ;}
1580 break; 1592 break;
1581 1593
1582 case 22: 1594 case 22:
1583#line 196 "dtc-parser.y" 1595#line 200 "dtc-parser.y"
1584 { 1596 {
1585 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); 1597 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref));
1586 ;} 1598 ;}
1587 break; 1599 break;
1588 1600
1589 case 23: 1601 case 23:
1590#line 200 "dtc-parser.y" 1602#line 204 "dtc-parser.y"
1591 { 1603 {
1592 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); 1604 struct search_path path = { srcpos_file->dir, NULL, NULL };
1605 struct dtc_file *file = dtc_open_file((yyvsp[(4) - (9)].data).val, &path);
1606 struct data d = empty_data;
1607
1608 if ((yyvsp[(6) - (9)].addr) != 0)
1609 if (fseek(file->file, (yyvsp[(6) - (9)].addr), SEEK_SET) != 0)
1610 yyerrorf("Couldn't seek to offset %llu in \"%s\": %s",
1611 (unsigned long long)(yyvsp[(6) - (9)].addr),
1612 (yyvsp[(4) - (9)].data).val, strerror(errno));
1613
1614 d = data_copy_file(file->file, (yyvsp[(8) - (9)].addr));
1615
1616 (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d);
1617 dtc_close_file(file);
1593 ;} 1618 ;}
1594 break; 1619 break;
1595 1620
1596 case 24: 1621 case 24:
1597#line 207 "dtc-parser.y" 1622#line 221 "dtc-parser.y"
1598 { 1623 {
1599 (yyval.data) = empty_data; 1624 struct search_path path = { srcpos_file->dir, NULL, NULL };
1625 struct dtc_file *file = dtc_open_file((yyvsp[(4) - (5)].data).val, &path);
1626 struct data d = empty_data;
1627
1628 d = data_copy_file(file->file, -1);
1629
1630 (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d);
1631 dtc_close_file(file);
1600 ;} 1632 ;}
1601 break; 1633 break;
1602 1634
1603 case 25: 1635 case 25:
1604#line 211 "dtc-parser.y" 1636#line 232 "dtc-parser.y"
1605 { 1637 {
1606 (yyval.data) = (yyvsp[(1) - (2)].data); 1638 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1607 ;} 1639 ;}
1608 break; 1640 break;
1609 1641
1610 case 26: 1642 case 26:
1611#line 215 "dtc-parser.y" 1643#line 239 "dtc-parser.y"
1612 { 1644 {
1613 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); 1645 (yyval.data) = empty_data;
1614 ;} 1646 ;}
1615 break; 1647 break;
1616 1648
1617 case 27: 1649 case 27:
1618#line 222 "dtc-parser.y" 1650#line 243 "dtc-parser.y"
1619 { 1651 {
1620 (yyval.data) = empty_data; 1652 (yyval.data) = (yyvsp[(1) - (2)].data);
1621 ;} 1653 ;}
1622 break; 1654 break;
1623 1655
1624 case 28: 1656 case 28:
1625#line 226 "dtc-parser.y" 1657#line 247 "dtc-parser.y"
1626 { 1658 {
1627 (yyval.data) = data_append_cell((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].cell)); 1659 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1628 ;} 1660 ;}
1629 break; 1661 break;
1630 1662
1631 case 29: 1663 case 29:
1632#line 230 "dtc-parser.y" 1664#line 254 "dtc-parser.y"
1665 {
1666 (yyval.data) = empty_data;
1667 ;}
1668 break;
1669
1670 case 30:
1671#line 258 "dtc-parser.y"
1672 {
1673 (yyval.data) = data_append_cell((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].cell));
1674 ;}
1675 break;
1676
1677 case 31:
1678#line 262 "dtc-parser.y"
1633 { 1679 {
1634 (yyval.data) = data_append_cell(data_add_marker((yyvsp[(1) - (2)].data), REF_PHANDLE, 1680 (yyval.data) = data_append_cell(data_add_marker((yyvsp[(1) - (2)].data), REF_PHANDLE,
1635 (yyvsp[(2) - (2)].labelref)), -1); 1681 (yyvsp[(2) - (2)].labelref)), -1);
1636 ;} 1682 ;}
1637 break; 1683 break;
1638 1684
1639 case 30: 1685 case 32:
1640#line 235 "dtc-parser.y" 1686#line 267 "dtc-parser.y"
1641 { 1687 {
1642 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); 1688 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1643 ;} 1689 ;}
1644 break; 1690 break;
1645 1691
1646 case 31: 1692 case 33:
1647#line 242 "dtc-parser.y" 1693#line 274 "dtc-parser.y"
1648 { 1694 {
1649 (yyval.cbase) = 16; 1695 (yyval.cbase) = 16;
1650 ;} 1696 ;}
1651 break; 1697 break;
1652 1698
1653 case 33: 1699 case 35:
1654#line 250 "dtc-parser.y" 1700#line 282 "dtc-parser.y"
1655 { 1701 {
1656 (yyval.cell) = eval_literal((yyvsp[(1) - (1)].literal), 0, 32); 1702 (yyval.cell) = eval_literal((yyvsp[(1) - (1)].literal), 0, 32);
1657 ;} 1703 ;}
1658 break; 1704 break;
1659 1705
1660 case 34: 1706 case 36:
1661#line 254 "dtc-parser.y" 1707#line 286 "dtc-parser.y"
1662 { 1708 {
1663 (yyval.cell) = eval_literal((yyvsp[(2) - (2)].literal), (yyvsp[(1) - (2)].cbase), 32); 1709 (yyval.cell) = eval_literal((yyvsp[(2) - (2)].literal), (yyvsp[(1) - (2)].cbase), 32);
1664 ;} 1710 ;}
1665 break; 1711 break;
1666 1712
1667 case 35: 1713 case 37:
1668#line 261 "dtc-parser.y" 1714#line 293 "dtc-parser.y"
1669 { 1715 {
1670 (yyval.data) = empty_data; 1716 (yyval.data) = empty_data;
1671 ;} 1717 ;}
1672 break; 1718 break;
1673 1719
1674 case 36: 1720 case 38:
1675#line 265 "dtc-parser.y" 1721#line 297 "dtc-parser.y"
1676 { 1722 {
1677 (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte)); 1723 (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte));
1678 ;} 1724 ;}
1679 break; 1725 break;
1680 1726
1681 case 37: 1727 case 39:
1682#line 269 "dtc-parser.y" 1728#line 301 "dtc-parser.y"
1683 { 1729 {
1684 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); 1730 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1685 ;} 1731 ;}
1686 break; 1732 break;
1687 1733
1688 case 38: 1734 case 40:
1689#line 276 "dtc-parser.y" 1735#line 308 "dtc-parser.y"
1690 { 1736 {
1691 (yyval.nodelist) = NULL; 1737 (yyval.nodelist) = NULL;
1692 ;} 1738 ;}
1693 break; 1739 break;
1694 1740
1695 case 39: 1741 case 41:
1696#line 280 "dtc-parser.y" 1742#line 312 "dtc-parser.y"
1697 { 1743 {
1698 (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist)); 1744 (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist));
1699 ;} 1745 ;}
1700 break; 1746 break;
1701 1747
1702 case 40: 1748 case 42:
1703#line 284 "dtc-parser.y" 1749#line 316 "dtc-parser.y"
1704 { 1750 {
1705 yyerror("syntax error: properties must precede subnodes\n"); 1751 yyerror("syntax error: properties must precede subnodes");
1706 YYERROR; 1752 YYERROR;
1707 ;} 1753 ;}
1708 break; 1754 break;
1709 1755
1710 case 41: 1756 case 43:
1711#line 292 "dtc-parser.y" 1757#line 324 "dtc-parser.y"
1712 { 1758 {
1713 (yyval.node) = name_node((yyvsp[(3) - (3)].node), (yyvsp[(2) - (3)].propnodename), (yyvsp[(1) - (3)].labelref)); 1759 (yyval.node) = name_node((yyvsp[(3) - (3)].node), (yyvsp[(2) - (3)].propnodename), (yyvsp[(1) - (3)].labelref));
1714 ;} 1760 ;}
1715 break; 1761 break;
1716 1762
1717 case 42: 1763 case 44:
1718#line 299 "dtc-parser.y" 1764#line 331 "dtc-parser.y"
1719 { 1765 {
1720 (yyval.labelref) = NULL; 1766 (yyval.labelref) = NULL;
1721 ;} 1767 ;}
1722 break; 1768 break;
1723 1769
1724 case 43: 1770 case 45:
1725#line 303 "dtc-parser.y" 1771#line 335 "dtc-parser.y"
1726 { 1772 {
1727 (yyval.labelref) = (yyvsp[(1) - (1)].labelref); 1773 (yyval.labelref) = (yyvsp[(1) - (1)].labelref);
1728 ;} 1774 ;}
@@ -1730,7 +1776,7 @@ yyreduce:
1730 1776
1731 1777
1732/* Line 1267 of yacc.c. */ 1778/* Line 1267 of yacc.c. */
1733#line 1734 "dtc-parser.tab.c" 1779#line 1780 "dtc-parser.tab.c"
1734 default: break; 1780 default: break;
1735 } 1781 }
1736 YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); 1782 YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -1950,21 +1996,32 @@ yyreturn:
1950} 1996}
1951 1997
1952 1998
1953#line 308 "dtc-parser.y" 1999#line 340 "dtc-parser.y"
1954 2000
1955 2001
1956void yyerror (char const *s) 2002void yyerrorf(char const *s, ...)
1957{ 2003{
1958 const char *fname = srcpos_filename_for_num(yylloc.filenum); 2004 const char *fname = srcpos_file ? srcpos_file->name : "<no-file>";
2005 va_list va;
2006 va_start(va, s);
1959 2007
1960 if (strcmp(fname, "-") == 0) 2008 if (strcmp(fname, "-") == 0)
1961 fname = "stdin"; 2009 fname = "stdin";
1962 2010
1963 fprintf(stderr, "%s:%d %s\n", 2011 fprintf(stderr, "%s:%d ", fname, yylloc.first_line);
1964 fname, yylloc.first_line, s); 2012 vfprintf(stderr, s, va);
2013 fprintf(stderr, "\n");
2014
2015 treesource_error = 1;
2016 va_end(va);
2017}
2018
2019void yyerror (char const *s)
2020{
2021 yyerrorf("%s", s);
1965} 2022}
1966 2023
1967unsigned long long eval_literal(const char *s, int base, int bits) 2024static unsigned long long eval_literal(const char *s, int base, int bits)
1968{ 2025{
1969 unsigned long long val; 2026 unsigned long long val;
1970 char *e; 2027 char *e;
diff --git a/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped b/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped
index 4707b029ed25..ba99100d55c9 100644
--- a/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped
+++ b/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped
@@ -48,7 +48,8 @@
48 DT_BYTE = 264, 48 DT_BYTE = 264,
49 DT_STRING = 265, 49 DT_STRING = 265,
50 DT_LABEL = 266, 50 DT_LABEL = 266,
51 DT_REF = 267 51 DT_REF = 267,
52 DT_INCBIN = 268
52 }; 53 };
53#endif 54#endif
54/* Tokens. */ 55/* Tokens. */
@@ -62,22 +63,23 @@
62#define DT_STRING 265 63#define DT_STRING 265
63#define DT_LABEL 266 64#define DT_LABEL 266
64#define DT_REF 267 65#define DT_REF 267
66#define DT_INCBIN 268
65 67
66 68
67 69
68 70
69#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 71#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
70typedef union YYSTYPE 72typedef union YYSTYPE
71#line 34 "dtc-parser.y" 73#line 37 "dtc-parser.y"
72{ 74{
73 char *propnodename; 75 char *propnodename;
74 char *literal; 76 char *literal;
75 char *labelref; 77 char *labelref;
76 unsigned int cbase; 78 unsigned int cbase;
77 u8 byte; 79 uint8_t byte;
78 struct data data; 80 struct data data;
79 81
80 u64 addr; 82 uint64_t addr;
81 cell_t cell; 83 cell_t cell;
82 struct property *prop; 84 struct property *prop;
83 struct property *proplist; 85 struct property *proplist;
@@ -86,7 +88,7 @@ typedef union YYSTYPE
86 struct reserve_info *re; 88 struct reserve_info *re;
87} 89}
88/* Line 1489 of yacc.c. */ 90/* Line 1489 of yacc.c. */
89#line 90 "dtc-parser.tab.h" 91#line 92 "dtc-parser.tab.h"
90 YYSTYPE; 92 YYSTYPE;
91# define yystype YYSTYPE /* obsolescent; will be withdrawn */ 93# define yystype YYSTYPE /* obsolescent; will be withdrawn */
92# define YYSTYPE_IS_DECLARED 1 94# define YYSTYPE_IS_DECLARED 1
diff --git a/arch/powerpc/boot/dtc-src/dtc-parser.y b/arch/powerpc/boot/dtc-src/dtc-parser.y
index 002ea7fef184..b2ab562420ea 100644
--- a/arch/powerpc/boot/dtc-src/dtc-parser.y
+++ b/arch/powerpc/boot/dtc-src/dtc-parser.y
@@ -21,14 +21,17 @@
21%locations 21%locations
22 22
23%{ 23%{
24#include <stdio.h>
25
24#include "dtc.h" 26#include "dtc.h"
25#include "srcpos.h" 27#include "srcpos.h"
26 28
27int yylex(void); 29extern int yylex(void);
28unsigned long long eval_literal(const char *s, int base, int bits);
29 30
30extern struct boot_info *the_boot_info; 31extern struct boot_info *the_boot_info;
32extern int treesource_error;
31 33
34static unsigned long long eval_literal(const char *s, int base, int bits);
32%} 35%}
33 36
34%union { 37%union {
@@ -36,10 +39,10 @@ extern struct boot_info *the_boot_info;
36 char *literal; 39 char *literal;
37 char *labelref; 40 char *labelref;
38 unsigned int cbase; 41 unsigned int cbase;
39 u8 byte; 42 uint8_t byte;
40 struct data data; 43 struct data data;
41 44
42 u64 addr; 45 uint64_t addr;
43 cell_t cell; 46 cell_t cell;
44 struct property *prop; 47 struct property *prop;
45 struct property *proplist; 48 struct property *proplist;
@@ -58,6 +61,7 @@ extern struct boot_info *the_boot_info;
58%token <data> DT_STRING 61%token <data> DT_STRING
59%token <labelref> DT_LABEL 62%token <labelref> DT_LABEL
60%token <labelref> DT_REF 63%token <labelref> DT_REF
64%token DT_INCBIN
61 65
62%type <data> propdata 66%type <data> propdata
63%type <data> propdataprefix 67%type <data> propdataprefix
@@ -84,11 +88,11 @@ extern struct boot_info *the_boot_info;
84sourcefile: 88sourcefile:
85 DT_V1 ';' memreserves devicetree 89 DT_V1 ';' memreserves devicetree
86 { 90 {
87 the_boot_info = build_boot_info($3, $4); 91 the_boot_info = build_boot_info($3, $4, 0);
88 } 92 }
89 | v0_memreserves devicetree 93 | v0_memreserves devicetree
90 { 94 {
91 the_boot_info = build_boot_info($1, $2); 95 the_boot_info = build_boot_info($1, $2, 0);
92 } 96 }
93 ; 97 ;
94 98
@@ -196,6 +200,34 @@ propdata:
196 { 200 {
197 $$ = data_add_marker($1, REF_PATH, $2); 201 $$ = data_add_marker($1, REF_PATH, $2);
198 } 202 }
203 | propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')'
204 {
205 struct search_path path = { srcpos_file->dir, NULL, NULL };
206 struct dtc_file *file = dtc_open_file($4.val, &path);
207 struct data d = empty_data;
208
209 if ($6 != 0)
210 if (fseek(file->file, $6, SEEK_SET) != 0)
211 yyerrorf("Couldn't seek to offset %llu in \"%s\": %s",
212 (unsigned long long)$6,
213 $4.val, strerror(errno));
214
215 d = data_copy_file(file->file, $8);
216
217 $$ = data_merge($1, d);
218 dtc_close_file(file);
219 }
220 | propdataprefix DT_INCBIN '(' DT_STRING ')'
221 {
222 struct search_path path = { srcpos_file->dir, NULL, NULL };
223 struct dtc_file *file = dtc_open_file($4.val, &path);
224 struct data d = empty_data;
225
226 d = data_copy_file(file->file, -1);
227
228 $$ = data_merge($1, d);
229 dtc_close_file(file);
230 }
199 | propdata DT_LABEL 231 | propdata DT_LABEL
200 { 232 {
201 $$ = data_add_marker($1, LABEL, $2); 233 $$ = data_add_marker($1, LABEL, $2);
@@ -282,7 +314,7 @@ subnodes:
282 } 314 }
283 | subnode propdef 315 | subnode propdef
284 { 316 {
285 yyerror("syntax error: properties must precede subnodes\n"); 317 yyerror("syntax error: properties must precede subnodes");
286 YYERROR; 318 YYERROR;
287 } 319 }
288 ; 320 ;
@@ -307,18 +339,29 @@ label:
307 339
308%% 340%%
309 341
310void yyerror (char const *s) 342void yyerrorf(char const *s, ...)
311{ 343{
312 const char *fname = srcpos_filename_for_num(yylloc.filenum); 344 const char *fname = srcpos_file ? srcpos_file->name : "<no-file>";
345 va_list va;
346 va_start(va, s);
313 347
314 if (strcmp(fname, "-") == 0) 348 if (strcmp(fname, "-") == 0)
315 fname = "stdin"; 349 fname = "stdin";
316 350
317 fprintf(stderr, "%s:%d %s\n", 351 fprintf(stderr, "%s:%d ", fname, yylloc.first_line);
318 fname, yylloc.first_line, s); 352 vfprintf(stderr, s, va);
353 fprintf(stderr, "\n");
354
355 treesource_error = 1;
356 va_end(va);
357}
358
359void yyerror (char const *s)
360{
361 yyerrorf("%s", s);
319} 362}
320 363
321unsigned long long eval_literal(const char *s, int base, int bits) 364static unsigned long long eval_literal(const char *s, int base, int bits)
322{ 365{
323 unsigned long long val; 366 unsigned long long val;
324 char *e; 367 char *e;
diff --git a/arch/powerpc/boot/dtc-src/dtc.c b/arch/powerpc/boot/dtc-src/dtc.c
index 01131d7c2d5e..d8fd43b4ac1a 100644
--- a/arch/powerpc/boot/dtc-src/dtc.c
+++ b/arch/powerpc/boot/dtc-src/dtc.c
@@ -55,7 +55,7 @@ char *join_path(const char *path, const char *name)
55 return str; 55 return str;
56} 56}
57 57
58void fill_fullpaths(struct node *tree, const char *prefix) 58static void fill_fullpaths(struct node *tree, const char *prefix)
59{ 59{
60 struct node *child; 60 struct node *child;
61 const char *unit; 61 const char *unit;
@@ -106,7 +106,7 @@ static void __attribute__ ((noreturn)) usage(void)
106 fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n"); 106 fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n");
107 fprintf(stderr, "\t-v\n"); 107 fprintf(stderr, "\t-v\n");
108 fprintf(stderr, "\t\tPrint DTC version and exit\n"); 108 fprintf(stderr, "\t\tPrint DTC version and exit\n");
109 exit(2); 109 exit(3);
110} 110}
111 111
112int main(int argc, char *argv[]) 112int main(int argc, char *argv[])
@@ -118,10 +118,9 @@ int main(int argc, char *argv[])
118 int force = 0, check = 0; 118 int force = 0, check = 0;
119 const char *arg; 119 const char *arg;
120 int opt; 120 int opt;
121 FILE *inf = NULL;
122 FILE *outf = NULL; 121 FILE *outf = NULL;
123 int outversion = DEFAULT_FDT_VERSION; 122 int outversion = DEFAULT_FDT_VERSION;
124 int boot_cpuid_phys = 0xfeedbeef; 123 long long cmdline_boot_cpuid = -1;
125 124
126 quiet = 0; 125 quiet = 0;
127 reservenum = 0; 126 reservenum = 0;
@@ -161,11 +160,11 @@ int main(int argc, char *argv[])
161 quiet++; 160 quiet++;
162 break; 161 break;
163 case 'b': 162 case 'b':
164 boot_cpuid_phys = strtol(optarg, NULL, 0); 163 cmdline_boot_cpuid = strtoll(optarg, NULL, 0);
165 break; 164 break;
166 case 'v': 165 case 'v':
167 printf("Version: %s\n", DTC_VERSION); 166 printf("Version: %s\n", DTC_VERSION);
168 exit(0); 167 exit(0);
169 case 'h': 168 case 'h':
170 default: 169 default:
171 usage(); 170 usage();
@@ -180,31 +179,27 @@ int main(int argc, char *argv[])
180 arg = argv[optind]; 179 arg = argv[optind];
181 180
182 /* minsize and padsize are mutually exclusive */ 181 /* minsize and padsize are mutually exclusive */
183 if ((minsize) && (padsize)) { 182 if (minsize && padsize)
184 die("Can't set both -p and -S\n"); 183 die("Can't set both -p and -S\n");
185 }
186 184
187 fprintf(stderr, "DTC: %s->%s on file \"%s\"\n", 185 fprintf(stderr, "DTC: %s->%s on file \"%s\"\n",
188 inform, outform, arg); 186 inform, outform, arg);
189 187
190 if (streq(inform, "dts")) { 188 if (streq(inform, "dts"))
191 bi = dt_from_source(arg); 189 bi = dt_from_source(arg);
192 } else if (streq(inform, "fs")) { 190 else if (streq(inform, "fs"))
193 bi = dt_from_fs(arg); 191 bi = dt_from_fs(arg);
194 } else if(streq(inform, "dtb")) { 192 else if(streq(inform, "dtb"))
195 inf = dtc_open_file(arg); 193 bi = dt_from_blob(arg);
196 bi = dt_from_blob(inf); 194 else
197 } else {
198 die("Unknown input format \"%s\"\n", inform); 195 die("Unknown input format \"%s\"\n", inform);
199 }
200 196
201 if (inf && (inf != stdin)) 197 if (cmdline_boot_cpuid != -1)
202 fclose(inf); 198 bi->boot_cpuid_phys = cmdline_boot_cpuid;
203 199
204 if (! bi || ! bi->dt) 200 fill_fullpaths(bi->dt, "");
205 die("Couldn't read input tree\n"); 201 process_checks(force, bi);
206 202
207 process_checks(force, bi, check, outversion, boot_cpuid_phys);
208 203
209 if (streq(outname, "-")) { 204 if (streq(outname, "-")) {
210 outf = stdout; 205 outf = stdout;
@@ -218,9 +213,9 @@ int main(int argc, char *argv[])
218 if (streq(outform, "dts")) { 213 if (streq(outform, "dts")) {
219 dt_to_source(outf, bi); 214 dt_to_source(outf, bi);
220 } else if (streq(outform, "dtb")) { 215 } else if (streq(outform, "dtb")) {
221 dt_to_blob(outf, bi, outversion, boot_cpuid_phys); 216 dt_to_blob(outf, bi, outversion);
222 } else if (streq(outform, "asm")) { 217 } else if (streq(outform, "asm")) {
223 dt_to_asm(outf, bi, outversion, boot_cpuid_phys); 218 dt_to_asm(outf, bi, outversion);
224 } else if (streq(outform, "null")) { 219 } else if (streq(outform, "null")) {
225 /* do nothing */ 220 /* do nothing */
226 } else { 221 } else {
diff --git a/arch/powerpc/boot/dtc-src/dtc.h b/arch/powerpc/boot/dtc-src/dtc.h
index 65281777a167..08d54c870086 100644
--- a/arch/powerpc/boot/dtc-src/dtc.h
+++ b/arch/powerpc/boot/dtc-src/dtc.h
@@ -30,10 +30,8 @@
30#include <ctype.h> 30#include <ctype.h>
31#include <errno.h> 31#include <errno.h>
32#include <unistd.h> 32#include <unistd.h>
33#include <netinet/in.h>
34#include <endian.h>
35#include <byteswap.h>
36 33
34#include <libfdt_env.h>
37#include <fdt.h> 35#include <fdt.h>
38 36
39#define DEFAULT_FDT_VERSION 17 37#define DEFAULT_FDT_VERSION 17
@@ -75,25 +73,8 @@ static inline void *xrealloc(void *p, size_t len)
75 return new; 73 return new;
76} 74}
77 75
78typedef uint8_t u8; 76typedef uint32_t cell_t;
79typedef uint16_t u16;
80typedef uint32_t u32;
81typedef uint64_t u64;
82typedef u32 cell_t;
83 77
84#define cpu_to_be16(x) htons(x)
85#define be16_to_cpu(x) ntohs(x)
86
87#define cpu_to_be32(x) htonl(x)
88#define be32_to_cpu(x) ntohl(x)
89
90#if __BYTE_ORDER == __BIG_ENDIAN
91#define cpu_to_be64(x) (x)
92#define be64_to_cpu(x) (x)
93#else
94#define cpu_to_be64(x) bswap_64(x)
95#define be64_to_cpu(x) bswap_64(x)
96#endif
97 78
98#define streq(a, b) (strcmp((a), (b)) == 0) 79#define streq(a, b) (strcmp((a), (b)) == 0)
99#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) 80#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
@@ -118,7 +99,6 @@ struct marker {
118struct data { 99struct data {
119 int len; 100 int len;
120 char *val; 101 char *val;
121 int asize;
122 struct marker *markers; 102 struct marker *markers;
123}; 103};
124 104
@@ -145,7 +125,7 @@ struct data data_insert_at_marker(struct data d, struct marker *m,
145struct data data_merge(struct data d1, struct data d2); 125struct data data_merge(struct data d1, struct data d2);
146struct data data_append_cell(struct data d, cell_t word); 126struct data data_append_cell(struct data d, cell_t word);
147struct data data_append_re(struct data d, const struct fdt_reserve_entry *re); 127struct data data_append_re(struct data d, const struct fdt_reserve_entry *re);
148struct data data_append_addr(struct data d, u64 addr); 128struct data data_append_addr(struct data d, uint64_t addr);
149struct data data_append_byte(struct data d, uint8_t byte); 129struct data data_append_byte(struct data d, uint8_t byte);
150struct data data_append_zeroes(struct data d, int len); 130struct data data_append_zeroes(struct data d, int len);
151struct data data_append_align(struct data d, int align); 131struct data data_append_align(struct data d, int align);
@@ -223,7 +203,7 @@ struct reserve_info {
223 char *label; 203 char *label;
224}; 204};
225 205
226struct reserve_info *build_reserve_entry(u64 start, u64 len, char *label); 206struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len, char *label);
227struct reserve_info *chain_reserve_entry(struct reserve_info *first, 207struct reserve_info *chain_reserve_entry(struct reserve_info *first,
228 struct reserve_info *list); 208 struct reserve_info *list);
229struct reserve_info *add_reserve_entry(struct reserve_info *list, 209struct reserve_info *add_reserve_entry(struct reserve_info *list,
@@ -233,24 +213,22 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list,
233struct boot_info { 213struct boot_info {
234 struct reserve_info *reservelist; 214 struct reserve_info *reservelist;
235 struct node *dt; /* the device tree */ 215 struct node *dt; /* the device tree */
216 uint32_t boot_cpuid_phys;
236}; 217};
237 218
238struct boot_info *build_boot_info(struct reserve_info *reservelist, 219struct boot_info *build_boot_info(struct reserve_info *reservelist,
239 struct node *tree); 220 struct node *tree, uint32_t boot_cpuid_phys);
240 221
241/* Checks */ 222/* Checks */
242 223
243void process_checks(int force, struct boot_info *bi, 224void process_checks(int force, struct boot_info *bi);
244 int checkflag, int outversion, int boot_cpuid_phys);
245 225
246/* Flattened trees */ 226/* Flattened trees */
247 227
248void dt_to_blob(FILE *f, struct boot_info *bi, int version, 228void dt_to_blob(FILE *f, struct boot_info *bi, int version);
249 int boot_cpuid_phys); 229void dt_to_asm(FILE *f, struct boot_info *bi, int version);
250void dt_to_asm(FILE *f, struct boot_info *bi, int version,
251 int boot_cpuid_phys);
252 230
253struct boot_info *dt_from_blob(FILE *f); 231struct boot_info *dt_from_blob(const char *fname);
254 232
255/* Tree source */ 233/* Tree source */
256 234
@@ -264,6 +242,5 @@ struct boot_info *dt_from_fs(const char *dirname);
264/* misc */ 242/* misc */
265 243
266char *join_path(const char *path, const char *name); 244char *join_path(const char *path, const char *name);
267void fill_fullpaths(struct node *tree, const char *prefix);
268 245
269#endif /* _DTC_H */ 246#endif /* _DTC_H */
diff --git a/arch/powerpc/boot/dtc-src/flattree.c b/arch/powerpc/boot/dtc-src/flattree.c
index a7cfb843d334..76acd28c068d 100644
--- a/arch/powerpc/boot/dtc-src/flattree.c
+++ b/arch/powerpc/boot/dtc-src/flattree.c
@@ -19,6 +19,7 @@
19 */ 19 */
20 20
21#include "dtc.h" 21#include "dtc.h"
22#include "srcpos.h"
22 23
23#define FTF_FULLPATH 0x1 24#define FTF_FULLPATH 0x1
24#define FTF_VARALIGN 0x2 25#define FTF_VARALIGN 0x2
@@ -162,28 +163,18 @@ static void asm_emit_data(void *e, struct data d)
162{ 163{
163 FILE *f = e; 164 FILE *f = e;
164 int off = 0; 165 int off = 0;
165 struct marker *m; 166 struct marker *m = d.markers;
166 167
167 m = d.markers; 168 for_each_marker_of_type(m, LABEL)
168 while (m) { 169 emit_offset_label(f, m->ref, m->offset);
169 if (m->type == LABEL)
170 emit_offset_label(f, m->ref, m->offset);
171 m = m->next;
172 }
173 170
174 while ((d.len - off) >= sizeof(u32)) { 171 while ((d.len - off) >= sizeof(uint32_t)) {
175 fprintf(f, "\t.long\t0x%x\n", 172 fprintf(f, "\t.long\t0x%x\n",
176 be32_to_cpu(*((u32 *)(d.val+off)))); 173 fdt32_to_cpu(*((uint32_t *)(d.val+off))));
177 off += sizeof(u32); 174 off += sizeof(uint32_t);
178 }
179
180 if ((d.len - off) >= sizeof(u16)) {
181 fprintf(f, "\t.short\t0x%hx\n",
182 be16_to_cpu(*((u16 *)(d.val+off))));
183 off += sizeof(u16);
184 } 175 }
185 176
186 if ((d.len - off) >= 1) { 177 while ((d.len - off) >= 1) {
187 fprintf(f, "\t.byte\t0x%hhx\n", d.val[off]); 178 fprintf(f, "\t.byte\t0x%hhx\n", d.val[off]);
188 off += 1; 179 off += 1;
189 } 180 }
@@ -336,29 +327,28 @@ static void make_fdt_header(struct fdt_header *fdt,
336 327
337 memset(fdt, 0xff, sizeof(*fdt)); 328 memset(fdt, 0xff, sizeof(*fdt));
338 329
339 fdt->magic = cpu_to_be32(FDT_MAGIC); 330 fdt->magic = cpu_to_fdt32(FDT_MAGIC);
340 fdt->version = cpu_to_be32(vi->version); 331 fdt->version = cpu_to_fdt32(vi->version);
341 fdt->last_comp_version = cpu_to_be32(vi->last_comp_version); 332 fdt->last_comp_version = cpu_to_fdt32(vi->last_comp_version);
342 333
343 /* Reserve map should be doubleword aligned */ 334 /* Reserve map should be doubleword aligned */
344 reserve_off = ALIGN(vi->hdr_size, 8); 335 reserve_off = ALIGN(vi->hdr_size, 8);
345 336
346 fdt->off_mem_rsvmap = cpu_to_be32(reserve_off); 337 fdt->off_mem_rsvmap = cpu_to_fdt32(reserve_off);
347 fdt->off_dt_struct = cpu_to_be32(reserve_off + reservesize); 338 fdt->off_dt_struct = cpu_to_fdt32(reserve_off + reservesize);
348 fdt->off_dt_strings = cpu_to_be32(reserve_off + reservesize 339 fdt->off_dt_strings = cpu_to_fdt32(reserve_off + reservesize
349 + dtsize); 340 + dtsize);
350 fdt->totalsize = cpu_to_be32(reserve_off + reservesize + dtsize + strsize); 341 fdt->totalsize = cpu_to_fdt32(reserve_off + reservesize + dtsize + strsize);
351 342
352 if (vi->flags & FTF_BOOTCPUID) 343 if (vi->flags & FTF_BOOTCPUID)
353 fdt->boot_cpuid_phys = cpu_to_be32(boot_cpuid_phys); 344 fdt->boot_cpuid_phys = cpu_to_fdt32(boot_cpuid_phys);
354 if (vi->flags & FTF_STRTABSIZE) 345 if (vi->flags & FTF_STRTABSIZE)
355 fdt->size_dt_strings = cpu_to_be32(strsize); 346 fdt->size_dt_strings = cpu_to_fdt32(strsize);
356 if (vi->flags & FTF_STRUCTSIZE) 347 if (vi->flags & FTF_STRUCTSIZE)
357 fdt->size_dt_struct = cpu_to_be32(dtsize); 348 fdt->size_dt_struct = cpu_to_fdt32(dtsize);
358} 349}
359 350
360void dt_to_blob(FILE *f, struct boot_info *bi, int version, 351void dt_to_blob(FILE *f, struct boot_info *bi, int version)
361 int boot_cpuid_phys)
362{ 352{
363 struct version_info *vi = NULL; 353 struct version_info *vi = NULL;
364 int i; 354 int i;
@@ -383,26 +373,26 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version,
383 373
384 /* Make header */ 374 /* Make header */
385 make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len, 375 make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len,
386 boot_cpuid_phys); 376 bi->boot_cpuid_phys);
387 377
388 /* 378 /*
389 * If the user asked for more space than is used, adjust the totalsize. 379 * If the user asked for more space than is used, adjust the totalsize.
390 */ 380 */
391 if (minsize > 0) { 381 if (minsize > 0) {
392 padlen = minsize - be32_to_cpu(fdt.totalsize); 382 padlen = minsize - fdt32_to_cpu(fdt.totalsize);
393 if ((padlen < 0) && (quiet < 1)) 383 if ((padlen < 0) && (quiet < 1))
394 fprintf(stderr, 384 fprintf(stderr,
395 "Warning: blob size %d >= minimum size %d\n", 385 "Warning: blob size %d >= minimum size %d\n",
396 be32_to_cpu(fdt.totalsize), minsize); 386 fdt32_to_cpu(fdt.totalsize), minsize);
397 } 387 }
398 388
399 if (padsize > 0) 389 if (padsize > 0)
400 padlen = padsize; 390 padlen = padsize;
401 391
402 if (padlen > 0) { 392 if (padlen > 0) {
403 int tsize = be32_to_cpu(fdt.totalsize); 393 int tsize = fdt32_to_cpu(fdt.totalsize);
404 tsize += padlen; 394 tsize += padlen;
405 fdt.totalsize = cpu_to_be32(tsize); 395 fdt.totalsize = cpu_to_fdt32(tsize);
406 } 396 }
407 397
408 /* 398 /*
@@ -410,7 +400,7 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version,
410 * the reserve buffer, add the reserve map terminating zeroes, 400 * the reserve buffer, add the reserve map terminating zeroes,
411 * the device tree itself, and finally the strings. 401 * the device tree itself, and finally the strings.
412 */ 402 */
413 blob = data_append_data(blob, &fdt, sizeof(fdt)); 403 blob = data_append_data(blob, &fdt, vi->hdr_size);
414 blob = data_append_align(blob, 8); 404 blob = data_append_align(blob, 8);
415 blob = data_merge(blob, reservebuf); 405 blob = data_merge(blob, reservebuf);
416 blob = data_append_zeroes(blob, sizeof(struct fdt_reserve_entry)); 406 blob = data_append_zeroes(blob, sizeof(struct fdt_reserve_entry));
@@ -449,7 +439,7 @@ static void dump_stringtable_asm(FILE *f, struct data strbuf)
449 } 439 }
450} 440}
451 441
452void dt_to_asm(FILE *f, struct boot_info *bi, int version, int boot_cpuid_phys) 442void dt_to_asm(FILE *f, struct boot_info *bi, int version)
453{ 443{
454 struct version_info *vi = NULL; 444 struct version_info *vi = NULL;
455 int i; 445 int i;
@@ -489,7 +479,7 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version, int boot_cpuid_phys)
489 479
490 if (vi->flags & FTF_BOOTCPUID) 480 if (vi->flags & FTF_BOOTCPUID)
491 fprintf(f, "\t.long\t%i\t\t\t\t\t/* boot_cpuid_phys */\n", 481 fprintf(f, "\t.long\t%i\t\t\t\t\t/* boot_cpuid_phys */\n",
492 boot_cpuid_phys); 482 bi->boot_cpuid_phys);
493 483
494 if (vi->flags & FTF_STRTABSIZE) 484 if (vi->flags & FTF_STRTABSIZE)
495 fprintf(f, "\t.long\t_%s_strings_end - _%s_strings_start\t/* size_dt_strings */\n", 485 fprintf(f, "\t.long\t_%s_strings_end - _%s_strings_start\t/* size_dt_strings */\n",
@@ -579,15 +569,15 @@ static void flat_read_chunk(struct inbuf *inb, void *p, int len)
579 inb->ptr += len; 569 inb->ptr += len;
580} 570}
581 571
582static u32 flat_read_word(struct inbuf *inb) 572static uint32_t flat_read_word(struct inbuf *inb)
583{ 573{
584 u32 val; 574 uint32_t val;
585 575
586 assert(((inb->ptr - inb->base) % sizeof(val)) == 0); 576 assert(((inb->ptr - inb->base) % sizeof(val)) == 0);
587 577
588 flat_read_chunk(inb, &val, sizeof(val)); 578 flat_read_chunk(inb, &val, sizeof(val));
589 579
590 return be32_to_cpu(val); 580 return fdt32_to_cpu(val);
591} 581}
592 582
593static void flat_realign(struct inbuf *inb, int align) 583static void flat_realign(struct inbuf *inb, int align)
@@ -615,7 +605,7 @@ static char *flat_read_string(struct inbuf *inb)
615 605
616 inb->ptr += len; 606 inb->ptr += len;
617 607
618 flat_realign(inb, sizeof(u32)); 608 flat_realign(inb, sizeof(uint32_t));
619 609
620 return str; 610 return str;
621} 611}
@@ -632,7 +622,7 @@ static struct data flat_read_data(struct inbuf *inb, int len)
632 622
633 flat_read_chunk(inb, d.val, len); 623 flat_read_chunk(inb, d.val, len);
634 624
635 flat_realign(inb, sizeof(u32)); 625 flat_realign(inb, sizeof(uint32_t));
636 626
637 return d; 627 return d;
638} 628}
@@ -659,7 +649,7 @@ static char *flat_read_stringtable(struct inbuf *inb, int offset)
659static struct property *flat_read_property(struct inbuf *dtbuf, 649static struct property *flat_read_property(struct inbuf *dtbuf,
660 struct inbuf *strbuf, int flags) 650 struct inbuf *strbuf, int flags)
661{ 651{
662 u32 proplen, stroff; 652 uint32_t proplen, stroff;
663 char *name; 653 char *name;
664 struct data val; 654 struct data val;
665 655
@@ -693,8 +683,8 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
693 p = inb->ptr; 683 p = inb->ptr;
694 while (1) { 684 while (1) {
695 flat_read_chunk(inb, &re, sizeof(re)); 685 flat_read_chunk(inb, &re, sizeof(re));
696 re.address = be64_to_cpu(re.address); 686 re.address = fdt64_to_cpu(re.address);
697 re.size = be64_to_cpu(re.size); 687 re.size = fdt64_to_cpu(re.size);
698 if (re.size == 0) 688 if (re.size == 0)
699 break; 689 break;
700 690
@@ -708,77 +698,37 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
708 698
709static char *nodename_from_path(const char *ppath, const char *cpath) 699static char *nodename_from_path(const char *ppath, const char *cpath)
710{ 700{
711 const char *lslash;
712 int plen; 701 int plen;
713 702
714 lslash = strrchr(cpath, '/'); 703 plen = strlen(ppath);
715 if (! lslash)
716 return NULL;
717
718 plen = lslash - cpath;
719
720 if (streq(cpath, "/") && streq(ppath, ""))
721 return "";
722
723 if ((plen == 0) && streq(ppath, "/"))
724 return strdup(lslash+1);
725
726 if (! strneq(ppath, cpath, plen))
727 return NULL;
728
729 return strdup(lslash+1);
730}
731
732static const char PROPCHAR[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,._+*#?-";
733static const char UNITCHAR[] = "0123456789abcdef,";
734
735static int check_node_name(const char *name)
736{
737 const char *atpos;
738 int basenamelen;
739 704
740 atpos = strrchr(name, '@'); 705 if (!strneq(ppath, cpath, plen))
706 die("Path \"%s\" is not valid as a child of \"%s\"\n",
707 cpath, ppath);
741 708
742 if (atpos) 709 /* root node is a special case */
743 basenamelen = atpos - name; 710 if (!streq(ppath, "/"))
744 else 711 plen++;
745 basenamelen = strlen(name);
746
747 if (strspn(name, PROPCHAR) < basenamelen)
748 return -1;
749 712
750 if (atpos 713 return strdup(cpath + plen);
751 && ((basenamelen + 1 + strspn(atpos+1, UNITCHAR)) < strlen(name)))
752 return -1;
753
754 return basenamelen;
755} 714}
756 715
757static struct node *unflatten_tree(struct inbuf *dtbuf, 716static struct node *unflatten_tree(struct inbuf *dtbuf,
758 struct inbuf *strbuf, 717 struct inbuf *strbuf,
759 const char *parent_path, int flags) 718 const char *parent_flatname, int flags)
760{ 719{
761 struct node *node; 720 struct node *node;
762 u32 val; 721 char *flatname;
722 uint32_t val;
763 723
764 node = build_node(NULL, NULL); 724 node = build_node(NULL, NULL);
765 725
766 if (flags & FTF_FULLPATH) { 726 flatname = flat_read_string(dtbuf);
767 node->fullpath = flat_read_string(dtbuf);
768 node->name = nodename_from_path(parent_path, node->fullpath);
769
770 if (! node->name)
771 die("Path \"%s\" is not valid as a child of \"%s\"\n",
772 node->fullpath, parent_path);
773 } else {
774 node->name = flat_read_string(dtbuf);
775 node->fullpath = join_path(parent_path, node->name);
776 }
777 727
778 node->basenamelen = check_node_name(node->name); 728 if (flags & FTF_FULLPATH)
779 if (node->basenamelen < 0) { 729 node->name = nodename_from_path(parent_flatname, flatname);
780 fprintf(stderr, "Warning \"%s\" has incorrect format\n", node->name); 730 else
781 } 731 node->name = flatname;
782 732
783 do { 733 do {
784 struct property *prop; 734 struct property *prop;
@@ -795,8 +745,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
795 break; 745 break;
796 746
797 case FDT_BEGIN_NODE: 747 case FDT_BEGIN_NODE:
798 child = unflatten_tree(dtbuf,strbuf, node->fullpath, 748 child = unflatten_tree(dtbuf,strbuf, flatname, flags);
799 flags);
800 add_child(node, child); 749 add_child(node, child);
801 break; 750 break;
802 751
@@ -825,10 +774,11 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
825} 774}
826 775
827 776
828struct boot_info *dt_from_blob(FILE *f) 777struct boot_info *dt_from_blob(const char *fname)
829{ 778{
830 u32 magic, totalsize, version, size_str, size_dt; 779 struct dtc_file *dtcf;
831 u32 off_dt, off_str, off_mem_rsvmap; 780 uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys;
781 uint32_t off_dt, off_str, off_mem_rsvmap;
832 int rc; 782 int rc;
833 char *blob; 783 char *blob;
834 struct fdt_header *fdt; 784 struct fdt_header *fdt;
@@ -838,54 +788,56 @@ struct boot_info *dt_from_blob(FILE *f)
838 int sizeleft; 788 int sizeleft;
839 struct reserve_info *reservelist; 789 struct reserve_info *reservelist;
840 struct node *tree; 790 struct node *tree;
841 u32 val; 791 uint32_t val;
842 int flags = 0; 792 int flags = 0;
843 793
844 rc = fread(&magic, sizeof(magic), 1, f); 794 dtcf = dtc_open_file(fname, NULL);
845 if (ferror(f)) 795
796 rc = fread(&magic, sizeof(magic), 1, dtcf->file);
797 if (ferror(dtcf->file))
846 die("Error reading DT blob magic number: %s\n", 798 die("Error reading DT blob magic number: %s\n",
847 strerror(errno)); 799 strerror(errno));
848 if (rc < 1) { 800 if (rc < 1) {
849 if (feof(f)) 801 if (feof(dtcf->file))
850 die("EOF reading DT blob magic number\n"); 802 die("EOF reading DT blob magic number\n");
851 else 803 else
852 die("Mysterious short read reading magic number\n"); 804 die("Mysterious short read reading magic number\n");
853 } 805 }
854 806
855 magic = be32_to_cpu(magic); 807 magic = fdt32_to_cpu(magic);
856 if (magic != FDT_MAGIC) 808 if (magic != FDT_MAGIC)
857 die("Blob has incorrect magic number\n"); 809 die("Blob has incorrect magic number\n");
858 810
859 rc = fread(&totalsize, sizeof(totalsize), 1, f); 811 rc = fread(&totalsize, sizeof(totalsize), 1, dtcf->file);
860 if (ferror(f)) 812 if (ferror(dtcf->file))
861 die("Error reading DT blob size: %s\n", strerror(errno)); 813 die("Error reading DT blob size: %s\n", strerror(errno));
862 if (rc < 1) { 814 if (rc < 1) {
863 if (feof(f)) 815 if (feof(dtcf->file))
864 die("EOF reading DT blob size\n"); 816 die("EOF reading DT blob size\n");
865 else 817 else
866 die("Mysterious short read reading blob size\n"); 818 die("Mysterious short read reading blob size\n");
867 } 819 }
868 820
869 totalsize = be32_to_cpu(totalsize); 821 totalsize = fdt32_to_cpu(totalsize);
870 if (totalsize < FDT_V1_SIZE) 822 if (totalsize < FDT_V1_SIZE)
871 die("DT blob size (%d) is too small\n", totalsize); 823 die("DT blob size (%d) is too small\n", totalsize);
872 824
873 blob = xmalloc(totalsize); 825 blob = xmalloc(totalsize);
874 826
875 fdt = (struct fdt_header *)blob; 827 fdt = (struct fdt_header *)blob;
876 fdt->magic = cpu_to_be32(magic); 828 fdt->magic = cpu_to_fdt32(magic);
877 fdt->totalsize = cpu_to_be32(totalsize); 829 fdt->totalsize = cpu_to_fdt32(totalsize);
878 830
879 sizeleft = totalsize - sizeof(magic) - sizeof(totalsize); 831 sizeleft = totalsize - sizeof(magic) - sizeof(totalsize);
880 p = blob + sizeof(magic) + sizeof(totalsize); 832 p = blob + sizeof(magic) + sizeof(totalsize);
881 833
882 while (sizeleft) { 834 while (sizeleft) {
883 if (feof(f)) 835 if (feof(dtcf->file))
884 die("EOF before reading %d bytes of DT blob\n", 836 die("EOF before reading %d bytes of DT blob\n",
885 totalsize); 837 totalsize);
886 838
887 rc = fread(p, 1, sizeleft, f); 839 rc = fread(p, 1, sizeleft, dtcf->file);
888 if (ferror(f)) 840 if (ferror(dtcf->file))
889 die("Error reading DT blob: %s\n", 841 die("Error reading DT blob: %s\n",
890 strerror(errno)); 842 strerror(errno));
891 843
@@ -893,19 +845,11 @@ struct boot_info *dt_from_blob(FILE *f)
893 p += rc; 845 p += rc;
894 } 846 }
895 847
896 off_dt = be32_to_cpu(fdt->off_dt_struct); 848 off_dt = fdt32_to_cpu(fdt->off_dt_struct);
897 off_str = be32_to_cpu(fdt->off_dt_strings); 849 off_str = fdt32_to_cpu(fdt->off_dt_strings);
898 off_mem_rsvmap = be32_to_cpu(fdt->off_mem_rsvmap); 850 off_mem_rsvmap = fdt32_to_cpu(fdt->off_mem_rsvmap);
899 version = be32_to_cpu(fdt->version); 851 version = fdt32_to_cpu(fdt->version);
900 852 boot_cpuid_phys = fdt32_to_cpu(fdt->boot_cpuid_phys);
901 fprintf(stderr, "\tmagic:\t\t\t0x%x\n", magic);
902 fprintf(stderr, "\ttotalsize:\t\t%d\n", totalsize);
903 fprintf(stderr, "\toff_dt_struct:\t\t0x%x\n", off_dt);
904 fprintf(stderr, "\toff_dt_strings:\t\t0x%x\n", off_str);
905 fprintf(stderr, "\toff_mem_rsvmap:\t\t0x%x\n", off_mem_rsvmap);
906 fprintf(stderr, "\tversion:\t\t0x%x\n", version );
907 fprintf(stderr, "\tlast_comp_version:\t0x%x\n",
908 be32_to_cpu(fdt->last_comp_version));
909 853
910 if (off_mem_rsvmap >= totalsize) 854 if (off_mem_rsvmap >= totalsize)
911 die("Mem Reserve structure offset exceeds total size\n"); 855 die("Mem Reserve structure offset exceeds total size\n");
@@ -916,21 +860,17 @@ struct boot_info *dt_from_blob(FILE *f)
916 if (off_str > totalsize) 860 if (off_str > totalsize)
917 die("String table offset exceeds total size\n"); 861 die("String table offset exceeds total size\n");
918 862
919 if (version >= 2)
920 fprintf(stderr, "\tboot_cpuid_phys:\t0x%x\n",
921 be32_to_cpu(fdt->boot_cpuid_phys));
922
923 size_str = -1;
924 if (version >= 3) { 863 if (version >= 3) {
925 size_str = be32_to_cpu(fdt->size_dt_strings); 864 uint32_t size_str = fdt32_to_cpu(fdt->size_dt_strings);
926 fprintf(stderr, "\tsize_dt_strings:\t%d\n", size_str);
927 if (off_str+size_str > totalsize) 865 if (off_str+size_str > totalsize)
928 die("String table extends past total size\n"); 866 die("String table extends past total size\n");
867 inbuf_init(&strbuf, blob + off_str, blob + off_str + size_str);
868 } else {
869 inbuf_init(&strbuf, blob + off_str, blob + totalsize);
929 } 870 }
930 871
931 if (version >= 17) { 872 if (version >= 17) {
932 size_dt = be32_to_cpu(fdt->size_dt_struct); 873 size_dt = fdt32_to_cpu(fdt->size_dt_struct);
933 fprintf(stderr, "\tsize_dt_struct:\t\t%d\n", size_dt);
934 if (off_dt+size_dt > totalsize) 874 if (off_dt+size_dt > totalsize)
935 die("Structure block extends past total size\n"); 875 die("Structure block extends past total size\n");
936 } 876 }
@@ -944,10 +884,6 @@ struct boot_info *dt_from_blob(FILE *f)
944 inbuf_init(&memresvbuf, 884 inbuf_init(&memresvbuf,
945 blob + off_mem_rsvmap, blob + totalsize); 885 blob + off_mem_rsvmap, blob + totalsize);
946 inbuf_init(&dtbuf, blob + off_dt, blob + totalsize); 886 inbuf_init(&dtbuf, blob + off_dt, blob + totalsize);
947 if (size_str >= 0)
948 inbuf_init(&strbuf, blob + off_str, blob + off_str + size_str);
949 else
950 inbuf_init(&strbuf, blob + off_str, blob + totalsize);
951 887
952 reservelist = flat_read_mem_reserve(&memresvbuf); 888 reservelist = flat_read_mem_reserve(&memresvbuf);
953 889
@@ -964,5 +900,7 @@ struct boot_info *dt_from_blob(FILE *f)
964 900
965 free(blob); 901 free(blob);
966 902
967 return build_boot_info(reservelist, tree); 903 dtc_close_file(dtcf);
904
905 return build_boot_info(reservelist, tree, boot_cpuid_phys);
968} 906}
diff --git a/arch/powerpc/boot/dtc-src/fstree.c b/arch/powerpc/boot/dtc-src/fstree.c
index 2a160a46998e..766b2694d935 100644
--- a/arch/powerpc/boot/dtc-src/fstree.c
+++ b/arch/powerpc/boot/dtc-src/fstree.c
@@ -31,8 +31,8 @@ static struct node *read_fstree(const char *dirname)
31 struct node *tree; 31 struct node *tree;
32 32
33 d = opendir(dirname); 33 d = opendir(dirname);
34 if (! d) 34 if (!d)
35 die("opendir(): %s\n", strerror(errno)); 35 die("Couldn't opendir() \"%s\": %s\n", dirname, strerror(errno));
36 36
37 tree = build_node(NULL, NULL); 37 tree = build_node(NULL, NULL);
38 38
@@ -87,8 +87,6 @@ struct boot_info *dt_from_fs(const char *dirname)
87 tree = read_fstree(dirname); 87 tree = read_fstree(dirname);
88 tree = name_node(tree, "", NULL); 88 tree = name_node(tree, "", NULL);
89 89
90 fill_fullpaths(tree, ""); 90 return build_boot_info(NULL, tree, 0);
91
92 return build_boot_info(NULL, tree);
93} 91}
94 92
diff --git a/arch/powerpc/boot/dtc-src/libfdt_env.h b/arch/powerpc/boot/dtc-src/libfdt_env.h
new file mode 100644
index 000000000000..449bf602daf1
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/libfdt_env.h
@@ -0,0 +1,23 @@
1#ifndef _LIBFDT_ENV_H
2#define _LIBFDT_ENV_H
3
4#include <stddef.h>
5#include <stdint.h>
6#include <string.h>
7
8#define _B(n) ((unsigned long long)((uint8_t *)&x)[n])
9static inline uint32_t fdt32_to_cpu(uint32_t x)
10{
11 return (_B(0) << 24) | (_B(1) << 16) | (_B(2) << 8) | _B(3);
12}
13#define cpu_to_fdt32(x) fdt32_to_cpu(x)
14
15static inline uint64_t fdt64_to_cpu(uint64_t x)
16{
17 return (_B(0) << 56) | (_B(1) << 48) | (_B(2) << 40) | (_B(3) << 32)
18 | (_B(4) << 24) | (_B(5) << 16) | (_B(6) << 8) | _B(7);
19}
20#define cpu_to_fdt64(x) fdt64_to_cpu(x)
21#undef _B
22
23#endif /* _LIBFDT_ENV_H */
diff --git a/arch/powerpc/boot/dtc-src/livetree.c b/arch/powerpc/boot/dtc-src/livetree.c
index 6ba0846b4310..0ca3de550b3f 100644
--- a/arch/powerpc/boot/dtc-src/livetree.c
+++ b/arch/powerpc/boot/dtc-src/livetree.c
@@ -115,6 +115,7 @@ void add_child(struct node *parent, struct node *child)
115 struct node **p; 115 struct node **p;
116 116
117 child->next_sibling = NULL; 117 child->next_sibling = NULL;
118 child->parent = parent;
118 119
119 p = &parent->children; 120 p = &parent->children;
120 while (*p) 121 while (*p)
@@ -123,7 +124,8 @@ void add_child(struct node *parent, struct node *child)
123 *p = child; 124 *p = child;
124} 125}
125 126
126struct reserve_info *build_reserve_entry(u64 address, u64 size, char *label) 127struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size,
128 char *label)
127{ 129{
128 struct reserve_info *new = xmalloc(sizeof(*new)); 130 struct reserve_info *new = xmalloc(sizeof(*new));
129 131
@@ -165,13 +167,14 @@ struct reserve_info *add_reserve_entry(struct reserve_info *list,
165} 167}
166 168
167struct boot_info *build_boot_info(struct reserve_info *reservelist, 169struct boot_info *build_boot_info(struct reserve_info *reservelist,
168 struct node *tree) 170 struct node *tree, uint32_t boot_cpuid_phys)
169{ 171{
170 struct boot_info *bi; 172 struct boot_info *bi;
171 173
172 bi = xmalloc(sizeof(*bi)); 174 bi = xmalloc(sizeof(*bi));
173 bi->reservelist = reservelist; 175 bi->reservelist = reservelist;
174 bi->dt = tree; 176 bi->dt = tree;
177 bi->boot_cpuid_phys = boot_cpuid_phys;
175 178
176 return bi; 179 return bi;
177} 180}
@@ -202,7 +205,7 @@ struct property *get_property(struct node *node, const char *propname)
202cell_t propval_cell(struct property *prop) 205cell_t propval_cell(struct property *prop)
203{ 206{
204 assert(prop->val.len == sizeof(cell_t)); 207 assert(prop->val.len == sizeof(cell_t));
205 return be32_to_cpu(*((cell_t *)prop->val.val)); 208 return fdt32_to_cpu(*((cell_t *)prop->val.val));
206} 209}
207 210
208struct node *get_subnode(struct node *node, const char *nodename) 211struct node *get_subnode(struct node *node, const char *nodename)
diff --git a/arch/powerpc/boot/dtc-src/srcpos.c b/arch/powerpc/boot/dtc-src/srcpos.c
index 352b0fe06fde..9641b7628b4d 100644
--- a/arch/powerpc/boot/dtc-src/srcpos.c
+++ b/arch/powerpc/boot/dtc-src/srcpos.c
@@ -20,86 +20,97 @@
20#include "dtc.h" 20#include "dtc.h"
21#include "srcpos.h" 21#include "srcpos.h"
22 22
23
24/*
25 * Record the complete unique set of opened file names.
26 * Primarily used to cache source position file names.
27 */
28#define MAX_N_FILE_NAMES (100)
29
30const char *file_names[MAX_N_FILE_NAMES];
31static int n_file_names = 0;
32
33/* 23/*
34 * Like yylineno, this is the current open file pos. 24 * Like yylineno, this is the current open file pos.
35 */ 25 */
36 26
37int srcpos_filenum = -1; 27struct dtc_file *srcpos_file;
38
39 28
40 29static int dtc_open_one(struct dtc_file *file,
41FILE *dtc_open_file(const char *fname) 30 const char *search,
31 const char *fname)
42{ 32{
43 FILE *f; 33 char *fullname;
44 34
45 if (lookup_file_name(fname, 1) < 0) 35 if (search) {
46 die("Too many files opened\n"); 36 fullname = xmalloc(strlen(search) + strlen(fname) + 2);
47 37
48 if (streq(fname, "-")) 38 strcpy(fullname, search);
49 f = stdin; 39 strcat(fullname, "/");
50 else 40 strcat(fullname, fname);
51 f = fopen(fname, "r"); 41 } else {
42 fullname = strdup(fname);
43 }
52 44
53 if (! f) 45 file->file = fopen(fullname, "r");
54 die("Couldn't open \"%s\": %s\n", fname, strerror(errno)); 46 if (!file->file) {
47 free(fullname);
48 return 0;
49 }
55 50
56 return f; 51 file->name = fullname;
52 return 1;
57} 53}
58 54
59 55
56struct dtc_file *dtc_open_file(const char *fname,
57 const struct search_path *search)
58{
59 static const struct search_path default_search = { NULL, NULL, NULL };
60 60
61/* 61 struct dtc_file *file;
62 * Locate and optionally add filename fname in the file_names[] array. 62 const char *slash;
63 *
64 * If the filename is currently not in the array and the boolean
65 * add_it is non-zero, an attempt to add the filename will be made.
66 *
67 * Returns;
68 * Index [0..MAX_N_FILE_NAMES) where the filename is kept
69 * -1 if the name can not be recorded
70 */
71 63
72int lookup_file_name(const char *fname, int add_it) 64 file = xmalloc(sizeof(struct dtc_file));
73{
74 int i;
75 65
76 for (i = 0; i < n_file_names; i++) { 66 slash = strrchr(fname, '/');
77 if (strcmp(file_names[i], fname) == 0) 67 if (slash) {
78 return i; 68 char *dir = xmalloc(slash - fname + 1);
69
70 memcpy(dir, fname, slash - fname);
71 dir[slash - fname] = 0;
72 file->dir = dir;
73 } else {
74 file->dir = NULL;
79 } 75 }
80 76
81 if (add_it) { 77 if (streq(fname, "-")) {
82 if (n_file_names < MAX_N_FILE_NAMES) { 78 file->name = "stdin";
83 file_names[n_file_names] = strdup(fname); 79 file->file = stdin;
84 return n_file_names++; 80 return file;
85 }
86 } 81 }
87 82
88 return -1; 83 if (fname[0] == '/') {
89} 84 file->file = fopen(fname, "r");
85 if (!file->file)
86 goto fail;
87
88 file->name = strdup(fname);
89 return file;
90 }
90 91
92 if (!search)
93 search = &default_search;
91 94
92const char *srcpos_filename_for_num(int filenum) 95 while (search) {
93{ 96 if (dtc_open_one(file, search->dir, fname))
94 if (0 <= filenum && filenum < n_file_names) { 97 return file;
95 return file_names[filenum]; 98
99 if (errno != ENOENT)
100 goto fail;
101
102 search = search->next;
96 } 103 }
97 104
98 return 0; 105fail:
106 die("Couldn't open \"%s\": %s\n", fname, strerror(errno));
99} 107}
100 108
101 109void dtc_close_file(struct dtc_file *file)
102const char *srcpos_get_filename(void)
103{ 110{
104 return srcpos_filename_for_num(srcpos_filenum); 111 if (fclose(file->file))
112 die("Error closing \"%s\": %s\n", file->name, strerror(errno));
113
114 free(file->dir);
115 free(file);
105} 116}
diff --git a/arch/powerpc/boot/dtc-src/srcpos.h b/arch/powerpc/boot/dtc-src/srcpos.h
index ce7ab5ba5b46..e17c7c04db8e 100644
--- a/arch/powerpc/boot/dtc-src/srcpos.h
+++ b/arch/powerpc/boot/dtc-src/srcpos.h
@@ -22,13 +22,21 @@
22 * array of all opened filenames. 22 * array of all opened filenames.
23 */ 23 */
24 24
25#include <stdio.h>
26
27struct dtc_file {
28 char *dir;
29 const char *name;
30 FILE *file;
31};
32
25#if ! defined(YYLTYPE) && ! defined(YYLTYPE_IS_DECLARED) 33#if ! defined(YYLTYPE) && ! defined(YYLTYPE_IS_DECLARED)
26typedef struct YYLTYPE { 34typedef struct YYLTYPE {
27 int first_line; 35 int first_line;
28 int first_column; 36 int first_column;
29 int last_line; 37 int last_line;
30 int last_column; 38 int last_column;
31 int filenum; 39 struct dtc_file *file;
32} YYLTYPE; 40} YYLTYPE;
33 41
34#define YYLTYPE_IS_DECLARED 1 42#define YYLTYPE_IS_DECLARED 1
@@ -48,7 +56,7 @@ typedef struct YYLTYPE {
48 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ 56 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
49 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ 57 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
50 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ 58 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
51 (Current).filenum = YYRHSLOC (Rhs, N).filenum; \ 59 (Current).file = YYRHSLOC (Rhs, N).file; \
52 } \ 60 } \
53 else \ 61 else \
54 { \ 62 { \
@@ -56,20 +64,22 @@ typedef struct YYLTYPE {
56 YYRHSLOC (Rhs, 0).last_line; \ 64 YYRHSLOC (Rhs, 0).last_line; \
57 (Current).first_column = (Current).last_column = \ 65 (Current).first_column = (Current).last_column = \
58 YYRHSLOC (Rhs, 0).last_column; \ 66 YYRHSLOC (Rhs, 0).last_column; \
59 (Current).filenum = YYRHSLOC (Rhs, 0).filenum; \ 67 (Current).file = YYRHSLOC (Rhs, 0).file; \
60 } \ 68 } \
61 while (YYID (0)) 69 while (YYID (0))
62 70
63 71
64 72
65extern void yyerror(char const *); 73extern void yyerror(char const *);
74extern void yyerrorf(char const *, ...) __attribute__((format(printf, 1, 2)));
66 75
67extern int srcpos_filenum; 76extern struct dtc_file *srcpos_file;
68 77
69extern int push_input_file(const char *filename); 78struct search_path {
70extern int pop_input_file(void); 79 const char *dir; /* NULL for current directory */
80 struct search_path *prev, *next;
81};
71 82
72extern FILE *dtc_open_file(const char *fname); 83extern struct dtc_file *dtc_open_file(const char *fname,
73extern int lookup_file_name(const char *fname, int add_it); 84 const struct search_path *search);
74extern const char *srcpos_filename_for_num(int filenum); 85extern void dtc_close_file(struct dtc_file *file);
75const char *srcpos_get_filename(void);
diff --git a/arch/powerpc/boot/dtc-src/treesource.c b/arch/powerpc/boot/dtc-src/treesource.c
index a6a776797636..ebeb6eb27907 100644
--- a/arch/powerpc/boot/dtc-src/treesource.c
+++ b/arch/powerpc/boot/dtc-src/treesource.c
@@ -23,20 +23,23 @@
23 23
24extern FILE *yyin; 24extern FILE *yyin;
25extern int yyparse(void); 25extern int yyparse(void);
26extern void yyerror(char const *);
27 26
28struct boot_info *the_boot_info; 27struct boot_info *the_boot_info;
28int treesource_error;
29 29
30struct boot_info *dt_from_source(const char *fname) 30struct boot_info *dt_from_source(const char *fname)
31{ 31{
32 the_boot_info = NULL; 32 the_boot_info = NULL;
33 treesource_error = 0;
33 34
34 push_input_file(fname); 35 srcpos_file = dtc_open_file(fname, NULL);
36 yyin = srcpos_file->file;
35 37
36 if (yyparse() != 0) 38 if (yyparse() != 0)
37 return NULL; 39 die("Unable to parse input tree\n");
38 40
39 fill_fullpaths(the_boot_info->dt, ""); 41 if (treesource_error)
42 die("Syntax error parsing input tree\n");
40 43
41 return the_boot_info; 44 return the_boot_info;
42} 45}
@@ -144,7 +147,7 @@ static void write_propval_cells(FILE *f, struct data val)
144 m = m->next; 147 m = m->next;
145 } 148 }
146 149
147 fprintf(f, "0x%x", be32_to_cpu(*cp++)); 150 fprintf(f, "0x%x", fdt32_to_cpu(*cp++));
148 if ((void *)cp >= propend) 151 if ((void *)cp >= propend)
149 break; 152 break;
150 fprintf(f, " "); 153 fprintf(f, " ");
@@ -173,7 +176,7 @@ static void write_propval_bytes(FILE *f, struct data val)
173 } 176 }
174 177
175 fprintf(f, "%02hhx", *bp++); 178 fprintf(f, "%02hhx", *bp++);
176 if ((void *)bp >= propend) 179 if ((const void *)bp >= propend)
177 break; 180 break;
178 fprintf(f, " "); 181 fprintf(f, " ");
179 } 182 }
diff --git a/arch/powerpc/boot/dtc-src/version_gen.h b/arch/powerpc/boot/dtc-src/version_gen.h
index 6c343031538e..658ff42429d6 100644
--- a/arch/powerpc/boot/dtc-src/version_gen.h
+++ b/arch/powerpc/boot/dtc-src/version_gen.h
@@ -1 +1 @@
#define DTC_VERSION "DTC 1.0.0-gd6f9b62f" #define DTC_VERSION "DTC 1.2.0"
diff --git a/arch/powerpc/boot/libfdt/Makefile.libfdt b/arch/powerpc/boot/libfdt/Makefile.libfdt
index 82f9c6a8287b..6c42acfa21ec 100644
--- a/arch/powerpc/boot/libfdt/Makefile.libfdt
+++ b/arch/powerpc/boot/libfdt/Makefile.libfdt
@@ -3,12 +3,6 @@
3# This is not a complete Makefile of itself. Instead, it is designed to 3# This is not a complete Makefile of itself. Instead, it is designed to
4# be easily embeddable into other systems of Makefiles. 4# be easily embeddable into other systems of Makefiles.
5# 5#
6LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
7LIBFDT_INCLUDES = fdt.h libfdt.h 6LIBFDT_INCLUDES = fdt.h libfdt.h
8LIBFDT_EXTRA = libfdt_internal.h 7LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
9LIBFDT_LIB = libfdt/libfdt.a
10
11LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o) 8LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
12
13$(LIBFDT_objdir)/$(LIBFDT_LIB): $(addprefix $(LIBFDT_objdir)/,$(LIBFDT_OBJS))
14
diff --git a/arch/powerpc/boot/libfdt/fdt.c b/arch/powerpc/boot/libfdt/fdt.c
index 586a36136db2..2acaec5923ae 100644
--- a/arch/powerpc/boot/libfdt/fdt.c
+++ b/arch/powerpc/boot/libfdt/fdt.c
@@ -63,7 +63,7 @@ int fdt_check_header(const void *fdt)
63 return -FDT_ERR_BADVERSION; 63 return -FDT_ERR_BADVERSION;
64 if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) 64 if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
65 return -FDT_ERR_BADVERSION; 65 return -FDT_ERR_BADVERSION;
66 } else if (fdt_magic(fdt) == SW_MAGIC) { 66 } else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
67 /* Unfinished sequential-write blob */ 67 /* Unfinished sequential-write blob */
68 if (fdt_size_dt_struct(fdt) == 0) 68 if (fdt_size_dt_struct(fdt) == 0)
69 return -FDT_ERR_BADSTATE; 69 return -FDT_ERR_BADSTATE;
@@ -76,7 +76,7 @@ int fdt_check_header(const void *fdt)
76 76
77const void *fdt_offset_ptr(const void *fdt, int offset, int len) 77const void *fdt_offset_ptr(const void *fdt, int offset, int len)
78{ 78{
79 const void *p; 79 const char *p;
80 80
81 if (fdt_version(fdt) >= 0x11) 81 if (fdt_version(fdt) >= 0x11)
82 if (((offset + len) < offset) 82 if (((offset + len) < offset)
@@ -124,11 +124,59 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset)
124 } 124 }
125 125
126 if (nextoffset) 126 if (nextoffset)
127 *nextoffset = ALIGN(offset, FDT_TAGSIZE); 127 *nextoffset = FDT_TAGALIGN(offset);
128 128
129 return tag; 129 return tag;
130} 130}
131 131
132int _fdt_check_node_offset(const void *fdt, int offset)
133{
134 if ((offset < 0) || (offset % FDT_TAGSIZE)
135 || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
136 return -FDT_ERR_BADOFFSET;
137
138 return offset;
139}
140
141int fdt_next_node(const void *fdt, int offset, int *depth)
142{
143 int nextoffset = 0;
144 uint32_t tag;
145
146 if (offset >= 0)
147 if ((nextoffset = _fdt_check_node_offset(fdt, offset)) < 0)
148 return nextoffset;
149
150 do {
151 offset = nextoffset;
152 tag = fdt_next_tag(fdt, offset, &nextoffset);
153
154 switch (tag) {
155 case FDT_PROP:
156 case FDT_NOP:
157 break;
158
159 case FDT_BEGIN_NODE:
160 if (depth)
161 (*depth)++;
162 break;
163
164 case FDT_END_NODE:
165 if (depth)
166 (*depth)--;
167 break;
168
169 case FDT_END:
170 return -FDT_ERR_NOTFOUND;
171
172 default:
173 return -FDT_ERR_BADSTRUCTURE;
174 }
175 } while (tag != FDT_BEGIN_NODE);
176
177 return offset;
178}
179
132const char *_fdt_find_string(const char *strtab, int tabsize, const char *s) 180const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
133{ 181{
134 int len = strlen(s) + 1; 182 int len = strlen(s) + 1;
@@ -136,17 +184,14 @@ const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
136 const char *p; 184 const char *p;
137 185
138 for (p = strtab; p <= last; p++) 186 for (p = strtab; p <= last; p++)
139 if (memeq(p, s, len)) 187 if (memcmp(p, s, len) == 0)
140 return p; 188 return p;
141 return NULL; 189 return NULL;
142} 190}
143 191
144int fdt_move(const void *fdt, void *buf, int bufsize) 192int fdt_move(const void *fdt, void *buf, int bufsize)
145{ 193{
146 int err = fdt_check_header(fdt); 194 FDT_CHECK_HEADER(fdt);
147
148 if (err)
149 return err;
150 195
151 if (fdt_totalsize(fdt) > bufsize) 196 if (fdt_totalsize(fdt) > bufsize)
152 return -FDT_ERR_NOSPACE; 197 return -FDT_ERR_NOSPACE;
diff --git a/arch/powerpc/boot/libfdt/fdt_ro.c b/arch/powerpc/boot/libfdt/fdt_ro.c
index 12a37d59f96e..129b532bcc1a 100644
--- a/arch/powerpc/boot/libfdt/fdt_ro.c
+++ b/arch/powerpc/boot/libfdt/fdt_ro.c
@@ -55,17 +55,10 @@
55 55
56#include "libfdt_internal.h" 56#include "libfdt_internal.h"
57 57
58#define CHECK_HEADER(fdt) \ 58static int _fdt_nodename_eq(const void *fdt, int offset,
59 { \ 59 const char *s, int len)
60 int err; \
61 if ((err = fdt_check_header(fdt)) != 0) \
62 return err; \
63 }
64
65static int nodename_eq(const void *fdt, int offset,
66 const char *s, int len)
67{ 60{
68 const char *p = fdt_offset_ptr(fdt, offset, len+1); 61 const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);
69 62
70 if (! p) 63 if (! p)
71 /* short match */ 64 /* short match */
@@ -84,12 +77,12 @@ static int nodename_eq(const void *fdt, int offset,
84 77
85const char *fdt_string(const void *fdt, int stroffset) 78const char *fdt_string(const void *fdt, int stroffset)
86{ 79{
87 return (char *)fdt + fdt_off_dt_strings(fdt) + stroffset; 80 return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
88} 81}
89 82
90int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) 83int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
91{ 84{
92 CHECK_HEADER(fdt); 85 FDT_CHECK_HEADER(fdt);
93 *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address); 86 *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
94 *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size); 87 *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
95 return 0; 88 return 0;
@@ -104,50 +97,24 @@ int fdt_num_mem_rsv(const void *fdt)
104 return i; 97 return i;
105} 98}
106 99
107int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, 100int fdt_subnode_offset_namelen(const void *fdt, int offset,
108 const char *name, int namelen) 101 const char *name, int namelen)
109{ 102{
110 int level = 0; 103 int depth;
111 uint32_t tag;
112 int offset, nextoffset;
113
114 CHECK_HEADER(fdt);
115
116 tag = fdt_next_tag(fdt, parentoffset, &nextoffset);
117 if (tag != FDT_BEGIN_NODE)
118 return -FDT_ERR_BADOFFSET;
119
120 do {
121 offset = nextoffset;
122 tag = fdt_next_tag(fdt, offset, &nextoffset);
123
124 switch (tag) {
125 case FDT_END:
126 return -FDT_ERR_TRUNCATED;
127
128 case FDT_BEGIN_NODE:
129 level++;
130 if (level != 1)
131 continue;
132 if (nodename_eq(fdt, offset+FDT_TAGSIZE, name, namelen))
133 /* Found it! */
134 return offset;
135 break;
136
137 case FDT_END_NODE:
138 level--;
139 break;
140 104
141 case FDT_PROP: 105 FDT_CHECK_HEADER(fdt);
142 case FDT_NOP:
143 break;
144 106
145 default: 107 for (depth = 0;
146 return -FDT_ERR_BADSTRUCTURE; 108 offset >= 0;
147 } 109 offset = fdt_next_node(fdt, offset, &depth)) {
148 } while (level >= 0); 110 if (depth < 0)
111 return -FDT_ERR_NOTFOUND;
112 else if ((depth == 1)
113 && _fdt_nodename_eq(fdt, offset, name, namelen))
114 return offset;
115 }
149 116
150 return -FDT_ERR_NOTFOUND; 117 return offset; /* error */
151} 118}
152 119
153int fdt_subnode_offset(const void *fdt, int parentoffset, 120int fdt_subnode_offset(const void *fdt, int parentoffset,
@@ -162,7 +129,7 @@ int fdt_path_offset(const void *fdt, const char *path)
162 const char *p = path; 129 const char *p = path;
163 int offset = 0; 130 int offset = 0;
164 131
165 CHECK_HEADER(fdt); 132 FDT_CHECK_HEADER(fdt);
166 133
167 if (*path != '/') 134 if (*path != '/')
168 return -FDT_ERR_BADPATH; 135 return -FDT_ERR_BADPATH;
@@ -190,16 +157,12 @@ int fdt_path_offset(const void *fdt, const char *path)
190 157
191const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) 158const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
192{ 159{
193 const struct fdt_node_header *nh; 160 const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset);
194 int err; 161 int err;
195 162
196 if ((err = fdt_check_header(fdt)) != 0) 163 if (((err = fdt_check_header(fdt)) != 0)
197 goto fail; 164 || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
198 165 goto fail;
199 err = -FDT_ERR_BADOFFSET;
200 nh = fdt_offset_ptr(fdt, nodeoffset, sizeof(*nh));
201 if (!nh || (fdt32_to_cpu(nh->tag) != FDT_BEGIN_NODE))
202 goto fail;
203 166
204 if (len) 167 if (len)
205 *len = strlen(nh->name); 168 *len = strlen(nh->name);
@@ -222,17 +185,11 @@ const struct fdt_property *fdt_get_property(const void *fdt,
222 int offset, nextoffset; 185 int offset, nextoffset;
223 int err; 186 int err;
224 187
225 if ((err = fdt_check_header(fdt)) != 0) 188 if (((err = fdt_check_header(fdt)) != 0)
226 goto fail; 189 || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))
227 190 goto fail;
228 err = -FDT_ERR_BADOFFSET;
229 if (nodeoffset % FDT_TAGSIZE)
230 goto fail;
231
232 tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
233 if (tag != FDT_BEGIN_NODE)
234 goto fail;
235 191
192 nextoffset = err;
236 do { 193 do {
237 offset = nextoffset; 194 offset = nextoffset;
238 195
@@ -253,7 +210,7 @@ const struct fdt_property *fdt_get_property(const void *fdt,
253 if (! prop) 210 if (! prop)
254 goto fail; 211 goto fail;
255 namestroff = fdt32_to_cpu(prop->nameoff); 212 namestroff = fdt32_to_cpu(prop->nameoff);
256 if (streq(fdt_string(fdt, namestroff), name)) { 213 if (strcmp(fdt_string(fdt, namestroff), name) == 0) {
257 /* Found it! */ 214 /* Found it! */
258 int len = fdt32_to_cpu(prop->len); 215 int len = fdt32_to_cpu(prop->len);
259 prop = fdt_offset_ptr(fdt, offset, 216 prop = fdt_offset_ptr(fdt, offset,
@@ -307,115 +264,91 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
307 264
308int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) 265int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
309{ 266{
310 uint32_t tag; 267 int pdepth = 0, p = 0;
311 int p = 0, overflow = 0; 268 int offset, depth, namelen;
312 int offset, nextoffset, namelen;
313 const char *name; 269 const char *name;
314 270
315 CHECK_HEADER(fdt); 271 FDT_CHECK_HEADER(fdt);
316
317 tag = fdt_next_tag(fdt, 0, &nextoffset);
318 if (tag != FDT_BEGIN_NODE)
319 return -FDT_ERR_BADSTRUCTURE;
320 272
321 if (buflen < 2) 273 if (buflen < 2)
322 return -FDT_ERR_NOSPACE; 274 return -FDT_ERR_NOSPACE;
323 buf[0] = '/';
324 p = 1;
325 275
326 while (nextoffset <= nodeoffset) { 276 for (offset = 0, depth = 0;
327 offset = nextoffset; 277 (offset >= 0) && (offset <= nodeoffset);
328 tag = fdt_next_tag(fdt, offset, &nextoffset); 278 offset = fdt_next_node(fdt, offset, &depth)) {
329 switch (tag) { 279 if (pdepth < depth)
330 case FDT_END: 280 continue; /* overflowed buffer */
331 return -FDT_ERR_BADOFFSET;
332 281
333 case FDT_BEGIN_NODE: 282 while (pdepth > depth) {
334 name = fdt_get_name(fdt, offset, &namelen); 283 do {
335 if (!name) 284 p--;
336 return namelen; 285 } while (buf[p-1] != '/');
337 if (overflow || ((p + namelen + 1) > buflen)) { 286 pdepth--;
338 overflow++; 287 }
339 break; 288
340 } 289 name = fdt_get_name(fdt, offset, &namelen);
290 if (!name)
291 return namelen;
292 if ((p + namelen + 1) <= buflen) {
341 memcpy(buf + p, name, namelen); 293 memcpy(buf + p, name, namelen);
342 p += namelen; 294 p += namelen;
343 buf[p++] = '/'; 295 buf[p++] = '/';
344 break; 296 pdepth++;
345 297 }
346 case FDT_END_NODE:
347 if (overflow) {
348 overflow--;
349 break;
350 }
351 do {
352 p--;
353 } while (buf[p-1] != '/');
354 break;
355 298
356 case FDT_PROP: 299 if (offset == nodeoffset) {
357 case FDT_NOP: 300 if (pdepth < (depth + 1))
358 break; 301 return -FDT_ERR_NOSPACE;
359 302
360 default: 303 if (p > 1) /* special case so that root path is "/", not "" */
361 return -FDT_ERR_BADSTRUCTURE; 304 p--;
305 buf[p] = '\0';
306 return p;
362 } 307 }
363 } 308 }
364 309
365 if (overflow) 310 if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
366 return -FDT_ERR_NOSPACE; 311 return -FDT_ERR_BADOFFSET;
312 else if (offset == -FDT_ERR_BADOFFSET)
313 return -FDT_ERR_BADSTRUCTURE;
367 314
368 if (p > 1) /* special case so that root path is "/", not "" */ 315 return offset; /* error from fdt_next_node() */
369 p--;
370 buf[p] = '\0';
371 return p;
372} 316}
373 317
374int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, 318int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
375 int supernodedepth, int *nodedepth) 319 int supernodedepth, int *nodedepth)
376{ 320{
377 int level = -1; 321 int offset, depth;
378 uint32_t tag;
379 int offset, nextoffset = 0;
380 int supernodeoffset = -FDT_ERR_INTERNAL; 322 int supernodeoffset = -FDT_ERR_INTERNAL;
381 323
382 CHECK_HEADER(fdt); 324 FDT_CHECK_HEADER(fdt);
383 325
384 if (supernodedepth < 0) 326 if (supernodedepth < 0)
385 return -FDT_ERR_NOTFOUND; 327 return -FDT_ERR_NOTFOUND;
386 328
387 do { 329 for (offset = 0, depth = 0;
388 offset = nextoffset; 330 (offset >= 0) && (offset <= nodeoffset);
389 tag = fdt_next_tag(fdt, offset, &nextoffset); 331 offset = fdt_next_node(fdt, offset, &depth)) {
390 switch (tag) { 332 if (depth == supernodedepth)
391 case FDT_END: 333 supernodeoffset = offset;
392 return -FDT_ERR_BADOFFSET;
393
394 case FDT_BEGIN_NODE:
395 level++;
396 if (level == supernodedepth)
397 supernodeoffset = offset;
398 break;
399
400 case FDT_END_NODE:
401 level--;
402 break;
403 334
404 case FDT_PROP: 335 if (offset == nodeoffset) {
405 case FDT_NOP: 336 if (nodedepth)
406 break; 337 *nodedepth = depth;
407 338
408 default: 339 if (supernodedepth > depth)
409 return -FDT_ERR_BADSTRUCTURE; 340 return -FDT_ERR_NOTFOUND;
341 else
342 return supernodeoffset;
410 } 343 }
411 } while (offset < nodeoffset); 344 }
412 345
413 if (nodedepth) 346 if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
414 *nodedepth = level; 347 return -FDT_ERR_BADOFFSET;
348 else if (offset == -FDT_ERR_BADOFFSET)
349 return -FDT_ERR_BADSTRUCTURE;
415 350
416 if (supernodedepth > level) 351 return offset; /* error from fdt_next_node() */
417 return -FDT_ERR_NOTFOUND;
418 return supernodeoffset;
419} 352}
420 353
421int fdt_node_depth(const void *fdt, int nodeoffset) 354int fdt_node_depth(const void *fdt, int nodeoffset)
@@ -443,51 +376,27 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
443 const char *propname, 376 const char *propname,
444 const void *propval, int proplen) 377 const void *propval, int proplen)
445{ 378{
446 uint32_t tag; 379 int offset;
447 int offset, nextoffset;
448 const void *val; 380 const void *val;
449 int len; 381 int len;
450 382
451 CHECK_HEADER(fdt); 383 FDT_CHECK_HEADER(fdt);
452
453 if (startoffset >= 0) {
454 tag = fdt_next_tag(fdt, startoffset, &nextoffset);
455 if (tag != FDT_BEGIN_NODE)
456 return -FDT_ERR_BADOFFSET;
457 } else {
458 nextoffset = 0;
459 }
460 384
461 /* FIXME: The algorithm here is pretty horrible: we scan each 385 /* FIXME: The algorithm here is pretty horrible: we scan each
462 * property of a node in fdt_getprop(), then if that didn't 386 * property of a node in fdt_getprop(), then if that didn't
463 * find what we want, we scan over them again making our way 387 * find what we want, we scan over them again making our way
464 * to the next node. Still it's the easiest to implement 388 * to the next node. Still it's the easiest to implement
465 * approach; performance can come later. */ 389 * approach; performance can come later. */
466 do { 390 for (offset = fdt_next_node(fdt, startoffset, NULL);
467 offset = nextoffset; 391 offset >= 0;
468 tag = fdt_next_tag(fdt, offset, &nextoffset); 392 offset = fdt_next_node(fdt, offset, NULL)) {
469 393 val = fdt_getprop(fdt, offset, propname, &len);
470 switch (tag) { 394 if (val && (len == proplen)
471 case FDT_BEGIN_NODE: 395 && (memcmp(val, propval, len) == 0))
472 val = fdt_getprop(fdt, offset, propname, &len); 396 return offset;
473 if (val 397 }
474 && (len == proplen)
475 && (memcmp(val, propval, len) == 0))
476 return offset;
477 break;
478
479 case FDT_PROP:
480 case FDT_END:
481 case FDT_END_NODE:
482 case FDT_NOP:
483 break;
484
485 default:
486 return -FDT_ERR_BADSTRUCTURE;
487 }
488 } while (tag != FDT_END);
489 398
490 return -FDT_ERR_NOTFOUND; 399 return offset; /* error from fdt_next_node() */
491} 400}
492 401
493int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) 402int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
@@ -499,10 +408,10 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
499 &phandle, sizeof(phandle)); 408 &phandle, sizeof(phandle));
500} 409}
501 410
502int _stringlist_contains(const void *strlist, int listlen, const char *str) 411int _stringlist_contains(const char *strlist, int listlen, const char *str)
503{ 412{
504 int len = strlen(str); 413 int len = strlen(str);
505 const void *p; 414 const char *p;
506 415
507 while (listlen >= len) { 416 while (listlen >= len) {
508 if (memcmp(str, strlist, len+1) == 0) 417 if (memcmp(str, strlist, len+1) == 0)
@@ -534,50 +443,24 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset,
534int fdt_node_offset_by_compatible(const void *fdt, int startoffset, 443int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
535 const char *compatible) 444 const char *compatible)
536{ 445{
537 uint32_t tag; 446 int offset, err;
538 int offset, nextoffset;
539 int err;
540
541 CHECK_HEADER(fdt);
542 447
543 if (startoffset >= 0) { 448 FDT_CHECK_HEADER(fdt);
544 tag = fdt_next_tag(fdt, startoffset, &nextoffset);
545 if (tag != FDT_BEGIN_NODE)
546 return -FDT_ERR_BADOFFSET;
547 } else {
548 nextoffset = 0;
549 }
550 449
551 /* FIXME: The algorithm here is pretty horrible: we scan each 450 /* FIXME: The algorithm here is pretty horrible: we scan each
552 * property of a node in fdt_node_check_compatible(), then if 451 * property of a node in fdt_node_check_compatible(), then if
553 * that didn't find what we want, we scan over them again 452 * that didn't find what we want, we scan over them again
554 * making our way to the next node. Still it's the easiest to 453 * making our way to the next node. Still it's the easiest to
555 * implement approach; performance can come later. */ 454 * implement approach; performance can come later. */
556 do { 455 for (offset = fdt_next_node(fdt, startoffset, NULL);
557 offset = nextoffset; 456 offset >= 0;
558 tag = fdt_next_tag(fdt, offset, &nextoffset); 457 offset = fdt_next_node(fdt, offset, NULL)) {
559 458 err = fdt_node_check_compatible(fdt, offset, compatible);
560 switch (tag) { 459 if ((err < 0) && (err != -FDT_ERR_NOTFOUND))
561 case FDT_BEGIN_NODE: 460 return err;
562 err = fdt_node_check_compatible(fdt, offset, 461 else if (err == 0)
563 compatible); 462 return offset;
564 if ((err < 0) 463 }
565 && (err != -FDT_ERR_NOTFOUND))
566 return err;
567 else if (err == 0)
568 return offset;
569 break;
570
571 case FDT_PROP:
572 case FDT_END:
573 case FDT_END_NODE:
574 case FDT_NOP:
575 break;
576
577 default:
578 return -FDT_ERR_BADSTRUCTURE;
579 }
580 } while (tag != FDT_END);
581 464
582 return -FDT_ERR_NOTFOUND; 465 return offset; /* error from fdt_next_node() */
583} 466}
diff --git a/arch/powerpc/boot/libfdt/fdt_rw.c b/arch/powerpc/boot/libfdt/fdt_rw.c
index 6673f8ec962a..8e7ec4cb7bcd 100644
--- a/arch/powerpc/boot/libfdt/fdt_rw.c
+++ b/arch/powerpc/boot/libfdt/fdt_rw.c
@@ -55,10 +55,10 @@
55 55
56#include "libfdt_internal.h" 56#include "libfdt_internal.h"
57 57
58static int _blocks_misordered(const void *fdt, 58static int _fdt_blocks_misordered(const void *fdt,
59 int mem_rsv_size, int struct_size) 59 int mem_rsv_size, int struct_size)
60{ 60{
61 return (fdt_off_mem_rsvmap(fdt) < ALIGN(sizeof(struct fdt_header), 8)) 61 return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8))
62 || (fdt_off_dt_struct(fdt) < 62 || (fdt_off_dt_struct(fdt) <
63 (fdt_off_mem_rsvmap(fdt) + mem_rsv_size)) 63 (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
64 || (fdt_off_dt_strings(fdt) < 64 || (fdt_off_dt_strings(fdt) <
@@ -67,16 +67,14 @@ static int _blocks_misordered(const void *fdt,
67 (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); 67 (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
68} 68}
69 69
70static int rw_check_header(void *fdt) 70static int _fdt_rw_check_header(void *fdt)
71{ 71{
72 int err; 72 FDT_CHECK_HEADER(fdt);
73 73
74 if ((err = fdt_check_header(fdt)))
75 return err;
76 if (fdt_version(fdt) < 17) 74 if (fdt_version(fdt) < 17)
77 return -FDT_ERR_BADVERSION; 75 return -FDT_ERR_BADVERSION;
78 if (_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry), 76 if (_fdt_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
79 fdt_size_dt_struct(fdt))) 77 fdt_size_dt_struct(fdt)))
80 return -FDT_ERR_BADLAYOUT; 78 return -FDT_ERR_BADLAYOUT;
81 if (fdt_version(fdt) > 17) 79 if (fdt_version(fdt) > 17)
82 fdt_set_version(fdt, 17); 80 fdt_set_version(fdt, 17);
@@ -84,36 +82,37 @@ static int rw_check_header(void *fdt)
84 return 0; 82 return 0;
85} 83}
86 84
87#define RW_CHECK_HEADER(fdt) \ 85#define FDT_RW_CHECK_HEADER(fdt) \
88 { \ 86 { \
89 int err; \ 87 int err; \
90 if ((err = rw_check_header(fdt)) != 0) \ 88 if ((err = _fdt_rw_check_header(fdt)) != 0) \
91 return err; \ 89 return err; \
92 } 90 }
93 91
94static inline int _blob_data_size(void *fdt) 92static inline int _fdt_data_size(void *fdt)
95{ 93{
96 return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); 94 return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
97} 95}
98 96
99static int _blob_splice(void *fdt, void *p, int oldlen, int newlen) 97static int _fdt_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
100{ 98{
101 void *end = fdt + _blob_data_size(fdt); 99 char *p = splicepoint;
100 char *end = (char *)fdt + _fdt_data_size(fdt);
102 101
103 if (((p + oldlen) < p) || ((p + oldlen) > end)) 102 if (((p + oldlen) < p) || ((p + oldlen) > end))
104 return -FDT_ERR_BADOFFSET; 103 return -FDT_ERR_BADOFFSET;
105 if ((end - oldlen + newlen) > (fdt + fdt_totalsize(fdt))) 104 if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
106 return -FDT_ERR_NOSPACE; 105 return -FDT_ERR_NOSPACE;
107 memmove(p + newlen, p + oldlen, end - p - oldlen); 106 memmove(p + newlen, p + oldlen, end - p - oldlen);
108 return 0; 107 return 0;
109} 108}
110 109
111static int _blob_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p, 110static int _fdt_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
112 int oldn, int newn) 111 int oldn, int newn)
113{ 112{
114 int delta = (newn - oldn) * sizeof(*p); 113 int delta = (newn - oldn) * sizeof(*p);
115 int err; 114 int err;
116 err = _blob_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p)); 115 err = _fdt_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
117 if (err) 116 if (err)
118 return err; 117 return err;
119 fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta); 118 fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
@@ -121,13 +120,13 @@ static int _blob_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
121 return 0; 120 return 0;
122} 121}
123 122
124static int _blob_splice_struct(void *fdt, void *p, 123static int _fdt_splice_struct(void *fdt, void *p,
125 int oldlen, int newlen) 124 int oldlen, int newlen)
126{ 125{
127 int delta = newlen - oldlen; 126 int delta = newlen - oldlen;
128 int err; 127 int err;
129 128
130 if ((err = _blob_splice(fdt, p, oldlen, newlen))) 129 if ((err = _fdt_splice(fdt, p, oldlen, newlen)))
131 return err; 130 return err;
132 131
133 fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta); 132 fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
@@ -135,19 +134,20 @@ static int _blob_splice_struct(void *fdt, void *p,
135 return 0; 134 return 0;
136} 135}
137 136
138static int _blob_splice_string(void *fdt, int newlen) 137static int _fdt_splice_string(void *fdt, int newlen)
139{ 138{
140 void *p = fdt + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); 139 void *p = (char *)fdt
140 + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
141 int err; 141 int err;
142 142
143 if ((err = _blob_splice(fdt, p, 0, newlen))) 143 if ((err = _fdt_splice(fdt, p, 0, newlen)))
144 return err; 144 return err;
145 145
146 fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen); 146 fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
147 return 0; 147 return 0;
148} 148}
149 149
150static int _find_add_string(void *fdt, const char *s) 150static int _fdt_find_add_string(void *fdt, const char *s)
151{ 151{
152 char *strtab = (char *)fdt + fdt_off_dt_strings(fdt); 152 char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
153 const char *p; 153 const char *p;
@@ -161,7 +161,7 @@ static int _find_add_string(void *fdt, const char *s)
161 return (p - strtab); 161 return (p - strtab);
162 162
163 new = strtab + fdt_size_dt_strings(fdt); 163 new = strtab + fdt_size_dt_strings(fdt);
164 err = _blob_splice_string(fdt, len); 164 err = _fdt_splice_string(fdt, len);
165 if (err) 165 if (err)
166 return err; 166 return err;
167 167
@@ -174,11 +174,10 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
174 struct fdt_reserve_entry *re; 174 struct fdt_reserve_entry *re;
175 int err; 175 int err;
176 176
177 if ((err = rw_check_header(fdt))) 177 FDT_RW_CHECK_HEADER(fdt);
178 return err;
179 178
180 re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt)); 179 re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
181 err = _blob_splice_mem_rsv(fdt, re, 0, 1); 180 err = _fdt_splice_mem_rsv(fdt, re, 0, 1);
182 if (err) 181 if (err)
183 return err; 182 return err;
184 183
@@ -192,19 +191,19 @@ int fdt_del_mem_rsv(void *fdt, int n)
192 struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n); 191 struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
193 int err; 192 int err;
194 193
195 if ((err = rw_check_header(fdt))) 194 FDT_RW_CHECK_HEADER(fdt);
196 return err; 195
197 if (n >= fdt_num_mem_rsv(fdt)) 196 if (n >= fdt_num_mem_rsv(fdt))
198 return -FDT_ERR_NOTFOUND; 197 return -FDT_ERR_NOTFOUND;
199 198
200 err = _blob_splice_mem_rsv(fdt, re, 1, 0); 199 err = _fdt_splice_mem_rsv(fdt, re, 1, 0);
201 if (err) 200 if (err)
202 return err; 201 return err;
203 return 0; 202 return 0;
204} 203}
205 204
206static int _resize_property(void *fdt, int nodeoffset, const char *name, int len, 205static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name,
207 struct fdt_property **prop) 206 int len, struct fdt_property **prop)
208{ 207{
209 int oldlen; 208 int oldlen;
210 int err; 209 int err;
@@ -213,36 +212,33 @@ static int _resize_property(void *fdt, int nodeoffset, const char *name, int len
213 if (! (*prop)) 212 if (! (*prop))
214 return oldlen; 213 return oldlen;
215 214
216 if ((err = _blob_splice_struct(fdt, (*prop)->data, 215 if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
217 ALIGN(oldlen, FDT_TAGSIZE), 216 FDT_TAGALIGN(len))))
218 ALIGN(len, FDT_TAGSIZE))))
219 return err; 217 return err;
220 218
221 (*prop)->len = cpu_to_fdt32(len); 219 (*prop)->len = cpu_to_fdt32(len);
222 return 0; 220 return 0;
223} 221}
224 222
225static int _add_property(void *fdt, int nodeoffset, const char *name, int len, 223static int _fdt_add_property(void *fdt, int nodeoffset, const char *name,
226 struct fdt_property **prop) 224 int len, struct fdt_property **prop)
227{ 225{
228 uint32_t tag;
229 int proplen; 226 int proplen;
230 int nextoffset; 227 int nextoffset;
231 int namestroff; 228 int namestroff;
232 int err; 229 int err;
233 230
234 tag = fdt_next_tag(fdt, nodeoffset, &nextoffset); 231 if ((nextoffset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)
235 if (tag != FDT_BEGIN_NODE) 232 return nextoffset;
236 return -FDT_ERR_BADOFFSET;
237 233
238 namestroff = _find_add_string(fdt, name); 234 namestroff = _fdt_find_add_string(fdt, name);
239 if (namestroff < 0) 235 if (namestroff < 0)
240 return namestroff; 236 return namestroff;
241 237
242 *prop = _fdt_offset_ptr_w(fdt, nextoffset); 238 *prop = _fdt_offset_ptr_w(fdt, nextoffset);
243 proplen = sizeof(**prop) + ALIGN(len, FDT_TAGSIZE); 239 proplen = sizeof(**prop) + FDT_TAGALIGN(len);
244 240
245 err = _blob_splice_struct(fdt, *prop, 0, proplen); 241 err = _fdt_splice_struct(fdt, *prop, 0, proplen);
246 if (err) 242 if (err)
247 return err; 243 return err;
248 244
@@ -252,18 +248,40 @@ static int _add_property(void *fdt, int nodeoffset, const char *name, int len,
252 return 0; 248 return 0;
253} 249}
254 250
251int fdt_set_name(void *fdt, int nodeoffset, const char *name)
252{
253 char *namep;
254 int oldlen, newlen;
255 int err;
256
257 FDT_RW_CHECK_HEADER(fdt);
258
259 namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);
260 if (!namep)
261 return oldlen;
262
263 newlen = strlen(name);
264
265 err = _fdt_splice_struct(fdt, namep, FDT_TAGALIGN(oldlen+1),
266 FDT_TAGALIGN(newlen+1));
267 if (err)
268 return err;
269
270 memcpy(namep, name, newlen+1);
271 return 0;
272}
273
255int fdt_setprop(void *fdt, int nodeoffset, const char *name, 274int fdt_setprop(void *fdt, int nodeoffset, const char *name,
256 const void *val, int len) 275 const void *val, int len)
257{ 276{
258 struct fdt_property *prop; 277 struct fdt_property *prop;
259 int err; 278 int err;
260 279
261 if ((err = rw_check_header(fdt))) 280 FDT_RW_CHECK_HEADER(fdt);
262 return err;
263 281
264 err = _resize_property(fdt, nodeoffset, name, len, &prop); 282 err = _fdt_resize_property(fdt, nodeoffset, name, len, &prop);
265 if (err == -FDT_ERR_NOTFOUND) 283 if (err == -FDT_ERR_NOTFOUND)
266 err = _add_property(fdt, nodeoffset, name, len, &prop); 284 err = _fdt_add_property(fdt, nodeoffset, name, len, &prop);
267 if (err) 285 if (err)
268 return err; 286 return err;
269 287
@@ -276,14 +294,14 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name)
276 struct fdt_property *prop; 294 struct fdt_property *prop;
277 int len, proplen; 295 int len, proplen;
278 296
279 RW_CHECK_HEADER(fdt); 297 FDT_RW_CHECK_HEADER(fdt);
280 298
281 prop = fdt_get_property_w(fdt, nodeoffset, name, &len); 299 prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
282 if (! prop) 300 if (! prop)
283 return len; 301 return len;
284 302
285 proplen = sizeof(*prop) + ALIGN(len, FDT_TAGSIZE); 303 proplen = sizeof(*prop) + FDT_TAGALIGN(len);
286 return _blob_splice_struct(fdt, prop, proplen, 0); 304 return _fdt_splice_struct(fdt, prop, proplen, 0);
287} 305}
288 306
289int fdt_add_subnode_namelen(void *fdt, int parentoffset, 307int fdt_add_subnode_namelen(void *fdt, int parentoffset,
@@ -296,7 +314,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
296 uint32_t tag; 314 uint32_t tag;
297 uint32_t *endtag; 315 uint32_t *endtag;
298 316
299 RW_CHECK_HEADER(fdt); 317 FDT_RW_CHECK_HEADER(fdt);
300 318
301 offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); 319 offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
302 if (offset >= 0) 320 if (offset >= 0)
@@ -309,19 +327,19 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
309 do { 327 do {
310 offset = nextoffset; 328 offset = nextoffset;
311 tag = fdt_next_tag(fdt, offset, &nextoffset); 329 tag = fdt_next_tag(fdt, offset, &nextoffset);
312 } while (tag == FDT_PROP); 330 } while ((tag == FDT_PROP) || (tag == FDT_NOP));
313 331
314 nh = _fdt_offset_ptr_w(fdt, offset); 332 nh = _fdt_offset_ptr_w(fdt, offset);
315 nodelen = sizeof(*nh) + ALIGN(namelen+1, FDT_TAGSIZE) + FDT_TAGSIZE; 333 nodelen = sizeof(*nh) + FDT_TAGALIGN(namelen+1) + FDT_TAGSIZE;
316 334
317 err = _blob_splice_struct(fdt, nh, 0, nodelen); 335 err = _fdt_splice_struct(fdt, nh, 0, nodelen);
318 if (err) 336 if (err)
319 return err; 337 return err;
320 338
321 nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); 339 nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
322 memset(nh->name, 0, ALIGN(namelen+1, FDT_TAGSIZE)); 340 memset(nh->name, 0, FDT_TAGALIGN(namelen+1));
323 memcpy(nh->name, name, namelen); 341 memcpy(nh->name, name, namelen);
324 endtag = (uint32_t *)((void *)nh + nodelen - FDT_TAGSIZE); 342 endtag = (uint32_t *)((char *)nh + nodelen - FDT_TAGSIZE);
325 *endtag = cpu_to_fdt32(FDT_END_NODE); 343 *endtag = cpu_to_fdt32(FDT_END_NODE);
326 344
327 return offset; 345 return offset;
@@ -336,36 +354,36 @@ int fdt_del_node(void *fdt, int nodeoffset)
336{ 354{
337 int endoffset; 355 int endoffset;
338 356
339 RW_CHECK_HEADER(fdt); 357 FDT_RW_CHECK_HEADER(fdt);
340 358
341 endoffset = _fdt_node_end_offset(fdt, nodeoffset); 359 endoffset = _fdt_node_end_offset(fdt, nodeoffset);
342 if (endoffset < 0) 360 if (endoffset < 0)
343 return endoffset; 361 return endoffset;
344 362
345 return _blob_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset), 363 return _fdt_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
346 endoffset - nodeoffset, 0); 364 endoffset - nodeoffset, 0);
347} 365}
348 366
349static void _packblocks(const void *fdt, void *buf, 367static void _fdt_packblocks(const char *old, char *new,
350 int mem_rsv_size, int struct_size) 368 int mem_rsv_size, int struct_size)
351{ 369{
352 int mem_rsv_off, struct_off, strings_off; 370 int mem_rsv_off, struct_off, strings_off;
353 371
354 mem_rsv_off = ALIGN(sizeof(struct fdt_header), 8); 372 mem_rsv_off = FDT_ALIGN(sizeof(struct fdt_header), 8);
355 struct_off = mem_rsv_off + mem_rsv_size; 373 struct_off = mem_rsv_off + mem_rsv_size;
356 strings_off = struct_off + struct_size; 374 strings_off = struct_off + struct_size;
357 375
358 memmove(buf + mem_rsv_off, fdt + fdt_off_mem_rsvmap(fdt), mem_rsv_size); 376 memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size);
359 fdt_set_off_mem_rsvmap(buf, mem_rsv_off); 377 fdt_set_off_mem_rsvmap(new, mem_rsv_off);
360 378
361 memmove(buf + struct_off, fdt + fdt_off_dt_struct(fdt), struct_size); 379 memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size);
362 fdt_set_off_dt_struct(buf, struct_off); 380 fdt_set_off_dt_struct(new, struct_off);
363 fdt_set_size_dt_struct(buf, struct_size); 381 fdt_set_size_dt_struct(new, struct_size);
364 382
365 memmove(buf + strings_off, fdt + fdt_off_dt_strings(fdt), 383 memmove(new + strings_off, old + fdt_off_dt_strings(old),
366 fdt_size_dt_strings(fdt)); 384 fdt_size_dt_strings(old));
367 fdt_set_off_dt_strings(buf, strings_off); 385 fdt_set_off_dt_strings(new, strings_off);
368 fdt_set_size_dt_strings(buf, fdt_size_dt_strings(fdt)); 386 fdt_set_size_dt_strings(new, fdt_size_dt_strings(old));
369} 387}
370 388
371int fdt_open_into(const void *fdt, void *buf, int bufsize) 389int fdt_open_into(const void *fdt, void *buf, int bufsize)
@@ -373,11 +391,11 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
373 int err; 391 int err;
374 int mem_rsv_size, struct_size; 392 int mem_rsv_size, struct_size;
375 int newsize; 393 int newsize;
376 void *tmp; 394 const char *fdtstart = fdt;
395 const char *fdtend = fdtstart + fdt_totalsize(fdt);
396 char *tmp;
377 397
378 err = fdt_check_header(fdt); 398 FDT_CHECK_HEADER(fdt);
379 if (err)
380 return err;
381 399
382 mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) 400 mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
383 * sizeof(struct fdt_reserve_entry); 401 * sizeof(struct fdt_reserve_entry);
@@ -390,7 +408,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
390 ; 408 ;
391 } 409 }
392 410
393 if (!_blocks_misordered(fdt, mem_rsv_size, struct_size)) { 411 if (!_fdt_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
394 /* no further work necessary */ 412 /* no further work necessary */
395 err = fdt_move(fdt, buf, bufsize); 413 err = fdt_move(fdt, buf, bufsize);
396 if (err) 414 if (err)
@@ -402,22 +420,23 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
402 } 420 }
403 421
404 /* Need to reorder */ 422 /* Need to reorder */
405 newsize = ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size 423 newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
406 + struct_size + fdt_size_dt_strings(fdt); 424 + struct_size + fdt_size_dt_strings(fdt);
407 425
408 if (bufsize < newsize) 426 if (bufsize < newsize)
409 return -FDT_ERR_NOSPACE; 427 return -FDT_ERR_NOSPACE;
410 428
411 if (((buf + newsize) <= fdt) 429 /* First attempt to build converted tree at beginning of buffer */
412 || (buf >= (fdt + fdt_totalsize(fdt)))) { 430 tmp = buf;
413 tmp = buf; 431 /* But if that overlaps with the old tree... */
414 } else { 432 if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
415 tmp = (void *)fdt + fdt_totalsize(fdt); 433 /* Try right after the old tree instead */
416 if ((tmp + newsize) > (buf + bufsize)) 434 tmp = (char *)(uintptr_t)fdtend;
435 if ((tmp + newsize) > ((char *)buf + bufsize))
417 return -FDT_ERR_NOSPACE; 436 return -FDT_ERR_NOSPACE;
418 } 437 }
419 438
420 _packblocks(fdt, tmp, mem_rsv_size, struct_size); 439 _fdt_packblocks(fdt, tmp, mem_rsv_size, struct_size);
421 memmove(buf, tmp, newsize); 440 memmove(buf, tmp, newsize);
422 441
423 fdt_set_magic(buf, FDT_MAGIC); 442 fdt_set_magic(buf, FDT_MAGIC);
@@ -432,16 +451,13 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
432int fdt_pack(void *fdt) 451int fdt_pack(void *fdt)
433{ 452{
434 int mem_rsv_size; 453 int mem_rsv_size;
435 int err;
436 454
437 err = rw_check_header(fdt); 455 FDT_RW_CHECK_HEADER(fdt);
438 if (err)
439 return err;
440 456
441 mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) 457 mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
442 * sizeof(struct fdt_reserve_entry); 458 * sizeof(struct fdt_reserve_entry);
443 _packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); 459 _fdt_packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
444 fdt_set_totalsize(fdt, _blob_data_size(fdt)); 460 fdt_set_totalsize(fdt, _fdt_data_size(fdt));
445 461
446 return 0; 462 return 0;
447} 463}
diff --git a/arch/powerpc/boot/libfdt/fdt_strerror.c b/arch/powerpc/boot/libfdt/fdt_strerror.c
index f9d32ef5360a..e6c3ceee8c58 100644
--- a/arch/powerpc/boot/libfdt/fdt_strerror.c
+++ b/arch/powerpc/boot/libfdt/fdt_strerror.c
@@ -55,29 +55,29 @@
55 55
56#include "libfdt_internal.h" 56#include "libfdt_internal.h"
57 57
58struct errtabent { 58struct fdt_errtabent {
59 const char *str; 59 const char *str;
60}; 60};
61 61
62#define ERRTABENT(val) \ 62#define FDT_ERRTABENT(val) \
63 [(val)] = { .str = #val, } 63 [(val)] = { .str = #val, }
64 64
65static struct errtabent errtable[] = { 65static struct fdt_errtabent fdt_errtable[] = {
66 ERRTABENT(FDT_ERR_NOTFOUND), 66 FDT_ERRTABENT(FDT_ERR_NOTFOUND),
67 ERRTABENT(FDT_ERR_EXISTS), 67 FDT_ERRTABENT(FDT_ERR_EXISTS),
68 ERRTABENT(FDT_ERR_NOSPACE), 68 FDT_ERRTABENT(FDT_ERR_NOSPACE),
69 69
70 ERRTABENT(FDT_ERR_BADOFFSET), 70 FDT_ERRTABENT(FDT_ERR_BADOFFSET),
71 ERRTABENT(FDT_ERR_BADPATH), 71 FDT_ERRTABENT(FDT_ERR_BADPATH),
72 ERRTABENT(FDT_ERR_BADSTATE), 72 FDT_ERRTABENT(FDT_ERR_BADSTATE),
73 73
74 ERRTABENT(FDT_ERR_TRUNCATED), 74 FDT_ERRTABENT(FDT_ERR_TRUNCATED),
75 ERRTABENT(FDT_ERR_BADMAGIC), 75 FDT_ERRTABENT(FDT_ERR_BADMAGIC),
76 ERRTABENT(FDT_ERR_BADVERSION), 76 FDT_ERRTABENT(FDT_ERR_BADVERSION),
77 ERRTABENT(FDT_ERR_BADSTRUCTURE), 77 FDT_ERRTABENT(FDT_ERR_BADSTRUCTURE),
78 ERRTABENT(FDT_ERR_BADLAYOUT), 78 FDT_ERRTABENT(FDT_ERR_BADLAYOUT),
79}; 79};
80#define ERRTABSIZE (sizeof(errtable) / sizeof(errtable[0])) 80#define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0]))
81 81
82const char *fdt_strerror(int errval) 82const char *fdt_strerror(int errval)
83{ 83{
@@ -85,8 +85,8 @@ const char *fdt_strerror(int errval)
85 return "<valid offset/length>"; 85 return "<valid offset/length>";
86 else if (errval == 0) 86 else if (errval == 0)
87 return "<no error>"; 87 return "<no error>";
88 else if (errval > -ERRTABSIZE) { 88 else if (errval > -FDT_ERRTABSIZE) {
89 const char *s = errtable[-errval].str; 89 const char *s = fdt_errtable[-errval].str;
90 90
91 if (s) 91 if (s)
92 return s; 92 return s;
diff --git a/arch/powerpc/boot/libfdt/fdt_sw.c b/arch/powerpc/boot/libfdt/fdt_sw.c
index dda2de34b2e0..698329e0ccaf 100644
--- a/arch/powerpc/boot/libfdt/fdt_sw.c
+++ b/arch/powerpc/boot/libfdt/fdt_sw.c
@@ -55,14 +55,22 @@
55 55
56#include "libfdt_internal.h" 56#include "libfdt_internal.h"
57 57
58static int check_header_sw(void *fdt) 58static int _fdt_sw_check_header(void *fdt)
59{ 59{
60 if (fdt_magic(fdt) != SW_MAGIC) 60 if (fdt_magic(fdt) != FDT_SW_MAGIC)
61 return -FDT_ERR_BADMAGIC; 61 return -FDT_ERR_BADMAGIC;
62 /* FIXME: should check more details about the header state */
62 return 0; 63 return 0;
63} 64}
64 65
65static void *grab_space(void *fdt, int len) 66#define FDT_SW_CHECK_HEADER(fdt) \
67 { \
68 int err; \
69 if ((err = _fdt_sw_check_header(fdt)) != 0) \
70 return err; \
71 }
72
73static void *_fdt_grab_space(void *fdt, int len)
66{ 74{
67 int offset = fdt_size_dt_struct(fdt); 75 int offset = fdt_size_dt_struct(fdt);
68 int spaceleft; 76 int spaceleft;
@@ -86,13 +94,13 @@ int fdt_create(void *buf, int bufsize)
86 94
87 memset(buf, 0, bufsize); 95 memset(buf, 0, bufsize);
88 96
89 fdt_set_magic(fdt, SW_MAGIC); 97 fdt_set_magic(fdt, FDT_SW_MAGIC);
90 fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION); 98 fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
91 fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION); 99 fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
92 fdt_set_totalsize(fdt, bufsize); 100 fdt_set_totalsize(fdt, bufsize);
93 101
94 fdt_set_off_mem_rsvmap(fdt, ALIGN(sizeof(struct fdt_header), 102 fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header),
95 sizeof(struct fdt_reserve_entry))); 103 sizeof(struct fdt_reserve_entry)));
96 fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt)); 104 fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
97 fdt_set_off_dt_strings(fdt, bufsize); 105 fdt_set_off_dt_strings(fdt, bufsize);
98 106
@@ -102,11 +110,10 @@ int fdt_create(void *buf, int bufsize)
102int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size) 110int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
103{ 111{
104 struct fdt_reserve_entry *re; 112 struct fdt_reserve_entry *re;
105 int err = check_header_sw(fdt);
106 int offset; 113 int offset;
107 114
108 if (err) 115 FDT_SW_CHECK_HEADER(fdt);
109 return err; 116
110 if (fdt_size_dt_struct(fdt)) 117 if (fdt_size_dt_struct(fdt))
111 return -FDT_ERR_BADSTATE; 118 return -FDT_ERR_BADSTATE;
112 119
@@ -114,7 +121,7 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
114 if ((offset + sizeof(*re)) > fdt_totalsize(fdt)) 121 if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
115 return -FDT_ERR_NOSPACE; 122 return -FDT_ERR_NOSPACE;
116 123
117 re = (struct fdt_reserve_entry *)(fdt + offset); 124 re = (struct fdt_reserve_entry *)((char *)fdt + offset);
118 re->address = cpu_to_fdt64(addr); 125 re->address = cpu_to_fdt64(addr);
119 re->size = cpu_to_fdt64(size); 126 re->size = cpu_to_fdt64(size);
120 127
@@ -131,13 +138,11 @@ int fdt_finish_reservemap(void *fdt)
131int fdt_begin_node(void *fdt, const char *name) 138int fdt_begin_node(void *fdt, const char *name)
132{ 139{
133 struct fdt_node_header *nh; 140 struct fdt_node_header *nh;
134 int err = check_header_sw(fdt);
135 int namelen = strlen(name) + 1; 141 int namelen = strlen(name) + 1;
136 142
137 if (err) 143 FDT_SW_CHECK_HEADER(fdt);
138 return err;
139 144
140 nh = grab_space(fdt, sizeof(*nh) + ALIGN(namelen, FDT_TAGSIZE)); 145 nh = _fdt_grab_space(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen));
141 if (! nh) 146 if (! nh)
142 return -FDT_ERR_NOSPACE; 147 return -FDT_ERR_NOSPACE;
143 148
@@ -149,12 +154,10 @@ int fdt_begin_node(void *fdt, const char *name)
149int fdt_end_node(void *fdt) 154int fdt_end_node(void *fdt)
150{ 155{
151 uint32_t *en; 156 uint32_t *en;
152 int err = check_header_sw(fdt);
153 157
154 if (err) 158 FDT_SW_CHECK_HEADER(fdt);
155 return err;
156 159
157 en = grab_space(fdt, FDT_TAGSIZE); 160 en = _fdt_grab_space(fdt, FDT_TAGSIZE);
158 if (! en) 161 if (! en)
159 return -FDT_ERR_NOSPACE; 162 return -FDT_ERR_NOSPACE;
160 163
@@ -162,7 +165,7 @@ int fdt_end_node(void *fdt)
162 return 0; 165 return 0;
163} 166}
164 167
165static int find_add_string(void *fdt, const char *s) 168static int _fdt_find_add_string(void *fdt, const char *s)
166{ 169{
167 char *strtab = (char *)fdt + fdt_totalsize(fdt); 170 char *strtab = (char *)fdt + fdt_totalsize(fdt);
168 const char *p; 171 const char *p;
@@ -188,17 +191,15 @@ static int find_add_string(void *fdt, const char *s)
188int fdt_property(void *fdt, const char *name, const void *val, int len) 191int fdt_property(void *fdt, const char *name, const void *val, int len)
189{ 192{
190 struct fdt_property *prop; 193 struct fdt_property *prop;
191 int err = check_header_sw(fdt);
192 int nameoff; 194 int nameoff;
193 195
194 if (err) 196 FDT_SW_CHECK_HEADER(fdt);
195 return err;
196 197
197 nameoff = find_add_string(fdt, name); 198 nameoff = _fdt_find_add_string(fdt, name);
198 if (nameoff == 0) 199 if (nameoff == 0)
199 return -FDT_ERR_NOSPACE; 200 return -FDT_ERR_NOSPACE;
200 201
201 prop = grab_space(fdt, sizeof(*prop) + ALIGN(len, FDT_TAGSIZE)); 202 prop = _fdt_grab_space(fdt, sizeof(*prop) + FDT_TAGALIGN(len));
202 if (! prop) 203 if (! prop)
203 return -FDT_ERR_NOSPACE; 204 return -FDT_ERR_NOSPACE;
204 205
@@ -211,18 +212,16 @@ int fdt_property(void *fdt, const char *name, const void *val, int len)
211 212
212int fdt_finish(void *fdt) 213int fdt_finish(void *fdt)
213{ 214{
214 int err = check_header_sw(fdt);
215 char *p = (char *)fdt; 215 char *p = (char *)fdt;
216 uint32_t *end; 216 uint32_t *end;
217 int oldstroffset, newstroffset; 217 int oldstroffset, newstroffset;
218 uint32_t tag; 218 uint32_t tag;
219 int offset, nextoffset; 219 int offset, nextoffset;
220 220
221 if (err) 221 FDT_SW_CHECK_HEADER(fdt);
222 return err;
223 222
224 /* Add terminator */ 223 /* Add terminator */
225 end = grab_space(fdt, sizeof(*end)); 224 end = _fdt_grab_space(fdt, sizeof(*end));
226 if (! end) 225 if (! end)
227 return -FDT_ERR_NOSPACE; 226 return -FDT_ERR_NOSPACE;
228 *end = cpu_to_fdt32(FDT_END); 227 *end = cpu_to_fdt32(FDT_END);
diff --git a/arch/powerpc/boot/libfdt/fdt_wip.c b/arch/powerpc/boot/libfdt/fdt_wip.c
index 88e24b8318f4..a4652c6e787e 100644
--- a/arch/powerpc/boot/libfdt/fdt_wip.c
+++ b/arch/powerpc/boot/libfdt/fdt_wip.c
@@ -72,11 +72,11 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
72 return 0; 72 return 0;
73} 73}
74 74
75static void nop_region(void *start, int len) 75static void _fdt_nop_region(void *start, int len)
76{ 76{
77 uint32_t *p; 77 uint32_t *p;
78 78
79 for (p = start; (void *)p < (start + len); p++) 79 for (p = start; (char *)p < ((char *)start + len); p++)
80 *p = cpu_to_fdt32(FDT_NOP); 80 *p = cpu_to_fdt32(FDT_NOP);
81} 81}
82 82
@@ -89,7 +89,7 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
89 if (! prop) 89 if (! prop)
90 return len; 90 return len;
91 91
92 nop_region(prop, len + sizeof(*prop)); 92 _fdt_nop_region(prop, len + sizeof(*prop));
93 93
94 return 0; 94 return 0;
95} 95}
@@ -139,6 +139,7 @@ int fdt_nop_node(void *fdt, int nodeoffset)
139 if (endoffset < 0) 139 if (endoffset < 0)
140 return endoffset; 140 return endoffset;
141 141
142 nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0), endoffset - nodeoffset); 142 _fdt_nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0),
143 endoffset - nodeoffset);
143 return 0; 144 return 0;
144} 145}
diff --git a/arch/powerpc/boot/libfdt/libfdt.h b/arch/powerpc/boot/libfdt/libfdt.h
index 6b2fb92ea357..ce80e4fb41b2 100644
--- a/arch/powerpc/boot/libfdt/libfdt.h
+++ b/arch/powerpc/boot/libfdt/libfdt.h
@@ -125,12 +125,18 @@
125const void *fdt_offset_ptr(const void *fdt, int offset, int checklen); 125const void *fdt_offset_ptr(const void *fdt, int offset, int checklen);
126static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) 126static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
127{ 127{
128 return (void *)fdt_offset_ptr(fdt, offset, checklen); 128 return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
129} 129}
130 130
131uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); 131uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
132 132
133/**********************************************************************/ 133/**********************************************************************/
134/* Traversal functions */
135/**********************************************************************/
136
137int fdt_next_node(const void *fdt, int offset, int *depth);
138
139/**********************************************************************/
134/* General functions */ 140/* General functions */
135/**********************************************************************/ 141/**********************************************************************/
136 142
@@ -207,7 +213,7 @@ int fdt_move(const void *fdt, void *buf, int bufsize);
207/**********************************************************************/ 213/**********************************************************************/
208 214
209/** 215/**
210 * fdt_string - retreive a string from the strings block of a device tree 216 * fdt_string - retrieve a string from the strings block of a device tree
211 * @fdt: pointer to the device tree blob 217 * @fdt: pointer to the device tree blob
212 * @stroffset: offset of the string within the strings block (native endian) 218 * @stroffset: offset of the string within the strings block (native endian)
213 * 219 *
@@ -221,7 +227,7 @@ int fdt_move(const void *fdt, void *buf, int bufsize);
221const char *fdt_string(const void *fdt, int stroffset); 227const char *fdt_string(const void *fdt, int stroffset);
222 228
223/** 229/**
224 * fdt_num_mem_rsv - retreive the number of memory reserve map entries 230 * fdt_num_mem_rsv - retrieve the number of memory reserve map entries
225 * @fdt: pointer to the device tree blob 231 * @fdt: pointer to the device tree blob
226 * 232 *
227 * Returns the number of entries in the device tree blob's memory 233 * Returns the number of entries in the device tree blob's memory
@@ -234,7 +240,7 @@ const char *fdt_string(const void *fdt, int stroffset);
234int fdt_num_mem_rsv(const void *fdt); 240int fdt_num_mem_rsv(const void *fdt);
235 241
236/** 242/**
237 * fdt_get_mem_rsv - retreive one memory reserve map entry 243 * fdt_get_mem_rsv - retrieve one memory reserve map entry
238 * @fdt: pointer to the device tree blob 244 * @fdt: pointer to the device tree blob
239 * @address, @size: pointers to 64-bit variables 245 * @address, @size: pointers to 64-bit variables
240 * 246 *
@@ -314,7 +320,7 @@ int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
314int fdt_path_offset(const void *fdt, const char *path); 320int fdt_path_offset(const void *fdt, const char *path);
315 321
316/** 322/**
317 * fdt_get_name - retreive the name of a given node 323 * fdt_get_name - retrieve the name of a given node
318 * @fdt: pointer to the device tree blob 324 * @fdt: pointer to the device tree blob
319 * @nodeoffset: structure block offset of the starting node 325 * @nodeoffset: structure block offset of the starting node
320 * @lenp: pointer to an integer variable (will be overwritten) or NULL 326 * @lenp: pointer to an integer variable (will be overwritten) or NULL
@@ -346,7 +352,7 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
346 * fdt_get_property() retrieves a pointer to the fdt_property 352 * fdt_get_property() retrieves a pointer to the fdt_property
347 * structure within the device tree blob corresponding to the property 353 * structure within the device tree blob corresponding to the property
348 * named 'name' of the node at offset nodeoffset. If lenp is 354 * named 'name' of the node at offset nodeoffset. If lenp is
349 * non-NULL, the length of the property value also returned, in the 355 * non-NULL, the length of the property value is also returned, in the
350 * integer pointed to by lenp. 356 * integer pointed to by lenp.
351 * 357 *
352 * returns: 358 * returns:
@@ -369,8 +375,8 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
369 const char *name, 375 const char *name,
370 int *lenp) 376 int *lenp)
371{ 377{
372 return (struct fdt_property *)fdt_get_property(fdt, nodeoffset, 378 return (struct fdt_property *)(uintptr_t)
373 name, lenp); 379 fdt_get_property(fdt, nodeoffset, name, lenp);
374} 380}
375 381
376/** 382/**
@@ -383,7 +389,7 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
383 * fdt_getprop() retrieves a pointer to the value of the property 389 * fdt_getprop() retrieves a pointer to the value of the property
384 * named 'name' of the node at offset nodeoffset (this will be a 390 * named 'name' of the node at offset nodeoffset (this will be a
385 * pointer to within the device blob itself, not a copy of the value). 391 * pointer to within the device blob itself, not a copy of the value).
386 * If lenp is non-NULL, the length of the property value also 392 * If lenp is non-NULL, the length of the property value is also
387 * returned, in the integer pointed to by lenp. 393 * returned, in the integer pointed to by lenp.
388 * 394 *
389 * returns: 395 * returns:
@@ -405,11 +411,11 @@ const void *fdt_getprop(const void *fdt, int nodeoffset,
405static inline void *fdt_getprop_w(void *fdt, int nodeoffset, 411static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
406 const char *name, int *lenp) 412 const char *name, int *lenp)
407{ 413{
408 return (void *)fdt_getprop(fdt, nodeoffset, name, lenp); 414 return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);
409} 415}
410 416
411/** 417/**
412 * fdt_get_phandle - retreive the phandle of a given node 418 * fdt_get_phandle - retrieve the phandle of a given node
413 * @fdt: pointer to the device tree blob 419 * @fdt: pointer to the device tree blob
414 * @nodeoffset: structure block offset of the node 420 * @nodeoffset: structure block offset of the node
415 * 421 *
@@ -417,7 +423,7 @@ static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
417 * structure block offset nodeoffset. 423 * structure block offset nodeoffset.
418 * 424 *
419 * returns: 425 * returns:
420 * the phandle of the node at nodeoffset, on succes (!= 0, != -1) 426 * the phandle of the node at nodeoffset, on success (!= 0, != -1)
421 * 0, if the node has no phandle, or another error occurs 427 * 0, if the node has no phandle, or another error occurs
422 */ 428 */
423uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); 429uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
@@ -516,7 +522,7 @@ int fdt_node_depth(const void *fdt, int nodeoffset);
516 * structure from the start to nodeoffset, *twice*. 522 * structure from the start to nodeoffset, *twice*.
517 * 523 *
518 * returns: 524 * returns:
519 * stucture block offset of the parent of the node at nodeoffset 525 * structure block offset of the parent of the node at nodeoffset
520 * (>=0), on success 526 * (>=0), on success
521 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag 527 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
522 * -FDT_ERR_BADMAGIC, 528 * -FDT_ERR_BADMAGIC,
@@ -573,7 +579,7 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
573 * @fdt: pointer to the device tree blob 579 * @fdt: pointer to the device tree blob
574 * @phandle: phandle value 580 * @phandle: phandle value
575 * 581 *
576 * fdt_node_offset_by_prop_value() returns the offset of the node 582 * fdt_node_offset_by_phandle() returns the offset of the node
577 * which has the given phandle value. If there is more than one node 583 * which has the given phandle value. If there is more than one node
578 * in the tree with the given phandle (an invalid tree), results are 584 * in the tree with the given phandle (an invalid tree), results are
579 * undefined. 585 * undefined.
@@ -655,8 +661,65 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
655/* Write-in-place functions */ 661/* Write-in-place functions */
656/**********************************************************************/ 662/**********************************************************************/
657 663
664/**
665 * fdt_setprop_inplace - change a property's value, but not its size
666 * @fdt: pointer to the device tree blob
667 * @nodeoffset: offset of the node whose property to change
668 * @name: name of the property to change
669 * @val: pointer to data to replace the property value with
670 * @len: length of the property value
671 *
672 * fdt_setprop_inplace() replaces the value of a given property with
673 * the data in val, of length len. This function cannot change the
674 * size of a property, and so will only work if len is equal to the
675 * current length of the property.
676 *
677 * This function will alter only the bytes in the blob which contain
678 * the given property value, and will not alter or move any other part
679 * of the tree.
680 *
681 * returns:
682 * 0, on success
683 * -FDT_ERR_NOSPACE, if len is not equal to the property's current length
684 * -FDT_ERR_NOTFOUND, node does not have the named property
685 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
686 * -FDT_ERR_BADMAGIC,
687 * -FDT_ERR_BADVERSION,
688 * -FDT_ERR_BADSTATE,
689 * -FDT_ERR_BADSTRUCTURE,
690 * -FDT_ERR_TRUNCATED, standard meanings
691 */
658int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, 692int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
659 const void *val, int len); 693 const void *val, int len);
694
695/**
696 * fdt_setprop_inplace_cell - change the value of a single-cell property
697 * @fdt: pointer to the device tree blob
698 * @nodeoffset: offset of the node whose property to change
699 * @name: name of the property to change
700 * @val: cell (32-bit integer) value to replace the property with
701 *
702 * fdt_setprop_inplace_cell() replaces the value of a given property
703 * with the 32-bit integer cell value in val, converting val to
704 * big-endian if necessary. This function cannot change the size of a
705 * property, and so will only work if the property already exists and
706 * has length 4.
707 *
708 * This function will alter only the bytes in the blob which contain
709 * the given property value, and will not alter or move any other part
710 * of the tree.
711 *
712 * returns:
713 * 0, on success
714 * -FDT_ERR_NOSPACE, if the property's length is not equal to 4
715 * -FDT_ERR_NOTFOUND, node does not have the named property
716 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
717 * -FDT_ERR_BADMAGIC,
718 * -FDT_ERR_BADVERSION,
719 * -FDT_ERR_BADSTATE,
720 * -FDT_ERR_BADSTRUCTURE,
721 * -FDT_ERR_TRUNCATED, standard meanings
722 */
660static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset, 723static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
661 const char *name, uint32_t val) 724 const char *name, uint32_t val)
662{ 725{
@@ -664,7 +727,54 @@ static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
664 return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val)); 727 return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
665} 728}
666 729
730/**
731 * fdt_nop_property - replace a property with nop tags
732 * @fdt: pointer to the device tree blob
733 * @nodeoffset: offset of the node whose property to nop
734 * @name: name of the property to nop
735 *
736 * fdt_nop_property() will replace a given property's representation
737 * in the blob with FDT_NOP tags, effectively removing it from the
738 * tree.
739 *
740 * This function will alter only the bytes in the blob which contain
741 * the property, and will not alter or move any other part of the
742 * tree.
743 *
744 * returns:
745 * 0, on success
746 * -FDT_ERR_NOTFOUND, node does not have the named property
747 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
748 * -FDT_ERR_BADMAGIC,
749 * -FDT_ERR_BADVERSION,
750 * -FDT_ERR_BADSTATE,
751 * -FDT_ERR_BADSTRUCTURE,
752 * -FDT_ERR_TRUNCATED, standard meanings
753 */
667int fdt_nop_property(void *fdt, int nodeoffset, const char *name); 754int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
755
756/**
757 * fdt_nop_node - replace a node (subtree) with nop tags
758 * @fdt: pointer to the device tree blob
759 * @nodeoffset: offset of the node to nop
760 *
761 * fdt_nop_node() will replace a given node's representation in the
762 * blob, including all its subnodes, if any, with FDT_NOP tags,
763 * effectively removing it from the tree.
764 *
765 * This function will alter only the bytes in the blob which contain
766 * the node and its properties and subnodes, and will not alter or
767 * move any other part of the tree.
768 *
769 * returns:
770 * 0, on success
771 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
772 * -FDT_ERR_BADMAGIC,
773 * -FDT_ERR_BADVERSION,
774 * -FDT_ERR_BADSTATE,
775 * -FDT_ERR_BADSTRUCTURE,
776 * -FDT_ERR_TRUNCATED, standard meanings
777 */
668int fdt_nop_node(void *fdt, int nodeoffset); 778int fdt_nop_node(void *fdt, int nodeoffset);
669 779
670/**********************************************************************/ 780/**********************************************************************/
@@ -693,23 +803,268 @@ int fdt_finish(void *fdt);
693int fdt_open_into(const void *fdt, void *buf, int bufsize); 803int fdt_open_into(const void *fdt, void *buf, int bufsize);
694int fdt_pack(void *fdt); 804int fdt_pack(void *fdt);
695 805
806/**
807 * fdt_add_mem_rsv - add one memory reserve map entry
808 * @fdt: pointer to the device tree blob
809 * @address, @size: 64-bit values (native endian)
810 *
811 * Adds a reserve map entry to the given blob reserving a region at
812 * address address of length size.
813 *
814 * This function will insert data into the reserve map and will
815 * therefore change the indexes of some entries in the table.
816 *
817 * returns:
818 * 0, on success
819 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
820 * contain the new reservation entry
821 * -FDT_ERR_BADMAGIC,
822 * -FDT_ERR_BADVERSION,
823 * -FDT_ERR_BADSTATE,
824 * -FDT_ERR_BADSTRUCTURE,
825 * -FDT_ERR_BADLAYOUT,
826 * -FDT_ERR_TRUNCATED, standard meanings
827 */
696int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size); 828int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
829
830/**
831 * fdt_del_mem_rsv - remove a memory reserve map entry
832 * @fdt: pointer to the device tree blob
833 * @n: entry to remove
834 *
835 * fdt_del_mem_rsv() removes the n-th memory reserve map entry from
836 * the blob.
837 *
838 * This function will delete data from the reservation table and will
839 * therefore change the indexes of some entries in the table.
840 *
841 * returns:
842 * 0, on success
843 * -FDT_ERR_NOTFOUND, there is no entry of the given index (i.e. there
844 * are less than n+1 reserve map entries)
845 * -FDT_ERR_BADMAGIC,
846 * -FDT_ERR_BADVERSION,
847 * -FDT_ERR_BADSTATE,
848 * -FDT_ERR_BADSTRUCTURE,
849 * -FDT_ERR_BADLAYOUT,
850 * -FDT_ERR_TRUNCATED, standard meanings
851 */
697int fdt_del_mem_rsv(void *fdt, int n); 852int fdt_del_mem_rsv(void *fdt, int n);
698 853
854/**
855 * fdt_set_name - change the name of a given node
856 * @fdt: pointer to the device tree blob
857 * @nodeoffset: structure block offset of a node
858 * @name: name to give the node
859 *
860 * fdt_set_name() replaces the name (including unit address, if any)
861 * of the given node with the given string. NOTE: this function can't
862 * efficiently check if the new name is unique amongst the given
863 * node's siblings; results are undefined if this function is invoked
864 * with a name equal to one of the given node's siblings.
865 *
866 * This function may insert or delete data from the blob, and will
867 * therefore change the offsets of some existing nodes.
868 *
869 * returns:
870 * 0, on success
871 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob
872 * to contain the new name
873 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
874 * -FDT_ERR_BADMAGIC,
875 * -FDT_ERR_BADVERSION,
876 * -FDT_ERR_BADSTATE, standard meanings
877 */
878int fdt_set_name(void *fdt, int nodeoffset, const char *name);
879
880/**
881 * fdt_setprop - create or change a property
882 * @fdt: pointer to the device tree blob
883 * @nodeoffset: offset of the node whose property to change
884 * @name: name of the property to change
885 * @val: pointer to data to set the property value to
886 * @len: length of the property value
887 *
888 * fdt_setprop() sets the value of the named property in the given
889 * node to the given value and length, creating the property if it
890 * does not already exist.
891 *
892 * This function may insert or delete data from the blob, and will
893 * therefore change the offsets of some existing nodes.
894 *
895 * returns:
896 * 0, on success
897 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
898 * contain the new property value
899 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
900 * -FDT_ERR_BADLAYOUT,
901 * -FDT_ERR_BADMAGIC,
902 * -FDT_ERR_BADVERSION,
903 * -FDT_ERR_BADSTATE,
904 * -FDT_ERR_BADSTRUCTURE,
905 * -FDT_ERR_BADLAYOUT,
906 * -FDT_ERR_TRUNCATED, standard meanings
907 */
699int fdt_setprop(void *fdt, int nodeoffset, const char *name, 908int fdt_setprop(void *fdt, int nodeoffset, const char *name,
700 const void *val, int len); 909 const void *val, int len);
910
911/**
912 * fdt_setprop_cell - set a property to a single cell value
913 * @fdt: pointer to the device tree blob
914 * @nodeoffset: offset of the node whose property to change
915 * @name: name of the property to change
916 * @val: 32-bit integer value for the property (native endian)
917 *
918 * fdt_setprop_cell() sets the value of the named property in the
919 * given node to the given cell value (converting to big-endian if
920 * necessary), or creates a new property with that value if it does
921 * not already exist.
922 *
923 * This function may insert or delete data from the blob, and will
924 * therefore change the offsets of some existing nodes.
925 *
926 * returns:
927 * 0, on success
928 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
929 * contain the new property value
930 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
931 * -FDT_ERR_BADLAYOUT,
932 * -FDT_ERR_BADMAGIC,
933 * -FDT_ERR_BADVERSION,
934 * -FDT_ERR_BADSTATE,
935 * -FDT_ERR_BADSTRUCTURE,
936 * -FDT_ERR_BADLAYOUT,
937 * -FDT_ERR_TRUNCATED, standard meanings
938 */
701static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, 939static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
702 uint32_t val) 940 uint32_t val)
703{ 941{
704 val = cpu_to_fdt32(val); 942 val = cpu_to_fdt32(val);
705 return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val)); 943 return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
706} 944}
945
946/**
947 * fdt_setprop_string - set a property to a string value
948 * @fdt: pointer to the device tree blob
949 * @nodeoffset: offset of the node whose property to change
950 * @name: name of the property to change
951 * @str: string value for the property
952 *
953 * fdt_setprop_string() sets the value of the named property in the
954 * given node to the given string value (using the length of the
955 * string to determine the new length of the property), or creates a
956 * new property with that value if it does not already exist.
957 *
958 * This function may insert or delete data from the blob, and will
959 * therefore change the offsets of some existing nodes.
960 *
961 * returns:
962 * 0, on success
963 * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to
964 * contain the new property value
965 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
966 * -FDT_ERR_BADLAYOUT,
967 * -FDT_ERR_BADMAGIC,
968 * -FDT_ERR_BADVERSION,
969 * -FDT_ERR_BADSTATE,
970 * -FDT_ERR_BADSTRUCTURE,
971 * -FDT_ERR_BADLAYOUT,
972 * -FDT_ERR_TRUNCATED, standard meanings
973 */
707#define fdt_setprop_string(fdt, nodeoffset, name, str) \ 974#define fdt_setprop_string(fdt, nodeoffset, name, str) \
708 fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) 975 fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
976
977/**
978 * fdt_delprop - delete a property
979 * @fdt: pointer to the device tree blob
980 * @nodeoffset: offset of the node whose property to nop
981 * @name: name of the property to nop
982 *
983 * fdt_del_property() will delete the given property.
984 *
985 * This function will delete data from the blob, and will therefore
986 * change the offsets of some existing nodes.
987 *
988 * returns:
989 * 0, on success
990 * -FDT_ERR_NOTFOUND, node does not have the named property
991 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
992 * -FDT_ERR_BADLAYOUT,
993 * -FDT_ERR_BADMAGIC,
994 * -FDT_ERR_BADVERSION,
995 * -FDT_ERR_BADSTATE,
996 * -FDT_ERR_BADSTRUCTURE,
997 * -FDT_ERR_TRUNCATED, standard meanings
998 */
709int fdt_delprop(void *fdt, int nodeoffset, const char *name); 999int fdt_delprop(void *fdt, int nodeoffset, const char *name);
1000
1001/**
1002 * fdt_add_subnode_namelen - creates a new node based on substring
1003 * @fdt: pointer to the device tree blob
1004 * @parentoffset: structure block offset of a node
1005 * @name: name of the subnode to locate
1006 * @namelen: number of characters of name to consider
1007 *
1008 * Identical to fdt_add_subnode(), but use only the first namelen
1009 * characters of name as the name of the new node. This is useful for
1010 * creating subnodes based on a portion of a larger string, such as a
1011 * full path.
1012 */
710int fdt_add_subnode_namelen(void *fdt, int parentoffset, 1013int fdt_add_subnode_namelen(void *fdt, int parentoffset,
711 const char *name, int namelen); 1014 const char *name, int namelen);
1015
1016/**
1017 * fdt_add_subnode - creates a new node
1018 * @fdt: pointer to the device tree blob
1019 * @parentoffset: structure block offset of a node
1020 * @name: name of the subnode to locate
1021 *
1022 * fdt_add_subnode() creates a new node as a subnode of the node at
1023 * structure block offset parentoffset, with the given name (which
1024 * should include the unit address, if any).
1025 *
1026 * This function will insert data into the blob, and will therefore
1027 * change the offsets of some existing nodes.
1028
1029 * returns:
1030 * structure block offset of the created nodeequested subnode (>=0), on success
1031 * -FDT_ERR_NOTFOUND, if the requested subnode does not exist
1032 * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
1033 * -FDT_ERR_EXISTS, if the node at parentoffset already has a subnode of
1034 * the given name
1035 * -FDT_ERR_NOSPACE, if there is insufficient free space in the
1036 * blob to contain the new node
1037 * -FDT_ERR_NOSPACE
1038 * -FDT_ERR_BADLAYOUT
1039 * -FDT_ERR_BADMAGIC,
1040 * -FDT_ERR_BADVERSION,
1041 * -FDT_ERR_BADSTATE,
1042 * -FDT_ERR_BADSTRUCTURE,
1043 * -FDT_ERR_TRUNCATED, standard meanings.
1044 */
712int fdt_add_subnode(void *fdt, int parentoffset, const char *name); 1045int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
1046
1047/**
1048 * fdt_del_node - delete a node (subtree)
1049 * @fdt: pointer to the device tree blob
1050 * @nodeoffset: offset of the node to nop
1051 *
1052 * fdt_del_node() will remove the given node, including all its
1053 * subnodes if any, from the blob.
1054 *
1055 * This function will delete data from the blob, and will therefore
1056 * change the offsets of some existing nodes.
1057 *
1058 * returns:
1059 * 0, on success
1060 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
1061 * -FDT_ERR_BADLAYOUT,
1062 * -FDT_ERR_BADMAGIC,
1063 * -FDT_ERR_BADVERSION,
1064 * -FDT_ERR_BADSTATE,
1065 * -FDT_ERR_BADSTRUCTURE,
1066 * -FDT_ERR_TRUNCATED, standard meanings
1067 */
713int fdt_del_node(void *fdt, int nodeoffset); 1068int fdt_del_node(void *fdt, int nodeoffset);
714 1069
715/**********************************************************************/ 1070/**********************************************************************/
diff --git a/arch/powerpc/boot/libfdt/libfdt_internal.h b/arch/powerpc/boot/libfdt/libfdt_internal.h
index 1e60936beb5b..46eb93e4af5c 100644
--- a/arch/powerpc/boot/libfdt/libfdt_internal.h
+++ b/arch/powerpc/boot/libfdt/libfdt_internal.h
@@ -52,38 +52,44 @@
52 */ 52 */
53#include <fdt.h> 53#include <fdt.h>
54 54
55#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) 55#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
56#define PALIGN(p, a) ((void *)ALIGN((unsigned long)(p), (a))) 56#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE))
57 57
58#define memeq(p, q, n) (memcmp((p), (q), (n)) == 0) 58#define FDT_CHECK_HEADER(fdt) \
59#define streq(p, q) (strcmp((p), (q)) == 0) 59 { \
60 int err; \
61 if ((err = fdt_check_header(fdt)) != 0) \
62 return err; \
63 }
60 64
61uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset); 65uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset);
66int _fdt_check_node_offset(const void *fdt, int offset);
62const char *_fdt_find_string(const char *strtab, int tabsize, const char *s); 67const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
63int _fdt_node_end_offset(void *fdt, int nodeoffset); 68int _fdt_node_end_offset(void *fdt, int nodeoffset);
64 69
65static inline const void *_fdt_offset_ptr(const void *fdt, int offset) 70static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
66{ 71{
67 return fdt + fdt_off_dt_struct(fdt) + offset; 72 return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
68} 73}
69 74
70static inline void *_fdt_offset_ptr_w(void *fdt, int offset) 75static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
71{ 76{
72 return (void *)_fdt_offset_ptr(fdt, offset); 77 return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset);
73} 78}
74 79
75static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n) 80static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
76{ 81{
77 const struct fdt_reserve_entry *rsv_table = 82 const struct fdt_reserve_entry *rsv_table =
78 fdt + fdt_off_mem_rsvmap(fdt); 83 (const struct fdt_reserve_entry *)
84 ((const char *)fdt + fdt_off_mem_rsvmap(fdt));
79 85
80 return rsv_table + n; 86 return rsv_table + n;
81} 87}
82static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n) 88static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
83{ 89{
84 return (void *)_fdt_mem_rsv(fdt, n); 90 return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n);
85} 91}
86 92
87#define SW_MAGIC (~FDT_MAGIC) 93#define FDT_SW_MAGIC (~FDT_MAGIC)
88 94
89#endif /* _LIBFDT_INTERNAL_H */ 95#endif /* _LIBFDT_INTERNAL_H */
diff --git a/arch/powerpc/boot/libfdt_env.h b/arch/powerpc/boot/libfdt_env.h
index a4b0fc959ece..c89fdb1b80e1 100644
--- a/arch/powerpc/boot/libfdt_env.h
+++ b/arch/powerpc/boot/libfdt_env.h
@@ -6,6 +6,7 @@
6 6
7typedef u32 uint32_t; 7typedef u32 uint32_t;
8typedef u64 uint64_t; 8typedef u64 uint64_t;
9typedef unsigned long uintptr_t;
9 10
10#define fdt16_to_cpu(x) (x) 11#define fdt16_to_cpu(x) (x)
11#define cpu_to_fdt16(x) (x) 12#define cpu_to_fdt16(x) (x)