/*
 * OF flat tree builder
 * Written by: Pantelis Antoniou <pantelis.antoniou@gmail.com>
 * Updated by: Matthew McClintock <msm@freescale.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <boot.h>
#include <init.h>
#include <malloc.h>
#include <environment.h>
#include <asm/byteorder.h>
#include <stdio.h>

#include <errno.h>
#include <stddef.h>

#include <ft_build.h>

#undef DEBUG

/* align addr on a size boundary - adjust address up if needed -- Cort */
#define _ALIGN(addr,size)       (((addr)+(size)-1)&(~((size)-1)))
#ifndef CONFIG_OF_BOOT_CPU
#define CONFIG_OF_BOOT_CPU 0
#endif
#define SIZE_OF_RSVMAP_ENTRY (2*sizeof(u64))

static void ft_put_word(struct ft_cxt *cxt, u32 v)
{
	memmove(cxt->p + sizeof(u32), cxt->p, cxt->p_end - cxt->p);

	*(u32 *) cxt->p = cpu_to_be32(v);
	cxt->p += sizeof(u32);
	cxt->p_end += sizeof(u32);
}

static inline void ft_put_bin(struct ft_cxt *cxt, const void *data, int sz)
{
	int aligned_size = ((u8 *)_ALIGN((unsigned long)cxt->p + sz,
					sizeof(u32))) - cxt->p;

	memmove(cxt->p + aligned_size, cxt->p, cxt->p_end - cxt->p);

	/* make sure the last bytes are zeroed */
	memset(cxt->p + aligned_size - (aligned_size % sizeof(u32)), 0,
			(aligned_size % sizeof(u32)));

	memcpy(cxt->p, data, sz);

	cxt->p += aligned_size;
	cxt->p_end += aligned_size;
}

void ft_begin_node(struct ft_cxt *cxt, const char *name)
{
	ft_put_word(cxt, OF_DT_BEGIN_NODE);
	ft_put_bin(cxt, name, strlen(name) + 1);
}

void ft_end_node(struct ft_cxt *cxt)
{
	ft_put_word(cxt, OF_DT_END_NODE);
}

void ft_nop(struct ft_cxt *cxt)
{
	ft_put_word(cxt, OF_DT_NOP);
}

static int lookup_string(struct ft_cxt *cxt, const char *name)
{
	u8 *p;

	p = cxt->p;
	while (p < cxt->p_end) {
		if (strcmp((char *)p, name) == 0)
			return p - cxt->p;
		p += strlen((char *)p) + 1;
	}

	return -1;
}

void ft_prop(struct ft_cxt *cxt, const char *name, const void *data, int sz)
{
	int off = 0;

	off = lookup_string(cxt, name);
	if (off == -1) {
		memcpy(cxt->p_end, name, strlen(name) + 1);
		off = cxt->p_end - cxt->p;
		cxt->p_end += strlen(name) + 1;
	}

	/* now put offset from beginning of *STRUCTURE* */
	/* will be fixed up at the end */
	ft_put_word(cxt, OF_DT_PROP);
	ft_put_word(cxt, sz);
	ft_put_word(cxt, off);
	ft_put_bin(cxt, data, sz);
}

void ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str)
{
	ft_prop(cxt, name, str, strlen(str) + 1);
}

void ft_prop_int(struct ft_cxt *cxt, const char *name, int val)
{
	u32 v = cpu_to_be32((u32) val);

	ft_prop(cxt, name, &v, sizeof(u32));
}

/* pick up and start working on a tree in place */
void ft_init_cxt(struct ft_cxt *cxt, void *blob)
{
	struct boot_param_header *bph = blob;

	memset(cxt, 0, sizeof(*cxt));

	cxt->bph = bph;
	bph->boot_cpuid_phys = CONFIG_OF_BOOT_CPU;

	/* find beginning and end of reserve map table (zeros in last entry) */
	cxt->p_rsvmap = (u8 *)bph + bph->off_mem_rsvmap;
	while ( ((uint64_t *)cxt->p_rsvmap)[0] != 0 &&
		     ((uint64_t *)cxt->p_rsvmap)[1] != 0 ) {
	cxt->p_rsvmap += SIZE_OF_RSVMAP_ENTRY;
	}

	cxt->p_start = (u8 *)bph + bph->off_dt_struct;
	cxt->p_end = (u8 *)bph + bph->totalsize;
	cxt->p = (u8 *)bph + bph->off_dt_strings;
}

/* add a reserver physical area to the rsvmap */
void ft_add_rsvmap(struct ft_cxt *cxt, u64 physstart, u64 physend)
{
	memmove(cxt->p_rsvmap + SIZE_OF_RSVMAP_ENTRY, cxt->p_rsvmap,
				 cxt->p_end - cxt->p_rsvmap);

	((u64 *)cxt->p_rsvmap)[0] = cpu_to_be64(physstart);
	((u64 *)cxt->p_rsvmap)[1] = cpu_to_be64(physend);
	((u64 *)cxt->p_rsvmap)[2] = 0;
	((u64 *)cxt->p_rsvmap)[3] = 0;

	cxt->p_rsvmap += SIZE_OF_RSVMAP_ENTRY;
	cxt->p_start += SIZE_OF_RSVMAP_ENTRY;
	cxt->p += SIZE_OF_RSVMAP_ENTRY;
	cxt->p_end += SIZE_OF_RSVMAP_ENTRY;
}

void ft_end_tree(struct ft_cxt *cxt)
{
	ft_put_word(cxt, OF_DT_END);
}

/* update the boot param header with correct values */
void ft_finalize_tree(struct ft_cxt *cxt) {
	struct boot_param_header *bph = cxt->bph;

	bph->totalsize = cxt->p_end - (u8 *)bph;
	bph->off_dt_struct = cxt->p_start - (u8 *)bph;
	bph->off_dt_strings = cxt->p - (u8 *)bph;
	bph->dt_strings_size = cxt->p_end - cxt->p;
}

static inline int isprint(int c)
{
	return c >= 0x20 && c <= 0x7e;
}

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 u8 *s;

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

	if (is_printable_string(data, len)) {
		puts(" = \"");
		puts(data);
		puts("\"");
		return;
	}

	switch (len) {
	case 1:		/* byte */
		printf(" = <%02x>", (*(u8 *) data) & 0xff);
		break;
	case 2:		/* half-word */
		printf(" = <%04x>", be16_to_cpu(*(u16 *) data) & 0xffff);
		break;
	case 4:		/* word */
		printf(" = <%x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU);
		break;
	case 8:		/* double-word */
		printf(" = <%qx>", be64_to_cpu(*(uint64_t *) data));
		break;
	default:		/* anything else... hexdump */
		printf(" = [");
		for (i = 0, s = data; i < len; i++)
			printf("%02x%s", s[i], i < len - 1 ? " " : "");
		printf("]");

		break;
	}
}

void ft_dump_blob(const void *bphp)
{
	const struct boot_param_header *bph = bphp;
	const uint64_t *p_rsvmap = (const uint64_t *)
		((const char *)bph + be32_to_cpu(bph->off_mem_rsvmap));
	const u32 *p_struct = (const u32 *)
		((const char *)bph + be32_to_cpu(bph->off_dt_struct));
	const u32 *p_strings = (const u32 *)
		((const char *)bph + be32_to_cpu(bph->off_dt_strings));
	u32 tag;
	const u32 *p;
	const char *s, *t;
	int depth, sz, shift;
	int i;
	uint64_t addr, size;

	if (be32_to_cpu(bph->magic) != OF_DT_HEADER) {
		/* not valid tree */
		return;
	}

	depth = 0;
	shift = 4;

	for (i = 0;; i++) {
		addr = be64_to_cpu(p_rsvmap[i * 2]);
		size = be64_to_cpu(p_rsvmap[i * 2 + 1]);
		if (addr == 0 && size == 0)
			break;

		printf("/memreserve/ %qx %qx;\n", addr, size);
	}

	p = p_struct;
	while ((tag = be32_to_cpu(*p++)) != OF_DT_END) {

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

		if (tag == OF_DT_BEGIN_NODE) {
			s = (const char *)p;
			p = (u32 *) _ALIGN((unsigned long)p + strlen(s) + 1, 4);

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

			depth++;
			continue;
		}

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

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

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

		if (tag != OF_DT_PROP) {
			fprintf(stderr, "%*s ** Unknown tag 0x%08x at 0x%p\n",
				depth * shift, "", tag, --p);
			break;
		}
		sz = be32_to_cpu(*p++);
		s = (const char *)p_strings + be32_to_cpu(*p++);
		t = (const char *)p;
		p = (const u32 *)_ALIGN((unsigned long)p + sz, 4);
		printf("%*s%s", depth * shift, "", s);
		print_data(t, sz);
		printf(";\n");
	}
}

void ft_backtrack_node(struct ft_cxt *cxt)
{
	int i = 4;

	while (be32_to_cpu(*(u32 *) (cxt->p - i)) != OF_DT_END_NODE)
		i += 4;

	memmove (cxt->p - i, cxt->p, cxt->p_end - cxt->p);

	cxt->p_end -= i;
	cxt->p -= i;
}

void *ft_get_prop(void *bphp, const char *propname, int *szp)
{
	struct boot_param_header *bph = bphp;
	uint32_t *p_struct =
	    (uint32_t *) ((char *)bph + be32_to_cpu(bph->off_dt_struct));
	uint32_t *p_strings =
	    (uint32_t *) ((char *)bph + be32_to_cpu(bph->off_dt_strings));
	uint32_t version = be32_to_cpu(bph->version);
	uint32_t tag;
	uint32_t *p;
	char *s, *t;
	char *ss;
	int sz;
	static char path[256], prop[256];

	path[0] = '\0';

	p = p_struct;
	while ((tag = be32_to_cpu(*p++)) != OF_DT_END) {

		if (tag == OF_DT_BEGIN_NODE) {
			s = (char *)p;
			p = (uint32_t *) _ALIGN((unsigned long)p + strlen(s) +
						1, 4);
			strcat(path, s);
			strcat(path, "/");
			continue;
		}

		if (tag == OF_DT_END_NODE) {
			path[strlen(path) - 1] = '\0';
			ss = strrchr(path, '/');
			if (ss != NULL)
				ss[1] = '\0';
			continue;
		}

		if (tag == OF_DT_NOP)
			continue;

		if (tag != OF_DT_PROP)
			break;

		sz = be32_to_cpu(*p++);
		s = (char *)p_strings + be32_to_cpu(*p++);
		if (version < 0x10 && sz >= 8)
			p = (uint32_t *) _ALIGN((unsigned long)p, 8);
		t = (char *)p;
		p = (uint32_t *) _ALIGN((unsigned long)p + sz, 4);

		strcpy(prop, path);
		strcat(prop, s);

		if (strcmp(prop, propname) == 0) {
			*szp = sz;
			return t;
		}
	}

	return NULL;
}

/********************************************************************/

/* Function that returns a character from the environment */
extern uchar(*env_get_char) (int);

#define BDM(x)	{	.name = #x, .offset = offsetof(bd_t, bi_ ##x ) }

#ifdef CONFIG_OF_HAS_BD_T
static const struct {
	const char *name;
	int offset;
} bd_map[] = {
	BDM(memstart),
	BDM(memsize),
	BDM(flashstart),
	BDM(flashsize),
	BDM(flashoffset),
	BDM(sramstart),
	BDM(sramsize),
#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \
	|| defined(CONFIG_E500)
	BDM(immr_base),
#endif
#if defined(CONFIG_MPC5xxx)
	BDM(mbar_base),
#endif
#if defined(CONFIG_MPC83XX)
	BDM(immrbar),
#endif
#if defined(CONFIG_MPC8220)
	BDM(mbar_base),
	BDM(inpfreq),
	BDM(pcifreq),
	BDM(pevfreq),
	BDM(flbfreq),
	BDM(vcofreq),
#endif
	BDM(bootflags),
	BDM(ip_addr),
	BDM(intfreq),
	BDM(busfreq),
#ifdef CONFIG_CPM2
	BDM(cpmfreq),
	BDM(brgfreq),
	BDM(sccfreq),
	BDM(vco),
#endif
#if defined(CONFIG_MPC5xxx)
	BDM(ipbfreq),
	BDM(pcifreq),
#endif
	BDM(baudrate),
};
#endif

void ft_setup(void *blob, bd_t * bd, ulong initrd_start, ulong initrd_end)
{
	u32 *p;
	int len;
	struct ft_cxt cxt;
	ulong clock;
#if defined(CONFIG_OF_HAS_BAREBOX_ENV)
	int k, nxt;
#endif
#if defined(CONFIG_OF_HAS_BD_T)
	u8 *end;
#endif
#if defined(CONFIG_OF_HAS_BAREBOX_ENV) || defined(CONFIG_OF_HAS_BD_T)
	int i;
	static char tmpenv[256];
#endif

	/* disable OF tree; booting old kernel */
	if (getenv("disable_of") != NULL) {
		memcpy(blob, bd, sizeof(*bd));
		return;
	}

#ifdef DEBUG
	printf ("recieved oftree\n");
	ft_dump_blob(blob);
#endif

	ft_init_cxt(&cxt, blob);

	if (initrd_start && initrd_end)
		ft_add_rsvmap(&cxt, initrd_start, initrd_end - initrd_start + 1);

	/* back into root */
	ft_backtrack_node(&cxt);

#ifdef CONFIG_OF_HAS_BAREBOX_ENV
	ft_begin_node(&cxt, "barebox-env");

	for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
		char *s, *lval, *rval;

		for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) ;
		s = tmpenv;
		for (k = i; k < nxt && s < &tmpenv[sizeof(tmpenv) - 1]; ++k)
			*s++ = env_get_char(k);
		*s++ = '\0';
		lval = tmpenv;
		s = strchr(tmpenv, '=');
		if (s != NULL) {
			*s++ = '\0';
			rval = s;
		} else
			continue;
		ft_prop_str(&cxt, lval, rval);
	}

	ft_end_node(&cxt);
#endif

	ft_begin_node(&cxt, "chosen");
	ft_prop_str(&cxt, "name", "chosen");

	ft_prop_str(&cxt, "bootargs", getenv("bootargs"));
	ft_prop_int(&cxt, "linux,platform", 0x600);	/* what is this? */
	if (initrd_start && initrd_end) {
		ft_prop_int(&cxt, "linux,initrd-start", initrd_start);
		ft_prop_int(&cxt, "linux,initrd-end", initrd_end);
	}
#ifdef OF_STDOUT_PATH
	ft_prop_str(&cxt, "linux,stdout-path", OF_STDOUT_PATH);
#endif

	ft_end_node(&cxt);

	ft_end_node(&cxt);	/* end root */

	ft_end_tree(&cxt);
	ft_finalize_tree(&cxt);

#ifdef CONFIG_OF_HAS_BD_T
	/* paste the bd_t at the end of the flat tree */
	end = (char *)blob +
	    be32_to_cpu(((struct boot_param_header *)blob)->totalsize);
	memcpy(end, bd, sizeof(*bd));
#endif

#ifdef CONFIG_PPC

#ifdef CONFIG_OF_HAS_BD_T
	for (i = 0; i < sizeof(bd_map)/sizeof(bd_map[0]); i++) {
		uint32_t v;

		sprintf(tmpenv, "/bd_t/%s", bd_map[i].name);
		v = *(uint32_t *)((char *)bd + bd_map[i].offset);

		p = ft_get_prop(blob, tmpenv, &len);
		if (p != NULL)
			*p = cpu_to_be32(v);
	}

	p = ft_get_prop(blob, "/bd_t/enetaddr", &len);
	if (p != NULL)
		memcpy(p, bd->bi_enetaddr, 6);

	p = ft_get_prop(blob, "/bd_t/ethspeed", &len);
	if (p != NULL)
		*p = cpu_to_be32((uint32_t) bd->bi_ethspeed);
#endif

	clock = bd->bi_intfreq;
	p = ft_get_prop(blob, "/cpus/" OF_CPU "/clock-frequency", &len);
	if (p != NULL)
		*p = cpu_to_be32(clock);

#ifdef OF_TBCLK
	clock = OF_TBCLK;
	p = ft_get_prop(blob, "/cpus/" OF_CPU "/timebase-frequency", &len);
	if (p != NULL)
		*p = cpu_to_be32(clock);
#endif
#endif				/* __powerpc__ */

#ifdef CONFIG_OF_BOARD_SETUP
	ft_board_setup(blob, bd);
#endif

	/* in case the size changed in the platform code */
	ft_finalize_tree(&cxt);

#ifdef DEBUG
	printf("final OF-tree\n");
	ft_dump_blob(blob);
#endif
}

static int oftree_handler_cmdline_parse(struct image_data *data, int opt,
		char *optarg)
{
	switch(opt) {
	case 'o':
		printf("using oftree %s\n", optarg);
		data->oftree = optarg;
		return 0;
	default:
		return 1;
	}
}

static struct image_handler of_handler = {
	.cmdline_options = "o:",
	.cmdline_parse = oftree_handler_cmdline_parse,
	.help_string = " -o <oftree>    use oftree",
};

static int oftree_register_image_handler(void)
{
	return register_image_handler(&of_handler);
}

late_initcall(oftree_register_image_handler);

