From: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>

i386 generic subarchitecture requires explicit dmi strings or command line
to enable bigsmp mode.  The patch below removes that restriction, and uses
bigsmp as soon as it finds more than 8 logical CPUs, Intel processors and
xAPIC support.

Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 arch/i386/kernel/acpi/boot.c              |    3 +++
 arch/i386/kernel/mpparse.c                |    9 +++++++++
 arch/i386/kernel/setup.c                  |    7 ++++++-
 arch/i386/mach-generic/bigsmp.c           |    5 ++++-
 arch/i386/mach-generic/probe.c            |   20 ++++++++++++++++++++
 include/asm-i386/apicdef.h                |    1 +
 include/asm-i386/mach-generic/mach_apic.h |    2 ++
 include/asm-i386/mpspec.h                 |    1 +
 8 files changed, 46 insertions(+), 2 deletions(-)

diff -puN arch/i386/kernel/acpi/boot.c~x86-automatically-enable-bigsmp-when-we-have-more-than-8-cpus-2 arch/i386/kernel/acpi/boot.c
--- devel/arch/i386/kernel/acpi/boot.c~x86-automatically-enable-bigsmp-when-we-have-more-than-8-cpus-2	2005-08-30 18:41:35.000000000 -0700
+++ devel-akpm/arch/i386/kernel/acpi/boot.c	2005-08-30 18:41:35.000000000 -0700
@@ -814,6 +814,9 @@ static void __init acpi_process_madt(voi
 		if (!error) {
 			acpi_lapic = 1;
 
+#ifdef CONFIG_X86_GENERICARCH
+			generic_bigsmp_probe();
+#endif
 			/*
 			 * Parse MADT IO-APIC entries
 			 */
diff -puN arch/i386/kernel/mpparse.c~x86-automatically-enable-bigsmp-when-we-have-more-than-8-cpus-2 arch/i386/kernel/mpparse.c
--- devel/arch/i386/kernel/mpparse.c~x86-automatically-enable-bigsmp-when-we-have-more-than-8-cpus-2	2005-08-30 18:41:35.000000000 -0700
+++ devel-akpm/arch/i386/kernel/mpparse.c	2005-08-30 18:41:35.000000000 -0700
@@ -65,6 +65,8 @@ int nr_ioapics;
 int pic_mode;
 unsigned long mp_lapic_addr;
 
+unsigned int def_to_bigsmp = 0;
+
 /* Processor that is doing the boot up */
 unsigned int boot_cpu_physical_apicid = -1U;
 /* Internal processor count */
@@ -213,6 +215,13 @@ static void __init MP_processor_info (st
 		ver = 0x10;
 	}
 	apic_version[m->mpc_apicid] = ver;
+	if ((num_processors > 8) &&
+	    APIC_XAPIC(ver) &&
+	    (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL))
+		def_to_bigsmp = 1;
+	else
+		def_to_bigsmp = 0;
+
 	bios_cpu_apicid[num_processors - 1] = m->mpc_apicid;
 }
 
diff -puN arch/i386/kernel/setup.c~x86-automatically-enable-bigsmp-when-we-have-more-than-8-cpus-2 arch/i386/kernel/setup.c
--- devel/arch/i386/kernel/setup.c~x86-automatically-enable-bigsmp-when-we-have-more-than-8-cpus-2	2005-08-30 18:41:35.000000000 -0700
+++ devel-akpm/arch/i386/kernel/setup.c	2005-08-30 18:41:35.000000000 -0700
@@ -1585,8 +1585,13 @@ void __init setup_arch(char **cmdline_p)
 	 */
 	acpi_boot_table_init();
 	acpi_boot_init();
-#endif
 
+#if defined(CONFIG_SMP) && defined(CONFIG_X86_PC)
+	if (def_to_bigsmp) {
+		printk(KERN_WARNING "More than 8 CPUs detected and CONFIG_X86_PC cannot handle it.\n Use CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n");
+	}
+#endif
+#endif
 #ifdef CONFIG_X86_LOCAL_APIC
 	if (smp_found_config)
 		get_smp_config();
diff -puN arch/i386/mach-generic/bigsmp.c~x86-automatically-enable-bigsmp-when-we-have-more-than-8-cpus-2 arch/i386/mach-generic/bigsmp.c
--- devel/arch/i386/mach-generic/bigsmp.c~x86-automatically-enable-bigsmp-when-we-have-more-than-8-cpus-2	2005-08-30 18:41:35.000000000 -0700
+++ devel-akpm/arch/i386/mach-generic/bigsmp.c	2005-08-30 18:41:35.000000000 -0700
@@ -47,7 +47,10 @@ static struct dmi_system_id __initdata b
 
 static __init int probe_bigsmp(void)
 { 
-	dmi_check_system(bigsmp_dmi_table);
+	if (def_to_bigsmp)
+        	dmi_bigsmp = 1;
+	else
+		dmi_check_system(bigsmp_dmi_table);
 	return dmi_bigsmp; 
 } 
 
diff -puN arch/i386/mach-generic/probe.c~x86-automatically-enable-bigsmp-when-we-have-more-than-8-cpus-2 arch/i386/mach-generic/probe.c
--- devel/arch/i386/mach-generic/probe.c~x86-automatically-enable-bigsmp-when-we-have-more-than-8-cpus-2	2005-08-30 18:41:35.000000000 -0700
+++ devel-akpm/arch/i386/mach-generic/probe.c	2005-08-30 18:41:35.000000000 -0700
@@ -30,6 +30,25 @@ struct genapic *apic_probe[] __initdata 
 	NULL,
 };
 
+static int cmdline_apic;
+
+void __init generic_bigsmp_probe(void)
+{
+	/*
+	 * This routine is used to switch to bigsmp mode when
+	 * - There is no apic= option specified by the user
+	 * - generic_apic_probe() has choosen apic_default as the sub_arch
+	 * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support
+	 */
+
+	if (!cmdline_apic && genapic == &apic_default)
+		if (apic_bigsmp.probe()) {
+			genapic = &apic_bigsmp;
+			printk(KERN_INFO "Overriding APIC driver with %s\n",
+			       genapic->name);
+		}
+}
+
 void __init generic_apic_probe(char *command_line) 
 { 
 	char *s;
@@ -52,6 +71,7 @@ void __init generic_apic_probe(char *com
 		if (!changed)
 			printk(KERN_ERR "Unknown genapic `%s' specified.\n", s);
 		*p = old;
+		cmdline_apic = changed;
 	} 
 	for (i = 0; !changed && apic_probe[i]; i++) { 
 		if (apic_probe[i]->probe()) {
diff -puN include/asm-i386/apicdef.h~x86-automatically-enable-bigsmp-when-we-have-more-than-8-cpus-2 include/asm-i386/apicdef.h
--- devel/include/asm-i386/apicdef.h~x86-automatically-enable-bigsmp-when-we-have-more-than-8-cpus-2	2005-08-30 18:41:35.000000000 -0700
+++ devel-akpm/include/asm-i386/apicdef.h	2005-08-30 18:41:35.000000000 -0700
@@ -16,6 +16,7 @@
 #define			GET_APIC_VERSION(x)	((x)&0xFF)
 #define			GET_APIC_MAXLVT(x)	(((x)>>16)&0xFF)
 #define			APIC_INTEGRATED(x)	((x)&0xF0)
+#define			APIC_XAPIC(x)		((x) >= 0x14)
 #define		APIC_TASKPRI	0x80
 #define			APIC_TPRI_MASK		0xFF
 #define		APIC_ARBPRI	0x90
diff -puN include/asm-i386/mach-generic/mach_apic.h~x86-automatically-enable-bigsmp-when-we-have-more-than-8-cpus-2 include/asm-i386/mach-generic/mach_apic.h
--- devel/include/asm-i386/mach-generic/mach_apic.h~x86-automatically-enable-bigsmp-when-we-have-more-than-8-cpus-2	2005-08-30 18:41:35.000000000 -0700
+++ devel-akpm/include/asm-i386/mach-generic/mach_apic.h	2005-08-30 18:41:35.000000000 -0700
@@ -28,4 +28,6 @@
 #define enable_apic_mode (genapic->enable_apic_mode)
 #define phys_pkg_id (genapic->phys_pkg_id)
 
+extern void generic_bigsmp_probe(void);
+
 #endif /* __ASM_MACH_APIC_H */
diff -puN include/asm-i386/mpspec.h~x86-automatically-enable-bigsmp-when-we-have-more-than-8-cpus-2 include/asm-i386/mpspec.h
--- devel/include/asm-i386/mpspec.h~x86-automatically-enable-bigsmp-when-we-have-more-than-8-cpus-2	2005-08-30 18:41:35.000000000 -0700
+++ devel-akpm/include/asm-i386/mpspec.h	2005-08-30 18:41:35.000000000 -0700
@@ -11,6 +11,7 @@ extern int mp_bus_id_to_local [MAX_MP_BU
 extern int quad_local_to_mp_bus_id [NR_CPUS/4][4];
 extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
 
+extern unsigned int def_to_bigsmp;
 extern unsigned int boot_cpu_physical_apicid;
 extern int smp_found_config;
 extern void find_smp_config (void);
_