/*	Copyright (c) 1993 INTEL CORPORATION */
/*	  All Rights Reserved  	*/

/*
 *         INTEL CORPORATION PROPRIETARY INFORMATION
 *
 *    This software is supplied under the terms of a license 
 *    agreement or nondisclosure agreement with Intel Corpo-
 *    ration and may not be copied or disclosed except in
 *    accordance with the terms of that agreement.
 */

#ifndef _OS2APIC_H
#define _OS2APIC_H

#define APICPHYS	0xfee00000		/* physical adr of Local APIC */
#define APICIPHYS	0xfec00000		/* physical adr of I/O APIC */

/* offsets for registers */

#define	AP_IO_REG	0
#define AP_IO_DATA	4
#define AP_TASKPRI	4*8
#define AP_ID		4*2
#define AP_VERS		4*3
#define AP_LDEST	4*0xd
#define AP_DESTFMT	4*0xe
#define AP_SPUR		4*0xf
#define AP_ICMD		4*0x30
#define AP_ICMD2	4*0x31
#define AP_LVT_TIMER	4*0x32
#define AP_LVT_I0	4*0x35
#define AP_LVT_I1	4*0x36
#define AP_ICOUNT	4*0x38
#define AP_CCOUNT	4*0x39
#define	AP_EOI		0xB0
#define	AP_ISR		0x100
#define	AP_IRR		0x200
#define	APIC_ID_REG	0x20
#define	AP_ESR		4*0x28
#define	AP_ERR_VEC	4*0x37


/* select values for I/O registers */

#define AIR_ID		0
#define AIR_VERS	1
#define AIR_RDT		0x10
#define AIR_RDT2	0x11

/* various values for registers */

#define AV_MASK		0x10000
#define AV_TOALL	0x7fffffff
#define APIC_LOGDEST(c)	(0x40000000>>(c))   /* logical destination if ON */
#define AV_IM_OFF	0x80000000	    /* logical destination if OFF */
#define AV_FIXED	0
#define AV_LOPRI	0x100
#define AV_NMI		0x400
#define AV_RESET	0x500
#define AV_STARTUP	0x600
#define AV_EXTINT	0x700
#define AV_PENDING	0x1000
#define AV_PDEST	0
#define AV_LDEST	0x800
#define AV_POLOW	0x2000
#define AV_POHIGH	0
#define AV_ASSERT	0x4000
#define AV_DEASSERT	0
#define AV_EDGE		0
#define AV_LEVEL	0x8000
#define	AV_POLARITY	0x2000
#define AV_XTOSELF	0x40000
#define AV_XTOALL	0x80000

#define	APIC_ENABLE	0x100

/* Task priority values */
#define	TPRIHI		0xf0			
#define	TPRILO		0x00			


/* APIC error status */

#define	AP_ERR_SEND_CS		0x0001
#define	AP_ERR_RCV_CS		0x0002
#define	AP_ERR_SEND_ACPT	0x0004
#define	AP_ERR_RCV_ACPT		0x0008
#define	AP_ERR_SEND_ILLEGAL	0x0020
#define	AP_ERR_RCV_ILLEGAL	0x0040
#define	AP_ERR_ILLEGAL_REG	0x0080

/* MP+AT Interrupt Mode Control Registers */
#define IMCR_ADDR	0x22
#define IMCR_DATA	0x23

/* CMOS shutdown status byte */
#define	SSB		0x0f

/* define for timer on APIC */
#define AP_CLKNUM       (14318000/HZ)

/* PC+MP Configurations */

#define PCMP_MODE	0xfe6f5		/* physical adr of PCMP config bytes */
#define PCMP_BASE	0x9fc00		/* base of PCMP floating pointer area */
#define	ROM_BASE	0xE0000		/* ROM Bios base */
#define	BIOS_AREA	0x00000		/* BIOS Area */
#define	BIOS_EBDA_PTR	0x40E	/* EBDA pointer */
#define	BIOS_BASE_MEM	0x413	/* Base mem area */


#define MAXIOAPIC	4	 	/* max number of I/O apics */
#define	MAXNUMCPU	16	 	/* max number of CPUs */
#define	NCPUS		MAXNUMCPU	/* max number of CPUs */

#define MP_IMCRP	0x80	 	/* IMCR present */
#define MP_DEF_ENTRY	2	 	/* default table to use */
#define MP_DEF_MODE	(MP_IMCRP|MP_DEF_ENTRY)

struct mpchdr {
	char sign[4];		 	/* signature "MPAT" */
	short tbl_len;		 	/* length of table */
	char spec_rev;		 	/* MP+AT specification revision no. */
	char checksum;
	char oem_id[8];
	char product_id[12];
	ulong_t oem_ptr;	 	/* pointer to oem table (optional) */
	short oem_len;		 	/* length of above table */
	short num_entry;	 	/* number of 'entry's to follow */
	ulong_t loc_apic_adr;	 	/* local apic physical address */
	char fill[4];
};

/* types of entries (stored in bytes[0]) */
#define MP_ET_PROC	0	 	/* processor */
#define MP_ET_BUS	1	 	/* bus */
#define MP_ET_IOAPIC	2	 	/* i/o apic */
#define MP_ET_I_INTR	3	 	/* interrupt assignment -> i/o apic */
#define MP_ET_L_INTR	4	 	/* interrupt assignment -> local apic */

struct mpe_proc {
	char entry_type;
	char apic_id;
	char apic_vers;
	char cpu_flags;
	int  stepping : 4,
	     model : 4,
	     family : 4;
	int features;
	int fill[2];
};

struct mpe_bus {
	char entry_type;
	char bus_id;
	char name[6];
};

struct mpe_ioapic {
	char entry_type;
	char apic_id;
	char apic_vers;
	char ioapic_flags;
	ulong_t io_apic_adr;
};

/* flag values for intr */
#define MP_INTR_POVAL	1
#define MP_INTR_POLOW	2
#define MP_INTR_ELVAL	4
#define MP_INTR_ELLEVEL 8

struct mpe_intr {
	char entry_type;
	char intr_type;
	char intr_flags;
	char fill;
	char src_bus;
	char src_irq;
	char dest_apicid;
	char dest_line;
};

union mpcentry {
	char bytes[20];
	struct mpe_proc p;
	struct mpe_bus b;
	struct mpe_ioapic a;
	struct mpe_intr i;
};

struct mpconfig {
	struct mpchdr hdr;
	union mpcentry entry[1];
};

struct	segoff	{
	unsigned short	offset;
	unsigned short	segment;
};


struct _io_chg {
	int local_or_io;		/* 1 if io apic, 0 if local */
	int io_id;			/* id of i/o apic (if i/o apic) */
	int line;			/* line of apic */
	int val1;			/* first word of redirection */
	int val2;			/* second word of redirection */
};

#define CONN_IRQ		0
#define CONN_NMI		1
#define CONN_SMI		2
#define CONN_PIC		3

#define CONN_RET_LOC		0
#define CONN_RET_IO		1
#define CONN_RET_FAIL		-1

struct pcmp_fptr {
	char sig[4];
	int paddr;
	char len, rev;
	char checksum;
	unsigned char	mp_feature1;
	unsigned char	mp_feature2;
	char fill[3];
};

struct	plma_s {
	ulong_t	procnum;
	ulong_t	apiclvadr;
	ulong_t	apicivadr;
};

typedef	struct	plma_s	PLMA;

struct	_irq_to_apic_s {
	ulong_t	ioapic_addr;
	ulong_t	apic_line;
};


#define	SPURIOUS_VEC		0xFF		/* APIC spurious vector */
#define	SPURIOUS_IRQ		0x11		/* APIC spurious vector */
#define	ERROR_VEC		0xF0
#define	ERROR_IRQ		0x12
#define	IPI_VEC			0xE0		/* IPI INT vector */
#define	IPI_IRQ			0x10		/* IPI map in irqi table */
#define	WARM_RESET_VEC_SEG	0x40		/* Warm reset vector segment */
#define	WARM_RESET_VEC_OFF	0x67		/* "    "      "    offset */
#define	MPAT_CONFIG_DATA	0x4AC		/* Pointer to MP config table */
#define	CPUANY			-1

/* PIC  port definations */

#define	PIC1_PORT0		0x20
#define	PIC1_PORT1		0x21
#define	PIC2_PORT0		0xA0
#define	PIC2_PORT1		0xA1
#define	OCW2_NON_SPECIFIC_EOI	0x20
#define	OCW3_READ_IRR		0x0a
#define	OCW3_READ_ISR		0x0b

/* EISA edge/level trigger ports */

#define	ELTR_PORT0		0x4d0
#define	ELTR_PORT1		0x4d1

#define	IODelay()		{int i; for(i=0; i<IODelayCount; i++); }

#define	VERSION			0x001

#endif	/* _OS2APIC_H */
