Skip site navigation (1)Skip section navigation (2)
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>