Index: sys/arch/x86/acpi/acpi_machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/x86/acpi/acpi_machdep.c,v retrieving revision 1.21 diff -p -u -r1.21 acpi_machdep.c --- sys/arch/x86/acpi/acpi_machdep.c 22 Nov 2018 15:06:00 -0000 1.21 +++ sys/arch/x86/acpi/acpi_machdep.c 25 Dec 2018 16:42:03 -0000 @@ -175,18 +175,22 @@ acpi_md_intr_establish(uint32_t Interrup void *ih; struct pic *pic; #if NIOAPIC > 0 - struct ioapic_softc *sc; + struct ioapic_softc *ioapic; struct acpi_md_override ovr; struct mp_intr_map tmpmap, *mip, **mipp = NULL; + intr_handle_t mpih; #endif int irq, pin, redir, mpflags; +printf("md_intr_establish %u\n", (unsigned) InterruptNumber); + /* * ACPI interrupts default to level-triggered active-low. */ mpflags = (MPS_INTTR_LEVEL << 2) | MPS_INTPO_ACTLO; redir = IOAPIC_REDLO_LEVEL | IOAPIC_REDLO_ACTLO; + irq = InterruptNumber; #if NIOAPIC > 0 @@ -194,7 +198,7 @@ acpi_md_intr_establish(uint32_t Interrup * Apply any MADT override setting. */ - ovr.irq = InterruptNumber; + ovr.irq = irq; ovr.pin = -1; if (acpi_madt_map() == AE_OK) { acpi_madt_walk(acpi_md_findoverride, &ovr); @@ -204,11 +208,11 @@ acpi_md_intr_establish(uint32_t Interrup } if (ovr.pin != -1) { - bool sci = InterruptNumber == AcpiGbl_FADT.SciInterrupt; + bool sci = irq == AcpiGbl_FADT.SciInterrupt; int polarity = ovr.flags & ACPI_MADT_POLARITY_MASK; int trigger = ovr.flags & ACPI_MADT_TRIGGER_MASK; - InterruptNumber = ovr.pin; + irq = ovr.pin; if (polarity == ACPI_MADT_POLARITY_ACTIVE_HIGH || (!sci && polarity == ACPI_MADT_POLARITY_CONFORMS)) { mpflags &= ~MPS_INTPO_ACTLO; @@ -224,49 +228,69 @@ acpi_md_intr_establish(uint32_t Interrup } } + pic = NULL; + pin = irq; + /* - * If the interrupt is handled via IOAPIC, update the map. - * If the map isn't set up yet, install a temporary one. + * Identify ISA & EISA interrupts */ - - sc = ioapic_find_bybase(InterruptNumber); - if (sc != NULL) { - pic = &sc->sc_pic; - - if (pic->pic_type == PIC_IOAPIC) { - pin = (int)InterruptNumber - pic->pic_vecbase; - irq = -1; - } else { - irq = pin = (int)InterruptNumber; + if (mp_busses != NULL) { + if (intr_find_mpmapping(mp_isa_bus, irq, &mpih) == 0 || + intr_find_mpmapping(mp_eisa_bus, irq, &mpih) == 0) { + if (!APIC_IRQ_ISLEGACY(mpih)) { + pin = APIC_IRQ_PIN(mpih); + ioapic = ioapic_find(APIC_IRQ_APIC(mpih)); + if (ioapic != NULL) + pic = &ioapic->sc_pic; + } } + } - mip = sc->sc_pins[pin].ip_map; - if (mip) { - mip->flags &= ~0xf; - mip->flags |= mpflags; - mip->redir &= ~(IOAPIC_REDLO_LEVEL | - IOAPIC_REDLO_ACTLO); - mip->redir |= redir; - } else { - mipp = &sc->sc_pins[pin].ip_map; - *mipp = &tmpmap; - tmpmap.redir = redir; - tmpmap.flags = mpflags; + if (pic == NULL) { + /* + * If the interrupt is handled via IOAPIC, update the map. + * If the map isn't set up yet, install a temporary one. + */ + ioapic = ioapic_find_bybase(irq); + if (ioapic != NULL) { + pic = &ioapic->sc_pic; + + if (pic->pic_type == PIC_IOAPIC) { + pin = irq - pic->pic_vecbase; + irq = -1; + } else { + pin = irq; + } + + mip = ioapic->sc_pins[pin].ip_map; + if (mip) { + mip->flags &= ~0xf; + mip->flags |= mpflags; + mip->redir &= ~(IOAPIC_REDLO_LEVEL | + IOAPIC_REDLO_ACTLO); + mip->redir |= redir; + } else { + mipp = &ioapic->sc_pins[pin].ip_map; + *mipp = &tmpmap; + tmpmap.redir = redir; + tmpmap.flags = mpflags; + } } - } else + } + + if (pic == NULL) #endif { pic = &i8259_pic; - irq = pin = (int)InterruptNumber; + pin = irq; } ih = intr_establish_xname(irq, pic, pin, type, ipl, handler, arg, mpsafe, xname); #if NIOAPIC > 0 - if (mipp) { + if (mipp) *mipp = NULL; - } #endif return ih;