Microprocessor Interrupts and Exceptions
The following writing example is from the AMD-K5 Technical
Reference Manual. We wrote the manual,
based on interviews with the AMD architecture team.
Interrupts and exceptions are often differentiated in x86 documentation
as follows: an interrupt is the assertion of a hardware
input signal and an exception is a software event, such
as an invalid opcode or execution of an INTn instruction. In some
documents, however, the terms interrupt and exception apply to
both hardware and software events, which are then differentiated
as external or hardware interrupts or exceptions, and internal
or software interrupts or exceptions, respectively. In still other
x86 documents, the term software interrupt means an INTn instruction
that vectors to an interrupt gate. Moreover, some of the old rules
commonly applied to interrupts do not apply to the external interrupts
defined for the Pentium processor: for example, not all external
interrupts alter the program flow, and not all are acknowledged
by the processor.
Because these variations in definition are potentially confusing,
this document assumes only the following definitions:
- Interrupt: The assertion (or in the case, of R/S#, the
driving Low) of one of eight hardware input signals (BUSCHK#,
R/S#, FLUSH#, SMI#, INIT, NMI, INTR, or STPCLK#).
- Exception: Any software-initiated event that accesses
an entry in the Real-Mode interrupt vector table (IVT) or in
the Protected-Mode interrupt descriptor table (IDT).
- External Interrupt: Same as interrupt.
- Software Interrupt: In Real Mode, any INTn instruction.
In Protected Mode, any INTn instruction that vectors to an IDT
entry that is an interrupt gate, or that is a task gate which
references a TSS with the interrupt flag (IF) cleared in its
EFLAGS image. (INTn instructions that vector to a trap gate are
not considered software interrupts because the processor does
not clear IF in such cases).
All interrupts are recognized on the next instruction-retirement
boundary. Most exceptions are recognized at the point in the instruction
where they occur, and are not usually deferred to the end of the
instruction. All interrupts and exceptions invalidate (flush) the
pipeline when recognized. All exceptions are handled precisely
so that the instruction causing an exception can be restarted after
the exception is serviced.
The processor writes (pushes) its current state onto the stack
prior to entering the service routine for exceptions and for BUSCHK#,
SMI#, NMI, and INTR interrupts. Because of these writes, the state
of EWBE# affects the processor's response to such interrupts and
exceptions. For example, if the processor has initiated a write
cycle prior to the next instruction-retirement boundary on which
such an interrupt would otherwise be recognized, the bus cycle
completes but the processor does not respond to the interrupt until
it samples EWBE# asserted so that it can write to the stack. Also,
if the processor has written to the stack once and EWBE# is not
asserted thereafter, the processor does not write again and its
response to an interrupt is halted. A negated EWBE# also pauses
the processor's response to FLUSH#, if the flush causes writebacks.
However, during interrupts that do not write to memory (R/S#, FLUSH#
if there are no writebacks, INIT, and STPCLK#) the state of EWBE#
has no affect on the processor's recognition of or response to
such interrupts.
The processor performs an interrupt by executing a microcode routine.
In this sense, an interrupt acts like the execution of a complex
instruction and the microcode routine has a completion boundary
that acts like an instruction-retirement boundary. In effect, the
microcode routine for an interrupt begins executing when the interrupt
is recognized on an instruction boundary and it finishes executing
when an associated interrupt service routine begins or the hardware
aspect of the interrupt function otherwise completes. For example,
the FLUSH# interrupt completes when all modified cache lines have
been written back to memory and all cache lines are invalidated,
whereas the R/S# interrupt completes when the processor negates
PRDY, and the STPCLK# interrupt completes when the processor drives
the Stop-Grant special bus cycle.
The four edge-triggered interrupts (FLUSH#, SMI#, INIT, and NMI)
are latched on one of the edges of CLK when they are asserted and
are recognized later, even if they are negated before being recognized.
The four level-sensitive interrupts (BUSCHK#, R/S#, INTR, and STPCLK#)
must be held asserted until recognized, except that the BUSCHK#
interrupt is sampled and latched with every BRDY#.
The processor disables the recognition of interrupts or exceptions
in the following cases:
- INTR Interrupt: The processor disables INTR interrupts
during all software interrupts (that is, INTn instructions that
vector through interrupt gates or through task gates that reference
a TSS with IF cleared in its EFLAGS image). It does this by automatically
clearing the IF bit in EFLAGS. If system logic can leave the
INTR signal asserted after the INTR service routine is entered,
the interrupt vector returned by system logic during the Interrupt-Acknowledge
operation must be for an interrupt gate or for a task gate that
references a TSS with IF cleared. (Software may set the IF flag
again upon entering the service routine.)
- NMI Interrupts: The processor disables NMI interrupts
until the IRET of the NMI service routine.
- Debug Breakpoints: After a debug breakpoint exception,
the debug service routine can disable debug exceptions for one
instruction by setting the resume flag (RF) in EFLAGS to 1, thus
preventing restarted instructions from generating another debug
fault. (The processor always clears RF to 0 after a debug exception,
to enable the recognition of a subsequent debug exception. The
AMD-K5 processor does not disable instruction-breakpoint exceptions
after MOV or POP instructions that load the stack segment selector,
as is done on the Pentium processor.)
Table 4-4 shows the characteristics of interrupts and exceptions
and the priority with which the processor recognizes them. The
term priority means two things here:
- Simultaneous Interrupts: The order in which a single
interrupt or exception is selected for recognition if all occur
simultaneously, and
- Latched Interrupts: The order in which latched interrupts
(any of the four edge-triggered interrupts, FLUSH#, SMI#, INIT,
or NMI) are recognized when the processor becomes interruptible
again after it recognizes a prior interrupt or exception. By
contrast, the term priority does not mean the order in which
level-sensitive interrupts (BUSCHK#, R/S#, INTR, and STPCLK#)
are nested, if one such interrupt occurs while the processor
is responding to another interrupt.
Interrupts are themselves interruptible only if they have a software
component, such as a service routine. All other interrupts complete
their action before the processor recognizes another interrupt.
Lower-priority interruptible interrupts can be interrupted by higher-priority
interrupts or exceptions at their point of interruptibility, which
is shown in the right-most column of Table 4-4 and is always on
an instruction boundary.
The processor recognizes BOFF#, HOLD, and AHOLD while any interrupt
signal is asserted, and these signals will intervene with their
normal timing in the handling of any interrupt or exception. The
interrupt or exception continues from where it left off after the
intervening signal is negated. For example, if BOFF# is asserted
while a FLUSH# operation is writing modified cache lines back to
memory, an in-progress writeback will be aborted but will be re-started
after BOFF# is negated, and the FLUSH# operation will then continue;
any writebacks that completed before BOFF# was asserted are not
affected. |