Merge from mpacpi.h 1.4.32.1, acpi_machdep.c 1.13.22.5 and

mpacpi.c 1.48.12.2 from jmcneill-pm:

Don't process the MADT and modify the interrupt config at one moment and
later trying to figure out if an entry was overriden and matches the
ACPI SCI. This is brain-dead and breaks in various situations.

Just check for each ISA override entry, if it matches the SCI. If it
does, remember it and use it for the interrupt setup. If there's no such
override assume that it is not changed, but override the polarity and
level from ISA settings to PCI settings.
This commit is contained in:
joerg 2007-10-06 04:39:10 +00:00
parent a544202cb5
commit f4fa1c68c7
3 changed files with 52 additions and 67 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: mpacpi.h,v 1.4 2006/07/04 00:30:22 christos Exp $ */
/* $NetBSD: mpacpi.h,v 1.5 2007/10/06 04:39:10 joerg Exp $ */
#ifndef _X86_MPACPI_H_
#define _X86_MPACPI_H_
@ -14,4 +14,6 @@ int mpacpi_scan_pci(struct device *, struct pcibus_attach_args *, cfprint_t);
struct mp_intr_map;
int mpacpi_findintr_linkdev(struct mp_intr_map *);
extern struct mp_intr_map *mpacpi_sci_override;
#endif /* _X86_MPACPI_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: acpi_machdep.c,v 1.15 2007/09/30 19:08:17 joerg Exp $ */
/* $NetBSD: acpi_machdep.c,v 1.16 2007/10/06 04:39:10 joerg Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.15 2007/09/30 19:08:17 joerg Exp $");
__KERNEL_RCSID(0, "$NetBSD: acpi_machdep.c,v 1.16 2007/10/06 04:39:10 joerg Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -117,15 +117,6 @@ acpi_md_OsInstallInterruptHandler(UINT32 InterruptNumber,
struct pic *pic;
int irq, pin, trigger;
struct acpi_intr_defer *aip;
#if NIOAPIC > 0
#if NACPI > 0
int i, h;
#endif
struct ioapic_softc *sc;
#endif
#if NACPI > 0 || NIOAPIC > 0
struct mp_intr_map *mip = NULL;
#endif
if (acpi_intrcold) {
aip = malloc(sizeof(struct acpi_intr_defer), M_TEMP, M_WAITOK);
@ -147,50 +138,47 @@ acpi_md_OsInstallInterruptHandler(UINT32 InterruptNumber,
* Can only match on ACPI global interrupt numbers if the ACPI
* interrupt info was extracted, which is in the ACPI case.
*/
if (mp_busses == NULL)
goto nomap;
for (i = 0; i < mp_nbus; i++) {
for (mip = mp_busses[i].mb_intrs; mip != NULL;
mip = mip->next) {
if (mip->bus_pin == (int)InterruptNumber) {
h = mip->ioapic_ih;
if (APIC_IRQ_ISLEGACY(h)) {
irq = APIC_IRQ_LEGACY_IRQ(h);
pin = irq;
pic = &i8259_pic;
trigger = IST_EDGE;
} else {
sc = ioapic_find(APIC_IRQ_APIC(h));
if (sc == NULL)
goto nomap;
pic = (struct pic *)sc;
pin = APIC_IRQ_PIN(h);
irq = -1;
trigger =
((mip->flags >> 2) & 3) ==
MPS_INTTR_EDGE ?
IST_EDGE : IST_LEVEL;
}
goto found;
}
}
if (mpacpi_sci_override != NULL) {
pic = mpacpi_sci_override->ioapic;
pin = mpacpi_sci_override->ioapic_pin;
if (mpacpi_sci_override->redir & IOAPIC_REDLO_LEVEL)
trigger = IST_LEVEL;
else
trigger = IST_EDGE;
if (pic->pic_type == PIC_IOAPIC)
irq = -1;
else
irq = (int)InterruptNumber;
goto sci_override;
}
nomap:
#endif
/*
* There was no ACPI interrupt source override,
*
* If the interrupt is handled via IOAPIC, mark it
* as level-triggered, active low in the table.
*/
#if NIOAPIC > 0
pin = (int)InterruptNumber;
for (sc = ioapics ; sc != NULL && pin > sc->sc_apic_sz;
sc = sc->sc_next)
pin -= sc->sc_apic_sz;
if (sc != NULL) {
if (nioapics > 1)
printf("acpi: WARNING: no matching "
"I/O apic for SCI, assuming %s\n",
sc->sc_pic.pic_dev.dv_xname);
pic = (struct pic *)sc;
pic = (struct pic *)ioapic_find_bybase(InterruptNumber);
if (pic != NULL) {
struct ioapic_softc *sc = (struct ioapic_softc *)pic;
struct mp_intr_map *mip;
if (pic->pic_type == PIC_IOAPIC) {
pin = (int)InterruptNumber - pic->pic_vecbase;
irq = -1;
} else {
irq = pin = (int)InterruptNumber;
}
mip = sc->sc_pins[pin].ip_map;
irq = -1;
if (mip) {
mip->flags &= ~3;
mip->flags |= MPS_INTPO_ACTLO;
mip->redir |= IOAPIC_REDLO_ACTLO;
}
} else
#endif
{
@ -199,23 +187,13 @@ nomap:
}
#if NACPI > 0 && NIOAPIC > 0
found:
#endif
#if NACPI > 0 || NIOAPIC > 0
/*
* If there was no ACPI interrupt source override,
* mark the SCI interrupt as level-triggered, active low
* in the table.
*/
if (mip != NULL && ((mip->sflags & MPI_OVR) == 0)) {
trigger = IST_LEVEL;
mip->flags &= ~3;
mip->flags |= MPS_INTPO_ACTLO;
mip->redir |= IOAPIC_REDLO_ACTLO;
}
#endif
trigger = IST_LEVEL;
#if NIOAPIC > 0
sci_override:
#endif
/*
* XXX probably, IPL_BIO is enough.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: mpacpi.c,v 1.49 2007/08/10 14:34:56 joerg Exp $ */
/* $NetBSD: mpacpi.c,v 1.50 2007/10/06 04:39:10 joerg Exp $ */
/*
* Copyright (c) 2003 Wasabi Systems, Inc.
@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mpacpi.c,v 1.49 2007/08/10 14:34:56 joerg Exp $");
__KERNEL_RCSID(0, "$NetBSD: mpacpi.c,v 1.50 2007/10/06 04:39:10 joerg Exp $");
#include "acpi.h"
#include "opt_acpi.h"
@ -135,6 +135,8 @@ static int mpacpi_maxpci;
static int mpacpi_npciroots;
#endif
struct mp_intr_map *mpacpi_sci_override;
static int mpacpi_intr_index;
static paddr_t mpacpi_lapic_base = LAPIC_BASE;
@ -289,6 +291,9 @@ mpacpi_nonpci_intr(APIC_HEADER *hdrp, void *aux)
if (pic->pic_type == PIC_IOAPIC)
((struct ioapic_softc *)pic)->sc_pins[pin].ip_map = mpi;
#endif
if (isa_ovr->Source == AcpiGbl_FADT->SciInt)
mpacpi_sci_override = mpi;
default:
break;
}