• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * This program is free software; you can redistribute it and/or
3   * modify it under the terms of the GNU General Public License
4   * as published by the Free Software Foundation; either version 2
5   * of the License, or (at your option) any later version.
6   *
7   * This program is distributed in the hope that it will be useful,
8   * but WITHOUT ANY WARRANTY; without even the implied warranty of
9   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10   * GNU General Public License for more details.
11   *
12   * You should have received a copy of the GNU General Public License
13   * along with this program; if not, write to the Free Software
14   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
15   *
16   * Copyright (C) 2000, 2001 Kanoj Sarcar
17   * Copyright (C) 2000, 2001 Ralf Baechle
18   * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
19   * Copyright (C) 2000, 2001, 2003 Broadcom Corporation
20   */
21  #include <linux/cache.h>
22  #include <linux/delay.h>
23  #include <linux/init.h>
24  #include <linux/interrupt.h>
25  #include <linux/smp.h>
26  #include <linux/spinlock.h>
27  #include <linux/threads.h>
28  #include <linux/module.h>
29  #include <linux/time.h>
30  #include <linux/timex.h>
31  #include <linux/sched.h>
32  #include <linux/cpumask.h>
33  #include <linux/cpu.h>
34  #include <linux/err.h>
35  #include <linux/ftrace.h>
36  
37  #include <linux/atomic.h>
38  #include <asm/cpu.h>
39  #include <asm/processor.h>
40  #include <asm/idle.h>
41  #include <asm/r4k-timer.h>
42  #include <asm/mmu_context.h>
43  #include <asm/time.h>
44  #include <asm/setup.h>
45  
46  volatile cpumask_t cpu_callin_map;	/* Bitmask of started secondaries */
47  
48  int __cpu_number_map[NR_CPUS];		/* Map physical to logical */
49  EXPORT_SYMBOL(__cpu_number_map);
50  
51  int __cpu_logical_map[NR_CPUS];		/* Map logical to physical */
52  EXPORT_SYMBOL(__cpu_logical_map);
53  
54  /* Number of TCs (or siblings in Intel speak) per CPU core */
55  int smp_num_siblings = 1;
56  EXPORT_SYMBOL(smp_num_siblings);
57  
58  /* representing the TCs (or siblings in Intel speak) of each logical CPU */
59  cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
60  EXPORT_SYMBOL(cpu_sibling_map);
61  
62  /* representing the core map of multi-core chips of each logical CPU */
63  cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
64  EXPORT_SYMBOL(cpu_core_map);
65  
66  /*
67   * A logcal cpu mask containing only one VPE per core to
68   * reduce the number of IPIs on large MT systems.
69   */
70  cpumask_t cpu_foreign_map __read_mostly;
71  EXPORT_SYMBOL(cpu_foreign_map);
72  
73  /* representing cpus for which sibling maps can be computed */
74  static cpumask_t cpu_sibling_setup_map;
75  
76  /* representing cpus for which core maps can be computed */
77  static cpumask_t cpu_core_setup_map;
78  
79  cpumask_t cpu_coherent_mask;
80  
set_cpu_sibling_map(int cpu)81  static inline void set_cpu_sibling_map(int cpu)
82  {
83  	int i;
84  
85  	cpu_set(cpu, cpu_sibling_setup_map);
86  
87  	if (smp_num_siblings > 1) {
88  		for_each_cpu_mask(i, cpu_sibling_setup_map) {
89  			if (cpu_data[cpu].package == cpu_data[i].package &&
90  				    cpu_data[cpu].core == cpu_data[i].core) {
91  				cpu_set(i, cpu_sibling_map[cpu]);
92  				cpu_set(cpu, cpu_sibling_map[i]);
93  			}
94  		}
95  	} else
96  		cpu_set(cpu, cpu_sibling_map[cpu]);
97  }
98  
set_cpu_core_map(int cpu)99  static inline void set_cpu_core_map(int cpu)
100  {
101  	int i;
102  
103  	cpu_set(cpu, cpu_core_setup_map);
104  
105  	for_each_cpu_mask(i, cpu_core_setup_map) {
106  		if (cpu_data[cpu].package == cpu_data[i].package) {
107  			cpu_set(i, cpu_core_map[cpu]);
108  			cpu_set(cpu, cpu_core_map[i]);
109  		}
110  	}
111  }
112  
113  /*
114   * Calculate a new cpu_foreign_map mask whenever a
115   * new cpu appears or disappears.
116   */
calculate_cpu_foreign_map(void)117  static inline void calculate_cpu_foreign_map(void)
118  {
119  	int i, k, core_present;
120  	cpumask_t temp_foreign_map;
121  
122  	/* Re-calculate the mask */
123  	for_each_online_cpu(i) {
124  		core_present = 0;
125  		for_each_cpu(k, &temp_foreign_map)
126  			if (cpu_data[i].package == cpu_data[k].package &&
127  			    cpu_data[i].core == cpu_data[k].core)
128  				core_present = 1;
129  		if (!core_present)
130  			cpumask_set_cpu(i, &temp_foreign_map);
131  	}
132  
133  	cpumask_copy(&cpu_foreign_map, &temp_foreign_map);
134  }
135  
136  struct plat_smp_ops *mp_ops;
137  EXPORT_SYMBOL(mp_ops);
138  
register_smp_ops(struct plat_smp_ops * ops)139  void register_smp_ops(struct plat_smp_ops *ops)
140  {
141  	if (mp_ops)
142  		printk(KERN_WARNING "Overriding previously set SMP ops\n");
143  
144  	mp_ops = ops;
145  }
146  
147  /*
148   * First C code run on the secondary CPUs after being started up by
149   * the master.
150   */
start_secondary(void)151  asmlinkage void start_secondary(void)
152  {
153  	unsigned int cpu;
154  
155  	cpu_probe();
156  	per_cpu_trap_init(false);
157  	mips_clockevent_init();
158  	mp_ops->init_secondary();
159  	cpu_report();
160  
161  	/*
162  	 * XXX parity protection should be folded in here when it's converted
163  	 * to an option instead of something based on .cputype
164  	 */
165  
166  	calibrate_delay();
167  	preempt_disable();
168  	cpu = smp_processor_id();
169  	cpu_data[cpu].udelay_val = loops_per_jiffy;
170  
171  	cpu_set(cpu, cpu_coherent_mask);
172  	notify_cpu_starting(cpu);
173  
174  	set_cpu_online(cpu, true);
175  
176  	set_cpu_sibling_map(cpu);
177  	set_cpu_core_map(cpu);
178  
179  	calculate_cpu_foreign_map();
180  
181  	cpu_set(cpu, cpu_callin_map);
182  
183  	synchronise_count_slave(cpu);
184  
185  	/*
186  	 * irq will be enabled in ->smp_finish(), enabling it too early
187  	 * is dangerous.
188  	 */
189  	WARN_ON_ONCE(!irqs_disabled());
190  	mp_ops->smp_finish();
191  
192  	cpu_startup_entry(CPUHP_ONLINE);
193  }
194  
195  /*
196   * Call into both interrupt handlers, as we share the IPI for them
197   */
smp_call_function_interrupt(void)198  void __irq_entry smp_call_function_interrupt(void)
199  {
200  	irq_enter();
201  	generic_smp_call_function_interrupt();
202  	irq_exit();
203  }
204  
stop_this_cpu(void * dummy)205  static void stop_this_cpu(void *dummy)
206  {
207  	/*
208  	 * Remove this CPU. Be a bit slow here and
209  	 * set the bits for every online CPU so we don't miss
210  	 * any IPI whilst taking this VPE down.
211  	 */
212  
213  	cpumask_copy(&cpu_foreign_map, cpu_online_mask);
214  
215  	/* Make it visible to every other CPU */
216  	smp_mb();
217  
218  	set_cpu_online(smp_processor_id(), false);
219  	calculate_cpu_foreign_map();
220  	local_irq_disable();
221  	while (1);
222  }
223  
smp_send_stop(void)224  void smp_send_stop(void)
225  {
226  	smp_call_function(stop_this_cpu, NULL, 0);
227  }
228  
smp_cpus_done(unsigned int max_cpus)229  void __init smp_cpus_done(unsigned int max_cpus)
230  {
231  }
232  
233  /* called from main before smp_init() */
smp_prepare_cpus(unsigned int max_cpus)234  void __init smp_prepare_cpus(unsigned int max_cpus)
235  {
236  	init_new_context(current, &init_mm);
237  	current_thread_info()->cpu = 0;
238  	mp_ops->prepare_cpus(max_cpus);
239  	set_cpu_sibling_map(0);
240  	set_cpu_core_map(0);
241  	calculate_cpu_foreign_map();
242  #ifndef CONFIG_HOTPLUG_CPU
243  	init_cpu_present(cpu_possible_mask);
244  #endif
245  	cpumask_copy(&cpu_coherent_mask, cpu_possible_mask);
246  }
247  
248  /* preload SMP state for boot cpu */
smp_prepare_boot_cpu(void)249  void smp_prepare_boot_cpu(void)
250  {
251  	set_cpu_possible(0, true);
252  	set_cpu_online(0, true);
253  	cpu_set(0, cpu_callin_map);
254  }
255  
__cpu_up(unsigned int cpu,struct task_struct * tidle)256  int __cpu_up(unsigned int cpu, struct task_struct *tidle)
257  {
258  	mp_ops->boot_secondary(cpu, tidle);
259  
260  	/*
261  	 * Trust is futile.  We should really have timeouts ...
262  	 */
263  	while (!cpu_isset(cpu, cpu_callin_map))
264  		udelay(100);
265  
266  	synchronise_count_master(cpu);
267  	return 0;
268  }
269  
270  /* Not really SMP stuff ... */
setup_profiling_timer(unsigned int multiplier)271  int setup_profiling_timer(unsigned int multiplier)
272  {
273  	return 0;
274  }
275  
flush_tlb_all_ipi(void * info)276  static void flush_tlb_all_ipi(void *info)
277  {
278  	local_flush_tlb_all();
279  }
280  
flush_tlb_all(void)281  void flush_tlb_all(void)
282  {
283  	on_each_cpu(flush_tlb_all_ipi, NULL, 1);
284  }
285  
flush_tlb_mm_ipi(void * mm)286  static void flush_tlb_mm_ipi(void *mm)
287  {
288  	local_flush_tlb_mm((struct mm_struct *)mm);
289  }
290  
291  /*
292   * Special Variant of smp_call_function for use by TLB functions:
293   *
294   *  o No return value
295   *  o collapses to normal function call on UP kernels
296   *  o collapses to normal function call on systems with a single shared
297   *    primary cache.
298   */
smp_on_other_tlbs(void (* func)(void * info),void * info)299  static inline void smp_on_other_tlbs(void (*func) (void *info), void *info)
300  {
301  	smp_call_function(func, info, 1);
302  }
303  
smp_on_each_tlb(void (* func)(void * info),void * info)304  static inline void smp_on_each_tlb(void (*func) (void *info), void *info)
305  {
306  	preempt_disable();
307  
308  	smp_on_other_tlbs(func, info);
309  	func(info);
310  
311  	preempt_enable();
312  }
313  
314  /*
315   * The following tlb flush calls are invoked when old translations are
316   * being torn down, or pte attributes are changing. For single threaded
317   * address spaces, a new context is obtained on the current cpu, and tlb
318   * context on other cpus are invalidated to force a new context allocation
319   * at switch_mm time, should the mm ever be used on other cpus. For
320   * multithreaded address spaces, intercpu interrupts have to be sent.
321   * Another case where intercpu interrupts are required is when the target
322   * mm might be active on another cpu (eg debuggers doing the flushes on
323   * behalf of debugees, kswapd stealing pages from another process etc).
324   * Kanoj 07/00.
325   */
326  
flush_tlb_mm(struct mm_struct * mm)327  void flush_tlb_mm(struct mm_struct *mm)
328  {
329  	preempt_disable();
330  
331  	if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
332  		smp_on_other_tlbs(flush_tlb_mm_ipi, mm);
333  	} else {
334  		unsigned int cpu;
335  
336  		for_each_online_cpu(cpu) {
337  			if (cpu != smp_processor_id() && cpu_context(cpu, mm))
338  				cpu_context(cpu, mm) = 0;
339  		}
340  	}
341  	local_flush_tlb_mm(mm);
342  
343  	preempt_enable();
344  }
345  
346  struct flush_tlb_data {
347  	struct vm_area_struct *vma;
348  	unsigned long addr1;
349  	unsigned long addr2;
350  };
351  
flush_tlb_range_ipi(void * info)352  static void flush_tlb_range_ipi(void *info)
353  {
354  	struct flush_tlb_data *fd = info;
355  
356  	local_flush_tlb_range(fd->vma, fd->addr1, fd->addr2);
357  }
358  
flush_tlb_range(struct vm_area_struct * vma,unsigned long start,unsigned long end)359  void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
360  {
361  	struct mm_struct *mm = vma->vm_mm;
362  
363  	preempt_disable();
364  	if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
365  		struct flush_tlb_data fd = {
366  			.vma = vma,
367  			.addr1 = start,
368  			.addr2 = end,
369  		};
370  
371  		smp_on_other_tlbs(flush_tlb_range_ipi, &fd);
372  	} else {
373  		unsigned int cpu;
374  
375  		for_each_online_cpu(cpu) {
376  			if (cpu != smp_processor_id() && cpu_context(cpu, mm))
377  				cpu_context(cpu, mm) = 0;
378  		}
379  	}
380  	local_flush_tlb_range(vma, start, end);
381  	preempt_enable();
382  }
383  
flush_tlb_kernel_range_ipi(void * info)384  static void flush_tlb_kernel_range_ipi(void *info)
385  {
386  	struct flush_tlb_data *fd = info;
387  
388  	local_flush_tlb_kernel_range(fd->addr1, fd->addr2);
389  }
390  
flush_tlb_kernel_range(unsigned long start,unsigned long end)391  void flush_tlb_kernel_range(unsigned long start, unsigned long end)
392  {
393  	struct flush_tlb_data fd = {
394  		.addr1 = start,
395  		.addr2 = end,
396  	};
397  
398  	on_each_cpu(flush_tlb_kernel_range_ipi, &fd, 1);
399  }
400  
flush_tlb_page_ipi(void * info)401  static void flush_tlb_page_ipi(void *info)
402  {
403  	struct flush_tlb_data *fd = info;
404  
405  	local_flush_tlb_page(fd->vma, fd->addr1);
406  }
407  
flush_tlb_page(struct vm_area_struct * vma,unsigned long page)408  void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
409  {
410  	preempt_disable();
411  	if ((atomic_read(&vma->vm_mm->mm_users) != 1) || (current->mm != vma->vm_mm)) {
412  		struct flush_tlb_data fd = {
413  			.vma = vma,
414  			.addr1 = page,
415  		};
416  
417  		smp_on_other_tlbs(flush_tlb_page_ipi, &fd);
418  	} else {
419  		unsigned int cpu;
420  
421  		for_each_online_cpu(cpu) {
422  			if (cpu != smp_processor_id() && cpu_context(cpu, vma->vm_mm))
423  				cpu_context(cpu, vma->vm_mm) = 0;
424  		}
425  	}
426  	local_flush_tlb_page(vma, page);
427  	preempt_enable();
428  }
429  
flush_tlb_one_ipi(void * info)430  static void flush_tlb_one_ipi(void *info)
431  {
432  	unsigned long vaddr = (unsigned long) info;
433  
434  	local_flush_tlb_one(vaddr);
435  }
436  
flush_tlb_one(unsigned long vaddr)437  void flush_tlb_one(unsigned long vaddr)
438  {
439  	smp_on_each_tlb(flush_tlb_one_ipi, (void *) vaddr);
440  }
441  
442  EXPORT_SYMBOL(flush_tlb_page);
443  EXPORT_SYMBOL(flush_tlb_one);
444  
445  #if defined(CONFIG_KEXEC)
446  void (*dump_ipi_function_ptr)(void *) = NULL;
dump_send_ipi(void (* dump_ipi_callback)(void *))447  void dump_send_ipi(void (*dump_ipi_callback)(void *))
448  {
449  	int i;
450  	int cpu = smp_processor_id();
451  
452  	dump_ipi_function_ptr = dump_ipi_callback;
453  	smp_mb();
454  	for_each_online_cpu(i)
455  		if (i != cpu)
456  			mp_ops->send_ipi_single(i, SMP_DUMP);
457  
458  }
459  EXPORT_SYMBOL(dump_send_ipi);
460  #endif
461  
462  #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
463  
464  static DEFINE_PER_CPU(atomic_t, tick_broadcast_count);
465  static DEFINE_PER_CPU(struct call_single_data, tick_broadcast_csd);
466  
tick_broadcast(const struct cpumask * mask)467  void tick_broadcast(const struct cpumask *mask)
468  {
469  	atomic_t *count;
470  	struct call_single_data *csd;
471  	int cpu;
472  
473  	for_each_cpu(cpu, mask) {
474  		count = &per_cpu(tick_broadcast_count, cpu);
475  		csd = &per_cpu(tick_broadcast_csd, cpu);
476  
477  		if (atomic_inc_return(count) == 1)
478  			smp_call_function_single_async(cpu, csd);
479  	}
480  }
481  
tick_broadcast_callee(void * info)482  static void tick_broadcast_callee(void *info)
483  {
484  	int cpu = smp_processor_id();
485  	tick_receive_broadcast();
486  	atomic_set(&per_cpu(tick_broadcast_count, cpu), 0);
487  }
488  
tick_broadcast_init(void)489  static int __init tick_broadcast_init(void)
490  {
491  	struct call_single_data *csd;
492  	int cpu;
493  
494  	for (cpu = 0; cpu < NR_CPUS; cpu++) {
495  		csd = &per_cpu(tick_broadcast_csd, cpu);
496  		csd->func = tick_broadcast_callee;
497  	}
498  
499  	return 0;
500  }
501  early_initcall(tick_broadcast_init);
502  
503  #endif /* CONFIG_GENERIC_CLOCKEVENTS_BROADCAST */
504