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

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

#ifdef ATR
#define EOIPENDING 0x40			/* EOI pending (hardware interrupt) */
#define QEOIPENDING 0x20		/* Queue a CBCB request to do EOI */
#endif ATR

#ifdef IBMRTPC
#define Adr_8259A	0xF0008880	/* first 8259 address (CPU IRPT 3) */
#define Adr_8259B	0XF00088A0	/* second 8259 address (CPU IRPT 4) */
#define CRRA		0x8c40
#define CRRB		0x8c60
#define INIT_8259(adr)	* (char volatile *) adr = 0x12; \
	* (char volatile *) (adr+1) = 0x00	/* send init sequence */
#endif IBMRTPC

#define INIT_INTR() INIT_8259(Adr_8259A);	\
		INIT_8259(Adr_8259B)	/* initialize both 8259's */

#define POLL_CMD	0x0c		/* poll interrupts */
#define GET_IMR		0x00		/* get interrupt mask register */
#define SET_IMR		0x00		/* set interrupt mask register */
#define GET_ISR		0x0b		/* get In Service Register */
#define GET_IRR		0x0a		/* get Int Request Register */
#define NSEOI_CMD 	0x20	/* non specific end of interrupt */
#define SEOI_CMD 	0x60	/* specific end of interrupt */
#ifdef IBMRTPC
#define DISPLAY(value)	display(value)	/* put into front panel display */
#endif IBMRTPC

#ifdef ATR
#define DISPLAY(value)
#endif ATR

/* Enable/Disable Interrupts from a Bus I/O level */
#define ENABLE	1
#define DISABLE	0

#define IOSPACE		0xf0000000	/* PC/AT IO map */
#define IOSPACE2	0xf4000000	/* PC/AT memory map */
#define IOSPACEMASK	0xff000000	/* mask for IOSPACEs */
#define FPASPACE	0xff000000	/* where FPA lives */
#define IOSPACESHIFT	24		/* number of bits to shift right */
#define IOPAGESHIFT	(IOSPACESHIFT-PGSHIFT)	/* number of bits to shift vpage right */

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

#include "../machine/cpu.h"

#ifndef u_short
#include "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 MEMROY WINDOWS
 *
 *	These macros provide a consistant method to access PC 
 *	memory from ROMP when using either the full RTPC IOCC 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_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 volatile *)((int)&(x)+pcif_128_b)) = (int)(v), \
		x = v)
#define PUT_PC2B(x,v) GEN_OUT(*((int volatile *)((int)&(x)+pcif_128_hw)) = (int)(v), \
		x = v)
#define PUT_PC4B(x,v) GEN_OUT(*((int volatile *)((int)&(x)+pcif_128_fw)) = (int)(v), \
		x = v)
		
#define GET_PC1B(x) GEN_IN(((char)*((int volatile *)((int)&(x)+pcif_128_b)) & 0xff), \
		x)
#define GET_PC2B(x) GEN_IN(((short)*((int volatile *)((int)&(x)+pcif_128_hw)) & 0xffff), \
		x)
#define GET_PC4B(x) GEN_IN((*((int volatile *)((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 volatile *)(port)) = (int) d)
#define IOIN(port) ( (char) ((*((int volatile *)(port))) & 0xff))  
#define IOOUTW(port, d) (*((int volatile *)(port)) = (int) d)
#define IOINW(port) ( (short) ((*((int volatile *)(port))) & 0xffff))  

#define OUT(port, d) GEN_OUT(IOOUT(((int)(port))+pcif_io_b, d), \
	* (char volatile *) ((int)(port)+IO_BASE) = d)
#define IN(port) GEN_IN(IOIN(((int)(port))+pcif_io_b), \
	* (char volatile *) ((int)(port)+IO_BASE))
#define OUTW(port, d) GEN_OUT(IOOUTW(((int)(port))+pcif_io_hw, d), \
	* (short volatile *) ((int)(port)+IO_BASE) = d)
#define INW(port) GEN_IN(IOINW(((int)(port))+pcif_io_hw), \
	* (short volatile *) ((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 get_128_window() (current_128_w << PCIF_R4_SHIFT)
#define get_512_window() (current_512_w << PCIF_R5_SHIFT)

#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 volatile *)(port)) =  d)
#define IOIN(port) ( (char) (*((char volatile *)(port))))  
#define IOOUTW(port, d) (*((short volatile *)(port)) = (int) d)
#define IOINW(port) ( (short) (*((short volatile *)(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) (*((char volatile *) (p)))
#define MM_OUT(p, d) (*((char volatile *) (p)) = ((char) (d)))
#define MM_INW(p) (*((short volatile *) (p)))
#define MM_OUTW(p, d) (*((short volatile *) (p)) = ((short) (d)))

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

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

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