diff options
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/kernel/acpi/boot.c | 3 | ||||
-rw-r--r-- | arch/i386/kernel/mpparse.c | 9 | ||||
-rw-r--r-- | arch/i386/kernel/setup.c | 8 | ||||
-rw-r--r-- | arch/i386/mach-generic/bigsmp.c | 5 | ||||
-rw-r--r-- | arch/i386/mach-generic/probe.c | 20 |
5 files changed, 43 insertions, 2 deletions
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index b7808a89d945..34ee500c26e5 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -833,6 +833,9 @@ acpi_process_madt(void) | |||
833 | if (!error) { | 833 | if (!error) { |
834 | acpi_lapic = 1; | 834 | acpi_lapic = 1; |
835 | 835 | ||
836 | #ifdef CONFIG_X86_GENERICARCH | ||
837 | generic_bigsmp_probe(); | ||
838 | #endif | ||
836 | /* | 839 | /* |
837 | * Parse MADT IO-APIC entries | 840 | * Parse MADT IO-APIC entries |
838 | */ | 841 | */ |
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index ce838abb27d8..788efffa9930 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c | |||
@@ -65,6 +65,8 @@ int nr_ioapics; | |||
65 | int pic_mode; | 65 | int pic_mode; |
66 | unsigned long mp_lapic_addr; | 66 | unsigned long mp_lapic_addr; |
67 | 67 | ||
68 | unsigned int def_to_bigsmp = 0; | ||
69 | |||
68 | /* Processor that is doing the boot up */ | 70 | /* Processor that is doing the boot up */ |
69 | unsigned int boot_cpu_physical_apicid = -1U; | 71 | unsigned int boot_cpu_physical_apicid = -1U; |
70 | /* Internal processor count */ | 72 | /* Internal processor count */ |
@@ -213,6 +215,13 @@ static void __init MP_processor_info (struct mpc_config_processor *m) | |||
213 | ver = 0x10; | 215 | ver = 0x10; |
214 | } | 216 | } |
215 | apic_version[m->mpc_apicid] = ver; | 217 | apic_version[m->mpc_apicid] = ver; |
218 | if ((num_processors > 8) && | ||
219 | APIC_XAPIC(ver) && | ||
220 | (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)) | ||
221 | def_to_bigsmp = 1; | ||
222 | else | ||
223 | def_to_bigsmp = 0; | ||
224 | |||
216 | bios_cpu_apicid[num_processors - 1] = m->mpc_apicid; | 225 | bios_cpu_apicid[num_processors - 1] = m->mpc_apicid; |
217 | } | 226 | } |
218 | 227 | ||
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 9adbf710ec8d..294bcca985ab 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
@@ -1585,8 +1585,14 @@ void __init setup_arch(char **cmdline_p) | |||
1585 | */ | 1585 | */ |
1586 | acpi_boot_table_init(); | 1586 | acpi_boot_table_init(); |
1587 | acpi_boot_init(); | 1587 | acpi_boot_init(); |
1588 | #endif | ||
1589 | 1588 | ||
1589 | #if defined(CONFIG_SMP) && defined(CONFIG_X86_PC) | ||
1590 | if (def_to_bigsmp) | ||
1591 | printk(KERN_WARNING "More than 8 CPUs detected and " | ||
1592 | "CONFIG_X86_PC cannot handle it.\nUse " | ||
1593 | "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n"); | ||
1594 | #endif | ||
1595 | #endif | ||
1590 | #ifdef CONFIG_X86_LOCAL_APIC | 1596 | #ifdef CONFIG_X86_LOCAL_APIC |
1591 | if (smp_found_config) | 1597 | if (smp_found_config) |
1592 | get_smp_config(); | 1598 | get_smp_config(); |
diff --git a/arch/i386/mach-generic/bigsmp.c b/arch/i386/mach-generic/bigsmp.c index 25883b44f625..037b2af1a1f4 100644 --- a/arch/i386/mach-generic/bigsmp.c +++ b/arch/i386/mach-generic/bigsmp.c | |||
@@ -47,7 +47,10 @@ static struct dmi_system_id __initdata bigsmp_dmi_table[] = { | |||
47 | 47 | ||
48 | static __init int probe_bigsmp(void) | 48 | static __init int probe_bigsmp(void) |
49 | { | 49 | { |
50 | dmi_check_system(bigsmp_dmi_table); | 50 | if (def_to_bigsmp) |
51 | dmi_bigsmp = 1; | ||
52 | else | ||
53 | dmi_check_system(bigsmp_dmi_table); | ||
51 | return dmi_bigsmp; | 54 | return dmi_bigsmp; |
52 | } | 55 | } |
53 | 56 | ||
diff --git a/arch/i386/mach-generic/probe.c b/arch/i386/mach-generic/probe.c index 5497c65a8790..cea5b3ce4b57 100644 --- a/arch/i386/mach-generic/probe.c +++ b/arch/i386/mach-generic/probe.c | |||
@@ -30,6 +30,25 @@ struct genapic *apic_probe[] __initdata = { | |||
30 | NULL, | 30 | NULL, |
31 | }; | 31 | }; |
32 | 32 | ||
33 | static int cmdline_apic; | ||
34 | |||
35 | void __init generic_bigsmp_probe(void) | ||
36 | { | ||
37 | /* | ||
38 | * This routine is used to switch to bigsmp mode when | ||
39 | * - There is no apic= option specified by the user | ||
40 | * - generic_apic_probe() has choosen apic_default as the sub_arch | ||
41 | * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support | ||
42 | */ | ||
43 | |||
44 | if (!cmdline_apic && genapic == &apic_default) | ||
45 | if (apic_bigsmp.probe()) { | ||
46 | genapic = &apic_bigsmp; | ||
47 | printk(KERN_INFO "Overriding APIC driver with %s\n", | ||
48 | genapic->name); | ||
49 | } | ||
50 | } | ||
51 | |||
33 | void __init generic_apic_probe(char *command_line) | 52 | void __init generic_apic_probe(char *command_line) |
34 | { | 53 | { |
35 | char *s; | 54 | char *s; |
@@ -52,6 +71,7 @@ void __init generic_apic_probe(char *command_line) | |||
52 | if (!changed) | 71 | if (!changed) |
53 | printk(KERN_ERR "Unknown genapic `%s' specified.\n", s); | 72 | printk(KERN_ERR "Unknown genapic `%s' specified.\n", s); |
54 | *p = old; | 73 | *p = old; |
74 | cmdline_apic = changed; | ||
55 | } | 75 | } |
56 | for (i = 0; !changed && apic_probe[i]; i++) { | 76 | for (i = 0; !changed && apic_probe[i]; i++) { |
57 | if (apic_probe[i]->probe()) { | 77 | if (apic_probe[i]->probe()) { |