Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

intel x86 instruction "cli"

281 views
Skip to first unread message

tcs

unread,
Mar 18, 2004, 9:39:58 AM3/18/04
to
Hi:
I read instruction manual that "cli" instruction disables maskable
interrupt. After reading more information about interrupt, I am a little
confused about the "cli" instruction.

When a piece of hardware generates interrupt, it asserts a wire which
connects to interrupt controllers, if this interrupt controllers is not told
to filter all interrupts then a wire from interrupt controller to CPU is
asserted.

OK, here is my question. When x86 executes "cli" instruction, does CPU
itself ignore the interrupt or the interrupt controller screen the interrupt
from arriving CPU?

thanks in advance

tcs


Ed Skinner

unread,
Mar 18, 2004, 11:33:35 AM3/18/04
to


Most computer systems (as opposed to just the processor chip itself)
have at least one Programmable Interrupt Controller, or PIC, device in
addition to the processor. Individual I/O device interrupt request wires
are connected to different inputs to the PIC (but sometimes multiple
devices will "share" the same wire to the PIC). System software can enable
and disable (unmask or mask) each of the multiple inputs to the PIC. The
PIC, however, has a single output that is the "OR" of all its inputs. That
is, if *any* I/O device is requesting an interrupt (and it is not masked
in the PIC), the PIC's output will be asserted. That single output wire
from the PIC goes to the processor's "interrupt request" input (pin).
Inside the processor, the "cli" and "sti" instructions mask (block)
and unmask (unblock) that single interrupt signal. When the processor's
interrupt mask is unmasked ("enabled" might be a better word to use in this
case) by the "sti" instruction, the processor suffers an interrupt. In the
software that is then executed, the first thing the software must do is
interrogate the PIC to find out where the interrupt is coming from.
Thangs get a little varied from here on and depend on the features of
the particular operating system. The more sophisticated ones will
determine which of the PIC inputs is active and, in the PIC, mask out that
input. If that was the only interrupt wire being pulled into the PIC, the
output from the PIC will then relax (become un-asserted) as there are no
more (unmasked) inputs to the PIC. At this point, the processor's
interrupt mask can be re-enabled (via "sti") while the software continues
on to talk with the device that caused the original interrupt and take
care of its needs. This re-enabling allows the operating system to handle
additional interrupts that occur in the midst of handling an earlier
interrupt. We could say that the interrupts are allowed to "nest" one
inside the other. In some cases this may require that portions of the
operating system be "reentrant".
In simpler (less sophisticated) operating systems, however, the
processor interrupt mask will be left in a masked (disabled) state for the
entire handling of the interrupt. That is, the PIC's mask for the
individual interrupt wire that is being yanked will be left in an enabled
state and so it is necessary to tell the device to stop asserting its
interrupt [to the PIC] so that the processor's interrupt request [from the
PIC] will go inactive, so that the processor's interrupt mask can be
reenabled [via "sti"] for future interrupts.
Finally, it may be useful to note that the "sti" instruction, or its
counterpart in non-X86 processors, is generally avoided. Instead, the
operating system software usually tries to look and see what the previous
state of the processor interrupt mask was, and then restore that state.
If you want to look at some real code, look for the "irq.c" source
file in a Linux source distribution. The comments are not always
completely accurate but, between them and the actual source code, it can
be very educational. You could compare old versions of Linux (such as the
very earliest) with the more recent. All are available at
http://www.kernel.org/ or one of its mirrors.
Good Luck!

--
Ed Skinner, e...@REMOVETHIS.flat5.net

Josef Möllers

unread,
Mar 18, 2004, 10:53:25 AM3/18/04
to

The CPU ignores the interrupt. You can still detect a pending interrupt
by polling the interrupt controller.

--
Josef Möllers (Pinguinpfleger bei FSC)
If failure had no penalty success would not be a prize
-- T. Pratchett

tcs

unread,
Mar 18, 2004, 9:48:08 PM3/18/04
to
> OK, here is my question. When x86 executes "cli" instruction, does CPU
> itself ignore the interrupt or the interrupt controller screen the
interrupt
> from arriving CPU?

The CPU ignores the interrupt. You can still detect a pending interrupt
by polling the interrupt controller.

Then, does interrupt priority come into play here? When x86 issues 'cli'
instruction due to interrupt 11, can interrupt 4 interrupt x86 again?

We are asking this because we would like to know if interrupt 4 can
interrupt handler for interrupt 11?

thanks

tcs


tcs

unread,
Mar 18, 2004, 9:45:17 PM3/18/04
to
According to your definitions of 'sophisticated' and 'simple' systems. Does
Linux belong to the simple one or sophisticated one?

thanks

tcs

gopan

unread,
Mar 18, 2004, 11:04:11 PM3/18/04
to
I have a doubt here
>

> Inside the processor, the "cli" and "sti" instructions mask (block)
> and unmask (unblock) that single interrupt signal. When the processor's
> interrupt mask is unmasked ("enabled" might be a better word to use in this
> case) by the "sti" instruction, the processor suffers an interrupt. In the
> software that is then executed, the first thing the software must do is
> interrogate the PIC to find out where the interrupt is coming from.

At least in an x86 with 8259 PIC, what i understand is the
processor when interrupted will issue two INTA signals to the PIC and
when the PIC on receiving the second INTA will output the vector
number corresponding to the interrupt in to the data bus. The
processor accepts it and if in protected mode, multiplies it by 8 and
add the value to the contents of IDTR to find the location of the ISR
to be executed.

So, in this case is there any need for the s/w to interrogate the PIC
to find out the source of interrupt?

gopan

unread,
Mar 19, 2004, 1:38:23 AM3/19/04
to
>
> Then, does interrupt priority come into play here? When x86 issues 'cli'
> instruction due to interrupt 11, can interrupt 4 interrupt x86 again?
>
The cli will cause processor to ignore all interrupts except
the NMI.

The x86 processor when interrupted will clear the interrupt flag
until the ISR executiong completes, this basically means all
interrupts disabled.

In linux the ISR will mask the corresponding interrupt bit in PIC and
will call sti so that processor can identify any new interrupt
generation ( as the interrupt
bit corresponding to the previous interrupt is cleared processor is
not notified
of the same interrupt again until ISR re enables that bit before
returning).

The purpose of this is to service any higher priority interrupts
arrival during the execution of current interrupt's ISR.

I had a similar doubt earlier and was cleared by the answers received
in this news group, hope I have understood correctly

Dmitry M. Shatrov

unread,
Mar 19, 2004, 2:55:21 AM3/19/04
to
tcs wrote:
> OK, here is my question. When x86 executes "cli" instruction, does CPU
> itself ignore the interrupt or the interrupt controller screen the interrupt
> from arriving CPU?

Nothing is ignored. To figure it out I got deep into i8259A's
operation, it's quite simple, for CPU the PIC sets INTR line high, and
it remains high until the CPU acknowledges an interrupt by writing
into PIC's control register (this is down in Linux's interupt handling
routines by Linux), the CPU checks INTR's state after each acomplished
innstruction (eh, not so simple for modern CPU's, I guess, but who
cares?), and goes to handle IRQ request only if the IF flag is set
(the on triggered by sti and zeroed by cli).

So. Between cli and sti the INTR line remains high, our CPU will
recognize the interrupt and process it just after we call sti. Proved
experimentally.

Josef Möllers

unread,
Mar 19, 2004, 3:41:20 AM3/19/04
to

gopan has already answered some of this.

1. cli will mask _all_ maskable interrupts.
2. with the PIC and APIC used in x86 systems, the OS can mask some
interrupt sources within the PIC, masked interrupts will not make it
past the (A)PIC.
3. (A)PICs support some form of priorization or another. IIRC, the 8259
PIC will allow for rotating priorities, i.e. once IRQ 11 has been
recognized, it will rotate into the least priority and, if IRQ 11 and
IRQ 4 will happen before the CPU can act upon either, the PIC will
report IRQ 4 as the one with the highest priority. The APIC allows for
static priorities IIRC.
4. "Interrupts through interrupt gates automatically clear the IF flag,
which disables interrupts."

In general, you should not have to worry about interrupts occurring
during interrupt handlers: the (A)PIC or the device itself will prevent
an interrupt from happening during its own interrupt handler. Also
interrupt handlers must be written such that the will not interfere with
other pieces of code or both must protect from each other. If you are
within a critical section of code (i.e. you must proceed at maximum
speed), you must disable interrupts.

news

unread,
Mar 19, 2004, 3:55:45 AM3/19/04
to
> In linux the ISR will mask the corresponding interrupt bit in PIC and
> will call sti so that processor can identify any new interrupt
> generation ( as the interrupt
> bit corresponding to the previous interrupt is cleared processor is
> not notified
> of the same interrupt again until ISR re enables that bit before
> returning).

I have a question on this. Why is the line masked, given that the
hardware will not generate another int until it is serviced?
Why not just only acknowledge the PIC?

> The purpose of this is to service any higher priority interrupts
> arrival during the execution of current interrupt's ISR.

But if ints are enabled, lower priority interrupts could be
triggered too, right?

Ed Skinner

unread,
Mar 19, 2004, 10:30:39 AM3/19/04
to
Linux is mostly sophisticated but the true answer is that it depends
on hardware capabilities -- there can be hardware requirements that tie
Linux's hands. I don't have a specific board in mind but I do know that,
if you look at the board-level sources for several different architectures
and boards, there is quite a bit of variety "beneath" Linux.
In other words, YMMV (Your Mileage May Vary).

Ed Skinner

unread,
Mar 19, 2004, 10:32:57 AM3/19/04
to
Good example of where the hardware is handling part of the interrupt
vectoring that, on other systems, has to be done in the software.
A pretty good book on this specific area is "Interrupt-Driven PC
System Design" by Joseph McGivern, ISBN 0-929392-50-7 because it shows a
lot of the variety that is possible using that PIC.

Kasper Dupont

unread,
Mar 19, 2004, 9:41:50 AM3/19/04
to
news wrote:
>
> But if ints are enabled, lower priority interrupts could be
> triggered too, right?

That depends on exactly how the PIC works (which I
unfortunately don't know). Of course you could
implement priorities in software by telling the PIC
to modify the mask appropriately.

Higher levels have some control over what is going
on. For example the IDE layer can actually decide if
an interrupt for a given unit may be interrupted.
(hdparm -u)

--
Kasper Dupont -- der bruger for meget tid paa usenet.
For sending spam use mailto:aaa...@daimi.au.dk
/* Would you like fries with that? */

Ed Skinner

unread,
Mar 19, 2004, 10:46:55 AM3/19/04
to

Yes, but...
One of the problems over the years has been the idea that interrupts
from hardware devices should have fixed priorities. For workstation
systems that may be appropriate but out in the real world, in particular
with embedded devices, priorities may sometimes need to change. The reason
for a change varies but the essential idea is that circumstances change
and so the system should change how it reacts accordingly. With hard-wired
priorities, this isn't possible. Some hardware devices have a priority
scheme built in to them. The i8259a is an example. In that device, the
priority is associated with the INT# and, if that feature in the device is
used, the system has to kowtow to the device.
A different solution would be to, for example, for the software to
read the state of all the INT lines into the PIC (which is possible in
some PICs) and, noting which INT#s are active, do a table lookup to
determine how important each of them is to the system at this moment. The
interrupts would then be handled in priority order and, during the life of
the system, interrupt priority could then be changed simply by replacing
the value in the lookup table. Hence, dynamic prioritization of hardware
interrupts.
I don't know what specific systems, if any, use this technique now.
For many, it may not be possible due to hardware limitations. In others,
it may be overkill or simply not needed. But in a few cases, being able to
re-prioritize the importance of, for example, the network versus the local
keyboard interrupts, may be essential.

Kasper Dupont

unread,
Mar 19, 2004, 9:50:06 AM3/19/04
to
Ed Skinner wrote:
>
> the first thing the software must do is
> interrogate the PIC to find out where the interrupt is coming from.

This is actually done mostly in hardware. The
only exception is when multiple device share
the same line to the PIC in which case you
cannot ask the PIC who asserted the line, you
have to ask the devices themselves. On all
x86 systems I have seen the only shared
interrupt was number 11.

> Instead, the
> operating system software usually tries to look and see what the previous
> state of the processor interrupt mask was, and then restore that state.

But you know the previous state. It has got to
be enabled. Otherwise the handler wouldn't have
been called.

Kasper Dupont

unread,
Mar 19, 2004, 9:53:55 AM3/19/04
to
Josef Möllers wrote:
>
> The CPU ignores the interrupt. You can still detect a pending interrupt
> by polling the interrupt controller.

Does this mean you can actually handle the interrupt
without ever enabling interrupts, so when you eventually
enable interrupts again there will be no pending
interrupt to interrupt you?

Kasper Dupont

unread,
Mar 19, 2004, 9:56:00 AM3/19/04
to
Ed Skinner wrote:
>

Something is wrong with your clock. According to
the headers you haven't written that posting yet.
I'm answering 50 minutes before you post it.

Ed Skinner

unread,
Mar 19, 2004, 11:37:55 AM3/19/04
to
On Fri, 19 Mar 2004 15:50:06 +0100, Kasper Dupont wrote:

> Ed Skinner wrote:
>>
>> the first thing the software must do is interrogate the PIC to find out
>> where the interrupt is coming from.
>
> This is actually done mostly in hardware. The only exception is when
> multiple device share the same line to the PIC in which case you cannot
> ask the PIC who asserted the line, you have to ask the devices themselves.
> On all x86 systems I have seen the only shared interrupt was number 11.
>
>> Instead, the
>> operating system software usually tries to look and see what the
>> previous state of the processor interrupt mask was, and then restore
>> that state.
>
> But you know the previous state. It has got to be enabled. Otherwise the
> handler wouldn't have been called.


Doh! (Thanks, and I'm brewing another cup of coffee: it's still early on this
side of the pond [in Arizona].)

Steven Rostedt

unread,
Mar 23, 2004, 8:18:30 AM3/23/04
to
Kasper Dupont wrote:
> Josef Möllers wrote:
>
>>The CPU ignores the interrupt. You can still detect a pending interrupt
>>by polling the interrupt controller.
>
>
> Does this mean you can actually handle the interrupt
> without ever enabling interrupts, so when you eventually
> enable interrupts again there will be no pending
> interrupt to interrupt you?
>

I haven't done this on Intel, but I have for other boards.
With interrupts off, I've checked (polled) for an asserted interrupt,
handled it, deassert it, and when interrupts where turned back
on, no interrupt took place. This was done for some special
reasons, and I'm not sure if something like this would ever
be done in general in linux. But to answer you question (but
not quite for Intel), Yes.

-- Steve

Ed Skinner

unread,
Mar 24, 2004, 12:06:01 PM3/24/04
to

In the VMEbus (hardware) backplane, there is an error condition that may
arise that looks somewhat like this "interrupt that goes away, but the
system suffers an interrupt anyway." Whether you call this a bug or a
feature [to which someone had better pay attention] depends on your
viewpoint.

Here's the scenario.

Let's assume we have a single-board computer (processor, FLASH, RAM, some
set of I/O devices, etc.) plugged into a VMEbus backplane. Also plugged
into that backplane is some special I/O controller. (VMEbus is used in
some very rugged environments with some very special electronics -- think
of submarines, for example.) In the system under consideration, let's say
that the single-board computer views that special I/O controller as one of
its I/O devices and has set things up so that, for example, the I/O
controller can generate an interrupt, via the VMEbus, into the
single-board computer where a device driver is ready to handle the
interrupt. So far, so good.

Now, let's introduce a lot of other "traffic" onto the VMEbus. We might,
for example, have several other single-board computers plugged into the
same VMEbus, or maybe there are additional "special I/O devices" on the
VMEbus. And let's say that the VMEbus is *very* busy with data transfers
with these other devices.

The third condition we need to be aware of is that VMEbus, under heavy
traffic loads, is somewhat position sensitive. Specifically, under heavy
load, boards near bus position #1 tend to get more favorable service. Note
that this only shows up as an appreciable delay when the VMEbus is very
busy. (When a given board has a lot of data to transfer, the transfer
speed is limited by the *slower* of the sender, the receiver, and the
VMEbus architectural limits. Normally these are all very fast but, for
very old boards in very new backplanes, this could become an issue.)

Okay, the scene is now set. Here's how the failure develops.

Let's suppose the "special I/O controller" wants to interrupt the
single-board computer. Before it can do so, however, it has to get its
interrupt request passed through the VMEbus to the single-board computer,
and the single-board computer has to "acquire" the VMEbus to acknowledge
the interrupt request. If, during this phase, the VMEbus remains busy for
a "long time" (typically measured in hundreds of microseconds), the
single-board computer which is attempting to "acquire" the VMEbus to do
the interrupt acknowledgement may "time-out" (fail to acquire the VMEbus
in the allotted interval). This "timer" is inside the chip on the
single-board computer that is responsible for that computer's acquisition
and use of the VMEbus. When the "bus acquisition timeout" happens, the
single-board computer goes ahead and processes an interrupt, but from an
unknown source. It looks like an interrupt from no where and most OSs log
it as a "spurious interrupt." Presumably, and at some later time, the
single-board computer will re-attempt to acquire the VMEbus and
acknowledge the interrupt and correct handling of the interrupt will then
take place.

If you're familiar with VMEbus, this is the same sequence that may result
in a "Bus Error" at what should be a valid VMEbus address. Again, if the
"acquire the VMEbus" cycle takes too long, the single-board computer (via
its on-board VMEbus access chip) will "time-out" the attempt and give a
"Bus Error" back to the processor. (In that case, however, the attempt is
not automatically retried unless the OS specifically knows it should
"rerun the bus cycle.")

I remember one catastrophic failure (involving companies who shall remain
nameless) in which a heavy piece of equipment, with the electronics
attempting to tell the main processor that there was a problem, literally
tore itself out of its bearings and rampaging through the company parking
lot doing lots of damage to employee vehicles and some of the nearby
forest. There were no reports of injuries (miraculously) but I'm sure the
attorneys made a lot of money on the ensuing litigation.

So, yes, in some architectures, the interrupt can (apparently) go away but
the system still "suffer" the interrupt. In the case described, it was
symptomatic of a much more severe system-design problem. Engineers had
been ignoring the "spurious interrupt" and also some "bus error at known
good addresses" indications but were assuming that the hardware was at
fault and that future hardware updates would (hopefully) make the
problem(s) go away. In reality, however, the system design and
software-initiated utilization of the hardware had pushed the overall
system beyond its limits and "loose parts" was the result.

0 new messages