// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Nios2 KGDB support
 *
 * Copyright (C) 2015 Altera Corporation
 * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
 *
 * Based on the code posted by Kazuyasu on the Altera Forum at:
 * http://www.alteraforum.com/forum/showpost.php?p=77003&postcount=20
 */
#include <linux/ptrace.h>
#include <linux/kgdb.h>
#include <linux/kdebug.h>
#include <linux/io.h>

static int wait_for_remote_debugger;

struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
{
	{ "zero", GDB_SIZEOF_REG, -1 },
	{ "at", GDB_SIZEOF_REG, offsetof(struct pt_regs, r1) },
	{ "r2", GDB_SIZEOF_REG, offsetof(struct pt_regs, r2) },
	{ "r3", GDB_SIZEOF_REG, offsetof(struct pt_regs, r3) },
	{ "r4", GDB_SIZEOF_REG, offsetof(struct pt_regs, r4) },
	{ "r5", GDB_SIZEOF_REG, offsetof(struct pt_regs, r5) },
	{ "r6", GDB_SIZEOF_REG, offsetof(struct pt_regs, r6) },
	{ "r7", GDB_SIZEOF_REG, offsetof(struct pt_regs, r7) },
	{ "r8", GDB_SIZEOF_REG, offsetof(struct pt_regs, r8) },
	{ "r9", GDB_SIZEOF_REG, offsetof(struct pt_regs, r9) },
	{ "r10", GDB_SIZEOF_REG, offsetof(struct pt_regs, r10) },
	{ "r11", GDB_SIZEOF_REG, offsetof(struct pt_regs, r11) },
	{ "r12", GDB_SIZEOF_REG, offsetof(struct pt_regs, r12) },
	{ "r13", GDB_SIZEOF_REG, offsetof(struct pt_regs, r13) },
	{ "r14", GDB_SIZEOF_REG, offsetof(struct pt_regs, r14) },
	{ "r15", GDB_SIZEOF_REG, offsetof(struct pt_regs, r15) },
	{ "r16", GDB_SIZEOF_REG, -1 },
	{ "r17", GDB_SIZEOF_REG, -1 },
	{ "r18", GDB_SIZEOF_REG, -1 },
	{ "r19", GDB_SIZEOF_REG, -1 },
	{ "r20", GDB_SIZEOF_REG, -1 },
	{ "r21", GDB_SIZEOF_REG, -1 },
	{ "r22", GDB_SIZEOF_REG, -1 },
	{ "r23", GDB_SIZEOF_REG, -1 },
	{ "et", GDB_SIZEOF_REG, -1 },
	{ "bt", GDB_SIZEOF_REG, -1 },
	{ "gp", GDB_SIZEOF_REG, offsetof(struct pt_regs, gp) },
	{ "sp", GDB_SIZEOF_REG, offsetof(struct pt_regs, sp) },
	{ "fp", GDB_SIZEOF_REG, offsetof(struct pt_regs, fp) },
	{ "ea", GDB_SIZEOF_REG, -1 },
	{ "ba", GDB_SIZEOF_REG, -1 },
	{ "ra", GDB_SIZEOF_REG, offsetof(struct pt_regs, ra) },
	{ "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, ea) },
	{ "status", GDB_SIZEOF_REG, -1 },
	{ "estatus", GDB_SIZEOF_REG, offsetof(struct pt_regs, estatus) },
	{ "bstatus", GDB_SIZEOF_REG, -1 },
	{ "ienable", GDB_SIZEOF_REG, -1 },
	{ "ipending", GDB_SIZEOF_REG, -1},
	{ "cpuid", GDB_SIZEOF_REG, -1 },
	{ "ctl6", GDB_SIZEOF_REG, -1 },
	{ "exception", GDB_SIZEOF_REG, -1 },
	{ "pteaddr", GDB_SIZEOF_REG, -1 },
	{ "tlbacc", GDB_SIZEOF_REG, -1 },
	{ "tlbmisc", GDB_SIZEOF_REG, -1 },
	{ "eccinj", GDB_SIZEOF_REG, -1 },
	{ "badaddr", GDB_SIZEOF_REG, -1 },
	{ "config", GDB_SIZEOF_REG, -1 },
	{ "mpubase", GDB_SIZEOF_REG, -1 },
	{ "mpuacc", GDB_SIZEOF_REG, -1 },
};

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;
}

void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
{
	memset((char *)gdb_regs, 0, NUMREGBYTES);
	gdb_regs[GDB_SP] = p->thread.kregs->sp;
	gdb_regs[GDB_PC] = p->thread.kregs->ea;
}

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

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 addr;

	switch (remcom_in_buffer[0]) {
	case 's':
	case 'c':
		/* handle the optional parameters */
		ptr = &remcom_in_buffer[1];
		if (kgdb_hex2long(&ptr, &addr))
			regs->ea = addr;

		return 0;
	}

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

asmlinkage void kgdb_breakpoint_c(struct pt_regs *regs)
{
	/*
	 * The breakpoint entry code has moved the PC on by 4 bytes, so we must
	 * move it back.  This could be done on the host but we do it here
	 */
	if (!wait_for_remote_debugger)
		regs->ea -= 4;
	else	/* pass the first trap 30 code */
		wait_for_remote_debugger = 0;

	kgdb_handle_exception(30, SIGTRAP, 0, regs);
}

int kgdb_arch_init(void)
{
	wait_for_remote_debugger = 1;
	return 0;
}

void kgdb_arch_exit(void)
{
	/* Nothing to do */
}

const struct kgdb_arch arch_kgdb_ops = {
	/* Breakpoint instruction: trap 30 */
	.gdb_bpt_instr = { 0xba, 0x6f, 0x3b, 0x00 },
};
