patch-2.4.0-test8 linux/arch/i386/kernel/io_apic.c
Next file: linux/arch/i386/kernel/mca.c
Previous file: linux/arch/i386/kernel/apic.c
Back to the patch index
Back to the overall index
- Lines: 70
- Date:
Tue Aug 29 14:10:53 2000
- Orig file:
v2.4.0-test7/linux/arch/i386/kernel/io_apic.c
- Orig date:
Wed Aug 23 18:36:36 2000
diff -u --recursive --new-file v2.4.0-test7/linux/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c
@@ -982,7 +982,10 @@
static void __init setup_ioapic_ids_from_mpc (void)
{
struct IO_APIC_reg_00 reg_00;
+ unsigned long phys_id_present_map = phys_cpu_present_map;
int apic;
+ int i;
+ unsigned char old_id;
/*
* Set the IOAPIC ID to the value stored in the MPC table.
@@ -992,6 +995,8 @@
/* Read the register 0 value */
*(int *)®_00 = io_apic_read(apic, 0);
+ old_id = mp_ioapics[apic].mpc_apicid;
+
if (mp_ioapics[apic].mpc_apicid >= 0xf) {
printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
apic, mp_ioapics[apic].mpc_apicid);
@@ -1001,20 +1006,40 @@
}
/*
+ * Sanity check, is the ID really free? Every APIC in a
+ * system must have a unique ID or we get lots of nice
+ * 'stuck on smp_invalidate_needed IPI wait' messages.
+ */
+ if (phys_id_present_map & (1 << mp_ioapics[apic].mpc_apicid)) {
+ printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
+ apic, mp_ioapics[apic].mpc_apicid);
+ for (i = 0; i < 0xf; i++)
+ if (!(phys_id_present_map & (1 << i)))
+ break;
+ if (i >= 0xf)
+ panic("Max APIC ID exceeded!\n");
+ printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
+ i);
+ phys_id_present_map |= 1 << i;
+ mp_ioapics[apic].mpc_apicid = i;
+ }
+
+ /*
+ * We need to adjust the IRQ routing table
+ * if the ID changed.
+ */
+ if (old_id != mp_ioapics[apic].mpc_apicid)
+ for (i = 0; i < mp_irq_entries; i++)
+ if (mp_irqs[i].mpc_dstapic == old_id)
+ mp_irqs[i].mpc_dstapic
+ = mp_ioapics[apic].mpc_apicid;
+
+ /*
* Read the right value from the MPC table and
* write it into the ID register.
*/
printk(KERN_INFO "...changing IO-APIC physical APIC ID to %d ...",
mp_ioapics[apic].mpc_apicid);
-
- /*
- * Sanity check, is the ID really free? Every APIC in the
- * system must have a unique ID or we get lots of nice
- * 'stuck on smp_invalidate_needed IPI wait' messages.
- */
- if (phys_cpu_present_map & (1<<mp_ioapics[apic].mpc_apicid))
- panic("APIC ID %d already used",
- mp_ioapics[apic].mpc_apicid);
reg_00.ID = mp_ioapics[apic].mpc_apicid;
io_apic_write(apic, 0, *(int *)®_00);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)