Interrupts
Basics
Busy-wait I/O is extremely inefficient—the
CPU does nothing but test the device status
while the I/O transaction is in progress. In
many cases, the CPU could do useful work in
parallel with the I/O transaction, such as:
ü
computation, as in determining the next
output to send to the device or processing
the last input received, and
ü
control of other I/O devices. To allow
parallelism,we need to introduce
new
The interrupt mechanism allows devices to
signal the CPU and to force execution of a
particular piece of code. When an interrupt
occurs, the program counter’s value is changed
to point to an interrupt handler routine
(also commonly known as a device driver) that
takes care of the device: writing the next
data, reading data that have just become ready,
and so on. The interrupt mechanism of course
saves the value of the PC at the interruption
so that the CPU can return to the program
that was interrupted. Interrupts therefore allow
the flow of control in the CPU to change
easily between different contexts, such as a
foreground computation and multiple I/O
devices. As shown in Figure, the interface
between the CPU and I/O device includes the
following signals for interrupting:
ü the I/O device asserts the interrupt
request signal when it wants service from the
CPU; and
ü the CPU asserts the interrupt acknowledge
signal when it is ready to handle the I/O
device’s request.
The I/O device’s logic decides when to
interrupt; for example, it may generate an
interrupt when its status register goes into
the ready state. The CPU may not be able to
immediately service an interrupt request
because it may be doing something else that must
be finished first—for example, a program that
talks to both a high-speed disk drive and
a low-speed keyboard should be designed to
finish a disk transaction before handling a
keyboard interrupt. Only when the CPU decides
to acknowledge the interrupt does the
CPU change the program counter to point to
the device’s handler. The interrupt handler
operates much like a subroutine, except that
it is not called by the executing program.
The program that runs when no interrupt is
being handled is often called the foreground
program; when the interrupt handler finishes,
it returns to the foreground program,
wherever processing was interrupted.
The interrupt mechanism.
Ø Priorities and Vectors
Providing a practical interrupt system
requires having more than a simple interrupt
request line. Most systems have more than one
I/O device, so there must be some mechanism
for allowing multiple devices to interrupt.We
also want to have flexibility in the locations of the
interrupt handling routines,the addresses for
devices,and so on. There are two ways in which
interrupts can be generalized to handle
multiple devices and to provide more flexible definitions
for the associated hardware and software:
ü interrupt priorities allow the CPU to
recognize some interrupts as more important
than others, and
ü interrupt vectors allow the interrupting
device to specify its handler.
Prioritized interrupts not only allow
multiple devices to be connected to the interrupt
line but also allow the CPU to ignore less
important interrupt requests while it handles more
important requests. As shown in Figure, the
CPU provides several different interrupt request
signals, shown here as L1, L2, up to Ln.
Typically, the lower-numbered interrupt lines are given
higher priority, so in this case, if devices
1, 2,and n all requested interrupts simultaneously, 1’s
request would be acknowledged because it is
connected to the highest-priority interrupt line.
Rather than provide a separate interrupt
acknowledge line for each device, most CPUs
use a set of signals that provide the
priority number of the winning interrupt in binary form (so
that interrupt level 7 requires 3 bits rather
than 7). A device knows that its interrupt request was
accepted by seeing its own priority number on
the interrupt acknowledge lines.
Prioritized device interrupts.
How do we change the priority of a device?
Simply by connecting it to a different
interrupt request line. This requires hardware
modification, so if priorities need to be
changeable, removable cards, programmable switches, or
some other mechanism should be provided to
make the change easy.
The priority mechanism must ensure that a
lower-priority interrupt does not occur when
a higher-priority interrupt is being handled.
The decision process is known as masking. When
an interrupt is acknowledged, the CPU stores
in an internal register the priority level of that
interrupt. When a subsequent interrupt is
received, its priority is checked against the priority
register; the new request is acknowledged
only if it has higher priority than the currently pending
interrupt.
When the interrupt handler exits, the
priority register must be reset. The need to reset the
priority register is one reason why most
architectures introduce a specialized instruction to return
from interrupts rather than using the
standard subroutine return instruction. The highest-priority
interrupt is normally called the non maskable
interrupt (NMI).The NMI cannot be turned off
and is usually reserved for interrupts caused
by power failures—a simple circuit can be used
to detect a dangerously low power supply, and
the NMI interrupt handler can be used to save
critical state in nonvolatile memory, turn
off I/O devices to eliminate spurious device operation
during power down, and so on.
Most CPUs provide a relatively small number
of interrupt priority levels, such as eight.
While more priority levels can be added with
external logic, they may not be necessary in all
cases. When several devices naturally assume
the same priority (such as when you have several
identical keypads attached to a single CPU),
you can combine polling with prioritized interrupts
to efficiently handle the devices.
Using polling to share an interrupt over
several devices.
Vectors provide flexibility in a different
dimension, namely, the ability to define the
interrupt handler that should service a
request from a device. Figure shows the hardware
structure required to support interrupt
vectors. In addition to the interrupt request and
acknowledge lines, additional interrupt
vector lines run from the devices to the CPU. After a
device’s request is acknowledged, it sends
its interrupt vector over those lines to the CPU. The
CPU then uses the vector number as an index
in a table stored in memory as shown in Figure.
The location referenced in the interrupt
vector table by the vector number gives the address of
the handler.
There are two important things to notice
about the interrupt vector mechanism.
First, the device, not the CPU, stores its
vector number. In this way, a device can be given
a new handler simply by changing the vector
number it sends, without modifying the system
software. For example, vector numbers can be
changed by programmable switches.
The second thing to notice is that there is
no fixed relationship between vector numbers
and interrupt handlers. The interrupt vector
table allows arbitrary relationships between devices
and handlers. The vector mechanism provides
great flexibility in the coupling of hardware
devices and the software routines that
service them.
Most modern CPUs implement both prioritized
and vectored interrupts. Priorities
determine which device is serviced first, and
vectors determine what routine is used to service
the interrupt. The combination of the two
provides a rich interface between hardware and
software.