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

	if (task == NULL)
		return;

	/* Initialize to zero. */
	memset(gdb_regs, 0, NUMREGBYTES);

	thread_regs = task_pt_regs(task);
	memcpy(gdb_regs, thread_regs, TREG_LAST_GPR * 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 = addr - MEM_SV_START + PAGE_OFFSET;
	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 initalization.
 *
 * This function will handle the initalization 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 uninitalization.
 *
 * This function will handle the uninitalization 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;
}
