summaryrefslogtreecommitdiffstats
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 @@
*/
#include "dtc.h"
+#include "srcpos.h"
#define FTF_FULLPATH 0x1
#define FTF_VARALIGN 0x2
@@ -162,28 +163,18 @@ static void asm_emit_data(void *e, struct data d)
{
FILE *f = e;
int off = 0;
- struct marker *m;
+ struct marker *m = d.markers;
- m = d.markers;
- while (m) {
- if (m->type == LABEL)
- emit_offset_label(f, m->ref, m->offset);
- m = m->next;
- }
+ for_each_marker_of_type(m, LABEL)
+ emit_offset_label(f, m->ref, m->offset);
- while ((d.len - off) >= sizeof(u32)) {
+ while ((d.len - off) >= sizeof(uint32_t)) {
fprintf(f, "\t.long\t0x%x\n",
- be32_to_cpu(*((u32 *)(d.val+off))));
- off += sizeof(u32);
- }
-
- if ((d.len - off) >= sizeof(u16)) {
- fprintf(f, "\t.short\t0x%hx\n",
- be16_to_cpu(*((u16 *)(d.val+off))));
- off += sizeof(u16);
+ fdt32_to_cpu(*((uint32_t *)(d.val+off))));
+ off += sizeof(uint32_t);
}
- if ((d.len - off) >= 1) {
+ while ((d.len - off) >= 1) {
fprintf(f, "\t.byte\t0x%hhx\n", d.val[off]);
off += 1;
}
@@ -336,29 +327,28 @@ static void make_fdt_header(struct fdt_header *fdt,
memset(fdt, 0xff, sizeof(*fdt));
- fdt->magic = cpu_to_be32(FDT_MAGIC);
- fdt->version = cpu_to_be32(vi->version);
- fdt->last_comp_version = cpu_to_be32(vi->last_comp_version);
+ fdt->magic = cpu_to_fdt32(FDT_MAGIC);
+ fdt->version = cpu_to_fdt32(vi->version);
+ fdt->last_comp_version = cpu_to_fdt32(vi->last_comp_version);
/* Reserve map should be doubleword aligned */
reserve_off = ALIGN(vi->hdr_size, 8);
- fdt->off_mem_rsvmap = cpu_to_be32(reserve_off);
- fdt->off_dt_struct = cpu_to_be32(reserve_off + reservesize);
- fdt->off_dt_strings = cpu_to_be32(reserve_off + reservesize
+ fdt->off_mem_rsvmap = cpu_to_fdt32(reserve_off);
+ fdt->off_dt_struct = cpu_to_fdt32(reserve_off + reservesize);
+ fdt->off_dt_strings = cpu_to_fdt32(reserve_off + reservesize
+ dtsize);
- fdt->totalsize = cpu_to_be32(reserve_off + reservesize + dtsize + strsize);
+ fdt->totalsize = cpu_to_fdt32(reserve_off + reservesize + dtsize + strsize);
if (vi->flags & FTF_BOOTCPUID)
- fdt->boot_cpuid_phys = cpu_to_be32(boot_cpuid_phys);
+ fdt->boot_cpuid_phys = cpu_to_fdt32(boot_cpuid_phys);
if (vi->flags & FTF_STRTABSIZE)
- fdt->size_dt_strings = cpu_to_be32(strsize);
+ fdt->size_dt_strings = cpu_to_fdt32(strsize);
if (vi->flags & FTF_STRUCTSIZE)
- fdt->size_dt_struct = cpu_to_be32(dtsize);
+ fdt->size_dt_struct = cpu_to_fdt32(dtsize);
}
-void dt_to_blob(FILE *f, struct boot_info *bi, int version,
- int boot_cpuid_phys)
+void dt_to_blob(FILE *f, struct boot_info *bi, int version)
{
struct version_info *vi = NULL;
int i;
@@ -383,26 +373,26 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version,
/* Make header */
make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len,
- boot_cpuid_phys);
+ bi->boot_cpuid_phys);
/*
* If the user asked for more space than is used, adjust the totalsize.
*/
if (minsize > 0) {
- padlen = minsize - be32_to_cpu(fdt.totalsize);
+ padlen = minsize - fdt32_to_cpu(fdt.totalsize);
if ((padlen < 0) && (quiet < 1))
fprintf(stderr,
"Warning: blob size %d >= minimum size %d\n",
- be32_to_cpu(fdt.totalsize), minsize);
+ fdt32_to_cpu(fdt.totalsize), minsize);
}
if (padsize > 0)
padlen = padsize;
if (padlen > 0) {
- int tsize = be32_to_cpu(fdt.totalsize);
+ int tsize = fdt32_to_cpu(fdt.totalsize);
tsize += padlen;
- fdt.totalsize = cpu_to_be32(tsize);
+ fdt.totalsize = cpu_to_fdt32(tsize);
}
/*
@@ -410,7 +400,7 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version,
* the reserve buffer, add the reserve map terminating zeroes,
* the device tree itself, and finally the strings.
*/
- blob = data_append_data(blob, &fdt, sizeof(fdt));
+ blob = data_append_data(blob, &fdt, vi->hdr_size);
blob = data_append_align(blob, 8);
blob = data_merge(blob, reservebuf);
blob = data_append_zeroes(blob, sizeof(struct fdt_reserve_entry));
@@ -449,7 +439,7 @@ static void dump_stringtable_asm(FILE *f, struct data strbuf)
}
}
-void dt_to_asm(FILE *f, struct boot_info *bi, int version, int boot_cpuid_phys)
+void dt_to_asm(FILE *f, struct boot_info *bi, int version)
{
struct version_info *vi = NULL;
int i;
@@ -489,7 +479,7 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version, int boot_cpuid_phys)
if (vi->flags & FTF_BOOTCPUID)
fprintf(f, "\t.long\t%i\t\t\t\t\t/* boot_cpuid_phys */\n",
- boot_cpuid_phys);
+ bi->boot_cpuid_phys);
if (vi->flags & FTF_STRTABSIZE)
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)
inb->ptr += len;
}
-static u32 flat_read_word(struct inbuf *inb)
+static uint32_t flat_read_word(struct inbuf *inb)
{
- u32 val;
+ uint32_t val;
assert(((inb->ptr - inb->base) % sizeof(val)) == 0);
flat_read_chunk(inb, &val, sizeof(val));
- return be32_to_cpu(val);
+ return fdt32_to_cpu(val);
}
static void flat_realign(struct inbuf *inb, int align)
@@ -615,7 +605,7 @@ static char *flat_read_string(struct inbuf *inb)
inb->ptr += len;
- flat_realign(inb, sizeof(u32));
+ flat_realign(inb, sizeof(uint32_t));
return str;
}
@@ -632,7 +622,7 @@ static struct data flat_read_data(struct inbuf *inb, int len)
flat_read_chunk(inb, d.val, len);
- flat_realign(inb, sizeof(u32));
+ flat_realign(inb, sizeof(uint32_t));
return d;
}
@@ -659,7 +649,7 @@ static char *flat_read_stringtable(struct inbuf *inb, int offset)
static struct property *flat_read_property(struct inbuf *dtbuf,
struct inbuf *strbuf, int flags)
{
- u32 proplen, stroff;
+ uint32_t proplen, stroff;
char *name;
struct data val;
@@ -693,8 +683,8 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
p = inb->ptr;
while (1) {
flat_read_chunk(inb, &re, sizeof(re));
- re.address = be64_to_cpu(re.address);
- re.size = be64_to_cpu(re.size);
+ re.address = fdt64_to_cpu(re.address);
+ re.size = fdt64_to_cpu(re.size);
if (re.size == 0)
break;
@@ -708,77 +698,37 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
static char *nodename_from_path(const char *ppath, const char *cpath)
{
- const char *lslash;
int plen;
- lslash = strrchr(cpath, '/');
- if (! lslash)
- return NULL;
-
- plen = lslash - cpath;
-
- if (streq(cpath, "/") && streq(ppath, ""))
- return "";
-
- if ((plen == 0) && streq(ppath, "/"))
- return strdup(lslash+1);
-
- if (! strneq(ppath, cpath, plen))
- return NULL;
-
- return strdup(lslash+1);
-}
-
-static const char PROPCHAR[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,._+*#?-";
-static const char UNITCHAR[] = "0123456789abcdef,";
-
-static int check_node_name(const char *name)
-{
- const char *atpos;
- int basenamelen;
+ plen = strlen(ppath);
- atpos = strrchr(name, '@');
+ if (!strneq(ppath, cpath, plen))
+ die("Path \"%s\" is not valid as a child of \"%s\"\n",
+ cpath, ppath);
- if (atpos)
- basenamelen = atpos - name;
- else
- basenamelen = strlen(name);
-
- if (strspn(name, PROPCHAR) < basenamelen)
- return -1;
+ /* root node is a special case */
+ if (!streq(ppath, "/"))
+ plen++;
- if (atpos
- && ((basenamelen + 1 + strspn(atpos+1, UNITCHAR)) < strlen(name)))
- return -1;
-
- return basenamelen;
+ return strdup(cpath + plen);
}
static struct node *unflatten_tree(struct inbuf *dtbuf,
struct inbuf *strbuf,
- const char *parent_path, int flags)
+ const char *parent_flatname, int flags)
{
struct node *node;
- u32 val;
+ char *flatname;
+ uint32_t val;
node = build_node(NULL, NULL);
- if (flags & FTF_FULLPATH) {
- node->fullpath = flat_read_string(dtbuf);
- node->name = nodename_from_path(parent_path, node->fullpath);
-
- if (! node->name)
- die("Path \"%s\" is not valid as a child of \"%s\"\n",
- node->fullpath, parent_path);
- } else {
- node->name = flat_read_string(dtbuf);
- node->fullpath = join_path(parent_path, node->name);
- }
+ flatname = flat_read_string(dtbuf);
- node->basenamelen = check_node_name(node->name);
- if (node->basenamelen < 0) {
- fprintf(stderr, "Warning \"%s\" has incorrect format\n", node->name);
- }
+ if (flags & FTF_FULLPATH)
+ node->name = nodename_from_path(parent_flatname, flatname);
+ else
+ node->name = flatname;
do {
struct property *prop;
@@ -795,8 +745,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
break;
case FDT_BEGIN_NODE:
- child = unflatten_tree(dtbuf,strbuf, node->fullpath,
- flags);
+ child = unflatten_tree(dtbuf,strbuf, flatname, flags);
add_child(node, child);
break;
@@ -825,10 +774,11 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
}
-struct boot_info *dt_from_blob(FILE *f)
+struct boot_info *dt_from_blob(const char *fname)
{
- u32 magic, totalsize, version, size_str, size_dt;
- u32 off_dt, off_str, off_mem_rsvmap;
+ struct dtc_file *dtcf;
+ uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys;
+ uint32_t off_dt, off_str, off_mem_rsvmap;
int rc;
char *blob;
struct fdt_header *fdt;
@@ -838,54 +788,56 @@ struct boot_info *dt_from_blob(FILE *f)
int sizeleft;
struct reserve_info *reservelist;
struct node *tree;
- u32 val;
+ uint32_t val;
int flags = 0;
- rc = fread(&magic, sizeof(magic), 1, f);
- if (ferror(f))
+ dtcf = dtc_open_file(fname, NULL);
+
+ rc = fread(&magic, sizeof(magic), 1, dtcf->file);
+ if (ferror(dtcf->file))
die("Error reading DT blob magic number: %s\n",
strerror(errno));
if (rc < 1) {
- if (feof(f))
+ if (feof(dtcf->file))
die("EOF reading DT blob magic number\n");
else
die("Mysterious short read reading magic number\n");
}
- magic = be32_to_cpu(magic);
+ magic = fdt32_to_cpu(magic);
if (magic != FDT_MAGIC)
die("Blob has incorrect magic number\n");
- rc = fread(&totalsize, sizeof(totalsize), 1, f);
- if (ferror(f))
+ rc = fread(&totalsize, sizeof(totalsize), 1, dtcf->file);
+ if (ferror(dtcf->file))
die("Error reading DT blob size: %s\n", strerror(errno));
if (rc < 1) {
- if (feof(f))
+ if (feof(dtcf->file))
die("EOF reading DT blob size\n");
else
die("Mysterious short read reading blob size\n");
}
- totalsize = be32_to_cpu(totalsize);
+ totalsize = fdt32_to_cpu(totalsize);
if (totalsize < FDT_V1_SIZE)
die("DT blob size (%d) is too small\n", totalsize);
blob = xmalloc(totalsize);
fdt = (struct fdt_header *)blob;
- fdt->magic = cpu_to_be32(magic);
- fdt->totalsize = cpu_to_be32(totalsize);
+ fdt->magic = cpu_to_fdt32(magic);
+ fdt->totalsize = cpu_to_fdt32(totalsize);
sizeleft = totalsize - sizeof(magic) - sizeof(totalsize);
p = blob + sizeof(magic) + sizeof(totalsize);
while (sizeleft) {
- if (feof(f))
+ if (feof(dtcf->file))
die("EOF before reading %d bytes of DT blob\n",
totalsize);
- rc = fread(p, 1, sizeleft, f);
- if (ferror(f))
+ rc = fread(p, 1, sizeleft, dtcf->file);
+ if (ferror(dtcf->file))
die("Error reading DT blob: %s\n",
strerror(errno));
@@ -893,19 +845,11 @@ struct boot_info *dt_from_blob(FILE *f)
p += rc;
}
- off_dt = be32_to_cpu(fdt->off_dt_struct);
- off_str = be32_to_cpu(fdt->off_dt_strings);
- off_mem_rsvmap = be32_to_cpu(fdt->off_mem_rsvmap);
- version = be32_to_cpu(fdt->version);
-
- fprintf(stderr, "\tmagic:\t\t\t0x%x\n", magic);
- fprintf(stderr, "\ttotalsize:\t\t%d\n", totalsize);
- fprintf(stderr, "\toff_dt_struct:\t\t0x%x\n", off_dt);
- fprintf(stderr, "\toff_dt_strings:\t\t0x%x\n", off_str);
- fprintf(stderr, "\toff_mem_rsvmap:\t\t0x%x\n", off_mem_rsvmap);
- fprintf(stderr, "\tversion:\t\t0x%x\n", version );
- fprintf(stderr, "\tlast_comp_version:\t0x%x\n",
- be32_to_cpu(fdt->last_comp_version));
+ off_dt = fdt32_to_cpu(fdt->off_dt_struct);
+ off_str = fdt32_to_cpu(fdt->off_dt_strings);
+ off_mem_rsvmap = fdt32_to_cpu(fdt->off_mem_rsvmap);
+ version = fdt32_to_cpu(fdt->version);
+ boot_cpuid_phys = fdt32_to_cpu(fdt->boot_cpuid_phys);
if (off_mem_rsvmap >= totalsize)
die("Mem Reserve structure offset exceeds total size\n");
@@ -916,21 +860,17 @@ struct boot_info *dt_from_blob(FILE *f)
if (off_str > totalsize)
die("String table offset exceeds total size\n");
- if (version >= 2)
- fprintf(stderr, "\tboot_cpuid_phys:\t0x%x\n",
- be32_to_cpu(fdt->boot_cpuid_phys));
-
- size_str = -1;
if (version >= 3) {
- size_str = be32_to_cpu(fdt->size_dt_strings);
- fprintf(stderr, "\tsize_dt_strings:\t%d\n", size_str);
+ uint32_t size_str = fdt32_to_cpu(fdt->size_dt_strings);
if (off_str+size_str > totalsize)
die("String table extends past total size\n");
+ inbuf_init(&strbuf, blob + off_str, blob + off_str + size_str);
+ } else {
+ inbuf_init(&strbuf, blob + off_str, blob + totalsize);
}
if (version >= 17) {
- size_dt = be32_to_cpu(fdt->size_dt_struct);
- fprintf(stderr, "\tsize_dt_struct:\t\t%d\n", size_dt);
+ size_dt = fdt32_to_cpu(fdt->size_dt_struct);
if (off_dt+size_dt > totalsize)
die("Structure block extends past total size\n");
}
@@ -944,10 +884,6 @@ struct boot_info *dt_from_blob(FILE *f)
inbuf_init(&memresvbuf,
blob + off_mem_rsvmap, blob + totalsize);
inbuf_init(&dtbuf, blob + off_dt, blob + totalsize);
- if (size_str >= 0)
- inbuf_init(&strbuf, blob + off_str, blob + off_str + size_str);
- else
- inbuf_init(&strbuf, blob + off_str, blob + totalsize);
reservelist = flat_read_mem_reserve(&memresvbuf);
@@ -964,5 +900,7 @@ struct boot_info *dt_from_blob(FILE *f)
free(blob);
- return build_boot_info(reservelist, tree);
+ dtc_close_file(dtcf);
+
+ return build_boot_info(reservelist, tree, boot_cpuid_phys);
}
OpenPOWER on IntegriCloud