patch-2.3.99-pre6 linux/arch/i386/kernel/mpparse.c

Next file: linux/arch/i386/kernel/mtrr.c
Previous file: linux/arch/i386/kernel/mca.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.99-pre5/linux/arch/i386/kernel/mpparse.c linux/arch/i386/kernel/mpparse.c
@@ -9,7 +9,7 @@
  *		Erich Boleyn	:	MP v1.4 and additional changes.
  *		Alan Cox	:	Added EBDA scanning
  *		Ingo Molnar	:	various cleanups and rewrites
- *	Maciej W. Rozycki	:	Bits for genuine 82489DX APICs
+ *	Maciej W. Rozycki	:	Bits for default MP configurations
  */
 
 #include <linux/mm.h>
@@ -34,7 +34,7 @@
  * Various Linux-internal data structures created from the
  * MP-table.
  */
-int apic_version [NR_CPUS];
+int apic_version [MAX_APICS];
 int mp_bus_id_to_type [MAX_MP_BUSSES] = { -1, };
 int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { -1, };
 int mp_current_pci_id = 0;
@@ -42,9 +42,9 @@
 unsigned long mp_lapic_addr = 0;
 
 /* Processor that is doing the boot up */
-unsigned int boot_cpu_id = 0;
+unsigned int boot_cpu_id = -1U;
 /* Internal processor count */
-static unsigned int num_processors = 1;
+static unsigned int num_processors = 0;
 
 /* Bitmask of physically existing CPUs */
 unsigned long phys_cpu_present_map = 0;
@@ -132,13 +132,12 @@
 	if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
 		Dprintk("    Bootup CPU\n");
 		boot_cpu_id = m->mpc_apicid;
-	} else
-		/* Boot CPU already counted */
-		num_processors++;
+	}
+	num_processors++;
 
-	if (m->mpc_apicid > NR_CPUS) {
-		printk("Processor #%d unused. (Max %d processors).\n",
-			m->mpc_apicid, NR_CPUS);
+	if (m->mpc_apicid > MAX_APICS) {
+		printk("Processor #%d INVALID. (Max ID: %d).\n",
+			m->mpc_apicid, MAX_APICS);
 		return;
 	}
 	ver = m->mpc_apicver;
@@ -164,18 +163,18 @@
 
 	if (strncmp(str, "ISA", 3) == 0) {
 		mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
-	} else {
-	if (strncmp(str, "EISA", 4) == 0) {
+	} else if (strncmp(str, "EISA", 4) == 0) {
 		mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA;
-	} else {
-	if (strncmp(str, "PCI", 3) == 0) {
+	} else if (strncmp(str, "PCI", 3) == 0) {
 		mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI;
 		mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id;
 		mp_current_pci_id++;
+	} else if (strncmp(str, "MCA", 3) == 0) {
+		mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA;
 	} else {
 		printk("Unknown bustype %s\n", str);
 		panic("cannot handle bus - mail to linux-smp@vger.rutgers.edu");
-	} } }
+	}
 }
 
 static void __init MP_ioapic_info (struct mpc_config_ioapic *m)
@@ -197,12 +196,22 @@
 static void __init MP_intsrc_info (struct mpc_config_intsrc *m)
 {
 	mp_irqs [mp_irq_entries] = *m;
+	Dprintk("Int: type %d, pol %d, trig %d, bus %d,"
+		" IRQ %02x, APIC ID %x, APIC INT %02x\n",
+			m->mpc_irqtype, m->mpc_irqflag & 3,
+			(m->mpc_irqflag >> 2) & 3, m->mpc_srcbus,
+			m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq);
 	if (++mp_irq_entries == MAX_IRQ_SOURCES)
 		panic("Max # of irq sources exceeded!!\n");
 }
 
 static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m)
 {
+	Dprintk("Lint: type %d, pol %d, trig %d, bus %d,"
+		" IRQ %02x, APIC ID %x, APIC LINT %02x\n",
+			m->mpc_irqtype, m->mpc_irqflag & 3,
+			(m->mpc_irqflag >> 2) &3, m->mpc_srcbusid,
+			m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint);
 	/*
 	 * Well it seems all SMP boards in existence
 	 * use ExtINT/LVT1 == LINT0 and
@@ -316,6 +325,122 @@
 	return num_processors;
 }
 
+static void __init construct_default_ioirq_mptable(int mpc_default_type)
+{
+	struct mpc_config_intsrc intsrc;
+	int i;
+
+	intsrc.mpc_type = MP_INTSRC;
+	intsrc.mpc_irqflag = 0;			/* conforming */
+	intsrc.mpc_srcbus = 0;
+	intsrc.mpc_dstapic = mp_ioapics[0].mpc_apicid;
+
+	intsrc.mpc_irqtype = mp_INT;
+	for (i = 0; i < 16; i++) {
+		switch (mpc_default_type) {
+		case 2:
+			if (i == 0 || i == 13)
+				continue;	/* IRQ0 & IRQ13 not connected */
+			/* fall through */
+		default:
+			if (i == 2)
+				continue;	/* IRQ2 is never connected */
+		}
+
+		intsrc.mpc_srcbusirq = i;
+		intsrc.mpc_dstirq = i ? i : 2;		/* IRQ0 to INTIN2 */
+		MP_intsrc_info(&intsrc);
+	}
+
+	intsrc.mpc_irqtype = mp_ExtINT;
+	intsrc.mpc_srcbusirq = 0;
+	intsrc.mpc_dstirq = 0;				/* 8259A to INTIN0 */
+	MP_intsrc_info(&intsrc);
+}
+
+static inline void __init construct_default_ISA_mptable(int mpc_default_type)
+{
+	struct mpc_config_processor processor;
+	struct mpc_config_bus bus;
+	struct mpc_config_ioapic ioapic;
+	struct mpc_config_lintsrc lintsrc;
+	int linttypes[2] = { mp_ExtINT, mp_NMI };
+	int i;
+
+	/*
+	 * local APIC has default address
+	 */
+	mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
+
+	/*
+	 * 2 CPUs, numbered 0 & 1.
+	 */
+	processor.mpc_type = MP_PROCESSOR;
+	/* Either an integrated APIC or a discrete 82489DX. */
+	processor.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
+	processor.mpc_cpuflag = CPU_ENABLED;
+	processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) |
+				   (boot_cpu_data.x86_model << 4) |
+				   boot_cpu_data.x86_mask;
+	processor.mpc_featureflag = boot_cpu_data.x86_capability;
+	processor.mpc_reserved[0] = 0;
+	processor.mpc_reserved[1] = 0;
+	for (i = 0; i < 2; i++) {
+		processor.mpc_apicid = i;
+		MP_processor_info(&processor);
+	}
+
+	bus.mpc_type = MP_BUS;
+	bus.mpc_busid = 0;
+	switch (mpc_default_type) {
+		default:
+			printk("???\nUnknown standard configuration %d\n",
+				mpc_default_type);
+			/* fall through */
+		case 1:
+		case 5:
+			memcpy(bus.mpc_bustype, "ISA   ", 6);
+			break;
+		case 2:
+		case 6:
+		case 3:
+			memcpy(bus.mpc_bustype, "EISA  ", 6);
+			break;
+		case 4:
+		case 7:
+			memcpy(bus.mpc_bustype, "MCA   ", 6);
+	}
+	MP_bus_info(&bus);
+	if (mpc_default_type > 4) {
+		bus.mpc_busid = 1;
+		memcpy(bus.mpc_bustype, "PCI   ", 6);
+		MP_bus_info(&bus);
+	}
+
+	ioapic.mpc_type = MP_IOAPIC;
+	ioapic.mpc_apicid = 2;
+	ioapic.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
+	ioapic.mpc_flags = MPC_APIC_USABLE;
+	ioapic.mpc_apicaddr = 0xFEC00000;
+	MP_ioapic_info(&ioapic);
+
+	/*
+	 * We set up most of the low 16 IO-APIC pins according to MPS rules.
+	 */
+	construct_default_ioirq_mptable(mpc_default_type);
+
+	lintsrc.mpc_type = MP_LINTSRC;
+	lintsrc.mpc_irqflag = 0;		/* conforming */
+	lintsrc.mpc_srcbusid = 0;
+	lintsrc.mpc_srcbusirq = 0;
+	lintsrc.mpc_destapic = MP_APIC_ALL;
+	for (i = 0; i < 2; i++) {
+		lintsrc.mpc_irqtype = linttypes[i];
+		lintsrc.mpc_destapiclint = i;
+		MP_lintsrc_info(&lintsrc);
+	}
+}
+
 static struct intel_mp_floating *mpf_found;
 
 /*
@@ -332,83 +457,43 @@
 		printk("    Virtual Wire compatibility mode.\n");
 		pic_mode = 0;
 	}
-	/*
-	 * default CPU id - if it's different in the mptable
-	 * then we change it before first using it.
-	 */
-	boot_cpu_id = 0;
+
 	/*
 	 * Now see if we need to read further.
 	 */
 	if (mpf->mpf_feature1 != 0) {
+
 		printk("Default MP configuration #%d\n", mpf->mpf_feature1);
+		construct_default_ISA_mptable(mpf->mpf_feature1);
 
-		/*
-		 * local APIC has default address
-		 */
-		mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
+	} else if (mpf->mpf_physptr) {
 
 		/*
-		 * 2 CPUs, numbered 0 & 1.
+		 * Read the physical hardware table.  Anything here will
+		 * override the defaults.
 		 */
-		phys_cpu_present_map = 3;
-		num_processors = 2;
+		smp_read_mpc((void *)mpf->mpf_physptr);
 
-		nr_ioapics = 1;
-		mp_ioapics[0].mpc_apicaddr = 0xFEC00000;
-		mp_ioapics[0].mpc_apicid = 2;
 		/*
-		 * Save the default type number, we
-		 * need it later to set the IO-APIC
-		 * up properly:
+		 * If there are no explicit MP IRQ entries, then we are
+		 * broken.  We set up most of the low 16 IO-APIC pins to
+		 * ISA defaults and hope it will work.
 		 */
-		mpc_default_type = mpf->mpf_feature1;
+		if (!mp_irq_entries) {
+			struct mpc_config_bus bus;
 
-		printk("Bus #0 is ");
-	}
+			printk("BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n");
 
-	switch (mpf->mpf_feature1) {
-		case 1:
-		case 5:
-			printk("ISA\n");
-			break;
-		case 2:
-			printk("EISA with no IRQ0 and no IRQ13 DMA chaining\n");
-			break;
-		case 6:
-		case 3:
-			printk("EISA\n");
-			break;
-		case 4:
-		case 7:
-			printk("MCA\n");
-			break;
-		case 0:
-			if (!mpf->mpf_physptr)
-				BUG();
-			break;
-		default:
-			printk("???\nUnknown standard configuration %d\n",
-				mpf->mpf_feature1);
-			return;
-	}
-	if (mpf->mpf_feature1 > 4) {
-		printk("Bus #1 is PCI\n");
+			bus.mpc_type = MP_BUS;
+			bus.mpc_busid = 0;
+			memcpy(bus.mpc_bustype, "ISA   ", 6);
+			MP_bus_info(&bus);
 
-		/*
-		 * Set local APIC version to the integrated form.
-		 * It's initialized to zero otherwise, representing
-		 * a discrete 82489DX.
-		 */
-		apic_version[0] = 0x10;
-		apic_version[1] = 0x10;
-	}
-	/*
-	 * Read the physical hardware table. Anything here will override the
-	 * defaults.
-	 */
-	if (mpf->mpf_physptr)
-		smp_read_mpc((void *)mpf->mpf_physptr);
+			construct_default_ioirq_mptable(0);
+		}
+
+	} else
+		BUG();
 
 	printk("Processors: %d\n", num_processors);
 	/*

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