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

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

#include "../ca/cpu.h"

#ifdef ATR
/*
 ********************************************************************
 *
 *                   This section of sa.h defines
 *    		     various macros and constants
 *		     that ONLY APPLY TO THE ATR
 *		     version of the kernel.
 *
 ********************************************************************
 */

#ifndef u_short
#include "../h/types.h"
#endif
/*
 *	The PC memory window appears to ROMP as the next megabyte of
 *	contiguous address space after the top of ROMP physical memory.
 *	
 *	This 1 megabyte window is divided into 4 different access methods
 *       to the PC memory space and 2 access methods to the PC I/O space.
 *	The access methods are:
 *
 *	512K memory window - This window occupies the space from the top
 *	of ROMP memory and continues for 512K. The window behaves exactly
 *	like ROMP memory; all types of operations are valid here.
 *
 *	128K memory window ; full word - This window's address space is 
 *	contiguous with the 512K memory window. This window behaves exactly
 *	like the 512K memory window.
 *
 *	128K memory window ; half word - This window's address space is
 *	contiguous with the 128K full word window. This window is used 
 *	for half word operations to or from PC memory.
 *
 *	128K memory window ; byte - This window's address space is
 *	contiguous with the 128K half word window. This window is used 
 *	for byte operations to or from PC memory.
 *
 *       	The purpose of providing FW, HW and byte windows is to allow
 *	        fast partial data transfers between ROMP and PC memory.
 *
 *	The next 2 window provide access to the I/O ports on the PC.
 *
 *	64K I/O window ; half word - This window's address space is contiguous
 *	with the 128K byte window. This window is used to transfer half word
 *	data to and from the PC I/O space.
 *
 *
 *	64K I/O window ; byte - This window's address space is contiguous
 *	with the 64K I/O window. This window is used to transfer byte 
 *	data to and from the PC I/O space.
 */


/*
 *		MACROS FOR ACCESS TO 128K PC MEMORY WINDOWS
 *
 *	These macros provide a consistant method to access PC 
 *	memory from ROMP when using either the full SB hardware
 *	or the coprecessor. 
 *
 *	Since all access to PC memory must use full word loads and
 *	stores when using the HW and BYTE 128K windows these macros
 *	take care of using the correct window for the particular
 *	access desired.
 *
 *
 *	NOTE: You must use the set_128_window() function before you
 *	      attempt to use these macros.
 */

#ifdef IBMRTPC
#define GEN_IN(cpu1,cpu2) (cpu == CPU_ATR) ? (cpu1) : (cpu2)
#define GEN_OUT(cpu1,cpu2) if (cpu == CPU_ATR) (cpu1) ; else (cpu2)
#define IO_BASE 0xf0000000	       /* I/O base address */
#define MEM_BASE 0xf4000000	       /* PC Memory base address */
#else
#define GEN_IN(cpu1,cpu2) (cpu1)
#define GEN_OUT(cpu1,cpu2) (cpu1)
#define IO_BASE	0x00000000		/* dummy value of IO_BASE */
#define MEM_BASE	0x00000000	/* dummy value of MEM_BASE */
#endif IBMRTPC

extern int pcif_128_b;		/* Defined in srt0.s */
extern int pcif_128_hw;
extern int pcif_128_fw;
extern int pcif_512_fw;
extern int pcif_io_b;
extern int pcif_io_hw;
extern int current_128_w;
extern int current_512_w;	

#define PUT_PC1B(x,v) GEN_OUT(*((int *)((int)&(x)+pcif_128_b)) = (int)(v), \
		x = v)
#define PUT_PC2B(x,v) GEN_OUT(*((int *)((int)&(x)+pcif_128_hw)) = (int)(v), \
		x = v)
#define PUT_PC4B(x,v) GEN_OUT(*((int *)((int)&(x)+pcif_128_fw)) = (int)(v), \
		x = v)
		
#define GET_PC1B(x) GEN_IN(((char)*((int *)((int)&(x)+pcif_128_b)) & 0xff), \
		x)
#define GET_PC2B(x) GEN_IN(((short)*((int *)((int)&(x)+pcif_128_hw)) & 0xffff), \
		x)
#define GET_PC4B(x) GEN_IN((*((int *)((int)&(x)+pcif_128_fw))), \
		x)

/*
 * The followin Macros are for use with the 512KB Window 
 *
 */


#define GET_PC(x)  (x)
#define PUT_PC(x,v) (x) = v

/*
 * These Macros provide access to the PC's I/O space.
 *
 */


#define IOOUT(port, d) (*((int *)(port)) = (int) d)
#define IOIN(port) ( (char) ((*((int *)(port))) & 0xff))  
#define IOOUTW(port, d) (*((int *)(port)) = (int) d)
#define IOINW(port) ( (short) ((*((int *)(port))) & 0xffff))  

#define OUT(port, d) GEN_OUT(IOOUT(((int)(port))+pcif_io_b, d), \
	* (char *) ((int)(port)+IO_BASE) = d)
#define IN(port) GEN_IN(IOIN(((int)(port))+pcif_io_b), \
	* (char *) ((int)(port)+IO_BASE))
#define OUTW(port, d) GEN_OUT(IOOUTW(((int)(port))+pcif_io_hw, d), \
	* (short *) ((int)(port)+IO_BASE) = d)
#define INW(port) GEN_IN(IOINW(((int)(port))+pcif_io_hw), \
	* (short *) ((int)(port)+IO_BASE))
/*
 *  Following macros do "in's and out's" for memory mapped devices
 *
 *  Must use set_128_window() before using these macros
 */

#define PCIF_R4_SIGBITS 7
#define PCIF_R4_SHIFT (24 - PCIF_R4_SIGBITS)
#define PCIF_R5_SIGBITS 5
#define PCIF_R5_SHIFT (24 - PCIF_R5_SIGBITS)

#define MM_IN(p) IOIN(((int)(p))+pcif_128_b)
#define MM_OUT(p, d) IOOUT(((int)(p))+pcif_128_b,d) 
#define MM_INW(p) IOINW(((int)(p))+pcif_128_hw)
#define MM_OUTW(p, d) IOOUTW(((int)(p))+pcif_128_hw,d) 


#else ATR



/*
 ********************************************************************
 *
 *                   This section of sa.h defines
 *    		     various macros and constants
 *		     that ONLY APPLY TO THE IBMRTPC
 *		     version of the kernel.
 *
 ********************************************************************
 */


#ifdef IBMRTPC

#define PUT_PC1B(x,v) x = v 
#define PUT_PC2B(x,v) x = v 
#define PUT_PC4B(x,v) x = v 
		
#define GET_PC1B(x) x 
#define GET_PC2B(x) x 
#define GET_PC4B(x) x

#define GET_PC(x)  x
#define PUT_PC(x,v) x = v


#define IOOUT(port, d) (*((char *)(port)) =  d)
#define IOIN(port) ( (char) (*((char *)(port))))  
#define IOOUTW(port, d) (*((short *)(port)) = (int) d)
#define IOINW(port) ( (short) (*((short *)(port)) ))  

#define OUT(port, d) IOOUT((int)(port)+IO_BASE, d)
#define IN(port) IOIN((int)(port)+IO_BASE)
#define OUTW(port, d) IOOUTW((int)(port)+IO_BASE, d)
#define INW(port) IOINW((int)(port)+IO_BASE) 

#define MM_IN(p) p
#define MM_OUT(p, d) p = d
#define MM_INW(p) p
#define MM_OUTW(p, d) p = d 

#define set_128_window(x) (x)	/* dummy */
#define set_512_window(x) (x)	/* dummy */

#define    CDB        0xF0008CE0       /* Hex Display Register  */
#define LED *(caddr_t) CDB

#define IO_BASE 0xf0000000	       /* I/O base address */
#define MEM_BASE 0xf4000000	       /* PC Memory base address */
#endif IBMRTPC
#endif  ATR

#define in(port) IN(port)
#define out(port,value) OUT(port,value)

#define DISPLAY(x) _display(x)

#ifdef DEBUG
#define LOCAL			       /* make it external */
#else
#define LOCAL	static		       /* make it local */
#endif DEBUG
