/*
 *  Meta exception handling.
 *
 *  Copyright (C) 2005,2006,2007,2008,2009,2012 Imagination Technologies Ltd.
 *
 * 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/export.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/sched/task.h>
#include <linux/sched/task_stack.h>
#include <linux/signal.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/preempt.h>
#include <linux/ptrace.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
#include <linux/kdebug.h>
#include <linux/kexec.h>
#include <linux/unistd.h>
#include <linux/smp.h>
#include <linux/slab.h>
#include <linux/syscalls.h>

#include <asm/bug.h>
#include <asm/core_reg.h>
#include <asm/irqflags.h>
#include <asm/siginfo.h>
#include <asm/traps.h>
#include <asm/hwthread.h>
#include <asm/setup.h>
#include <asm/switch.h>
#include <asm/user_gateway.h>
#include <asm/syscall.h>
#include <asm/syscalls.h>

/* Passing syscall arguments as long long is quicker. */
typedef unsigned int (*LPSYSCALL) (unsigned long long,
				   unsigned long long,
				   unsigned long long);

/*
 * Users of LNKSET should compare the bus error bits obtained from DEFR
 * against TXDEFR_LNKSET_SUCCESS only as the failure code will vary between
 * different cores revisions.
 */
#define TXDEFR_LNKSET_SUCCESS 0x02000000
#define TXDEFR_LNKSET_FAILURE 0x04000000

/*
 * Our global TBI handle.  Initialised from setup.c/setup_arch.
 */
DECLARE_PER_CPU(PTBI, pTBI);

#ifdef CONFIG_SMP
static DEFINE_PER_CPU(unsigned int, trigger_mask);
#else
unsigned int global_trigger_mask;
EXPORT_SYMBOL(global_trigger_mask);
#endif

unsigned long per_cpu__stack_save[NR_CPUS];

static const char * const trap_names[] = {
	[TBIXXF_SIGNUM_IIF] = "Illegal instruction fault",
	[TBIXXF_SIGNUM_PGF] = "Privilege violation",
	[TBIXXF_SIGNUM_DHF] = "Unaligned data access fault",
	[TBIXXF_SIGNUM_IGF] = "Code fetch general read failure",
	[TBIXXF_SIGNUM_DGF] = "Data access general read/write fault",
	[TBIXXF_SIGNUM_IPF] = "Code fetch page fault",
	[TBIXXF_SIGNUM_DPF] = "Data access page fault",
	[TBIXXF_SIGNUM_IHF] = "Instruction breakpoint",
	[TBIXXF_SIGNUM_DWF] = "Read-only data access fault",
};

const char *trap_name(int trapno)
{
	if (trapno >= 0 && trapno < ARRAY_SIZE(trap_names)
			&& trap_names[trapno])
		return trap_names[trapno];
	return "Unknown fault";
}

static DEFINE_SPINLOCK(die_lock);

void __noreturn die(const char *str, struct pt_regs *regs,
		    long err, unsigned long addr)
{
	static int die_counter;

	oops_enter();

	spin_lock_irq(&die_lock);
	console_verbose();
	bust_spinlocks(1);
	pr_err("%s: err %04lx (%s) addr %08lx [#%d]\n", str, err & 0xffff,
	       trap_name(err & 0xffff), addr, ++die_counter);

	print_modules();
	show_regs(regs);

	pr_err("Process: %s (pid: %d, stack limit = %p)\n", current->comm,
	       task_pid_nr(current), task_stack_page(current) + THREAD_SIZE);

	bust_spinlocks(0);
	add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
	if (kexec_should_crash(current))
		crash_kexec(regs);

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

	if (panic_on_oops)
		panic("Fatal exception");

	spin_unlock_irq(&die_lock);
	oops_exit();
	do_exit(SIGSEGV);
}

#ifdef CONFIG_METAG_DSP
/*
 * The ECH encoding specifies the size of a DSPRAM as,
 *
 *		"slots" / 4
 *
 * A "slot" is the size of two DSPRAM bank entries; an entry from
 * DSPRAM bank A and an entry from DSPRAM bank B. One DSPRAM bank
 * entry is 4 bytes.
 */
#define SLOT_SZ	8
static inline unsigned int decode_dspram_size(unsigned int size)
{
	unsigned int _sz = size & 0x7f;

	return _sz * SLOT_SZ * 4;
}

static void dspram_save(struct meta_ext_context *dsp_ctx,
			unsigned int ramA_sz, unsigned int ramB_sz)
{
	unsigned int ram_sz[2];
	int i;

	ram_sz[0] = ramA_sz;
	ram_sz[1] = ramB_sz;

	for (i = 0; i < 2; i++) {
		if (ram_sz[i] != 0) {
			unsigned int sz;

			if (i == 0)
				sz = decode_dspram_size(ram_sz[i] >> 8);
			else
				sz = decode_dspram_size(ram_sz[i]);

			if (dsp_ctx->ram[i] == NULL) {
				dsp_ctx->ram[i] = kmalloc(sz, GFP_KERNEL);

				if (dsp_ctx->ram[i] == NULL)
					panic("couldn't save DSP context");
			} else {
				if (ram_sz[i] > dsp_ctx->ram_sz[i]) {
					kfree(dsp_ctx->ram[i]);

					dsp_ctx->ram[i] = kmalloc(sz,
								  GFP_KERNEL);

					if (dsp_ctx->ram[i] == NULL)
						panic("couldn't save DSP context");
				}
			}

			if (i == 0)
				__TBIDspramSaveA(ram_sz[i], dsp_ctx->ram[i]);
			else
				__TBIDspramSaveB(ram_sz[i], dsp_ctx->ram[i]);

			dsp_ctx->ram_sz[i] = ram_sz[i];
		}
	}
}
#endif /* CONFIG_METAG_DSP */

/*
 * Allow interrupts to be nested and save any "extended" register
 * context state, e.g. DSP regs and RAMs.
 */
static void nest_interrupts(TBIRES State, unsigned long mask)
{
#ifdef CONFIG_METAG_DSP
	struct meta_ext_context *dsp_ctx;
	unsigned int D0_8;

	/*
	 * D0.8 may contain an ECH encoding. The upper 16 bits
	 * tell us what DSP resources the current process is
	 * using. OR the bits into the SaveMask so that
	 * __TBINestInts() knows what resources to save as
	 * part of this context.
	 *
	 * Don't save the context if we're nesting interrupts in the
	 * kernel because the kernel doesn't use DSP hardware.
	 */
	D0_8 = __core_reg_get(D0.8);

	if (D0_8 && (State.Sig.SaveMask & TBICTX_PRIV_BIT)) {
		State.Sig.SaveMask |= (D0_8 >> 16);

		dsp_ctx = current->thread.dsp_context;
		if (dsp_ctx == NULL) {
			dsp_ctx = kzalloc(sizeof(*dsp_ctx), GFP_KERNEL);
			if (dsp_ctx == NULL)
				panic("couldn't save DSP context: ENOMEM");

			current->thread.dsp_context = dsp_ctx;
		}

		current->thread.user_flags |= (D0_8 & 0xffff0000);
		__TBINestInts(State, &dsp_ctx->regs, mask);
		dspram_save(dsp_ctx, D0_8 & 0x7f00, D0_8 & 0x007f);
	} else
		__TBINestInts(State, NULL, mask);
#else
	__TBINestInts(State, NULL, mask);
#endif
}

void head_end(TBIRES State, unsigned long mask)
{
	unsigned int savemask = (unsigned short)State.Sig.SaveMask;
	unsigned int ctx_savemask = (unsigned short)State.Sig.pCtx->SaveMask;

	if (savemask & TBICTX_PRIV_BIT) {
		ctx_savemask |= TBICTX_PRIV_BIT;
		current->thread.user_flags = savemask;
	}

	/* Always undo the sleep bit */
	ctx_savemask &= ~TBICTX_WAIT_BIT;

	/* Always save the catch buffer and RD pipe if they are dirty */
	savemask |= TBICTX_XCBF_BIT;

	/* Only save the catch and RD if we have not already done so.
	 * Note - the RD bits are in the pCtx only, and not in the
	 * State.SaveMask.
	 */
	if ((savemask & TBICTX_CBUF_BIT) ||
	    (ctx_savemask & TBICTX_CBRP_BIT)) {
		/* Have we already saved the buffers though?
		 * - See TestTrack 5071 */
		if (ctx_savemask & TBICTX_XCBF_BIT) {
			/* Strip off the bits so the call to __TBINestInts
			 * won't save the buffers again. */
			savemask &= ~TBICTX_CBUF_BIT;
			ctx_savemask &= ~TBICTX_CBRP_BIT;
		}
	}

#ifdef CONFIG_METAG_META21
	{
		unsigned int depth, txdefr;

		/*
		 * Save TXDEFR state.
		 *
		 * The process may have been interrupted after a LNKSET, but
		 * before it could read the DEFR state, so we mustn't lose that
		 * state or it could end up retrying an atomic operation that
		 * succeeded.
		 *
		 * All interrupts are disabled at this point so we
		 * don't need to perform any locking. We must do this
		 * dance before we use LNKGET or LNKSET.
		 */
		BUG_ON(current->thread.int_depth > HARDIRQ_BITS);

		depth = current->thread.int_depth++;

		txdefr = __core_reg_get(TXDEFR);

		txdefr &= TXDEFR_BUS_STATE_BITS;
		if (txdefr & TXDEFR_LNKSET_SUCCESS)
			current->thread.txdefr_failure &= ~(1 << depth);
		else
			current->thread.txdefr_failure |= (1 << depth);
	}
#endif

	State.Sig.SaveMask = savemask;
	State.Sig.pCtx->SaveMask = ctx_savemask;

	nest_interrupts(State, mask);

#ifdef CONFIG_METAG_POISON_CATCH_BUFFERS
	/* Poison the catch registers.  This shows up any mistakes we have
	 * made in their handling MUCH quicker.
	 */
	__core_reg_set(TXCATCH0, 0x87650021);
	__core_reg_set(TXCATCH1, 0x87654322);
	__core_reg_set(TXCATCH2, 0x87654323);
	__core_reg_set(TXCATCH3, 0x87654324);
#endif /* CONFIG_METAG_POISON_CATCH_BUFFERS */
}

TBIRES tail_end_sys(TBIRES State, int syscall, int *restart)
{
	struct pt_regs *regs = (struct pt_regs *)State.Sig.pCtx;
	unsigned long flags;

	local_irq_disable();

	if (user_mode(regs)) {
		flags = current_thread_info()->flags;
		if (flags & _TIF_WORK_MASK &&
		    do_work_pending(regs, flags, syscall)) {
			*restart = 1;
			return State;
		}

#ifdef CONFIG_METAG_FPU
		if (current->thread.fpu_context &&
		    current->thread.fpu_context->needs_restore) {
			__TBICtxFPURestore(State, current->thread.fpu_context);
			/*
			 * Clearing this bit ensures the FP unit is not made
			 * active again unless it is used.
			 */
			State.Sig.SaveMask &= ~TBICTX_FPAC_BIT;
			current->thread.fpu_context->needs_restore = false;
		}
		State.Sig.TrigMask |= TBI_TRIG_BIT(TBID_SIGNUM_DFR);
#endif
	}

	/* TBI will turn interrupts back on at some point. */
	if (!irqs_disabled_flags((unsigned long)State.Sig.TrigMask))
		trace_hardirqs_on();

#ifdef CONFIG_METAG_DSP
	/*
	 * If we previously saved an extended context then restore it
	 * now. Otherwise, clear D0.8 because this process is not
	 * using DSP hardware.
	 */
	if (State.Sig.pCtx->SaveMask & TBICTX_XEXT_BIT) {
		unsigned int D0_8;
		struct meta_ext_context *dsp_ctx = current->thread.dsp_context;

		/* Make sure we're going to return to userland. */
		BUG_ON(current->thread.int_depth != 1);

		if (dsp_ctx->ram_sz[0] > 0)
			__TBIDspramRestoreA(dsp_ctx->ram_sz[0],
					    dsp_ctx->ram[0]);
		if (dsp_ctx->ram_sz[1] > 0)
			__TBIDspramRestoreB(dsp_ctx->ram_sz[1],
					    dsp_ctx->ram[1]);

		State.Sig.SaveMask |= State.Sig.pCtx->SaveMask;
		__TBICtxRestore(State, current->thread.dsp_context);
		D0_8 = __core_reg_get(D0.8);
		D0_8 |= current->thread.user_flags & 0xffff0000;
		D0_8 |= (dsp_ctx->ram_sz[1] | dsp_ctx->ram_sz[0]) & 0xffff;
		__core_reg_set(D0.8, D0_8);
	} else
		__core_reg_set(D0.8, 0);
#endif /* CONFIG_METAG_DSP */

#ifdef CONFIG_METAG_META21
	{
		unsigned int depth, txdefr;

		/*
		 * If there hasn't been a LNKSET since the last LNKGET then the
		 * link flag will be set, causing the next LNKSET to succeed if
		 * the addresses match. The two LNK operations may not be a pair
		 * (e.g. see atomic_read()), so the LNKSET should fail.
		 * We use a conditional-never LNKSET to clear the link flag
		 * without side effects.
		 */
		asm volatile("LNKSETDNV [D0Re0],D0Re0");

		depth = --current->thread.int_depth;

		BUG_ON(user_mode(regs) && depth);

		txdefr = __core_reg_get(TXDEFR);

		txdefr &= ~TXDEFR_BUS_STATE_BITS;

		/* Do we need to restore a failure code into TXDEFR? */
		if (current->thread.txdefr_failure & (1 << depth))
			txdefr |= (TXDEFR_LNKSET_FAILURE | TXDEFR_BUS_TRIG_BIT);
		else
			txdefr |= (TXDEFR_LNKSET_SUCCESS | TXDEFR_BUS_TRIG_BIT);

		__core_reg_set(TXDEFR, txdefr);
	}
#endif
	return State;
}

#ifdef CONFIG_SMP
/*
 * If we took an interrupt in the middle of __kuser_get_tls then we need
 * to rewind the PC to the start of the function in case the process
 * gets migrated to another thread (SMP only) and it reads the wrong tls
 * data.
 */
static inline void _restart_critical_section(TBIRES State)
{
	unsigned long get_tls_start;
	unsigned long get_tls_end;

	get_tls_start = (unsigned long)__kuser_get_tls -
		(unsigned long)&__user_gateway_start;

	get_tls_start += USER_GATEWAY_PAGE;

	get_tls_end = (unsigned long)__kuser_get_tls_end -
		(unsigned long)&__user_gateway_start;

	get_tls_end += USER_GATEWAY_PAGE;

	if ((State.Sig.pCtx->CurrPC >= get_tls_start) &&
	    (State.Sig.pCtx->CurrPC < get_tls_end))
		State.Sig.pCtx->CurrPC = get_tls_start;
}
#else
/*
 * If we took an interrupt in the middle of
 * __kuser_cmpxchg then we need to rewind the PC to the
 * start of the function.
 */
static inline void _restart_critical_section(TBIRES State)
{
	unsigned long cmpxchg_start;
	unsigned long cmpxchg_end;

	cmpxchg_start = (unsigned long)__kuser_cmpxchg -
		(unsigned long)&__user_gateway_start;

	cmpxchg_start += USER_GATEWAY_PAGE;

	cmpxchg_end = (unsigned long)__kuser_cmpxchg_end -
		(unsigned long)&__user_gateway_start;

	cmpxchg_end += USER_GATEWAY_PAGE;

	if ((State.Sig.pCtx->CurrPC >= cmpxchg_start) &&
	    (State.Sig.pCtx->CurrPC < cmpxchg_end))
		State.Sig.pCtx->CurrPC = cmpxchg_start;
}
#endif

/* Used by kick_handler() */
void restart_critical_section(TBIRES State)
{
	_restart_critical_section(State);
}

TBIRES trigger_handler(TBIRES State, int SigNum, int Triggers, int Inst,
		       PTBI pTBI)
{
	head_end(State, ~INTS_OFF_MASK);

	/* If we interrupted user code handle any critical sections. */
	if (State.Sig.SaveMask & TBICTX_PRIV_BIT)
		_restart_critical_section(State);

	trace_hardirqs_off();

	do_IRQ(SigNum, (struct pt_regs *)State.Sig.pCtx);

	return tail_end(State);
}

static unsigned int load_fault(PTBICTXEXTCB0 pbuf)
{
	return pbuf->CBFlags & TXCATCH0_READ_BIT;
}

static unsigned long fault_address(PTBICTXEXTCB0 pbuf)
{
	return pbuf->CBAddr;
}

static void unhandled_fault(struct pt_regs *regs, unsigned long addr,
			    int signo, int code, int trapno)
{
	if (user_mode(regs)) {
		siginfo_t info;

		if (show_unhandled_signals && unhandled_signal(current, signo)
		    && printk_ratelimit()) {

			pr_info("pid %d unhandled fault: pc 0x%08x, addr 0x%08lx, trap %d (%s)\n",
				current->pid, regs->ctx.CurrPC, addr,
				trapno, trap_name(trapno));
			print_vma_addr(" in ", regs->ctx.CurrPC);
			print_vma_addr(" rtp in ", regs->ctx.DX[4].U1);
			printk("\n");
			show_regs(regs);
		}

		info.si_signo = signo;
		info.si_errno = 0;
		info.si_code = code;
		info.si_addr = (__force void __user *)addr;
		info.si_trapno = trapno;
		force_sig_info(signo, &info, current);
	} else {
		die("Oops", regs, trapno, addr);
	}
}

static int handle_data_fault(PTBICTXEXTCB0 pcbuf, struct pt_regs *regs,
			     unsigned int data_address, int trapno)
{
	int ret;

	ret = do_page_fault(regs, data_address, !load_fault(pcbuf), trapno);

	return ret;
}

static unsigned long get_inst_fault_address(struct pt_regs *regs)
{
	return regs->ctx.CurrPC;
}

TBIRES fault_handler(TBIRES State, int SigNum, int Triggers,
		     int Inst, PTBI pTBI)
{
	struct pt_regs *regs = (struct pt_regs *)State.Sig.pCtx;
	PTBICTXEXTCB0 pcbuf = (PTBICTXEXTCB0)&regs->extcb0;
	unsigned long data_address;

	head_end(State, ~INTS_OFF_MASK);

	/* Hardware breakpoint or data watch */
	if ((SigNum == TBIXXF_SIGNUM_IHF) ||
	    ((SigNum == TBIXXF_SIGNUM_DHF) &&
	     (pcbuf[0].CBFlags & (TXCATCH0_WATCH1_BIT |
				  TXCATCH0_WATCH0_BIT)))) {
		State = __TBIUnExpXXX(State, SigNum, Triggers, Inst,
				      pTBI);
		return tail_end(State);
	}

	local_irq_enable();

	data_address = fault_address(pcbuf);

	switch (SigNum) {
	case TBIXXF_SIGNUM_IGF:
		/* 1st-level entry invalid (instruction fetch) */
	case TBIXXF_SIGNUM_IPF: {
		/* 2nd-level entry invalid (instruction fetch) */
		unsigned long addr = get_inst_fault_address(regs);
		do_page_fault(regs, addr, 0, SigNum);
		break;
	}

	case TBIXXF_SIGNUM_DGF:
		/* 1st-level entry invalid (data access) */
	case TBIXXF_SIGNUM_DPF:
		/* 2nd-level entry invalid (data access) */
	case TBIXXF_SIGNUM_DWF:
		/* Write to read only page */
		handle_data_fault(pcbuf, regs, data_address, SigNum);
		break;

	case TBIXXF_SIGNUM_IIF:
		/* Illegal instruction */
		unhandled_fault(regs, regs->ctx.CurrPC, SIGILL, ILL_ILLOPC,
				SigNum);
		break;

	case TBIXXF_SIGNUM_DHF:
		/* Unaligned access */
		unhandled_fault(regs, data_address, SIGBUS, BUS_ADRALN,
				SigNum);
		break;
	case TBIXXF_SIGNUM_PGF:
		/* Privilege violation */
		unhandled_fault(regs, data_address, SIGSEGV, SEGV_ACCERR,
				SigNum);
		break;
	default:
		BUG();
		break;
	}

	return tail_end(State);
}

static bool switch_is_syscall(unsigned int inst)
{
	return inst == __METAG_SW_ENCODING(SYS);
}

static bool switch_is_legacy_syscall(unsigned int inst)
{
	return inst == __METAG_SW_ENCODING(SYS_LEGACY);
}

static inline void step_over_switch(struct pt_regs *regs, unsigned int inst)
{
	regs->ctx.CurrPC += 4;
}

static inline int test_syscall_work(void)
{
	return current_thread_info()->flags & _TIF_WORK_SYSCALL_MASK;
}

TBIRES switch1_handler(TBIRES State, int SigNum, int Triggers,
		       int Inst, PTBI pTBI)
{
	struct pt_regs *regs = (struct pt_regs *)State.Sig.pCtx;
	unsigned int sysnumber;
	unsigned long long a1_a2, a3_a4, a5_a6;
	LPSYSCALL syscall_entry;
	int restart;

	head_end(State, ~INTS_OFF_MASK);

	/*
	 * If this is not a syscall SWITCH it could be a breakpoint.
	 */
	if (!switch_is_syscall(Inst)) {
		/*
		 * Alert the user if they're trying to use legacy system
		 * calls. This suggests they need to update their C
		 * library and build against up to date kernel headers.
		 */
		if (switch_is_legacy_syscall(Inst))
			pr_warn_once("WARNING: A legacy syscall was made. Your userland needs updating.\n");
		/*
		 * We don't know how to handle the SWITCH and cannot
		 * safely ignore it, so treat all unknown switches
		 * (including breakpoints) as traps.
		 */
		force_sig(SIGTRAP, current);
		return tail_end(State);
	}

	local_irq_enable();

restart_syscall:
	restart = 0;
	sysnumber = regs->ctx.DX[0].U1;

	if (test_syscall_work())
		sysnumber = syscall_trace_enter(regs);

	/* Skip over the SWITCH instruction - or you just get 'stuck' on it! */
	step_over_switch(regs, Inst);

	if (sysnumber >= __NR_syscalls) {
		pr_debug("unknown syscall number: %d\n", sysnumber);
		syscall_entry = (LPSYSCALL) sys_ni_syscall;
	} else {
		syscall_entry = (LPSYSCALL) sys_call_table[sysnumber];
	}

	/* Use 64bit loads for speed. */
	a5_a6 = *(unsigned long long *)&regs->ctx.DX[1];
	a3_a4 = *(unsigned long long *)&regs->ctx.DX[2];
	a1_a2 = *(unsigned long long *)&regs->ctx.DX[3];

	/* here is the actual call to the syscall handler functions */
	regs->ctx.DX[0].U0 = syscall_entry(a1_a2, a3_a4, a5_a6);

	if (test_syscall_work())
		syscall_trace_leave(regs);

	State = tail_end_sys(State, sysnumber, &restart);
	/* Handlerless restarts shouldn't go via userland */
	if (restart)
		goto restart_syscall;
	return State;
}

TBIRES switchx_handler(TBIRES State, int SigNum, int Triggers,
		       int Inst, PTBI pTBI)
{
	struct pt_regs *regs = (struct pt_regs *)State.Sig.pCtx;

	/*
	 * This can be caused by any user process simply executing an unusual
	 * SWITCH instruction. If there's no DA, __TBIUnExpXXX will cause the
	 * thread to stop, so signal a SIGTRAP instead.
	 */
	head_end(State, ~INTS_OFF_MASK);
	if (user_mode(regs))
		force_sig(SIGTRAP, current);
	else
		State = __TBIUnExpXXX(State, SigNum, Triggers, Inst, pTBI);
	return tail_end(State);
}

#ifdef CONFIG_METAG_META21
TBIRES fpe_handler(TBIRES State, int SigNum, int Triggers, int Inst, PTBI pTBI)
{
	struct pt_regs *regs = (struct pt_regs *)State.Sig.pCtx;
	unsigned int error_state = Triggers;
	siginfo_t info;

	head_end(State, ~INTS_OFF_MASK);

	local_irq_enable();

	info.si_signo = SIGFPE;

	if (error_state & TXSTAT_FPE_INVALID_BIT)
		info.si_code = FPE_FLTINV;
	else if (error_state & TXSTAT_FPE_DIVBYZERO_BIT)
		info.si_code = FPE_FLTDIV;
	else if (error_state & TXSTAT_FPE_OVERFLOW_BIT)
		info.si_code = FPE_FLTOVF;
	else if (error_state & TXSTAT_FPE_UNDERFLOW_BIT)
		info.si_code = FPE_FLTUND;
	else if (error_state & TXSTAT_FPE_INEXACT_BIT)
		info.si_code = FPE_FLTRES;
	else
		info.si_code = FPE_FIXME;
	info.si_errno = 0;
	info.si_addr = (__force void __user *)regs->ctx.CurrPC;
	force_sig_info(SIGFPE, &info, current);

	return tail_end(State);
}
#endif

#ifdef CONFIG_METAG_SUSPEND_MEM
struct traps_context {
	PTBIAPIFN fnSigs[TBID_SIGNUM_MAX + 1];
};

static struct traps_context *metag_traps_context;

int traps_save_context(void)
{
	unsigned long cpu = smp_processor_id();
	PTBI _pTBI = per_cpu(pTBI, cpu);
	struct traps_context *context;

	context = kzalloc(sizeof(*context), GFP_ATOMIC);
	if (!context)
		return -ENOMEM;

	memcpy(context->fnSigs, (void *)_pTBI->fnSigs, sizeof(context->fnSigs));

	metag_traps_context = context;
	return 0;
}

int traps_restore_context(void)
{
	unsigned long cpu = smp_processor_id();
	PTBI _pTBI = per_cpu(pTBI, cpu);
	struct traps_context *context = metag_traps_context;

	metag_traps_context = NULL;

	memcpy((void *)_pTBI->fnSigs, context->fnSigs, sizeof(context->fnSigs));

	kfree(context);
	return 0;
}
#endif

#ifdef CONFIG_SMP
static inline unsigned int _get_trigger_mask(void)
{
	unsigned long cpu = smp_processor_id();
	return per_cpu(trigger_mask, cpu);
}

unsigned int get_trigger_mask(void)
{
	return _get_trigger_mask();
}
EXPORT_SYMBOL(get_trigger_mask);

static void set_trigger_mask(unsigned int mask)
{
	unsigned long cpu = smp_processor_id();
	per_cpu(trigger_mask, cpu) = mask;
}

void arch_local_irq_enable(void)
{
	preempt_disable();
	arch_local_irq_restore(_get_trigger_mask());
	preempt_enable_no_resched();
}
EXPORT_SYMBOL(arch_local_irq_enable);
#else
static void set_trigger_mask(unsigned int mask)
{
	global_trigger_mask = mask;
}
#endif

void per_cpu_trap_init(unsigned long cpu)
{
	TBIRES int_context;
	unsigned int thread = cpu_2_hwthread_id[cpu];

	set_trigger_mask(TBI_INTS_INIT(thread) | /* interrupts */
			 TBI_TRIG_BIT(TBID_SIGNUM_LWK) | /* low level kick */
			 TBI_TRIG_BIT(TBID_SIGNUM_SW1));

	/* non-priv - use current stack */
	int_context.Sig.pCtx = NULL;
	/* Start with interrupts off */
	int_context.Sig.TrigMask = INTS_OFF_MASK;
	int_context.Sig.SaveMask = 0;

	/* And call __TBIASyncTrigger() */
	__TBIASyncTrigger(int_context);
}

void __init trap_init(void)
{
	unsigned long cpu = smp_processor_id();
	PTBI _pTBI = per_cpu(pTBI, cpu);

	_pTBI->fnSigs[TBID_SIGNUM_XXF] = fault_handler;
	_pTBI->fnSigs[TBID_SIGNUM_SW0] = switchx_handler;
	_pTBI->fnSigs[TBID_SIGNUM_SW1] = switch1_handler;
	_pTBI->fnSigs[TBID_SIGNUM_SW2] = switchx_handler;
	_pTBI->fnSigs[TBID_SIGNUM_SW3] = switchx_handler;
	_pTBI->fnSigs[TBID_SIGNUM_LWK] = kick_handler;

#ifdef CONFIG_METAG_META21
	_pTBI->fnSigs[TBID_SIGNUM_DFR] = __TBIHandleDFR;
	_pTBI->fnSigs[TBID_SIGNUM_FPE] = fpe_handler;
#endif

	per_cpu_trap_init(cpu);
}

void tbi_startup_interrupt(int irq)
{
	unsigned long cpu = smp_processor_id();
	PTBI _pTBI = per_cpu(pTBI, cpu);

	BUG_ON(irq > TBID_SIGNUM_MAX);

	/* For TR1 and TR2, the thread id is encoded in the irq number */
	if (irq >= TBID_SIGNUM_T10 && irq < TBID_SIGNUM_TR3)
		cpu = hwthread_id_2_cpu[(irq - TBID_SIGNUM_T10) % 4];

	set_trigger_mask(get_trigger_mask() | TBI_TRIG_BIT(irq));

	_pTBI->fnSigs[irq] = trigger_handler;
}

void tbi_shutdown_interrupt(int irq)
{
	unsigned long cpu = smp_processor_id();
	PTBI _pTBI = per_cpu(pTBI, cpu);

	BUG_ON(irq > TBID_SIGNUM_MAX);

	set_trigger_mask(get_trigger_mask() & ~TBI_TRIG_BIT(irq));

	_pTBI->fnSigs[irq] = __TBIUnExpXXX;
}

int ret_from_fork(TBIRES arg)
{
	struct task_struct *prev = arg.Switch.pPara;
	struct task_struct *tsk = current;
	struct pt_regs *regs = task_pt_regs(tsk);
	int (*fn)(void *);
	TBIRES Next;

	schedule_tail(prev);

	if (tsk->flags & PF_KTHREAD) {
		fn = (void *)regs->ctx.DX[4].U1;
		BUG_ON(!fn);

		fn((void *)regs->ctx.DX[3].U1);
	}

	if (test_syscall_work())
		syscall_trace_leave(regs);

	preempt_disable();

	Next.Sig.TrigMask = get_trigger_mask();
	Next.Sig.SaveMask = 0;
	Next.Sig.pCtx = &regs->ctx;

	set_gateway_tls(current->thread.tls_ptr);

	preempt_enable_no_resched();

	/* And interrupts should come back on when we resume the real usermode
	 * code. Call __TBIASyncResume()
	 */
	__TBIASyncResume(tail_end(Next));
	/* ASyncResume should NEVER return */
	BUG();
	return 0;
}

void show_trace(struct task_struct *tsk, unsigned long *sp,
		struct pt_regs *regs)
{
	unsigned long addr;
#ifdef CONFIG_FRAME_POINTER
	unsigned long fp, fpnew;
	unsigned long stack;
#endif

	if (regs && user_mode(regs))
		return;

	printk("\nCall trace: ");
#ifdef CONFIG_KALLSYMS
	printk("\n");
#endif

	if (!tsk)
		tsk = current;

#ifdef CONFIG_FRAME_POINTER
	if (regs) {
		print_ip_sym(regs->ctx.CurrPC);
		fp = regs->ctx.AX[1].U0;
	} else {
		fp = __core_reg_get(A0FrP);
	}

	/* detect when the frame pointer has been used for other purposes and
	 * doesn't point to the stack (it may point completely elsewhere which
	 * kstack_end may not detect).
	 */
	stack = (unsigned long)task_stack_page(tsk);
	while (fp >= stack && fp + 8 <= stack + THREAD_SIZE) {
		addr = __raw_readl((unsigned long *)(fp + 4)) - 4;
		if (kernel_text_address(addr))
			print_ip_sym(addr);
		else
			break;
		/* stack grows up, so frame pointers must decrease */
		fpnew = __raw_readl((unsigned long *)(fp + 0));
		if (fpnew >= fp)
			break;
		fp = fpnew;
	}
#else
	while (!kstack_end(sp)) {
		addr = (*sp--) - 4;
		if (kernel_text_address(addr))
			print_ip_sym(addr);
	}
#endif

	printk("\n");

	debug_show_held_locks(tsk);
}

void show_stack(struct task_struct *tsk, unsigned long *sp)
{
	if (!tsk)
		tsk = current;
	if (tsk == current)
		sp = (unsigned long *)current_stack_pointer;
	else
		sp = (unsigned long *)tsk->thread.kernel_context->AX[0].U0;

	show_trace(tsk, sp, NULL);
}
