Date: Fri, 4 Aug 2000 23:20:04 -0700 (PDT) From: Tor.Egge@fast.no To: freebsd-bugs@FreeBSD.org Subject: Re: kern/20312: IO APIC problems Message-ID: <200008050620.XAA80210@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/20312; it has been noted by GNATS.
From: Tor.Egge@fast.no
To: steve@sse0691.bri.hp.com
Cc: FreeBSD-gnats-submit@FreeBSD.ORG, msmith@FreeBSD.ORG
Subject: Re: kern/20312: IO APIC problems
Date: Sat, 05 Aug 2000 08:09:39 +0200
The problem is due to a incomplete fix for panics on machines
where the BIOS doesn't set the physical IO APIC ids, cf. PR 18919.
msmith 2000/05/31 14:37:29 PDT
Revision Changes Path
1.117 +3 -8 src/sys/i386/i386/mp_machdep.c
1.39 +19 -1 src/sys/i386/i386/mpapic.c
1.52 +2 -1 src/sys/i386/include/smp.h
Section 3.6.6 of the Intel MP spec describes the operating system as
responsible for verifying that the IO APIC ids are unique and
acceptable. If also contains a statement restricting the acceptable
ids to the lowest possible ids left over after local apic id assignment.
Thus the following patch might be applicable.
- Tor Egge
Index: mp_machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/mp_machdep.c,v
retrieving revision 1.117
diff -u -r1.117 mp_machdep.c
--- mp_machdep.c 2000/05/31 21:37:24 1.117
+++ mp_machdep.c 2000/08/05 05:45:50
@@ -1013,6 +1029,42 @@
}
}
+
+static void
+swap_apic_id(int oldid, int newid)
+{
+ int x;
+ int apic;
+ int oapic;
+
+
+ if (oldid == newid)
+ return;
+
+ printf("IOAPIC#%d assigned physical APIC ID %d\n",
+ ID_TO_IO(oldid), newid);
+
+ /* Swap IOAPIC physical IDs in interrupt entries */
+ for (x = 0; x < nintrs; x++) {
+ if (io_apic_ints[x].dst_apic_id == oldid)
+ io_apic_ints[x].dst_apic_id = newid;
+ else if (io_apic_ints[x].dst_apic_id == newid)
+ io_apic_ints[x].dst_apic_id = oldid;
+ }
+
+ /* Swap IOAPIC physical IDs in IO_TO_ID and ID_TO_IO mappings */
+ apic = ID_TO_IO(oldid);
+ oapic = ID_TO_IO(newid);
+ if (oapic >= 0 && IO_TO_ID(oapic) == newid) {
+ ID_TO_IO(oldid) = oapic;
+ IO_TO_ID(oapic) = oldid;
+ } else {
+ ID_TO_IO(oldid) = -1;
+ }
+ ID_TO_IO(newid) = apic;
+ IO_TO_ID(apic) = newid;
+}
+
/*
* parse an Intel MP specification table
*/
@@ -1024,6 +1076,9 @@
int bus_0 = 0; /* Stop GCC warning */
int bus_pci = 0; /* Stop GCC warning */
int num_pci_bus;
+ int apic; /* logical IO APIC ID */
+ int new_physid; /* Free physical IO APIC ID */
+ int max_physid; /* Max physical IO APIC ID */
/*
* Fix mis-numbering of the PCI bus and its INT entries if the BIOS
@@ -1076,6 +1131,21 @@
}
}
}
+ /* Assign IOAPIC ids */
+ new_physid = 0; /* Start with first possible APIC ID */
+ max_physid = 15; /* physical APIC IDs are in range 0..15 */
+ for (apic = 0; apic < mp_napics; ++apic) { /* For all IO APICs */
+ /* Find next free APIC ID (not used by any CPU) */
+ while (new_physid <= max_physid &&
+ ID_TO_CPU(new_physid) >= 0 &&
+ CPU_TO_ID(ID_TO_CPU(new_physid)) == new_physid)
+ new_physid++;
+
+ if (new_physid < max_physid) {
+ swap_apic_id(IO_TO_ID(apic), new_physid);
+ new_physid++;
+ }
+ }
}
@@ -1602,7 +1672,6 @@
{
int ap_cpu_id;
#if defined(APIC_IO)
- u_int32_t ux;
int io_apic_id;
int pin;
#endif /* APIC_IO */
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200008050620.XAA80210>
