aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/kernel/apic.c77
-rw-r--r--arch/i386/kernel/i8259.c4
-rw-r--r--arch/i386/kernel/io_apic.c6
-rw-r--r--arch/i386/kernel/smpboot.c68
-rw-r--r--arch/i386/kernel/time.c12
-rw-r--r--include/asm-i386/apic.h3
-rw-r--r--include/asm-i386/hw_irq.h1
-rw-r--r--include/asm-i386/mach-default/smpboot_hooks.h15
-rw-r--r--include/asm-i386/mach-visws/smpboot_hooks.h7
-rw-r--r--init/main.c11
10 files changed, 104 insertions, 100 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
804void __init init_apic_mappings(void) 804void __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 */
1264int __init APIC_init(void) 1261int __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
1320void __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
2394void __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;
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 */
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
441device_initcall(time_init_device); 441device_initcall(time_init_device);
442 442
443extern void (*late_time_init)(void);
444#ifdef CONFIG_HPET_TIMER 443#ifdef CONFIG_HPET_TIMER
444extern 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 */
446static void __init hpet_time_init(void) 446static 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}
diff --git a/include/asm-i386/apic.h b/include/asm-i386/apic.h
index a515e2aed829..8c454aa58ac6 100644
--- a/include/asm-i386/apic.h
+++ b/include/asm-i386/apic.h
@@ -118,8 +118,7 @@ extern void release_lapic_nmi(void);
118extern void disable_timer_nmi_watchdog(void); 118extern void disable_timer_nmi_watchdog(void);
119extern void enable_timer_nmi_watchdog(void); 119extern void enable_timer_nmi_watchdog(void);
120extern void nmi_watchdog_tick (struct pt_regs * regs); 120extern void nmi_watchdog_tick (struct pt_regs * regs);
121extern int APIC_init(void); 121extern int APIC_init_uniprocessor (void);
122extern void APIC_late_time_init(void);
123extern void disable_APIC_timer(void); 122extern void disable_APIC_timer(void);
124extern void enable_APIC_timer(void); 123extern void enable_APIC_timer(void);
125 124
diff --git a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h
index 9139b89497a1..622815bf3243 100644
--- a/include/asm-i386/hw_irq.h
+++ b/include/asm-i386/hw_irq.h
@@ -55,7 +55,6 @@ void init_8259A(int aeoi);
55void FASTCALL(send_IPI_self(int vector)); 55void FASTCALL(send_IPI_self(int vector));
56void init_VISWS_APIC_irqs(void); 56void init_VISWS_APIC_irqs(void);
57void setup_IO_APIC(void); 57void setup_IO_APIC(void);
58void IO_APIC_late_time_init(void);
59void disable_IO_APIC(void); 58void disable_IO_APIC(void);
60void print_IO_APIC(void); 59void print_IO_APIC(void);
61int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn); 60int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
diff --git a/include/asm-i386/mach-default/smpboot_hooks.h b/include/asm-i386/mach-default/smpboot_hooks.h
index d7c70c144f9f..7f45f6311059 100644
--- a/include/asm-i386/mach-default/smpboot_hooks.h
+++ b/include/asm-i386/mach-default/smpboot_hooks.h
@@ -1,6 +1,11 @@
1/* two abstractions specific to kernel/smpboot.c, mainly to cater to visws 1/* two abstractions specific to kernel/smpboot.c, mainly to cater to visws
2 * which needs to alter them. */ 2 * which needs to alter them. */
3 3
4static inline void smpboot_clear_io_apic_irqs(void)
5{
6 io_apic_irqs = 0;
7}
8
4static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) 9static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
5{ 10{
6 CMOS_WRITE(0xa, 0xf); 11 CMOS_WRITE(0xa, 0xf);
@@ -27,3 +32,13 @@ static inline void smpboot_restore_warm_reset_vector(void)
27 32
28 *((volatile long *) phys_to_virt(0x467)) = 0; 33 *((volatile long *) phys_to_virt(0x467)) = 0;
29} 34}
35
36static inline void smpboot_setup_io_apic(void)
37{
38 /*
39 * Here we can be sure that there is an IO-APIC in the system. Let's
40 * go and set it up:
41 */
42 if (!skip_ioapic_setup && nr_ioapics)
43 setup_IO_APIC();
44}
diff --git a/include/asm-i386/mach-visws/smpboot_hooks.h b/include/asm-i386/mach-visws/smpboot_hooks.h
index 14d8e0375f7a..d926471fa359 100644
--- a/include/asm-i386/mach-visws/smpboot_hooks.h
+++ b/include/asm-i386/mach-visws/smpboot_hooks.h
@@ -11,7 +11,14 @@ static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
11 11
12/* for visws do nothing for any of these */ 12/* for visws do nothing for any of these */
13 13
14static inline void smpboot_clear_io_apic_irqs(void)
15{
16}
17
14static inline void smpboot_restore_warm_reset_vector(void) 18static inline void smpboot_restore_warm_reset_vector(void)
15{ 19{
16} 20}
17 21
22static inline void smpboot_setup_io_apic(void)
23{
24}
diff --git a/init/main.c b/init/main.c
index 4075d97e94b1..f142d4035341 100644
--- a/init/main.c
+++ b/init/main.c
@@ -64,6 +64,10 @@
64#endif 64#endif
65#endif 65#endif
66 66
67#ifdef CONFIG_X86_LOCAL_APIC
68#include <asm/smp.h>
69#endif
70
67/* 71/*
68 * Versions of gcc older than that listed below may actually compile 72 * Versions of gcc older than that listed below may actually compile
69 * and link okay, but the end product can have subtle run time bugs. 73 * and link okay, but the end product can have subtle run time bugs.
@@ -310,7 +314,14 @@ extern void setup_arch(char **);
310 314
311#ifndef CONFIG_SMP 315#ifndef CONFIG_SMP
312 316
317#ifdef CONFIG_X86_LOCAL_APIC
318static void __init smp_init(void)
319{
320 APIC_init_uniprocessor();
321}
322#else
313#define smp_init() do { } while (0) 323#define smp_init() do { } while (0)
324#endif
314 325
315static inline void setup_per_cpu_areas(void) { } 326static inline void setup_per_cpu_areas(void) { }
316static inline void smp_prepare_cpus(unsigned int maxcpus) { } 327static inline void smp_prepare_cpus(unsigned int maxcpus) { }