aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/boot/dtc-src/flattree.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/boot/dtc-src/flattree.c')
-rw-r--r--arch/powerpc/boot/dtc-src/flattree.c232
1 files changed, 85 insertions, 147 deletions
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}