chrp_smp.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: %F% %I% %G% %U% %#%
  3.  */
  4. /*
  5.  * Smp support for CHRP machines.
  6.  *
  7.  * Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great
  8.  * deal of code from the sparc and intel versions.
  9.  *
  10.  * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
  11.  *
  12.  */
  13. #include <linux/config.h>
  14. #include <linux/kernel.h>
  15. #include <linux/sched.h>
  16. #include <linux/smp.h>
  17. #include <linux/smp_lock.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/kernel_stat.h>
  20. #include <linux/delay.h>
  21. #define __KERNEL_SYSCALLS__
  22. #include <linux/unistd.h>
  23. #include <linux/init.h>
  24. #include <linux/spinlock.h>
  25. #include <asm/ptrace.h>
  26. #include <asm/atomic.h>
  27. #include <asm/irq.h>
  28. #include <asm/page.h>
  29. #include <asm/pgtable.h>
  30. #include <asm/hardirq.h>
  31. #include <asm/softirq.h>
  32. #include <asm/sections.h>
  33. #include <asm/io.h>
  34. #include <asm/prom.h>
  35. #include <asm/smp.h>
  36. #include <asm/residual.h>
  37. #include <asm/time.h>
  38. #include "open_pic.h"
  39. extern unsigned long smp_chrp_cpu_nr;
  40. static int __init
  41. smp_chrp_probe(void)
  42. {
  43. if (smp_chrp_cpu_nr > 1)
  44. openpic_request_IPIs();
  45. return smp_chrp_cpu_nr;
  46. }
  47. static void __init
  48. smp_chrp_kick_cpu(int nr)
  49. {
  50. *(unsigned long *)KERNELBASE = nr;
  51. asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
  52. }
  53. static void __init
  54. smp_chrp_setup_cpu(int cpu_nr)
  55. {
  56. static atomic_t ready = ATOMIC_INIT(1);
  57. static volatile int frozen = 0;
  58. if (cpu_nr == 0) {
  59. /* wait for all the others */
  60. while (atomic_read(&ready) < smp_num_cpus)
  61. barrier();
  62. atomic_set(&ready, 1);
  63. /* freeze the timebase */
  64. call_rtas("freeze-time-base", 0, 1, NULL);
  65. mb();
  66. frozen = 1;
  67. /* XXX assumes this is not a 601 */
  68. set_tb(0, 0);
  69. last_jiffy_stamp(0) = 0;
  70. while (atomic_read(&ready) < smp_num_cpus)
  71. barrier();
  72. /* thaw the timebase again */
  73. call_rtas("thaw-time-base", 0, 1, NULL);
  74. mb();
  75. frozen = 0;
  76. smp_tb_synchronized = 1;
  77. } else {
  78. atomic_inc(&ready);
  79. while (!frozen)
  80. barrier();
  81. set_tb(0, 0);
  82. last_jiffy_stamp(0) = 0;
  83. mb();
  84. atomic_inc(&ready);
  85. while (frozen)
  86. barrier();
  87. }
  88. if (OpenPIC_Addr)
  89. do_openpic_setup_cpu();
  90. }
  91. #ifdef CONFIG_POWER4
  92. static void __chrp
  93. smp_xics_message_pass(int target, int msg, unsigned long data, int wait)
  94. {
  95. /* for now, only do reschedule messages
  96.    since we only have one IPI */
  97. if (msg != PPC_MSG_RESCHEDULE)
  98. return;
  99. for (i = 0; i < smp_num_cpus; ++i) {
  100. if (target == MSG_ALL || target == i
  101.     || (target == MSG_ALL_BUT_SELF
  102. && i != smp_processor_id()))
  103. xics_cause_IPI(i);
  104. }
  105. }
  106. static int __chrp
  107. smp_xics_probe(void)
  108. {
  109. return smp_chrp_cpu_nr;
  110. }
  111. static void __chrp
  112. smp_xics_setup_cpu(int cpu_nr)
  113. {
  114. if (cpu_nr > 0)
  115. xics_setup_cpu();
  116. }
  117. #endif /* CONFIG_POWER4 */
  118. /* CHRP with openpic */
  119. struct smp_ops_t chrp_smp_ops __chrpdata = {
  120. smp_openpic_message_pass,
  121. smp_chrp_probe,
  122. smp_chrp_kick_cpu,
  123. smp_chrp_setup_cpu,
  124. };
  125. #ifdef CONFIG_POWER4
  126. /* CHRP with new XICS interrupt controller */
  127. struct smp_ops_t xics_smp_ops __chrpdata = {
  128. smp_xics_message_pass,
  129. smp_xics_probe,
  130. smp_chrp_kick_cpu,
  131. smp_xics_setup_cpu,
  132. };
  133. #endif /* CONFIG_POWER4 */