/*
 * Copyright (C) 1996 Paul Mackerras.
 */
#include <linux/config.h>
#include <linux/string.h>
#include <asm/machdep.h>
#include <asm/io.h>
#include <asm/page.h>
#include <linux/adb.h>
#include <linux/pmu.h>
#include <linux/cuda.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/sysrq.h>
#include <linux/bitops.h>
#include <asm/xmon.h>
#include <asm/prom.h>
#include <asm/bootx.h>
#include <asm/machdep.h>
#include <asm/errno.h>
#include <asm/pmac_feature.h>
#include <asm/processor.h>
#include <asm/delay.h>
#include <asm/btext.h>

static volatile unsigned char *sccc, *sccd;
unsigned int TXRDY, RXRDY, DLAB;
static int xmon_expect(const char *str, unsigned int timeout);

static int use_serial;
static int use_screen;
static int via_modem;
static int xmon_use_sccb;
static struct device_node *channel_node;

#define TB_SPEED	25000000

static inline unsigned int readtb(void)
{
	unsigned int ret;

	asm volatile("mftb %0" : "=r" (ret) :);
	return ret;
}

void buf_access(void)
{
	if (DLAB)
		sccd[3] &= ~DLAB;	/* reset DLAB */
}

extern int adb_init(void);

#ifdef CONFIG_PPC_CHRP
/*
 * This looks in the "ranges" property for the primary PCI host bridge
 * to find the physical address of the start of PCI/ISA I/O space.
 * It is basically a cut-down version of pci_process_bridge_OF_ranges.
 */
static unsigned long chrp_find_phys_io_base(void)
{
	struct device_node *node;
	unsigned int *ranges;
	unsigned long base = CHRP_ISA_IO_BASE;
	int rlen = 0;
	int np;

	node = find_devices("isa");
	if (node != NULL) {
		node = node->parent;
		if (node == NULL || node->type == NULL
		    || strcmp(node->type, "pci") != 0)
			node = NULL;
	}
	if (node == NULL)
		node = find_devices("pci");
	if (node == NULL)
		return base;

	ranges = (unsigned int *) get_property(node, "ranges", &rlen);
	np = prom_n_addr_cells(node) + 5;
	while ((rlen -= np * sizeof(unsigned int)) >= 0) {
		if ((ranges[0] >> 24) == 1 && ranges[2] == 0) {
			/* I/O space starting at 0, grab the phys base */
			base = ranges[np - 3];
			break;
		}
		ranges += np;
	}
	return base;
}
#endif /* CONFIG_PPC_CHRP */

#ifdef CONFIG_MAGIC_SYSRQ
static void sysrq_handle_xmon(int key, struct pt_regs *regs,
			      struct tty_struct *tty)
{
	xmon(regs);
}

static struct sysrq_key_op sysrq_xmon_op =
{
	.handler =	sysrq_handle_xmon,
	.help_msg =	"Xmon",
	.action_msg =	"Entering xmon",
};
#endif

void
xmon_map_scc(void)
{
#ifdef CONFIG_PPC_MULTIPLATFORM
	volatile unsigned char *base;

	if (_machine == _MACH_Pmac) {
		struct device_node *np;
		unsigned long addr;
#ifdef CONFIG_BOOTX_TEXT
		if (!use_screen && !use_serial
		    && !machine_is_compatible("iMac")) {
			/* see if there is a keyboard in the device tree
			   with a parent of type "adb" */
			for (np = find_devices("keyboard"); np; np = np->next)
				if (np->parent && np->parent->type
				    && strcmp(np->parent->type, "adb") == 0)
					break;

			/* needs to be hacked if xmon_printk is to be used
			   from within find_via_pmu() */
#ifdef CONFIG_ADB_PMU
			if (np != NULL && boot_text_mapped && find_via_pmu())
				use_screen = 1;
#endif
#ifdef CONFIG_ADB_CUDA
			if (np != NULL && boot_text_mapped && find_via_cuda())
				use_screen = 1;
#endif
		}
		if (!use_screen && (np = find_devices("escc")) != NULL) {
			/*
			 * look for the device node for the serial port
			 * we're using and see if it says it has a modem
			 */
			char *name = xmon_use_sccb? "ch-b": "ch-a";
			char *slots;
			int l;

			np = np->child;
			while (np != NULL && strcmp(np->name, name) != 0)
				np = np->sibling;
			if (np != NULL) {
				/* XXX should parse this properly */
				channel_node = np;
				slots = get_property(np, "slot-names", &l);
				if (slots != NULL && l >= 10
				    && strcmp(slots+4, "Modem") == 0)
					via_modem = 1;
			}
		}
		btext_drawstring("xmon uses ");
		if (use_screen)
			btext_drawstring("screen and keyboard\n");
		else {
			if (via_modem)
				btext_drawstring("modem on ");
			btext_drawstring(xmon_use_sccb? "printer": "modem");
			btext_drawstring(" port\n");
		}

#endif /* CONFIG_BOOTX_TEXT */

#ifdef CHRP_ESCC
		addr = 0xc1013020;
#else
		addr = 0xf3013020;
#endif
		TXRDY = 4;
		RXRDY = 1;
	
		np = find_devices("mac-io");
		if (np && np->n_addrs)
			addr = np->addrs[0].address + 0x13020;
		base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE);
		sccc = base + (addr & ~PAGE_MASK);
		sccd = sccc + 0x10;

	}
#ifdef CONFIG_PPC_CHRP
	else {
		base = (volatile unsigned char *) isa_io_base;
		if (_machine == _MACH_chrp)
			base = (volatile unsigned char *)
				ioremap(chrp_find_phys_io_base(), 0x1000);

		sccc = base + 0x3fd;
		sccd = base + 0x3f8;
		if (xmon_use_sccb) {
			sccc -= 0x100;
			sccd -= 0x100;
		}
		TXRDY = 0x20;
		RXRDY = 1;
		DLAB = 0x80;
	}
#endif /* CONFIG_PPC_CHRP */
#elif defined(CONFIG_GEMINI)
	/* should already be mapped by the kernel boot */
	sccc = (volatile unsigned char *) 0xffeffb0d;
	sccd = (volatile unsigned char *) 0xffeffb08;
	TXRDY = 0x20;
	RXRDY = 1;
	DLAB = 0x80;
#elif defined(CONFIG_405GP)
	sccc = (volatile unsigned char *)0xef600305;
	sccd = (volatile unsigned char *)0xef600300;
	TXRDY = 0x20;
	RXRDY = 1;
	DLAB = 0x80;
#endif /* platform */

	register_sysrq_key('x', &sysrq_xmon_op);
}

static int scc_initialized = 0;

void xmon_init_scc(void);
extern void cuda_poll(void);

static inline void do_poll_adb(void)
{
#ifdef CONFIG_ADB_PMU
	if (sys_ctrler == SYS_CTRLER_PMU)
		pmu_poll_adb();
#endif /* CONFIG_ADB_PMU */
#ifdef CONFIG_ADB_CUDA
	if (sys_ctrler == SYS_CTRLER_CUDA)
		cuda_poll();
#endif /* CONFIG_ADB_CUDA */
}

int
xmon_write(void *handle, void *ptr, int nb)
{
	char *p = ptr;
	int i, c, ct;

#ifdef CONFIG_SMP
	static unsigned long xmon_write_lock;
	int lock_wait = 1000000;
	int locked;

	while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0)
		if (--lock_wait == 0)
			break;
#endif

#ifdef CONFIG_BOOTX_TEXT
	if (use_screen) {
		/* write it on the screen */
		for (i = 0; i < nb; ++i)
			btext_drawchar(*p++);
		goto out;
	}
#endif
	if (!scc_initialized)
		xmon_init_scc();
	ct = 0;
	for (i = 0; i < nb; ++i) {
		while ((*sccc & TXRDY) == 0)
			do_poll_adb();
		c = p[i];
		if (c == '\n' && !ct) {
			c = '\r';
			ct = 1;
			--i;
		} else {
			ct = 0;
		}
		buf_access();
		*sccd = c;
		eieio();
	}

 out:
#ifdef CONFIG_SMP
	if (!locked)
		clear_bit(0, &xmon_write_lock);
#endif
	return nb;
}

int xmon_wants_key;
int xmon_adb_keycode;

#ifdef CONFIG_BOOTX_TEXT
static int xmon_adb_shiftstate;

static unsigned char xmon_keytab[128] =
	"asdfhgzxcv\000bqwer"				/* 0x00 - 0x0f */
	"yt123465=97-80]o"				/* 0x10 - 0x1f */
	"u[ip\rlj'k;\\,/nm."				/* 0x20 - 0x2f */
	"\t `\177\0\033\0\0\0\0\0\0\0\0\0\0"		/* 0x30 - 0x3f */
	"\0.\0*\0+\0\0\0\0\0/\r\0-\0"			/* 0x40 - 0x4f */
	"\0\0000123456789\0\0\0";			/* 0x50 - 0x5f */

static unsigned char xmon_shift_keytab[128] =
	"ASDFHGZXCV\000BQWER"				/* 0x00 - 0x0f */
	"YT!@#$^%+(&_*)}O"				/* 0x10 - 0x1f */
	"U{IP\rLJ\"K:|<?NM>"				/* 0x20 - 0x2f */
	"\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0"		/* 0x30 - 0x3f */
	"\0.\0*\0+\0\0\0\0\0/\r\0-\0"			/* 0x40 - 0x4f */
	"\0\0000123456789\0\0\0";			/* 0x50 - 0x5f */

static int
xmon_get_adb_key(void)
{
	int k, t, on;

	xmon_wants_key = 1;
	for (;;) {
		xmon_adb_keycode = -1;
		t = 0;
		on = 0;
		do {
			if (--t < 0) {
				on = 1 - on;
				btext_drawchar(on? 0xdb: 0x20);
				btext_drawchar('\b');
				t = 200000;
			}
			do_poll_adb();
		} while (xmon_adb_keycode == -1);
		k = xmon_adb_keycode;
		if (on)
			btext_drawstring(" \b");

		/* test for shift keys */
		if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
			xmon_adb_shiftstate = (k & 0x80) == 0;
			continue;
		}
		if (k >= 0x80)
			continue;	/* ignore up transitions */
		k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
		if (k != 0)
			break;
	}
	xmon_wants_key = 0;
	return k;
}
#endif /* CONFIG_BOOTX_TEXT */

int
xmon_read(void *handle, void *ptr, int nb)
{
    char *p = ptr;
    int i;

#ifdef CONFIG_BOOTX_TEXT
    if (use_screen) {
	for (i = 0; i < nb; ++i)
	    *p++ = xmon_get_adb_key();
	return i;
    }
#endif
    if (!scc_initialized)
	xmon_init_scc();
    for (i = 0; i < nb; ++i) {
	while ((*sccc & RXRDY) == 0)
	    do_poll_adb();
	buf_access();
	*p++ = *sccd;
    }
    return i;
}

int
xmon_read_poll(void)
{
	if ((*sccc & RXRDY) == 0) {
		do_poll_adb();
		return -1;
	}
	buf_access();
	return *sccd;
}

static unsigned char scc_inittab[] = {
    13, 0,		/* set baud rate divisor */
    12, 1,
    14, 1,		/* baud rate gen enable, src=rtxc */
    11, 0x50,		/* clocks = br gen */
    5,  0xea,		/* tx 8 bits, assert DTR & RTS */
    4,  0x46,		/* x16 clock, 1 stop */
    3,  0xc1,		/* rx enable, 8 bits */
};

void
xmon_init_scc(void)
{
	if ( _machine == _MACH_chrp )
	{
		sccd[3] = 0x83; eieio();	/* LCR = 8N1 + DLAB */
		sccd[0] = 12; eieio();		/* DLL = 9600 baud */
		sccd[1] = 0; eieio();
		sccd[2] = 0; eieio();		/* FCR = 0 */
		sccd[3] = 3; eieio();		/* LCR = 8N1 */
		sccd[1] = 0; eieio();		/* IER = 0 */
	}
	else if ( _machine == _MACH_Pmac )
	{
		int i, x;

		if (channel_node != 0)
			pmac_call_feature(
				PMAC_FTR_SCC_ENABLE,
				channel_node,
				PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
			printk(KERN_INFO "Serial port locked ON by debugger !\n");
		if (via_modem && channel_node != 0) {
			unsigned int t0;

			pmac_call_feature(
				PMAC_FTR_MODEM_ENABLE,
				channel_node, 0, 1);
			printk(KERN_INFO "Modem powered up by debugger !\n");
			t0 = readtb();
			while (readtb() - t0 < 3*TB_SPEED)
				eieio();
		}
		/* use the B channel if requested */
		if (xmon_use_sccb) {
			sccc = (volatile unsigned char *)
				((unsigned long)sccc & ~0x20);
			sccd = sccc + 0x10;
		}
		for (i = 20000; i != 0; --i) {
			x = *sccc; eieio();
		}
		*sccc = 9; eieio();		/* reset A or B side */
		*sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio();
		for (i = 0; i < sizeof(scc_inittab); ++i) {
			*sccc = scc_inittab[i];
			eieio();
		}
	}
	scc_initialized = 1;
	if (via_modem) {
		for (;;) {
			xmon_write(NULL, "ATE1V1\r", 7);
			if (xmon_expect("OK", 5)) {
				xmon_write(NULL, "ATA\r", 4);
				if (xmon_expect("CONNECT", 40))
					break;
			}
			xmon_write(NULL, "+++", 3);
			xmon_expect("OK", 3);
		}
	}
}

#if 0
extern int (*prom_entry)(void *);

int
xmon_exit(void)
{
    struct prom_args {
	char *service;
    } args;

    for (;;) {
	args.service = "exit";
	(*prom_entry)(&args);
    }
}
#endif

void *xmon_stdin;
void *xmon_stdout;
void *xmon_stderr;

void
xmon_init(int arg)
{
	xmon_map_scc();
}

int
xmon_putc(int c, void *f)
{
    char ch = c;

    if (c == '\n')
	xmon_putc('\r', f);
    return xmon_write(f, &ch, 1) == 1? c: -1;
}

int
xmon_putchar(int c)
{
    return xmon_putc(c, xmon_stdout);
}

int
xmon_fputs(char *str, void *f)
{
    int n = strlen(str);

    return xmon_write(f, str, n) == n? 0: -1;
}

int
xmon_readchar(void)
{
    char ch;

    for (;;) {
	switch (xmon_read(xmon_stdin, &ch, 1)) {
	case 1:
	    return ch;
	case -1:
	    xmon_printf("read(stdin) returned -1\r\n", 0, 0);
	    return -1;
	}
    }
}

static char line[256];
static char *lineptr;
static int lineleft;

int xmon_expect(const char *str, unsigned int timeout)
{
	int c;
	unsigned int t0;

	timeout *= TB_SPEED;
	t0 = readtb();
	do {
		lineptr = line;
		for (;;) {
			c = xmon_read_poll();
			if (c == -1) {
				if (readtb() - t0 > timeout)
					return 0;
				continue;
			}
			if (c == '\n')
				break;
			if (c != '\r' && lineptr < &line[sizeof(line) - 1])
				*lineptr++ = c;
		}
		*lineptr = 0;
	} while (strstr(line, str) == NULL);
	return 1;
}

int
xmon_getchar(void)
{
    int c;

    if (lineleft == 0) {
	lineptr = line;
	for (;;) {
	    c = xmon_readchar();
	    if (c == -1 || c == 4)
		break;
	    if (c == '\r' || c == '\n') {
		*lineptr++ = '\n';
		xmon_putchar('\n');
		break;
	    }
	    switch (c) {
	    case 0177:
	    case '\b':
		if (lineptr > line) {
		    xmon_putchar('\b');
		    xmon_putchar(' ');
		    xmon_putchar('\b');
		    --lineptr;
		}
		break;
	    case 'U' & 0x1F:
		while (lineptr > line) {
		    xmon_putchar('\b');
		    xmon_putchar(' ');
		    xmon_putchar('\b');
		    --lineptr;
		}
		break;
	    default:
		if (lineptr >= &line[sizeof(line) - 1])
		    xmon_putchar('\a');
		else {
		    xmon_putchar(c);
		    *lineptr++ = c;
		}
	    }
	}
	lineleft = lineptr - line;
	lineptr = line;
    }
    if (lineleft == 0)
	return -1;
    --lineleft;
    return *lineptr++;
}

char *
xmon_fgets(char *str, int nb, void *f)
{
    char *p;
    int c;

    for (p = str; p < str + nb - 1; ) {
	c = xmon_getchar();
	if (c == -1) {
	    if (p == str)
		return NULL;
	    break;
	}
	*p++ = c;
	if (c == '\n')
	    break;
    }
    *p = 0;
    return str;
}

void
xmon_enter(void)
{
#ifdef CONFIG_ADB_PMU
	if (_machine == _MACH_Pmac) {
		pmu_suspend();
	}
#endif
}

void
xmon_leave(void)
{
#ifdef CONFIG_ADB_PMU
	if (_machine == _MACH_Pmac) {
		pmu_resume();
	}
#endif
}
