1 // io/irq/i8259.cc -- Intel 8259-compatible IRQ support
3 // This software is copyright (c) 2006 Scott Wood <scott@buserror.net>.
5 // This software is provided 'as-is', without any express or implied warranty.
6 // In no event will the authors or contributors be held liable for any damages
7 // arising from the use of this software.
9 // Permission is hereby granted to everyone, free of charge, to use, copy,
10 // modify, prepare derivative works of, publish, distribute, perform,
11 // sublicense, and/or sell copies of the Software, provided that the above
12 // copyright notice and disclaimer of warranty be included in all copies or
13 // substantial portions of this software.
16 #include <kern/kernel.h>
18 #include <kern/i8259.h>
23 // This assumes a second i8259 cascaded on IRQ2 of the first i8259,
24 // with I/O port bases of 0x20 and 0xa0, as every i8259 I've
25 // encountered has been configured that way, even on non-x86
26 // platforms. This can be made more general later if need be.
28 // FIXME: For non-x86 platforms, the I/O window base must be added in.
30 inline void I8259::output_mask(int off)
32 ll_out_8(off ? 0xa1 : 0x21, cached_masks[0]);
35 inline void I8259::mask(u32 irq)
42 cached_masks[off] |= (1 << bit);
46 void I8259::unmask(u32 irq)
53 cached_masks[off] &= ~(1 << bit);
57 void I8259::mask_and_ack(u32 irq)
65 ll_out_8(0x20, 0x60 | bit);
67 ll_out_8(0xa0, 0x60 | bit);
72 int I8259::get_pending_irq()
74 #if defined(_LL_ARCH_x86) || defined(_LL_ARCH_x64)
79 u8 ret = ll_in_8(0x20);
92 // Shouldn't happen, as even if the device de-asserts the
93 // cascaded interrupt, it should wait for EOI.
104 // Initialize each 8259 for edge triggered, cascade, 8086 mode.
105 // Interrupt vectors are set to 0x20-0x2f (this only matters on
108 ll_out_8(0x20, 0x11);
109 ll_out_8(0x21, 0x20);
110 ll_out_8(0x21, 0x04);
111 ll_out_8(0x21, 0x01);
113 ll_out_8(0xa0, 0x11);
114 ll_out_8(0xa1, 0x28);
115 ll_out_8(0xa1, 0x02);
116 ll_out_8(0xa1, 0x01);
118 // Mask all IRQs initially.
120 cached_masks[0] = cached_masks[1] = 0xff;
121 ll_out_8(0x21, 0xff);
122 ll_out_8(0xa1, 0xff);
124 bzero(irqslots, sizeof(irqslots));
126 for (int i = 0; i < 16; i++)
127 irqslots[i].controller = this;