#include <common.h>
#include <command.h>

#if (CONFIG_COMMANDS & CFG_CMD_KGDB)

#include <kgdb.h>
#include <asm/signal.h>
#include <asm/processor.h>

#define PC_REGNUM 64
#define SP_REGNUM 1

void breakinst(void);

int
kgdb_setjmp(long *buf)
{
	asm ("mflr 0; stw 0,0(%0);"
	     "stw 1,4(%0); stw 2,8(%0);"
	     "mfcr 0; stw 0,12(%0);"
	     "stmw 13,16(%0)"
	     : : "r" (buf));
	/* XXX should save fp regs as well */
	return 0;
}

void
kgdb_longjmp(long *buf, int val)
{
	if (val == 0)
		val = 1;
	asm ("lmw 13,16(%0);"
	     "lwz 0,12(%0); mtcrf 0x38,0;"
	     "lwz 0,0(%0); lwz 1,4(%0); lwz 2,8(%0);"
	     "mtlr 0; mr 3,%1"
	     : : "r" (buf), "r" (val));
}

static inline unsigned long
get_msr(void)
{
	unsigned long msr;
	asm volatile("mfmsr %0" : "=r" (msr):);
	return msr;
}

static inline void
set_msr(unsigned long msr)
{
	asm volatile("mtmsr %0" : : "r" (msr));
}

/* Convert the SPARC hardware trap type code to a unix signal number. */
/*
 * This table contains the mapping between PowerPC hardware trap types, and
 * signals, which are primarily what GDB understands.
 */
static struct hard_trap_info
{
	unsigned int tt;		/* Trap type code for powerpc */
	unsigned char signo;		/* Signal that we map this trap into */
} hard_trap_info[] = {
	{ 0x200, SIGSEGV },			/* machine check */
	{ 0x300, SIGSEGV },			/* address error (store) */
	{ 0x400, SIGBUS },			/* instruction bus error */
	{ 0x500, SIGINT },			/* interrupt */
	{ 0x600, SIGBUS },			/* alingment */
	{ 0x700, SIGTRAP },			/* breakpoint trap */
	{ 0x800, SIGFPE },			/* fpu unavail */
	{ 0x900, SIGALRM },			/* decrementer */
	{ 0xa00, SIGILL },			/* reserved */
	{ 0xb00, SIGILL },			/* reserved */
	{ 0xc00, SIGCHLD },			/* syscall */
	{ 0xd00, SIGTRAP },			/* single-step/watch */
	{ 0xe00, SIGFPE },			/* fp assist */
	{ 0, 0}				/* Must be last */
};

static int
computeSignal(unsigned int tt)
{
	struct hard_trap_info *ht;

	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
		if (ht->tt == tt)
			return ht->signo;

	return SIGHUP;         /* default for things we don't know about */
}

void
kgdb_enter(struct pt_regs *regs, kgdb_data *kdp)
{
	unsigned long msr;

	kdp->private[0] = msr = get_msr();
	set_msr(msr & ~MSR_EE);	/* disable interrupts */

	if (regs->nip == (unsigned long)breakinst) {
		/* Skip over breakpoint trap insn */
		regs->nip += 4;
	}
	regs->msr &= ~MSR_SE;

	/* reply to host that an exception has occurred */
	kdp->sigval = computeSignal(regs->trap);

	kdp->nregs = 2;

	kdp->regs[0].num = PC_REGNUM;
	kdp->regs[0].val = regs->nip;

	kdp->regs[1].num = SP_REGNUM;
	kdp->regs[1].val = regs->gpr[SP_REGNUM];
}

void
kgdb_exit(struct pt_regs *regs, kgdb_data *kdp)
{
	unsigned long msr = kdp->private[0];

	if (kdp->extype & KGDBEXIT_WITHADDR)
		regs->nip = kdp->exaddr;

	switch (kdp->extype & KGDBEXIT_TYPEMASK) {

	case KGDBEXIT_KILL:
	case KGDBEXIT_CONTINUE:
		set_msr(msr);
		break;

	case KGDBEXIT_SINGLE:
		regs->msr |= MSR_SE;
#if 0
		set_msr(msr | MSR_SE);
#endif
		break;
	}
}

int
kgdb_trap(struct pt_regs *regs)
{
	return (regs->trap);
}

/* return the value of the CPU registers.
 * some of them are non-PowerPC names :(
 * they are stored in gdb like:
 * struct {
 *     u32 gpr[32];
 *     f64 fpr[32];
 *     u32 pc, ps, cnd, lr; (ps=msr)
 *     u32 cnt, xer, mq;
 * }
 */

#define SPACE_REQUIRED	((32*4)+(32*8)+(6*4))

#ifdef CONFIG_8260
/* store floating double indexed */
#define STFDI(n,p)	__asm__ __volatile__ ("stfd " #n ",%0" : "=o"(p[2*n]))
/* store floating double multiple */
#define STFDM(p)	{ STFDI( 0,p); STFDI( 1,p); STFDI( 2,p); STFDI( 3,p); \
			  STFDI( 4,p); STFDI( 5,p); STFDI( 6,p); STFDI( 7,p); \
			  STFDI( 8,p); STFDI( 9,p); STFDI(10,p); STFDI(11,p); \
			  STFDI(12,p); STFDI(13,p); STFDI(14,p); STFDI(15,p); \
			  STFDI(16,p); STFDI(17,p); STFDI(18,p); STFDI(19,p); \
			  STFDI(20,p); STFDI(21,p); STFDI(22,p); STFDI(23,p); \
			  STFDI(24,p); STFDI(25,p); STFDI(26,p); STFDI(27,p); \
			  STFDI(28,p); STFDI(29,p); STFDI(30,p); STFDI(31,p); }
#endif

int
kgdb_getregs(struct pt_regs *regs, char *buf, int max)
{
	int i;
	unsigned long *ptr = (unsigned long *)buf;

	if (max < SPACE_REQUIRED)
		kgdb_error(KGDBERR_NOSPACE);

	if ((unsigned long)ptr & 3)
		kgdb_error(KGDBERR_ALIGNFAULT);

	/* General Purpose Regs */
	for (i = 0; i < 32; i++)
		*ptr++ = regs->gpr[i];

	/* Floating Point Regs */
#ifdef CONFIG_8260
	STFDM(ptr);
	ptr += 32*2;
#else
	for (i = 0; i < 32; i++) {
		*ptr++ = 0;
		*ptr++ = 0;
	}
#endif

	/* pc, msr, cr, lr, ctr, xer, (mq is unused) */
	*ptr++ = regs->nip;
	*ptr++ = regs->msr;
	*ptr++ = regs->ccr;
	*ptr++ = regs->link;
	*ptr++ = regs->ctr;
	*ptr++ = regs->xer;

	return (SPACE_REQUIRED);
}

/* set the value of the CPU registers */

#ifdef CONFIG_8260
/* load floating double */
#define LFD(n,v)	__asm__ __volatile__ ("lfd " #n ",%0" :: "o"(v))
/* load floating double indexed */
#define LFDI(n,p)	__asm__ __volatile__ ("lfd " #n ",%0" :: "o"((p)[2*n]))
/* load floating double multiple */
#define LFDM(p)		{ LFDI( 0,p); LFDI( 1,p); LFDI( 2,p); LFDI( 3,p); \
			  LFDI( 4,p); LFDI( 5,p); LFDI( 6,p); LFDI( 7,p); \
			  LFDI( 8,p); LFDI( 9,p); LFDI(10,p); LFDI(11,p); \
			  LFDI(12,p); LFDI(13,p); LFDI(14,p); LFDI(15,p); \
			  LFDI(16,p); LFDI(17,p); LFDI(18,p); LFDI(19,p); \
			  LFDI(20,p); LFDI(21,p); LFDI(22,p); LFDI(23,p); \
			  LFDI(24,p); LFDI(25,p); LFDI(26,p); LFDI(27,p); \
			  LFDI(28,p); LFDI(29,p); LFDI(30,p); LFDI(31,p); }
#endif

void
kgdb_putreg(struct pt_regs *regs, int regno, char *buf, int length)
{
	unsigned long *ptr = (unsigned long *)buf;

	if (regno < 0 || regno >= 70)
		kgdb_error(KGDBERR_BADPARAMS);
	else if (regno >= 32 && regno < 64) {
		if (length < 8)
			kgdb_error(KGDBERR_NOSPACE);
	}
	else {
		if (length < 4)
			kgdb_error(KGDBERR_NOSPACE);
	}

	if ((unsigned long)ptr & 3)
		kgdb_error(KGDBERR_ALIGNFAULT);

	if (regno >= 0 && regno < 32)
		regs->gpr[regno] = *ptr;
	else switch (regno) {

#ifdef CONFIG_8260
#define caseF(n) \
	case (n) + 32:	LFD(n, *ptr);		break;

caseF( 0) caseF( 1) caseF( 2) caseF( 3) caseF( 4) caseF( 5) caseF( 6) caseF( 7)
caseF( 8) caseF( 9) caseF(10) caseF(11) caseF(12) caseF(13) caseF(14) caseF(15)
caseF(16) caseF(17) caseF(18) caseF(19) caseF(20) caseF(21) caseF(22) caseF(23)
caseF(24) caseF(25) caseF(26) caseF(27) caseF(28) caseF(29) caseF(30) caseF(31)

#undef caseF
#endif

	case 64:	regs->nip = *ptr;	break;
	case 65:	regs->msr = *ptr;	break;
	case 66:	regs->ccr = *ptr;	break;
	case 67:	regs->link = *ptr;	break;
	case 68:	regs->ctr = *ptr;	break;
	case 69:	regs->ctr = *ptr;	break;

	default:
		kgdb_error(KGDBERR_BADPARAMS);
	}
}

void
kgdb_putregs(struct pt_regs *regs, char *buf, int length)
{
	int i;
	unsigned long *ptr = (unsigned long *)buf;

	if (length < SPACE_REQUIRED)
		kgdb_error(KGDBERR_NOSPACE);

	if ((unsigned long)ptr & 3)
		kgdb_error(KGDBERR_ALIGNFAULT);

	/*
	 * If the stack pointer has moved, you should pray.
	 * (cause only god can help you).
	 */

	/* General Purpose Regs */
	for (i = 0; i < 32; i++)
		regs->gpr[i] = *ptr++;

	/* Floating Point Regs */
#ifdef CONFIG_8260
	LFDM(ptr);
#endif
	ptr += 32*2;

	/* pc, msr, cr, lr, ctr, xer, (mq is unused) */
	regs->nip = *ptr++;
	regs->msr = *ptr++;
	regs->ccr = *ptr++;
	regs->link = *ptr++;
	regs->ctr = *ptr++;
	regs->xer = *ptr++;
}

/* This function will generate a breakpoint exception.  It is used at the
   beginning of a program to sync up with a debugger and can be used
   otherwise as a quick means to stop program execution and "break" into
   the debugger. */

void
kgdb_breakpoint(int argc, char *argv[])
{
	asm("	.globl breakinst\n\
	     breakinst: .long 0x7d821008\n\
	    ");
}

#endif /* CFG_CMD_KGDB */
