#include <linux/console.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/screen_info.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/fcntl.h>
#include <asm/setup.h>
#include <xen/hvc-console.h>

/* Simple VGA output */
#define VGABASE		(__ISA_IO_base + 0xb8000)

static int max_ypos = 25, max_xpos = 80;
static int current_ypos = 25, current_xpos = 0;

static void early_vga_write(struct console *con, const char *str, unsigned n)
{
	char c;
	int  i, k, j;

	while ((c = *str++) != '\0' && n-- > 0) {
		if (current_ypos >= max_ypos) {
			/* scroll 1 line up */
			for (k = 1, j = 0; k < max_ypos; k++, j++) {
				for (i = 0; i < max_xpos; i++) {
					writew(readw(VGABASE+2*(max_xpos*k+i)),
					       VGABASE + 2*(max_xpos*j + i));
				}
			}
			for (i = 0; i < max_xpos; i++)
				writew(0x720, VGABASE + 2*(max_xpos*j + i));
			current_ypos = max_ypos-1;
		}
		if (c == '\n') {
			current_xpos = 0;
			current_ypos++;
		} else if (c != '\r')  {
			writew(((0x7 << 8) | (unsigned short) c),
			       VGABASE + 2*(max_xpos*current_ypos +
						current_xpos++));
			if (current_xpos >= max_xpos) {
				current_xpos = 0;
				current_ypos++;
			}
		}
	}
}

static struct console early_vga_console = {
	.name =		"earlyvga",
	.write =	early_vga_write,
	.flags =	CON_PRINTBUFFER,
	.index =	-1,
};

/* Serial functions loosely based on a similar package from Klaus P. Gerlicher */

static int early_serial_base = 0x3f8;  /* ttyS0 */

#define XMTRDY          0x20

#define DLAB		0x80

#define TXR             0       /*  Transmit register (WRITE) */
#define RXR             0       /*  Receive register  (READ)  */
#define IER             1       /*  Interrupt Enable          */
#define IIR             2       /*  Interrupt ID              */
#define FCR             2       /*  FIFO control              */
#define LCR             3       /*  Line control              */
#define MCR             4       /*  Modem control             */
#define LSR             5       /*  Line Status               */
#define MSR             6       /*  Modem Status              */
#define DLL             0       /*  Divisor Latch Low         */
#define DLH             1       /*  Divisor latch High        */

static int early_serial_putc(unsigned char ch)
{
	unsigned timeout = 0xffff;
	while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout)
		cpu_relax();
	outb(ch, early_serial_base + TXR);
	return timeout ? 0 : -1;
}

static void early_serial_write(struct console *con, const char *s, unsigned n)
{
	while (*s && n-- > 0) {
		if (*s == '\n')
			early_serial_putc('\r');
		early_serial_putc(*s);
		s++;
	}
}

#define DEFAULT_BAUD 9600

static __init void early_serial_init(char *s)
{
	unsigned char c;
	unsigned divisor;
	unsigned baud = DEFAULT_BAUD;
	char *e;

	if (*s == ',')
		++s;

	if (*s) {
		unsigned port;
		if (!strncmp(s,"0x",2)) {
			early_serial_base = simple_strtoul(s, &e, 16);
		} else {
			static int bases[] = { 0x3f8, 0x2f8 };

			if (!strncmp(s,"ttyS",4))
				s += 4;
			port = simple_strtoul(s, &e, 10);
			if (port > 1 || s == e)
				port = 0;
			early_serial_base = bases[port];
		}
		s += strcspn(s, ",");
		if (*s == ',')
			s++;
	}

	outb(0x3, early_serial_base + LCR);	/* 8n1 */
	outb(0, early_serial_base + IER);	/* no interrupt */
	outb(0, early_serial_base + FCR);	/* no fifo */
	outb(0x3, early_serial_base + MCR);	/* DTR + RTS */

	if (*s) {
		baud = simple_strtoul(s, &e, 0);
		if (baud == 0 || s == e)
			baud = DEFAULT_BAUD;
	}

	divisor = 115200 / baud;
	c = inb(early_serial_base + LCR);
	outb(c | DLAB, early_serial_base + LCR);
	outb(divisor & 0xff, early_serial_base + DLL);
	outb((divisor >> 8) & 0xff, early_serial_base + DLH);
	outb(c & ~DLAB, early_serial_base + LCR);
}

static struct console early_serial_console = {
	.name =		"earlyser",
	.write =	early_serial_write,
	.flags =	CON_PRINTBUFFER,
	.index =	-1,
};

/* Console interface to a host file on AMD's SimNow! */

static int simnow_fd;

enum {
	MAGIC1 = 0xBACCD00A,
	MAGIC2 = 0xCA110000,
	XOPEN = 5,
	XWRITE = 4,
};

static noinline long simnow(long cmd, long a, long b, long c)
{
	long ret;
	asm volatile("cpuid" :
		     "=a" (ret) :
		     "b" (a), "c" (b), "d" (c), "0" (MAGIC1), "D" (cmd + MAGIC2));
	return ret;
}

static void __init simnow_init(char *str)
{
	char *fn = "klog";
	if (*str == '=')
		fn = ++str;
	/* error ignored */
	simnow_fd = simnow(XOPEN, (unsigned long)fn, O_WRONLY|O_APPEND|O_CREAT, 0644);
}

static void simnow_write(struct console *con, const char *s, unsigned n)
{
	simnow(XWRITE, simnow_fd, (unsigned long)s, n);
}

static struct console simnow_console = {
	.name =		"simnow",
	.write =	simnow_write,
	.flags =	CON_PRINTBUFFER,
	.index =	-1,
};

/* Direct interface for emergencies */
struct console *early_console = &early_vga_console;
static int early_console_initialized = 0;

void early_printk(const char *fmt, ...)
{
	char buf[512];
	int n;
	va_list ap;

	va_start(ap,fmt);
	n = vscnprintf(buf,512,fmt,ap);
	early_console->write(early_console,buf,n);
	va_end(ap);
}

static int __initdata keep_early;

static int __init setup_early_printk(char *buf)
{
	if (!buf)
		return 0;

	if (early_console_initialized)
		return 0;
	early_console_initialized = 1;

	if (strstr(buf, "keep"))
		keep_early = 1;

	if (!strncmp(buf, "serial", 6)) {
		early_serial_init(buf + 6);
		early_console = &early_serial_console;
	} else if (!strncmp(buf, "ttyS", 4)) {
		early_serial_init(buf);
		early_console = &early_serial_console;
	} else if (!strncmp(buf, "vga", 3)
	           && boot_params.screen_info.orig_video_isVGA == 1) {
		max_xpos = boot_params.screen_info.orig_video_cols;
		max_ypos = boot_params.screen_info.orig_video_lines;
		current_ypos = boot_params.screen_info.orig_y;
		early_console = &early_vga_console;
 	} else if (!strncmp(buf, "simnow", 6)) {
 		simnow_init(buf + 6);
 		early_console = &simnow_console;
 		keep_early = 1;
#ifdef CONFIG_HVC_XEN
	} else if (!strncmp(buf, "xen", 3)) {
		early_console = &xenboot_console;
#endif
	}

	if (keep_early)
		early_console->flags &= ~CON_BOOT;
	else
		early_console->flags |= CON_BOOT;
	register_console(early_console);
	return 0;
}
early_param("earlyprintk", setup_early_printk);
