NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/47648: NetBSD 6.1_RC1 ACPI interupt routing problem + other ACPI lossage
On Mon, Mar 18, 2013 at 10:10:02AM -0700, Chuck Silvers wrote:
> actually I thought of a simpler hack than I was thinking of before,
> please try the attached patch.
>
> if that works then there's other hacky code (from before I got involved)
> that can be removed too.
The patch workes and fixes the problem! I get a neat 100 interrupts/sec and my
impression is that it is smoother than before, but thats most likely my
imagination :)
Would you like to commit it to -current en to netbsd-6? Maybe it can be pulled
up before 6.1 comes out?
Thanks a lot,
Reinoud
> Index: src/sys/arch/x86/x86/mpacpi.c
> ===================================================================
> RCS file: /home/chs/netbsd/cvs/src/sys/arch/x86/x86/mpacpi.c,v
> retrieving revision 1.96
> diff -u -p -r1.96 mpacpi.c
> --- src/sys/arch/x86/x86/mpacpi.c 3 Oct 2012 17:04:25 -0000 1.96
> +++ src/sys/arch/x86/x86/mpacpi.c 18 Mar 2013 16:49:06 -0000
> @@ -942,13 +942,6 @@ mpacpi_find_interrupts(void *self)
> printf("mpacpi: %d PCI busses\n", mpacpi_npci);
> #endif
> mpacpi_config_irouting(acpi);
> -#if NIOAPIC > 0
> - /*
> - * XXX fix up the SCI interrupt polarity.
> - * it's installed before we have parsed the MADT.
> - */
> - ioapic_reenable();
> -#endif
> if (mp_verbose)
> for (i = 0; i < mp_nintr; i++)
> mpacpi_print_intr(&mp_intrs[i]);
> Index: src/sys/arch/x86/acpi/acpi_machdep.c
> ===================================================================
> RCS file: /home/chs/netbsd/cvs/src/sys/arch/x86/acpi/acpi_machdep.c,v
> retrieving revision 1.4
> diff -u -p -r1.4 acpi_machdep.c
> --- src/sys/arch/x86/acpi/acpi_machdep.c 23 Sep 2012 00:31:05 -0000
> 1.4
> +++ src/sys/arch/x86/acpi/acpi_machdep.c 18 Mar 2013 17:05:17 -0000
> @@ -93,6 +93,30 @@ acpi_md_OsGetRootPointer(void)
> return PhysicalAddress;
> }
>
> +
> +struct acpi_md_sci {
> + int pin;
> + int flags;
> +};
> +
> +static ACPI_STATUS
> +acpi_md_findsci(ACPI_SUBTABLE_HEADER *hdrp, void *aux)
> +{
> + ACPI_MADT_INTERRUPT_OVERRIDE *iop;
> + struct acpi_md_sci *scip;
> +
> + if (hdrp->Type != ACPI_MADT_TYPE_INTERRUPT_OVERRIDE) {
> + return AE_OK;
> + }
> +
> + iop = (void *)hdrp;
> + if (iop->SourceIrq == AcpiGbl_FADT.SciInterrupt) {
> + scip->pin = iop->GlobalIrq;
> + scip->flags = iop->IntiFlags;
> + }
> + return AE_OK;
> +}
> +
> ACPI_STATUS
> acpi_md_OsInstallInterruptHandler(uint32_t InterruptNumber,
> ACPI_OSD_HANDLER ServiceRoutine, void *Context, void **cookiep)
> @@ -101,37 +125,50 @@ acpi_md_OsInstallInterruptHandler(uint32
> struct pic *pic;
> #if NIOAPIC > 0
> struct ioapic_softc *sc;
> + struct acpi_md_sci sci;
> #endif
> - int irq, pin, trigger;
> + int irq, pin, trigger, redir, mpflags;
> +
> + /*
> + * The SCI defaults to level-triggered active-low.
> + */
> +
> + trigger = IST_LEVEL;
> + mpflags = (MPS_INTTR_LEVEL << 2) | MPS_INTPO_ACTLO;
> + redir = IOAPIC_REDLO_LEVEL | IOAPIC_REDLO_ACTLO;
>
> #if NIOAPIC > 0
> +
> /*
> - * Can only match on ACPI global interrupt numbers if the ACPI
> - * interrupt info was extracted, which is in the ACPI case.
> + * Apply any MADT override setting.
> */
> - 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
> +
> + if (acpi_madt_map() != AE_OK) {
> + return AE_NO_ACPI_TABLES;
> + }
> + sci.pin = -1;
> + acpi_madt_walk(acpi_md_findsci, &sci);
> + acpi_madt_unmap();
> +
> + if (sci.pin != -1) {
> + InterruptNumber = sci.pin;
> + if ((sci.flags & ACPI_MADT_POLARITY_MASK) ==
> + ACPI_MADT_POLARITY_ACTIVE_HIGH) {
> + mpflags &= ~MPS_INTPO_ACTLO;
> + redir &= ~IOAPIC_REDLO_ACTLO;
> + }
> + if ((sci.flags & ACPI_MADT_TRIGGER_MASK) ==
> + ACPI_MADT_TRIGGER_EDGE) {
> trigger = IST_EDGE;
> - if (pic->pic_type == PIC_IOAPIC)
> - irq = -1;
> - else
> - irq = (int)InterruptNumber;
> - goto sci_override;
> + mpflags &= ~(MPS_INTTR_LEVEL << 2);
> + redir &= ~IOAPIC_REDLO_LEVEL;
> + }
> }
> -#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 the interrupt is handled via IOAPIC, update the map.
> */
>
> -#if NIOAPIC > 0
> sc = ioapic_find_bybase(InterruptNumber);
> if (sc != NULL) {
> pic = &sc->sc_pic;
> @@ -146,9 +183,12 @@ acpi_md_OsInstallInterruptHandler(uint32
>
> mip = sc->sc_pins[pin].ip_map;
> if (mip) {
> - mip->flags &= ~3;
> - mip->flags |= MPS_INTPO_ACTLO;
> - mip->redir |= IOAPIC_REDLO_ACTLO;
> + mip->flags &= ~(ACPI_MADT_TRIGGER_MASK |
> + ACPI_MADT_POLARITY_MASK);
> + mip->flags |= mpflags;
> + mip->redir &= ~(IOAPIC_REDLO_LEVEL |
> + IOAPIC_REDLO_ACTLO);
> + mip->redir |= redir;
> }
> } else
> #endif
> @@ -157,12 +197,6 @@ acpi_md_OsInstallInterruptHandler(uint32
> irq = pin = (int)InterruptNumber;
> }
>
> - trigger = IST_LEVEL;
> -
> -#if NIOAPIC > 0
> -sci_override:
> -#endif
> -
> /*
> * XXX probably, IPL_BIO is enough.
> */
Home |
Main Index |
Thread Index |
Old Index