/*
 * Big Endian PROM code for SNI RM machines
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2005-2006 Florian Lohoff (flo@rfc822.org)
 * Copyright (C) 2005-2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/console.h>

#include <asm/addrspace.h>
#include <asm/sni.h>
#include <asm/mipsprom.h>
#include <asm/mipsregs.h>
#include <asm/bootinfo.h>

/* special SNI prom calls */
/*
 * This does not exist in all proms - SINIX compares
 * the prom env variable "version" against "2.0008"
 * or greater. If lesser it tries to probe interesting
 * registers
 */
#define PROM_GET_MEMCONF	58
#define PROM_GET_HWCONF		61

#define PROM_VEC		(u64 *)CKSEG1ADDR(0x1fc00000)
#define PROM_ENTRY(x)		(PROM_VEC + (x))

#define ___prom_putchar		((int *(*)(int))PROM_ENTRY(PROM_PUTCHAR))
#define ___prom_getenv		((char *(*)(char *))PROM_ENTRY(PROM_GETENV))
#define ___prom_get_memconf	((void (*)(void *))PROM_ENTRY(PROM_GET_MEMCONF))
#define ___prom_get_hwconf	((u32 (*)(void))PROM_ENTRY(PROM_GET_HWCONF))

#ifdef CONFIG_64BIT

static u8 o32_stk[16384];
#define O32_STK	  &o32_stk[sizeof(o32_stk)]

#define __PROM_O32(fun, arg) fun arg __asm__(#fun); \
				     __asm__(#fun " = call_o32")

int   __PROM_O32(__prom_putchar, (int *(*)(int), void *, int));
char *__PROM_O32(__prom_getenv, (char *(*)(char *), void *, char *));
void  __PROM_O32(__prom_get_memconf, (void (*)(void *), void *, void *));
u32   __PROM_O32(__prom_get_hwconf, (u32 (*)(void), void *));

#define _prom_putchar(x)     __prom_putchar(___prom_putchar, O32_STK, x)
#define _prom_getenv(x)	     __prom_getenv(___prom_getenv, O32_STK, x)
#define _prom_get_memconf(x) __prom_get_memconf(___prom_get_memconf, O32_STK, x)
#define _prom_get_hwconf()   __prom_get_hwconf(___prom_get_hwconf, O32_STK)

#else
#define _prom_putchar(x)     ___prom_putchar(x)
#define _prom_getenv(x)	     ___prom_getenv(x)
#define _prom_get_memconf(x) ___prom_get_memconf(x)
#define _prom_get_hwconf(x)  ___prom_get_hwconf(x)
#endif

void prom_putchar(char c)
{
	_prom_putchar(c);
}


char *prom_getenv(char *s)
{
	return _prom_getenv(s);
}

void *prom_get_hwconf(void)
{
	u32 hwconf = _prom_get_hwconf();

	if (hwconf == 0xffffffff)
		return NULL;

	return (void *)CKSEG1ADDR(hwconf);
}

void __init prom_free_prom_memory(void)
{
}

/*
 * /proc/cpuinfo system type
 *
 */
char *system_type = "Unknown";
const char *get_system_type(void)
{
	return system_type;
}

static void __init sni_mem_init(void)
{
	int i, memsize;
	struct membank {
		u32		size;
		u32		base;
		u32		size2;
		u32		pad1;
		u32		pad2;
	} memconf[8];
	int brd_type = *(unsigned char *)SNI_IDPROM_BRDTYPE;


	/* MemSIZE from prom in 16MByte chunks */
	memsize = *((unsigned char *) SNI_IDPROM_MEMSIZE) * 16;

	pr_debug("IDProm memsize: %u MByte\n", memsize);

	/* get memory bank layout from prom */
	_prom_get_memconf(&memconf);

	pr_debug("prom_get_mem_conf memory configuration:\n");
	for (i = 0; i < 8 && memconf[i].size; i++) {
		if (brd_type == SNI_BRD_PCI_TOWER ||
		    brd_type == SNI_BRD_PCI_TOWER_CPLUS) {
			if (memconf[i].base >= 0x20000000 &&
			    memconf[i].base <  0x30000000)
				memconf[i].base -= 0x20000000;
		}
		pr_debug("Bank%d: %08x @ %08x\n", i,
			memconf[i].size, memconf[i].base);
		add_memory_region(memconf[i].base, memconf[i].size,
				  BOOT_MEM_RAM);
	}
}

void __init prom_init(void)
{
	int argc = fw_arg0;
	u32 *argv = (u32 *)CKSEG0ADDR(fw_arg1);
	int i;

	sni_mem_init();

	/* copy prom cmdline parameters to kernel cmdline */
	for (i = 1; i < argc; i++) {
		strcat(arcs_cmdline, (char *)CKSEG0ADDR(argv[i]));
		if (i < (argc - 1))
			strcat(arcs_cmdline, " ");
	}
}
