aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/smp.c')
-rw-r--r--arch/sparc64/kernel/smp.c418
1 files changed, 314 insertions, 104 deletions
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 1f7ad8a69052..373a701c90a5 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -38,6 +38,7 @@
38#include <asm/timer.h> 38#include <asm/timer.h>
39#include <asm/starfire.h> 39#include <asm/starfire.h>
40#include <asm/tlb.h> 40#include <asm/tlb.h>
41#include <asm/sections.h>
41 42
42extern void calibrate_delay(void); 43extern void calibrate_delay(void);
43 44
@@ -46,6 +47,8 @@ static unsigned char boot_cpu_id;
46 47
47cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE; 48cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE;
48cpumask_t phys_cpu_present_map __read_mostly = CPU_MASK_NONE; 49cpumask_t phys_cpu_present_map __read_mostly = CPU_MASK_NONE;
50cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly =
51 { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
49static cpumask_t smp_commenced_mask; 52static cpumask_t smp_commenced_mask;
50static cpumask_t cpu_callout_map; 53static cpumask_t cpu_callout_map;
51 54
@@ -77,7 +80,7 @@ void smp_bogo(struct seq_file *m)
77 80
78void __init smp_store_cpu_info(int id) 81void __init smp_store_cpu_info(int id)
79{ 82{
80 int cpu_node; 83 int cpu_node, def;
81 84
82 /* multiplier and counter set by 85 /* multiplier and counter set by
83 smp_setup_percpu_timer() */ 86 smp_setup_percpu_timer() */
@@ -87,24 +90,32 @@ void __init smp_store_cpu_info(int id)
87 cpu_data(id).clock_tick = prom_getintdefault(cpu_node, 90 cpu_data(id).clock_tick = prom_getintdefault(cpu_node,
88 "clock-frequency", 0); 91 "clock-frequency", 0);
89 92
90 cpu_data(id).pgcache_size = 0; 93 def = ((tlb_type == hypervisor) ? (8 * 1024) : (16 * 1024));
91 cpu_data(id).pte_cache[0] = NULL;
92 cpu_data(id).pte_cache[1] = NULL;
93 cpu_data(id).pgd_cache = NULL;
94 cpu_data(id).idle_volume = 1;
95
96 cpu_data(id).dcache_size = prom_getintdefault(cpu_node, "dcache-size", 94 cpu_data(id).dcache_size = prom_getintdefault(cpu_node, "dcache-size",
97 16 * 1024); 95 def);
96
97 def = 32;
98 cpu_data(id).dcache_line_size = 98 cpu_data(id).dcache_line_size =
99 prom_getintdefault(cpu_node, "dcache-line-size", 32); 99 prom_getintdefault(cpu_node, "dcache-line-size", def);
100
101 def = 16 * 1024;
100 cpu_data(id).icache_size = prom_getintdefault(cpu_node, "icache-size", 102 cpu_data(id).icache_size = prom_getintdefault(cpu_node, "icache-size",
101 16 * 1024); 103 def);
104
105 def = 32;
102 cpu_data(id).icache_line_size = 106 cpu_data(id).icache_line_size =
103 prom_getintdefault(cpu_node, "icache-line-size", 32); 107 prom_getintdefault(cpu_node, "icache-line-size", def);
108
109 def = ((tlb_type == hypervisor) ?
110 (3 * 1024 * 1024) :
111 (4 * 1024 * 1024));
104 cpu_data(id).ecache_size = prom_getintdefault(cpu_node, "ecache-size", 112 cpu_data(id).ecache_size = prom_getintdefault(cpu_node, "ecache-size",
105 4 * 1024 * 1024); 113 def);
114
115 def = 64;
106 cpu_data(id).ecache_line_size = 116 cpu_data(id).ecache_line_size =
107 prom_getintdefault(cpu_node, "ecache-line-size", 64); 117 prom_getintdefault(cpu_node, "ecache-line-size", def);
118
108 printk("CPU[%d]: Caches " 119 printk("CPU[%d]: Caches "
109 "D[sz(%d):line_sz(%d)] " 120 "D[sz(%d):line_sz(%d)] "
110 "I[sz(%d):line_sz(%d)] " 121 "I[sz(%d):line_sz(%d)] "
@@ -119,27 +130,16 @@ static void smp_setup_percpu_timer(void);
119 130
120static volatile unsigned long callin_flag = 0; 131static volatile unsigned long callin_flag = 0;
121 132
122extern void inherit_locked_prom_mappings(int save_p);
123
124static inline void cpu_setup_percpu_base(unsigned long cpu_id)
125{
126 __asm__ __volatile__("mov %0, %%g5\n\t"
127 "stxa %0, [%1] %2\n\t"
128 "membar #Sync"
129 : /* no outputs */
130 : "r" (__per_cpu_offset(cpu_id)),
131 "r" (TSB_REG), "i" (ASI_IMMU));
132}
133
134void __init smp_callin(void) 133void __init smp_callin(void)
135{ 134{
136 int cpuid = hard_smp_processor_id(); 135 int cpuid = hard_smp_processor_id();
137 136
138 inherit_locked_prom_mappings(0); 137 __local_per_cpu_offset = __per_cpu_offset(cpuid);
139 138
140 __flush_tlb_all(); 139 if (tlb_type == hypervisor)
140 sun4v_ktsb_register();
141 141
142 cpu_setup_percpu_base(cpuid); 142 __flush_tlb_all();
143 143
144 smp_setup_percpu_timer(); 144 smp_setup_percpu_timer();
145 145
@@ -316,6 +316,8 @@ static void smp_synchronize_one_tick(int cpu)
316 spin_unlock_irqrestore(&itc_sync_lock, flags); 316 spin_unlock_irqrestore(&itc_sync_lock, flags);
317} 317}
318 318
319extern void sun4v_init_mondo_queues(int use_bootmem, int cpu, int alloc, int load);
320
319extern unsigned long sparc64_cpu_startup; 321extern unsigned long sparc64_cpu_startup;
320 322
321/* The OBP cpu startup callback truncates the 3rd arg cookie to 323/* The OBP cpu startup callback truncates the 3rd arg cookie to
@@ -331,21 +333,31 @@ static int __devinit smp_boot_one_cpu(unsigned int cpu)
331 unsigned long cookie = 333 unsigned long cookie =
332 (unsigned long)(&cpu_new_thread); 334 (unsigned long)(&cpu_new_thread);
333 struct task_struct *p; 335 struct task_struct *p;
334 int timeout, ret, cpu_node; 336 int timeout, ret;
335 337
336 p = fork_idle(cpu); 338 p = fork_idle(cpu);
337 callin_flag = 0; 339 callin_flag = 0;
338 cpu_new_thread = task_thread_info(p); 340 cpu_new_thread = task_thread_info(p);
339 cpu_set(cpu, cpu_callout_map); 341 cpu_set(cpu, cpu_callout_map);
340 342
341 cpu_find_by_mid(cpu, &cpu_node); 343 if (tlb_type == hypervisor) {
342 prom_startcpu(cpu_node, entry, cookie); 344 /* Alloc the mondo queues, cpu will load them. */
345 sun4v_init_mondo_queues(0, cpu, 1, 0);
346
347 prom_startcpu_cpuid(cpu, entry, cookie);
348 } else {
349 int cpu_node;
350
351 cpu_find_by_mid(cpu, &cpu_node);
352 prom_startcpu(cpu_node, entry, cookie);
353 }
343 354
344 for (timeout = 0; timeout < 5000000; timeout++) { 355 for (timeout = 0; timeout < 5000000; timeout++) {
345 if (callin_flag) 356 if (callin_flag)
346 break; 357 break;
347 udelay(100); 358 udelay(100);
348 } 359 }
360
349 if (callin_flag) { 361 if (callin_flag) {
350 ret = 0; 362 ret = 0;
351 } else { 363 } else {
@@ -441,7 +453,7 @@ static __inline__ void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, c
441static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask) 453static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask)
442{ 454{
443 u64 pstate, ver; 455 u64 pstate, ver;
444 int nack_busy_id, is_jalapeno; 456 int nack_busy_id, is_jbus;
445 457
446 if (cpus_empty(mask)) 458 if (cpus_empty(mask))
447 return; 459 return;
@@ -451,7 +463,8 @@ static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mas
451 * derivative processor. 463 * derivative processor.
452 */ 464 */
453 __asm__ ("rdpr %%ver, %0" : "=r" (ver)); 465 __asm__ ("rdpr %%ver, %0" : "=r" (ver));
454 is_jalapeno = ((ver >> 32) == 0x003e0016); 466 is_jbus = ((ver >> 32) == __JALAPENO_ID ||
467 (ver >> 32) == __SERRANO_ID);
455 468
456 __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); 469 __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
457 470
@@ -476,7 +489,7 @@ retry:
476 for_each_cpu_mask(i, mask) { 489 for_each_cpu_mask(i, mask) {
477 u64 target = (i << 14) | 0x70; 490 u64 target = (i << 14) | 0x70;
478 491
479 if (!is_jalapeno) 492 if (!is_jbus)
480 target |= (nack_busy_id << 24); 493 target |= (nack_busy_id << 24);
481 __asm__ __volatile__( 494 __asm__ __volatile__(
482 "stxa %%g0, [%0] %1\n\t" 495 "stxa %%g0, [%0] %1\n\t"
@@ -529,7 +542,7 @@ retry:
529 for_each_cpu_mask(i, mask) { 542 for_each_cpu_mask(i, mask) {
530 u64 check_mask; 543 u64 check_mask;
531 544
532 if (is_jalapeno) 545 if (is_jbus)
533 check_mask = (0x2UL << (2*i)); 546 check_mask = (0x2UL << (2*i));
534 else 547 else
535 check_mask = (0x2UL << 548 check_mask = (0x2UL <<
@@ -544,6 +557,155 @@ retry:
544 } 557 }
545} 558}
546 559
560/* Multi-cpu list version. */
561static void hypervisor_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask)
562{
563 struct trap_per_cpu *tb;
564 u16 *cpu_list;
565 u64 *mondo;
566 cpumask_t error_mask;
567 unsigned long flags, status;
568 int cnt, retries, this_cpu, prev_sent, i;
569
570 /* We have to do this whole thing with interrupts fully disabled.
571 * Otherwise if we send an xcall from interrupt context it will
572 * corrupt both our mondo block and cpu list state.
573 *
574 * One consequence of this is that we cannot use timeout mechanisms
575 * that depend upon interrupts being delivered locally. So, for
576 * example, we cannot sample jiffies and expect it to advance.
577 *
578 * Fortunately, udelay() uses %stick/%tick so we can use that.
579 */
580 local_irq_save(flags);
581
582 this_cpu = smp_processor_id();
583 tb = &trap_block[this_cpu];
584
585 mondo = __va(tb->cpu_mondo_block_pa);
586 mondo[0] = data0;
587 mondo[1] = data1;
588 mondo[2] = data2;
589 wmb();
590
591 cpu_list = __va(tb->cpu_list_pa);
592
593 /* Setup the initial cpu list. */
594 cnt = 0;
595 for_each_cpu_mask(i, mask)
596 cpu_list[cnt++] = i;
597
598 cpus_clear(error_mask);
599 retries = 0;
600 prev_sent = 0;
601 do {
602 int forward_progress, n_sent;
603
604 status = sun4v_cpu_mondo_send(cnt,
605 tb->cpu_list_pa,
606 tb->cpu_mondo_block_pa);
607
608 /* HV_EOK means all cpus received the xcall, we're done. */
609 if (likely(status == HV_EOK))
610 break;
611
612 /* First, see if we made any forward progress.
613 *
614 * The hypervisor indicates successful sends by setting
615 * cpu list entries to the value 0xffff.
616 */
617 n_sent = 0;
618 for (i = 0; i < cnt; i++) {
619 if (likely(cpu_list[i] == 0xffff))
620 n_sent++;
621 }
622
623 forward_progress = 0;
624 if (n_sent > prev_sent)
625 forward_progress = 1;
626
627 prev_sent = n_sent;
628
629 /* If we get a HV_ECPUERROR, then one or more of the cpus
630 * in the list are in error state. Use the cpu_state()
631 * hypervisor call to find out which cpus are in error state.
632 */
633 if (unlikely(status == HV_ECPUERROR)) {
634 for (i = 0; i < cnt; i++) {
635 long err;
636 u16 cpu;
637
638 cpu = cpu_list[i];
639 if (cpu == 0xffff)
640 continue;
641
642 err = sun4v_cpu_state(cpu);
643 if (err >= 0 &&
644 err == HV_CPU_STATE_ERROR) {
645 cpu_list[i] = 0xffff;
646 cpu_set(cpu, error_mask);
647 }
648 }
649 } else if (unlikely(status != HV_EWOULDBLOCK))
650 goto fatal_mondo_error;
651
652 /* Don't bother rewriting the CPU list, just leave the
653 * 0xffff and non-0xffff entries in there and the
654 * hypervisor will do the right thing.
655 *
656 * Only advance timeout state if we didn't make any
657 * forward progress.
658 */
659 if (unlikely(!forward_progress)) {
660 if (unlikely(++retries > 10000))
661 goto fatal_mondo_timeout;
662
663 /* Delay a little bit to let other cpus catch up
664 * on their cpu mondo queue work.
665 */
666 udelay(2 * cnt);
667 }
668 } while (1);
669
670 local_irq_restore(flags);
671
672 if (unlikely(!cpus_empty(error_mask)))
673 goto fatal_mondo_cpu_error;
674
675 return;
676
677fatal_mondo_cpu_error:
678 printk(KERN_CRIT "CPU[%d]: SUN4V mondo cpu error, some target cpus "
679 "were in error state\n",
680 this_cpu);
681 printk(KERN_CRIT "CPU[%d]: Error mask [ ", this_cpu);
682 for_each_cpu_mask(i, error_mask)
683 printk("%d ", i);
684 printk("]\n");
685 return;
686
687fatal_mondo_timeout:
688 local_irq_restore(flags);
689 printk(KERN_CRIT "CPU[%d]: SUN4V mondo timeout, no forward "
690 " progress after %d retries.\n",
691 this_cpu, retries);
692 goto dump_cpu_list_and_out;
693
694fatal_mondo_error:
695 local_irq_restore(flags);
696 printk(KERN_CRIT "CPU[%d]: Unexpected SUN4V mondo error %lu\n",
697 this_cpu, status);
698 printk(KERN_CRIT "CPU[%d]: Args were cnt(%d) cpulist_pa(%lx) "
699 "mondo_block_pa(%lx)\n",
700 this_cpu, cnt, tb->cpu_list_pa, tb->cpu_mondo_block_pa);
701
702dump_cpu_list_and_out:
703 printk(KERN_CRIT "CPU[%d]: CPU list [ ", this_cpu);
704 for (i = 0; i < cnt; i++)
705 printk("%u ", cpu_list[i]);
706 printk("]\n");
707}
708
547/* Send cross call to all processors mentioned in MASK 709/* Send cross call to all processors mentioned in MASK
548 * except self. 710 * except self.
549 */ 711 */
@@ -557,8 +719,10 @@ static void smp_cross_call_masked(unsigned long *func, u32 ctx, u64 data1, u64 d
557 719
558 if (tlb_type == spitfire) 720 if (tlb_type == spitfire)
559 spitfire_xcall_deliver(data0, data1, data2, mask); 721 spitfire_xcall_deliver(data0, data1, data2, mask);
560 else 722 else if (tlb_type == cheetah || tlb_type == cheetah_plus)
561 cheetah_xcall_deliver(data0, data1, data2, mask); 723 cheetah_xcall_deliver(data0, data1, data2, mask);
724 else
725 hypervisor_xcall_deliver(data0, data1, data2, mask);
562 /* NOTE: Caller runs local copy on master. */ 726 /* NOTE: Caller runs local copy on master. */
563 727
564 put_cpu(); 728 put_cpu();
@@ -594,16 +758,13 @@ extern unsigned long xcall_call_function;
594 * You must not call this function with disabled interrupts or from a 758 * You must not call this function with disabled interrupts or from a
595 * hardware interrupt handler or from a bottom half handler. 759 * hardware interrupt handler or from a bottom half handler.
596 */ 760 */
597int smp_call_function(void (*func)(void *info), void *info, 761static int smp_call_function_mask(void (*func)(void *info), void *info,
598 int nonatomic, int wait) 762 int nonatomic, int wait, cpumask_t mask)
599{ 763{
600 struct call_data_struct data; 764 struct call_data_struct data;
601 int cpus = num_online_cpus() - 1; 765 int cpus;
602 long timeout; 766 long timeout;
603 767
604 if (!cpus)
605 return 0;
606
607 /* Can deadlock when called with interrupts disabled */ 768 /* Can deadlock when called with interrupts disabled */
608 WARN_ON(irqs_disabled()); 769 WARN_ON(irqs_disabled());
609 770
@@ -614,9 +775,14 @@ int smp_call_function(void (*func)(void *info), void *info,
614 775
615 spin_lock(&call_lock); 776 spin_lock(&call_lock);
616 777
778 cpu_clear(smp_processor_id(), mask);
779 cpus = cpus_weight(mask);
780 if (!cpus)
781 goto out_unlock;
782
617 call_data = &data; 783 call_data = &data;
618 784
619 smp_cross_call(&xcall_call_function, 0, 0, 0); 785 smp_cross_call_masked(&xcall_call_function, 0, 0, 0, mask);
620 786
621 /* 787 /*
622 * Wait for other cpus to complete function or at 788 * Wait for other cpus to complete function or at
@@ -630,18 +796,25 @@ int smp_call_function(void (*func)(void *info), void *info,
630 udelay(1); 796 udelay(1);
631 } 797 }
632 798
799out_unlock:
633 spin_unlock(&call_lock); 800 spin_unlock(&call_lock);
634 801
635 return 0; 802 return 0;
636 803
637out_timeout: 804out_timeout:
638 spin_unlock(&call_lock); 805 spin_unlock(&call_lock);
639 printk("XCALL: Remote cpus not responding, ncpus=%ld finished=%ld\n", 806 printk("XCALL: Remote cpus not responding, ncpus=%d finished=%d\n",
640 (long) num_online_cpus() - 1L, 807 cpus, atomic_read(&data.finished));
641 (long) atomic_read(&data.finished));
642 return 0; 808 return 0;
643} 809}
644 810
811int smp_call_function(void (*func)(void *info), void *info,
812 int nonatomic, int wait)
813{
814 return smp_call_function_mask(func, info, nonatomic, wait,
815 cpu_online_map);
816}
817
645void smp_call_function_client(int irq, struct pt_regs *regs) 818void smp_call_function_client(int irq, struct pt_regs *regs)
646{ 819{
647 void (*func) (void *info) = call_data->func; 820 void (*func) (void *info) = call_data->func;
@@ -659,13 +832,25 @@ void smp_call_function_client(int irq, struct pt_regs *regs)
659 } 832 }
660} 833}
661 834
835static void tsb_sync(void *info)
836{
837 struct mm_struct *mm = info;
838
839 if (current->active_mm == mm)
840 tsb_context_switch(mm);
841}
842
843void smp_tsb_sync(struct mm_struct *mm)
844{
845 smp_call_function_mask(tsb_sync, mm, 0, 1, mm->cpu_vm_mask);
846}
847
662extern unsigned long xcall_flush_tlb_mm; 848extern unsigned long xcall_flush_tlb_mm;
663extern unsigned long xcall_flush_tlb_pending; 849extern unsigned long xcall_flush_tlb_pending;
664extern unsigned long xcall_flush_tlb_kernel_range; 850extern unsigned long xcall_flush_tlb_kernel_range;
665extern unsigned long xcall_flush_tlb_all_spitfire;
666extern unsigned long xcall_flush_tlb_all_cheetah;
667extern unsigned long xcall_report_regs; 851extern unsigned long xcall_report_regs;
668extern unsigned long xcall_receive_signal; 852extern unsigned long xcall_receive_signal;
853extern unsigned long xcall_new_mmu_context_version;
669 854
670#ifdef DCACHE_ALIASING_POSSIBLE 855#ifdef DCACHE_ALIASING_POSSIBLE
671extern unsigned long xcall_flush_dcache_page_cheetah; 856extern unsigned long xcall_flush_dcache_page_cheetah;
@@ -693,11 +878,17 @@ static __inline__ void __local_flush_dcache_page(struct page *page)
693void smp_flush_dcache_page_impl(struct page *page, int cpu) 878void smp_flush_dcache_page_impl(struct page *page, int cpu)
694{ 879{
695 cpumask_t mask = cpumask_of_cpu(cpu); 880 cpumask_t mask = cpumask_of_cpu(cpu);
696 int this_cpu = get_cpu(); 881 int this_cpu;
882
883 if (tlb_type == hypervisor)
884 return;
697 885
698#ifdef CONFIG_DEBUG_DCFLUSH 886#ifdef CONFIG_DEBUG_DCFLUSH
699 atomic_inc(&dcpage_flushes); 887 atomic_inc(&dcpage_flushes);
700#endif 888#endif
889
890 this_cpu = get_cpu();
891
701 if (cpu == this_cpu) { 892 if (cpu == this_cpu) {
702 __local_flush_dcache_page(page); 893 __local_flush_dcache_page(page);
703 } else if (cpu_online(cpu)) { 894 } else if (cpu_online(cpu)) {
@@ -713,7 +904,7 @@ void smp_flush_dcache_page_impl(struct page *page, int cpu)
713 __pa(pg_addr), 904 __pa(pg_addr),
714 (u64) pg_addr, 905 (u64) pg_addr,
715 mask); 906 mask);
716 } else { 907 } else if (tlb_type == cheetah || tlb_type == cheetah_plus) {
717#ifdef DCACHE_ALIASING_POSSIBLE 908#ifdef DCACHE_ALIASING_POSSIBLE
718 data0 = 909 data0 =
719 ((u64)&xcall_flush_dcache_page_cheetah); 910 ((u64)&xcall_flush_dcache_page_cheetah);
@@ -735,7 +926,12 @@ void flush_dcache_page_all(struct mm_struct *mm, struct page *page)
735 void *pg_addr = page_address(page); 926 void *pg_addr = page_address(page);
736 cpumask_t mask = cpu_online_map; 927 cpumask_t mask = cpu_online_map;
737 u64 data0; 928 u64 data0;
738 int this_cpu = get_cpu(); 929 int this_cpu;
930
931 if (tlb_type == hypervisor)
932 return;
933
934 this_cpu = get_cpu();
739 935
740 cpu_clear(this_cpu, mask); 936 cpu_clear(this_cpu, mask);
741 937
@@ -752,7 +948,7 @@ void flush_dcache_page_all(struct mm_struct *mm, struct page *page)
752 __pa(pg_addr), 948 __pa(pg_addr),
753 (u64) pg_addr, 949 (u64) pg_addr,
754 mask); 950 mask);
755 } else { 951 } else if (tlb_type == cheetah || tlb_type == cheetah_plus) {
756#ifdef DCACHE_ALIASING_POSSIBLE 952#ifdef DCACHE_ALIASING_POSSIBLE
757 data0 = ((u64)&xcall_flush_dcache_page_cheetah); 953 data0 = ((u64)&xcall_flush_dcache_page_cheetah);
758 cheetah_xcall_deliver(data0, 954 cheetah_xcall_deliver(data0,
@@ -769,38 +965,58 @@ void flush_dcache_page_all(struct mm_struct *mm, struct page *page)
769 put_cpu(); 965 put_cpu();
770} 966}
771 967
968static void __smp_receive_signal_mask(cpumask_t mask)
969{
970 smp_cross_call_masked(&xcall_receive_signal, 0, 0, 0, mask);
971}
972
772void smp_receive_signal(int cpu) 973void smp_receive_signal(int cpu)
773{ 974{
774 cpumask_t mask = cpumask_of_cpu(cpu); 975 cpumask_t mask = cpumask_of_cpu(cpu);
775 976
776 if (cpu_online(cpu)) { 977 if (cpu_online(cpu))
777 u64 data0 = (((u64)&xcall_receive_signal) & 0xffffffff); 978 __smp_receive_signal_mask(mask);
778
779 if (tlb_type == spitfire)
780 spitfire_xcall_deliver(data0, 0, 0, mask);
781 else
782 cheetah_xcall_deliver(data0, 0, 0, mask);
783 }
784} 979}
785 980
786void smp_receive_signal_client(int irq, struct pt_regs *regs) 981void smp_receive_signal_client(int irq, struct pt_regs *regs)
787{ 982{
788 /* Just return, rtrap takes care of the rest. */
789 clear_softint(1 << irq); 983 clear_softint(1 << irq);
790} 984}
791 985
792void smp_report_regs(void) 986void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
793{ 987{
794 smp_cross_call(&xcall_report_regs, 0, 0, 0); 988 struct mm_struct *mm;
989 unsigned long flags;
990
991 clear_softint(1 << irq);
992
993 /* See if we need to allocate a new TLB context because
994 * the version of the one we are using is now out of date.
995 */
996 mm = current->active_mm;
997 if (unlikely(!mm || (mm == &init_mm)))
998 return;
999
1000 spin_lock_irqsave(&mm->context.lock, flags);
1001
1002 if (unlikely(!CTX_VALID(mm->context)))
1003 get_new_mmu_context(mm);
1004
1005 spin_unlock_irqrestore(&mm->context.lock, flags);
1006
1007 load_secondary_context(mm);
1008 __flush_tlb_mm(CTX_HWBITS(mm->context),
1009 SECONDARY_CONTEXT);
795} 1010}
796 1011
797void smp_flush_tlb_all(void) 1012void smp_new_mmu_context_version(void)
798{ 1013{
799 if (tlb_type == spitfire) 1014 smp_cross_call(&xcall_new_mmu_context_version, 0, 0, 0);
800 smp_cross_call(&xcall_flush_tlb_all_spitfire, 0, 0, 0); 1015}
801 else 1016
802 smp_cross_call(&xcall_flush_tlb_all_cheetah, 0, 0, 0); 1017void smp_report_regs(void)
803 __flush_tlb_all(); 1018{
1019 smp_cross_call(&xcall_report_regs, 0, 0, 0);
804} 1020}
805 1021
806/* We know that the window frames of the user have been flushed 1022/* We know that the window frames of the user have been flushed
@@ -944,24 +1160,19 @@ void smp_release(void)
944 * can service tlb flush xcalls... 1160 * can service tlb flush xcalls...
945 */ 1161 */
946extern void prom_world(int); 1162extern void prom_world(int);
947extern void save_alternate_globals(unsigned long *); 1163
948extern void restore_alternate_globals(unsigned long *);
949void smp_penguin_jailcell(int irq, struct pt_regs *regs) 1164void smp_penguin_jailcell(int irq, struct pt_regs *regs)
950{ 1165{
951 unsigned long global_save[24];
952
953 clear_softint(1 << irq); 1166 clear_softint(1 << irq);
954 1167
955 preempt_disable(); 1168 preempt_disable();
956 1169
957 __asm__ __volatile__("flushw"); 1170 __asm__ __volatile__("flushw");
958 save_alternate_globals(global_save);
959 prom_world(1); 1171 prom_world(1);
960 atomic_inc(&smp_capture_registry); 1172 atomic_inc(&smp_capture_registry);
961 membar_storeload_storestore(); 1173 membar_storeload_storestore();
962 while (penguins_are_doing_time) 1174 while (penguins_are_doing_time)
963 rmb(); 1175 rmb();
964 restore_alternate_globals(global_save);
965 atomic_dec(&smp_capture_registry); 1176 atomic_dec(&smp_capture_registry);
966 prom_world(0); 1177 prom_world(0);
967 1178
@@ -1082,6 +1293,8 @@ int setup_profiling_timer(unsigned int multiplier)
1082/* Constrain the number of cpus to max_cpus. */ 1293/* Constrain the number of cpus to max_cpus. */
1083void __init smp_prepare_cpus(unsigned int max_cpus) 1294void __init smp_prepare_cpus(unsigned int max_cpus)
1084{ 1295{
1296 int i;
1297
1085 if (num_possible_cpus() > max_cpus) { 1298 if (num_possible_cpus() > max_cpus) {
1086 int instance, mid; 1299 int instance, mid;
1087 1300
@@ -1096,6 +1309,20 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
1096 } 1309 }
1097 } 1310 }
1098 1311
1312 for_each_cpu(i) {
1313 if (tlb_type == hypervisor) {
1314 int j;
1315
1316 /* XXX get this mapping from machine description */
1317 for_each_cpu(j) {
1318 if ((j >> 2) == (i >> 2))
1319 cpu_set(j, cpu_sibling_map[i]);
1320 }
1321 } else {
1322 cpu_set(i, cpu_sibling_map[i]);
1323 }
1324 }
1325
1099 smp_store_cpu_info(boot_cpu_id); 1326 smp_store_cpu_info(boot_cpu_id);
1100} 1327}
1101 1328
@@ -1117,12 +1344,15 @@ void __init smp_setup_cpu_possible_map(void)
1117 1344
1118void __devinit smp_prepare_boot_cpu(void) 1345void __devinit smp_prepare_boot_cpu(void)
1119{ 1346{
1120 if (hard_smp_processor_id() >= NR_CPUS) { 1347 int cpu = hard_smp_processor_id();
1348
1349 if (cpu >= NR_CPUS) {
1121 prom_printf("Serious problem, boot cpu id >= NR_CPUS\n"); 1350 prom_printf("Serious problem, boot cpu id >= NR_CPUS\n");
1122 prom_halt(); 1351 prom_halt();
1123 } 1352 }
1124 1353
1125 current_thread_info()->cpu = hard_smp_processor_id(); 1354 current_thread_info()->cpu = cpu;
1355 __local_per_cpu_offset = __per_cpu_offset(cpu);
1126 1356
1127 cpu_set(smp_processor_id(), cpu_online_map); 1357 cpu_set(smp_processor_id(), cpu_online_map);
1128 cpu_set(smp_processor_id(), phys_cpu_present_map); 1358 cpu_set(smp_processor_id(), phys_cpu_present_map);
@@ -1139,7 +1369,11 @@ int __devinit __cpu_up(unsigned int cpu)
1139 if (!cpu_isset(cpu, cpu_online_map)) { 1369 if (!cpu_isset(cpu, cpu_online_map)) {
1140 ret = -ENODEV; 1370 ret = -ENODEV;
1141 } else { 1371 } else {
1142 smp_synchronize_one_tick(cpu); 1372 /* On SUN4V, writes to %tick and %stick are
1373 * not allowed.
1374 */
1375 if (tlb_type != hypervisor)
1376 smp_synchronize_one_tick(cpu);
1143 } 1377 }
1144 } 1378 }
1145 return ret; 1379 return ret;
@@ -1183,12 +1417,9 @@ void __init setup_per_cpu_areas(void)
1183{ 1417{
1184 unsigned long goal, size, i; 1418 unsigned long goal, size, i;
1185 char *ptr; 1419 char *ptr;
1186 /* Created by linker magic */
1187 extern char __per_cpu_start[], __per_cpu_end[];
1188 1420
1189 /* Copy section for each CPU (we discard the original) */ 1421 /* Copy section for each CPU (we discard the original) */
1190 goal = ALIGN(__per_cpu_end - __per_cpu_start, PAGE_SIZE); 1422 goal = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
1191
1192#ifdef CONFIG_MODULES 1423#ifdef CONFIG_MODULES
1193 if (goal < PERCPU_ENOUGH_ROOM) 1424 if (goal < PERCPU_ENOUGH_ROOM)
1194 goal = PERCPU_ENOUGH_ROOM; 1425 goal = PERCPU_ENOUGH_ROOM;
@@ -1197,31 +1428,10 @@ void __init setup_per_cpu_areas(void)
1197 for (size = 1UL; size < goal; size <<= 1UL) 1428 for (size = 1UL; size < goal; size <<= 1UL)
1198 __per_cpu_shift++; 1429 __per_cpu_shift++;
1199 1430
1200 /* Make sure the resulting __per_cpu_base value 1431 ptr = alloc_bootmem(size * NR_CPUS);
1201 * will fit in the 43-bit sign extended IMMU
1202 * TSB register.
1203 */
1204 ptr = __alloc_bootmem(size * NR_CPUS, PAGE_SIZE,
1205 (unsigned long) __per_cpu_start);
1206 1432
1207 __per_cpu_base = ptr - __per_cpu_start; 1433 __per_cpu_base = ptr - __per_cpu_start;
1208 1434
1209 if ((__per_cpu_shift < PAGE_SHIFT) ||
1210 (__per_cpu_base & ~PAGE_MASK) ||
1211 (__per_cpu_base != (((long) __per_cpu_base << 20) >> 20))) {
1212 prom_printf("PER_CPU: Invalid layout, "
1213 "ptr[%p] shift[%lx] base[%lx]\n",
1214 ptr, __per_cpu_shift, __per_cpu_base);
1215 prom_halt();
1216 }
1217
1218 for (i = 0; i < NR_CPUS; i++, ptr += size) 1435 for (i = 0; i < NR_CPUS; i++, ptr += size)
1219 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); 1436 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
1220
1221 /* Finally, load in the boot cpu's base value.
1222 * We abuse the IMMU TSB register for trap handler
1223 * entry and exit loading of %g5. That is why it
1224 * has to be page aligned.
1225 */
1226 cpu_setup_percpu_base(hard_smp_processor_id());
1227} 1437}