// SPDX-License-Identifier: GPL-2.0
/*
 * PA-RISC KGDB support
 *
 * Copyright (c) 2019 Sven Schnelle <svens@stackframe.org>
 *
 */

#include <linux/kgdb.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/notifier.h>
#include <linux/kdebug.h>
#include <linux/uaccess.h>
#include <asm/ptrace.h>
#include <asm/traps.h>
#include <asm/processor.h>
#include <asm/patch.h>
#include <asm/cacheflush.h>

const struct kgdb_arch arch_kgdb_ops = {
	.gdb_bpt_instr = { 0x03, 0xff, 0xa0, 0x1f }
};

static int __kgdb_notify(struct die_args *args, unsigned long cmd)
{
	struct pt_regs *regs = args->regs;

	if (kgdb_handle_exception(1, args->signr, cmd, regs))
		return NOTIFY_DONE;
	return NOTIFY_STOP;
}

static int kgdb_notify(struct notifier_block *self,
		       unsigned long cmd, void *ptr)
{
	unsigned long flags;
	int ret;

	local_irq_save(flags);
	ret = __kgdb_notify(ptr, cmd);
	local_irq_restore(flags);

	return ret;
}

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

int kgdb_arch_init(void)
{
	return register_die_notifier(&kgdb_notifier);
}

void kgdb_arch_exit(void)
{
	unregister_die_notifier(&kgdb_notifier);
}

void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
{
	struct parisc_gdb_regs *gr = (struct parisc_gdb_regs *)gdb_regs;

	memset(gr, 0, sizeof(struct parisc_gdb_regs));

	memcpy(gr->gpr, regs->gr, sizeof(gr->gpr));
	memcpy(gr->fr, regs->fr, sizeof(gr->fr));

	gr->sr0 = regs->sr[0];
	gr->sr1 = regs->sr[1];
	gr->sr2 = regs->sr[2];
	gr->sr3 = regs->sr[3];
	gr->sr4 = regs->sr[4];
	gr->sr5 = regs->sr[5];
	gr->sr6 = regs->sr[6];
	gr->sr7 = regs->sr[7];

	gr->sar = regs->sar;
	gr->iir = regs->iir;
	gr->isr = regs->isr;
	gr->ior = regs->ior;
	gr->ipsw = regs->ipsw;
	gr->cr27 = regs->cr27;

	gr->iaoq_f = regs->iaoq[0];
	gr->iasq_f = regs->iasq[0];

	gr->iaoq_b = regs->iaoq[1];
	gr->iasq_b = regs->iasq[1];
}

void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
{
	struct parisc_gdb_regs *gr = (struct parisc_gdb_regs *)gdb_regs;


	memcpy(regs->gr, gr->gpr, sizeof(regs->gr));
	memcpy(regs->fr, gr->fr, sizeof(regs->fr));

	regs->sr[0] = gr->sr0;
	regs->sr[1] = gr->sr1;
	regs->sr[2] = gr->sr2;
	regs->sr[3] = gr->sr3;
	regs->sr[4] = gr->sr4;
	regs->sr[5] = gr->sr5;
	regs->sr[6] = gr->sr6;
	regs->sr[7] = gr->sr7;

	regs->sar = gr->sar;
	regs->iir = gr->iir;
	regs->isr = gr->isr;
	regs->ior = gr->ior;
	regs->ipsw = gr->ipsw;
	regs->cr27 = gr->cr27;

	regs->iaoq[0] = gr->iaoq_f;
	regs->iasq[0] = gr->iasq_f;

	regs->iaoq[1] = gr->iaoq_b;
	regs->iasq[1] = gr->iasq_b;
}

void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs,
				struct task_struct *task)
{
	struct pt_regs *regs = task_pt_regs(task);
	unsigned long gr30, iaoq;

	gr30 = regs->gr[30];
	iaoq = regs->iaoq[0];

	regs->gr[30] = regs->ksp;
	regs->iaoq[0] = regs->kpc;
	pt_regs_to_gdb_regs(gdb_regs, regs);

	regs->gr[30] = gr30;
	regs->iaoq[0] = iaoq;

}

static void step_instruction_queue(struct pt_regs *regs)
{
	regs->iaoq[0] = regs->iaoq[1];
	regs->iaoq[1] += 4;
}

void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip)
{
	regs->iaoq[0] = ip;
	regs->iaoq[1] = ip + 4;
}

int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
{
	int ret = copy_from_kernel_nofault(bpt->saved_instr,
			(char *)bpt->bpt_addr, BREAK_INSTR_SIZE);
	if (ret)
		return ret;

	__patch_text((void *)bpt->bpt_addr,
			*(unsigned int *)&arch_kgdb_ops.gdb_bpt_instr);
	return ret;
}

int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
{
	__patch_text((void *)bpt->bpt_addr, *(unsigned int *)&bpt->saved_instr);
	return 0;
}

int kgdb_arch_handle_exception(int trap, int signo,
		int err_code, char *inbuf, char *outbuf,
		struct pt_regs *regs)
{
	unsigned long addr;
	char *p = inbuf + 1;

	switch (inbuf[0]) {
	case 'D':
	case 'c':
	case 'k':
		kgdb_contthread = NULL;
		kgdb_single_step = 0;

		if (kgdb_hex2long(&p, &addr))
			kgdb_arch_set_pc(regs, addr);
		else if (trap == 9 && regs->iir ==
				PARISC_KGDB_COMPILED_BREAK_INSN)
			step_instruction_queue(regs);
		return 0;
	case 's':
		kgdb_single_step = 1;
		if (kgdb_hex2long(&p, &addr)) {
			kgdb_arch_set_pc(regs, addr);
		} else if (trap == 9 && regs->iir ==
				PARISC_KGDB_COMPILED_BREAK_INSN) {
			step_instruction_queue(regs);
			mtctl(-1, 0);
		} else {
			mtctl(0, 0);
		}
		regs->gr[0] |= PSW_R;
		return 0;

	}
	return -1;
}
