Subject: Re: ACPI test kernels for *all* users
To: None <current-users@netbsd.org>
From: Joerg Sonnenberger <joerg@britannica.bec.de>
List: current-users
Date: 10/05/2007 17:23:25
--sdtB3X0nJg68CQEu
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Wed, Oct 03, 2007 at 01:35:24AM +0200, Joerg Sonnenberger wrote:
> it seems that the fix for ACPI SCI handling broke some machines that
> were working before. The jmcneill-pm branch has a change that it
> should fix all cases, but it is aggressive and might break older machines.

Attached is the backport of that specific change. It can be applied with
some fuzz to current as well.

Please test this. GENERIC kernels for netbsd4 can be found at
http://www.netbsd.org/~joerg/netbsd4-i386.bz2 and
http://www.netbsd.org/~joerg/netbsd4-amd64.bz2

I will ask for a pullup of this change only, if noone steps up with a
regression relative to RC1 for this patch. In that case the original
pullup will be backed out as well.

Joerg

--sdtB3X0nJg68CQEu
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="sci-rewrite-4.diff"

Index: include/mpacpi.h
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/include/mpacpi.h,v
retrieving revision 1.4
diff -u -r1.4 mpacpi.h
--- include/mpacpi.h	4 Jul 2006 00:30:22 -0000	1.4
+++ include/mpacpi.h	5 Oct 2007 15:01:56 -0000
@@ -14,4 +14,6 @@
 struct mp_intr_map;
 int mpacpi_findintr_linkdev(struct mp_intr_map *);
 
+extern struct mp_intr_map *mpacpi_sci_override;
+
 #endif /* _X86_MPACPI_H_ */
Index: x86/acpi_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/acpi_machdep.c,v
retrieving revision 1.12.6.1
diff -u -r1.12.6.1 acpi_machdep.c
--- x86/acpi_machdep.c	30 Sep 2007 19:50:29 -0000	1.12.6.1
+++ x86/acpi_machdep.c	5 Oct 2007 15:01:56 -0000
@@ -117,15 +117,6 @@
 	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 @@
 	 * 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 @@
 	}
 
 #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.
 	 */
Index: x86/ioapic.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/ioapic.c,v
retrieving revision 1.16
diff -u -r1.16 ioapic.c
--- x86/ioapic.c	16 Nov 2006 01:32:39 -0000	1.16
+++ x86/ioapic.c	5 Oct 2007 15:01:56 -0000
@@ -437,8 +437,8 @@
 				redlo &= ~IOAPIC_REDLO_ACTLO;
 		}
 	}
-	ioapic_write(sc, IOAPIC_REDLO(pin), redlo);
 	ioapic_write(sc, IOAPIC_REDHI(pin), redhi);
+	ioapic_write(sc, IOAPIC_REDLO(pin), redlo);
 	if (mp_verbose)
 		ioapic_print_redir(sc, "int", pin);
 }
Index: x86/mpacpi.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/mpacpi.c,v
retrieving revision 1.44.2.1
diff -u -r1.44.2.1 mpacpi.c
--- x86/mpacpi.c	28 Apr 2007 01:17:43 -0000	1.44.2.1
+++ x86/mpacpi.c	5 Oct 2007 15:01:56 -0000
@@ -134,6 +134,8 @@
 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;
 
@@ -283,6 +285,9 @@
 		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;
 	}

--sdtB3X0nJg68CQEu--