/*
 * ftdump.c - Contributed by Pantelis Antoniou <pantelis.antoniou AT gmail.com>
 */

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <netinet/in.h>
#include <byteswap.h>

#include <fdt.h>

#define cpu_to_be16(x)	htons(x)
#define be16_to_cpu(x)	ntohs(x)

#define cpu_to_be32(x)	htonl(x)
#define be32_to_cpu(x)	ntohl(x)

#if __BYTE_ORDER == __BIG_ENDIAN
#define cpu_to_be64(x)	(x)
#define be64_to_cpu(x)	(x)
#else
#define cpu_to_be64(x)	bswap_64(x)
#define be64_to_cpu(x)	bswap_64(x)
#endif

#define ALIGN(x, a)	(((x) + ((a) - 1)) & ~((a) - 1))
#define PALIGN(p, a)	((void *)(ALIGN((unsigned long)(p), (a))))
#define GET_CELL(p)	(p += 4, *((uint32_t *)(p-4)))

static int is_printable_string(const void *data, int len)
{
	const char *s = data;
	const char *ss;

	/* zero length is not */
	if (len == 0)
		return 0;

	/* must terminate with zero */
	if (s[len - 1] != '\0')
		return 0;

	ss = s;
	while (*s && isprint(*s))
		s++;

	/* not zero, or not done yet */
	if (*s != '\0' || (s + 1 - ss) < len)
		return 0;

	return 1;
}

static void print_data(const void *data, int len)
{
	int i;
	const uint8_t *s;

	/* no data, don't print */
	if (len == 0)
		return;

	if (is_printable_string(data, len)) {
		printf(" = \"%s\"", (char *)data);
	} else if ((len % 4) == 0) {
		printf(" = <");
		for (i = 0; i < len; i += 4)
			printf("%08x%s", *((uint32_t *)data + i),
			       i < (len - 4) ? " " : "");
		printf(">");
	} else {
		printf(" = [");
		for (i = 0, s = data; i < len; i++)
			printf("%02x%s", s[i], i < len - 1 ? " " : "");
		printf("]");
	}
}

static void dump_blob(void *blob)
{
	struct fdt_header *bph = blob;
	uint32_t off_mem_rsvmap = be32_to_cpu(bph->off_mem_rsvmap);
	uint32_t off_dt = be32_to_cpu(bph->off_dt_struct);
	uint32_t off_str = be32_to_cpu(bph->off_dt_strings);
	struct fdt_reserve_entry *p_rsvmap =
		(struct fdt_reserve_entry *)(blob + off_mem_rsvmap);
	char *p_struct = blob + off_dt;
	char *p_strings = blob + off_str;
	uint32_t version = be32_to_cpu(bph->version);
	uint32_t totalsize = be32_to_cpu(bph->totalsize);
	uint32_t tag;
	char *p;
	char *s, *t;
	int depth, sz, shift;
	int i;
	uint64_t addr, size;

	depth = 0;
	shift = 4;

	printf("// magic:\t\t0x%x\n", be32_to_cpu(bph->magic));
	printf("// totalsize:\t\t0x%x (%d)\n", totalsize, totalsize);
	printf("// off_dt_struct:\t0x%x\n", off_dt);
	printf("// off_dt_strings:\t0x%x\n", off_str);
	printf("// off_mem_rsvmap:\t0x%x\n", off_mem_rsvmap);
	printf("// version:\t\t%d\n", version);
	printf("// last_comp_version:\t%d\n",
	       be32_to_cpu(bph->last_comp_version));
	if (version >= 2)
		printf("// boot_cpuid_phys:\t0x%x\n",
		       be32_to_cpu(bph->boot_cpuid_phys));

	if (version >= 3)
		printf("// size_dt_strings:\t0x%x\n",
		       be32_to_cpu(bph->size_dt_strings));
	if (version >= 17)
		printf("// size_dt_struct:\t0x%x\n",
		       be32_to_cpu(bph->size_dt_struct));
	printf("\n");

	for (i = 0; ; i++) {
		addr = be64_to_cpu(p_rsvmap[i].address);
		size = be64_to_cpu(p_rsvmap[i].size);
		if (addr == 0 && size == 0)
			break;

		printf("/memreserve/ %llx %llx;\n",
		       (unsigned long long)addr, (unsigned long long)size);
	}

	p = p_struct;
	while ((tag = be32_to_cpu(GET_CELL(p))) != FDT_END) {

		/* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */

		if (tag == FDT_BEGIN_NODE) {
			s = p;
			p = PALIGN(p + strlen(s) + 1, 4);

			if (*s == '\0')
				s = "/";

			printf("%*s%s {\n", depth * shift, "", s);

			depth++;
			continue;
		}

		if (tag == FDT_END_NODE) {
			depth--;

			printf("%*s};\n", depth * shift, "");
			continue;
		}

		if (tag == FDT_NOP) {
			printf("%*s// [NOP]\n", depth * shift, "");
			continue;
		}

		if (tag != FDT_PROP) {
			fprintf(stderr, "%*s ** Unknown tag 0x%08x\n", depth * shift, "", tag);
			break;
		}
		sz = be32_to_cpu(GET_CELL(p));
		s = p_strings + be32_to_cpu(GET_CELL(p));
		if (version < 16 && sz >= 8)
			p = PALIGN(p, 8);
		t = p;

		p = PALIGN(p + sz, 4);

		printf("%*s%s", depth * shift, "", s);
		print_data(t, sz);
		printf(";\n");
	}
}


int main(int argc, char *argv[])
{
	FILE *fp;
	char buf[16384];	/* 16k max */
	int size;

	if (argc < 2) {
		fprintf(stderr, "supply input filename\n");
		return 5;
	}

	fp = fopen(argv[1], "rb");
	if (fp == NULL) {
		fprintf(stderr, "unable to open %s\n", argv[1]);
		return 10;
	}

	size = fread(buf, 1, sizeof(buf), fp);
	if (size == sizeof(buf)) {	/* too large */
		fprintf(stderr, "file too large\n");
		return 10;
	}

	dump_blob(buf);

	fclose(fp);

	return 0;
}
