/*
 * Hardware exception handling
 *
 * Copyright (C) 2010 Tobias Klauser <tklauser@distanz.ch>
 * Copyright (C) 2004 Microtronix Datacom Ltd.
 * Copyright (C) 2001 Vic Phillips
 *
 * This file is subject to the terms and conditions of the GNU General
 * Public License.  See the file COPYING in the main directory of this
 * archive for more details.
 */

#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/export.h>
#include <linux/mm.h>
#include <linux/ptrace.h>

#include <asm/traps.h>
#include <asm/sections.h>
#include <linux/uaccess.h>

static DEFINE_SPINLOCK(die_lock);

static void _send_sig(int signo, int code, unsigned long addr)
{
	force_sig_fault(signo, code, (void __user *) addr);
}

void die(const char *str, struct pt_regs *regs, long err)
{
	console_verbose();
	spin_lock_irq(&die_lock);
	pr_warn("Oops: %s, sig: %ld\n", str, err);
	show_regs(regs);
	spin_unlock_irq(&die_lock);
	/*
	 * do_exit() should take care of panic'ing from an interrupt
	 * context so we don't handle it here
	 */
	do_exit(err);
}

void _exception(int signo, struct pt_regs *regs, int code, unsigned long addr)
{
	if (!user_mode(regs))
		die("Exception in kernel mode", regs, signo);

	_send_sig(signo, code, addr);
}

/*
 * The show_stack is an external API which we do not use ourselves.
 */

int kstack_depth_to_print = 48;

void show_stack(struct task_struct *task, unsigned long *stack)
{
	unsigned long *endstack, addr;
	int i;

	if (!stack) {
		if (task)
			stack = (unsigned long *)task->thread.ksp;
		else
			stack = (unsigned long *)&stack;
	}

	addr = (unsigned long) stack;
	endstack = (unsigned long *) PAGE_ALIGN(addr);

	pr_emerg("Stack from %08lx:", (unsigned long)stack);
	for (i = 0; i < kstack_depth_to_print; i++) {
		if (stack + 1 > endstack)
			break;
		if (i % 8 == 0)
			pr_emerg("\n       ");
		pr_emerg(" %08lx", *stack++);
	}

	pr_emerg("\nCall Trace:");
	i = 0;
	while (stack + 1 <= endstack) {
		addr = *stack++;
		/*
		 * If the address is either in the text segment of the
		 * kernel, or in the region which contains vmalloc'ed
		 * memory, it *may* be the address of a calling
		 * routine; if so, print it so that someone tracing
		 * down the cause of the crash will be able to figure
		 * out the call path that was taken.
		 */
		if (((addr >= (unsigned long) _stext) &&
		     (addr <= (unsigned long) _etext))) {
			if (i % 4 == 0)
				pr_emerg("\n       ");
			pr_emerg(" [<%08lx>]", addr);
			i++;
		}
	}
	pr_emerg("\n");
}

void __init trap_init(void)
{
	/* Nothing to do here */
}

/* Breakpoint handler */
asmlinkage void breakpoint_c(struct pt_regs *fp)
{
	/*
	 * 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
	 * because monitor.S of JTAG gdbserver does it too.
	 */
	fp->ea -= 4;
	_exception(SIGTRAP, fp, TRAP_BRKPT, fp->ea);
}

#ifndef CONFIG_NIOS2_ALIGNMENT_TRAP
/* Alignment exception handler */
asmlinkage void handle_unaligned_c(struct pt_regs *fp, int cause)
{
	unsigned long addr = RDCTL(CTL_BADADDR);

	cause >>= 2;
	fp->ea -= 4;

	if (fixup_exception(fp))
		return;

	if (!user_mode(fp)) {
		pr_alert("Unaligned access from kernel mode, this might be a hardware\n");
		pr_alert("problem, dump registers and restart the instruction\n");
		pr_alert("  BADADDR 0x%08lx\n", addr);
		pr_alert("  cause   %d\n", cause);
		pr_alert("  op-code 0x%08lx\n", *(unsigned long *)(fp->ea));
		show_regs(fp);
		return;
	}

	_exception(SIGBUS, fp, BUS_ADRALN, addr);
}
#endif /* CONFIG_NIOS2_ALIGNMENT_TRAP */

/* Illegal instruction handler */
asmlinkage void handle_illegal_c(struct pt_regs *fp)
{
	fp->ea -= 4;
	_exception(SIGILL, fp, ILL_ILLOPC, fp->ea);
}

/* Supervisor instruction handler */
asmlinkage void handle_supervisor_instr(struct pt_regs *fp)
{
	fp->ea -= 4;
	_exception(SIGILL, fp, ILL_PRVOPC, fp->ea);
}

/* Division error handler */
asmlinkage void handle_diverror_c(struct pt_regs *fp)
{
	fp->ea -= 4;
	_exception(SIGFPE, fp, FPE_INTDIV, fp->ea);
}

/* Unhandled exception handler */
asmlinkage void unhandled_exception(struct pt_regs *regs, int cause)
{
	unsigned long addr = RDCTL(CTL_BADADDR);

	cause /= 4;

	pr_emerg("Unhandled exception #%d in %s mode (badaddr=0x%08lx)\n",
			cause, user_mode(regs) ? "user" : "kernel", addr);

	regs->ea -= 4;
	show_regs(regs);

	pr_emerg("opcode: 0x%08lx\n", *(unsigned long *)(regs->ea));
}

asmlinkage void handle_trap_1_c(struct pt_regs *fp)
{
	_send_sig(SIGUSR1, 0, fp->ea);
}

asmlinkage void handle_trap_2_c(struct pt_regs *fp)
{
	_send_sig(SIGUSR2, 0, fp->ea);
}

asmlinkage void handle_trap_3_c(struct pt_regs *fp)
{
	_send_sig(SIGILL, ILL_ILLTRP, fp->ea);
}
