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