/*
 * Copyright 2013 Tilera Corporation. All Rights Reserved.
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   as published by the Free Software Foundation, version 2.
 *
 *   This program is distributed in the hope that it will be useful, but
 *   WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 *   NON INFRINGEMENT.  See the GNU General Public License for
 *   more details.
 *
 * TILE-Gx KGDB support.
 */

#include <linux/ptrace.h>
#include <linux/kgdb.h>
#include <linux/kdebug.h>
#include <linux/uaccess.h>
#include <linux/module.h>
#include <asm/cacheflush.h>

static tile_bundle_bits singlestep_insn = TILEGX_BPT_BUNDLE | DIE_SSTEPBP;
static unsigned long stepped_addr;
static tile_bundle_bits stepped_instr;

struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
	{ "r0", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[0])},
	{ "r1", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[1])},
	{ "r2", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[2])},
	{ "r3", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[3])},
	{ "r4", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[4])},
	{ "r5", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[5])},
	{ "r6", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[6])},
	{ "r7", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[7])},
	{ "r8", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[8])},
	{ "r9", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[9])},
	{ "r10", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[10])},
	{ "r11", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[11])},
	{ "r12", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[12])},
	{ "r13", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[13])},
	{ "r14", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[14])},
	{ "r15", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[15])},
	{ "r16", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[16])},
	{ "r17", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[17])},
	{ "r18", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[18])},
	{ "r19", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[19])},
	{ "r20", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[20])},
	{ "r21", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[21])},
	{ "r22", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[22])},
	{ "r23", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[23])},
	{ "r24", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[24])},
	{ "r25", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[25])},
	{ "r26", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[26])},
	{ "r27", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[27])},
	{ "r28", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[28])},
	{ "r29", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[29])},
	{ "r30", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[30])},
	{ "r31", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[31])},
	{ "r32", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[32])},
	{ "r33", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[33])},
	{ "r34", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[34])},
	{ "r35", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[35])},
	{ "r36", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[36])},
	{ "r37", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[37])},
	{ "r38", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[38])},
	{ "r39", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[39])},
	{ "r40", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[40])},
	{ "r41", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[41])},
	{ "r42", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[42])},
	{ "r43", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[43])},
	{ "r44", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[44])},
	{ "r45", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[45])},
	{ "r46", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[46])},
	{ "r47", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[47])},
	{ "r48", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[48])},
	{ "r49", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[49])},
	{ "r50", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[50])},
	{ "r51", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[51])},
	{ "r52", GDB_SIZEOF_REG, offsetof(struct pt_regs, regs[52])},
	{ "tp", GDB_SIZEOF_REG, offsetof(struct pt_regs, tp)},
	{ "sp", GDB_SIZEOF_REG, offsetof(struct pt_regs, sp)},
	{ "lr", GDB_SIZEOF_REG, offsetof(struct pt_regs, lr)},
	{ "sn", GDB_SIZEOF_REG, -1},
	{ "idn0", GDB_SIZEOF_REG, -1},
	{ "idn1", GDB_SIZEOF_REG, -1},
	{ "udn0", GDB_SIZEOF_REG, -1},
	{ "udn1", GDB_SIZEOF_REG, -1},
	{ "udn2", GDB_SIZEOF_REG, -1},
	{ "udn3", GDB_SIZEOF_REG, -1},
	{ "zero", GDB_SIZEOF_REG, -1},
	{ "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, pc)},
	{ "faultnum", GDB_SIZEOF_REG, offsetof(struct pt_regs, faultnum)},
};

char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
{
	if (regno >= DBG_MAX_REG_NUM || regno < 0)
		return NULL;

	if (dbg_reg_def[regno].offset != -1)
		memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
		       dbg_reg_def[regno].size);
	else
		memset(mem, 0, dbg_reg_def[regno].size);
	return dbg_reg_def[regno].name;
}

int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
{
	if (regno >= DBG_MAX_REG_NUM || regno < 0)
		return -EINVAL;

	if (dbg_reg_def[regno].offset != -1)
		memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
		       dbg_reg_def[regno].size);
	return 0;
}

/*
 * Similar to pt_regs_to_gdb_regs() except that process is sleeping and so
 * we may not be able to get all the info.
 */
void
sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
{
	struct pt_regs *thread_regs;
	const int NGPRS = TREG_LAST_GPR + 1;

	if (task == NULL)
		return;

	thread_regs = task_pt_regs(task);
	memcpy(gdb_regs, thread_regs, NGPRS * sizeof(unsigned long));
	memset(&gdb_regs[NGPRS], 0,
	       (TILEGX_PC_REGNUM - NGPRS) * sizeof(unsigned long));
	gdb_regs[TILEGX_PC_REGNUM] = thread_regs->pc;
	gdb_regs[TILEGX_FAULTNUM_REGNUM] = thread_regs->faultnum;
}

void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
{
	regs->pc = pc;
}

static void kgdb_call_nmi_hook(void *ignored)
{
	kgdb_nmicallback(raw_smp_processor_id(), NULL);
}

void kgdb_roundup_cpus(unsigned long flags)
{
	local_irq_enable();
	smp_call_function(kgdb_call_nmi_hook, NULL, 0);
	local_irq_disable();
}

/*
 * Convert a kernel address to the writable kernel text mapping.
 */
static unsigned long writable_address(unsigned long addr)
{
	unsigned long ret = 0;

	if (core_kernel_text(addr))
		ret = ktext_writable_addr(addr);
	else if (is_module_text_address(addr))
		ret = addr;
	else
		pr_err("Unknown virtual address 0x%lx\n", addr);

	return ret;
}

/*
 * Calculate the new address for after a step.
 */
static unsigned long get_step_address(struct pt_regs *regs)
{
	int src_reg;
	int jump_off;
	int br_off;
	unsigned long addr;
	unsigned int opcode;
	tile_bundle_bits bundle;

	/* Move to the next instruction by default. */
	addr = regs->pc + TILEGX_BUNDLE_SIZE_IN_BYTES;
	bundle = *(unsigned long *)instruction_pointer(regs);

	/* 0: X mode, Otherwise: Y mode. */
	if (bundle & TILEGX_BUNDLE_MODE_MASK) {
		if (get_Opcode_Y1(bundle) == RRR_1_OPCODE_Y1 &&
		    get_RRROpcodeExtension_Y1(bundle) ==
		    UNARY_RRR_1_OPCODE_Y1) {
			opcode = get_UnaryOpcodeExtension_Y1(bundle);

			switch (opcode) {
			case JALR_UNARY_OPCODE_Y1:
			case JALRP_UNARY_OPCODE_Y1:
			case JR_UNARY_OPCODE_Y1:
			case JRP_UNARY_OPCODE_Y1:
				src_reg = get_SrcA_Y1(bundle);
				dbg_get_reg(src_reg, &addr, regs);
				break;
			}
		}
	} else if (get_Opcode_X1(bundle) == RRR_0_OPCODE_X1) {
		if (get_RRROpcodeExtension_X1(bundle) ==
		    UNARY_RRR_0_OPCODE_X1) {
			opcode = get_UnaryOpcodeExtension_X1(bundle);

			switch (opcode) {
			case JALR_UNARY_OPCODE_X1:
			case JALRP_UNARY_OPCODE_X1:
			case JR_UNARY_OPCODE_X1:
			case JRP_UNARY_OPCODE_X1:
				src_reg = get_SrcA_X1(bundle);
				dbg_get_reg(src_reg, &addr, regs);
				break;
			}
		}
	} else if (get_Opcode_X1(bundle) == JUMP_OPCODE_X1) {
		opcode = get_JumpOpcodeExtension_X1(bundle);

		switch (opcode) {
		case JAL_JUMP_OPCODE_X1:
		case J_JUMP_OPCODE_X1:
			jump_off = sign_extend(get_JumpOff_X1(bundle), 27);
			addr = regs->pc +
				(jump_off << TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES);
			break;
		}
	} else if (get_Opcode_X1(bundle) == BRANCH_OPCODE_X1) {
		br_off = 0;
		opcode = get_BrType_X1(bundle);

		switch (opcode) {
		case BEQZT_BRANCH_OPCODE_X1:
		case BEQZ_BRANCH_OPCODE_X1:
			if (get_SrcA_X1(bundle) == 0)
				br_off = get_BrOff_X1(bundle);
			break;
		case BGEZT_BRANCH_OPCODE_X1:
		case BGEZ_BRANCH_OPCODE_X1:
			if (get_SrcA_X1(bundle) >= 0)
				br_off = get_BrOff_X1(bundle);
			break;
		case BGTZT_BRANCH_OPCODE_X1:
		case BGTZ_BRANCH_OPCODE_X1:
			if (get_SrcA_X1(bundle) > 0)
				br_off = get_BrOff_X1(bundle);
			break;
		case BLBCT_BRANCH_OPCODE_X1:
		case BLBC_BRANCH_OPCODE_X1:
			if (!(get_SrcA_X1(bundle) & 1))
				br_off = get_BrOff_X1(bundle);
			break;
		case BLBST_BRANCH_OPCODE_X1:
		case BLBS_BRANCH_OPCODE_X1:
			if (get_SrcA_X1(bundle) & 1)
				br_off = get_BrOff_X1(bundle);
			break;
		case BLEZT_BRANCH_OPCODE_X1:
		case BLEZ_BRANCH_OPCODE_X1:
			if (get_SrcA_X1(bundle) <= 0)
				br_off = get_BrOff_X1(bundle);
			break;
		case BLTZT_BRANCH_OPCODE_X1:
		case BLTZ_BRANCH_OPCODE_X1:
			if (get_SrcA_X1(bundle) < 0)
				br_off = get_BrOff_X1(bundle);
			break;
		case BNEZT_BRANCH_OPCODE_X1:
		case BNEZ_BRANCH_OPCODE_X1:
			if (get_SrcA_X1(bundle) != 0)
				br_off = get_BrOff_X1(bundle);
			break;
		}

		if (br_off != 0) {
			br_off = sign_extend(br_off, 17);
			addr = regs->pc +
				(br_off << TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES);
		}
	}

	return addr;
}

/*
 * Replace the next instruction after the current instruction with a
 * breakpoint instruction.
 */
static void do_single_step(struct pt_regs *regs)
{
	unsigned long addr_wr;

	/* Determine where the target instruction will send us to. */
	stepped_addr = get_step_address(regs);
	probe_kernel_read((char *)&stepped_instr, (char *)stepped_addr,
			  BREAK_INSTR_SIZE);

	addr_wr = writable_address(stepped_addr);
	probe_kernel_write((char *)addr_wr, (char *)&singlestep_insn,
			   BREAK_INSTR_SIZE);
	smp_wmb();
	flush_icache_range(stepped_addr, stepped_addr + BREAK_INSTR_SIZE);
}

static void undo_single_step(struct pt_regs *regs)
{
	unsigned long addr_wr;

	if (stepped_instr == 0)
		return;

	addr_wr = writable_address(stepped_addr);
	probe_kernel_write((char *)addr_wr, (char *)&stepped_instr,
			   BREAK_INSTR_SIZE);
	stepped_instr = 0;
	smp_wmb();
	flush_icache_range(stepped_addr, stepped_addr + BREAK_INSTR_SIZE);
}

/*
 * Calls linux_debug_hook before the kernel dies. If KGDB is enabled,
 * then try to fall into the debugger.
 */
static int
kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
{
	int ret;
	unsigned long flags;
	struct die_args *args = (struct die_args *)ptr;
	struct pt_regs *regs = args->regs;

#ifdef CONFIG_KPROBES
	/*
	 * Return immediately if the kprobes fault notifier has set
	 * DIE_PAGE_FAULT.
	 */
	if (cmd == DIE_PAGE_FAULT)
		return NOTIFY_DONE;
#endif /* CONFIG_KPROBES */

	switch (cmd) {
	case DIE_BREAK:
	case DIE_COMPILED_BPT:
		break;
	case DIE_SSTEPBP:
		local_irq_save(flags);
		kgdb_handle_exception(0, SIGTRAP, 0, regs);
		local_irq_restore(flags);
		return NOTIFY_STOP;
	default:
		/* Userspace events, ignore. */
		if (user_mode(regs))
			return NOTIFY_DONE;
	}

	local_irq_save(flags);
	ret = kgdb_handle_exception(args->trapnr, args->signr, args->err, regs);
	local_irq_restore(flags);
	if (ret)
		return NOTIFY_DONE;

	return NOTIFY_STOP;
}

static struct notifier_block kgdb_notifier = {
	.notifier_call = kgdb_notify,
};

/*
 * kgdb_arch_handle_exception - Handle architecture specific GDB packets.
 * @vector: The error vector of the exception that happened.
 * @signo: The signal number of the exception that happened.
 * @err_code: The error code of the exception that happened.
 * @remcom_in_buffer: The buffer of the packet we have read.
 * @remcom_out_buffer: The buffer of %BUFMAX bytes to write a packet into.
 * @regs: The &struct pt_regs of the current process.
 *
 * This function MUST handle the 'c' and 's' command packets,
 * as well packets to set / remove a hardware breakpoint, if used.
 * If there are additional packets which the hardware needs to handle,
 * they are handled here. The code should return -1 if it wants to
 * process more packets, and a %0 or %1 if it wants to exit from the
 * kgdb callback.
 */
int kgdb_arch_handle_exception(int vector, int signo, int err_code,
			       char *remcom_in_buffer, char *remcom_out_buffer,
			       struct pt_regs *regs)
{
	char *ptr;
	unsigned long address;

	/* Undo any stepping we may have done. */
	undo_single_step(regs);

	switch (remcom_in_buffer[0]) {
	case 'c':
	case 's':
	case 'D':
	case 'k':
		/*
		 * Try to read optional parameter, pc unchanged if no parm.
		 * If this was a compiled-in breakpoint, we need to move
		 * to the next instruction or we will just breakpoint
		 * over and over again.
		 */
		ptr = &remcom_in_buffer[1];
		if (kgdb_hex2long(&ptr, &address))
			regs->pc = address;
		else if (*(unsigned long *)regs->pc == compiled_bpt)
			regs->pc += BREAK_INSTR_SIZE;

		if (remcom_in_buffer[0] == 's') {
			do_single_step(regs);
			kgdb_single_step = 1;
			atomic_set(&kgdb_cpu_doing_single_step,
				   raw_smp_processor_id());
		} else
			atomic_set(&kgdb_cpu_doing_single_step, -1);

		return 0;
	}

	return -1; /* this means that we do not want to exit from the handler */
}

struct kgdb_arch arch_kgdb_ops;

/*
 * kgdb_arch_init - Perform any architecture specific initialization.
 *
 * This function will handle the initialization of any architecture
 * specific callbacks.
 */
int kgdb_arch_init(void)
{
	tile_bundle_bits bundle = TILEGX_BPT_BUNDLE;

	memcpy(arch_kgdb_ops.gdb_bpt_instr, &bundle, BREAK_INSTR_SIZE);
	return register_die_notifier(&kgdb_notifier);
}

/*
 * kgdb_arch_exit - Perform any architecture specific uninitialization.
 *
 * This function will handle the uninitialization of any architecture
 * specific callbacks, for dynamic registration and unregistration.
 */
void kgdb_arch_exit(void)
{
	unregister_die_notifier(&kgdb_notifier);
}

int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
{
	int err;
	unsigned long addr_wr = writable_address(bpt->bpt_addr);

	if (addr_wr == 0)
		return -1;

	err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,
				BREAK_INSTR_SIZE);
	if (err)
		return err;

	err = probe_kernel_write((char *)addr_wr, arch_kgdb_ops.gdb_bpt_instr,
				 BREAK_INSTR_SIZE);
	smp_wmb();
	flush_icache_range((unsigned long)bpt->bpt_addr,
			   (unsigned long)bpt->bpt_addr + BREAK_INSTR_SIZE);
	return err;
}

int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
{
	int err;
	unsigned long addr_wr = writable_address(bpt->bpt_addr);

	if (addr_wr == 0)
		return -1;

	err = probe_kernel_write((char *)addr_wr, (char *)bpt->saved_instr,
				 BREAK_INSTR_SIZE);
	smp_wmb();
	flush_icache_range((unsigned long)bpt->bpt_addr,
			   (unsigned long)bpt->bpt_addr + BREAK_INSTR_SIZE);
	return err;
}
