The 8259 Programmable Interrupt Controller
Introduction
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.
ICW-1
7 | 6 |
5 | 4 |
3 | 2 |
1 | 0 |
0 | 0 |
0 | 1 |
LTIM | ADI |
SNGL | IC4 |
- Bits 7..5 are used for the interrupt vector address when operating the PIC in
MCS-80/85 mode and should always be set to 0 when working on an 80x86 system.
- Bit 4 must be set to 1 and indicates that the controller is being initialized.
- If LTIM is set (LTIM=1), the controller operates in Level Triggered mode
as opposed to Edge Triggered. The controller is usually initialized with
LTIM = 0 when operating on 80x86 systems.
- If ADI is set, the CALL address interval is set to 4, otherwise it is set to
8. This field can be ignored for non MCS-80/85 systems that does not require
that an automatic CALL operation code is sent to the processor. By convention,
this field is always cleared on 80x86 based systems.
- Setting SGNL indicates that there is only a single controller present. Clearing
SGNL allows cascading. ICW-3 must be sent to the controller if SGNL is cleared.
- Setting IC4 indicates that the controller should expect to receive ICW4
during the initialization process.
ICW-2
7 | 6 |
5 | 4 |
3 | 2 |
1 | 0 |
A15/T7 | A14/T6 |
A13/T5 | A12/T4 |
A11/T3 | A10 |
A9 | A8 |
- Bits 7..3 specify address bits A15..A11 for the interrupt vector address when
operating in MCS-80/85 mode.
- Bits 2..0 specify address bits A10..A8 for the interrupt vector address
when operating in MCS-80/85 mode and can be set to 0 when working on
an 80x86 system. T7..T3 is used to specify the interrupt vector address when
the controller operates in 80x86 mode.
ICW-3 (Master Device)
7 | 6 |
5 | 4 |
3 | 2 |
1 | 0 |
S7 | S6 |
S5 | S4 |
S3 | S2 |
S1 | S0 |
- S7..S0 indicates that the specified interrupt request (IR) is connected
to a slave.
ICW-3 (Slave Device)
7 | 6 |
5 | 4 |
3 | 2 |
1 | 0 |
0 | 0 |
0 | 0 |
0 | ID2 |
ID1 | ID0 |
- Bits 7..3 must be set to 0.
- ID2..ID0 selects the IRQ line on the master controller to which the slave is
connected and specifies the IRQ number in binary. For example, a value of
001b
selects IRQ-1 while a value of 100b
selects
IRQ-4.
ICW-4
7 | 6 |
5 | 4 |
3 | 2 |
1 | 0 |
0 | 0 |
0 | SFNM |
BUF | M/S |
AEOI | µPM |
- Bits 7..5 must be set to 0.
- Setting SFNM selects the special fully nested mode which is often used
in large systems containing multiple cascaded controllers to recognize mutliple
levels of prioritized interrupts on a slave controller.
- When BUF is set, the controller operates in buffered mode.
- When BUF is set, M/S can be used to select Buffered Master (M/S = 1) or
Buffered Slave (M/S = 0).
- Setting AEOI selects automatic end of interrupt mode whereby the controller
automatically performs an end of interrupt (EOI) operation on the
trailing edge of the last interrupt acknowledge pulse.
- Setting µPM indicates that the controller is operating in 8086/8088 mode.
Clearing µPM selects MCS-80/85 mode.
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 |
- M7..M0 control the mask bits for the associated interrupt line. Setting
a bit enables the mask and inhibits the specified interrupt.
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.
OCW-2
7 | 6 |
5 | 4 |
3 | 2 |
1 | 0 |
R | SL |
EOI | 0 |
0 | L2 |
L1 | L0 |
- Bits 3 and 4 are always set to 0.
- L2..L0 can be used to set the interrupt level upon which the controller must
react.
-
R | SL |
EOI | Selection |
0 | 0 |
0 | Rotate in Automatic EOI mode (CLEAR) |
0 | 0 |
1 | Non-specific EOI command |
0 | 1 |
0 | No Operation |
0 | 1 |
1 | Specific EOI command |
1 | 0 |
0 | Rotate in Automatic EOI mode (SET) |
1 | 0 |
1 | Rotate on non-specific EOI |
1 | 1 |
0 | Set priority command |
1 | 1 |
1 | Rotate on specific EOI |
The rotation options can be used to alter the priorities of the various interrupts.
IRQs are usually prioritized in ascending order (IRQ0 has the highest priority), but
by enabling priority rotation, the device currently being serviced receives the lowest
priority. The aim of this mode is to enforce an equal priority scheme and should
be used in systems where multiple devices with the same priority level
must be serviced.
Example
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.
- The adapter sends a signal to the PIC by driving interrupt line 3 from low to high.
- 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.
- 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.
- 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.
- 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.
- 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.
- The processor now interrupts the currently executing program by pushing
the contents of the
EFLAGS
, CS
and EIP
register on the stack.
- 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.
- 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.
- 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
- 8259A Programmable Interrupt Controller (8259A/8259A-2) Datasheet, 1988,
Intel Corporation, Order Number: 231468-003.
- The Undocumented PC, Frank van Gilluwe, Addison Wesley, 1997.
- Protected Mode Software Architecture, Tom Shanley, Mindshare Inc.,
Addison Wesley, 1996.
- Programming the 80386, Crawford and Gelsinger, Sybex, 1986.
Page developed by Jacques Eloff
Last updated: 12.01.2005