aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/smpboot.c
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2005-11-02 02:15:43 -0500
committerStephen Rothwell <sfr@canb.auug.org.au>2005-11-02 02:15:43 -0500
commit2be7a906752abf8dce9350c23b6d1036049a5d3e (patch)
treeef178fa5801bdce24938819086662bb747d8c0c2 /arch/i386/kernel/smpboot.c
parentaaf8a7a2949481482200686c7bd3852e5be2e093 (diff)
parentfbf1769d08a8b085834dceb228540153ac2cd534 (diff)
Merge Paulus' tree
Diffstat (limited to 'arch/i386/kernel/smpboot.c')
-rw-r--r--arch/i386/kernel/smpboot.c68
1 files changed, 52 insertions, 16 deletions
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 5a2bbe0c4fff..01b618e73ecd 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -1078,16 +1078,6 @@ void *xquad_portio;
1078EXPORT_SYMBOL(xquad_portio); 1078EXPORT_SYMBOL(xquad_portio);
1079#endif 1079#endif
1080 1080
1081/*
1082 * Fall back to non SMP mode after errors.
1083 *
1084 */
1085static __init void disable_smp(void)
1086{
1087 cpu_set(0, cpu_sibling_map[0]);
1088 cpu_set(0, cpu_core_map[0]);
1089}
1090
1091static void __init smp_boot_cpus(unsigned int max_cpus) 1081static void __init smp_boot_cpus(unsigned int max_cpus)
1092{ 1082{
1093 int apicid, cpu, bit, kicked; 1083 int apicid, cpu, bit, kicked;
@@ -1100,6 +1090,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1100 printk("CPU%d: ", 0); 1090 printk("CPU%d: ", 0);
1101 print_cpu_info(&cpu_data[0]); 1091 print_cpu_info(&cpu_data[0]);
1102 1092
1093 boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
1103 boot_cpu_logical_apicid = logical_smp_processor_id(); 1094 boot_cpu_logical_apicid = logical_smp_processor_id();
1104 x86_cpu_to_apicid[0] = boot_cpu_physical_apicid; 1095 x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
1105 1096
@@ -1111,27 +1102,68 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1111 cpus_clear(cpu_core_map[0]); 1102 cpus_clear(cpu_core_map[0]);
1112 cpu_set(0, cpu_core_map[0]); 1103 cpu_set(0, cpu_core_map[0]);
1113 1104
1114 map_cpu_to_logical_apicid();
1115
1116 /* 1105 /*
1117 * If we couldn't find an SMP configuration at boot time, 1106 * If we couldn't find an SMP configuration at boot time,
1118 * get out of here now! 1107 * get out of here now!
1119 */ 1108 */
1120 if (!smp_found_config && !acpi_lapic) { 1109 if (!smp_found_config && !acpi_lapic) {
1121 printk(KERN_NOTICE "SMP motherboard not detected.\n"); 1110 printk(KERN_NOTICE "SMP motherboard not detected.\n");
1122 disable_smp(); 1111 smpboot_clear_io_apic_irqs();
1112 phys_cpu_present_map = physid_mask_of_physid(0);
1113 if (APIC_init_uniprocessor())
1114 printk(KERN_NOTICE "Local APIC not detected."
1115 " Using dummy APIC emulation.\n");
1116 map_cpu_to_logical_apicid();
1117 cpu_set(0, cpu_sibling_map[0]);
1118 cpu_set(0, cpu_core_map[0]);
1119 return;
1120 }
1121
1122 /*
1123 * Should not be necessary because the MP table should list the boot
1124 * CPU too, but we do it for the sake of robustness anyway.
1125 * Makes no sense to do this check in clustered apic mode, so skip it
1126 */
1127 if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
1128 printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
1129 boot_cpu_physical_apicid);
1130 physid_set(hard_smp_processor_id(), phys_cpu_present_map);
1131 }
1132
1133 /*
1134 * If we couldn't find a local APIC, then get out of here now!
1135 */
1136 if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid]) && !cpu_has_apic) {
1137 printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
1138 boot_cpu_physical_apicid);
1139 printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
1140 smpboot_clear_io_apic_irqs();
1141 phys_cpu_present_map = physid_mask_of_physid(0);
1142 cpu_set(0, cpu_sibling_map[0]);
1143 cpu_set(0, cpu_core_map[0]);
1123 return; 1144 return;
1124 } 1145 }
1125 1146
1147 verify_local_APIC();
1148
1126 /* 1149 /*
1127 * If SMP should be disabled, then really disable it! 1150 * If SMP should be disabled, then really disable it!
1128 */ 1151 */
1129 if (!max_cpus || (enable_local_apic < 0)) { 1152 if (!max_cpus) {
1130 printk(KERN_INFO "SMP mode deactivated.\n"); 1153 smp_found_config = 0;
1131 disable_smp(); 1154 printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
1155 smpboot_clear_io_apic_irqs();
1156 phys_cpu_present_map = physid_mask_of_physid(0);
1157 cpu_set(0, cpu_sibling_map[0]);
1158 cpu_set(0, cpu_core_map[0]);
1132 return; 1159 return;
1133 } 1160 }
1134 1161
1162 connect_bsp_APIC();
1163 setup_local_APIC();
1164 map_cpu_to_logical_apicid();
1165
1166
1135 setup_portio_remap(); 1167 setup_portio_remap();
1136 1168
1137 /* 1169 /*
@@ -1212,6 +1244,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1212 cpu_set(0, cpu_sibling_map[0]); 1244 cpu_set(0, cpu_sibling_map[0]);
1213 cpu_set(0, cpu_core_map[0]); 1245 cpu_set(0, cpu_core_map[0]);
1214 1246
1247 smpboot_setup_io_apic();
1248
1249 setup_boot_APIC_clock();
1250
1215 /* 1251 /*
1216 * Synchronize the TSC with the AP 1252 * Synchronize the TSC with the AP
1217 */ 1253 */