/*---------------------------------------------------------------------------+
 |  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 <asm/uaccess.h>
#include <asm/desc.h>

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


#define FPU_WRITE_BIT 0x10

static int reg_offset[] = {
	offsetof(struct info,___eax),
	offsetof(struct info,___ecx),
	offsetof(struct info,___edx),
	offsetof(struct info,___ebx),
	offsetof(struct info,___esp),
	offsetof(struct info,___ebp),
	offsetof(struct info,___esi),
	offsetof(struct info,___edi)
};

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

static int reg_offset_vm86[] = {
	offsetof(struct info,___cs),
	offsetof(struct info,___vm86_ds),
	offsetof(struct info,___vm86_es),
	offsetof(struct info,___vm86_fs),
	offsetof(struct info,___vm86_gs),
	offsetof(struct info,___ss),
	offsetof(struct info,___vm86_ds)
      };

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

/* These are dummy, fs and gs are not saved on the stack. */
#define ___FS ___ds
#define ___GS ___ds

static int reg_offset_pm[] = {
	offsetof(struct info,___cs),
	offsetof(struct info,___ds),
	offsetof(struct info,___es),
	offsetof(struct info,___FS),
	offsetof(struct info,___GS),
	offsetof(struct info,___ss),
	offsetof(struct info,___ds)
      };

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


/* 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 )
    {
      /* fs and gs aren't used by the kernel, so they still have their
	 user-space values. */
    case PREFIX_FS_-1:
      /* N.B. - movl %seg, mem is a 2 byte write regardless of prefix */
      savesegment(fs, addr->selector);
      break;
    case PREFIX_GS_-1:
      savesegment(gs, addr->selector);
      break;
    default:
      addr->selector = PM_REG_(segment);
    }

  descriptor = LDT_DESCRIPTOR(PM_REG_(segment));
  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->___ebx + FPU_info->___esi;
      break;
    case 1:
      address += FPU_info->___ebx + FPU_info->___edi;
      break;
    case 2:
      address += FPU_info->___ebp + FPU_info->___esi;
      if ( addr_modes.override.segment == PREFIX_DEFAULT )
	addr_modes.override.segment = PREFIX_SS_;
      break;
    case 3:
      address += FPU_info->___ebp + FPU_info->___edi;
      if ( addr_modes.override.segment == PREFIX_DEFAULT )
	addr_modes.override.segment = PREFIX_SS_;
      break;
    case 4:
      address += FPU_info->___esi;
      break;
    case 5:
      address += FPU_info->___edi;
      break;
    case 6:
      address += FPU_info->___ebp;
      if ( addr_modes.override.segment == PREFIX_DEFAULT )
	addr_modes.override.segment = PREFIX_SS_;
      break;
    case 7:
      address += FPU_info->___ebx;
      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 ;
}
