The programmable interrupt controller is a chip on the IBM PC which is responsible for multiplexing interrupts from peripherals into one interrupt line on the CPU.
When a device needs to inform the system (i.e.: when new data is available, or on completion of a task), it fires an Interrupt Request (hence the name IRQ). The PIC then decides what to do with this interrupt request by looking at his internal configuration registers. The PIC can then decide to deliver the interrupt to the CPU (if the interrupt line is not masked), and find out the number of the IDT entry to call.
Typical wiring of the PIC
Each PIC has eight input lines (connected to peripherals) and one output line (connected to the CPU). The IBM PC has typically 2 PICs : one master and one slave. The slave’s output pin is connected to the master’s second input pin.
Here are the devices typically conntected to the PICs on an IBM PC :
- Master 8259
- IRQ0 – Intel 8253 or Intel 8254 Programmable Interval Timer, aka the system timer or PIT
- IRQ1 – Intel 8042 keyboard controller
- IRQ2 – not assigned in PC/XT; cascaded to slave 8259 INT line in PC/AT
- IRQ3 – 8250 UART serial port COM2 and COM4
- IRQ4 – 8250 UART serial port COM1 and COM3
- IRQ5 – hard disk controller in PC/XT; Intel 8255 parallel port LPT2 in PC/AT
- IRQ6 – Intel 82072A floppy disk controller
- IRQ7 – Intel 8255 parallel port LPT1 / spurious interrupt
- Slave 8259 (PC/AT and later only)
- IRQ8 – real-time clock (RTC)
- IRQ9 – no common assignment
- IRQ10 – no common assignment
- IRQ11 – no common assignment
- IRQ12 – Intel 8042 PS/2 mouse controller
- IRQ13 – math coprocessor
- IRQ14 – hard disk controller 1
- IRQ15 – hard disk controller 2
Configuring the PIC
The IBM PC’s PIC is configured by using regular port-mapped I/O. The four port numbers are:
0x20, the master PIC’s port A
0x21, the master PIC’s port B
0xA0, the slave PIC’s port A
0xA1, the slave PIC’s port B
The PIC’s initialization is done with Initialization Command Words (ICW). The kernel has to send a series of ICW (ICW1 through ICW4) to both PICs to initialize them.
The first ICW sets a few parameters controlling the PIC’s mode of operation. ICW1 has to be sent to port A of each PIC.
0 0 0 1 x 0 x x | | | | | +---- (1) | +------ (2) +---------- (3)
- ICW4 present (set) or not (clear)
- single controller (set) or cascade mode (clear)
- level triggered mode (set) or edge triggered mode (clear)
As said earlier, we typically have two PICs on an IBM PC, so we work in cascade mode. We also know that interrupts are edge triggered and we will need to program the ICW4, so a typical initialization sequence would be:
mov $0x11, %al ; We can only output %al to I/O ports, not immediate values outb %al, $0x20 ; Send $0x11 to the master PIC outb %al, $0xA0 ; Send $0x11 to the slave PIC
The second ICW informs the PIC about the base offset in the interrupt descriptor table (IDT) to use when transmitting an IRQ from a device to the CPU. The base offset must be a multiple of 8 (hence the three last zeroes in the following scheme). ICW2 has to be sent to port B of each PIC.
x x x x x 0 0 0 | | | | | | | | +------------------ (1)
- Interrupt vector base address
Both PICs handle different IRQs from devices, so a different base offset must be configured for each one of them.
For example, if we send the following command words:
mov $0x40, %al outb %al, 0x21 ; Set the master PIC's base offset to 64 add $0x10, %al outb %al, 0xA1 ; Set the slave PIC's base offset to 80
an IRQ coming from the keyboard would be handled by the IDT entry number 65 (0x40 + 1), and an IRQ coming from the hard disk controller 1 by the IDT entry number 86 (0x50 + 6).
The third ICW is used to give information about how master and slave PICs are connected. The ICW3 is sent to port B of each PIC.
The ICW3’s format is not the same for the master and the slave PIC:
Master PIC x x x x x x x x | | | | | | | | +------------------ (1) Slave PIC 0 0 0 0 0 x x x | | | +-------- (2)
- For each bit, indicate whether a slave PIC is connected to this pin (set) or not (clear)
- Indicate to the slave his slave ID (which pin of the master it is connected to)
The fourth ICW sets some additional operation modes for the PICs. It has to be sent to port B of each PIC.
0 0 0 x x x x 1 | --- | | | +------ (1) | +--------- (2) +------------ (3)
- Automatic (set) EOI or normal (clear) EOI
- Buffering mode
- Special mode fully nested (set) or not (clear)
When no special mode of operation is required, the programmer can just clear every configuration bit. For example:
mov $0x01, %al outb %al, 0x21 outb %al, 0xA1
When the PIC is initialized, the kernel can send Operation Control Words (OCW) to the PIC to perform various tasks such as acknowledging an IRQ.
OCW1 is used to mask/unmask IRQs on a PIC. It is just sent to port B of the PIC.
x x x x x x x x | | | | | | | | +------------------ (1)
- For each bit, indicate whether the corresponding IRQ is masked (set) or not (clear)
For example, if we want to mask the IRQ 3 of the master PIC, we could do something like:
mov $1, %bl shl $3, %bl inb $0x21, %al or %bl, %al outb %al, $0x21
OCW2 is one of the most frequently used control words in normal operation mode. It allows the kernel, among other things, to acknowledge an IRQ. If an IRQ is not acknowledged, the PIC won’t send any other interrupt for a given peripheral. OCW2 is sent to each PIC’s port A.
x x x 0 0 x x x | | | ----- | | | | | | | +------ (1) | | +-------------- (2) | +---------------- (3) +------------------ (4)
- Interrupt level to be acted upon when sending a specific command
- Send an EOI (end of interrupt command) (set)
- Send a specific (set) or a non-specific (clear) command
- Rotate priorities (set) or not (clear)
When the kernel just wants to acknowledge the latest IRQ handled, it can just send a non-specific EOI command. Always remember that if the IRQ was fired by the slave PIC, both master and slave PICs have to be acknowledged:
mov $0x20, %al outb %al, $0x20 ; Send ACK to master PIC outb %al, $0xA0 ; Send ACK to slave PIC
Thanks to the nested interrupts system, the latest handled IRQ is always the one with the highest priority (i.e.: the one with the smallest number), so a specific EOI command is not required and the PIC can determine the acknowledged IRQ by itself.
- 8259A’s datasheet