diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/kernel/apic.c | 77 | ||||
-rw-r--r-- | arch/i386/kernel/i8259.c | 4 | ||||
-rw-r--r-- | arch/i386/kernel/io_apic.c | 6 | ||||
-rw-r--r-- | arch/i386/kernel/smpboot.c | 68 | ||||
-rw-r--r-- | arch/i386/kernel/time.c | 12 |
5 files changed, 70 insertions, 97 deletions
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 9204be6eedb3..7c724ffa08bb 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c | |||
@@ -803,7 +803,6 @@ no_apic: | |||
803 | 803 | ||
804 | void __init init_apic_mappings(void) | 804 | void __init init_apic_mappings(void) |
805 | { | 805 | { |
806 | unsigned int orig_apicid; | ||
807 | unsigned long apic_phys; | 806 | unsigned long apic_phys; |
808 | 807 | ||
809 | /* | 808 | /* |
@@ -825,11 +824,8 @@ void __init init_apic_mappings(void) | |||
825 | * Fetch the APIC ID of the BSP in case we have a | 824 | * Fetch the APIC ID of the BSP in case we have a |
826 | * default configuration (or the MP table is broken). | 825 | * default configuration (or the MP table is broken). |
827 | */ | 826 | */ |
828 | orig_apicid = boot_cpu_physical_apicid; | 827 | if (boot_cpu_physical_apicid == -1U) |
829 | boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); | 828 | boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); |
830 | if ((orig_apicid != -1U) && (orig_apicid != boot_cpu_physical_apicid)) | ||
831 | printk(KERN_WARNING "Boot APIC ID in local APIC unexpected (%d vs %d)", | ||
832 | orig_apicid, boot_cpu_physical_apicid); | ||
833 | 829 | ||
834 | #ifdef CONFIG_X86_IO_APIC | 830 | #ifdef CONFIG_X86_IO_APIC |
835 | { | 831 | { |
@@ -1259,81 +1255,40 @@ fastcall void smp_error_interrupt(struct pt_regs *regs) | |||
1259 | } | 1255 | } |
1260 | 1256 | ||
1261 | /* | 1257 | /* |
1262 | * This initializes the IO-APIC and APIC hardware. | 1258 | * This initializes the IO-APIC and APIC hardware if this is |
1259 | * a UP kernel. | ||
1263 | */ | 1260 | */ |
1264 | int __init APIC_init(void) | 1261 | int __init APIC_init_uniprocessor (void) |
1265 | { | 1262 | { |
1266 | if (enable_local_apic < 0) { | 1263 | if (enable_local_apic < 0) |
1267 | printk(KERN_INFO "APIC disabled\n"); | 1264 | clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); |
1268 | return -1; | ||
1269 | } | ||
1270 | 1265 | ||
1271 | /* See if we have a SMP configuration or have forced enabled | 1266 | if (!smp_found_config && !cpu_has_apic) |
1272 | * the local apic. | ||
1273 | */ | ||
1274 | if (!smp_found_config && !acpi_lapic && !cpu_has_apic) { | ||
1275 | enable_local_apic = -1; | ||
1276 | return -1; | 1267 | return -1; |
1277 | } | ||
1278 | 1268 | ||
1279 | /* | 1269 | /* |
1280 | * Complain if the BIOS pretends there is an apic. | 1270 | * Complain if the BIOS pretends there is one. |
1281 | * Then get out because we don't have an a local apic. | ||
1282 | */ | 1271 | */ |
1283 | if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { | 1272 | if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { |
1284 | printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", | 1273 | printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", |
1285 | boot_cpu_physical_apicid); | 1274 | boot_cpu_physical_apicid); |
1286 | printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); | ||
1287 | enable_local_apic = -1; | ||
1288 | return -1; | 1275 | return -1; |
1289 | } | 1276 | } |
1290 | 1277 | ||
1291 | verify_local_APIC(); | 1278 | verify_local_APIC(); |
1292 | 1279 | ||
1293 | /* | ||
1294 | * Should not be necessary because the MP table should list the boot | ||
1295 | * CPU too, but we do it for the sake of robustness anyway. | ||
1296 | * Makes no sense to do this check in clustered apic mode, so skip it | ||
1297 | */ | ||
1298 | if (!check_phys_apicid_present(boot_cpu_physical_apicid)) { | ||
1299 | printk("weird, boot CPU (#%d) not listed by the BIOS.\n", | ||
1300 | boot_cpu_physical_apicid); | ||
1301 | physid_set(boot_cpu_physical_apicid, phys_cpu_present_map); | ||
1302 | } | ||
1303 | |||
1304 | /* | ||
1305 | * Switch from PIC to APIC mode. | ||
1306 | */ | ||
1307 | connect_bsp_APIC(); | 1280 | connect_bsp_APIC(); |
1308 | setup_local_APIC(); | ||
1309 | 1281 | ||
1310 | #ifdef CONFIG_X86_IO_APIC | 1282 | phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid); |
1311 | /* | ||
1312 | * Now start the IO-APICs | ||
1313 | */ | ||
1314 | if (smp_found_config && !skip_ioapic_setup && nr_ioapics) | ||
1315 | setup_IO_APIC(); | ||
1316 | #endif | ||
1317 | return 0; | ||
1318 | } | ||
1319 | 1283 | ||
1320 | void __init APIC_late_time_init(void) | 1284 | setup_local_APIC(); |
1321 | { | ||
1322 | /* Improve our loops per jiffy estimate */ | ||
1323 | loops_per_jiffy = ((1000 + HZ - 1)/HZ)*cpu_khz; | ||
1324 | boot_cpu_data.loops_per_jiffy = loops_per_jiffy; | ||
1325 | cpu_data[0].loops_per_jiffy = loops_per_jiffy; | ||
1326 | |||
1327 | /* setup_apic_nmi_watchdog doesn't work properly before cpu_khz is | ||
1328 | * initialized. So redo it here to ensure the boot cpu is setup | ||
1329 | * properly. | ||
1330 | */ | ||
1331 | if (nmi_watchdog == NMI_LOCAL_APIC) | ||
1332 | setup_apic_nmi_watchdog(); | ||
1333 | 1285 | ||
1334 | #ifdef CONFIG_X86_IO_APIC | 1286 | #ifdef CONFIG_X86_IO_APIC |
1335 | if (smp_found_config && !skip_ioapic_setup && nr_ioapics) | 1287 | if (smp_found_config) |
1336 | IO_APIC_late_time_init(); | 1288 | if (!skip_ioapic_setup && nr_ioapics) |
1289 | setup_IO_APIC(); | ||
1337 | #endif | 1290 | #endif |
1338 | setup_boot_APIC_clock(); | 1291 | setup_boot_APIC_clock(); |
1292 | |||
1293 | return 0; | ||
1339 | } | 1294 | } |
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c index d86f24909284..323ef8ab3244 100644 --- a/arch/i386/kernel/i8259.c +++ b/arch/i386/kernel/i8259.c | |||
@@ -435,8 +435,4 @@ void __init init_IRQ(void) | |||
435 | setup_irq(FPU_IRQ, &fpu_irq); | 435 | setup_irq(FPU_IRQ, &fpu_irq); |
436 | 436 | ||
437 | irq_ctx_init(smp_processor_id()); | 437 | irq_ctx_init(smp_processor_id()); |
438 | |||
439 | #ifdef CONFIG_X86_LOCAL_APIC | ||
440 | APIC_init(); | ||
441 | #endif | ||
442 | } | 438 | } |
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 5a77c52b20a9..cc5d7ac5b2e7 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -2387,15 +2387,11 @@ void __init setup_IO_APIC(void) | |||
2387 | sync_Arb_IDs(); | 2387 | sync_Arb_IDs(); |
2388 | setup_IO_APIC_irqs(); | 2388 | setup_IO_APIC_irqs(); |
2389 | init_IO_APIC_traps(); | 2389 | init_IO_APIC_traps(); |
2390 | check_timer(); | ||
2390 | if (!acpi_ioapic) | 2391 | if (!acpi_ioapic) |
2391 | print_IO_APIC(); | 2392 | print_IO_APIC(); |
2392 | } | 2393 | } |
2393 | 2394 | ||
2394 | void __init IO_APIC_late_time_init(void) | ||
2395 | { | ||
2396 | check_timer(); | ||
2397 | } | ||
2398 | |||
2399 | /* | 2395 | /* |
2400 | * Called after all the initialization is done. If we didnt find any | 2396 | * Called after all the initialization is done. If we didnt find any |
2401 | * APIC bugs then we can allow the modify fast path | 2397 | * APIC bugs then we can allow the modify fast path |
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; | |||
1078 | EXPORT_SYMBOL(xquad_portio); | 1078 | EXPORT_SYMBOL(xquad_portio); |
1079 | #endif | 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 | static void __init smp_boot_cpus(unsigned int max_cpus) | 1081 | static 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 | */ |
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index 07471bba2dc6..41c5b2dc6200 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c | |||
@@ -440,8 +440,8 @@ static int time_init_device(void) | |||
440 | 440 | ||
441 | device_initcall(time_init_device); | 441 | device_initcall(time_init_device); |
442 | 442 | ||
443 | extern void (*late_time_init)(void); | ||
444 | #ifdef CONFIG_HPET_TIMER | 443 | #ifdef CONFIG_HPET_TIMER |
444 | extern void (*late_time_init)(void); | ||
445 | /* Duplicate of time_init() below, with hpet_enable part added */ | 445 | /* Duplicate of time_init() below, with hpet_enable part added */ |
446 | static void __init hpet_time_init(void) | 446 | static void __init hpet_time_init(void) |
447 | { | 447 | { |
@@ -458,11 +458,6 @@ static void __init hpet_time_init(void) | |||
458 | printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name); | 458 | printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name); |
459 | 459 | ||
460 | time_init_hook(); | 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 | #endif | 462 | #endif |
468 | 463 | ||
@@ -487,9 +482,4 @@ void __init time_init(void) | |||
487 | printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name); | 482 | printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name); |
488 | 483 | ||
489 | time_init_hook(); | 484 | time_init_hook(); |
490 | |||
491 | #ifdef CONFIG_X86_LOCAL_APIC | ||
492 | if (enable_local_apic >= 0) | ||
493 | late_time_init = APIC_late_time_init; | ||
494 | #endif | ||
495 | } | 485 | } |