blob: 73f7e8b9543aa55051e6a912e231db6ad6c8aa3b [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * x86 SMP booting functions
3 *
4 * (c) 1995 Alan Cox, Building #3 <alan@redhat.com>
5 * (c) 1998, 1999, 2000 Ingo Molnar <mingo@redhat.com>
6 * Copyright 2001 Andi Kleen, SuSE Labs.
7 *
8 * Much of the core SMP work is based on previous work by Thomas Radke, to
9 * whom a great many thanks are extended.
10 *
11 * Thanks to Intel for making available several different Pentium,
12 * Pentium Pro and Pentium-II/Xeon MP machines.
13 * Original development of Linux SMP code supported by Caldera.
14 *
Andi Kleena8ab26f2005-04-16 15:25:19 -070015 * This code is released under the GNU General Public License version 2
Linus Torvalds1da177e2005-04-16 15:20:36 -070016 *
17 * Fixes
18 * Felix Koop : NR_CPUS used properly
19 * Jose Renau : Handle single CPU case.
20 * Alan Cox : By repeated request 8) - Total BogoMIP report.
21 * Greg Wright : Fix for kernel stacks panic.
22 * Erich Boleyn : MP v1.4 and additional changes.
23 * Matthias Sattler : Changes for 2.1 kernel map.
24 * Michel Lespinasse : Changes for 2.1 kernel map.
25 * Michael Chastain : Change trampoline.S to gnu as.
26 * Alan Cox : Dumb bug: 'B' step PPro's are fine
27 * Ingo Molnar : Added APIC timers, based on code
28 * from Jose Renau
29 * Ingo Molnar : various cleanups and rewrites
30 * Tigran Aivazian : fixed "0.00 in /proc/uptime on SMP" bug.
31 * Maciej W. Rozycki : Bits for genuine 82489DX APICs
32 * Andi Kleen : Changed for SMP boot into long mode.
Andi Kleena8ab26f2005-04-16 15:25:19 -070033 * Rusty Russell : Hacked into shape for new "hotplug" boot process.
34 * Andi Kleen : Converted to new state machine.
35 * Various cleanups.
36 * Probably mostly hotplug CPU ready now.
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 */
38
Andi Kleena8ab26f2005-04-16 15:25:19 -070039
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#include <linux/config.h>
41#include <linux/init.h>
42
43#include <linux/mm.h>
44#include <linux/kernel_stat.h>
45#include <linux/smp_lock.h>
46#include <linux/irq.h>
47#include <linux/bootmem.h>
48#include <linux/thread_info.h>
49#include <linux/module.h>
50
51#include <linux/delay.h>
52#include <linux/mc146818rtc.h>
53#include <asm/mtrr.h>
54#include <asm/pgalloc.h>
55#include <asm/desc.h>
56#include <asm/kdebug.h>
57#include <asm/tlbflush.h>
58#include <asm/proto.h>
59
Andi Kleena8ab26f2005-04-16 15:25:19 -070060/* Change for real CPU hotplug. Note other files need to be fixed
61 first too. */
62#define __cpuinit __init
63#define __cpuinitdata __initdata
64
Linus Torvalds1da177e2005-04-16 15:20:36 -070065/* Number of siblings per CPU package */
66int smp_num_siblings = 1;
67/* Package ID of each logical CPU */
68u8 phys_proc_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
Andi Kleen3dd9d512005-04-16 15:25:15 -070069u8 cpu_core_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
Linus Torvalds1da177e2005-04-16 15:20:36 -070070EXPORT_SYMBOL(phys_proc_id);
Andi Kleen3dd9d512005-04-16 15:25:15 -070071EXPORT_SYMBOL(cpu_core_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -070072
73/* Bitmask of currently online CPUs */
74cpumask_t cpu_online_map;
75
Andi Kleena8ab26f2005-04-16 15:25:19 -070076EXPORT_SYMBOL(cpu_online_map);
77
78/*
79 * Private maps to synchronize booting between AP and BP.
80 * Probably not needed anymore, but it makes for easier debugging. -AK
81 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070082cpumask_t cpu_callin_map;
83cpumask_t cpu_callout_map;
Andi Kleena8ab26f2005-04-16 15:25:19 -070084
85cpumask_t cpu_possible_map;
86EXPORT_SYMBOL(cpu_possible_map);
Linus Torvalds1da177e2005-04-16 15:20:36 -070087
88/* Per CPU bogomips and other parameters */
89struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
90
Andi Kleena8ab26f2005-04-16 15:25:19 -070091/* Set when the idlers are all forked */
92int smp_threads_ready;
93
Linus Torvalds1da177e2005-04-16 15:20:36 -070094cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
Andi Kleen3dd9d512005-04-16 15:25:15 -070095cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
97/*
98 * Trampoline 80x86 program as an array.
99 */
100
Andi Kleena8ab26f2005-04-16 15:25:19 -0700101extern unsigned char trampoline_data[];
102extern unsigned char trampoline_end[];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103
104/*
105 * Currently trivial. Write the real->protected mode
106 * bootstrap into the page concerned. The caller
107 * has made sure it's suitably aligned.
108 */
109
Andi Kleena8ab26f2005-04-16 15:25:19 -0700110static unsigned long __cpuinit setup_trampoline(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111{
112 void *tramp = __va(SMP_TRAMPOLINE_BASE);
113 memcpy(tramp, trampoline_data, trampoline_end - trampoline_data);
114 return virt_to_phys(tramp);
115}
116
117/*
118 * The bootstrap kernel entry code has set these up. Save them for
119 * a given CPU
120 */
121
Andi Kleena8ab26f2005-04-16 15:25:19 -0700122static void __cpuinit smp_store_cpu_info(int id)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123{
124 struct cpuinfo_x86 *c = cpu_data + id;
125
126 *c = boot_cpu_data;
127 identify_cpu(c);
128}
129
130/*
Andi Kleena8ab26f2005-04-16 15:25:19 -0700131 * Synchronize TSCs of CPUs
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 *
Andi Kleena8ab26f2005-04-16 15:25:19 -0700133 * This new algorithm is less accurate than the old "zero TSCs"
134 * one, but we cannot zero TSCs anymore in the new hotplug CPU
135 * model.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136 */
137
Andi Kleena8ab26f2005-04-16 15:25:19 -0700138static atomic_t __cpuinitdata tsc_flag;
139static __cpuinitdata DEFINE_SPINLOCK(tsc_sync_lock);
140static unsigned long long __cpuinitdata bp_tsc, ap_tsc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141
142#define NR_LOOPS 5
143
Andi Kleena8ab26f2005-04-16 15:25:19 -0700144static void __cpuinit sync_tsc_bp_init(int init)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145{
Andi Kleena8ab26f2005-04-16 15:25:19 -0700146 if (init)
147 _raw_spin_lock(&tsc_sync_lock);
148 else
149 _raw_spin_unlock(&tsc_sync_lock);
150 atomic_set(&tsc_flag, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151}
152
Andi Kleena8ab26f2005-04-16 15:25:19 -0700153/*
154 * Synchronize TSC on AP with BP.
155 */
156static void __cpuinit __sync_tsc_ap(void)
157{
158 if (!cpu_has_tsc)
159 return;
160 Dprintk("AP %d syncing TSC\n", smp_processor_id());
161
162 while (atomic_read(&tsc_flag) != 0)
163 cpu_relax();
164 atomic_inc(&tsc_flag);
165 mb();
166 _raw_spin_lock(&tsc_sync_lock);
167 wrmsrl(MSR_IA32_TSC, bp_tsc);
168 _raw_spin_unlock(&tsc_sync_lock);
169 rdtscll(ap_tsc);
170 mb();
171 atomic_inc(&tsc_flag);
172 mb();
173}
174
175static void __cpuinit sync_tsc_ap(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176{
177 int i;
Andi Kleena8ab26f2005-04-16 15:25:19 -0700178 for (i = 0; i < NR_LOOPS; i++)
179 __sync_tsc_ap();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181
Andi Kleena8ab26f2005-04-16 15:25:19 -0700182/*
183 * Synchronize TSC from BP to AP.
184 */
185static void __cpuinit __sync_tsc_bp(int cpu)
186{
187 if (!cpu_has_tsc)
188 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189
Andi Kleena8ab26f2005-04-16 15:25:19 -0700190 /* Wait for AP */
191 while (atomic_read(&tsc_flag) == 0)
192 cpu_relax();
193 /* Save BPs TSC */
194 sync_core();
195 rdtscll(bp_tsc);
196 /* Don't do the sync core here to avoid too much latency. */
197 mb();
198 /* Start the AP */
199 _raw_spin_unlock(&tsc_sync_lock);
200 /* Wait for AP again */
201 while (atomic_read(&tsc_flag) < 2)
202 cpu_relax();
203 rdtscl(bp_tsc);
204 barrier();
205}
206
207static void __cpuinit sync_tsc_bp(int cpu)
208{
209 int i;
210 for (i = 0; i < NR_LOOPS - 1; i++) {
211 __sync_tsc_bp(cpu);
212 sync_tsc_bp_init(1);
213 }
214 __sync_tsc_bp(cpu);
215 printk(KERN_INFO "Synced TSC of CPU %d difference %Ld\n",
216 cpu, ap_tsc - bp_tsc);
217}
218
219static atomic_t init_deasserted __cpuinitdata;
220
221/*
222 * Report back to the Boot Processor.
223 * Running on AP.
224 */
225void __cpuinit smp_callin(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226{
227 int cpuid, phys_id;
228 unsigned long timeout;
229
230 /*
231 * If waken up by an INIT in an 82489DX configuration
232 * we may get here before an INIT-deassert IPI reaches
233 * our local APIC. We have to wait for the IPI or we'll
234 * lock up on an APIC access.
235 */
Andi Kleena8ab26f2005-04-16 15:25:19 -0700236 while (!atomic_read(&init_deasserted))
237 cpu_relax();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238
239 /*
240 * (This works even if the APIC is not enabled.)
241 */
242 phys_id = GET_APIC_ID(apic_read(APIC_ID));
243 cpuid = smp_processor_id();
244 if (cpu_isset(cpuid, cpu_callin_map)) {
245 panic("smp_callin: phys CPU#%d, CPU#%d already present??\n",
246 phys_id, cpuid);
247 }
248 Dprintk("CPU#%d (phys ID: %d) waiting for CALLOUT\n", cpuid, phys_id);
249
250 /*
251 * STARTUP IPIs are fragile beasts as they might sometimes
252 * trigger some glue motherboard logic. Complete APIC bus
253 * silence for 1 second, this overestimates the time the
254 * boot CPU is spending to send the up to 2 STARTUP IPIs
255 * by a factor of two. This should be enough.
256 */
257
258 /*
259 * Waiting 2s total for startup (udelay is not yet working)
260 */
261 timeout = jiffies + 2*HZ;
262 while (time_before(jiffies, timeout)) {
263 /*
264 * Has the boot CPU finished it's STARTUP sequence?
265 */
266 if (cpu_isset(cpuid, cpu_callout_map))
267 break;
Andi Kleena8ab26f2005-04-16 15:25:19 -0700268 cpu_relax();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269 }
270
271 if (!time_before(jiffies, timeout)) {
272 panic("smp_callin: CPU%d started up but did not get a callout!\n",
273 cpuid);
274 }
275
276 /*
277 * the boot CPU has finished the init stage and is spinning
278 * on callin_map until we finish. We are free to set up this
279 * CPU, first the APIC. (this is probably redundant on most
280 * boards)
281 */
282
283 Dprintk("CALLIN, before setup_local_APIC().\n");
284 setup_local_APIC();
285
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286 /*
287 * Get our bogomips.
288 */
289 calibrate_delay();
290 Dprintk("Stack at about %p\n",&cpuid);
291
292 disable_APIC_timer();
293
294 /*
295 * Save our processor parameters
296 */
297 smp_store_cpu_info(cpuid);
298
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299 /*
300 * Allow the master to continue.
301 */
302 cpu_set(cpuid, cpu_callin_map);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303}
304
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305/*
Andi Kleena8ab26f2005-04-16 15:25:19 -0700306 * Setup code on secondary processor (after comming out of the trampoline)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307 */
Andi Kleena8ab26f2005-04-16 15:25:19 -0700308void __cpuinit start_secondary(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309{
310 /*
311 * Dont put anything before smp_callin(), SMP
312 * booting is too fragile that we want to limit the
313 * things done here to the most necessary things.
314 */
315 cpu_init();
316 smp_callin();
317
Andi Kleena8ab26f2005-04-16 15:25:19 -0700318 /*
319 * Synchronize the TSC with the BP
320 */
321 sync_tsc_ap();
322
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 /* otherwise gcc will move up the smp_processor_id before the cpu_init */
324 barrier();
325
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 Dprintk("cpu %d: setting up apic clock\n", smp_processor_id());
327 setup_secondary_APIC_clock();
328
Andi Kleena8ab26f2005-04-16 15:25:19 -0700329 Dprintk("cpu %d: enabling apic timer\n", smp_processor_id());
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330
331 if (nmi_watchdog == NMI_IO_APIC) {
332 disable_8259A_irq(0);
333 enable_NMI_through_LVT0(NULL);
334 enable_8259A_irq(0);
335 }
336
337
Andi Kleena8ab26f2005-04-16 15:25:19 -0700338 enable_APIC_timer();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700339
340 /*
Andi Kleena8ab26f2005-04-16 15:25:19 -0700341 * Allow the master to continue.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343 cpu_set(smp_processor_id(), cpu_online_map);
Andi Kleena8ab26f2005-04-16 15:25:19 -0700344 mb();
345
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346 cpu_idle();
347}
348
Andi Kleena8ab26f2005-04-16 15:25:19 -0700349extern volatile unsigned long init_rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350extern void (*initial_code)(void);
351
352#if APIC_DEBUG
Andi Kleena8ab26f2005-04-16 15:25:19 -0700353static void inquire_remote_apic(int apicid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354{
355 unsigned i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 };
356 char *names[] = { "ID", "VERSION", "SPIV" };
357 int timeout, status;
358
359 printk(KERN_INFO "Inquiring remote APIC #%d...\n", apicid);
360
361 for (i = 0; i < sizeof(regs) / sizeof(*regs); i++) {
362 printk("... APIC #%d %s: ", apicid, names[i]);
363
364 /*
365 * Wait for idle.
366 */
367 apic_wait_icr_idle();
368
369 apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
370 apic_write_around(APIC_ICR, APIC_DM_REMRD | regs[i]);
371
372 timeout = 0;
373 do {
374 udelay(100);
375 status = apic_read(APIC_ICR) & APIC_ICR_RR_MASK;
376 } while (status == APIC_ICR_RR_INPROG && timeout++ < 1000);
377
378 switch (status) {
379 case APIC_ICR_RR_VALID:
380 status = apic_read(APIC_RRR);
381 printk("%08x\n", status);
382 break;
383 default:
384 printk("failed\n");
385 }
386 }
387}
388#endif
389
Andi Kleena8ab26f2005-04-16 15:25:19 -0700390/*
391 * Kick the secondary to wake up.
392 */
393static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int start_rip)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394{
395 unsigned long send_status = 0, accept_status = 0;
396 int maxlvt, timeout, num_starts, j;
397
398 Dprintk("Asserting INIT.\n");
399
400 /*
401 * Turn INIT on target chip
402 */
403 apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
404
405 /*
406 * Send IPI
407 */
408 apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_INT_ASSERT
409 | APIC_DM_INIT);
410
411 Dprintk("Waiting for send to finish...\n");
412 timeout = 0;
413 do {
414 Dprintk("+");
415 udelay(100);
416 send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
417 } while (send_status && (timeout++ < 1000));
418
419 mdelay(10);
420
421 Dprintk("Deasserting INIT.\n");
422
423 /* Target chip */
424 apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
425
426 /* Send IPI */
427 apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT);
428
429 Dprintk("Waiting for send to finish...\n");
430 timeout = 0;
431 do {
432 Dprintk("+");
433 udelay(100);
434 send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
435 } while (send_status && (timeout++ < 1000));
436
437 atomic_set(&init_deasserted, 1);
438
439 /*
440 * Should we send STARTUP IPIs ?
441 *
442 * Determine this based on the APIC version.
443 * If we don't have an integrated APIC, don't send the STARTUP IPIs.
444 */
445 if (APIC_INTEGRATED(apic_version[phys_apicid]))
446 num_starts = 2;
447 else
448 num_starts = 0;
449
450 /*
451 * Run STARTUP IPI loop.
452 */
453 Dprintk("#startup loops: %d.\n", num_starts);
454
455 maxlvt = get_maxlvt();
456
457 for (j = 1; j <= num_starts; j++) {
458 Dprintk("Sending STARTUP #%d.\n",j);
459 apic_read_around(APIC_SPIV);
460 apic_write(APIC_ESR, 0);
461 apic_read(APIC_ESR);
462 Dprintk("After apic_write.\n");
463
464 /*
465 * STARTUP IPI
466 */
467
468 /* Target chip */
469 apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid));
470
471 /* Boot on the stack */
472 /* Kick the second */
473 apic_write_around(APIC_ICR, APIC_DM_STARTUP
474 | (start_rip >> 12));
475
476 /*
477 * Give the other CPU some time to accept the IPI.
478 */
479 udelay(300);
480
481 Dprintk("Startup point 1.\n");
482
483 Dprintk("Waiting for send to finish...\n");
484 timeout = 0;
485 do {
486 Dprintk("+");
487 udelay(100);
488 send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
489 } while (send_status && (timeout++ < 1000));
490
491 /*
492 * Give the other CPU some time to accept the IPI.
493 */
494 udelay(200);
495 /*
496 * Due to the Pentium erratum 3AP.
497 */
498 if (maxlvt > 3) {
499 apic_read_around(APIC_SPIV);
500 apic_write(APIC_ESR, 0);
501 }
502 accept_status = (apic_read(APIC_ESR) & 0xEF);
503 if (send_status || accept_status)
504 break;
505 }
506 Dprintk("After Startup.\n");
507
508 if (send_status)
509 printk(KERN_ERR "APIC never delivered???\n");
510 if (accept_status)
511 printk(KERN_ERR "APIC delivery error (%lx).\n", accept_status);
512
513 return (send_status | accept_status);
514}
515
Andi Kleena8ab26f2005-04-16 15:25:19 -0700516/*
517 * Boot one CPU.
518 */
519static int __cpuinit do_boot_cpu(int cpu, int apicid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520{
521 struct task_struct *idle;
522 unsigned long boot_error;
Andi Kleena8ab26f2005-04-16 15:25:19 -0700523 int timeout;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524 unsigned long start_rip;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 /*
526 * We can't use kernel_thread since we must avoid to
527 * reschedule the child.
528 */
529 idle = fork_idle(cpu);
Andi Kleena8ab26f2005-04-16 15:25:19 -0700530 if (IS_ERR(idle)) {
531 printk("failed fork for CPU %d\n", cpu);
532 return PTR_ERR(idle);
533 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534 x86_cpu_to_apicid[cpu] = apicid;
535
536 cpu_pda[cpu].pcurrent = idle;
537
538 start_rip = setup_trampoline();
539
Andi Kleena8ab26f2005-04-16 15:25:19 -0700540 init_rsp = idle->thread.rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 per_cpu(init_tss,cpu).rsp0 = init_rsp;
542 initial_code = start_secondary;
543 clear_ti_thread_flag(idle->thread_info, TIF_FORK);
544
Andi Kleena8ab26f2005-04-16 15:25:19 -0700545 printk(KERN_INFO "Booting processor %d/%d rip %lx rsp %lx\n", cpu, apicid,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546 start_rip, init_rsp);
547
548 /*
549 * This grunge runs the startup process for
550 * the targeted processor.
551 */
552
553 atomic_set(&init_deasserted, 0);
554
555 Dprintk("Setting warm reset code and vector.\n");
556
557 CMOS_WRITE(0xa, 0xf);
558 local_flush_tlb();
559 Dprintk("1.\n");
560 *((volatile unsigned short *) phys_to_virt(0x469)) = start_rip >> 4;
561 Dprintk("2.\n");
562 *((volatile unsigned short *) phys_to_virt(0x467)) = start_rip & 0xf;
563 Dprintk("3.\n");
564
565 /*
566 * Be paranoid about clearing APIC errors.
567 */
568 if (APIC_INTEGRATED(apic_version[apicid])) {
569 apic_read_around(APIC_SPIV);
570 apic_write(APIC_ESR, 0);
571 apic_read(APIC_ESR);
572 }
573
574 /*
575 * Status is now clean
576 */
577 boot_error = 0;
578
579 /*
580 * Starting actual IPI sequence...
581 */
Andi Kleena8ab26f2005-04-16 15:25:19 -0700582 boot_error = wakeup_secondary_via_INIT(apicid, start_rip);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583
584 if (!boot_error) {
585 /*
586 * allow APs to start initializing.
587 */
588 Dprintk("Before Callout %d.\n", cpu);
589 cpu_set(cpu, cpu_callout_map);
590 Dprintk("After Callout %d.\n", cpu);
591
592 /*
593 * Wait 5s total for a response
594 */
595 for (timeout = 0; timeout < 50000; timeout++) {
596 if (cpu_isset(cpu, cpu_callin_map))
597 break; /* It has booted */
598 udelay(100);
599 }
600
601 if (cpu_isset(cpu, cpu_callin_map)) {
602 /* number CPUs logically, starting from 1 (BSP is 0) */
603 Dprintk("OK.\n");
604 print_cpu_info(&cpu_data[cpu]);
605 Dprintk("CPU has booted.\n");
606 } else {
607 boot_error = 1;
608 if (*((volatile unsigned char *)phys_to_virt(SMP_TRAMPOLINE_BASE))
609 == 0xA5)
610 /* trampoline started but...? */
611 printk("Stuck ??\n");
612 else
613 /* trampoline code not run */
614 printk("Not responding.\n");
615#if APIC_DEBUG
616 inquire_remote_apic(apicid);
617#endif
618 }
619 }
620 if (boot_error) {
621 cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */
622 clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */
Andi Kleena8ab26f2005-04-16 15:25:19 -0700623 cpu_clear(cpu, cpu_present_map);
624 cpu_clear(cpu, cpu_possible_map);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 x86_cpu_to_apicid[cpu] = BAD_APICID;
626 x86_cpu_to_log_apicid[cpu] = BAD_APICID;
Andi Kleena8ab26f2005-04-16 15:25:19 -0700627 return -EIO;
628 }
629
630 return 0;
631}
632
633cycles_t cacheflush_time;
634unsigned long cache_decay_ticks;
635
636/*
637 * Construct cpu_sibling_map[], so that we can tell the sibling CPU
638 * on SMT systems efficiently.
639 */
640static __cpuinit void detect_siblings(void)
641{
642 int cpu;
643
644 for (cpu = 0; cpu < NR_CPUS; cpu++) {
645 cpus_clear(cpu_sibling_map[cpu]);
646 cpus_clear(cpu_core_map[cpu]);
647 }
648
649 for_each_online_cpu (cpu) {
650 struct cpuinfo_x86 *c = cpu_data + cpu;
651 int siblings = 0;
652 int i;
653 if (smp_num_siblings > 1) {
654 for_each_online_cpu (i) {
Siddha, Suresh Bd31ddaa2005-04-16 15:25:20 -0700655 if (cpu_core_id[cpu] == cpu_core_id[i]) {
Andi Kleena8ab26f2005-04-16 15:25:19 -0700656 siblings++;
657 cpu_set(i, cpu_sibling_map[cpu]);
658 }
659 }
660 } else {
661 siblings++;
662 cpu_set(cpu, cpu_sibling_map[cpu]);
663 }
664
665 if (siblings != smp_num_siblings) {
666 printk(KERN_WARNING
667 "WARNING: %d siblings found for CPU%d, should be %d\n",
668 siblings, cpu, smp_num_siblings);
669 smp_num_siblings = siblings;
670 }
671 if (c->x86_num_cores > 1) {
672 for_each_online_cpu(i) {
673 if (phys_proc_id[cpu] == phys_proc_id[i])
674 cpu_set(i, cpu_core_map[cpu]);
675 }
676 } else
677 cpu_core_map[cpu] = cpu_sibling_map[cpu];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678 }
679}
680
Andi Kleena8ab26f2005-04-16 15:25:19 -0700681/*
682 * Cleanup possible dangling ends...
683 */
684static __cpuinit void smp_cleanup_boot(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 /*
Andi Kleena8ab26f2005-04-16 15:25:19 -0700687 * Paranoid: Set warm reset code and vector here back
688 * to default values.
689 */
690 CMOS_WRITE(0, 0xf);
691
692 /*
693 * Reset trampoline flag
694 */
695 *((volatile int *) phys_to_virt(0x467)) = 0;
696
697#ifndef CONFIG_HOTPLUG_CPU
698 /*
699 * Free pages reserved for SMP bootup.
700 * When you add hotplug CPU support later remove this
701 * Note there is more work to be done for later CPU bootup.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702 */
703
Andi Kleena8ab26f2005-04-16 15:25:19 -0700704 free_page((unsigned long) __va(PAGE_SIZE));
705 free_page((unsigned long) __va(SMP_TRAMPOLINE_BASE));
706#endif
707}
708
709/*
710 * Fall back to non SMP mode after errors.
711 *
712 * RED-PEN audit/test this more. I bet there is more state messed up here.
713 */
714static __cpuinit void disable_smp(void)
715{
716 cpu_present_map = cpumask_of_cpu(0);
717 cpu_possible_map = cpumask_of_cpu(0);
718 if (smp_found_config)
719 phys_cpu_present_map = physid_mask_of_physid(boot_cpu_id);
720 else
721 phys_cpu_present_map = physid_mask_of_physid(0);
722 cpu_set(0, cpu_sibling_map[0]);
723 cpu_set(0, cpu_core_map[0]);
724}
725
726/*
727 * Handle user cpus=... parameter.
728 */
729static __cpuinit void enforce_max_cpus(unsigned max_cpus)
730{
731 int i, k;
732 k = 0;
733 for (i = 0; i < NR_CPUS; i++) {
734 if (!cpu_possible(i))
735 continue;
736 if (++k > max_cpus) {
737 cpu_clear(i, cpu_possible_map);
738 cpu_clear(i, cpu_present_map);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 }
740 }
741}
742
743/*
Andi Kleena8ab26f2005-04-16 15:25:19 -0700744 * Various sanity checks.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 */
Andi Kleena8ab26f2005-04-16 15:25:19 -0700746static int __cpuinit smp_sanity_check(unsigned max_cpus)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748 if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) {
749 printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
750 hard_smp_processor_id());
751 physid_set(hard_smp_processor_id(), phys_cpu_present_map);
752 }
753
754 /*
755 * If we couldn't find an SMP configuration at boot time,
756 * get out of here now!
757 */
758 if (!smp_found_config) {
759 printk(KERN_NOTICE "SMP motherboard not detected.\n");
Andi Kleena8ab26f2005-04-16 15:25:19 -0700760 disable_smp();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761 if (APIC_init_uniprocessor())
762 printk(KERN_NOTICE "Local APIC not detected."
763 " Using dummy APIC emulation.\n");
Andi Kleena8ab26f2005-04-16 15:25:19 -0700764 return -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 }
766
767 /*
768 * Should not be necessary because the MP table should list the boot
769 * CPU too, but we do it for the sake of robustness anyway.
770 */
771 if (!physid_isset(boot_cpu_id, phys_cpu_present_map)) {
772 printk(KERN_NOTICE "weird, boot CPU (#%d) not listed by the BIOS.\n",
773 boot_cpu_id);
774 physid_set(hard_smp_processor_id(), phys_cpu_present_map);
775 }
776
777 /*
778 * If we couldn't find a local APIC, then get out of here now!
779 */
780 if (APIC_INTEGRATED(apic_version[boot_cpu_id]) && !cpu_has_apic) {
781 printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
782 boot_cpu_id);
783 printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
Andi Kleena8ab26f2005-04-16 15:25:19 -0700784 nr_ioapics = 0;
785 return -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786 }
787
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 /*
789 * If SMP should be disabled, then really disable it!
790 */
791 if (!max_cpus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792 printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
Andi Kleena8ab26f2005-04-16 15:25:19 -0700793 nr_ioapics = 0;
794 return -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795 }
796
Andi Kleena8ab26f2005-04-16 15:25:19 -0700797 return 0;
798}
799
800/*
801 * Prepare for SMP bootup. The MP table or ACPI has been read
802 * earlier. Just do some sanity checking here and enable APIC mode.
803 */
804void __cpuinit smp_prepare_cpus(unsigned int max_cpus)
805{
806 int i;
807
808 nmi_watchdog_default();
809 current_cpu_data = boot_cpu_data;
810 current_thread_info()->cpu = 0; /* needed? */
811
812 enforce_max_cpus(max_cpus);
813
814 /*
815 * Fill in cpu_present_mask
816 */
817 for (i = 0; i < NR_CPUS; i++) {
818 int apicid = cpu_present_to_apicid(i);
819 if (physid_isset(apicid, phys_cpu_present_map)) {
820 cpu_set(i, cpu_present_map);
821 /* possible map would be different if we supported real
822 CPU hotplug. */
823 cpu_set(i, cpu_possible_map);
824 }
825 }
826
827 if (smp_sanity_check(max_cpus) < 0) {
828 printk(KERN_INFO "SMP disabled\n");
829 disable_smp();
830 return;
831 }
832
833
834 /*
835 * Switch from PIC to APIC mode.
836 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 connect_bsp_APIC();
838 setup_local_APIC();
839
Andi Kleena8ab26f2005-04-16 15:25:19 -0700840 if (GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_id) {
841 panic("Boot APIC ID in local APIC unexpected (%d vs %d)",
842 GET_APIC_ID(apic_read(APIC_ID)), boot_cpu_id);
843 /* Or can we switch back to PIC here? */
844 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845 x86_cpu_to_apicid[0] = boot_cpu_id;
846
847 /*
Andi Kleena8ab26f2005-04-16 15:25:19 -0700848 * Now start the IO-APICs
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849 */
850 if (!skip_ioapic_setup && nr_ioapics)
851 setup_IO_APIC();
852 else
853 nr_ioapics = 0;
854
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 /*
Andi Kleena8ab26f2005-04-16 15:25:19 -0700856 * Set up local APIC timer on boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858
Andi Kleena8ab26f2005-04-16 15:25:19 -0700859 setup_boot_APIC_clock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860}
861
Andi Kleena8ab26f2005-04-16 15:25:19 -0700862/*
863 * Early setup to make printk work.
864 */
865void __init smp_prepare_boot_cpu(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866{
Andi Kleena8ab26f2005-04-16 15:25:19 -0700867 int me = smp_processor_id();
868 cpu_set(me, cpu_online_map);
869 cpu_set(me, cpu_callout_map);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870}
871
Andi Kleena8ab26f2005-04-16 15:25:19 -0700872/*
873 * Entry point to boot a CPU.
874 *
875 * This is all __cpuinit, not __devinit for now because we don't support
876 * CPU hotplug (yet).
877 */
878int __cpuinit __cpu_up(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879{
Andi Kleena8ab26f2005-04-16 15:25:19 -0700880 int err;
881 int apicid = cpu_present_to_apicid(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882
Andi Kleena8ab26f2005-04-16 15:25:19 -0700883 WARN_ON(irqs_disabled());
884
885 Dprintk("++++++++++++++++++++=_---CPU UP %u\n", cpu);
886
887 if (apicid == BAD_APICID || apicid == boot_cpu_id ||
888 !physid_isset(apicid, phys_cpu_present_map)) {
889 printk("__cpu_up: bad cpu %d\n", cpu);
890 return -EINVAL;
891 }
892 sync_tsc_bp_init(1);
893
894 /* Boot it! */
895 err = do_boot_cpu(cpu, apicid);
896 if (err < 0) {
897 sync_tsc_bp_init(0);
898 Dprintk("do_boot_cpu failed %d\n", err);
899 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900 }
901
Andi Kleena8ab26f2005-04-16 15:25:19 -0700902 sync_tsc_bp(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903
904 /* Unleash the CPU! */
905 Dprintk("waiting for cpu %d\n", cpu);
906
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907 while (!cpu_isset(cpu, cpu_online_map))
Andi Kleena8ab26f2005-04-16 15:25:19 -0700908 cpu_relax();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 return 0;
910}
911
Andi Kleena8ab26f2005-04-16 15:25:19 -0700912/*
913 * Finish the SMP boot.
914 */
915void __cpuinit smp_cpus_done(unsigned int max_cpus)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916{
Andi Kleena8ab26f2005-04-16 15:25:19 -0700917 zap_low_mappings();
918 smp_cleanup_boot();
919
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920#ifdef CONFIG_X86_IO_APIC
921 setup_ioapic_dest();
922#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923
Andi Kleena8ab26f2005-04-16 15:25:19 -0700924 detect_siblings();
925 time_init_gtod();
926}