1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-21 15:45:02 +00:00

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
This commit is contained in:
Peter Wemm 1998-09-28 13:47:23 +00:00
parent eb70c7babf
commit b9b5f72bb6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=39715

View File

@ -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: