/*
 * allow a console to be used for early printk
 * derived from arch/x86/kernel/early_printk.c
 *
 * Copyright 2007-2009 Analog Devices Inc.
 *
 * Licensed under the GPL-2
 */

#include <linux/kernel.h>
#include <linux/sched/debug.h>
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/console.h>
#include <linux/string.h>
#include <linux/reboot.h>
#include <asm/blackfin.h>
#include <asm/irq_handler.h>
#include <asm/early_printk.h>

#ifdef CONFIG_SERIAL_BFIN
extern struct console *bfin_earlyserial_init(unsigned int port,
						unsigned int cflag);
#endif
#ifdef CONFIG_BFIN_JTAG_COMM
extern struct console *bfin_jc_early_init(void);
#endif

/* Default console */
#define DEFAULT_PORT 0
#define DEFAULT_CFLAG CS8|B57600

/* Default console for early crashes */
#define DEFAULT_EARLY_PORT "serial,uart0,57600"

#ifdef CONFIG_SERIAL_CORE
/* What should get here is "0,57600" */
static struct console * __init earlyserial_init(char *buf)
{
	int baud, bit;
	char parity;
	unsigned int serial_port = DEFAULT_PORT;
	unsigned int cflag = DEFAULT_CFLAG;

	serial_port = simple_strtoul(buf, &buf, 10);
	buf++;

	cflag = 0;
	baud = simple_strtoul(buf, &buf, 10);
	switch (baud) {
	case 1200:
		cflag |= B1200;
		break;
	case 2400:
		cflag |= B2400;
		break;
	case 4800:
		cflag |= B4800;
		break;
	case 9600:
		cflag |= B9600;
		break;
	case 19200:
		cflag |= B19200;
		break;
	case 38400:
		cflag |= B38400;
		break;
	case 115200:
		cflag |= B115200;
		break;
	default:
		cflag |= B57600;
	}

	parity = buf[0];
	buf++;
	switch (parity) {
	case 'e':
		cflag |= PARENB;
		break;
	case 'o':
		cflag |= PARODD;
		break;
	}

	bit = simple_strtoul(buf, &buf, 10);
	switch (bit) {
	case 5:
		cflag |= CS5;
		break;
	case 6:
		cflag |= CS6;
		break;
	case 7:
		cflag |= CS7;
		break;
	default:
		cflag |= CS8;
	}

#ifdef CONFIG_SERIAL_BFIN
	return bfin_earlyserial_init(serial_port, cflag);
#else
	return NULL;
#endif

}
#endif

int __init setup_early_printk(char *buf)
{

	/* Crashing in here would be really bad, so check both the var
	   and the pointer before we start using it
	 */
	if (!buf)
		return 0;

	if (!*buf)
		return 0;

	if (early_console != NULL)
		return 0;

#ifdef CONFIG_SERIAL_BFIN
	/* Check for Blackfin Serial */
	if (!strncmp(buf, "serial,uart", 11)) {
		buf += 11;
		early_console = earlyserial_init(buf);
	}
#endif

#ifdef CONFIG_BFIN_JTAG_COMM
	/* Check for Blackfin JTAG */
	if (!strncmp(buf, "jtag", 4)) {
		buf += 4;
		early_console = bfin_jc_early_init();
	}
#endif

#ifdef CONFIG_FB
		/* TODO: add framebuffer console support */
#endif

	if (likely(early_console)) {
		early_console->flags |= CON_BOOT;

		register_console(early_console);
		printk(KERN_INFO "early printk enabled on %s%d\n",
			early_console->name,
			early_console->index);
	}

	return 0;
}

/*
 * Set up a temporary Event Vector Table, so if something bad happens before
 * the kernel is fully started, it doesn't vector off into somewhere we don't
 * know
 */

asmlinkage void __init init_early_exception_vectors(void)
{
	u32 evt;
	SSYNC();

	/*
	 * This starts up the shadow buffer, incase anything crashes before
	 * setup arch
	 */
	mark_shadow_error();
	early_shadow_puts(linux_banner);
	early_shadow_stamp();

	if (CPUID != bfin_cpuid()) {
		early_shadow_puts("Running on wrong machine type, expected");
		early_shadow_reg(CPUID, 16);
		early_shadow_puts(", but running on");
		early_shadow_reg(bfin_cpuid(), 16);
		early_shadow_puts("\n");
	}

	/* cannot program in software:
	 * evt0 - emulation (jtag)
	 * evt1 - reset
	 */
	for (evt = EVT2; evt <= EVT15; evt += 4)
		bfin_write32(evt, early_trap);
	CSYNC();

	/* Set all the return from interrupt, exception, NMI to a known place
	 * so if we do a RETI, RETX or RETN by mistake - we go somewhere known
	 * Note - don't change RETS - we are in a subroutine, or
	 * RETE - since it might screw up if emulator is attached
	 */
	asm("\tRETI = %0; RETX = %0; RETN = %0;\n"
		: : "p"(early_trap));

}

__attribute__((__noreturn__))
asmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr)
{
	/* This can happen before the uart is initialized, so initialize
	 * the UART now (but only if we are running on the processor we think
	 * we are compiled for - otherwise we write to MMRs that don't exist,
	 * and cause other problems. Nothing comes out the UART, but it does
	 * end up in the __buf_log.
	 */
	if (likely(early_console == NULL) && CPUID == bfin_cpuid())
		setup_early_printk(DEFAULT_EARLY_PORT);

	if (!shadow_console_enabled()) {
		/* crap - we crashed before setup_arch() */
		early_shadow_puts("panic before setup_arch\n");
		early_shadow_puts("IPEND:");
		early_shadow_reg(fp->ipend, 16);
		if (fp->seqstat & SEQSTAT_EXCAUSE) {
			early_shadow_puts("\nEXCAUSE:");
			early_shadow_reg(fp->seqstat & SEQSTAT_EXCAUSE, 8);
		}
		if (fp->seqstat & SEQSTAT_HWERRCAUSE) {
			early_shadow_puts("\nHWERRCAUSE:");
			early_shadow_reg(
				(fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14, 8);
		}
		early_shadow_puts("\nErr @");
		if (fp->ipend & EVT_EVX)
			early_shadow_reg(fp->retx, 32);
		else
			early_shadow_reg(fp->pc, 32);
#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
		early_shadow_puts("\nTrace:");
		if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) {
			while (bfin_read_TBUFSTAT() & TBUFCNT) {
				early_shadow_puts("\nT  :");
				early_shadow_reg(bfin_read_TBUF(), 32);
				early_shadow_puts("\n S :");
				early_shadow_reg(bfin_read_TBUF(), 32);
			}
		}
#endif
		early_shadow_puts("\nUse bfin-elf-addr2line to determine "
			"function names\n");
		/*
		 * We should panic(), but we can't - since panic calls printk,
		 * and printk uses memcpy.
		 * we want to reboot, but if the machine type is different,
		 * can't due to machine specific reboot sequences
		 */
		if (CPUID == bfin_cpuid()) {
			early_shadow_puts("Trying to restart\n");
			machine_restart("");
		}

		early_shadow_puts("Halting, since it is not safe to restart\n");
		while (1)
			asm volatile ("EMUEXCPT; IDLE;\n");

	} else {
		printk(KERN_EMERG "Early panic\n");
		show_regs(fp);
		dump_bfin_trace_buffer();
	}

	panic("Died early");
}

early_param("earlyprintk", setup_early_printk);
