From owner-freebsd-bugs Fri Aug 4 23:20:13 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id 2134337B607 for ; Fri, 4 Aug 2000 23:20:04 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id XAA80210; Fri, 4 Aug 2000 23:20:04 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Date: Fri, 4 Aug 2000 23:20:04 -0700 (PDT) Message-Id: <200008050620.XAA80210@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: Tor.Egge@fast.no Subject: Re: kern/20312: IO APIC problems Reply-To: Tor.Egge@fast.no Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org 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