xref: /netbsd-src/sys/arch/x86/include/i8259.h (revision aad01611e7d49352752bfcd4a3f76ed8d8b2123e)
1*aad01611Sagc /*	$NetBSD: i8259.h,v 1.4 2003/08/07 16:30:32 agc Exp $	*/
28375b2d9Sfvdl 
38375b2d9Sfvdl /*-
48375b2d9Sfvdl  * Copyright (c) 1990 The Regents of the University of California.
58375b2d9Sfvdl  * All rights reserved.
68375b2d9Sfvdl  *
78375b2d9Sfvdl  * This code is derived from software contributed to Berkeley by
88375b2d9Sfvdl  * William Jolitz.
98375b2d9Sfvdl  *
108375b2d9Sfvdl  * Redistribution and use in source and binary forms, with or without
118375b2d9Sfvdl  * modification, are permitted provided that the following conditions
128375b2d9Sfvdl  * are met:
138375b2d9Sfvdl  * 1. Redistributions of source code must retain the above copyright
148375b2d9Sfvdl  *    notice, this list of conditions and the following disclaimer.
158375b2d9Sfvdl  * 2. Redistributions in binary form must reproduce the above copyright
168375b2d9Sfvdl  *    notice, this list of conditions and the following disclaimer in the
178375b2d9Sfvdl  *    documentation and/or other materials provided with the distribution.
18*aad01611Sagc  * 3. Neither the name of the University nor the names of its contributors
198375b2d9Sfvdl  *    may be used to endorse or promote products derived from this software
208375b2d9Sfvdl  *    without specific prior written permission.
218375b2d9Sfvdl  *
228375b2d9Sfvdl  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
238375b2d9Sfvdl  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
248375b2d9Sfvdl  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
258375b2d9Sfvdl  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
268375b2d9Sfvdl  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
278375b2d9Sfvdl  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
288375b2d9Sfvdl  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
298375b2d9Sfvdl  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
308375b2d9Sfvdl  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
318375b2d9Sfvdl  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
328375b2d9Sfvdl  * SUCH DAMAGE.
338375b2d9Sfvdl  *
348375b2d9Sfvdl  *	@(#)icu.h	5.6 (Berkeley) 5/9/91
358375b2d9Sfvdl  */
368375b2d9Sfvdl 
378375b2d9Sfvdl #ifndef	_X86_I8259_H_
388375b2d9Sfvdl #define	_X86_I8259_H_
398375b2d9Sfvdl 
408375b2d9Sfvdl #include <dev/isa/isareg.h>
418375b2d9Sfvdl 
428375b2d9Sfvdl #ifndef	_LOCORE
438375b2d9Sfvdl 
448375b2d9Sfvdl /*
458375b2d9Sfvdl  * Interrupt "level" mechanism variables, masks, and macros
468375b2d9Sfvdl  */
478375b2d9Sfvdl extern	unsigned i8259_imen;		/* interrupt mask enable */
488375b2d9Sfvdl extern unsigned i8259_setmask(unsigned);
498375b2d9Sfvdl 
508375b2d9Sfvdl #define SET_ICUS()	(outb(IO_ICU1 + 1, imen), outb(IO_ICU2 + 1, imen >> 8))
518375b2d9Sfvdl 
528375b2d9Sfvdl extern void i8259_default_setup(void);
538375b2d9Sfvdl extern void i8259_reinit(void);
548375b2d9Sfvdl 
558375b2d9Sfvdl #endif /* !_LOCORE */
568375b2d9Sfvdl 
578375b2d9Sfvdl /*
588375b2d9Sfvdl  * Interrupt enable bits -- in order of priority
598375b2d9Sfvdl  */
608375b2d9Sfvdl #define	IRQ_SLAVE	2
618375b2d9Sfvdl 
628375b2d9Sfvdl /*
638375b2d9Sfvdl  * Interrupt Control offset into Interrupt descriptor table (IDT)
648375b2d9Sfvdl  */
658375b2d9Sfvdl #define	ICU_OFFSET	32		/* 0-31 are processor exceptions */
668375b2d9Sfvdl #define	ICU_LEN		16		/* 32-47 are ISA interrupts */
678375b2d9Sfvdl 
688375b2d9Sfvdl 
698375b2d9Sfvdl #define ICU_HARDWARE_MASK
708375b2d9Sfvdl 
718375b2d9Sfvdl /*
728375b2d9Sfvdl  * These macros are fairly self explanatory.  If ICU_SPECIAL_MASK_MODE is
738375b2d9Sfvdl  * defined, we try to take advantage of the ICU's `special mask mode' by only
748375b2d9Sfvdl  * EOIing the interrupts on return.  This avoids the requirement of masking and
758375b2d9Sfvdl  * unmasking.  We can't do this without special mask mode, because the ICU
768375b2d9Sfvdl  * would also hold interrupts that it thinks are of lower priority.
778375b2d9Sfvdl  *
788375b2d9Sfvdl  * Many machines do not support special mask mode, so by default we don't try
798375b2d9Sfvdl  * to use it.
808375b2d9Sfvdl  */
818375b2d9Sfvdl 
828375b2d9Sfvdl #define	IRQ_BIT(num)	(1 << ((num) % 8))
838375b2d9Sfvdl #define	IRQ_BYTE(num)	((num) >> 3)
848375b2d9Sfvdl 
858375b2d9Sfvdl #define i8259_late_ack(num)
868375b2d9Sfvdl 
878375b2d9Sfvdl #ifdef ICU_SPECIAL_MASK_MODE
888375b2d9Sfvdl 
898375b2d9Sfvdl #define	i8259_asm_ack1(num)
908375b2d9Sfvdl #define	i8259_asm_ack2(num) \
918375b2d9Sfvdl 	movb	$(0x60|IRQ_SLAVE),%al	/* specific EOI for IRQ2 */	;\
928375b2d9Sfvdl 	outb	%al,$IO_ICU1
938375b2d9Sfvdl #define	i8259_asm_mask(num)
948375b2d9Sfvdl #define	i8259_asm_unmask(num) \
958375b2d9Sfvdl 	movb	$(0x60|(num%8)),%al	/* specific EOI */		;\
968375b2d9Sfvdl 	outb	%al,$ICUADDR
978375b2d9Sfvdl 
988375b2d9Sfvdl #else /* ICU_SPECIAL_MASK_MODE */
998375b2d9Sfvdl 
1008375b2d9Sfvdl #ifndef	AUTO_EOI_1
1018375b2d9Sfvdl #define	i8259_asm_ack1(num) \
1028375b2d9Sfvdl 	movb	$(0x60|(num%8)),%al	/* specific EOI */		;\
1038375b2d9Sfvdl 	outb	%al,$IO_ICU1
1048375b2d9Sfvdl #else
1058375b2d9Sfvdl #define	i8259_asm_ack1(num)
1068375b2d9Sfvdl #endif
1078375b2d9Sfvdl 
1088375b2d9Sfvdl #ifndef AUTO_EOI_2
1098375b2d9Sfvdl #define	i8259_asm_ack2(num) \
1108375b2d9Sfvdl 	movb	$(0x60|(num%8)),%al	/* specific EOI */		;\
1118375b2d9Sfvdl 	outb	%al,$IO_ICU2		/* do the second ICU first */	;\
1128375b2d9Sfvdl 	movb	$(0x60|IRQ_SLAVE),%al	/* specific EOI for IRQ2 */	;\
1138375b2d9Sfvdl 	outb	%al,$IO_ICU1
1148375b2d9Sfvdl #else
1158375b2d9Sfvdl #define	i8259_asm_ack2(num)
1168375b2d9Sfvdl #endif
1178375b2d9Sfvdl 
1188375b2d9Sfvdl #ifdef PIC_MASKDELAY
1198375b2d9Sfvdl #define MASKDELAY	pushl %eax ; inb $0x84,%al ; popl %eax
1208375b2d9Sfvdl #else
1218375b2d9Sfvdl #define MASKDELAY
1228375b2d9Sfvdl #endif
1238375b2d9Sfvdl 
1248375b2d9Sfvdl #ifdef ICU_HARDWARE_MASK
1258375b2d9Sfvdl 
1268375b2d9Sfvdl #define	i8259_asm_mask(num) \
1272934faceSfvdl 	movb	CVAROFF(i8259_imen, IRQ_BYTE(num)),%al			;\
1288375b2d9Sfvdl 	orb	$IRQ_BIT(num),%al					;\
1292934faceSfvdl 	movb	%al,CVAROFF(i8259_imen, IRQ_BYTE(num))			;\
1308375b2d9Sfvdl 	MASKDELAY							;\
1318375b2d9Sfvdl 	outb	%al,$(ICUADDR+1)
1328375b2d9Sfvdl #define	i8259_asm_unmask(num) \
1332934faceSfvdl 	movb	CVAROFF(i8259_imen, IRQ_BYTE(num)),%al			;\
1348375b2d9Sfvdl 	andb	$~IRQ_BIT(num),%al					;\
1352934faceSfvdl 	movb	%al,CVAROFF(i8259_imen, IRQ_BYTE(num))			;\
1368375b2d9Sfvdl 	MASKDELAY							;\
1372cd70f0dSfvdl 	outb	%al,$(ICUADDR+1)
1388375b2d9Sfvdl 
1398375b2d9Sfvdl #else /* ICU_HARDWARE_MASK */
1408375b2d9Sfvdl 
1418375b2d9Sfvdl #define	i8259_asm_mask(num)
1428375b2d9Sfvdl #define	i8259_asm_unmask(num)
1438375b2d9Sfvdl 
1448375b2d9Sfvdl #endif /* ICU_HARDWARE_MASK */
1458375b2d9Sfvdl #endif /* ICU_SPECIAL_MASK_MODE */
1468375b2d9Sfvdl 
1478375b2d9Sfvdl #endif /* !_X86_I8259_H_ */
148