/*
 * 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;

	} 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;
	}
#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
}
