1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include <linux/module.h>
26#include <linux/acpi.h>
27#include <linux/bootmem.h>
28#include <linux/cpu.h>
29#include <linux/delay.h>
30#include <linux/init.h>
31#include <linux/interrupt.h>
32#include <linux/irq.h>
33#include <linux/kernel.h>
34#include <linux/kernel_stat.h>
35#include <linux/mm.h>
36#include <linux/notifier.h>
37#include <linux/smp.h>
38#include <linux/spinlock.h>
39#include <linux/efi.h>
40#include <linux/percpu.h>
41#include <linux/bitops.h>
42
43#include <linux/atomic.h>
44#include <asm/cache.h>
45#include <asm/current.h>
46#include <asm/delay.h>
47#include <asm/io.h>
48#include <asm/irq.h>
49#include <asm/machvec.h>
50#include <asm/mca.h>
51#include <asm/page.h>
52#include <asm/pgalloc.h>
53#include <asm/pgtable.h>
54#include <asm/processor.h>
55#include <asm/ptrace.h>
56#include <asm/sal.h>
57#include <asm/tlbflush.h>
58#include <asm/unistd.h>
59#include <asm/sn/arch.h>
60
61#define SMP_DEBUG 0
62
63#if SMP_DEBUG
64#define Dprintk(x...) printk(x)
65#else
66#define Dprintk(x...)
67#endif
68
69#ifdef CONFIG_HOTPLUG_CPU
70#ifdef CONFIG_PERMIT_BSP_REMOVE
71#define bsp_remove_ok 1
72#else
73#define bsp_remove_ok 0
74#endif
75
76
77
78
79struct sal_to_os_boot sal_boot_rendez_state[NR_CPUS];
80
81
82
83
84
85struct sal_to_os_boot *sal_state_for_booting_cpu = &sal_boot_rendez_state[0];
86
87#define set_brendez_area(x) (sal_state_for_booting_cpu = &sal_boot_rendez_state[(x)]);
88
89#else
90#define set_brendez_area(x)
91#endif
92
93
94
95
96
97#define MASTER (0)
98#define SLAVE (SMP_CACHE_BYTES/8)
99
100#define NUM_ROUNDS 64
101#define NUM_ITERS 5
102
103static DEFINE_SPINLOCK(itc_sync_lock);
104static volatile unsigned long go[SLAVE + 1];
105
106#define DEBUG_ITC_SYNC 0
107
108extern void start_ap (void);
109extern unsigned long ia64_iobase;
110
111struct task_struct *task_for_booting_cpu;
112
113
114
115
116DEFINE_PER_CPU(int, cpu_state);
117
118cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
119EXPORT_SYMBOL(cpu_core_map);
120DEFINE_PER_CPU_SHARED_ALIGNED(cpumask_t, cpu_sibling_map);
121EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
122
123int smp_num_siblings = 1;
124
125
126volatile int ia64_cpu_to_sapicid[NR_CPUS];
127EXPORT_SYMBOL(ia64_cpu_to_sapicid);
128
129static cpumask_t cpu_callin_map;
130
131struct smp_boot_data smp_boot_data __initdata;
132
133unsigned long ap_wakeup_vector = -1;
134
135char __initdata no_int_routing;
136
137unsigned char smp_int_redirect;
138
139#ifdef CONFIG_FORCE_CPEI_RETARGET
140#define CPEI_OVERRIDE_DEFAULT (1)
141#else
142#define CPEI_OVERRIDE_DEFAULT (0)
143#endif
144
145unsigned int force_cpei_retarget = CPEI_OVERRIDE_DEFAULT;
146
147static int __init
148cmdl_force_cpei(char *str)
149{
150 int value=0;
151
152 get_option (&str, &value);
153 force_cpei_retarget = value;
154
155 return 1;
156}
157
158__setup("force_cpei=", cmdl_force_cpei);
159
160static int __init
161nointroute (char *str)
162{
163 no_int_routing = 1;
164 printk ("no_int_routing on\n");
165 return 1;
166}
167
168__setup("nointroute", nointroute);
169
170static void fix_b0_for_bsp(void)
171{
172#ifdef CONFIG_HOTPLUG_CPU
173 int cpuid;
174 static int fix_bsp_b0 = 1;
175
176 cpuid = smp_processor_id();
177
178
179
180
181 if (!(fix_bsp_b0 && cpuid))
182 return;
183
184 sal_boot_rendez_state[0].br[0] = sal_boot_rendez_state[cpuid].br[0];
185 printk ("Fixed BSP b0 value from CPU %d\n", cpuid);
186
187 fix_bsp_b0 = 0;
188#endif
189}
190
191void
192sync_master (void *arg)
193{
194 unsigned long flags, i;
195
196 go[MASTER] = 0;
197
198 local_irq_save(flags);
199 {
200 for (i = 0; i < NUM_ROUNDS*NUM_ITERS; ++i) {
201 while (!go[MASTER])
202 cpu_relax();
203 go[MASTER] = 0;
204 go[SLAVE] = ia64_get_itc();
205 }
206 }
207 local_irq_restore(flags);
208}
209
210
211
212
213
214
215static inline long
216get_delta (long *rt, long *master)
217{
218 unsigned long best_t0 = 0, best_t1 = ~0UL, best_tm = 0;
219 unsigned long tcenter, t0, t1, tm;
220 long i;
221
222 for (i = 0; i < NUM_ITERS; ++i) {
223 t0 = ia64_get_itc();
224 go[MASTER] = 1;
225 while (!(tm = go[SLAVE]))
226 cpu_relax();
227 go[SLAVE] = 0;
228 t1 = ia64_get_itc();
229
230 if (t1 - t0 < best_t1 - best_t0)
231 best_t0 = t0, best_t1 = t1, best_tm = tm;
232 }
233
234 *rt = best_t1 - best_t0;
235 *master = best_tm - best_t0;
236
237
238 tcenter = (best_t0/2 + best_t1/2);
239 if (best_t0 % 2 + best_t1 % 2 == 2)
240 ++tcenter;
241 return tcenter - best_tm;
242}
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276void
277ia64_sync_itc (unsigned int master)
278{
279 long i, delta, adj, adjust_latency = 0, done = 0;
280 unsigned long flags, rt, master_time_stamp, bound;
281#if DEBUG_ITC_SYNC
282 struct {
283 long rt;
284 long master;
285 long diff;
286 long lat;
287 } t[NUM_ROUNDS];
288#endif
289
290
291
292
293
294
295
296 BUG_ON((ia64_get_itv() & (1 << 16)) == 0);
297
298 go[MASTER] = 1;
299
300 if (smp_call_function_single(master, sync_master, NULL, 0) < 0) {
301 printk(KERN_ERR "sync_itc: failed to get attention of CPU %u!\n", master);
302 return;
303 }
304
305 while (go[MASTER])
306 cpu_relax();
307
308 spin_lock_irqsave(&itc_sync_lock, flags);
309 {
310 for (i = 0; i < NUM_ROUNDS; ++i) {
311 delta = get_delta(&rt, &master_time_stamp);
312 if (delta == 0) {
313 done = 1;
314 bound = rt;
315 }
316
317 if (!done) {
318 if (i > 0) {
319 adjust_latency += -delta;
320 adj = -delta + adjust_latency/4;
321 } else
322 adj = -delta;
323
324 ia64_set_itc(ia64_get_itc() + adj);
325 }
326#if DEBUG_ITC_SYNC
327 t[i].rt = rt;
328 t[i].master = master_time_stamp;
329 t[i].diff = delta;
330 t[i].lat = adjust_latency/4;
331#endif
332 }
333 }
334 spin_unlock_irqrestore(&itc_sync_lock, flags);
335
336#if DEBUG_ITC_SYNC
337 for (i = 0; i < NUM_ROUNDS; ++i)
338 printk("rt=%5ld master=%5ld diff=%5ld adjlat=%5ld\n",
339 t[i].rt, t[i].master, t[i].diff, t[i].lat);
340#endif
341
342 printk(KERN_INFO "CPU %d: synchronized ITC with CPU %u (last diff %ld cycles, "
343 "maxerr %lu cycles)\n", smp_processor_id(), master, delta, rt);
344}
345
346
347
348
349static inline void smp_setup_percpu_timer(void)
350{
351}
352
353static void
354smp_callin (void)
355{
356 int cpuid, phys_id, itc_master;
357 struct cpuinfo_ia64 *last_cpuinfo, *this_cpuinfo;
358 extern void ia64_init_itm(void);
359 extern volatile int time_keeper_id;
360
361#ifdef CONFIG_PERFMON
362 extern void pfm_init_percpu(void);
363#endif
364
365 cpuid = smp_processor_id();
366 phys_id = hard_smp_processor_id();
367 itc_master = time_keeper_id;
368
369 if (cpu_online(cpuid)) {
370 printk(KERN_ERR "huh, phys CPU#0x%x, CPU#0x%x already present??\n",
371 phys_id, cpuid);
372 BUG();
373 }
374
375 fix_b0_for_bsp();
376
377
378
379
380 set_numa_node(cpu_to_node_map[cpuid]);
381 set_numa_mem(local_memory_node(cpu_to_node_map[cpuid]));
382
383 spin_lock(&vector_lock);
384
385 __setup_vector_irq(cpuid);
386 notify_cpu_starting(cpuid);
387 set_cpu_online(cpuid, true);
388 per_cpu(cpu_state, cpuid) = CPU_ONLINE;
389 spin_unlock(&vector_lock);
390
391 smp_setup_percpu_timer();
392
393 ia64_mca_cmc_vector_setup();
394
395#ifdef CONFIG_PERFMON
396 pfm_init_percpu();
397#endif
398
399 local_irq_enable();
400
401 if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) {
402
403
404
405
406
407
408 Dprintk("Going to syncup ITC with ITC Master.\n");
409 ia64_sync_itc(itc_master);
410 }
411
412
413
414
415 ia64_init_itm();
416
417
418
419
420
421 last_cpuinfo = cpu_data(cpuid - 1);
422 this_cpuinfo = local_cpu_data;
423 if (last_cpuinfo->itc_freq != this_cpuinfo->itc_freq ||
424 last_cpuinfo->proc_freq != this_cpuinfo->proc_freq ||
425 last_cpuinfo->features != this_cpuinfo->features ||
426 last_cpuinfo->revision != this_cpuinfo->revision ||
427 last_cpuinfo->family != this_cpuinfo->family ||
428 last_cpuinfo->archrev != this_cpuinfo->archrev ||
429 last_cpuinfo->model != this_cpuinfo->model)
430 calibrate_delay();
431 local_cpu_data->loops_per_jiffy = loops_per_jiffy;
432
433
434
435
436 cpumask_set_cpu(cpuid, &cpu_callin_map);
437 Dprintk("Stack on CPU %d at about %p\n",cpuid, &cpuid);
438}
439
440
441
442
443
444int
445start_secondary (void *unused)
446{
447
448 ia64_set_kr(IA64_KR_IO_BASE, __pa(ia64_iobase));
449#ifndef CONFIG_PRINTK_TIME
450 Dprintk("start_secondary: starting CPU 0x%x\n", hard_smp_processor_id());
451#endif
452 efi_map_pal_code();
453 cpu_init();
454 preempt_disable();
455 smp_callin();
456
457 cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
458 return 0;
459}
460
461static int
462do_boot_cpu (int sapicid, int cpu, struct task_struct *idle)
463{
464 int timeout;
465
466 task_for_booting_cpu = idle;
467 Dprintk("Sending wakeup vector %lu to AP 0x%x/0x%x.\n", ap_wakeup_vector, cpu, sapicid);
468
469 set_brendez_area(cpu);
470 platform_send_ipi(cpu, ap_wakeup_vector, IA64_IPI_DM_INT, 0);
471
472
473
474
475 Dprintk("Waiting on callin_map ...");
476 for (timeout = 0; timeout < 100000; timeout++) {
477 if (cpumask_test_cpu(cpu, &cpu_callin_map))
478 break;
479 barrier();
480 udelay(100);
481 }
482 Dprintk("\n");
483
484 if (!cpumask_test_cpu(cpu, &cpu_callin_map)) {
485 printk(KERN_ERR "Processor 0x%x/0x%x is stuck.\n", cpu, sapicid);
486 ia64_cpu_to_sapicid[cpu] = -1;
487 set_cpu_online(cpu, false);
488 return -EINVAL;
489 }
490 return 0;
491}
492
493static int __init
494decay (char *str)
495{
496 int ticks;
497 get_option (&str, &ticks);
498 return 1;
499}
500
501__setup("decay=", decay);
502
503
504
505
506void __init
507smp_build_cpu_map (void)
508{
509 int sapicid, cpu, i;
510 int boot_cpu_id = hard_smp_processor_id();
511
512 for (cpu = 0; cpu < NR_CPUS; cpu++) {
513 ia64_cpu_to_sapicid[cpu] = -1;
514 }
515
516 ia64_cpu_to_sapicid[0] = boot_cpu_id;
517 init_cpu_present(cpumask_of(0));
518 set_cpu_possible(0, true);
519 for (cpu = 1, i = 0; i < smp_boot_data.cpu_count; i++) {
520 sapicid = smp_boot_data.cpu_phys_id[i];
521 if (sapicid == boot_cpu_id)
522 continue;
523 set_cpu_present(cpu, true);
524 set_cpu_possible(cpu, true);
525 ia64_cpu_to_sapicid[cpu] = sapicid;
526 cpu++;
527 }
528}
529
530
531
532
533void __init
534smp_prepare_cpus (unsigned int max_cpus)
535{
536 int boot_cpu_id = hard_smp_processor_id();
537
538
539
540
541
542 smp_setup_percpu_timer();
543
544 cpumask_set_cpu(0, &cpu_callin_map);
545
546 local_cpu_data->loops_per_jiffy = loops_per_jiffy;
547 ia64_cpu_to_sapicid[0] = boot_cpu_id;
548
549 printk(KERN_INFO "Boot processor id 0x%x/0x%x\n", 0, boot_cpu_id);
550
551 current_thread_info()->cpu = 0;
552
553
554
555
556 if (!max_cpus) {
557 printk(KERN_INFO "SMP mode deactivated.\n");
558 init_cpu_online(cpumask_of(0));
559 init_cpu_present(cpumask_of(0));
560 init_cpu_possible(cpumask_of(0));
561 return;
562 }
563}
564
565void smp_prepare_boot_cpu(void)
566{
567 set_cpu_online(smp_processor_id(), true);
568 cpumask_set_cpu(smp_processor_id(), &cpu_callin_map);
569 set_numa_node(cpu_to_node_map[smp_processor_id()]);
570 per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
571}
572
573#ifdef CONFIG_HOTPLUG_CPU
574static inline void
575clear_cpu_sibling_map(int cpu)
576{
577 int i;
578
579 for_each_cpu(i, &per_cpu(cpu_sibling_map, cpu))
580 cpumask_clear_cpu(cpu, &per_cpu(cpu_sibling_map, i));
581 for_each_cpu(i, &cpu_core_map[cpu])
582 cpumask_clear_cpu(cpu, &cpu_core_map[i]);
583
584 per_cpu(cpu_sibling_map, cpu) = cpu_core_map[cpu] = CPU_MASK_NONE;
585}
586
587static void
588remove_siblinginfo(int cpu)
589{
590 int last = 0;
591
592 if (cpu_data(cpu)->threads_per_core == 1 &&
593 cpu_data(cpu)->cores_per_socket == 1) {
594 cpumask_clear_cpu(cpu, &cpu_core_map[cpu]);
595 cpumask_clear_cpu(cpu, &per_cpu(cpu_sibling_map, cpu));
596 return;
597 }
598
599 last = (cpumask_weight(&cpu_core_map[cpu]) == 1 ? 1 : 0);
600
601
602 clear_cpu_sibling_map(cpu);
603}
604
605extern void fixup_irqs(void);
606
607int migrate_platform_irqs(unsigned int cpu)
608{
609 int new_cpei_cpu;
610 struct irq_data *data = NULL;
611 const struct cpumask *mask;
612 int retval = 0;
613
614
615
616
617 if (cpe_vector > 0 && is_cpu_cpei_target(cpu)) {
618 printk ("CPU (%d) is CPEI Target\n", cpu);
619 if (can_cpei_retarget()) {
620
621
622
623 new_cpei_cpu = cpumask_any(cpu_online_mask);
624 mask = cpumask_of(new_cpei_cpu);
625 set_cpei_target_cpu(new_cpei_cpu);
626 data = irq_get_irq_data(ia64_cpe_irq);
627
628
629
630
631
632 if (data && data->chip) {
633 data->chip->irq_disable(data);
634 data->chip->irq_set_affinity(data, mask, false);
635 data->chip->irq_enable(data);
636 printk ("Re-targeting CPEI to cpu %d\n", new_cpei_cpu);
637 }
638 }
639 if (!data) {
640 printk ("Unable to retarget CPEI, offline cpu [%d] failed\n", cpu);
641 retval = -EBUSY;
642 }
643 }
644 return retval;
645}
646
647
648int __cpu_disable(void)
649{
650 int cpu = smp_processor_id();
651
652
653
654
655 if (cpu == 0 && !bsp_remove_ok) {
656 printk ("Your platform does not support removal of BSP\n");
657 return (-EBUSY);
658 }
659
660 if (ia64_platform_is("sn2")) {
661 if (!sn_cpu_disable_allowed(cpu))
662 return -EBUSY;
663 }
664
665 set_cpu_online(cpu, false);
666
667 if (migrate_platform_irqs(cpu)) {
668 set_cpu_online(cpu, true);
669 return -EBUSY;
670 }
671
672 remove_siblinginfo(cpu);
673 fixup_irqs();
674 local_flush_tlb_all();
675 cpumask_clear_cpu(cpu, &cpu_callin_map);
676 return 0;
677}
678
679void __cpu_die(unsigned int cpu)
680{
681 unsigned int i;
682
683 for (i = 0; i < 100; i++) {
684
685 if (per_cpu(cpu_state, cpu) == CPU_DEAD)
686 {
687 printk ("CPU %d is now offline\n", cpu);
688 return;
689 }
690 msleep(100);
691 }
692 printk(KERN_ERR "CPU %u didn't die...\n", cpu);
693}
694#endif
695
696void
697smp_cpus_done (unsigned int dummy)
698{
699 int cpu;
700 unsigned long bogosum = 0;
701
702
703
704
705
706 for_each_online_cpu(cpu) {
707 bogosum += cpu_data(cpu)->loops_per_jiffy;
708 }
709
710 printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
711 (int)num_online_cpus(), bogosum/(500000/HZ), (bogosum/(5000/HZ))%100);
712}
713
714static inline void set_cpu_sibling_map(int cpu)
715{
716 int i;
717
718 for_each_online_cpu(i) {
719 if ((cpu_data(cpu)->socket_id == cpu_data(i)->socket_id)) {
720 cpumask_set_cpu(i, &cpu_core_map[cpu]);
721 cpumask_set_cpu(cpu, &cpu_core_map[i]);
722 if (cpu_data(cpu)->core_id == cpu_data(i)->core_id) {
723 cpumask_set_cpu(i,
724 &per_cpu(cpu_sibling_map, cpu));
725 cpumask_set_cpu(cpu,
726 &per_cpu(cpu_sibling_map, i));
727 }
728 }
729 }
730}
731
732int
733__cpu_up(unsigned int cpu, struct task_struct *tidle)
734{
735 int ret;
736 int sapicid;
737
738 sapicid = ia64_cpu_to_sapicid[cpu];
739 if (sapicid == -1)
740 return -EINVAL;
741
742
743
744
745
746 if (cpumask_test_cpu(cpu, &cpu_callin_map))
747 return -EINVAL;
748
749 per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
750
751 ret = do_boot_cpu(sapicid, cpu, tidle);
752 if (ret < 0)
753 return ret;
754
755 if (cpu_data(cpu)->threads_per_core == 1 &&
756 cpu_data(cpu)->cores_per_socket == 1) {
757 cpumask_set_cpu(cpu, &per_cpu(cpu_sibling_map, cpu));
758 cpumask_set_cpu(cpu, &cpu_core_map[cpu]);
759 return 0;
760 }
761
762 set_cpu_sibling_map(cpu);
763
764 return 0;
765}
766
767
768
769
770
771
772
773void __init
774init_smp_config(void)
775{
776 struct fptr {
777 unsigned long fp;
778 unsigned long gp;
779 } *ap_startup;
780 long sal_ret;
781
782
783 ap_startup = (struct fptr *) start_ap;
784 sal_ret = ia64_sal_set_vectors(SAL_VECTOR_OS_BOOT_RENDEZ,
785 ia64_tpa(ap_startup->fp), ia64_tpa(ap_startup->gp), 0, 0, 0, 0);
786 if (sal_ret < 0)
787 printk(KERN_ERR "SMP: Can't set SAL AP Boot Rendezvous: %s\n",
788 ia64_sal_strerror(sal_ret));
789}
790
791
792
793
794
795void identify_siblings(struct cpuinfo_ia64 *c)
796{
797 long status;
798 u16 pltid;
799 pal_logical_to_physical_t info;
800
801 status = ia64_pal_logical_to_phys(-1, &info);
802 if (status != PAL_STATUS_SUCCESS) {
803 if (status != PAL_STATUS_UNIMPLEMENTED) {
804 printk(KERN_ERR
805 "ia64_pal_logical_to_phys failed with %ld\n",
806 status);
807 return;
808 }
809
810 info.overview_ppid = 0;
811 info.overview_cpp = 1;
812 info.overview_tpc = 1;
813 }
814
815 status = ia64_sal_physical_id_info(&pltid);
816 if (status != PAL_STATUS_SUCCESS) {
817 if (status != PAL_STATUS_UNIMPLEMENTED)
818 printk(KERN_ERR
819 "ia64_sal_pltid failed with %ld\n",
820 status);
821 return;
822 }
823
824 c->socket_id = (pltid << 8) | info.overview_ppid;
825
826 if (info.overview_cpp == 1 && info.overview_tpc == 1)
827 return;
828
829 c->cores_per_socket = info.overview_cpp;
830 c->threads_per_core = info.overview_tpc;
831 c->num_log = info.overview_num_log;
832
833 c->core_id = info.log1_cid;
834 c->thread_id = info.log1_tid;
835}
836
837
838
839
840
841
842
843int is_multithreading_enabled(void)
844{
845 int i, j;
846
847 for_each_present_cpu(i) {
848 for_each_present_cpu(j) {
849 if (j == i)
850 continue;
851 if ((cpu_data(j)->socket_id == cpu_data(i)->socket_id)) {
852 if (cpu_data(j)->core_id == cpu_data(i)->core_id)
853 return 1;
854 }
855 }
856 }
857 return 0;
858}
859EXPORT_SYMBOL_GPL(is_multithreading_enabled);
860