symbian-qemu-0.9.1-12/dtc-trunk/ftdump.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * ftdump.c - Contributed by Pantelis Antoniou <pantelis.antoniou AT gmail.com>
       
     3  */
       
     4 
       
     5 #include <stdint.h>
       
     6 #include <stdio.h>
       
     7 #include <string.h>
       
     8 #include <ctype.h>
       
     9 #include <getopt.h>
       
    10 
       
    11 #include <fdt.h>
       
    12 #include <libfdt_env.h>
       
    13 #include <version_gen.h>
       
    14 
       
    15 #define ALIGN(x, a)	(((x) + ((a) - 1)) & ~((a) - 1))
       
    16 #define PALIGN(p, a)	((void *)(ALIGN((unsigned long)(p), (a))))
       
    17 #define GET_CELL(p)	(p += 4, *((uint32_t *)(p-4)))
       
    18 
       
    19 static int is_printable_string(const void *data, int len)
       
    20 {
       
    21 	const char *s = data;
       
    22 	const char *ss;
       
    23 
       
    24 	/* zero length is not */
       
    25 	if (len == 0)
       
    26 		return 0;
       
    27 
       
    28 	/* must terminate with zero */
       
    29 	if (s[len - 1] != '\0')
       
    30 		return 0;
       
    31 
       
    32 	ss = s;
       
    33 	while (*s && isprint(*s))
       
    34 		s++;
       
    35 
       
    36 	/* not zero, or not done yet */
       
    37 	if (*s != '\0' || (s + 1 - ss) < len)
       
    38 		return 0;
       
    39 
       
    40 	return 1;
       
    41 }
       
    42 
       
    43 static void print_data(const void *data, int len)
       
    44 {
       
    45 	int i;
       
    46 	const uint8_t *s;
       
    47 
       
    48 	/* no data, don't print */
       
    49 	if (len == 0)
       
    50 		return;
       
    51 
       
    52 	if (is_printable_string(data, len)) {
       
    53 		printf(" = \"%s\"", (const char *)data);
       
    54 	} else if ((len % 4) == 0) {
       
    55 		printf(" = <");
       
    56 		for (i = 0; i < len; i += 4)
       
    57 			printf("%08x%s", *((const uint32_t *)data + i),
       
    58 			       i < (len - 4) ? " " : "");
       
    59 		printf(">");
       
    60 	} else {
       
    61 		printf(" = [");
       
    62 		for (i = 0, s = data; i < len; i++)
       
    63 			printf("%02x%s", s[i], i < len - 1 ? " " : "");
       
    64 		printf("]");
       
    65 	}
       
    66 }
       
    67 
       
    68 static void dump_blob(void *blob)
       
    69 {
       
    70 	struct fdt_header *bph = blob;
       
    71 	uint32_t off_mem_rsvmap = fdt32_to_cpu(bph->off_mem_rsvmap);
       
    72 	uint32_t off_dt = fdt32_to_cpu(bph->off_dt_struct);
       
    73 	uint32_t off_str = fdt32_to_cpu(bph->off_dt_strings);
       
    74 	struct fdt_reserve_entry *p_rsvmap =
       
    75 		(struct fdt_reserve_entry *)((char *)blob + off_mem_rsvmap);
       
    76 	char *p_struct = (char *)blob + off_dt;
       
    77 	char *p_strings = (char *)blob + off_str;
       
    78 	uint32_t version = fdt32_to_cpu(bph->version);
       
    79 	uint32_t totalsize = fdt32_to_cpu(bph->totalsize);
       
    80 	uint32_t tag;
       
    81 	char *p;
       
    82 	char *s, *t;
       
    83 	int depth, sz, shift;
       
    84 	int i;
       
    85 	uint64_t addr, size;
       
    86 
       
    87 	depth = 0;
       
    88 	shift = 4;
       
    89 
       
    90 	printf("// magic:\t\t0x%x\n", fdt32_to_cpu(bph->magic));
       
    91 	printf("// totalsize:\t\t0x%x (%d)\n", totalsize, totalsize);
       
    92 	printf("// off_dt_struct:\t0x%x\n", off_dt);
       
    93 	printf("// off_dt_strings:\t0x%x\n", off_str);
       
    94 	printf("// off_mem_rsvmap:\t0x%x\n", off_mem_rsvmap);
       
    95 	printf("// version:\t\t%d\n", version);
       
    96 	printf("// last_comp_version:\t%d\n",
       
    97 	       fdt32_to_cpu(bph->last_comp_version));
       
    98 	if (version >= 2)
       
    99 		printf("// boot_cpuid_phys:\t0x%x\n",
       
   100 		       fdt32_to_cpu(bph->boot_cpuid_phys));
       
   101 
       
   102 	if (version >= 3)
       
   103 		printf("// size_dt_strings:\t0x%x\n",
       
   104 		       fdt32_to_cpu(bph->size_dt_strings));
       
   105 	if (version >= 17)
       
   106 		printf("// size_dt_struct:\t0x%x\n",
       
   107 		       fdt32_to_cpu(bph->size_dt_struct));
       
   108 	printf("\n");
       
   109 
       
   110 	for (i = 0; ; i++) {
       
   111 		addr = fdt64_to_cpu(p_rsvmap[i].address);
       
   112 		size = fdt64_to_cpu(p_rsvmap[i].size);
       
   113 		if (addr == 0 && size == 0)
       
   114 			break;
       
   115 
       
   116 		printf("/memreserve/ %llx %llx;\n",
       
   117 		       (unsigned long long)addr, (unsigned long long)size);
       
   118 	}
       
   119 
       
   120 	p = p_struct;
       
   121 	while ((tag = fdt32_to_cpu(GET_CELL(p))) != FDT_END) {
       
   122 
       
   123 		/* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */
       
   124 
       
   125 		if (tag == FDT_BEGIN_NODE) {
       
   126 			s = p;
       
   127 			p = PALIGN(p + strlen(s) + 1, 4);
       
   128 
       
   129 			if (*s == '\0')
       
   130 				s = "/";
       
   131 
       
   132 			printf("%*s%s {\n", depth * shift, "", s);
       
   133 
       
   134 			depth++;
       
   135 			continue;
       
   136 		}
       
   137 
       
   138 		if (tag == FDT_END_NODE) {
       
   139 			depth--;
       
   140 
       
   141 			printf("%*s};\n", depth * shift, "");
       
   142 			continue;
       
   143 		}
       
   144 
       
   145 		if (tag == FDT_NOP) {
       
   146 			printf("%*s// [NOP]\n", depth * shift, "");
       
   147 			continue;
       
   148 		}
       
   149 
       
   150 		if (tag != FDT_PROP) {
       
   151 			fprintf(stderr, "%*s ** Unknown tag 0x%08x\n", depth * shift, "", tag);
       
   152 			break;
       
   153 		}
       
   154 		sz = fdt32_to_cpu(GET_CELL(p));
       
   155 		s = p_strings + fdt32_to_cpu(GET_CELL(p));
       
   156 		if (version < 16 && sz >= 8)
       
   157 			p = PALIGN(p, 8);
       
   158 		t = p;
       
   159 
       
   160 		p = PALIGN(p + sz, 4);
       
   161 
       
   162 		printf("%*s%s", depth * shift, "", s);
       
   163 		print_data(t, sz);
       
   164 		printf(";\n");
       
   165 	}
       
   166 }
       
   167 
       
   168 static void  __attribute__ ((noreturn)) usage(int error)
       
   169 {
       
   170         FILE *f = error ? stderr : stdout;
       
   171 	fprintf(f, "Usage:\n");
       
   172 	fprintf(f, "\tftdump [options] <input file>\n");
       
   173 	fprintf(f, "\nOptions:\n");
       
   174 	fprintf(f, "\t-h\n");
       
   175 	fprintf(f, "\t\tThis help text\n");
       
   176 	fprintf(f, "\t-v\n");
       
   177 	fprintf(f, "\t\tPrint ftdump version and exit\n");
       
   178 	fprintf(f, "\n");
       
   179 	fprintf(f, "Report bugs to %s\n", BUG_URL);
       
   180 	exit(error ? 3 : 0);
       
   181 }
       
   182 
       
   183 int main(int argc, char *argv[])
       
   184 {
       
   185         static const struct option longopts[] = {
       
   186             {"help", no_argument, NULL, 'h'},
       
   187             {"version", no_argument, NULL, 'v'},
       
   188             {NULL, 0, NULL, 0}
       
   189         };
       
   190         int opt;
       
   191 	FILE *fp;
       
   192 	char buf[16384];	/* 16k max */
       
   193 	int size;
       
   194 
       
   195 	while ((opt = getopt_long(argc, argv, "hv",
       
   196                 longopts, NULL)) != EOF) {
       
   197 		switch (opt) {
       
   198 		case 'h':
       
   199                         usage(0);
       
   200 		case 'v':
       
   201 			printf("Version: %s\n", DTC_VERSION);
       
   202 			exit(0);
       
   203                 default:
       
   204                         usage(1);
       
   205                 }
       
   206         }
       
   207 
       
   208 	if (argc != optind + 1) {
       
   209                 usage(1);
       
   210 	}
       
   211 
       
   212 	fp = fopen(argv[optind], "rb");
       
   213 	if (fp == NULL) {
       
   214 		fprintf(stderr, "unable to open %s\n", argv[1]);
       
   215 		return 10;
       
   216 	}
       
   217 
       
   218 	size = fread(buf, 1, sizeof(buf), fp);
       
   219 	if (size == sizeof(buf)) {	/* too large */
       
   220 		fprintf(stderr, "file too large\n");
       
   221 		return 10;
       
   222 	}
       
   223 
       
   224 	dump_blob(buf);
       
   225 
       
   226 	fclose(fp);
       
   227 
       
   228 	return 0;
       
   229 }