STI, HLT in acpi_cpu_idle_c1

Matthew Dillon dillon at
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

    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

    For all intents and purposes you should treat 'STI; HLT' as a single

    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.


More information about the freebsd-current mailing list