/*
 *  linux/arch/nios2/kernel/misaligned.c
 *
 *  basic emulation for mis-aligned accesses on the NIOS II cpu
 *  modelled after the version for arm in arm/alignment.c
 *
 *  Brad Parker <brad@heeltoe.com>
 *  Copyright (C) 2010 Ambient Corporation
 *  Copyright (c) 2010 Altera Corporation, San Jose, California, USA.
 *  Copyright (c) 2010 Arrow Electronics, Inc.
 *
 * 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/errno.h>
#include <linux/string.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <linux/seq_file.h>

#include <asm/traps.h>
#include <asm/unaligned.h>

/* instructions we emulate */
#define INST_LDHU	0x0b
#define INST_STH	0x0d
#define INST_LDH	0x0f
#define INST_STW	0x15
#define INST_LDW	0x17

static unsigned long ma_user, ma_kern, ma_skipped, ma_half, ma_word;

static unsigned int ma_usermode;
#define UM_WARN		0x01
#define UM_FIXUP	0x02
#define UM_SIGNAL	0x04
#define KM_WARN		0x08

/* see arch/nios2/include/asm/ptrace.h */
static u8 sys_stack_frame_reg_offset[] = {
	/* struct pt_regs */
	8, 9, 10, 11, 12, 13, 14, 15, 1, 2, 3, 4, 5, 6, 7, 0,
	/* struct switch_stack */
	16, 17, 18, 19, 20, 21, 22, 23, 0, 0, 0, 0, 0, 0, 0, 0
};

static int reg_offsets[32];

static inline u32 get_reg_val(struct pt_regs *fp, int reg)
{
	u8 *p = ((u8 *)fp) + reg_offsets[reg];

	return *(u32 *)p;
}

static inline void put_reg_val(struct pt_regs *fp, int reg, u32 val)
{
	u8 *p = ((u8 *)fp) + reg_offsets[reg];
	*(u32 *)p = val;
}

/*
 * (mis)alignment handler
 */
asmlinkage void handle_unaligned_c(struct pt_regs *fp, int cause)
{
	u32 isn, addr, val;
	int in_kernel;
	u8 a, b, d0, d1, d2, d3;
	u16 imm16;
	unsigned int fault;

	/* back up one instruction */
	fp->ea -= 4;

	if (fixup_exception(fp)) {
		ma_skipped++;
		return;
	}

	in_kernel = !user_mode(fp);

	isn = *(unsigned long *)(fp->ea);

	fault = 0;

	/* do fixup if in kernel or mode turned on */
	if (in_kernel || (ma_usermode & UM_FIXUP)) {
		/* decompose instruction */
		a = (isn >> 27) & 0x1f;
		b = (isn >> 22) & 0x1f;
		imm16 = (isn >> 6) & 0xffff;
		addr = get_reg_val(fp, a) + imm16;

		/* do fixup to saved registers */
		switch (isn & 0x3f) {
		case INST_LDHU:
			fault |= __get_user(d0, (u8 *)(addr+0));
			fault |= __get_user(d1, (u8 *)(addr+1));
			val = (d1 << 8) | d0;
			put_reg_val(fp, b, val);
			ma_half++;
			break;
		case INST_STH:
			val = get_reg_val(fp, b);
			d1 = val >> 8;
			d0 = val >> 0;

			pr_debug("sth: ra=%d (%08x) rb=%d (%08x), imm16 %04x addr %08x val %08x\n",
				a, get_reg_val(fp, a),
				b, get_reg_val(fp, b),
				imm16, addr, val);

			if (in_kernel) {
				*(u8 *)(addr+0) = d0;
				*(u8 *)(addr+1) = d1;
			} else {
				fault |= __put_user(d0, (u8 *)(addr+0));
				fault |= __put_user(d1, (u8 *)(addr+1));
			}
			ma_half++;
			break;
		case INST_LDH:
			fault |= __get_user(d0, (u8 *)(addr+0));
			fault |= __get_user(d1, (u8 *)(addr+1));
			val = (short)((d1 << 8) | d0);
			put_reg_val(fp, b, val);
			ma_half++;
			break;
		case INST_STW:
			val = get_reg_val(fp, b);
			d3 = val >> 24;
			d2 = val >> 16;
			d1 = val >> 8;
			d0 = val >> 0;
			if (in_kernel) {
				*(u8 *)(addr+0) = d0;
				*(u8 *)(addr+1) = d1;
				*(u8 *)(addr+2) = d2;
				*(u8 *)(addr+3) = d3;
			} else {
				fault |= __put_user(d0, (u8 *)(addr+0));
				fault |= __put_user(d1, (u8 *)(addr+1));
				fault |= __put_user(d2, (u8 *)(addr+2));
				fault |= __put_user(d3, (u8 *)(addr+3));
			}
			ma_word++;
			break;
		case INST_LDW:
			fault |= __get_user(d0, (u8 *)(addr+0));
			fault |= __get_user(d1, (u8 *)(addr+1));
			fault |= __get_user(d2, (u8 *)(addr+2));
			fault |= __get_user(d3, (u8 *)(addr+3));
			val = (d3 << 24) | (d2 << 16) | (d1 << 8) | d0;
			put_reg_val(fp, b, val);
			ma_word++;
			break;
		}
	}

	addr = RDCTL(CTL_BADADDR);
	cause >>= 2;

	if (fault) {
		if (in_kernel) {
			pr_err("fault during kernel misaligned fixup @ %#lx; addr 0x%08x; isn=0x%08x\n",
				fp->ea, (unsigned int)addr,
				(unsigned int)isn);
		} else {
			pr_err("fault during user misaligned fixup @ %#lx; isn=%08x addr=0x%08x sp=0x%08lx pid=%d\n",
				fp->ea,
				(unsigned int)isn, addr, fp->sp,
				current->pid);

			_exception(SIGSEGV, fp, SEGV_MAPERR, fp->ea);
			return;
		}
	}

	/*
	 * kernel mode -
	 *  note exception and skip bad instruction (return)
	 */
	if (in_kernel) {
		ma_kern++;
		fp->ea += 4;

		if (ma_usermode & KM_WARN) {
			pr_err("kernel unaligned access @ %#lx; BADADDR 0x%08x; cause=%d, isn=0x%08x\n",
				fp->ea,
				(unsigned int)addr, cause,
				(unsigned int)isn);
			/* show_regs(fp); */
		}

		return;
	}

	ma_user++;

	/*
	 * user mode -
	 *  possibly warn,
	 *  possibly send SIGBUS signal to process
	 */
	if (ma_usermode & UM_WARN) {
		pr_err("user unaligned access @ %#lx; isn=0x%08lx ea=0x%08lx ra=0x%08lx sp=0x%08lx\n",
			(unsigned long)addr, (unsigned long)isn,
			fp->ea, fp->ra, fp->sp);
	}

	if (ma_usermode & UM_SIGNAL)
		_exception(SIGBUS, fp, BUS_ADRALN, fp->ea);
	else
		fp->ea += 4;	/* else advance */
}

static void __init misaligned_calc_reg_offsets(void)
{
	int i, r, offset;

	/* pre-calc offsets of registers on sys call stack frame */
	offset = 0;

	/* struct pt_regs */
	for (i = 0; i < 16; i++) {
		r = sys_stack_frame_reg_offset[i];
		reg_offsets[r] = offset;
		offset += 4;
	}

	/* struct switch_stack */
	offset = -sizeof(struct switch_stack);
	for (i = 16; i < 32; i++) {
		r = sys_stack_frame_reg_offset[i];
		reg_offsets[r] = offset;
		offset += 4;
	}
}


static int __init misaligned_init(void)
{
	/* default mode - silent fix */
	ma_usermode = UM_FIXUP | KM_WARN;

	misaligned_calc_reg_offsets();

	return 0;
}

fs_initcall(misaligned_init);
