summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1998-09-28 13:47:23 +0000
committerpeter <peter@FreeBSD.org>1998-09-28 13:47:23 +0000
commitc7cd80895a2d293b7020acd4df0323dd40b6f12a (patch)
tree24213d9fbbd41cd7fb02d783db436341f02096c2
parent49a373f7fc0c7c403ab627b68917f379b4d1f521 (diff)
downloadFreeBSD-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
-rw-r--r--sys/i386/i386/mpapic.c35
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:
OpenPOWER on IntegriCloud