// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/linkage.h>
#include <linux/mm.h>
#include <linux/memblock.h>
#include <linux/pm.h>
#include <linux/smp.h>

#include <asm/bootinfo.h>
#include <asm/reboot.h>
#include <asm/setup.h>
#include <asm/sibyte/board.h>
#include <asm/smp-ops.h>

#include <asm/fw/cfe/cfe_api.h>
#include <asm/fw/cfe/cfe_error.h>

/* Max ram addressable in 32-bit segments */
#ifdef CONFIG_64BIT
#define MAX_RAM_SIZE (~0ULL)
#else
#ifdef CONFIG_HIGHMEM
#ifdef CONFIG_PHYS_ADDR_T_64BIT
#define MAX_RAM_SIZE (~0ULL)
#else
#define MAX_RAM_SIZE (0xffffffffULL)
#endif
#else
#define MAX_RAM_SIZE (0x1fffffffULL)
#endif
#endif

int cfe_cons_handle;

#ifdef CONFIG_BLK_DEV_INITRD
extern unsigned long initrd_start, initrd_end;
#endif

static void __noreturn cfe_linux_exit(void *arg)
{
	int warm = *(int *)arg;

	if (smp_processor_id()) {
		static int reboot_smp;

		/* Don't repeat the process from another CPU */
		if (!reboot_smp) {
			/* Get CPU 0 to do the cfe_exit */
			reboot_smp = 1;
			smp_call_function(cfe_linux_exit, arg, 0);
		}
	} else {
		printk("Passing control back to CFE...\n");
		cfe_exit(warm, 0);
		printk("cfe_exit returned??\n");
	}
	while (1);
}

static void __noreturn cfe_linux_restart(char *command)
{
	static const int zero;

	cfe_linux_exit((void *)&zero);
}

static void __noreturn cfe_linux_halt(void)
{
	static const int one = 1;

	cfe_linux_exit((void *)&one);
}

static __init void prom_meminit(void)
{
	u64 addr, size, type; /* regardless of PHYS_ADDR_T_64BIT */
	int mem_flags = 0;
	unsigned int idx;
	int rd_flag;
#ifdef CONFIG_BLK_DEV_INITRD
	unsigned long initrd_pstart;
	unsigned long initrd_pend;

	initrd_pstart = CPHYSADDR(initrd_start);
	initrd_pend = CPHYSADDR(initrd_end);
	if (initrd_start &&
	    ((initrd_pstart > MAX_RAM_SIZE)
	     || (initrd_pend > MAX_RAM_SIZE))) {
		panic("initrd out of addressable memory");
	}

#endif /* INITRD */

	for (idx = 0; cfe_enummem(idx, mem_flags, &addr, &size, &type) != CFE_ERR_NOMORE;
	     idx++) {
		rd_flag = 0;
		if (type == CFE_MI_AVAILABLE) {
			/*
			 * See if this block contains (any portion of) the
			 * ramdisk
			 */
#ifdef CONFIG_BLK_DEV_INITRD
			if (initrd_start) {
				if ((initrd_pstart > addr) &&
				    (initrd_pstart < (addr + size))) {
					memblock_add(addr,
						     initrd_pstart - addr);
					rd_flag = 1;
				}
				if ((initrd_pend > addr) &&
				    (initrd_pend < (addr + size))) {
					memblock_add(initrd_pend,
						(addr + size) - initrd_pend);
					rd_flag = 1;
				}
			}
#endif
			if (!rd_flag) {
				if (addr > MAX_RAM_SIZE)
					continue;
				if (addr+size > MAX_RAM_SIZE)
					size = MAX_RAM_SIZE - (addr+size) + 1;
				/*
				 * memcpy/__copy_user prefetch, which
				 * will cause a bus error for
				 * KSEG/KUSEG addrs not backed by RAM.
				 * Hence, reserve some padding for the
				 * prefetch distance.
				 */
				if (size > 512)
					size -= 512;
				memblock_add(addr, size);
			}
		}
	}
#ifdef CONFIG_BLK_DEV_INITRD
	if (initrd_start) {
		memblock_add(initrd_pstart, initrd_pend - initrd_pstart);
		memblock_reserve(initrd_pstart, initrd_pend - initrd_pstart);
	}
#endif
}

#ifdef CONFIG_BLK_DEV_INITRD
static int __init initrd_setup(char *str)
{
	char rdarg[64];
	int idx;
	char *tmp, *endptr;
	unsigned long initrd_size;

	/* Make a copy of the initrd argument so we can smash it up here */
	for (idx = 0; idx < sizeof(rdarg)-1; idx++) {
		if (!str[idx] || (str[idx] == ' ')) break;
		rdarg[idx] = str[idx];
	}

	rdarg[idx] = 0;
	str = rdarg;

	/*
	 *Initrd location comes in the form "<hex size of ramdisk in bytes>@<location in memory>"
	 *  e.g. initrd=3abfd@80010000.	 This is set up by the loader.
	 */
	for (tmp = str; *tmp != '@'; tmp++) {
		if (!*tmp) {
			goto fail;
		}
	}
	*tmp = 0;
	tmp++;
	if (!*tmp) {
		goto fail;
	}
	initrd_size = simple_strtoul(str, &endptr, 16);
	if (*endptr) {
		*(tmp-1) = '@';
		goto fail;
	}
	*(tmp-1) = '@';
	initrd_start = simple_strtoul(tmp, &endptr, 16);
	if (*endptr) {
		goto fail;
	}
	initrd_end = initrd_start + initrd_size;
	printk("Found initrd of %lx@%lx\n", initrd_size, initrd_start);
	return 1;
 fail:
	printk("Bad initrd argument.  Disabling initrd\n");
	initrd_start = 0;
	initrd_end = 0;
	return 1;
}

#endif

extern const struct plat_smp_ops sb_smp_ops;
extern const struct plat_smp_ops bcm1480_smp_ops;

/*
 * prom_init is called just after the cpu type is determined, from setup_arch()
 */
void __init prom_init(void)
{
	uint64_t cfe_ept, cfe_handle;
	unsigned int cfe_eptseal;
	int argc = fw_arg0;
	char **envp = (char **) fw_arg2;
	int *prom_vec = (int *) fw_arg3;

	_machine_restart   = cfe_linux_restart;
	_machine_halt	   = cfe_linux_halt;
	pm_power_off = cfe_linux_halt;

	/*
	 * Check if a loader was used; if NOT, the 4 arguments are
	 * what CFE gives us (handle, 0, EPT and EPTSEAL)
	 */
	if (argc < 0) {
		cfe_handle = (uint64_t)(long)argc;
		cfe_ept = (long)envp;
		cfe_eptseal = (uint32_t)(unsigned long)prom_vec;
	} else {
		if ((int32_t)(long)prom_vec < 0) {
			/*
			 * Old loader; all it gives us is the handle,
			 * so use the "known" entrypoint and assume
			 * the seal.
			 */
			cfe_handle = (uint64_t)(long)prom_vec;
			cfe_ept = (uint64_t)((int32_t)0x9fc00500);
			cfe_eptseal = CFE_EPTSEAL;
		} else {
			/*
			 * Newer loaders bundle the handle/ept/eptseal
			 * Note: prom_vec is in the loader's useg
			 * which is still alive in the TLB.
			 */
			cfe_handle = (uint64_t)((int32_t *)prom_vec)[0];
			cfe_ept = (uint64_t)((int32_t *)prom_vec)[2];
			cfe_eptseal = (unsigned int)((uint32_t *)prom_vec)[3];
		}
	}
	if (cfe_eptseal != CFE_EPTSEAL) {
		/* too early for panic to do any good */
		printk("CFE's entrypoint seal doesn't match. Spinning.");
		while (1) ;
	}
	cfe_init(cfe_handle, cfe_ept);
	/*
	 * Get the handle for (at least) prom_putchar, possibly for
	 * boot console
	 */
	cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
	if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, COMMAND_LINE_SIZE) < 0) {
		if (argc >= 0) {
			/* The loader should have set the command line */
			/* too early for panic to do any good */
			printk("LINUX_CMDLINE not defined in cfe.");
			while (1) ;
		}
	}

#ifdef CONFIG_BLK_DEV_INITRD
	{
		char *ptr;
		/* Need to find out early whether we've got an initrd.	So scan
		   the list looking now */
		for (ptr = arcs_cmdline; *ptr; ptr++) {
			while (*ptr == ' ') {
				ptr++;
			}
			if (!strncmp(ptr, "initrd=", 7)) {
				initrd_setup(ptr+7);
				break;
			} else {
				while (*ptr && (*ptr != ' ')) {
					ptr++;
				}
			}
		}
	}
#endif /* CONFIG_BLK_DEV_INITRD */

	/* Not sure this is needed, but it's the safe way. */
	arcs_cmdline[COMMAND_LINE_SIZE-1] = 0;

	prom_meminit();

#if defined(CONFIG_SIBYTE_BCM112X) || defined(CONFIG_SIBYTE_SB1250)
	register_smp_ops(&sb_smp_ops);
#endif
#ifdef CONFIG_SIBYTE_BCM1x80
	register_smp_ops(&bcm1480_smp_ops);
#endif
}

void prom_putchar(char c)
{
	int ret;

	while ((ret = cfe_write(cfe_cons_handle, &c, 1)) == 0)
		;
}
