diff options
| author | Jeff Garzik <jgarzik@pobox.com> | 2005-11-05 15:37:24 -0500 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-11-05 15:37:24 -0500 |
| commit | d40d9d29c020f8466c96f8e3ad4b7c014ff1085d (patch) | |
| tree | cb30b4e80f37e0d734a826aa6b29394f46123f9f /arch/i386/kernel | |
| parent | 96a71d52bb91d9b386a60f904956420f98946dd3 (diff) | |
| parent | 70d9d825e0a5a78ec1dacaaaf5c72ff5b0206fab (diff) | |
Merge branch 'master'
Diffstat (limited to 'arch/i386/kernel')
| -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 | } |
