/* kgdb support for MN10300
 *
 * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public Licence
 * as published by the Free Software Foundation; either version
 * 2 of the Licence, or (at your option) any later version.
 */

#include <linux/slab.h>
#include <linux/ptrace.h>
#include <linux/kgdb.h>
#include <linux/uaccess.h>
#include <unit/leds.h>
#include <unit/serial.h>
#include <asm/debugger.h>
#include <asm/serial-regs.h>
#include "internal.h"

/*
 * Software single-stepping breakpoint save (used by __switch_to())
 */
static struct thread_info *kgdb_sstep_thread;
u8 *kgdb_sstep_bp_addr[2];
u8 kgdb_sstep_bp[2];

/*
 * Copy kernel exception frame registers to the GDB register file
 */
void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
{
	unsigned long ssp = (unsigned long) (regs + 1);

	gdb_regs[GDB_FR_D0]	= regs->d0;
	gdb_regs[GDB_FR_D1]	= regs->d1;
	gdb_regs[GDB_FR_D2]	= regs->d2;
	gdb_regs[GDB_FR_D3]	= regs->d3;
	gdb_regs[GDB_FR_A0]	= regs->a0;
	gdb_regs[GDB_FR_A1]	= regs->a1;
	gdb_regs[GDB_FR_A2]	= regs->a2;
	gdb_regs[GDB_FR_A3]	= regs->a3;
	gdb_regs[GDB_FR_SP]	= (regs->epsw & EPSW_nSL) ? regs->sp : ssp;
	gdb_regs[GDB_FR_PC]	= regs->pc;
	gdb_regs[GDB_FR_MDR]	= regs->mdr;
	gdb_regs[GDB_FR_EPSW]	= regs->epsw;
	gdb_regs[GDB_FR_LIR]	= regs->lir;
	gdb_regs[GDB_FR_LAR]	= regs->lar;
	gdb_regs[GDB_FR_MDRQ]	= regs->mdrq;
	gdb_regs[GDB_FR_E0]	= regs->e0;
	gdb_regs[GDB_FR_E1]	= regs->e1;
	gdb_regs[GDB_FR_E2]	= regs->e2;
	gdb_regs[GDB_FR_E3]	= regs->e3;
	gdb_regs[GDB_FR_E4]	= regs->e4;
	gdb_regs[GDB_FR_E5]	= regs->e5;
	gdb_regs[GDB_FR_E6]	= regs->e6;
	gdb_regs[GDB_FR_E7]	= regs->e7;
	gdb_regs[GDB_FR_SSP]	= ssp;
	gdb_regs[GDB_FR_MSP]	= 0;
	gdb_regs[GDB_FR_USP]	= regs->sp;
	gdb_regs[GDB_FR_MCRH]	= regs->mcrh;
	gdb_regs[GDB_FR_MCRL]	= regs->mcrl;
	gdb_regs[GDB_FR_MCVF]	= regs->mcvf;
	gdb_regs[GDB_FR_DUMMY0]	= 0;
	gdb_regs[GDB_FR_DUMMY1]	= 0;
	gdb_regs[GDB_FR_FS0]	= 0;
}

/*
 * Extracts kernel SP/PC values understandable by gdb from the values
 * saved by switch_to().
 */
void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
{
	gdb_regs[GDB_FR_SSP]	= p->thread.sp;
	gdb_regs[GDB_FR_PC]	= p->thread.pc;
	gdb_regs[GDB_FR_A3]	= p->thread.a3;
	gdb_regs[GDB_FR_USP]	= p->thread.usp;
	gdb_regs[GDB_FR_FPCR]	= p->thread.fpu_state.fpcr;
}

/*
 * Fill kernel exception frame registers from the GDB register file
 */
void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
{
	regs->d0	= gdb_regs[GDB_FR_D0];
	regs->d1	= gdb_regs[GDB_FR_D1];
	regs->d2	= gdb_regs[GDB_FR_D2];
	regs->d3	= gdb_regs[GDB_FR_D3];
	regs->a0	= gdb_regs[GDB_FR_A0];
	regs->a1	= gdb_regs[GDB_FR_A1];
	regs->a2	= gdb_regs[GDB_FR_A2];
	regs->a3	= gdb_regs[GDB_FR_A3];
	regs->sp	= gdb_regs[GDB_FR_SP];
	regs->pc	= gdb_regs[GDB_FR_PC];
	regs->mdr	= gdb_regs[GDB_FR_MDR];
	regs->epsw	= gdb_regs[GDB_FR_EPSW];
	regs->lir	= gdb_regs[GDB_FR_LIR];
	regs->lar	= gdb_regs[GDB_FR_LAR];
	regs->mdrq	= gdb_regs[GDB_FR_MDRQ];
	regs->e0	= gdb_regs[GDB_FR_E0];
	regs->e1	= gdb_regs[GDB_FR_E1];
	regs->e2	= gdb_regs[GDB_FR_E2];
	regs->e3	= gdb_regs[GDB_FR_E3];
	regs->e4	= gdb_regs[GDB_FR_E4];
	regs->e5	= gdb_regs[GDB_FR_E5];
	regs->e6	= gdb_regs[GDB_FR_E6];
	regs->e7	= gdb_regs[GDB_FR_E7];
	regs->sp	= gdb_regs[GDB_FR_SSP];
	/* gdb_regs[GDB_FR_MSP]; */
	// regs->usp	= gdb_regs[GDB_FR_USP];
	regs->mcrh	= gdb_regs[GDB_FR_MCRH];
	regs->mcrl	= gdb_regs[GDB_FR_MCRL];
	regs->mcvf	= gdb_regs[GDB_FR_MCVF];
	/* gdb_regs[GDB_FR_DUMMY0]; */
	/* gdb_regs[GDB_FR_DUMMY1]; */

	// regs->fpcr	= gdb_regs[GDB_FR_FPCR];
	// regs->fs0	= gdb_regs[GDB_FR_FS0];
}

struct kgdb_arch arch_kgdb_ops = {
	.gdb_bpt_instr	= { 0xff },
	.flags		= KGDB_HW_BREAKPOINT,
};

static const unsigned char mn10300_kgdb_insn_sizes[256] =
{
	/* 1  2  3  4  5  6  7  8  9  a  b  c  d  e  f */
	1, 3, 3, 3, 1, 3, 3, 3, 1, 3, 3, 3, 1, 3, 3, 3,	/* 0 */
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 1 */
	2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, /* 2 */
	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, /* 3 */
	1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, /* 4 */
	1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, /* 5 */
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 7 */
	2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* 8 */
	2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* 9 */
	2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* a */
	2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* b */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 2, /* c */
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */
	0, 2, 2, 2, 2, 2, 2, 4, 0, 3, 0, 4, 0, 6, 7, 1  /* f */
};

/*
 * Attempt to emulate single stepping by means of breakpoint instructions.
 * Although there is a single-step trace flag in EPSW, its use is not
 * sufficiently documented and is only intended for use with the JTAG debugger.
 */
static int kgdb_arch_do_singlestep(struct pt_regs *regs)
{
	unsigned long arg;
	unsigned size;
	u8 *pc = (u8 *)regs->pc, *sp = (u8 *)(regs + 1), cur;
	u8 *x = NULL, *y = NULL;
	int ret;

	ret = probe_kernel_read(&cur, pc, 1);
	if (ret < 0)
		return ret;

	size = mn10300_kgdb_insn_sizes[cur];
	if (size > 0) {
		x = pc + size;
		goto set_x;
	}

	switch (cur) {
		/* Bxx (d8,PC) */
	case 0xc0 ... 0xca:
		ret = probe_kernel_read(&arg, pc + 1, 1);
		if (ret < 0)
			return ret;
		x = pc + 2;
		if (arg >= 0 && arg <= 2)
			goto set_x;
		y = pc + (s8)arg;
		goto set_x_and_y;

		/* LXX (d8,PC) */
	case 0xd0 ... 0xda:
		x = pc + 1;
		if (regs->pc == regs->lar)
			goto set_x;
		y = (u8 *)regs->lar;
		goto set_x_and_y;

		/* SETLB - loads the next four bytes into the LIR register
		 * (which mustn't include a breakpoint instruction) */
	case 0xdb:
		x = pc + 5;
		goto set_x;

		/* JMP (d16,PC) or CALL (d16,PC) */
	case 0xcc:
	case 0xcd:
		ret = probe_kernel_read(&arg, pc + 1, 2);
		if (ret < 0)
			return ret;
		x = pc + (s16)arg;
		goto set_x;

		/* JMP (d32,PC) or CALL (d32,PC) */
	case 0xdc:
	case 0xdd:
		ret = probe_kernel_read(&arg, pc + 1, 4);
		if (ret < 0)
			return ret;
		x = pc + (s32)arg;
		goto set_x;

		/* RETF */
	case 0xde:
		x = (u8 *)regs->mdr;
		goto set_x;

		/* RET */
	case 0xdf:
		ret = probe_kernel_read(&arg, pc + 2, 1);
		if (ret < 0)
			return ret;
		ret = probe_kernel_read(&x, sp + (s8)arg, 4);
		if (ret < 0)
			return ret;
		goto set_x;

	case 0xf0:
		ret = probe_kernel_read(&cur, pc + 1, 1);
		if (ret < 0)
			return ret;

		if (cur >= 0xf0 && cur <= 0xf7) {
			/* JMP (An) / CALLS (An) */
			switch (cur & 3) {
			case 0: x = (u8 *)regs->a0; break;
			case 1: x = (u8 *)regs->a1; break;
			case 2: x = (u8 *)regs->a2; break;
			case 3: x = (u8 *)regs->a3; break;
			}
			goto set_x;
		} else if (cur == 0xfc) {
			/* RETS */
			ret = probe_kernel_read(&x, sp, 4);
			if (ret < 0)
				return ret;
			goto set_x;
		} else if (cur == 0xfd) {
			/* RTI */
			ret = probe_kernel_read(&x, sp + 4, 4);
			if (ret < 0)
				return ret;
			goto set_x;
		} else {
			x = pc + 2;
			goto set_x;
		}
		break;

		/* potential 3-byte conditional branches */
	case 0xf8:
		ret = probe_kernel_read(&cur, pc + 1, 1);
		if (ret < 0)
			return ret;
		x = pc + 3;

		if (cur >= 0xe8 && cur <= 0xeb) {
			ret = probe_kernel_read(&arg, pc + 2, 1);
			if (ret < 0)
				return ret;
			if (arg >= 0 && arg <= 3)
				goto set_x;
			y = pc + (s8)arg;
			goto set_x_and_y;
		}
		goto set_x;

	case 0xfa:
		ret = probe_kernel_read(&cur, pc + 1, 1);
		if (ret < 0)
			return ret;

		if (cur == 0xff) {
			/* CALLS (d16,PC) */
			ret = probe_kernel_read(&arg, pc + 2, 2);
			if (ret < 0)
				return ret;
			x = pc + (s16)arg;
			goto set_x;
		}

		x = pc + 4;
		goto set_x;

	case 0xfc:
		ret = probe_kernel_read(&cur, pc + 1, 1);
		if (ret < 0)
			return ret;

		if (cur == 0xff) {
			/* CALLS (d32,PC) */
			ret = probe_kernel_read(&arg, pc + 2, 4);
			if (ret < 0)
				return ret;
			x = pc + (s32)arg;
			goto set_x;
		}

		x = pc + 6;
		goto set_x;
	}

	return 0;

set_x:
	kgdb_sstep_bp_addr[0] = x;
	kgdb_sstep_bp_addr[1] = NULL;
	ret = probe_kernel_read(&kgdb_sstep_bp[0], x, 1);
	if (ret < 0)
		return ret;
	ret = probe_kernel_write(x, &arch_kgdb_ops.gdb_bpt_instr, 1);
	if (ret < 0)
		return ret;
	kgdb_sstep_thread = current_thread_info();
	debugger_local_cache_flushinv_one(x);
	return ret;

set_x_and_y:
	kgdb_sstep_bp_addr[0] = x;
	kgdb_sstep_bp_addr[1] = y;
	ret = probe_kernel_read(&kgdb_sstep_bp[0], x, 1);
	if (ret < 0)
		return ret;
	ret = probe_kernel_read(&kgdb_sstep_bp[1], y, 1);
	if (ret < 0)
		return ret;
	ret = probe_kernel_write(x, &arch_kgdb_ops.gdb_bpt_instr, 1);
	if (ret < 0)
		return ret;
	ret = probe_kernel_write(y, &arch_kgdb_ops.gdb_bpt_instr, 1);
	if (ret < 0) {
		probe_kernel_write(kgdb_sstep_bp_addr[0],
				   &kgdb_sstep_bp[0], 1);
	} else {
		kgdb_sstep_thread = current_thread_info();
	}
	debugger_local_cache_flushinv_one(x);
	debugger_local_cache_flushinv_one(y);
	return ret;
}

/*
 * Remove emplaced single-step breakpoints, returning true if we hit one of
 * them.
 */
static bool kgdb_arch_undo_singlestep(struct pt_regs *regs)
{
	bool hit = false;
	u8 *x = kgdb_sstep_bp_addr[0], *y = kgdb_sstep_bp_addr[1];
	u8 opcode;

	if (kgdb_sstep_thread == current_thread_info()) {
		if (x) {
			if (x == (u8 *)regs->pc)
				hit = true;
			if (probe_kernel_read(&opcode, x,
					      1) < 0 ||
			    opcode != 0xff)
				BUG();
			probe_kernel_write(x, &kgdb_sstep_bp[0], 1);
			debugger_local_cache_flushinv_one(x);
		}
		if (y) {
			if (y == (u8 *)regs->pc)
				hit = true;
			if (probe_kernel_read(&opcode, y,
					      1) < 0 ||
			    opcode != 0xff)
				BUG();
			probe_kernel_write(y, &kgdb_sstep_bp[1], 1);
			debugger_local_cache_flushinv_one(y);
		}
	}

	kgdb_sstep_bp_addr[0] = NULL;
	kgdb_sstep_bp_addr[1] = NULL;
	kgdb_sstep_thread = NULL;
	return hit;
}

/*
 * Catch a single-step-pending thread being deleted and make sure the global
 * single-step state is cleared.  At this point the breakpoints should have
 * been removed by __switch_to().
 */
void free_thread_info(struct thread_info *ti)
{
	if (kgdb_sstep_thread == ti) {
		kgdb_sstep_thread = NULL;

		/* However, we may now be running in degraded mode, with most
		 * of the CPUs disabled until such a time as KGDB is reentered,
		 * so force immediate reentry */
		kgdb_breakpoint();
	}
	kfree(ti);
}

/*
 * Handle unknown packets and [CcsDk] packets
 * - at this point breakpoints have been installed
 */
int kgdb_arch_handle_exception(int vector, int signo, int err_code,
			       char *remcom_in_buffer, char *remcom_out_buffer,
			       struct pt_regs *regs)
{
	long addr;
	char *ptr;

	switch (remcom_in_buffer[0]) {
	case 'c':
	case 's':
		/* try to read optional parameter, pc unchanged if no parm */
		ptr = &remcom_in_buffer[1];
		if (kgdb_hex2long(&ptr, &addr))
			regs->pc = addr;
	case 'D':
	case 'k':
		atomic_set(&kgdb_cpu_doing_single_step, -1);

		if (remcom_in_buffer[0] == 's') {
			kgdb_arch_do_singlestep(regs);
			kgdb_single_step = 1;
			atomic_set(&kgdb_cpu_doing_single_step,
				   raw_smp_processor_id());
		}
		return 0;
	}
	return -1; /* this means that we do not want to exit from the handler */
}

/*
 * Handle event interception
 * - returns 0 if the exception should be skipped, -ERROR otherwise.
 */
int debugger_intercept(enum exception_code excep, int signo, int si_code,
		       struct pt_regs *regs)
{
	int ret;

	if (kgdb_arch_undo_singlestep(regs)) {
		excep = EXCEP_TRAP;
		signo = SIGTRAP;
		si_code = TRAP_TRACE;
	}

	ret = kgdb_handle_exception(excep, signo, si_code, regs);

	debugger_local_cache_flushinv();

	return ret;
}

/*
 * Determine if we've hit a debugger special breakpoint
 */
int at_debugger_breakpoint(struct pt_regs *regs)
{
	return regs->pc == (unsigned long)&__arch_kgdb_breakpoint;
}

/*
 * Initialise kgdb
 */
int kgdb_arch_init(void)
{
	return 0;
}

/*
 * Do something, perhaps, but don't know what.
 */
void kgdb_arch_exit(void)
{
}

#ifdef CONFIG_SMP
void debugger_nmi_interrupt(struct pt_regs *regs, enum exception_code code)
{
	kgdb_nmicallback(arch_smp_processor_id(), regs);
	debugger_local_cache_flushinv();
}

void kgdb_roundup_cpus(unsigned long flags)
{
	smp_jump_to_debugger();
}
#endif
