/*---------------------------------------------------------------------------+
 |  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))

/* This dummy, gs is not saved on the stack. */
#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 )
    {
      /* gs isn't used by the kernel, so it still has its
	 user-space value. */
    case PREFIX_GS_-1:
      /* N.B. - movl %seg, mem is a 2 byte write regardless of prefix */
      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 ;
}
