root/picirq.c
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- picsetmask
- picenable
- picinit
1 // Intel 8259A programmable interrupt controllers.
2
3 #include "types.h"
4 #include "x86.h"
5 #include "traps.h"
6
7 // I/O Addresses of the two programmable interrupt controllers
8 #define IO_PIC1 0x20 // Master (IRQs 0-7)
9 #define IO_PIC2 0xA0 // Slave (IRQs 8-15)
10
11 #define IRQ_SLAVE 2 // IRQ at which slave connects to master
12
13 // Current IRQ mask.
14 // Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
15 static ushort irqmask = 0xFFFF & ~(1<<IRQ_SLAVE);
16
17 static void
18 picsetmask(ushort mask)
19 {
20 irqmask = mask;
21 outb(IO_PIC1+1, mask);
22 outb(IO_PIC2+1, mask >> 8);
23 }
24
25 void
26 picenable(int irq)
27 {
28 picsetmask(irqmask & ~(1<<irq));
29 }
30
31 // Initialize the 8259A interrupt controllers.
32 void
33 picinit(void)
34 {
35 // mask all interrupts
36 outb(IO_PIC1+1, 0xFF);
37 outb(IO_PIC2+1, 0xFF);
38
39 // Set up master (8259A-1)
40
41 // ICW1: 0001g0hi
42 // g: 0 = edge triggering, 1 = level triggering
43 // h: 0 = cascaded PICs, 1 = master only
44 // i: 0 = no ICW4, 1 = ICW4 required
45 outb(IO_PIC1, 0x11);
46
47 // ICW2: Vector offset
48 outb(IO_PIC1+1, T_IRQ0);
49
50 // ICW3: (master PIC) bit mask of IR lines connected to slaves
51 // (slave PIC) 3-bit # of slave's connection to master
52 outb(IO_PIC1+1, 1<<IRQ_SLAVE);
53
54 // ICW4: 000nbmap
55 // n: 1 = special fully nested mode
56 // b: 1 = buffered mode
57 // m: 0 = slave PIC, 1 = master PIC
58 // (ignored when b is 0, as the master/slave role
59 // can be hardwired).
60 // a: 1 = Automatic EOI mode
61 // p: 0 = MCS-80/85 mode, 1 = intel x86 mode
62 outb(IO_PIC1+1, 0x3);
63
64 // Set up slave (8259A-2)
65 outb(IO_PIC2, 0x11); // ICW1
66 outb(IO_PIC2+1, T_IRQ0 + 8); // ICW2
67 outb(IO_PIC2+1, IRQ_SLAVE); // ICW3
68 // NB Automatic EOI mode doesn't tend to work on the slave.
69 // Linux source code says it's "to be investigated".
70 outb(IO_PIC2+1, 0x3); // ICW4
71
72 // OCW3: 0ef01prs
73 // ef: 0x = NOP, 10 = clear specific mask, 11 = set specific mask
74 // p: 0 = no polling, 1 = polling mode
75 // rs: 0x = NOP, 10 = read IRR, 11 = read ISR
76 outb(IO_PIC1, 0x68); // clear specific mask
77 outb(IO_PIC1, 0x0a); // read IRR by default
78
79 outb(IO_PIC2, 0x68); // OCW3
80 outb(IO_PIC2, 0x0a); // OCW3
81
82 if(irqmask != 0xFFFF)
83 picsetmask(irqmask);
84 }