/*
 * 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 <linux/sched/task_stack.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;
}
