/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1987
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header:mc881.h 12.0$ */
/* $ACIS:mc881.h 12.0$ */
/* $Source: /ibm/acis/usr/sys/ca/RCS/mc881.h,v $ */

#if !defined(lint) && !defined(LOCORE) && defined(RCS_HDRS)
static char *rcsidmc881 = "$Header:mc881.h 12.0$";
#endif

/*
 * This file describes the mc68881 chip as far as the kernel
 * needs to know about it.
 */

/*
 * C I R
 *
 * Coprocessor Interface Register map
 */

#define	MC_CIR_RESPONSE			0x00	/* read only */
#define	MC_CIR_CONTROL			0x02	/* write only */
#define	MC_CIR_SAVE			0x04	/* read only */
#define	MC_CIR_RESTORE			0x06	/* read/write */
#define	MC_CIR_OPERATION_WORD		0x08	/* write only */
#define	MC_CIR_COMMAND			0x0a	/* write only */
#define	MC_CIR_CONDITION		0x0e	/* write only */
#define	MC_CIR_OPERAND			0x10	/* read/write, 32 bits */
#define	MC_CIR_REGISTER_SELECT		0x14	/* read only */
#define	MC_CIR_INSTRUCTION_ADDRESS	0x18	/* write only, 32 bits */
#define	MC_CIR_OPERAND_ADDRESS		0x1c	/* read/write, 32 bits */

/*
 * The MC68881 puts all 16 bit registers on the upper halfword
 * of the memory bus.  Since when we access a half word, we
 * expect to get either the upper halfword (A%4==0) or lower
 * halfword (A%4==2), we need to worry about how the processor
 * card interacts with the 68881.  So, we define all accesses
 * in terms of macros.
 */

#define	MC_CIR_READ_16(reg)	((*((u_int *)(IOIM_881_SW_BASE+(reg))))>>16)
#define	MC_CIR_WRITE_16(reg,val) \
			(*(u_int *) (IOIM_881_SW_BASE+(reg))) = (val)<<16
#define	MC_CIR_READ_32(reg)	(*((u_int *)(IOIM_881_SW_BASE+(reg))))
#define	MC_CIR_WRITE_32(reg,val)(*(u_int *) (IOIM_881_SW_BASE+(reg))) = (val)

/*
 * C I R
 *
 * Coprocessor Interface Registers content descriptions
 */

/* Response CIR */

/* - general format */
#define	MC_RESPONSE_CA		(1<<15)	/* Come-again */
#define	MC_RESPONSE_PC		(1<<14)	/* Send the program counter */
#define	MC_RESPONSE_DR		(1<<13)	/* Direction bit (1 ==> to cpu) */
#define	MC_RESPONSE_FUNCTION_MASK	0x1f00
#define	MC_RESPONSE_PARAMETER_MASK	0xff

/* - specific format */
#define	MC_RESPONSE_NULL_MASK		0x3efc
#define	MC_RESPONSE_NULL_VALUE		0x0800
#define	MC_RESPONSE_EEA_XFER_DATA_MASK	0x1800
#define	MC_RESPONSE_EEA_XFER_DATA_VALUE	0x1000
#define	MC_RESPONSE_XFER_REGISTER_MASK	0x1ff0
#define	MC_RESPONSE_XFER_REGISTER_VALUE	0x0c00
#define	MC_RESPONSE_XFER_MULTIPLE_REG_MASK	0x1f00
#define	MC_RESPONSE_XFER_MULTIPLE_REG_VALUE	0x0100
#define	MC_RESPONSE_TAKE_EXCEPT_MASK	0xbf00
#define	MC_RESPONSE_TAKE_PRE_EXCEPT	0x1c00
#define	MC_RESPONSE_TAKE_MID_EXCEPT	0x1d00

#define MC_RESPONSE_PROTOCOL_VIOLATION	13	/* in vector number */

/* Control CIR */

#define	MC_CIR_CONTROL_XA	0x02		/* Exception acknowledge */
#define	MC_CIR_CONTROL_AB	0x01		/* Abort */

/*
 * Save CIR - one reads this register to determine the amount of state
 * that needs to be saved during context switch.
 */

/*
 * Restore CIR - one first writes this register with the state which one
 * wishes to restore, then reads it to make sure that the format written
 * was legal.  (If, by chance, the format was NOT legal, then
 * MC_CIR_CONTROL_AB should be sent to the 68881 Control CIR.)
 */

#define	MC_STATE_MASK		0xff00
#define		MC_STATE_NULL		0x00	/* Null state (4 bytes) */
#define		MC_STATE_NOT_READY	0x01	/* Not ready, come again */
#define		MC_STATE_ILLEGAL	0x02	/* take format exception */
/* Any other state (1f, 3f, etc.) is the version number */
#define	MC_NULL_FRAME_SIZE		0	/* No state data */
#define	MC_NON_NULL_FRAME_SIZE_MASK	0x00ff	/* In bytes */
#define MC_IDLE_FRAME_SIZE		0x18	/* idle frame size */

/* Operation Word CIR - unused by 68881 */

/* Command CIR */

/*
 * F  P  C  R
 *
 * Control Register
 */

/* The Exception Enable byte (also for FPSR Exception Status below) */
#define	MC_EXCEPT_BSUN	0x8000		/* Branch/set on unordered */
#define	MC_EXCEPT_SNAN	0x4000		/* Signalling NAN */
#define	MC_EXCEPT_OPERR	0x2000		/* Operand error */
#define	MC_EXCEPT_OVFL	0x1000		/* Overflow */
#define	MC_EXCEPT_UNFL	0x0800		/* Underflow */
#define	MC_EXCEPT_DZ	0x0400		/* Divide by zero */
#define	MC_EXCEPT_INEX2	0x0200		/* Inexact operation */
#define	MC_EXCEPT_INEX1	0x0100		/* Inexact decimal input */

/* The Mode Control byte */
#define	MC_PREC_MASK	0x00c0		/* Mask for rounding precision */
#define		MC_PREC_EXTENDED	0x0000	/* Extended */
#define		MC_PREC_SINGLE		0x0040	/* Single */
#define		MC_PREC_DOUBLE		0x0080	/* Double */
#define		MC_PREC_UNDEFINED	0x00c0	/* Undefined, reserved */
#define	MC_MODE_MASK	0x0030		/* Mask for rounding mode */
#define		MC_MODE_NEAREST		0x0000	/* To nearest */
#define		MC_MODE_ZERO		0x0010	/* toward zero */
#define		MC_MODE_MINUS_INFINITY	0x0020	/* toward minus infinity */
#define		MC_MODE_PLUS_INFINITY	0x0030	/* toward plus infinity */

/*
 * F  P  S  R
 *
 * Status register
 */

/* The Condition Code byte */
#define	MC_CC_N		(1<<27)		/* Negative */
#define	MC_CC_Z		(1<<26)		/* Zero */
#define	MC_CC_I		(1<<25)		/* Infinity */
#define	MC_CC_NAN	(1<<24)		/* Not A Number */

/* The quotient byte */
#define	MC_QUOT_SIGN	(1<<23)		/* Sign of quotient */
#define	MC_QUOT_LSB_SHIFT	16	/* For extraction */
#define	MC_QUOT_LSB_MASK	0x3f	/* Mask for lsb of quotient */
#define	MC_QUOT_EXTRACT(X)	(((X)>>MC_QUOT_LSB_SHIFT)&MC_QUOT_LSB_MASK)

/* The Exception Status byte - see FPCR "Exception Enable byte" above */

/* The Accrued Exception byte */
#define	MC_ACCRUED_IOP	(1<<7)		/* Invalid operation */
#define	MC_ACCRUED_OVFL	(1<<6)		/* Overflow */
#define	MC_ACCRUED_UNFL	(1<<5)		/* Underflow */
#define	MC_ACCRUED_DZ	(1<<4)		/* Divide by zero */
#define	MC_ACCRUED_INEX	(1<<3)		/* Inexact */

/*
 * The following are some used 68881 commands.
 */

#define	MC_SAVE_DATA_REGS	0xf0ff	/* FMOVEM.X FP0-FP7,ea */
#define	MC_RESTORE_DATA_REGS	0xd0ff	/* FMOVEM.X ea,FP0-FP7 */

#define	MC_SAVE_CONTROL_REGS	0xbc00	/* FMOVEM.L FPCR/FPSR/FPIAR,ea */
#define	MC_RESTORE_CONTROL_REGS	0x9c00	/* FMOVEM.L ea,FPCR/FPSR/FPIAR */

/*
 * define a BIU flags bit 
 */
#define MC_BIU_INST_PENDING	0x40000000	/* instruction pending (inverted) */
