/*
 *  Early boot support code for BootX bootloader
 *
 *  Copyright (C) 2005 Ben. Herrenschmidt (benh@kernel.crashing.org)
 *
 *  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.
 */

#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/version.h>
#include <asm/sections.h>
#include <asm/prom.h>
#include <asm/page.h>
#include <asm/bootx.h>
#include <asm/bootinfo.h>
#include <asm/btext.h>
#include <asm/io.h>

#undef DEBUG
#define SET_BOOT_BAT

#ifdef DEBUG
#define DBG(fmt...) do { bootx_printf(fmt); } while(0)
#else
#define DBG(fmt...) do { } while(0)
#endif

extern void __start(unsigned long r3, unsigned long r4, unsigned long r5);

static unsigned long __initdata bootx_dt_strbase;
static unsigned long __initdata bootx_dt_strend;
static unsigned long __initdata bootx_node_chosen;
static boot_infos_t * __initdata bootx_info;
static char __initdata bootx_disp_path[256];

/* Is boot-info compatible ? */
#define BOOT_INFO_IS_COMPATIBLE(bi) \
	((bi)->compatible_version <= BOOT_INFO_VERSION)
#define BOOT_INFO_IS_V2_COMPATIBLE(bi)	((bi)->version >= 2)
#define BOOT_INFO_IS_V4_COMPATIBLE(bi)	((bi)->version >= 4)

#ifdef CONFIG_BOOTX_TEXT
static void __init bootx_printf(const char *format, ...)
{
	const char *p, *q, *s;
	va_list args;
	unsigned long v;

	va_start(args, format);
	for (p = format; *p != 0; p = q) {
		for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
			;
		if (q > p)
			btext_drawtext(p, q - p);
		if (*q == 0)
			break;
		if (*q == '\n') {
			++q;
			btext_flushline();
			btext_drawstring("\r\n");
			btext_flushline();
			continue;
		}
		++q;
		if (*q == 0)
			break;
		switch (*q) {
		case 's':
			++q;
			s = va_arg(args, const char *);
			if (s == NULL)
				s = "<NULL>";
			btext_drawstring(s);
			break;
		case 'x':
			++q;
			v = va_arg(args, unsigned long);
			btext_drawhex(v);
			break;
		}
	}
}
#else /* CONFIG_BOOTX_TEXT */
static void __init bootx_printf(const char *format, ...) {}
#endif /* CONFIG_BOOTX_TEXT */

static void * __init bootx_early_getprop(unsigned long base,
					 unsigned long node,
					 char *prop)
{
	struct bootx_dt_node *np = (struct bootx_dt_node *)(base + node);
	u32 *ppp = &np->properties;

	while(*ppp) {
		struct bootx_dt_prop *pp =
			(struct bootx_dt_prop *)(base + *ppp);

		if (strcmp((char *)((unsigned long)pp->name + base),
			   prop) == 0) {
			return (void *)((unsigned long)pp->value + base);
		}
		ppp = &pp->next;
	}
	return NULL;
}

#define dt_push_token(token, mem) \
	do { \
		*(mem) = _ALIGN_UP(*(mem),4); \
		*((u32 *)*(mem)) = token; \
		*(mem) += 4; \
	} while(0)

static unsigned long __init bootx_dt_find_string(char *str)
{
	char *s, *os;

	s = os = (char *)bootx_dt_strbase;
	s += 4;
	while (s <  (char *)bootx_dt_strend) {
		if (strcmp(s, str) == 0)
			return s - os;
		s += strlen(s) + 1;
	}
	return 0;
}

static void __init bootx_dt_add_prop(char *name, void *data, int size,
				  unsigned long *mem_end)
{
	unsigned long soff = bootx_dt_find_string(name);
	if (data == NULL)
		size = 0;
	if (soff == 0) {
		bootx_printf("WARNING: Can't find string index for <%s>\n",
			     name);
		return;
	}
	if (size > 0x20000) {
		bootx_printf("WARNING: ignoring large property ");
		bootx_printf("%s length 0x%x\n", name, size);
		return;
	}
	dt_push_token(OF_DT_PROP, mem_end);
	dt_push_token(size, mem_end);
	dt_push_token(soff, mem_end);

	/* push property content */
	if (size && data) {
		memcpy((void *)*mem_end, data, size);
		*mem_end = _ALIGN_UP(*mem_end + size, 4);
	}
}

static void __init bootx_add_chosen_props(unsigned long base,
					  unsigned long *mem_end)
{
	u32 val;

	if (bootx_info->kernelParamsOffset) {
		char *args = (char *)((unsigned long)bootx_info) +
			bootx_info->kernelParamsOffset;
		bootx_dt_add_prop("bootargs", args, strlen(args) + 1, mem_end);
	}
	if (bootx_info->ramDisk) {
		val = ((unsigned long)bootx_info) + bootx_info->ramDisk;
		bootx_dt_add_prop("linux,initrd-start", &val, 4, mem_end);
		val += bootx_info->ramDiskSize;
		bootx_dt_add_prop("linux,initrd-end", &val, 4, mem_end);
	}
	if (strlen(bootx_disp_path))
		bootx_dt_add_prop("linux,stdout-path", bootx_disp_path,
				  strlen(bootx_disp_path) + 1, mem_end);
}

static void __init bootx_add_display_props(unsigned long base,
					   unsigned long *mem_end)
{
	bootx_dt_add_prop("linux,boot-display", NULL, 0, mem_end);
	bootx_dt_add_prop("linux,opened", NULL, 0, mem_end);
}

static void __init bootx_dt_add_string(char *s, unsigned long *mem_end)
{
	unsigned int l = strlen(s) + 1;
	memcpy((void *)*mem_end, s, l);
	bootx_dt_strend = *mem_end = *mem_end + l;
}

static void __init bootx_scan_dt_build_strings(unsigned long base,
					       unsigned long node,
					       unsigned long *mem_end)
{
	struct bootx_dt_node *np = (struct bootx_dt_node *)(base + node);
	u32 *cpp, *ppp = &np->properties;
	unsigned long soff;
	char *namep;

	/* Keep refs to known nodes */
	namep = np->full_name ? (char *)(base + np->full_name) : NULL;
       	if (namep == NULL) {
		bootx_printf("Node without a full name !\n");
		namep = "";
	}
	DBG("* strings: %s\n", namep);

	if (!strcmp(namep, "/chosen")) {
		DBG(" detected /chosen ! adding properties names !\n");
		bootx_dt_add_string("linux,platform", mem_end);
		bootx_dt_add_string("linux,stdout-path", mem_end);
		bootx_dt_add_string("linux,initrd-start", mem_end);
		bootx_dt_add_string("linux,initrd-end", mem_end);
		bootx_dt_add_string("bootargs", mem_end);
		bootx_node_chosen = node;
	}
	if (node == bootx_info->dispDeviceRegEntryOffset) {
		DBG(" detected display ! adding properties names !\n");
		bootx_dt_add_string("linux,boot-display", mem_end);
		bootx_dt_add_string("linux,opened", mem_end);
		strncpy(bootx_disp_path, namep, 255);
	}

	/* get and store all property names */
	while (*ppp) {
		struct bootx_dt_prop *pp =
			(struct bootx_dt_prop *)(base + *ppp);

		namep = pp->name ? (char *)(base + pp->name) : NULL;
 		if (namep == NULL || strcmp(namep, "name") == 0)
 			goto next;
		/* get/create string entry */
		soff = bootx_dt_find_string(namep);
		if (soff == 0)
			bootx_dt_add_string(namep, mem_end);
	next:
		ppp = &pp->next;
	}

	/* do all our children */
	cpp = &np->child;
	while(*cpp) {
		np = (struct bootx_dt_node *)(base + *cpp);
		bootx_scan_dt_build_strings(base, *cpp, mem_end);
		cpp = &np->sibling;
	}
}

static void __init bootx_scan_dt_build_struct(unsigned long base,
					      unsigned long node,
					      unsigned long *mem_end)
{
	struct bootx_dt_node *np = (struct bootx_dt_node *)(base + node);
	u32 *cpp, *ppp = &np->properties;
	char *namep, *p, *ep, *lp;
	int l;

	dt_push_token(OF_DT_BEGIN_NODE, mem_end);

	/* get the node's full name */
	namep = np->full_name ? (char *)(base + np->full_name) : NULL;
	if (namep == NULL)
		namep = "";
	l = strlen(namep);

	DBG("* struct: %s\n", namep);

	/* Fixup an Apple bug where they have bogus \0 chars in the
	 * middle of the path in some properties, and extract
	 * the unit name (everything after the last '/').
	 */
	memcpy((void *)*mem_end, namep, l + 1);
	namep = (char *)*mem_end;
	for (lp = p = namep, ep = namep + l; p < ep; p++) {
		if (*p == '/')
			lp = namep;
		else if (*p != 0)
			*lp++ = *p;
	}
	*lp = 0;
	*mem_end = _ALIGN_UP((unsigned long)lp + 1, 4);

	/* get and store all properties */
	while (*ppp) {
		struct bootx_dt_prop *pp =
			(struct bootx_dt_prop *)(base + *ppp);

		namep = pp->name ? (char *)(base + pp->name) : NULL;
		/* Skip "name" */
 		if (namep == NULL || !strcmp(namep, "name"))
 			goto next;
		/* Skip "bootargs" in /chosen too as we replace it */
		if (node == bootx_node_chosen && !strcmp(namep, "bootargs"))
			goto next;

		/* push property head */
		bootx_dt_add_prop(namep,
				  pp->value ? (void *)(base + pp->value): NULL,
				  pp->length, mem_end);
	next:
		ppp = &pp->next;
	}

	if (node == bootx_node_chosen)
		bootx_add_chosen_props(base, mem_end);
	if (node == bootx_info->dispDeviceRegEntryOffset)
		bootx_add_display_props(base, mem_end);

	/* do all our children */
	cpp = &np->child;
	while(*cpp) {
		np = (struct bootx_dt_node *)(base + *cpp);
		bootx_scan_dt_build_struct(base, *cpp, mem_end);
		cpp = &np->sibling;
	}

	dt_push_token(OF_DT_END_NODE, mem_end);
}

static unsigned long __init bootx_flatten_dt(unsigned long start)
{
	boot_infos_t *bi = bootx_info;
	unsigned long mem_start, mem_end;
	struct boot_param_header *hdr;
	unsigned long base;
	u64 *rsvmap;

	/* Start using memory after the big blob passed by BootX, get
	 * some space for the header
	 */
	mem_start = mem_end = _ALIGN_UP(((unsigned long)bi) + start, 4);
	DBG("Boot params header at: %x\n", mem_start);
	hdr = (struct boot_param_header *)mem_start;
	mem_end += sizeof(struct boot_param_header);
	rsvmap = (u64 *)(_ALIGN_UP(mem_end, 8));
	hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - mem_start;
	mem_end = ((unsigned long)rsvmap) + 8 * sizeof(u64);

	/* Get base of tree */
	base = ((unsigned long)bi) + bi->deviceTreeOffset;

	/* Build string array */
	DBG("Building string array at: %x\n", mem_end);
	DBG("Device Tree Base=%x\n", base);
	bootx_dt_strbase = mem_end;
	mem_end += 4;
	bootx_dt_strend = mem_end;
	bootx_scan_dt_build_strings(base, 4, &mem_end);
	hdr->off_dt_strings = bootx_dt_strbase - mem_start;
	hdr->dt_strings_size = bootx_dt_strend - bootx_dt_strbase;

	/* Build structure */
	mem_end = _ALIGN(mem_end, 16);
	DBG("Building device tree structure at: %x\n", mem_end);
	hdr->off_dt_struct = mem_end - mem_start;
	bootx_scan_dt_build_struct(base, 4, &mem_end);
	dt_push_token(OF_DT_END, &mem_end);

	/* Finish header */
	hdr->boot_cpuid_phys = 0;
	hdr->magic = OF_DT_HEADER;
	hdr->totalsize = mem_end - mem_start;
	hdr->version = OF_DT_VERSION;
	/* Version 16 is not backward compatible */
	hdr->last_comp_version = 0x10;

	/* Reserve the whole thing and copy the reserve map in, we
	 * also bump mem_reserve_cnt to cause further reservations to
	 * fail since it's too late.
	 */
	mem_end = _ALIGN(mem_end, PAGE_SIZE);
	DBG("End of boot params: %x\n", mem_end);
	rsvmap[0] = mem_start;
	rsvmap[1] = mem_end;
	rsvmap[2] = 0;
	rsvmap[3] = 0;

	return (unsigned long)hdr;
}


#ifdef CONFIG_BOOTX_TEXT
static void __init btext_welcome(boot_infos_t *bi)
{
	unsigned long flags;
	unsigned long pvr;

	bootx_printf("Welcome to Linux, kernel " UTS_RELEASE "\n");
	bootx_printf("\nlinked at        : 0x%x", KERNELBASE);
	bootx_printf("\nframe buffer at  : 0x%x", bi->dispDeviceBase);
	bootx_printf(" (phys), 0x%x", bi->logicalDisplayBase);
	bootx_printf(" (log)");
	bootx_printf("\nklimit           : 0x%x",(unsigned long)klimit);
	bootx_printf("\nboot_info at     : 0x%x", bi);
	__asm__ __volatile__ ("mfmsr %0" : "=r" (flags));
	bootx_printf("\nMSR              : 0x%x", flags);
	__asm__ __volatile__ ("mfspr %0, 287" : "=r" (pvr));
	bootx_printf("\nPVR              : 0x%x", pvr);
	pvr >>= 16;
	if (pvr > 1) {
	    __asm__ __volatile__ ("mfspr %0, 1008" : "=r" (flags));
	    bootx_printf("\nHID0             : 0x%x", flags);
	}
	if (pvr == 8 || pvr == 12 || pvr == 0x800c) {
	    __asm__ __volatile__ ("mfspr %0, 1019" : "=r" (flags));
	    bootx_printf("\nICTC             : 0x%x", flags);
	}
#ifdef DEBUG
	bootx_printf("\n\n");
	bootx_printf("bi->deviceTreeOffset   : 0x%x\n",
		     bi->deviceTreeOffset);
	bootx_printf("bi->deviceTreeSize     : 0x%x\n",
		     bi->deviceTreeSize);
#endif
	bootx_printf("\n\n");
}
#endif /* CONFIG_BOOTX_TEXT */

void __init bootx_init(unsigned long r3, unsigned long r4)
{
	boot_infos_t *bi = (boot_infos_t *) r4;
	unsigned long hdr;
	unsigned long space;
	unsigned long ptr, x;
	char *model;
	unsigned long offset = reloc_offset();

	reloc_got2(offset);

	bootx_info = bi;

	/* We haven't cleared any bss at this point, make sure
	 * what we need is initialized
	 */
	bootx_dt_strbase = bootx_dt_strend = 0;
	bootx_node_chosen = 0;
	bootx_disp_path[0] = 0;

	if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
		bi->logicalDisplayBase = bi->dispDeviceBase;

#ifdef CONFIG_BOOTX_TEXT
	btext_setup_display(bi->dispDeviceRect[2] - bi->dispDeviceRect[0],
			    bi->dispDeviceRect[3] - bi->dispDeviceRect[1],
			    bi->dispDeviceDepth, bi->dispDeviceRowBytes,
			    (unsigned long)bi->logicalDisplayBase);
	btext_clearscreen();
	btext_flushscreen();
#endif /* CONFIG_BOOTX_TEXT */

	/*
	 * Test if boot-info is compatible.  Done only in config
	 * CONFIG_BOOTX_TEXT since there is nothing much we can do
	 * with an incompatible version, except display a message
	 * and eventually hang the processor...
	 *
	 * I'll try to keep enough of boot-info compatible in the
	 * future to always allow display of this message;
	 */
	if (!BOOT_INFO_IS_COMPATIBLE(bi)) {
		bootx_printf(" !!! WARNING - Incompatible version"
			     " of BootX !!!\n\n\n");
		for (;;)
			;
	}
	if (bi->architecture != BOOT_ARCH_PCI) {
		bootx_printf(" !!! WARNING - Usupported machine"
			     " architecture !\n");
		for (;;)
			;
	}

#ifdef CONFIG_BOOTX_TEXT
	btext_welcome(bi);
#endif
	/* New BootX enters kernel with MMU off, i/os are not allowed
	 * here. This hack will have been done by the boostrap anyway.
	 */
	if (bi->version < 4) {
		/*
		 * XXX If this is an iMac, turn off the USB controller.
		 */
		model = (char *) bootx_early_getprop(r4 + bi->deviceTreeOffset,
						     4, "model");
		if (model
		    && (strcmp(model, "iMac,1") == 0
			|| strcmp(model, "PowerMac1,1") == 0)) {
			bootx_printf("iMac,1 detected, shutting down USB \n");
			out_le32((unsigned __iomem *)0x80880008, 1);	/* XXX */
		}
	}

	/* Get a pointer that points above the device tree, args, ramdisk,
	 * etc... to use for generating the flattened tree
	 */
	if (bi->version < 5) {
		space = bi->deviceTreeOffset + bi->deviceTreeSize;
		if (bi->ramDisk)
			space = bi->ramDisk + bi->ramDiskSize;
	} else
		space = bi->totalParamsSize;

	bootx_printf("Total space used by parameters & ramdisk: %x \n", space);

	/* New BootX will have flushed all TLBs and enters kernel with
	 * MMU switched OFF, so this should not be useful anymore.
	 */
	if (bi->version < 4) {
		bootx_printf("Touching pages...\n");

		/*
		 * Touch each page to make sure the PTEs for them
		 * are in the hash table - the aim is to try to avoid
		 * getting DSI exceptions while copying the kernel image.
		 */
		for (ptr = ((unsigned long) &_stext) & PAGE_MASK;
		     ptr < (unsigned long)bi + space; ptr += PAGE_SIZE)
			x = *(volatile unsigned long *)ptr;
	}

	/* Ok, now we need to generate a flattened device-tree to pass
	 * to the kernel
	 */
	bootx_printf("Preparing boot params...\n");

	hdr = bootx_flatten_dt(space);

#ifdef CONFIG_BOOTX_TEXT
#ifdef SET_BOOT_BAT
	bootx_printf("Preparing BAT...\n");
	btext_prepare_BAT();
#else
	btext_unmap();
#endif
#endif

	reloc_got2(-offset);

	__start(hdr, KERNELBASE + offset, 0);
}
