diff options
author | peter <peter@FreeBSD.org> | 1998-09-28 13:47:23 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1998-09-28 13:47:23 +0000 |
commit | c7cd80895a2d293b7020acd4df0323dd40b6f12a (patch) | |
tree | 24213d9fbbd41cd7fb02d783db436341f02096c2 /sys | |
parent | 49a373f7fc0c7c403ab627b68917f379b4d1f521 (diff) | |
download | FreeBSD-src-c7cd80895a2d293b7020acd4df0323dd40b6f12a.zip FreeBSD-src-c7cd80895a2d293b7020acd4df0323dd40b6f12a.tar.gz |
Fix (?) EISA interrupt configuration based on observation of what we've
seen in practice. The MPspec is ambiguous and/or contradicts itself.
We now look at the ELCR to determine the trigger mode (edge/level) of an
interrupt tagged as "conforming" in the mptable. EISA interrupts appear
to be presented to the APIC as active high in all cases (they are level
inverted) that we've seen, so use this for the 'conforming' level case.
Of note, the system I'm using has 2 PCI cards in it, and the PCI cards
interrupts (5 and 9) appear in the ELCR register as level sensitive and the
mptable lists 5 and 9 as coming from the EISA bus. The PCI interrupts
are active-high by the time they reach the APIC even though they are
electrically active low at the slot.
We should still work should somebody implement this on motherboards
differently in the future as long as the mptable is clear about the
trigger/polarity.
Current should work on Holm Tiffe's machine now.
Based on code from: Tor.Egge@fast.no
Diffstat (limited to 'sys')
-rw-r--r-- | sys/i386/i386/mpapic.c | 35 |
1 files changed, 9 insertions, 26 deletions
diff --git a/sys/i386/i386/mpapic.c b/sys/i386/i386/mpapic.c index 48663a4..8ae6854 100644 --- a/sys/i386/i386/mpapic.c +++ b/sys/i386/i386/mpapic.c @@ -22,7 +22,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mpapic.c,v 1.31 1998/05/17 17:32:10 tegge Exp $ + * $Id: mpapic.c,v 1.32 1998/09/06 22:41:40 tegge Exp $ */ #include "opt_smp.h" @@ -303,12 +303,14 @@ trigger(int apic, int pin, u_int32_t * flags) printf("EISA INTCONTROL = %08x\n", intcontrol); } + /* Use ELCR settings to determine level or edge mode */ + level = (intcontrol >> eirq) & 1; + /* - * EISA IRQ's are identical to ISA irq's, regardless of - * whether they are edge or level since they go through - * the level/polarity converter gadget. + * Note that on older Neptune chipset based systems, any + * pci interrupts often show up here and in the ELCR as well + * as level sensitive interrupts attributed to the EISA bus. */ - level = 0; if (level) *flags |= IOART_TRGRLVL; @@ -338,8 +340,6 @@ static void polarity(int apic, int pin, u_int32_t * flags, int level) { int id; - int eirq; - int pol; switch (apic_polarity(apic, pin)) { @@ -368,25 +368,8 @@ polarity(int apic, int pin, u_int32_t * flags, int level) return; case EISA: - eirq = apic_src_bus_irq(apic, pin); - if (eirq < 0 || eirq > 15) { - printf("EISA POL: IRQ %d??\n", eirq); - goto bad; - } - /* XXX EISA IRQ's are identical to ISA irq's, regardless of - * whether they are edge or level since they go through the - * level/polarity converter gadget. */ - - if (level == 1) /* XXX Always false */ - pol = 0; /* if level, active low */ - else - pol = 1; /* if edge, high edge */ - - if (pol == 0) - *flags |= IOART_INTALO; - else - *flags &= ~IOART_INTALO; - + /* polarity converter always gives active high */ + *flags &= ~IOART_INTALO; return; case PCI: |