still serv_close bug...
[mit-jos.git] / kern / picirq.c
blob74373ded6f2d6351e05d9250222548c05a2aac2c
1 /* See COPYRIGHT for copyright information. */
3 #include <inc/assert.h>
5 #include <kern/picirq.h>
8 // Current IRQ mask.
9 // Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
10 uint16_t irq_mask_8259A = 0xFFFF & ~(1<<IRQ_SLAVE);
11 static bool didinit;
13 /* Initialize the 8259A interrupt controllers. */
14 void
15 pic_init(void)
17 didinit = 1;
19 // mask all interrupts
20 outb(IO_PIC1+1, 0xFF);
21 outb(IO_PIC2+1, 0xFF);
23 // Set up master (8259A-1)
25 // ICW1: 0001g0hi
26 // g: 0 = edge triggering, 1 = level triggering
27 // h: 0 = cascaded PICs, 1 = master only
28 // i: 0 = no ICW4, 1 = ICW4 required
29 outb(IO_PIC1, 0x11);
31 // ICW2: Vector offset
32 outb(IO_PIC1+1, IRQ_OFFSET);
34 // ICW3: bit mask of IR lines connected to slave PICs (master PIC),
35 // 3-bit No of IR line at which slave connects to master(slave PIC).
36 outb(IO_PIC1+1, 1<<IRQ_SLAVE);
38 // ICW4: 000nbmap
39 // n: 1 = special fully nested mode
40 // b: 1 = buffered mode
41 // m: 0 = slave PIC, 1 = master PIC
42 // (ignored when b is 0, as the master/slave role
43 // can be hardwired).
44 // a: 1 = Automatic EOI mode
45 // p: 0 = MCS-80/85 mode, 1 = intel x86 mode
46 outb(IO_PIC1+1, 0x3);
48 // Set up slave (8259A-2)
49 outb(IO_PIC2, 0x11); // ICW1
50 outb(IO_PIC2+1, IRQ_OFFSET + 8); // ICW2
51 outb(IO_PIC2+1, IRQ_SLAVE); // ICW3
52 // NB Automatic EOI mode doesn't tend to work on the slave.
53 // Linux source code says it's "to be investigated".
54 outb(IO_PIC2+1, 0x01); // ICW4
56 // OCW3: 0ef01prs
57 // ef: 0x = NOP, 10 = clear specific mask, 11 = set specific mask
58 // p: 0 = no polling, 1 = polling mode
59 // rs: 0x = NOP, 10 = read IRR, 11 = read ISR
60 outb(IO_PIC1, 0x68); /* clear specific mask */
61 outb(IO_PIC1, 0x0a); /* read IRR by default */
63 outb(IO_PIC2, 0x68); /* OCW3 */
64 outb(IO_PIC2, 0x0a); /* OCW3 */
66 if (irq_mask_8259A != 0xFFFF)
67 irq_setmask_8259A(irq_mask_8259A);
70 void
71 irq_setmask_8259A(uint16_t mask)
73 int i;
74 irq_mask_8259A = mask;
75 if (!didinit)
76 return;
77 outb(IO_PIC1+1, (char)mask);
78 outb(IO_PIC2+1, (char)(mask >> 8));
79 cprintf("enabled interrupts:");
80 for (i = 0; i < 16; i++)
81 if (~mask & (1<<i))
82 cprintf(" %d", i);
83 cprintf("\n");