The 8259 Programmable Interrupt Controller


One of the main tasks of operating systems entails the management of resources. These resources may include various devices used for both input and output. Two major techniques exist whereby devices can be managed. The first technique is called polling and requires that the system interrogates (polls) each device separately to determine if the device requires servicing. Once every device has been polled, a new iteration is started and the devices are polled again. This method is not very effective because the system spends a large amount of processing time polling devices that may not require any servicing.

The second technique is based on interrupts and allows a system to service devices on demand (asynchronously), thereby increasing the time available to perform other processing tasks. A device that requires servicing will initiate an interrupt signal causing the system to stop its current task (after the processor has completed the current instruction) and transfer control to the service routine associated with the interrupt request. Control is transferred back to the interrupted task once the service routine has completed its task.

Most personal computers (PCs) contain an 8259A programmable interrupt controller (PIC) to manage the interrupt signals received from devices. A single 8259A PIC can handle 8 separate interrupts and multiple PICs can be cascaded to handle up to 64 interrupts. The original IBM PC/XT contained a single PIC, but engineers soon realized that a secondary controller was needed to accommodate all the new devices being developed for PCs. Today, most PCs contain two interrupt controllers, with the secondary controller chained (cascaded) unto the first controller (on most PCs, the secondary controller is chained to the second interrupt line of the primary controller) making it unavailable to other devices.

Communicating with the 8259A

Communication with the 8259A is facilitated by sending various commands over the bus to the two I/O ports (port A and port B) of the controller. Port A and B of the primary controller is located at I/O addresses 20H and 21H respectively. Port A and B of the secondary controller can be accessed at I/O addresses A0H and A1H.

Initializing the 8259A

The 8259A PIC is initialized by sending a sequence of initialization control words (ICWs) to the controller. ICW-1 must be sent to port A while ICW-2, ICW-3 and ICW-4 are sent to port B. Systems containing more than one PIC must send ICWs to both the primary and secondary controllers.
7 6 5 4 3 2 1 0

7 6 5 4 3 2 1 0
A15/T7 A14/T6 A13/T5 A12/T4 A11/T3 A10 A9 A8

ICW-3 (Master Device)
7 6 5 4 3 2 1 0
S7 S6 S5 S4 S3 S2 S1 S0

ICW-3 (Slave Device)
7 6 5 4 3 2 1 0
0 0 0 0 0 ID2 ID1 ID0

7 6 5 4 3 2 1 0

Controlling the 8259A

The 8259A PIC can be controlled by sending specific operation command words (OCWs) to either port B (OCW-1) or port A (OCW-2 and OCW-3).
OCW-1 (Interrupt Mask Register)
7 6 5 4 3 2 1 0
M7 M6 M5 M4 M3 M2 M1 M0

The current value of the interrupt mask register (IMR) can be obtained by reading OCW-1 from port B and set by writing OCW-1 to port B. IRQ0..IRQ7 are controlled by the primary controller's IMR, IRQ8..15 are controlled by the secondary controller's IMR. The IMR controls the various interrupt signals that will be sent to the CPU. Setting a specific bit in the IMR inhibits (disable) the associated interrupt while clearing a specific bit will enable recognition of the associated interrupt.
7 6 5 4 3 2 1 0
R SL EOI 0 0 L2 L1 L0


In this example, we consider an adapter card using interrupt line 3 to generate an interrupt signal. We will assume that the processor is operating in protected and examine how the various hardware and software components interact to service the device. Please note that the example does not address situations involving task switches or privilege level changes.
  1. The adapter sends a signal to the PIC by driving interrupt line 3 from low to high.
  2. The PIC records the request in the interrupt request register (IRR) by setting the bit position corresponding to the interrupt line in the IRR. In this example, bit 3 of the IRR will be set to 1.
  3. The PIC proceeds by examining the contents of the IMR to determine if the requested interrupt may be serviced. If the interrupt is not inhibited, the PIC determines if there are any higher priority interrupts waiting to be serviced or in the process of being serviced. The PIC takes no further action if there are any outstanding interrupts.
  4. If there are no outstanding interrupts, the PIC sends a signal to the CPU over a dedicated interrupt line to inform the processor that a hardware interrupt has occurred.
  5. Upon receiving a signal from the PIC, the CPU completes execution of the current instruction and delays the execution of the next instruction in the prefetch queue or instruction pipeline. The CPU now examines the interrupt flag in the EFLAGS register. If the interrupt flag is set, the processor will recognize external interrupts and sends an acknowledgement signal back to the PIC.
  6. When the PIC receives the acknowledgement signal, it sends the interrupt vector number to the processor. The vector is obtained from the contents loaded into ICW-2 during initialization and combined with the interrupt request number. The PIC also sets bit 3 of the in-service register (ISR) indicating that interrupt servicing is in progress.
  7. The processor now interrupts the currently executing program by pushing the contents of the EFLAGS, CS and EIP register on the stack.
  8. The processor uses the interrupt vector number to locate a gate descriptor in the IDT. The selector field of the gate descriptor is now loaded into the CS segment selector to obtain a segment descriptor from the GDT. The offset field of the gate descriptor in the IDT is loaded into EIP and, together with the base address of the segment descriptor in the GDT will form the linear address for the entry point into the service routine. If paging is enabled, the CPU will first translate the linear address to a physical address, otherwise the linear address will map directly to a physical memory location. Depending on the structure of the system, a number of checks are performed by the processor to verify the access rights of the segment containing the service routine. The processor will also clear the interrupt flag in the EFLAGS register if the IDT entry for the service routine selected an interrupt-gate descriptor. The IF bit is left unchanged if either a task-gate or trap-gate descriptor was selected.
  9. The interrupt service routine (ISR) can now perform all necessary tasks required to service the specific device. Typical operations may include reading/writing data from/to the device, examining status registers, etc. Once the device has been serviced, the ISR sends an end of interrupt (EOI) signal to the PIC. Upon receiving the EOI signal, the PIC clears the bit in the in-service register associated with interrupt 3 and is ready to accept new interrupts.
  10. The service routine is now complete and will execute an IRETD instruction, popping the EFLAGS, CS and EIP registers (previously stored by the processor) from the stack, transferring control back to the interrupted task.

Further Reading

Page developed by Jacques Eloff
Last updated: 12.01.2005