/*
 *  linux/arch/ppc64/kernel/traps.c
 *
 *  Copyright (C) 1995-1996  Gary Thomas (gdt@linuxppc.org)
 *
 *  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; either version
 *  2 of the License, or (at your option) any later version.
 *
 *  Modified by Cort Dougan (cort@cs.nmt.edu)
 *  and Paul Mackerras (paulus@cs.anu.edu.au)
 */

/*
 * This file handles the architecture-dependent parts of hardware exceptions
 */

#include <linux/config.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <asm/kdebug.h>

#include <asm/pgtable.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/ppcdebug.h>
#include <asm/rtas.h>
#include <asm/systemcfg.h>
#include <asm/machdep.h>
#include <asm/pmc.h>

#ifdef CONFIG_DEBUGGER
int (*__debugger)(struct pt_regs *regs);
int (*__debugger_ipi)(struct pt_regs *regs);
int (*__debugger_bpt)(struct pt_regs *regs);
int (*__debugger_sstep)(struct pt_regs *regs);
int (*__debugger_iabr_match)(struct pt_regs *regs);
int (*__debugger_dabr_match)(struct pt_regs *regs);
int (*__debugger_fault_handler)(struct pt_regs *regs);

EXPORT_SYMBOL(__debugger);
EXPORT_SYMBOL(__debugger_ipi);
EXPORT_SYMBOL(__debugger_bpt);
EXPORT_SYMBOL(__debugger_sstep);
EXPORT_SYMBOL(__debugger_iabr_match);
EXPORT_SYMBOL(__debugger_dabr_match);
EXPORT_SYMBOL(__debugger_fault_handler);
#endif

struct notifier_block *ppc64_die_chain;
static DEFINE_SPINLOCK(die_notifier_lock);

int register_die_notifier(struct notifier_block *nb)
{
	int err = 0;
	unsigned long flags;

	spin_lock_irqsave(&die_notifier_lock, flags);
	err = notifier_chain_register(&ppc64_die_chain, nb);
	spin_unlock_irqrestore(&die_notifier_lock, flags);
	return err;
}

/*
 * Trap & Exception support
 */

static DEFINE_SPINLOCK(die_lock);

int die(const char *str, struct pt_regs *regs, long err)
{
	static int die_counter;
	int nl = 0;

	if (debugger(regs))
		return 1;

	console_verbose();
	spin_lock_irq(&die_lock);
	bust_spinlocks(1);
	printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
#ifdef CONFIG_PREEMPT
	printk("PREEMPT ");
	nl = 1;
#endif
#ifdef CONFIG_SMP
	printk("SMP NR_CPUS=%d ", NR_CPUS);
	nl = 1;
#endif
#ifdef CONFIG_DEBUG_PAGEALLOC
	printk("DEBUG_PAGEALLOC ");
	nl = 1;
#endif
#ifdef CONFIG_NUMA
	printk("NUMA ");
	nl = 1;
#endif
	switch(systemcfg->platform) {
		case PLATFORM_PSERIES:
			printk("PSERIES ");
			nl = 1;
			break;
		case PLATFORM_PSERIES_LPAR:
			printk("PSERIES LPAR ");
			nl = 1;
			break;
		case PLATFORM_ISERIES_LPAR:
			printk("ISERIES LPAR ");
			nl = 1;
			break;
		case PLATFORM_POWERMAC:
			printk("POWERMAC ");
			nl = 1;
			break;
	}
	if (nl)
		printk("\n");
	print_modules();
	show_regs(regs);
	bust_spinlocks(0);
	spin_unlock_irq(&die_lock);

	if (in_interrupt())
		panic("Fatal exception in interrupt");

	if (panic_on_oops) {
		printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
		ssleep(5);
		panic("Fatal exception");
	}
	do_exit(SIGSEGV);

	return 0;
}

void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
{
	siginfo_t info;

	if (!user_mode(regs)) {
		if (die("Exception in kernel mode", regs, signr))
			return;
	}

	memset(&info, 0, sizeof(info));
	info.si_signo = signr;
	info.si_code = code;
	info.si_addr = (void __user *) addr;
	force_sig_info(signr, &info, current);
}

void system_reset_exception(struct pt_regs *regs)
{
	/* See if any machine dependent calls */
	if (ppc_md.system_reset_exception)
		ppc_md.system_reset_exception(regs);

	die("System Reset", regs, 0);

	/* Must die if the interrupt is not recoverable */
	if (!(regs->msr & MSR_RI))
		panic("Unrecoverable System Reset");

	/* What should we do here? We could issue a shutdown or hard reset. */
}

void machine_check_exception(struct pt_regs *regs)
{
	int recover = 0;

	/* See if any machine dependent calls */
	if (ppc_md.machine_check_exception)
		recover = ppc_md.machine_check_exception(regs);

	if (recover)
		return;

	if (debugger_fault_handler(regs))
		return;
	die("Machine check", regs, 0);

	/* Must die if the interrupt is not recoverable */
	if (!(regs->msr & MSR_RI))
		panic("Unrecoverable Machine check");
}

void unknown_exception(struct pt_regs *regs)
{
	printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
	       regs->nip, regs->msr, regs->trap);

	_exception(SIGTRAP, regs, 0, 0);
}

void instruction_breakpoint_exception(struct pt_regs *regs)
{
	if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5,
					5, SIGTRAP) == NOTIFY_STOP)
		return;
	if (debugger_iabr_match(regs))
		return;
	_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
}

void single_step_exception(struct pt_regs *regs)
{
	regs->msr &= ~MSR_SE;  /* Turn off 'trace' bit */

	if (notify_die(DIE_SSTEP, "single_step", regs, 5,
					5, SIGTRAP) == NOTIFY_STOP)
		return;
	if (debugger_sstep(regs))
		return;

	_exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
}

/*
 * After we have successfully emulated an instruction, we have to
 * check if the instruction was being single-stepped, and if so,
 * pretend we got a single-step exception.  This was pointed out
 * by Kumar Gala.  -- paulus
 */
static inline void emulate_single_step(struct pt_regs *regs)
{
	if (regs->msr & MSR_SE)
		single_step_exception(regs);
}

static void parse_fpe(struct pt_regs *regs)
{
	int code = 0;
	unsigned long fpscr;

	flush_fp_to_thread(current);

	fpscr = current->thread.fpscr;

	/* Invalid operation */
	if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX))
		code = FPE_FLTINV;

	/* Overflow */
	else if ((fpscr & FPSCR_OE) && (fpscr & FPSCR_OX))
		code = FPE_FLTOVF;

	/* Underflow */
	else if ((fpscr & FPSCR_UE) && (fpscr & FPSCR_UX))
		code = FPE_FLTUND;

	/* Divide by zero */
	else if ((fpscr & FPSCR_ZE) && (fpscr & FPSCR_ZX))
		code = FPE_FLTDIV;

	/* Inexact result */
	else if ((fpscr & FPSCR_XE) && (fpscr & FPSCR_XX))
		code = FPE_FLTRES;

	_exception(SIGFPE, regs, code, regs->nip);
}

/*
 * Illegal instruction emulation support.  Return non-zero if we can't
 * emulate, or -EFAULT if the associated memory access caused an access
 * fault.  Return zero on success.
 */

#define INST_MFSPR_PVR		0x7c1f42a6
#define INST_MFSPR_PVR_MASK	0xfc1fffff

#define INST_DCBA		0x7c0005ec
#define INST_DCBA_MASK		0x7c0007fe

#define INST_MCRXR		0x7c000400
#define INST_MCRXR_MASK		0x7c0007fe

static int emulate_instruction(struct pt_regs *regs)
{
	unsigned int instword;

	if (!user_mode(regs))
		return -EINVAL;

	CHECK_FULL_REGS(regs);

	if (get_user(instword, (unsigned int __user *)(regs->nip)))
		return -EFAULT;

	/* Emulate the mfspr rD, PVR. */
	if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) {
		unsigned int rd;

		rd = (instword >> 21) & 0x1f;
		regs->gpr[rd] = mfspr(SPRN_PVR);
		return 0;
	}

	/* Emulating the dcba insn is just a no-op.  */
	if ((instword & INST_DCBA_MASK) == INST_DCBA) {
		static int warned;

		if (!warned) {
			printk(KERN_WARNING
			       "process %d (%s) uses obsolete 'dcba' insn\n",
			       current->pid, current->comm);
			warned = 1;
		}
		return 0;
	}

	/* Emulate the mcrxr insn.  */
	if ((instword & INST_MCRXR_MASK) == INST_MCRXR) {
		static int warned;
		unsigned int shift;

		if (!warned) {
			printk(KERN_WARNING
			       "process %d (%s) uses obsolete 'mcrxr' insn\n",
			       current->pid, current->comm);
			warned = 1;
		}

		shift = (instword >> 21) & 0x1c;
		regs->ccr &= ~(0xf0000000 >> shift);
		regs->ccr |= (regs->xer & 0xf0000000) >> shift;
		regs->xer &= ~0xf0000000;
		return 0;
	}

	return -EINVAL;
}

/*
 * Look through the list of trap instructions that are used for BUG(),
 * BUG_ON() and WARN_ON() and see if we hit one.  At this point we know
 * that the exception was caused by a trap instruction of some kind.
 * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0
 * otherwise.
 */
extern struct bug_entry __start___bug_table[], __stop___bug_table[];

#ifndef CONFIG_MODULES
#define module_find_bug(x)	NULL
#endif

struct bug_entry *find_bug(unsigned long bugaddr)
{
	struct bug_entry *bug;

	for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
		if (bugaddr == bug->bug_addr)
			return bug;
	return module_find_bug(bugaddr);
}

static int
check_bug_trap(struct pt_regs *regs)
{
	struct bug_entry *bug;
	unsigned long addr;

	if (regs->msr & MSR_PR)
		return 0;	/* not in kernel */
	addr = regs->nip;	/* address of trap instruction */
	if (addr < PAGE_OFFSET)
		return 0;
	bug = find_bug(regs->nip);
	if (bug == NULL)
		return 0;
	if (bug->line & BUG_WARNING_TRAP) {
		/* this is a WARN_ON rather than BUG/BUG_ON */
		printk(KERN_ERR "Badness in %s at %s:%d\n",
		       bug->function, bug->file,
		      (unsigned int)bug->line & ~BUG_WARNING_TRAP);
		show_stack(current, (void *)regs->gpr[1]);
		return 1;
	}
	printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n",
	       bug->function, bug->file, (unsigned int)bug->line);
	return 0;
}

void program_check_exception(struct pt_regs *regs)
{
	if (debugger_fault_handler(regs))
		return;

	if (regs->msr & 0x100000) {
		/* IEEE FP exception */
		parse_fpe(regs);
	} else if (regs->msr & 0x20000) {
		/* trap exception */

		if (notify_die(DIE_BPT, "breakpoint", regs, 5,
					5, SIGTRAP) == NOTIFY_STOP)
			return;
		if (debugger_bpt(regs))
			return;

		if (check_bug_trap(regs)) {
			regs->nip += 4;
			return;
		}
		_exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);

	} else {
		/* Privileged or illegal instruction; try to emulate it. */
		switch (emulate_instruction(regs)) {
		case 0:
			regs->nip += 4;
			emulate_single_step(regs);
			break;

		case -EFAULT:
			_exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
			break;

		default:
			if (regs->msr & 0x40000)
				/* priveleged */
				_exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
			else
				/* illegal */
				_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
			break;
		}
	}
}

void kernel_fp_unavailable_exception(struct pt_regs *regs)
{
	printk(KERN_EMERG "Unrecoverable FP Unavailable Exception "
			  "%lx at %lx\n", regs->trap, regs->nip);
	die("Unrecoverable FP Unavailable Exception", regs, SIGABRT);
}

void altivec_unavailable_exception(struct pt_regs *regs)
{
	if (user_mode(regs)) {
		/* A user program has executed an altivec instruction,
		   but this kernel doesn't support altivec. */
		_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
		return;
	}
	printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception "
			  "%lx at %lx\n", regs->trap, regs->nip);
	die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
}

extern perf_irq_t perf_irq;

void performance_monitor_exception(struct pt_regs *regs)
{
	perf_irq(regs);
}

void alignment_exception(struct pt_regs *regs)
{
	int fixed;

	fixed = fix_alignment(regs);

	if (fixed == 1) {
		regs->nip += 4;	/* skip over emulated instruction */
		emulate_single_step(regs);
		return;
	}

	/* Operand address was bad */	
	if (fixed == -EFAULT) {
		if (user_mode(regs)) {
			_exception(SIGSEGV, regs, SEGV_MAPERR, regs->dar);
		} else {
			/* Search exception table */
			bad_page_fault(regs, regs->dar, SIGSEGV);
		}

		return;
	}

	_exception(SIGBUS, regs, BUS_ADRALN, regs->nip);
}

#ifdef CONFIG_ALTIVEC
void altivec_assist_exception(struct pt_regs *regs)
{
	int err;
	siginfo_t info;

	if (!user_mode(regs)) {
		printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode"
		       " at %lx\n", regs->nip);
		die("Kernel VMX/Altivec assist exception", regs, SIGILL);
	}

	flush_altivec_to_thread(current);

	err = emulate_altivec(regs);
	if (err == 0) {
		regs->nip += 4;		/* skip emulated instruction */
		emulate_single_step(regs);
		return;
	}

	if (err == -EFAULT) {
		/* got an error reading the instruction */
		info.si_signo = SIGSEGV;
		info.si_errno = 0;
		info.si_code = SEGV_MAPERR;
		info.si_addr = (void __user *) regs->nip;
		force_sig_info(SIGSEGV, &info, current);
	} else {
		/* didn't recognize the instruction */
		/* XXX quick hack for now: set the non-Java bit in the VSCR */
		if (printk_ratelimit())
			printk(KERN_ERR "Unrecognized altivec instruction "
			       "in %s at %lx\n", current->comm, regs->nip);
		current->thread.vscr.u[3] |= 0x10000;
	}
}
#endif /* CONFIG_ALTIVEC */

/*
 * We enter here if we get an unrecoverable exception, that is, one
 * that happened at a point where the RI (recoverable interrupt) bit
 * in the MSR is 0.  This indicates that SRR0/1 are live, and that
 * we therefore lost state by taking this exception.
 */
void unrecoverable_exception(struct pt_regs *regs)
{
	printk(KERN_EMERG "Unrecoverable exception %lx at %lx\n",
	       regs->trap, regs->nip);
	die("Unrecoverable exception", regs, SIGABRT);
}

/*
 * We enter here if we discover during exception entry that we are
 * running in supervisor mode with a userspace value in the stack pointer.
 */
void kernel_bad_stack(struct pt_regs *regs)
{
	printk(KERN_EMERG "Bad kernel stack pointer %lx at %lx\n",
	       regs->gpr[1], regs->nip);
	die("Bad kernel stack pointer", regs, SIGABRT);
}

void __init trap_init(void)
{
}
