/*---------------------------------------------------------------------------+
 |  get_address.c                                                            |
 |                                                                           |
 | Get the effective address from an FPU instruction.                        |
 |                                                                           |
 | Copyright (C) 1992,1993,1994,1997                                         |
 |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
 |                       Australia.  E-mail   billm@suburbia.net             |
 |                                                                           |
 |                                                                           |
 +---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------+
 | Note:                                                                     |
 |    The file contains code which accesses user memory.                     |
 |    Emulator static data may change when user memory is accessed, due to   |
 |    other processes using the emulator while swapping is in progress.      |
 +---------------------------------------------------------------------------*/

#include <linux/stddef.h>

#include <linux/uaccess.h>
#include <asm/vm86.h>

#include "fpu_system.h"
#include "exception.h"
#include "fpu_emu.h"

#define FPU_WRITE_BIT 0x10

static int reg_offset[] = {
	offsetof(struct pt_regs, ax),
	offsetof(struct pt_regs, cx),
	offsetof(struct pt_regs, dx),
	offsetof(struct pt_regs, bx),
	offsetof(struct pt_regs, sp),
	offsetof(struct pt_regs, bp),
	offsetof(struct pt_regs, si),
	offsetof(struct pt_regs, di)
};

#define REG_(x) (*(long *)(reg_offset[(x)] + (u_char *)FPU_info->regs))

static int reg_offset_vm86[] = {
	offsetof(struct pt_regs, cs),
	offsetof(struct kernel_vm86_regs, ds),
	offsetof(struct kernel_vm86_regs, es),
	offsetof(struct kernel_vm86_regs, fs),
	offsetof(struct kernel_vm86_regs, gs),
	offsetof(struct pt_regs, ss),
	offsetof(struct kernel_vm86_regs, ds)
};

#define VM86_REG_(x) (*(unsigned short *) \
		(reg_offset_vm86[((unsigned)x)] + (u_char *)FPU_info->regs))

static int reg_offset_pm[] = {
	offsetof(struct pt_regs, cs),
	offsetof(struct pt_regs, ds),
	offsetof(struct pt_regs, es),
	offsetof(struct pt_regs, fs),
	offsetof(struct pt_regs, ds),	/* dummy, not saved on stack */
	offsetof(struct pt_regs, ss),
	offsetof(struct pt_regs, ds)
};

#define PM_REG_(x) (*(unsigned short *) \
		(reg_offset_pm[((unsigned)x)] + (u_char *)FPU_info->regs))

/* Decode the SIB byte. This function assumes mod != 0 */
static int sib(int mod, unsigned long *fpu_eip)
{
	u_char ss, index, base;
	long offset;

	RE_ENTRANT_CHECK_OFF;
	FPU_code_access_ok(1);
	FPU_get_user(base, (u_char __user *) (*fpu_eip));	/* The SIB byte */
	RE_ENTRANT_CHECK_ON;
	(*fpu_eip)++;
	ss = base >> 6;
	index = (base >> 3) & 7;
	base &= 7;

	if ((mod == 0) && (base == 5))
		offset = 0;	/* No base register */
	else
		offset = REG_(base);

	if (index == 4) {
		/* No index register */
		/* A non-zero ss is illegal */
		if (ss)
			EXCEPTION(EX_Invalid);
	} else {
		offset += (REG_(index)) << ss;
	}

	if (mod == 1) {
		/* 8 bit signed displacement */
		long displacement;
		RE_ENTRANT_CHECK_OFF;
		FPU_code_access_ok(1);
		FPU_get_user(displacement, (signed char __user *)(*fpu_eip));
		offset += displacement;
		RE_ENTRANT_CHECK_ON;
		(*fpu_eip)++;
	} else if (mod == 2 || base == 5) {	/* The second condition also has mod==0 */
		/* 32 bit displacement */
		long displacement;
		RE_ENTRANT_CHECK_OFF;
		FPU_code_access_ok(4);
		FPU_get_user(displacement, (long __user *)(*fpu_eip));
		offset += displacement;
		RE_ENTRANT_CHECK_ON;
		(*fpu_eip) += 4;
	}

	return offset;
}

static unsigned long vm86_segment(u_char segment, struct address *addr)
{
	segment--;
#ifdef PARANOID
	if (segment > PREFIX_SS_) {
		EXCEPTION(EX_INTERNAL | 0x130);
		math_abort(FPU_info, SIGSEGV);
	}
#endif /* PARANOID */
	addr->selector = VM86_REG_(segment);
	return (unsigned long)VM86_REG_(segment) << 4;
}

/* This should work for 16 and 32 bit protected mode. */
static long pm_address(u_char FPU_modrm, u_char segment,
		       struct address *addr, long offset)
{
	struct desc_struct descriptor;
	unsigned long base_address, limit, address, seg_top;

	segment--;

#ifdef PARANOID
	/* segment is unsigned, so this also detects if segment was 0: */
	if (segment > PREFIX_SS_) {
		EXCEPTION(EX_INTERNAL | 0x132);
		math_abort(FPU_info, SIGSEGV);
	}
#endif /* PARANOID */

	switch (segment) {
	case PREFIX_GS_ - 1:
		/* user gs handling can be lazy, use special accessors */
		addr->selector = get_user_gs(FPU_info->regs);
		break;
	default:
		addr->selector = PM_REG_(segment);
	}

	descriptor = FPU_get_ldt_descriptor(addr->selector);
	base_address = SEG_BASE_ADDR(descriptor);
	address = base_address + offset;
	limit = base_address
	    + (SEG_LIMIT(descriptor) + 1) * SEG_GRANULARITY(descriptor) - 1;
	if (limit < base_address)
		limit = 0xffffffff;

	if (SEG_EXPAND_DOWN(descriptor)) {
		if (SEG_G_BIT(descriptor))
			seg_top = 0xffffffff;
		else {
			seg_top = base_address + (1 << 20);
			if (seg_top < base_address)
				seg_top = 0xffffffff;
		}
		access_limit =
		    (address <= limit) || (address >= seg_top) ? 0 :
		    ((seg_top - address) >= 255 ? 255 : seg_top - address);
	} else {
		access_limit =
		    (address > limit) || (address < base_address) ? 0 :
		    ((limit - address) >= 254 ? 255 : limit - address + 1);
	}
	if (SEG_EXECUTE_ONLY(descriptor) ||
	    (!SEG_WRITE_PERM(descriptor) && (FPU_modrm & FPU_WRITE_BIT))) {
		access_limit = 0;
	}
	return address;
}

/*
       MOD R/M byte:  MOD == 3 has a special use for the FPU
                      SIB byte used iff R/M = 100b

       7   6   5   4   3   2   1   0
       .....   .........   .........
        MOD    OPCODE(2)     R/M

       SIB byte

       7   6   5   4   3   2   1   0
       .....   .........   .........
        SS      INDEX        BASE

*/

void __user *FPU_get_address(u_char FPU_modrm, unsigned long *fpu_eip,
			     struct address *addr, fpu_addr_modes addr_modes)
{
	u_char mod;
	unsigned rm = FPU_modrm & 7;
	long *cpu_reg_ptr;
	int address = 0;	/* Initialized just to stop compiler warnings. */

	/* Memory accessed via the cs selector is write protected
	   in `non-segmented' 32 bit protected mode. */
	if (!addr_modes.default_mode && (FPU_modrm & FPU_WRITE_BIT)
	    && (addr_modes.override.segment == PREFIX_CS_)) {
		math_abort(FPU_info, SIGSEGV);
	}

	addr->selector = FPU_DS;	/* Default, for 32 bit non-segmented mode. */

	mod = (FPU_modrm >> 6) & 3;

	if (rm == 4 && mod != 3) {
		address = sib(mod, fpu_eip);
	} else {
		cpu_reg_ptr = &REG_(rm);
		switch (mod) {
		case 0:
			if (rm == 5) {
				/* Special case: disp32 */
				RE_ENTRANT_CHECK_OFF;
				FPU_code_access_ok(4);
				FPU_get_user(address,
					     (unsigned long __user
					      *)(*fpu_eip));
				(*fpu_eip) += 4;
				RE_ENTRANT_CHECK_ON;
				addr->offset = address;
				return (void __user *)address;
			} else {
				address = *cpu_reg_ptr;	/* Just return the contents
							   of the cpu register */
				addr->offset = address;
				return (void __user *)address;
			}
		case 1:
			/* 8 bit signed displacement */
			RE_ENTRANT_CHECK_OFF;
			FPU_code_access_ok(1);
			FPU_get_user(address, (signed char __user *)(*fpu_eip));
			RE_ENTRANT_CHECK_ON;
			(*fpu_eip)++;
			break;
		case 2:
			/* 32 bit displacement */
			RE_ENTRANT_CHECK_OFF;
			FPU_code_access_ok(4);
			FPU_get_user(address, (long __user *)(*fpu_eip));
			(*fpu_eip) += 4;
			RE_ENTRANT_CHECK_ON;
			break;
		case 3:
			/* Not legal for the FPU */
			EXCEPTION(EX_Invalid);
		}
		address += *cpu_reg_ptr;
	}

	addr->offset = address;

	switch (addr_modes.default_mode) {
	case 0:
		break;
	case VM86:
		address += vm86_segment(addr_modes.override.segment, addr);
		break;
	case PM16:
	case SEG32:
		address = pm_address(FPU_modrm, addr_modes.override.segment,
				     addr, address);
		break;
	default:
		EXCEPTION(EX_INTERNAL | 0x133);
	}

	return (void __user *)address;
}

void __user *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
				struct address *addr, fpu_addr_modes addr_modes)
{
	u_char mod;
	unsigned rm = FPU_modrm & 7;
	int address = 0;	/* Default used for mod == 0 */

	/* Memory accessed via the cs selector is write protected
	   in `non-segmented' 32 bit protected mode. */
	if (!addr_modes.default_mode && (FPU_modrm & FPU_WRITE_BIT)
	    && (addr_modes.override.segment == PREFIX_CS_)) {
		math_abort(FPU_info, SIGSEGV);
	}

	addr->selector = FPU_DS;	/* Default, for 32 bit non-segmented mode. */

	mod = (FPU_modrm >> 6) & 3;

	switch (mod) {
	case 0:
		if (rm == 6) {
			/* Special case: disp16 */
			RE_ENTRANT_CHECK_OFF;
			FPU_code_access_ok(2);
			FPU_get_user(address,
				     (unsigned short __user *)(*fpu_eip));
			(*fpu_eip) += 2;
			RE_ENTRANT_CHECK_ON;
			goto add_segment;
		}
		break;
	case 1:
		/* 8 bit signed displacement */
		RE_ENTRANT_CHECK_OFF;
		FPU_code_access_ok(1);
		FPU_get_user(address, (signed char __user *)(*fpu_eip));
		RE_ENTRANT_CHECK_ON;
		(*fpu_eip)++;
		break;
	case 2:
		/* 16 bit displacement */
		RE_ENTRANT_CHECK_OFF;
		FPU_code_access_ok(2);
		FPU_get_user(address, (unsigned short __user *)(*fpu_eip));
		(*fpu_eip) += 2;
		RE_ENTRANT_CHECK_ON;
		break;
	case 3:
		/* Not legal for the FPU */
		EXCEPTION(EX_Invalid);
		break;
	}
	switch (rm) {
	case 0:
		address += FPU_info->regs->bx + FPU_info->regs->si;
		break;
	case 1:
		address += FPU_info->regs->bx + FPU_info->regs->di;
		break;
	case 2:
		address += FPU_info->regs->bp + FPU_info->regs->si;
		if (addr_modes.override.segment == PREFIX_DEFAULT)
			addr_modes.override.segment = PREFIX_SS_;
		break;
	case 3:
		address += FPU_info->regs->bp + FPU_info->regs->di;
		if (addr_modes.override.segment == PREFIX_DEFAULT)
			addr_modes.override.segment = PREFIX_SS_;
		break;
	case 4:
		address += FPU_info->regs->si;
		break;
	case 5:
		address += FPU_info->regs->di;
		break;
	case 6:
		address += FPU_info->regs->bp;
		if (addr_modes.override.segment == PREFIX_DEFAULT)
			addr_modes.override.segment = PREFIX_SS_;
		break;
	case 7:
		address += FPU_info->regs->bx;
		break;
	}

      add_segment:
	address &= 0xffff;

	addr->offset = address;

	switch (addr_modes.default_mode) {
	case 0:
		break;
	case VM86:
		address += vm86_segment(addr_modes.override.segment, addr);
		break;
	case PM16:
	case SEG32:
		address = pm_address(FPU_modrm, addr_modes.override.segment,
				     addr, address);
		break;
	default:
		EXCEPTION(EX_INTERNAL | 0x131);
	}

	return (void __user *)address;
}
