3
* Graeme Russ, graeme.russ@gmail.com
6
* Daniel Engstr�m, Omicron Ceti AB, daniel@omicron.se.
8
* See file CREDITS for list of people who contributed to this
11
* This program is free software; you can redistribute it and/or
12
* modify it under the terms of the GNU General Public License as
13
* published by the Free Software Foundation; either version 2 of
14
* the License, or (at your option) any later version.
16
* This program is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
* GNU General Public License for more details.
21
* You should have received a copy of the GNU General Public License
22
* along with this program; if not, write to the Free Software
23
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28
* This file provides the interrupt handling functionality for systems
29
* based on the standard PC/AT architecture using two cascaded i8259
30
* Programmable Interrupt Controllers.
35
#include <asm/i8259.h>
36
#include <asm/ibmpc.h>
37
#include <asm/interrupt.h>
39
#if CONFIG_SYS_NUM_IRQS != 16
40
#error "CONFIG_SYS_NUM_IRQS must equal 16 if CONFIG_SYS_NUM_IRQS is defined"
43
int interrupt_init(void)
49
/* Mask all interrupts */
50
outb(0xff, MASTER_PIC + IMR);
51
outb(0xff, SLAVE_PIC + IMR);
54
/* Place master PIC interrupts at INT20 */
55
/* ICW3, One slave PIC is present */
56
outb(ICW1_SEL|ICW1_EICW4, MASTER_PIC + ICW1);
57
outb(0x20, MASTER_PIC + ICW2);
58
outb(IR2, MASTER_PIC + ICW3);
59
outb(ICW4_PM, MASTER_PIC + ICW4);
61
for (i = 0; i < 8; i++)
62
outb(OCW2_SEOI | i, MASTER_PIC + OCW2);
65
/* Place slave PIC interrupts at INT28 */
67
outb(ICW1_SEL|ICW1_EICW4, SLAVE_PIC + ICW1);
68
outb(0x28, SLAVE_PIC + ICW2);
69
outb(0x02, SLAVE_PIC + ICW3);
70
outb(ICW4_PM, SLAVE_PIC + ICW4);
72
for (i = 0; i < 8; i++)
73
outb(OCW2_SEOI | i, SLAVE_PIC + OCW2);
76
* Enable cascaded interrupts by unmasking the cascade IRQ pin of
86
void mask_irq(int irq)
90
if (irq >= CONFIG_SYS_NUM_IRQS)
94
imr_port = SLAVE_PIC + IMR;
96
imr_port = MASTER_PIC + IMR;
98
outb(inb(imr_port) | (1 << (irq & 7)), imr_port);
101
void unmask_irq(int irq)
105
if (irq >= CONFIG_SYS_NUM_IRQS)
109
imr_port = SLAVE_PIC + IMR;
111
imr_port = MASTER_PIC + IMR;
113
outb(inb(imr_port) & ~(1 << (irq & 7)), imr_port);
116
void specific_eoi(int irq)
118
if (irq >= CONFIG_SYS_NUM_IRQS)
123
* IRQ is on the slave - Issue a corresponding EOI to the
124
* slave PIC and an EOI for IRQ2 (the cascade interrupt)
127
outb(OCW2_SEOI | (irq & 7), SLAVE_PIC + OCW2);
131
outb(OCW2_SEOI | irq, MASTER_PIC + OCW2);