PIC

[ Class Overview ] [ PIC ]

The Programmable Interrupt Controller (PIC)

The PIC 8259A is a chip (or part of a chip) that, like the processor itself, can be found on the motherboard of any PC. Its task is to coordinate the interrupt requests of the various devices.

For this purpose, the PIC has 8 input lines IR0 to IR7, to each of which the interrupt output of a device can be connected. Examples for these devices are the timer, the keyboard, the serial interfaces (mouse) and the hard disk controller. The number of the IR pin also indicates the priority of the interrupt. The device connected to IR0 is treated with the highest priority, the one connected to IR7 with the lowest.

The PIC has several outputs that are connected to the CPU. Among others the INT pin of the PIC is directly connected to the INTR pin of the CPU, likewise the pins labeled INTA on both sides are coupled. The pins D0 to D7 of the PIC are connected to the eight least significant bit lines of the data bus.

If the PIC detects that there is an interrupt request on at least one of its input lines IR0 to IR7, and the PIC has not been told to ignore the corresponding request, it will pass the interrupt request to the CPU via its output INTR. The CPU will acknowledge the request by means of the line INTA and ask for the number of the interrupt by a second signal on INTA. The PIC will respond by placing the number of the interrupt (equal to the number of the input line + an offset) on the data bus. The CPU is now able to find the start address of the associated interrupt handling routine and start the interrupt handler.

To enable the PIC to remember from which devices it has received interrupt requests, which ones it should ignore, and which ones are currently being handled by the CPU, it has three internal registers, each 8 bits wide:

Interrupt Request Register (IRR)
Here the PIC stores on which of the IR lines interrupt requests were signaled. This means that the device in question only needs to trigger a short change in the level on the line.
Interrupt Service Register (ISR)
If the interrupt requests of several devices are present at the same time, the PIC shall first forward only the most important one. For this purpose the interrupt request of the CPU is indicated via the INT line. As soon as the CPU has responded with two INTA signals, not only the number of the interrupt is output on the data lines D0–D7, but also the corresponding bit in the ISR is set. At the same time, the bit in the IRR is cleared. However, the bit in the ISR remains set until it is explicitly cleared by the interrupt handling routine using a special instruction. When another interrupt arrives, the PIC can easily tell if it is even more important than the one it just handled. In this case it will inform the CPU by sending another signal on the INT line.
Interrupt Mask Register (IMR)
Using this register it is possible to selectively suppress interrupts. A set bit in the IMR ensures that the PIC ignores interrupts of the corresponding device.

To be able to distinguish more than 8 interrupt sources, modern PCs (that means all starting from the XT) contain two PICs that are cascaded (connected in series). So the INT output of the slave PIC has no direct connection to the INTR input of the CPU, but is connected to one of the IR inputs (IR2) of the master PIC. In addition, master and slave are connected via three further lines, via which the master can inform the slave when it should put the number of the interrupt signaled by it on the data bus.

Software

Ignoring an Interrupt

On the CPU side we can ensure that the currently running program is not interrupted. This can be achieved with the assembly instruction cli, which clears the "interrupt enabled" bit in the EFLAGS register. From now on, the processor does not react to signals on its INTR line anymore. Because the PIC forwards an interrupt at the earliest when the CPU has reacted to the previous interrupt, the PIC will not forward interrupts as long as the CPU ignores them.

This can be reversed with the sti instruction.

Interrupts can also be selectively suppressed. For this the PIC must be programmed as usual with in and out instructions.

Software for Handling Interrupts

When an interrupt arrives that has been allowed by both the PIC and the CPU, the processor automatically starts the interrupt handling routine.

Its address is taken from an interrupt descriptor table (IDT), where the number of the interrupt placed on the data bus by the PIC serves as an index. With the 8086 processor the position of the interrupt descriptor table was still fixed by the hardware, with the 80386 its beginning and its size is described by the IDT register.

The interrupt descriptor table can contain a maximum of 256 interrupt gate descriptors, of which there are three different types:

Task Gate
The interrupt-gate descriptor points to a task, a hardware supported process. When the corresponding interrupt occurs, the processor automatically performs a task switch to the specified interrupt task.
Interrupt Gate
The interrupt-gate descriptor points to a procedure that is called as an interrupt handling routine without a prior task switch.
Trap Gate
The trap-gate descriptor points to a procedure that is called as a trap handling routine without a prior task switch. Main difference to interrupt gates is that interrupts are not disabled while running the trap handler.

Before the processor calls the specified handling routine as a result of an interrupt or trap, it places the current contents of the EFLAGS (or, in Long mode, RFLAGS) register on the stack. This allows it now to clear the "interrupt enable" flag in EFLAGS, preventing nested handling of further interrupts. As with a normal function call, the return address (content of code segment and instruction pointer) is then saved on the stack before the handling routine is started. For some exceptions the processor additionally places an error code on the stack.

In the case of interrupts (not traps), one task of the interrupt handling routine is to inform the PIC that the interrupt has been handled. This is necessary because otherwise the PIC will not forward any further interrupts from the same device. Sending the interrupt acknowledge signal is again done with one (or in case of cascaded PICs with two) out instruction(s) to the port of the PIC.

The iretq instruction completes interrupt handling. The processor fetches the return address from the stack, restores the contents of the EFLAGS (or RFLAGS) register and returns to the interrupted function. Due to the fact that also EFLAGS is restored, at the latest now the interrupts are enabled again on the CPU side.

Accessing the PICs via Ports

Each of the two PICs in a PC has two ports in the I/O address space with the following functionality:

Port (IRQ0–7/IRQ8–15)Read dataWrite data
0x20/0xa0IRR,ISR,Int.VektorICW1,OCW2,OCW3
0x21/0xa1IMRICW2,ICW3,ICW4,OCW1

The acronyms ICW and OCW stand for Initialization Control Word and Operation Control Word. Relevant for you are only the operation control words OCW1 and OCW2:

The initialization command words ICW1-ICW4 are used to initialize the chip, whereby among other things we specify AEOI mode. All this is done in OOStuBS within the startup code (startup.asm), so for once you don't have to take care of it yourself.


Literature