AP-578
22
2/21/97 12:57 PM 24329102.DOC
INTEL CONFIDENTIAL
(until publication date)
3.5 Need for Preserving the State
of IGNNE# Circuit if Use FPU
and SMM
In Section 2.3.2 the recommended circuit (Figure 2)
for MS-DOS compatible FPU exception handling for
Intel486 processors and beyond contains two flip
flops. When the FPU exception handler accesses
I/O port 0F0H it clears the IRQ13 interrupt request
output from Flip Flop #1 and also clocks out the
IGNNE# signal (active) from Flip Flop #2. The
assertion of IGNNE# may be used by the handler if
needed to execute any FPU instruction while
ignoring the pending FPU errors. The problem here
is that the state of Flip Flop #2 is effectively an
additional (but hidden) status bit that can affect
processor behavior, and so ideally should be saved
upon entering SMM, and restored before resuming
to normal operation. If this is not done, and also the
SMM code saves the FPU state, AND an FPU error
handler is being used which relies on IGNNE#
assertion, then (very rarely) the FPU handler will
nest inside itself and malfunction. The following
example shows how this can happen.
The problem will only occur if the processor enters
SMM between the OUT and the FLDCW
instructions. But if that happens, AND the SMM
code saves the FPU state using FNSAVE, then the
IGNNE# Flip Flop will be cleared (because
FNSAVE clears the FPU errors and thus de-asserts
FERR#). When the processor returns from SMM it
will restore the FPU state with FRSTOR, which will
re-assert FERR#, but the IGNNE# Flip Flop will not
get set. Then when the FPU error handler executes
the FLDCW instruction, the active error condition
will cause the processor to re-enter the FPU error
handler from the beginning. This may cause the
handler to malfunction.
Note that NMI (or any interrupt through INTR that is
enabled inside the FPU exception handler) will
cause this same problem, if the interrupt routine
saves and restores the FPU state, and it happens
to occur between the OUT and the FLDCW
instructions. SMI is the main focus here because it
is much more likely to invoke FNSAVE/FRSTOR
than other interrupts because of 0V suspend (see
below). The problem can easily be eliminated from
all interrupts besides SMI and NMI by not enabling
INTR inside the FPU exception handler.
To avoid this problem, Intel recommends two
measures:
1. Do not use the FPU for calculations inside
SMM code (or code for NMI, or any other
interrupts enabled inside the FPU exception
handler). (The normal power management,
and sometimes security, functions provided by
SMM have no need for FPU calculations; if
they are needed for some special case, use
scaling or emulation instead.) This eliminates
the need to do FNSAVE/FRSTOR inside SMM
code, except when going into an 0V suspend
state (in which, in order to save power, the
processor is turned off completely, requiring its
complete state to be saved).
2. The system should not call upon SMM code to
put the processor into 0V suspend while the
processor is running FPU calculations, or just
after an interrupt has occurred. Normal power
management protocol avoids this by going into
power down states only after timed intervals in
which no system activity occurs.
3.6 Considerations When FPU
Shared Between Tasks
The Intel Architecture allows speculative deferral of
floating-point state swaps on task switches. This
feature allows postponing an FPU state swap until
an FPU instruction is actually encountered in
another task. Since kernel tasks rarely use floating-
point, and some applications do not use floating-
point or use it infrequently, the amount of time
saved by avoiding unnecessary stores of the
floating-point state is significant. Speculative
deferral of FPU saves does, however, place an
extra burden on the kernel in three key ways:
1. The kernel must keep track of which thread
owns the FPU, which may be different from
the currently executing thread.
2. The kernel must associate any floating-point
exceptions with the generating task. This
requires special handling since floating-point
exceptions are delivered asynchronous with
other system activity.
3. There are conditions under which spurious
floating-point exception interrupts are
generated, which the kernel must recognize
and discard.