/*
 *  linux/arch/arm26/kernel/traps.c
 *
 *  Copyright (C) 1995-2002 Russell King
 *  Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
 *  Copyright (C) 2003 Ian Molton (ARM26)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 *  'traps.c' handles hardware exceptions after we have saved some state in
 *  'linux/arch/arm26/lib/traps.S'.  Mostly a debugging aid, but will probably
 *  kill the offending process.
 */

#include <linux/module.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/spinlock.h>
#include <linux/personality.h>
#include <linux/ptrace.h>
#include <linux/elf.h>
#include <linux/interrupt.h>
#include <linux/init.h>

#include <asm/atomic.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
#include <asm/semaphore.h>

#include "ptrace.h"

extern void c_backtrace (unsigned long fp, int pmode);
extern void show_pte(struct mm_struct *mm, unsigned long addr);

const char *processor_modes[] = { "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" };

static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" "*bad reason*"};

/*
 * Stack pointers should always be within the kernels view of
 * physical memory.  If it is not there, then we can't dump
 * out any information relating to the stack.
 */
static int verify_stack(unsigned long sp)
{
	if (sp < PAGE_OFFSET || (sp > (unsigned long)high_memory && high_memory != 0))
		return -EFAULT;

	return 0;
}

/*
 * Dump out the contents of some memory nicely...
 */
static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
{
	unsigned long p = bottom & ~31;
	mm_segment_t fs;
	int i;

	/*
	 * We need to switch to kernel mode so that we can use __get_user
	 * to safely read from kernel space.  Note that we now dump the
	 * code first, just in case the backtrace kills us.
	 */
	fs = get_fs();
	set_fs(KERNEL_DS);

	printk("%s", str);
	printk("(0x%08lx to 0x%08lx)\n", bottom, top);

	for (p = bottom & ~31; p < top;) {
		printk("%04lx: ", p & 0xffff);

		for (i = 0; i < 8; i++, p += 4) {
			unsigned int val;

			if (p < bottom || p >= top)
				printk("         ");
			else {
				__get_user(val, (unsigned long *)p);
				printk("%08x ", val);
			}
		}
		printk ("\n");
	}

	set_fs(fs);
}

static void dump_instr(struct pt_regs *regs)
{
	unsigned long addr = instruction_pointer(regs);
	const int width = 8;
	mm_segment_t fs;
	int i;

	/*
	 * We need to switch to kernel mode so that we can use __get_user
	 * to safely read from kernel space.  Note that we now dump the
	 * code first, just in case the backtrace kills us.
	 */
	fs = get_fs();
	set_fs(KERNEL_DS);

	printk("Code: ");
	for (i = -4; i < 1; i++) {
		unsigned int val, bad;

		bad = __get_user(val, &((u32 *)addr)[i]);

		if (!bad)
			printk(i == 0 ? "(%0*x) " : "%0*x ", width, val);
		else {
			printk("bad PC value.");
			break;
		}
	}
	printk("\n");

	set_fs(fs);
}

/*static*/ void __dump_stack(struct task_struct *tsk, unsigned long sp)
{
	dump_mem("Stack: ", sp, 8192+(unsigned long)task_stack_page(tsk));
}

void dump_stack(void)
{
#ifdef CONFIG_DEBUG_ERRORS
        __backtrace();
#endif
}

EXPORT_SYMBOL(dump_stack);

//FIXME - was a static fn
void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
{
	unsigned int fp;
	int ok = 1;

	printk("Backtrace: ");
	fp = regs->ARM_fp;
	if (!fp) {
		printk("no frame pointer");
		ok = 0;
	} else if (verify_stack(fp)) {
		printk("invalid frame pointer 0x%08x", fp);
		ok = 0;
	} else if (fp < (unsigned long)end_of_stack(tsk))
		printk("frame pointer underflow");
	printk("\n");

	if (ok)
		c_backtrace(fp, processor_mode(regs));
}

/* FIXME - this is probably wrong.. */
void show_stack(struct task_struct *task, unsigned long *sp) {
	dump_mem("Stack: ", (unsigned long)sp, 8192+(unsigned long)task_stack_page(task));
}

DEFINE_SPINLOCK(die_lock);

/*
 * This function is protected against re-entrancy.
 */
NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
{
	struct task_struct *tsk = current;

	console_verbose();
	spin_lock_irq(&die_lock);

	printk("Internal error: %s: %x\n", str, err);
	printk("CPU: %d\n", smp_processor_id());
	show_regs(regs);
	printk("Process %s (pid: %d, stack limit = 0x%p)\n",
		current->comm, current->pid, end_of_stack(tsk));

	if (!user_mode(regs) || in_interrupt()) {
		__dump_stack(tsk, (unsigned long)(regs + 1));
		dump_backtrace(regs, tsk);
		dump_instr(regs);
	}
while(1);
	spin_unlock_irq(&die_lock);
	do_exit(SIGSEGV);
}

void die_if_kernel(const char *str, struct pt_regs *regs, int err)
{
	if (user_mode(regs))
    		return;

    	die(str, regs, err);
}

static DECLARE_MUTEX(undef_sem);
static int (*undef_hook)(struct pt_regs *);

int request_undef_hook(int (*fn)(struct pt_regs *))
{
	int ret = -EBUSY;

	down(&undef_sem);
	if (undef_hook == NULL) {
		undef_hook = fn;
		ret = 0;
	}
	up(&undef_sem);

	return ret;
}

int release_undef_hook(int (*fn)(struct pt_regs *))
{
	int ret = -EINVAL;

	down(&undef_sem);
	if (undef_hook == fn) {
		undef_hook = NULL;
		ret = 0;
	}
	up(&undef_sem);

	return ret;
}

static int undefined_extension(struct pt_regs *regs, unsigned int op)
{
	switch (op) {
	case 1:	/* 0xde01 / 0x?7f001f0 */
		ptrace_break(current, regs);
		return 0;
	}
	return 1;
}

asmlinkage void do_undefinstr(struct pt_regs *regs)
{
	siginfo_t info;
	void *pc;

	regs->ARM_pc -= 4;

	pc = (unsigned long *)instruction_pointer(regs); /* strip PSR */

	if (user_mode(regs)) {
		u32 instr;

		get_user(instr, (u32 *)pc);

		if ((instr & 0x0fff00ff) == 0x07f000f0 &&
		    undefined_extension(regs, (instr >> 8) & 255) == 0) {
			regs->ARM_pc += 4;
			return;
		}
	} else {
		if (undef_hook && undef_hook(regs) == 0) {
			regs->ARM_pc += 4;
			return;
		}
	}

#ifdef CONFIG_DEBUG_USER
	printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
		current->comm, current->pid, pc);
	dump_instr(regs);
#endif

	current->thread.error_code = 0;
	current->thread.trap_no = 6;

	info.si_signo = SIGILL;
	info.si_errno = 0;
	info.si_code  = ILL_ILLOPC;
	info.si_addr  = pc;

	force_sig_info(SIGILL, &info, current);

	die_if_kernel("Oops - undefined instruction", regs, 0);
}

asmlinkage void do_excpt(unsigned long address, struct pt_regs *regs, int mode)
{
	siginfo_t info;

#ifdef CONFIG_DEBUG_USER
	printk(KERN_INFO "%s (%d): address exception: pc=%08lx\n",
		current->comm, current->pid, instruction_pointer(regs));
	dump_instr(regs);
#endif

	current->thread.error_code = 0;
	current->thread.trap_no = 11;

	info.si_signo = SIGBUS;
	info.si_errno = 0;
	info.si_code  = BUS_ADRERR;
	info.si_addr  = (void *)address;

	force_sig_info(SIGBUS, &info, current);

	die_if_kernel("Oops - address exception", regs, mode);
}

asmlinkage void do_unexp_fiq (struct pt_regs *regs)
{
#ifndef CONFIG_IGNORE_FIQ
	printk("Hmm.  Unexpected FIQ received, but trying to continue\n");
	printk("You may have a hardware problem...\n");
#endif
}

/*
 * bad_mode handles the impossible case in the vectors.  If you see one of
 * these, then it's extremely serious, and could mean you have buggy hardware.
 * It never returns, and never tries to sync.  We hope that we can at least
 * dump out some state information...
 */
asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode)
{
	unsigned int vectors = vectors_base();

	console_verbose();

	printk(KERN_CRIT "Bad mode in %s handler detected: mode %s\n",
		handler[reason<5?reason:4], processor_modes[proc_mode]);

	/*
	 * Dump out the vectors and stub routines.  Maybe a better solution
	 * would be to dump them out only if we detect that they are corrupted.
	 */
	dump_mem(KERN_CRIT "Vectors: ", vectors, vectors + 0x40);
	dump_mem(KERN_CRIT "Stubs: ", vectors + 0x200, vectors + 0x4b8);

	die("Oops", regs, 0);
	local_irq_disable();
	panic("bad mode");
}

static int bad_syscall(int n, struct pt_regs *regs)
{
	struct thread_info *thread = current_thread_info();
	siginfo_t info;

	if (current->personality != PER_LINUX && thread->exec_domain->handler) {
		thread->exec_domain->handler(n, regs);
		return regs->ARM_r0;
	}

#ifdef CONFIG_DEBUG_USER
	printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
		current->pid, current->comm, n);
	dump_instr(regs);
#endif

	info.si_signo = SIGILL;
	info.si_errno = 0;
	info.si_code  = ILL_ILLTRP;
	info.si_addr  = (void *)instruction_pointer(regs) - 4;

	force_sig_info(SIGILL, &info, current);
	die_if_kernel("Oops", regs, n);
	return regs->ARM_r0;
}

static inline void
do_cache_op(unsigned long start, unsigned long end, int flags)
{
	struct vm_area_struct *vma;

	if (end < start)
		return;

	vma = find_vma(current->active_mm, start);
	if (vma && vma->vm_start < end) {
		if (start < vma->vm_start)
			start = vma->vm_start;
		if (end > vma->vm_end)
			end = vma->vm_end;
	}
}

/*
 * Handle all unrecognised system calls.
 *  0x9f0000 - 0x9fffff are some more esoteric system calls
 */
#define NR(x) ((__ARM_NR_##x) - __ARM_NR_BASE)
asmlinkage int arm_syscall(int no, struct pt_regs *regs)
{
	siginfo_t info;

	if ((no >> 16) != 0x9f)
		return bad_syscall(no, regs);

	switch (no & 0xffff) {
	case 0: /* branch through 0 */
		info.si_signo = SIGSEGV;
		info.si_errno = 0;
		info.si_code  = SEGV_MAPERR;
		info.si_addr  = NULL;

		force_sig_info(SIGSEGV, &info, current);

		die_if_kernel("branch through zero", regs, 0);
		return 0;

	case NR(breakpoint): /* SWI BREAK_POINT */
		ptrace_break(current, regs);
		return regs->ARM_r0;

	case NR(cacheflush):
		return 0;

	case NR(usr26):
		break;

	default:
		/* Calls 9f00xx..9f07ff are defined to return -ENOSYS
		   if not implemented, rather than raising SIGILL.  This
		   way the calling program can gracefully determine whether
		   a feature is supported.  */
		if (no <= 0x7ff)
			return -ENOSYS;
		break;
	}
#ifdef CONFIG_DEBUG_USER
	/*
	 * experience shows that these seem to indicate that
	 * something catastrophic has happened
	 */
	printk("[%d] %s: arm syscall %d\n", current->pid, current->comm, no);
	dump_instr(regs);
	if (user_mode(regs)) {
		show_regs(regs);
		c_backtrace(regs->ARM_fp, processor_mode(regs));
	}
#endif
	info.si_signo = SIGILL;
	info.si_errno = 0;
	info.si_code  = ILL_ILLTRP;
	info.si_addr  = (void *)instruction_pointer(regs) - 4;

	force_sig_info(SIGILL, &info, current);
	die_if_kernel("Oops", regs, no);
	return 0;
}

void __bad_xchg(volatile void *ptr, int size)
{
	printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
		__builtin_return_address(0), ptr, size);
	BUG();
}

/*
 * A data abort trap was taken, but we did not handle the instruction.
 * Try to abort the user program, or panic if it was the kernel.
 */
asmlinkage void
baddataabort(int code, unsigned long instr, struct pt_regs *regs)
{
	unsigned long addr = instruction_pointer(regs);
	siginfo_t info;

#ifdef CONFIG_DEBUG_USER
	printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
		current->pid, current->comm, code, instr);
	dump_instr(regs);
	show_pte(current->mm, addr);
#endif

	info.si_signo = SIGILL;
	info.si_errno = 0;
	info.si_code  = ILL_ILLOPC;
	info.si_addr  = (void *)addr;

	force_sig_info(SIGILL, &info, current);
	die_if_kernel("unknown data abort code", regs, instr);
}

volatile void __bug(const char *file, int line, void *data)
{
	printk(KERN_CRIT"kernel BUG at %s:%d!", file, line);
	if (data)
		printk(KERN_CRIT" - extra data = %p", data);
	printk("\n");
	*(int *)0 = 0;
}

void __readwrite_bug(const char *fn)
{
	printk("%s called, but not implemented", fn);
	BUG();
}

void __pte_error(const char *file, int line, unsigned long val)
{
	printk("%s:%d: bad pte %08lx.\n", file, line, val);
}

void __pmd_error(const char *file, int line, unsigned long val)
{
	printk("%s:%d: bad pmd %08lx.\n", file, line, val);
}

void __pgd_error(const char *file, int line, unsigned long val)
{
	printk("%s:%d: bad pgd %08lx.\n", file, line, val);
}

asmlinkage void __div0(void)
{
	printk("Division by zero in kernel.\n");
	dump_stack();
}

void abort(void)
{
	BUG();

	/* if that doesn't kill us, halt */
	panic("Oops failed to kill thread");
}

void __init trap_init(void)
{
	extern void __trap_init(unsigned long);
	unsigned long base = vectors_base();

	__trap_init(base);
	if (base != 0)
		printk(KERN_DEBUG "Relocating machine vectors to 0x%08lx\n",
			base);
}
