patch-2.4.23 linux-2.4.23/arch/i386/kernel/mpparse.c

Next file: linux-2.4.23/arch/i386/kernel/pci-i386.c
Previous file: linux-2.4.23/arch/i386/kernel/irq.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.22/arch/i386/kernel/mpparse.c linux-2.4.23/arch/i386/kernel/mpparse.c
@@ -229,6 +229,11 @@
 		boot_cpu_logical_apicid = logical_apicid;
 	}
 
+	if (num_processors >= NR_CPUS){
+		printk(KERN_WARNING "NR_CPUS limit of %i reached. Cannot "
+			"boot CPU(apicid 0x%x).\n", NR_CPUS, m->mpc_apicid);
+		return;
+	}
 	num_processors++;
 
 	if (m->mpc_apicid > MAX_APICS) {
@@ -582,10 +587,6 @@
 		++mpc_record;
 	}
 
-	if (clustered_apic_mode){
-		phys_cpu_present_map = logical_cpu_present_map;
-	}
-
 
 	printk("Enabling APIC mode: ");
 	if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ)
@@ -683,6 +684,24 @@
 	struct mpc_config_lintsrc lintsrc;
 	int linttypes[2] = { mp_ExtINT, mp_NMI };
 	int i;
+	struct {
+		int mp_bus_id_to_type[MAX_MP_BUSSES];
+		int mp_bus_id_to_node[MAX_MP_BUSSES];
+		int mp_bus_id_to_local[MAX_MP_BUSSES];
+		int mp_bus_id_to_pci_bus[MAX_MP_BUSSES];
+		struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
+	} *bus_data;
+
+	bus_data = alloc_bootmem(sizeof(*bus_data));
+	if (!bus_data)
+		panic("SMP mptable: out of memory!\n");
+	mp_bus_id_to_type = bus_data->mp_bus_id_to_type;
+	mp_bus_id_to_node = bus_data->mp_bus_id_to_node;
+	mp_bus_id_to_local = bus_data->mp_bus_id_to_local;
+	mp_bus_id_to_pci_bus = bus_data->mp_bus_id_to_pci_bus;
+	mp_irqs = bus_data->mp_irqs;
+	for (i = 0; i < MAX_MP_BUSSES; ++i)
+		mp_bus_id_to_pci_bus[i] = -1;
 
 	/*
 	 * local APIC has default address
@@ -977,7 +996,14 @@
 
 	processor.mpc_type = MP_PROCESSOR;
 	processor.mpc_apicid = id;
-	processor.mpc_apicver = 0x10; /* TBD: lapic version */
+
+	/*
+	 * mp_register_lapic_address() which is called before the
+	 * current function does the fixmap of FIX_APIC_BASE.
+	 * Read in the correct APIC version from there
+	 */
+	processor.mpc_apicver = apic_read(APIC_LVR);
+
 	processor.mpc_cpuflag = (enabled ? CPU_ENABLED : 0);
 	processor.mpc_cpuflag |= (boot_cpu ? CPU_BOOTPROCESSOR : 0);
 	processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | 
@@ -1014,7 +1040,7 @@
 			return i;
 	}
 
-	printk(KERN_ERR "ERROR: Unable to locate IOAPIC for IRQ %d/n", irq);
+	printk(KERN_ERR "ERROR: Unable to locate IOAPIC for IRQ %d\n", irq);
 
 	return -1;
 }
@@ -1114,7 +1140,7 @@
 	 */
 	for (i = 0; i < mp_irq_entries; i++) {
 		if ((mp_irqs[i].mpc_dstapic == intsrc.mpc_dstapic) 
-			&& (mp_irqs[i].mpc_dstirq == intsrc.mpc_dstirq)) {
+			&& (mp_irqs[i].mpc_srcbusirq == intsrc.mpc_srcbusirq)) {
 			mp_irqs[i] = intsrc;
 			found = 1;
 			break;
@@ -1199,8 +1225,6 @@
 	}
 }
 
-/* Ensure the ACPI SCI interrupt level is active low, edge-triggered */
-
 extern FADT_DESCRIPTOR acpi_fadt;
 
 void __init mp_config_ioapic_for_sci(int irq)
@@ -1209,6 +1233,7 @@
 	int ioapic_pin;
 	struct acpi_table_madt* madt;
 	struct acpi_table_int_src_ovr *entry = NULL;
+	acpi_interrupt_flags flags;
 	void *madt_end;
 	acpi_status status;
 
@@ -1227,30 +1252,36 @@
 
 		while ((void *) entry < madt_end) {
                 	if (entry->header.type == ACPI_MADT_INT_SRC_OVR &&
-			    acpi_fadt.sci_int == entry->bus_irq) {
-				/*
-				 * See the note at the end of ACPI 2.0b section
-				 * 5.2.10.8 for what this is about.
-				 */
-				if (entry->bus_irq != entry->global_irq) {
-					acpi_fadt.sci_int = entry->global_irq;
-					irq = entry->global_irq;
-					break;
-				}
-				else
-                			return;
-			}
-
+			    acpi_fadt.sci_int == entry->bus_irq)
+				goto found;
+			
                 	entry = (struct acpi_table_int_src_ovr *)
                 	        ((unsigned long) entry + entry->header.length);
         	}
 	}
+	/*
+	 * Although the ACPI spec says that the SCI should be level/low
+	 * don't reprogram it unless there is an explicit MADT OVR entry
+	 * instructing us to do so -- otherwise we break Tyan boards which
+	 * have the SCI wired edge/high but no MADT OVR.
+	 */
+	return;
 
+found:
+	/*
+	 * See the note at the end of ACPI 2.0b section
+	 * 5.2.10.8 for what this is about.
+	 */
+	flags = entry->flags;
+	acpi_fadt.sci_int = entry->global_irq;
+	irq = entry->global_irq;
+	
 	ioapic = mp_find_ioapic(irq);
 
 	ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
 
-	io_apic_set_pci_routing(ioapic, ioapic_pin, irq, 1, 1); // Active low, level triggered
+	io_apic_set_pci_routing(ioapic, ioapic_pin, irq, 
+				(flags.trigger >> 1) , (flags.polarity >> 1));
 }
 
 
@@ -1288,8 +1319,10 @@
 		}
 
 		/* Don't set up the ACPI SCI because it's already set up */
-		if (acpi_fadt.sci_int == irq)
+                if (acpi_fadt.sci_int == irq) {
+                        entry->irq = irq; /*we still need to set entry's irq*/
 			continue;
+                }
 	
 		ioapic = mp_find_ioapic(irq);
 		if (ioapic < 0)
@@ -1328,6 +1361,8 @@
 			entry->irq);
 	}
 	
+	print_IO_APIC();
+
 	return;
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)