Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Revert "i386: move apic init in init_IRQs"

Commit f2b36db692b7ff6972320ad9839ae656a3b0ee3e causes a bootup hang on
at least one machine. Revert for now until we understand why. The old
code may be ugly, but it works.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>

+106 -102
+17 -62
arch/i386/kernel/apic.c
··· 803 803 804 804 void __init init_apic_mappings(void) 805 805 { 806 - unsigned int orig_apicid; 807 806 unsigned long apic_phys; 808 807 809 808 /* ··· 824 825 * Fetch the APIC ID of the BSP in case we have a 825 826 * default configuration (or the MP table is broken). 826 827 */ 827 - orig_apicid = boot_cpu_physical_apicid; 828 - boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); 829 - if ((orig_apicid != -1U) && (orig_apicid != boot_cpu_physical_apicid)) 830 - printk(KERN_WARNING "Boot APIC ID in local APIC unexpected (%d vs %d)", 831 - orig_apicid, boot_cpu_physical_apicid); 828 + if (boot_cpu_physical_apicid == -1U) 829 + boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); 832 830 833 831 #ifdef CONFIG_X86_IO_APIC 834 832 { ··· 1255 1259 } 1256 1260 1257 1261 /* 1258 - * This initializes the IO-APIC and APIC hardware. 1262 + * This initializes the IO-APIC and APIC hardware if this is 1263 + * a UP kernel. 1259 1264 */ 1260 - int __init APIC_init(void) 1265 + int __init APIC_init_uniprocessor (void) 1261 1266 { 1262 - if (enable_local_apic < 0) { 1263 - printk(KERN_INFO "APIC disabled\n"); 1264 - return -1; 1265 - } 1267 + if (enable_local_apic < 0) 1268 + clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); 1266 1269 1267 - /* See if we have a SMP configuration or have forced enabled 1268 - * the local apic. 1269 - */ 1270 - if (!smp_found_config && !acpi_lapic && !cpu_has_apic) { 1271 - enable_local_apic = -1; 1270 + if (!smp_found_config && !cpu_has_apic) 1272 1271 return -1; 1273 - } 1274 1272 1275 1273 /* 1276 - * Complain if the BIOS pretends there is an apic. 1277 - * Then get out because we don't have an a local apic. 1274 + * Complain if the BIOS pretends there is one. 1278 1275 */ 1279 1276 if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { 1280 1277 printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", 1281 1278 boot_cpu_physical_apicid); 1282 - printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); 1283 - enable_local_apic = -1; 1284 1279 return -1; 1285 1280 } 1286 1281 1287 1282 verify_local_APIC(); 1288 1283 1289 - /* 1290 - * Should not be necessary because the MP table should list the boot 1291 - * CPU too, but we do it for the sake of robustness anyway. 1292 - * Makes no sense to do this check in clustered apic mode, so skip it 1293 - */ 1294 - if (!check_phys_apicid_present(boot_cpu_physical_apicid)) { 1295 - printk("weird, boot CPU (#%d) not listed by the BIOS.\n", 1296 - boot_cpu_physical_apicid); 1297 - physid_set(boot_cpu_physical_apicid, phys_cpu_present_map); 1298 - } 1299 - 1300 - /* 1301 - * Switch from PIC to APIC mode. 1302 - */ 1303 1284 connect_bsp_APIC(); 1285 + 1286 + phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid); 1287 + 1304 1288 setup_local_APIC(); 1305 1289 1306 1290 #ifdef CONFIG_X86_IO_APIC 1307 - /* 1308 - * Now start the IO-APICs 1309 - */ 1310 - if (smp_found_config && !skip_ioapic_setup && nr_ioapics) 1311 - setup_IO_APIC(); 1312 - #endif 1313 - return 0; 1314 - } 1315 - 1316 - void __init APIC_late_time_init(void) 1317 - { 1318 - /* Improve our loops per jiffy estimate */ 1319 - loops_per_jiffy = ((1000 + HZ - 1)/HZ)*cpu_khz; 1320 - boot_cpu_data.loops_per_jiffy = loops_per_jiffy; 1321 - cpu_data[0].loops_per_jiffy = loops_per_jiffy; 1322 - 1323 - /* setup_apic_nmi_watchdog doesn't work properly before cpu_khz is 1324 - * initialized. So redo it here to ensure the boot cpu is setup 1325 - * properly. 1326 - */ 1327 - if (nmi_watchdog == NMI_LOCAL_APIC) 1328 - setup_apic_nmi_watchdog(); 1329 - 1330 - #ifdef CONFIG_X86_IO_APIC 1331 - if (smp_found_config && !skip_ioapic_setup && nr_ioapics) 1332 - IO_APIC_late_time_init(); 1291 + if (smp_found_config) 1292 + if (!skip_ioapic_setup && nr_ioapics) 1293 + setup_IO_APIC(); 1333 1294 #endif 1334 1295 setup_boot_APIC_clock(); 1296 + 1297 + return 0; 1335 1298 }
-4
arch/i386/kernel/i8259.c
··· 435 435 setup_irq(FPU_IRQ, &fpu_irq); 436 436 437 437 irq_ctx_init(smp_processor_id()); 438 - 439 - #ifdef CONFIG_X86_LOCAL_APIC 440 - APIC_init(); 441 - #endif 442 438 }
+1 -5
arch/i386/kernel/io_apic.c
··· 2387 2387 sync_Arb_IDs(); 2388 2388 setup_IO_APIC_irqs(); 2389 2389 init_IO_APIC_traps(); 2390 + check_timer(); 2390 2391 if (!acpi_ioapic) 2391 2392 print_IO_APIC(); 2392 - } 2393 - 2394 - void __init IO_APIC_late_time_init(void) 2395 - { 2396 - check_timer(); 2397 2393 } 2398 2394 2399 2395 /*
+53 -17
arch/i386/kernel/smpboot.c
··· 1078 1078 EXPORT_SYMBOL(xquad_portio); 1079 1079 #endif 1080 1080 1081 - /* 1082 - * Fall back to non SMP mode after errors. 1083 - * 1084 - */ 1085 - static __init void disable_smp(void) 1086 - { 1087 - cpu_set(0, cpu_sibling_map[0]); 1088 - cpu_set(0, cpu_core_map[0]); 1089 - } 1090 - 1091 1081 static void __init smp_boot_cpus(unsigned int max_cpus) 1092 1082 { 1093 1083 int apicid, cpu, bit, kicked; ··· 1090 1100 printk("CPU%d: ", 0); 1091 1101 print_cpu_info(&cpu_data[0]); 1092 1102 1103 + boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); 1093 1104 boot_cpu_logical_apicid = logical_smp_processor_id(); 1094 1105 x86_cpu_to_apicid[0] = boot_cpu_physical_apicid; 1095 1106 ··· 1102 1111 cpus_clear(cpu_core_map[0]); 1103 1112 cpu_set(0, cpu_core_map[0]); 1104 1113 1105 - map_cpu_to_logical_apicid(); 1106 - 1107 1114 /* 1108 1115 * If we couldn't find an SMP configuration at boot time, 1109 1116 * get out of here now! 1110 1117 */ 1111 1118 if (!smp_found_config && !acpi_lapic) { 1112 1119 printk(KERN_NOTICE "SMP motherboard not detected.\n"); 1113 - disable_smp(); 1120 + smpboot_clear_io_apic_irqs(); 1121 + phys_cpu_present_map = physid_mask_of_physid(0); 1122 + if (APIC_init_uniprocessor()) 1123 + printk(KERN_NOTICE "Local APIC not detected." 1124 + " Using dummy APIC emulation.\n"); 1125 + map_cpu_to_logical_apicid(); 1126 + cpu_set(0, cpu_sibling_map[0]); 1127 + cpu_set(0, cpu_core_map[0]); 1114 1128 return; 1115 1129 } 1116 1130 1117 1131 /* 1118 - * If SMP should be disabled, then really disable it! 1132 + * Should not be necessary because the MP table should list the boot 1133 + * CPU too, but we do it for the sake of robustness anyway. 1134 + * Makes no sense to do this check in clustered apic mode, so skip it 1119 1135 */ 1120 - if (!max_cpus || (enable_local_apic < 0)) { 1121 - printk(KERN_INFO "SMP mode deactivated.\n"); 1122 - disable_smp(); 1136 + if (!check_phys_apicid_present(boot_cpu_physical_apicid)) { 1137 + printk("weird, boot CPU (#%d) not listed by the BIOS.\n", 1138 + boot_cpu_physical_apicid); 1139 + physid_set(hard_smp_processor_id(), phys_cpu_present_map); 1140 + } 1141 + 1142 + /* 1143 + * If we couldn't find a local APIC, then get out of here now! 1144 + */ 1145 + if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid]) && !cpu_has_apic) { 1146 + printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", 1147 + boot_cpu_physical_apicid); 1148 + printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); 1149 + smpboot_clear_io_apic_irqs(); 1150 + phys_cpu_present_map = physid_mask_of_physid(0); 1151 + cpu_set(0, cpu_sibling_map[0]); 1152 + cpu_set(0, cpu_core_map[0]); 1123 1153 return; 1124 1154 } 1155 + 1156 + verify_local_APIC(); 1157 + 1158 + /* 1159 + * If SMP should be disabled, then really disable it! 1160 + */ 1161 + if (!max_cpus) { 1162 + smp_found_config = 0; 1163 + printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); 1164 + smpboot_clear_io_apic_irqs(); 1165 + phys_cpu_present_map = physid_mask_of_physid(0); 1166 + cpu_set(0, cpu_sibling_map[0]); 1167 + cpu_set(0, cpu_core_map[0]); 1168 + return; 1169 + } 1170 + 1171 + connect_bsp_APIC(); 1172 + setup_local_APIC(); 1173 + map_cpu_to_logical_apicid(); 1174 + 1125 1175 1126 1176 setup_portio_remap(); 1127 1177 ··· 1243 1211 1244 1212 cpu_set(0, cpu_sibling_map[0]); 1245 1213 cpu_set(0, cpu_core_map[0]); 1214 + 1215 + smpboot_setup_io_apic(); 1216 + 1217 + setup_boot_APIC_clock(); 1246 1218 1247 1219 /* 1248 1220 * Synchronize the TSC with the AP
+1 -11
arch/i386/kernel/time.c
··· 440 440 441 441 device_initcall(time_init_device); 442 442 443 - extern void (*late_time_init)(void); 444 443 #ifdef CONFIG_HPET_TIMER 444 + extern void (*late_time_init)(void); 445 445 /* Duplicate of time_init() below, with hpet_enable part added */ 446 446 static void __init hpet_time_init(void) 447 447 { ··· 458 458 printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name); 459 459 460 460 time_init_hook(); 461 - 462 - #ifdef CONFIG_X86_LOCAL_APIC 463 - if (enable_local_apic >= 0) 464 - APIC_late_time_init(); 465 - #endif 466 461 } 467 462 #endif 468 463 ··· 482 487 printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name); 483 488 484 489 time_init_hook(); 485 - 486 - #ifdef CONFIG_X86_LOCAL_APIC 487 - if (enable_local_apic >= 0) 488 - late_time_init = APIC_late_time_init; 489 - #endif 490 490 }
+1 -2
include/asm-i386/apic.h
··· 118 118 extern void disable_timer_nmi_watchdog(void); 119 119 extern void enable_timer_nmi_watchdog(void); 120 120 extern void nmi_watchdog_tick (struct pt_regs * regs); 121 - extern int APIC_init(void); 122 - extern void APIC_late_time_init(void); 121 + extern int APIC_init_uniprocessor (void); 123 122 extern void disable_APIC_timer(void); 124 123 extern void enable_APIC_timer(void); 125 124
-1
include/asm-i386/hw_irq.h
··· 55 55 void FASTCALL(send_IPI_self(int vector)); 56 56 void init_VISWS_APIC_irqs(void); 57 57 void setup_IO_APIC(void); 58 - void IO_APIC_late_time_init(void); 59 58 void disable_IO_APIC(void); 60 59 void print_IO_APIC(void); 61 60 int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
+15
include/asm-i386/mach-default/smpboot_hooks.h
··· 1 1 /* two abstractions specific to kernel/smpboot.c, mainly to cater to visws 2 2 * which needs to alter them. */ 3 3 4 + static inline void smpboot_clear_io_apic_irqs(void) 5 + { 6 + io_apic_irqs = 0; 7 + } 8 + 4 9 static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) 5 10 { 6 11 CMOS_WRITE(0xa, 0xf); ··· 31 26 CMOS_WRITE(0, 0xf); 32 27 33 28 *((volatile long *) phys_to_virt(0x467)) = 0; 29 + } 30 + 31 + static inline void smpboot_setup_io_apic(void) 32 + { 33 + /* 34 + * Here we can be sure that there is an IO-APIC in the system. Let's 35 + * go and set it up: 36 + */ 37 + if (!skip_ioapic_setup && nr_ioapics) 38 + setup_IO_APIC(); 34 39 }
+7
include/asm-i386/mach-visws/smpboot_hooks.h
··· 11 11 12 12 /* for visws do nothing for any of these */ 13 13 14 + static inline void smpboot_clear_io_apic_irqs(void) 15 + { 16 + } 17 + 14 18 static inline void smpboot_restore_warm_reset_vector(void) 15 19 { 16 20 } 17 21 22 + static inline void smpboot_setup_io_apic(void) 23 + { 24 + }
+11
init/main.c
··· 64 64 #endif 65 65 #endif 66 66 67 + #ifdef CONFIG_X86_LOCAL_APIC 68 + #include <asm/smp.h> 69 + #endif 70 + 67 71 /* 68 72 * Versions of gcc older than that listed below may actually compile 69 73 * and link okay, but the end product can have subtle run time bugs. ··· 314 310 315 311 #ifndef CONFIG_SMP 316 312 313 + #ifdef CONFIG_X86_LOCAL_APIC 314 + static void __init smp_init(void) 315 + { 316 + APIC_init_uniprocessor(); 317 + } 318 + #else 317 319 #define smp_init() do { } while (0) 320 + #endif 318 321 319 322 static inline void setup_per_cpu_areas(void) { } 320 323 static inline void smp_prepare_cpus(unsigned int maxcpus) { }