smp.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. * arch/sh/kernel/smp.c
  3. *
  4. * SMP support for the SuperH processors.
  5. *
  6. * Copyright (C) 2002, 2003 Paul Mundt
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by the
  10. * Free Software Foundation; either version 2 of the License, or (at your
  11. * option) any later version.
  12. */
  13. #include <linux/err.h>
  14. #include <linux/cache.h>
  15. #include <linux/cpumask.h>
  16. #include <linux/delay.h>
  17. #include <linux/init.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/spinlock.h>
  20. #include <linux/threads.h>
  21. #include <linux/module.h>
  22. #include <linux/time.h>
  23. #include <linux/timex.h>
  24. #include <linux/sched.h>
  25. #include <linux/module.h>
  26. #include <asm/atomic.h>
  27. #include <asm/processor.h>
  28. #include <asm/system.h>
  29. #include <asm/mmu_context.h>
  30. #include <asm/smp.h>
  31. /*
  32. * This was written with the Sega Saturn (SMP SH-2 7604) in mind,
  33. * but is designed to be usable regardless if there's an MMU
  34. * present or not.
  35. */
  36. struct sh_cpuinfo cpu_data[NR_CPUS];
  37. extern void per_cpu_trap_init(void);
  38. cpumask_t cpu_possible_map;
  39. EXPORT_SYMBOL(cpu_possible_map);
  40. cpumask_t cpu_online_map;
  41. EXPORT_SYMBOL(cpu_online_map);
  42. static atomic_t cpus_booted = ATOMIC_INIT(0);
  43. /* These are defined by the board-specific code. */
  44. /*
  45. * Cause the function described by call_data to be executed on the passed
  46. * cpu. When the function has finished, increment the finished field of
  47. * call_data.
  48. */
  49. void __smp_send_ipi(unsigned int cpu, unsigned int action);
  50. /*
  51. * Find the number of available processors
  52. */
  53. unsigned int __smp_probe_cpus(void);
  54. /*
  55. * Start a particular processor
  56. */
  57. void __smp_slave_init(unsigned int cpu);
  58. /*
  59. * Run specified function on a particular processor.
  60. */
  61. void __smp_call_function(unsigned int cpu);
  62. static inline void __init smp_store_cpu_info(unsigned int cpu)
  63. {
  64. cpu_data[cpu].loops_per_jiffy = loops_per_jiffy;
  65. }
  66. void __init smp_prepare_cpus(unsigned int max_cpus)
  67. {
  68. unsigned int cpu = smp_processor_id();
  69. int i;
  70. atomic_set(&cpus_booted, 1);
  71. smp_store_cpu_info(cpu);
  72. for (i = 0; i < __smp_probe_cpus(); i++)
  73. cpu_set(i, cpu_possible_map);
  74. }
  75. void __devinit smp_prepare_boot_cpu(void)
  76. {
  77. unsigned int cpu = smp_processor_id();
  78. cpu_set(cpu, cpu_online_map);
  79. cpu_set(cpu, cpu_possible_map);
  80. }
  81. int __cpu_up(unsigned int cpu)
  82. {
  83. struct task_struct *tsk;
  84. tsk = fork_idle(cpu);
  85. if (IS_ERR(tsk))
  86. panic("Failed forking idle task for cpu %d\n", cpu);
  87. task_thread_info(tsk)->cpu = cpu;
  88. cpu_set(cpu, cpu_online_map);
  89. return 0;
  90. }
  91. int start_secondary(void *unused)
  92. {
  93. unsigned int cpu;
  94. cpu = smp_processor_id();
  95. atomic_inc(&init_mm.mm_count);
  96. current->active_mm = &init_mm;
  97. smp_store_cpu_info(cpu);
  98. __smp_slave_init(cpu);
  99. preempt_disable();
  100. per_cpu_trap_init();
  101. atomic_inc(&cpus_booted);
  102. cpu_idle();
  103. return 0;
  104. }
  105. void __init smp_cpus_done(unsigned int max_cpus)
  106. {
  107. smp_mb();
  108. }
  109. void smp_send_reschedule(int cpu)
  110. {
  111. __smp_send_ipi(cpu, SMP_MSG_RESCHEDULE);
  112. }
  113. static void stop_this_cpu(void *unused)
  114. {
  115. cpu_clear(smp_processor_id(), cpu_online_map);
  116. local_irq_disable();
  117. for (;;)
  118. cpu_relax();
  119. }
  120. void smp_send_stop(void)
  121. {
  122. smp_call_function(stop_this_cpu, 0, 1, 0);
  123. }
  124. struct smp_fn_call_struct smp_fn_call = {
  125. .lock = SPIN_LOCK_UNLOCKED,
  126. .finished = ATOMIC_INIT(0),
  127. };
  128. /*
  129. * The caller of this wants the passed function to run on every cpu. If wait
  130. * is set, wait until all cpus have finished the function before returning.
  131. * The lock is here to protect the call structure.
  132. * You must not call this function with disabled interrupts or from a
  133. * hardware interrupt handler or from a bottom half handler.
  134. */
  135. int smp_call_function(void (*func)(void *info), void *info, int retry, int wait)
  136. {
  137. unsigned int nr_cpus = atomic_read(&cpus_booted);
  138. int i;
  139. if (nr_cpus < 2)
  140. return 0;
  141. /* Can deadlock when called with interrupts disabled */
  142. WARN_ON(irqs_disabled());
  143. spin_lock(&smp_fn_call.lock);
  144. atomic_set(&smp_fn_call.finished, 0);
  145. smp_fn_call.fn = func;
  146. smp_fn_call.data = info;
  147. for (i = 0; i < nr_cpus; i++)
  148. if (i != smp_processor_id())
  149. __smp_call_function(i);
  150. if (wait)
  151. while (atomic_read(&smp_fn_call.finished) != (nr_cpus - 1));
  152. spin_unlock(&smp_fn_call.lock);
  153. return 0;
  154. }
  155. /* Not really SMP stuff ... */
  156. int setup_profiling_timer(unsigned int multiplier)
  157. {
  158. return 0;
  159. }