Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 29 Nov 1997 05:10:56 +1100
From:      Bruce Evans <bde@zeta.org.au>
To:        bde@zeta.org.au, mouth@ibm.net
Cc:        hackers@FreeBSD.ORG
Subject:   Re: 650 UART, SIO driver, 8259 PIC
Message-ID:  <199711281810.FAA09194@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>>next bus clock cycle).  The handler must not return with the edge latch
>>set, at least for 16x50 devices, since if the edge latch is set then
>>there must be a device irq and returning would give up the only chance
>>of handling the irq.
>
>I don't see the potential for that problem with FIFOed UARTs where
>several have their INT output ORed on a multiport interrupt sharing
>card.  Perhaps with non-FIFOed UARTS.

I see a large potential.  Consider one UART on sio1.  It will take
at least 2 usec for the interrupt handler to be entered and clear the
interrupt (it will usually take longer; the worst case for a 16550 is
about 70 usec).  For input at 115200 bps, it will interrupt about 822
times per second, so the UART will drive the IRQ high for at least 0.1644%
of the time.  Consider another UART on sio0 and suppose it is handling
satuated input at 115200 bps and that the interrupts are asynchronous
with the interrupts from the first device.  It will interrupt at about
822 times per second and there will be a problem 0.1644% of the time.  The
chance of a problem after 1 second (if we start scanning for interrupts on
sio0 and don't go back to sio0 after finding an interrupt on sio1) is 1 -
(1 - 1644/10**6)**822 = 74 in 100.  For non-FIFO UARTS there will be 14
times more interrupts per second and a chance of a problem of almost 100
in 100.  In practice the interrupts will not be completely asynchronous.
For two channels of saturated input, the interrupt frequencies will be
determined mostly by the clock frequencies on the transmitters, and
problems will occur when the two clocks are almost in phase.

>One of my objectives is implementing input burst mode for 550 (or
>better) UARTs.  A second driver called sio550.c could shed the legacy
>8250/16450 baggage. That's not only reasonable, it's even wise given
>the prevalence of 550s and higher in the market today.

They're not different enough to justify a completely different driver.

>And as far as the edge latch goes, the handler apparently *can* safely
>return with the edge latch set if there was a down/up transition on
>the IRQ line before EOI.  Although that seems unlikely because of the

I think the EOI timing doesn't make any difference when CPU interrupts
are kept disabled throughout interrupt handling, as they are for "fast"
interrupt handlers like siointr().  Fast interrupt handlers delay
explicitly sending and EOI until after the interrupt is handled.  This
is for bogus historical reasons.  Auto EOI is normally used for the
first ICU, so sending an EOI early gets tested too.  "Slow" interrupt
handlers must send the EOI early for FreeBSD's interrupt mechanism to
work at all.

>relatively large time needed to refill any UART to its FIFO trigger
>level after draining it once, perhaps theoretically it could happen on
>a multiport card where you've acked your interrupt, drained all the
>UARTs (only once, not looping for a second pass), and then receive a
>new interrupt from one of the UARTs you've already drained.  I gather
>that is the case you are concerned about.

Not really.  As you pointed out, it isn't a problem for input except in
the overloaded case.  It is a problem if input is mixed with output or
there is another active UART.  Mixed i/o is similar to i/i on mixed
devices - there's just a divisor of 16 instead of 14 in the calculations.

>But in the non-pathological case of a machine which is able to do
>other useful work, by clearing the INT output of the last UART before
>any of the previously drained UARTs can raise their INT output again,
>you will have at least one down/up transition on the IRQ line.  If you

That would be a pessimization.  It requires _two_ extra outputs per
port (one to mess up the INT enable and one to restore it).  The
best case for the current loop is one extra input per port, and this
can be arranged to be the usual case with some small changes).
Changing the INT enable also amplifies bugs in 8250s :-).

>agree with following writer's conclusion, the handler *can* safely
>issue EOI and return after making only one pass to drain the UARTs.
>
>Attributed to Chris Hall (chris@locomotive.com)

I don't think he concluded much about EOI.

>...
>3.  The Mechanisms
>
>The PC sets the 8259A into:
     ^^ BIOS
>
>  * Edge Triggered Interrupts
>  * Cascaded (on AT and later) ; Single (on earlier machines)
>  * Not Special Fully Nested (to do with Slave 8259A, see below)
>  * Not Buffered Normal EOI (Not Automatic EOI on INTA)

FreeBSD sets Auto EOI for the first ICU by default, and Auto EOI
for the second ICU is good for serial devices if it works.

>3.1  One 8259A, All IRQ Unmasked, No Interrupts In Service
>     and None Active.
>...
>   7  Setting B3 of the ISR clears B3 of the ESR.
>   8  The CPU issues the second of two INTA cycles.  The
>      8259A issues the interrupt vector associated with the
>      highest priority ISR (B3).  The contents of the IRR
>      are unfrozen.

According to the diagram in the Intel data sheet, and my experiments,
the IRR follows a signal from the edge latch until the edge latch is
cleared - it reads as 0.

>   9  The INT latch is cleared -- so the INT output is set
>      inactive.

According to the diagram in the Intel data sheet, and my experiments,
the edge latch isn't cleared until the external interrupt goes away.

>  10  B3 of the IRR is set to 0 (IRR is unfrozen and B3 of
>      ESR is zero).
>  11  At some time in the future, the CPU issues an EOI
>      command, which clears B3 of the ISR.

EOI mainly affects the priority logic.

>...
>3.2  Meaning of "Edge Triggered Interrupt Mode"
>
>The behavior of the ESR, IRR and ISR described above is what
>happens in the famous Edge Triggered Interrupt Mode.
                ^^infamous :-)

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199711281810.FAA09194>