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:
parent
eb70c7babf
commit
b9b5f72bb6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=39715
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user