preliminaryDataProcessing.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * linux/arch/alpha/kernel/smp.c
  3. *
  4. * 2001-07-09 Phil Ezolt (Phillip.Ezolt@compaq.com)
  5. * Renamed modified smp_call_function to smp_call_function_on_cpu()
  6. * Created an function that conforms to the old calling convention
  7. * of smp_call_function().
  8. *
  9. * This is helpful for DCPI.
  10. *
  11. */
  12. #include <linux/errno.h>
  13. #include <linux/kernel.h>
  14. #include <linux/kernel_stat.h>
  15. #include <linux/module.h>
  16. #include <linux/sched.h>
  17. #include <linux/mm.h>
  18. #include <linux/err.h>
  19. #include <linux/threads.h>
  20. #include <linux/smp.h>
  21. #include <linux/interrupt.h>
  22. #include <linux/init.h>
  23. #include <linux/delay.h>
  24. #include <linux/spinlock.h>
  25. #include <linux/irq.h>
  26. #include <linux/cache.h>
  27. #include <linux/profile.h>
  28. #include <linux/bitops.h>
  29. #include <linux/cpu.h>
  30. #include <asm/hwrpb.h>
  31. #include <asm/ptrace.h>
  32. #include <linux/atomic.h>
  33. #include <asm/io.h>
  34. #include <asm/irq.h>
  35. #include <asm/pgtable.h>
  36. #include <asm/pgalloc.h>
  37. #include <asm/mmu_context.h>
  38. #include <asm/tlbflush.h>
  39. #include "proto.h"
  40. #include "irq_impl.h"
  41. #define DEBUG_SMP 0
  42. #if DEBUG_SMP
  43. #define DBGS(args) printk args
  44. #else
  45. #define DBGS(args)
  46. #endif
  47. /* A collection of per-processor data. */
  48. struct cpuinfo_alpha cpu_data[NR_CPUS];
  49. EXPORT_SYMBOL(cpu_data);
  50. /* A collection of single bit ipi messages. */
  51. static struct {
  52. unsigned long bits ____cacheline_aligned;
  53. } ipi_data[NR_CPUS] __cacheline_aligned;
  54. enum ipi_message_type {
  55. IPI_RESCHEDULE,
  56. IPI_CALL_FUNC,
  57. IPI_CALL_FUNC_SINGLE,
  58. IPI_CPU_STOP,
  59. };
  60. /* Set to a secondary's cpuid when it comes online. */
  61. static int smp_secondary_alive = 0;
  62. int smp_num_probed; /* Internal processor count */
  63. int smp_num_cpus = 1; /* Number that came online. */
  64. EXPORT_SYMBOL(smp_num_cpus);
  65. /*
  66. * Called by both boot and secondaries to move global data into
  67. * per-processor storage.
  68. */
  69. static inline void __init
  70. smp_store_cpu_info(int cpuid)
  71. {
  72. cpu_data[cpuid].loops_per_jiffy = loops_per_jiffy;
  73. cpu_data[cpuid].last_asn = ASN_FIRST_VERSION;
  74. cpu_data[cpuid].need_new_asn = 0;
  75. cpu_data[cpuid].asn_lock = 0;
  76. }
  77. /*
  78. * Ideally sets up per-cpu profiling hooks. Doesn't do much now...
  79. */
  80. static inline void __init
  81. smp_setup_percpu_timer(int cpuid)
  82. {
  83. cpu_data[cpuid].prof_counter = 1;
  84. cpu_data[cpuid].prof_multiplier = 1;
  85. }
  86. static void __init
  87. wait_boot_cpu_to_stop(int cpuid)
  88. {
  89. unsigned long stop = jiffies + 10*HZ;
  90. while (time_before(jiffies, stop)) {
  91. if (!smp_secondary_alive)
  92. return;
  93. barrier();
  94. }
  95. printk("wait_boot_cpu_to_stop: FAILED on CPU %d, hanging now\n", cpuid);
  96. for (;;)
  97. barrier();
  98. }
  99. /*
  100. * Where secondaries begin a life of C.
  101. */
  102. void __cpuinit
  103. smp_callin(void)
  104. {
  105. int cpuid = hard_smp_processor_id();
  106. if (cpu_online(cpuid)) {
  107. printk("??, cpu 0x%x already present??\n", cpuid);
  108. BUG();
  109. }
  110. set_cpu_online(cpuid, true);
  111. /* Turn on machine checks. */
  112. wrmces(7);
  113. /* Set trap vectors. */
  114. trap_init();
  115. /* Set interrupt vector. */
  116. wrent(entInt, 0);
  117. /* Get our local ticker going. */
  118. smp_setup_percpu_timer(cpuid);
  119. /* Call platform-specific callin, if specified */
  120. if (alpha_mv.smp_callin) alpha_mv.smp_callin();
  121. /* All kernel threads share the same mm context. */
  122. atomic_inc(&init_mm.mm_count);
  123. current->active_mm = &init_mm;
  124. /* inform the notifiers about the new cpu */
  125. notify_cpu_starting(cpuid);
  126. /* Must have completely accurate bogos. */
  127. local_irq_enable();
  128. /* Wait boot CPU to stop with irq enabled before running
  129. calibrate_delay. */
  130. wait_boot_cpu_to_stop(cpuid);
  131. mb();
  132. calibrate_delay();
  133. smp_store_cpu_info(cpuid);
  134. /* Allow master to continue only after we written loops_per_jiffy. */
  135. wmb();
  136. smp_secondary_alive = 1;
  137. DBGS(("smp_callin: commencing CPU %d current %p active_mm %p\n",
  138. cpuid, current, current->active_mm));