[net.micro.pc] Edge Triggered Messages

BRACKENRIDGE%USC-ISIB@sri-unix.UUCP (01/10/84)

From:  Billy <BRACKENRIDGE@USC-ISIB>

Here is an edited version of the edge triggered interrupt debate. These
messages will be of interest to anyone writing code for the IBM async
port. It also should shed some light on some of the design decisions
taken in the two MIT comm packages supported in the INFO-IBMPC library:

Date: 30 Nov 1983 1619-PST
Subject: Bugs in the COM: Package
From: Craig Milo Rogers  <ROGERS@USC-ISIB>
To: Romkey@MIT-CSR

	Hi.  I've been using a version of your interrupt-driven COM:
package for the IBM PC.  I think that I've discovered a timing bug in
it, as follows:

1)	The IBM PC uses the 8259 interrupt controller in edge-triggered
	mode.

2)	The COM interrupt routine checks for interrupts from the 8250
	before clearing the interrupt flag in the 8259 with a specific
	end-of-interrupt.

3)	Between the time that the interrupt code checks for interrupt
	sources, and the time that it clears the interrupt flag, a new
	interrupt source could appear on the 8250.  The resulting edge
	to the 8259 would be lost when the EOI is issued.


	My conclusion is that the end-of-interrupt should be issued to
the 8259 BEFORE the 8250 is checked for interrupt sources.  How does this
sound to you?

					Craig Milo Rogers
-------

------------------------------
Date:  16 December 1983 23:53 est
From:  Saltzer at MIT-MULTICS
Subject:  edge-triggered interrupts
To:  Rogers at USC-ISIB
cc:  Saltzer at MIT-MULTICS, romkey at MIT-CSR

Craig,

Now that classes are over, I finally had a chance to look into the
8250-8259 interrupt interaction question that you raised.  The
documentation on the 8259 is a little vague on this point, but
I believe that it is actually quite clever in edge-triggered
mode.  If an edge comes along, it latches the fact, and ignores
more edges till the signal goes back down again AND the interrupt
gets forwarded to the 8088.  Then it begins watching for more
edges.  For the case of an 8250, the 8250 brings up its interrupt
line, the 8259 latches and, unless there is other activity,
notifies the 8088.  The 8088 accepts the interrupt and begins
running the COM interrupt handler, which knocks down the interrupt
line when it reads the IIR of the 8250.  That dropping of the
interrupt line in turn causes the 8259 to start watching for
another edge.

The EOI has as its only function allowing the 8259 to coordinate
interrupts among various levels.    Until the EOI is issued,
not recognized by the 8259.  After the EOI, they will be.
The EOI has nothing to do with whether or not edges are
noticed and latched for later handling.

Thus the EOI should be set as the last thing on the way out.
If you set it early in the routine, the manipulation of the
registers in the 8250 will cycle the interrupt line and
generate a COM interrupt on top of the COM interrupt.  The
result is a series of nested COM interrupts until you get
deep enough that the IIR seems empty and no further COM interrupts
get generated.

That is how I read the manual, though I am the first to admit
that any interpretation of the manual seems to require a leap
or two of the imagination to fill in some of the gaps.  In
any case, this model of how it works is consistent with all
the external observations we have been able to make of the
two chips and with the bugs we have tripped over when we tried
different models (such as yours.)

		Jerry Saltzer

------------------------------
Date: 19 Dec 1983 1147-PST
Subject: Re: edge-triggered interrupts
From: Craig Milo Rogers  <ROGERS@USC-ISIB>
To: Saltzer@MIT-MULTICS
cc: romkey@MIT-CSR, Gillmann@USC-ISIB

	Thank you for your analysis of the problem.  That must explain
the "LATCH ARMED" indications on the "IR Trigerring Timing Requirements"
diagram in the 8259A specs from Intel.  Your empirical experiences
certainly outweigh my theoretical speculations.

	However, I would like to speculate some more based on the new data.
Assume that the receiver were to request an interrupt.  The 8250 would
request an interrupt.  IRR would be set active in the 8259A.  Eventually,
the 8088 interrupts.  IRR is set inactive, ISR is set active.  The
interrupt routine checks the receive condition, and clears it.  The 8250
drops its interrupt request line.  The 8259A latch is reenabled.  Suppose
that the transmit section were now to request an interrupt.  The 8250 would
raise its interrupt line.  The 8259A would latch it, and set IRR again.
The 8088 is still in the interrupt service routine, which now repolls the
8250 for transmit interrupts.  Seeing one, it clears it.  The 8250 drops its
interrupt line.  The interrupt service routine issues the EOI, clearing the
ISR bit.  The 8088 returns from the interrupt routine, reenabling its
interrupts.  The 8259A has been waiting for the 8088 to process the
interrupt cycle caused by the IRR bit activated by the transmit request.
However, since the 8250's interrupt line was dropped before the 8088
acknowleged the interrupt to the 8259A, the 8259A should perform a "Default
IR7" interrupt cycle, instead of a normal interrupt.  If the line printer
(IR7) is enabled at the same time, this will cause a false line printer
interrupt.  Any objections to this scenario?

	In any case, I fail to see how nested COM interrupts could result.
8088 interrupts are disabled throughout execution of the interrupt routine
(no STI or POPF).  At least, this is true of the version the Dick Gillmann
gave me to start with.

					Craig Milo Rogers
-------

------------------------------
Date:  20 December 1983 20:57 est
From:  Saltzer at MIT-MULTICS
Subject:  Re: edge-triggered interrupts
To:  Craig Milo Rogers <ROGERS at USC-ISIB>
cc:  Saltzer at MIT-MULTICS, romkey at MIT-CSR, 
     Gillmann at USC-ISIB

Craig,

Your scenario is one I hadn't thought about before, but it sounds
correct.  It also explains one mystery.  Our serial line interrupt
handler has a counter to pick up interrupts for which no condition code
is set; that counter has never registered anything but zero.  Yet the
repoll sequence ought to cause some conditions to be serviced in advance
of the interrupt that they cause, so that counter ought to occasionally
record something.  (We are certain that such early conditions actually
occur because the handler loses characters if you don't repoll.)  Your
scenario calls for such early-serviced conditions to lead to level-7
interrupts rather than serial line interrupts, so this handler never
sees them.  I suppose that whatever level-7 handler is available is
smart enough to ignore interrupts that don't have serviceable conditions
to back them up so it doesn't matter.  And I don't suppose it counts
these cases so I can't verify that the com line is giving it extra
things to ignore.

I forgot that the CPU remains masked through the handler--the nested
interrupt thing can't happen.

It would help a bit if INTEL would publish the wiring diagram of the
8259 (and the 8250).  The English language description sure leaves a lot
to the imagination.

		Jerry

------------------------------
Date: 20 Dec 1983 18:42:39 PST
Subject: Re: edge-triggered interrupts
From: Craig Milo Rogers  <ROGERS@USC-ISIB>
To: Saltzer@MIT-MULTICS
cc: romkey@MIT-CSR, Gillmann@USC-ISIB

	Interesting.  I expect that your repoll sequence is necessary
to prevent lost characters because the 8250 is presenting an interrupt
*level* condition, rather than an interrupt *edge* condition.  Thus,
if more than one interrupt source is present withing the chip (say,
receive and transmit), the interrupt request will remain active until
all sources have been serviced.  If the interrupt service routine were
to service only one source before returning, the 8250 would not generate
another edge for the 8259A.  At least, this is how I read the 8250
documentation in the IBM Technical Reference manual.

	Thus, if you don't repoll to verify that all possible interrupt
sources on the 8250 are clear before returning from the current interrupt,
I would expect you to eventually reach a state where no more characters
get through.  This is somewhat different from your description of "losing
characters" when repolling isn't present.  I am concerned about the
discrepancy.  Does your application code perhaps time out and reset the
8250?

	So, even if you were to instrument the IRQ7 (line printer) service
routine, I would expect to find few fake interrupts due to the 8250
ports.  Considering the various windows involved, missing interrupt
request edges should be far more common than delayed interrupt
request edges, up to the point where the interrupt service routine itself
is consuming 50% or so of the 8088 CPU.

	By the way, I believe that there is a wiring error in the IBM
Line Printer interface circuit, so that all line printer interrupts
are treated by the 8259A as fake IRQ7 interrupts rather than real ones.
If you have time, you might review my analysis at the start of the line
printer interrupt handler in [ISIB]<INFO-IBMPC.INT>LPT_PKG.ASM.  I am
interested in any comments you have.

					Craig Milo Rogers
-------

------------------------------
Date:  20 December 1983 22:45 est
From:  Saltzer at MIT-MULTICS
Subject:  Re: edge-triggered interrupts
To:  Craig Milo Rogers <ROGERS at USC-ISIB>
cc:  Saltzer at MIT-MULTICS, romkey at MIT-CSR, 
     Gillmann at USC-ISIB

Craig,

You are certainly correct in your analysis of why one must repoll for
further conditions after servicing the first one found.  However I am
unconvinced by the argument that suggests that early handling of
conditions will be rare.  If the line is operating full-duplex, a
transmit holding register empty condition can occur at any time.  If it
occurs before the receive condition is read (but after the receive
condition is registered) the interrupt line out of the 8250 will stay
high, causing the "lost interrupt" effect.  And that small window
definitely does get hit, at least at 9600 baud and 19.2K, in our
experience.  If the THRE condition occurs after the receive condtion is
read, then there should be a fake interrupt at level 7.  If this window
is at least as large as the previous one (and it is in this code) then
unneeded interrupts should be at least as frequent as lost interrupts
without repolling.

This whole area I haven't looked carefully at for at least 18 months, so
my recall sometimes is a little fuzzy.

		Jerry

------------------------------
Subject: Re: edge-triggered interrupts
From: Craig Milo Rogers  <ROGERS@USC-ISIB>
To: Saltzer@MIT-MULTICS
cc: romkey@MIT-CSR, Gillmann@USC-ISIB

	By the way, the repoll code in the COM routines doesn't check for
line/modem status transition interrupts.  It seems to me that this is an
error.  A line/modem status transition could take place while a transmit or
receive interrupt is being processed;  the interrupt request line will not
drop;  the interrupt routine will dismiss;  no more COM interrupts.

					Craig Milo Rogers
-------

------------------------------
Date:  22 December 1983 21:31 est
From:  Saltzer at MIT-MULTICS
Subject:  Re: edge-triggered interrupts
To:  Craig Milo Rogers <ROGERS at USC-ISIB>

Craig, Good try, but no cigar.  The COM code (as I left it behind--hope
you didn't change this property) doesn't enable line/modem status
transition conditions, so they don't affect the interrupt request line.
If they were enabled, they would have to be polled, agreed.    There is
a place in the code to go to in case the conditions appear in the IIR,
but that path was provided as a safety net, not because I expected it
ever to be followed.

I ran into a subtle interaction in the polling for transmit interrupts,
which led me look for every possible excuse to avoid enabling for lower
priority interrupts.  The reading of the IIR (which you have to do to
find out whether or not the lower priority interrupts are there) resets
the THRE condition.  So I couldn't figure out any way to repoll without
taking a chance on losing a THRE condition.  Repolling again for an
empty transmitter register would work, but then one would have to repoll
yet again for a modem/line interrupt, etc., forever.  So I just ducked
the issue and left it for someone to sort out who really needed those
conditions monitored.
		Jerry
-------