STI, HLT in acpi_cpu_idle_c1
Matthew Dillon
dillon at apollo.backplane.com
Thu Jun 17 20:28:46 GMT 2004
:>
:> The whole point is for interrupts to be disabled when the
:> HLT instruction
:> *begins* execution (they're only disabled for one cycle).
:>
:
:Ummm, doesn't STI *enable* interrupts?
:
:so you're saying the point is that on entry to
:acpi_cpu_idle_c1, that the caller has done a CLI?
:And that the STI then enables interrupts during the HLT
:instruction?
Ok, I'll try to explain it better.
CLI - disable interrupts
STI - enable interrupts
HLT - halt the cpu until an interrupt occurs. If interrupts are disabled,
this will halt the cpu until an NMI occurs.
Now, there's a problem... the problem is that if you enable interrupts
and halt (to wait for the next interrupt), then there is a one-instruction
window where an interrupt might occur *BEFORE* you HLT. This interrupt
may do something (such as schedule a thread) that means that you really
don't want to halt now waiting for a *SECOND* interrupt to occur.
In order to deal with this problem, Intel specified that the 'STI ; HLT'
sequence of instructions will *GUARENTEE* that interrupts will remain
disabled for one additional cycle, which gives HLT a chance to enter into
its wait state. An interrupt occuring in between the STI and HLT would
therefore cause the HLT to resume.
In later cpu's Intel and Amd both guarentee the atomicy of the
STI; HLT instruction combination. No interrupt will be allowed to
take effect inbetween the instructions, no trap will occur. No NMI
will occur... nothing (either that or, for an NMI, the cpu will fixup
the interrupt flag and set the restart point to the STI rather then the
HLT).
For all intents and purposes you should treat 'STI; HLT' as a single
instruction.
If you stick a NOP in there you will screw everything up... it will make
it possible for an interrupt to occur inbetween the STI and HLT, *BEFORE*
the HLT enters its wait state. When the interrupt finishes HLT will
enter its wait state and not resume again until a *SECOND* interrupt
occurs, which is not what you want because you might be in a situation
(such as during booting) where no other interrupt will occur or where
most other interrupt sources might be disabled or non-functional
(e.g. ACPI sleep).
So, if the emulator is not coming out of the HLT it's a bug in the
emulator. The STI; HLT sequence is correct.
-Matt
More information about the freebsd-current
mailing list