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

/*
 * this file contains those defines and declarations required 
 * for either the floating point accelerator or the
 * advanced floating point accelerator
 */

#define	NUM_FPA_SETS	32	/* Number of fpa register sets */

#define	NUM_FPA_FLOATS	14	/* Number of floats in  fpa register set */
#define	NUM_AFPA_FLOATS	64	/* Number of floats in Afpa register set */

/* following bits are in p_fpareg */
#define FPA_NONE	0xff	/* no FPA present */
#define FPA_LOCK	0x80	/* bit on if FPA is to be locked */
#define FPA_UNUSED	0xfe	/* fpa not used yet */
#define FPA_SAVED	0xfd	/* fpa saved - must be restored */

#define fpa_reset()	* (int volatile *) FPA_RST = 0
#define fpa_rdscx()	* (int volatile *) FPA_RDSCX
#define fpa_lockfp()	* (int volatile *) FPA_LOCKFP = 0
#define fpa_tskswu(n)	* (int volatile *) FPA_TSKSWU = n
#define fpa_wtstr(n)	* (int volatile *) FPA_WTSTR = n
#define fpa_rdstr()	* (int volatile *) FPA_RDSTR
#define	fpa_wtier(n)	* (int volatile *) FPA_WTIER = n
#define	fpa_rdier(n)	* (int volatile *) FPA_RDIER
#define fpa_hasreg(reg)	(((reg)&FPA_LOCK) == 0)

#define FPA_BASE	0xff000000		/* PIO base */
#define FPA_DMA_BASE	0xfe000000		/* DMA base */
#define FPA_RST		(FPA_BASE + 0x20004)
#define FPA_LOCKFP	(FPA_BASE + 0x27000)
#define FPA_TSKSWU	(FPA_BASE + 0x23fb8)
#define FPA_RDSCX	(FPA_BASE + 0x2dfb8)
#define	FPA_RDIER	(FPA_BASE + 0x2f3c0)
#define	FPA_WTIER	(FPA_BASE + 0x2503c)
#define FPA_WTSTR	(FPA_BASE + 0x43fb8)
#define FPA_RDSTR	(FPA_BASE + 0x0dfb8)
#define FPA_WTFR	(FPA_BASE + 0x25000)
#define FPA_RDFR	(FPA_BASE + 0x2f000)

		/* Note numbering: lsb is bit 31, msb is bit 0 */
#define	POS_AT(msb,lsb,value)	(((value)&((1<<(1+lsb-msb))-1))<<(31-lsb))

#define	AFPA_BASE_OP(base, op1ext, op2ext, ds, fpuopcode, op1, op2, ts) \
		(base|POS_AT(8,9,op1ext)|POS_AT(10,11,op2ext)| \
		POS_AT(12,13,ds)|POS_AT(14,21,fpuopcode)|POS_AT(22,25,op1)| \
		POS_AT(26,29,op2)|POS_AT(30,31,ts))
#define	AFPA_OP(op1ext, op2ext, ds, fpuopcode, op1, op2, ts) \
	AFPA_BASE_OP(FPA_BASE, op1ext, op2ext, ds, fpuopcode, op1, op2, ts)
#define	AFPA_DMA_OP(op1ext, op2ext, ds, fpuopcode, op1, op2, ts) \
	AFPA_BASE_OP(FPA_DMA_BASE, op1ext, op2ext, ds, fpuopcode, op1, op2, ts)

#define	AFPA_DISABLE_CONTROL_STORE	AFPA_OP(0,0,3,0x9f,0,0,0)
#define	AFPA_ENABLE_CONTROL_STORE	AFPA_OP(0,0,0,0x98,0,0,0)
#define	AFPA_DIAG_TSKSWU		AFPA_OP(0,0,0,0x9d,0,0,0)

#define	afpa_disable_control_store() \
		{ \
		    int xyz; \
		    xyz = *(int volatile *) AFPA_DISABLE_CONTROL_STORE; \
		}
#define	afpa_enable_control_store()	(*(int volatile *)AFPA_ENABLE_CONTROL_STORE) = 1
/* Diagnostic task switch/unlock for loading time */
#define afpa_diag_tskswu(n)		(*(int volatile *)AFPA_DIAG_TSKSWU) = (n)

#define	afpa_write_register(reg,contents) \
	(*(int volatile *) (FPA_WTFR | ((reg & 0x30)<<16) | ((reg & 0xf)<<2)) = (contents))

#define	afpa_read_register(reg) \
	(*(int volatile *) (FPA_RDFR | ((reg & 0x30)<<18) | ((reg & 0xf)<<6)))

#define	AFPA_LENGTH_REGISTER	AFPA_DMA_OP(0,1,3,0x9f,0,0,3)
#define	AFPA_WRITE_LENGTH_REGISTER(x) (*(int volatile *) AFPA_LENGTH_REGISTER) = (x)
#define	AFPA_READ_LENGTH_REGISTER()	(*(int volatile *) AFPA_LENGTH_REGISTER)


/* Constants related to loading the AFPA microcode */
			    /* Where high order 32 bits go */
#define	AFPA_UCODE_HIGH		(FPA_BASE + 0x1c0000)
			    /* Where low order 32 bits go */
#define	AFPA_UCODE_LOW		(FPA_BASE + 0x1c0001)
			    /* The lowest legal AFPA ucode address */
#define	AFPA_UCODE_LOWEST	(FPA_BASE + 0x1c0000)
			    /* The highest legal AFPA ucode address */
#define	AFPA_UCODE_HIGHEST	(FPA_BASE + 0x1c0000 + (0xfff<<2) + 1)
#define AFPA_READ_UCODE_HIGH(content,offset)	{ \
	(content) = (*(int volatile *)(AFPA_UCODE_HIGH | ((offset) << 2))); \
	DELAY(10); \
	}
#define AFPA_READ_UCODE_LOW(content,offset)	{ \
	(content) = (*(int volatile *)(AFPA_UCODE_LOW | ((offset) << 2))); \
	DELAY(10); \
	}
#define AFPA_WRITE_UCODE_HIGH(content,offset)	{ \
	(*(int volatile *)(AFPA_UCODE_HIGH | ((offset) << 2))) = (content); \
	DELAY(10); \
	}
#define AFPA_WRITE_UCODE_LOW(content,offset)	{ \
	(*(int volatile *)(AFPA_UCODE_LOW | ((offset) << 2))) = (content); \
	DELAY(10); \
	}

#define FPA_TASK_EXCEPTION	0x1000	/* this task caused exception */
