/*
 * Copyright 2010 Tilera Corporation. All Rights Reserved.
 *
 *   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, version 2.
 *
 *   This program is distributed in the hope that it will be useful, but
 *   WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 *   NON INFRINGEMENT.  See the GNU General Public License for
 *   more details.
 */

#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/kprobes.h>
#include <linux/module.h>
#include <linux/reboot.h>
#include <linux/uaccess.h>
#include <linux/ptrace.h>
#include <asm/opcode-tile.h>

#include <arch/interrupts.h>
#include <arch/spr_def.h>

void __init trap_init(void)
{
	/* Nothing needed here since we link code at .intrpt1 */
}

int unaligned_fixup = 1;

static int __init setup_unaligned_fixup(char *str)
{
	/*
	 * Say "=-1" to completely disable it.  If you just do "=0", we
	 * will still parse the instruction, then fire a SIGBUS with
	 * the correct address from inside the single_step code.
	 */
	long val;
	if (strict_strtol(str, 0, &val) != 0)
		return 0;
	unaligned_fixup = val;
	printk("Fixups for unaligned data accesses are %s\n",
	       unaligned_fixup >= 0 ?
	       (unaligned_fixup ? "enabled" : "disabled") :
	       "completely disabled");
	return 1;
}
__setup("unaligned_fixup=", setup_unaligned_fixup);

#if CHIP_HAS_TILE_DMA()

static int dma_disabled;

static int __init nodma(char *str)
{
	printk("User-space DMA is disabled\n");
	dma_disabled = 1;
	return 1;
}
__setup("nodma", nodma);

/* How to decode SPR_GPV_REASON */
#define IRET_ERROR (1U << 31)
#define MT_ERROR   (1U << 30)
#define MF_ERROR   (1U << 29)
#define SPR_INDEX  ((1U << 15) - 1)
#define SPR_MPL_SHIFT  9  /* starting bit position for MPL encoded in SPR */

/*
 * See if this GPV is just to notify the kernel of SPR use and we can
 * retry the user instruction after adjusting some MPLs suitably.
 */
static int retry_gpv(unsigned int gpv_reason)
{
	int mpl;

	if (gpv_reason & IRET_ERROR)
		return 0;

	BUG_ON((gpv_reason & (MT_ERROR|MF_ERROR)) == 0);
	mpl = (gpv_reason & SPR_INDEX) >> SPR_MPL_SHIFT;
	if (mpl == INT_DMA_NOTIFY && !dma_disabled) {
		/* User is turning on DMA. Allow it and retry. */
		printk(KERN_DEBUG "Process %d/%s is now enabled for DMA\n",
		       current->pid, current->comm);
		BUG_ON(current->thread.tile_dma_state.enabled);
		current->thread.tile_dma_state.enabled = 1;
		grant_dma_mpls();
		return 1;
	}

	return 0;
}

#endif /* CHIP_HAS_TILE_DMA() */

/* Defined inside do_trap(), below. */
#ifdef __tilegx__
extern tilegx_bundle_bits bpt_code;
#else
extern tile_bundle_bits bpt_code;
#endif

void __kprobes do_trap(struct pt_regs *regs, int fault_num,
		       unsigned long reason)
{
	siginfo_t info = { 0 };
	int signo, code;
	unsigned long address;
	__typeof__(bpt_code) instr;

	/* Re-enable interrupts. */
	local_irq_enable();

	/*
	 * If it hits in kernel mode and we can't fix it up, just exit the
	 * current process and hope for the best.
	 */
	if (!user_mode(regs)) {
		if (fixup_exception(regs))  /* only UNALIGN_DATA in practice */
			return;
		printk(KERN_ALERT "Kernel took bad trap %d at PC %#lx\n",
		       fault_num, regs->pc);
		if (fault_num == INT_GPV)
			printk(KERN_ALERT "GPV_REASON is %#lx\n", reason);
		show_regs(regs);
		do_exit(SIGKILL);  /* FIXME: implement i386 die() */
		return;
	}

	switch (fault_num) {
	case INT_ILL:
		asm(".pushsection .rodata.bpt_code,\"a\";"
		    ".align 8;"
		    "bpt_code: bpt;"
		    ".size bpt_code,.-bpt_code;"
		    ".popsection");

		if (copy_from_user(&instr, (void *)regs->pc, sizeof(instr))) {
			printk(KERN_ERR "Unreadable instruction for INT_ILL:"
			       " %#lx\n", regs->pc);
			do_exit(SIGKILL);
			return;
		}
		if (instr == bpt_code) {
			signo = SIGTRAP;
			code = TRAP_BRKPT;
		} else {
			signo = SIGILL;
			code = ILL_ILLOPC;
		}
		address = regs->pc;
		break;
	case INT_GPV:
#if CHIP_HAS_TILE_DMA()
		if (retry_gpv(reason))
			return;
#endif
		/*FALLTHROUGH*/
	case INT_UDN_ACCESS:
	case INT_IDN_ACCESS:
#if CHIP_HAS_SN()
	case INT_SN_ACCESS:
#endif
		signo = SIGILL;
		code = ILL_PRVREG;
		address = regs->pc;
		break;
	case INT_SWINT_3:
	case INT_SWINT_2:
	case INT_SWINT_0:
		signo = SIGILL;
		code = ILL_ILLTRP;
		address = regs->pc;
		break;
	case INT_UNALIGN_DATA:
#ifndef __tilegx__  /* FIXME: GX: no single-step yet */
		if (unaligned_fixup >= 0) {
			struct single_step_state *state =
				current_thread_info()->step_state;
			if (!state || (void *)(regs->pc) != state->buffer) {
				single_step_once(regs);
				return;
			}
		}
#endif
		signo = SIGBUS;
		code = BUS_ADRALN;
		address = 0;
		break;
	case INT_DOUBLE_FAULT:
		/*
		 * For double fault, "reason" is actually passed as
		 * SYSTEM_SAVE_1_2, the hypervisor's double-fault info, so
		 * we can provide the original fault number rather than
		 * the uninteresting "INT_DOUBLE_FAULT" so the user can
		 * learn what actually struck while PL0 ICS was set.
		 */
		fault_num = reason;
		signo = SIGILL;
		code = ILL_DBLFLT;
		address = regs->pc;
		break;
#ifdef __tilegx__
	case INT_ILL_TRANS:
		signo = SIGSEGV;
		code = SEGV_MAPERR;
		if (reason & SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK)
			address = regs->pc;
		else
			address = 0;  /* FIXME: GX: single-step for address */
		break;
#endif
	default:
		panic("Unexpected do_trap interrupt number %d", fault_num);
		return;
	}

	info.si_signo = signo;
	info.si_code = code;
	info.si_addr = (void *)address;
	if (signo == SIGILL)
		info.si_trapno = fault_num;
	force_sig_info(signo, &info, current);
}

extern void _dump_stack(int dummy, ulong pc, ulong lr, ulong sp, ulong r52);

void kernel_double_fault(int dummy, ulong pc, ulong lr, ulong sp, ulong r52)
{
	_dump_stack(dummy, pc, lr, sp, r52);
	printk("Double fault: exiting\n");
	machine_halt();
}
