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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: SCCS/s.smp.c 1.37 11/23/01 16:38:30 paulus
  3.  */
  4. /*
  5.  * Smp support for ppc.
  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 <linux/cache.h>
  26. #include <asm/ptrace.h>
  27. #include <asm/atomic.h>
  28. #include <asm/irq.h>
  29. #include <asm/page.h>
  30. #include <asm/pgtable.h>
  31. #include <asm/hardirq.h>
  32. #include <asm/softirq.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. int smp_threads_ready;
  39. volatile int smp_commenced;
  40. int smp_num_cpus = 1;
  41. int smp_tb_synchronized;
  42. struct cpuinfo_PPC cpu_data[NR_CPUS];
  43. struct klock_info_struct klock_info = { KLOCK_CLEAR, 0 };
  44. atomic_t ipi_recv;
  45. atomic_t ipi_sent;
  46. spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
  47. unsigned int prof_multiplier[NR_CPUS];
  48. unsigned int prof_counter[NR_CPUS];
  49. cycles_t cacheflush_time;
  50. static int max_cpus __initdata = NR_CPUS;
  51. unsigned long cpu_online_map;
  52. int smp_hw_index[NR_CPUS];
  53. static struct smp_ops_t *smp_ops;
  54. /* all cpu mappings are 1-1 -- Cort */
  55. volatile unsigned long cpu_callin_map[NR_CPUS];
  56. #define TB_SYNC_PASSES 4
  57. volatile unsigned long __initdata tb_sync_flag = 0;
  58. volatile unsigned long __initdata tb_offset = 0;
  59. int start_secondary(void *);
  60. extern int cpu_idle(void *unused);
  61. void smp_call_function_interrupt(void);
  62. void smp_message_pass(int target, int msg, unsigned long data, int wait);
  63. /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
  64.  * 
  65.  * Make sure this matches openpic_request_IPIs in open_pic.c, or what shows up
  66.  * in /proc/interrupts will be wrong!!! --Troy */
  67. #define PPC_MSG_CALL_FUNCTION 0
  68. #define PPC_MSG_RESCHEDULE 1
  69. #define PPC_MSG_INVALIDATE_TLB 2
  70. #define PPC_MSG_XMON_BREAK 3
  71. #define smp_message_pass(t,m,d,w) 
  72.     do { if (smp_ops) 
  73.      atomic_inc(&ipi_sent); 
  74.      smp_ops->message_pass((t),(m),(d),(w)); 
  75.        } while(0)
  76. /* 
  77.  * Common functions
  78.  */
  79. void smp_local_timer_interrupt(struct pt_regs * regs)
  80. {
  81. int cpu = smp_processor_id();
  82. if (!--prof_counter[cpu]) {
  83. update_process_times(user_mode(regs));
  84. prof_counter[cpu]=prof_multiplier[cpu];
  85. }
  86. }
  87. void smp_message_recv(int msg, struct pt_regs *regs)
  88. {
  89. atomic_inc(&ipi_recv);
  90. switch( msg ) {
  91. case PPC_MSG_CALL_FUNCTION:
  92. smp_call_function_interrupt();
  93. break;
  94. case PPC_MSG_RESCHEDULE: 
  95. current->need_resched = 1;
  96. break;
  97. case PPC_MSG_INVALIDATE_TLB:
  98. _tlbia();
  99. break;
  100. #ifdef CONFIG_XMON
  101. case PPC_MSG_XMON_BREAK:
  102. xmon(regs);
  103. break;
  104. #endif /* CONFIG_XMON */
  105. default:
  106. printk("SMP %d: smp_message_recv(): unknown msg %dn",
  107.        smp_processor_id(), msg);
  108. break;
  109. }
  110. }
  111. /*
  112.  * 750's don't broadcast tlb invalidates so
  113.  * we have to emulate that behavior.
  114.  *   -- Cort
  115.  */
  116. void smp_send_tlb_invalidate(int cpu)
  117. {
  118. if ( PVR_VER(mfspr(PVR)) == 8 )
  119. smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_INVALIDATE_TLB, 0, 0);
  120. }
  121. void smp_send_reschedule(int cpu)
  122. {
  123. /*
  124.  * This is only used if `cpu' is running an idle task,
  125.  * so it will reschedule itself anyway...
  126.  *
  127.  * This isn't the case anymore since the other CPU could be
  128.  * sleeping and won't reschedule until the next interrupt (such
  129.  * as the timer).
  130.  *  -- Cort
  131.  */
  132. /* This is only used if `cpu' is running an idle task,
  133.    so it will reschedule itself anyway... */
  134. smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0);
  135. }
  136. #ifdef CONFIG_XMON
  137. void smp_send_xmon_break(int cpu)
  138. {
  139. smp_message_pass(cpu, PPC_MSG_XMON_BREAK, 0, 0);
  140. }
  141. #endif /* CONFIG_XMON */
  142. static void stop_this_cpu(void *dummy)
  143. {
  144. __cli();
  145. while (1)
  146. ;
  147. }
  148. void smp_send_stop(void)
  149. {
  150. smp_call_function(stop_this_cpu, NULL, 1, 0);
  151. smp_num_cpus = 1;
  152. }
  153. /*
  154.  * Structure and data for smp_call_function(). This is designed to minimise
  155.  * static memory requirements. It also looks cleaner.
  156.  * Stolen from the i386 version.
  157.  */
  158. static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
  159. static struct call_data_struct {
  160. void (*func) (void *info);
  161. void *info;
  162. atomic_t started;
  163. atomic_t finished;
  164. int wait;
  165. } *call_data;
  166. /*
  167.  * this function sends a 'generic call function' IPI to all other CPUs
  168.  * in the system.
  169.  */
  170. int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
  171. int wait)
  172. /*
  173.  * [SUMMARY] Run a function on all other CPUs.
  174.  * <func> The function to run. This must be fast and non-blocking.
  175.  * <info> An arbitrary pointer to pass to the function.
  176.  * <nonatomic> currently unused.
  177.  * <wait> If true, wait (atomically) until function has completed on other CPUs.
  178.  * [RETURNS] 0 on success, else a negative status code. Does not return until
  179.  * remote CPUs are nearly ready to execute <<func>> or are or have executed.
  180.  *
  181.  * You must not call this function with disabled interrupts or from a
  182.  * hardware interrupt handler, you may call it from a bottom half handler.
  183.  */
  184. {
  185. struct call_data_struct data;
  186. int ret = -1, cpus = smp_num_cpus-1;
  187. int timeout;
  188. if (!cpus)
  189. return 0;
  190. data.func = func;
  191. data.info = info;
  192. atomic_set(&data.started, 0);
  193. data.wait = wait;
  194. if (wait)
  195. atomic_set(&data.finished, 0);
  196. spin_lock_bh(&call_lock);
  197. call_data = &data;
  198. /* Send a message to all other CPUs and wait for them to respond */
  199. smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION, 0, 0);
  200. /* Wait for response */
  201. timeout = 1000000;
  202. while (atomic_read(&data.started) != cpus) {
  203. if (--timeout == 0) {
  204. printk("smp_call_function on cpu %d: other cpus not responding (%d)n",
  205.        smp_processor_id(), atomic_read(&data.started));
  206. goto out;
  207. }
  208. barrier();
  209. udelay(1);
  210. }
  211. if (wait) {
  212. timeout = 1000000;
  213. while (atomic_read(&data.finished) != cpus) {
  214. if (--timeout == 0) {
  215. printk("smp_call_function on cpu %d: other cpus not finishing (%d/%d)n",
  216.        smp_processor_id(), atomic_read(&data.finished), atomic_read(&data.started));
  217. goto out;
  218. }
  219. barrier();
  220. udelay(1);
  221. }
  222. }
  223. ret = 0;
  224.  out:
  225. spin_unlock_bh(&call_lock);
  226. return ret;
  227. }
  228. void smp_call_function_interrupt(void)
  229. {
  230. void (*func) (void *info) = call_data->func;
  231. void *info = call_data->info;
  232. int wait = call_data->wait;
  233. /*
  234.  * Notify initiating CPU that I've grabbed the data and am
  235.  * about to execute the function
  236.  */
  237. atomic_inc(&call_data->started);
  238. /*
  239.  * At this point the info structure may be out of scope unless wait==1
  240.  */
  241. (*func)(info);
  242. if (wait)
  243. atomic_inc(&call_data->finished);
  244. }
  245. void __init smp_boot_cpus(void)
  246. {
  247. extern struct task_struct *current_set[NR_CPUS];
  248. int i, cpu_nr;
  249. struct task_struct *p;
  250. printk("Entering SMP Mode...n");
  251. smp_num_cpus = 1;
  252.         smp_store_cpu_info(0);
  253. cpu_online_map = 1UL;
  254. /*
  255.  * assume for now that the first cpu booted is
  256.  * cpu 0, the master -- Cort
  257.  */
  258. cpu_callin_map[0] = 1;
  259. current->processor = 0;
  260. init_idle();
  261. for (i = 0; i < NR_CPUS; i++) {
  262. prof_counter[i] = 1;
  263. prof_multiplier[i] = 1;
  264. }
  265. /*
  266.  * XXX very rough, assumes 20 bus cycles to read a cache line,
  267.  * timebase increments every 4 bus cycles, 32kB L1 data cache.
  268.  */
  269. cacheflush_time = 5 * 1024;
  270. smp_ops = ppc_md.smp_ops;
  271. if (smp_ops == NULL) {
  272. printk("SMP not supported on this machine.n");
  273. return;
  274. }
  275. /* Probe arch for CPUs */
  276. cpu_nr = smp_ops->probe();
  277. /*
  278.  * only check for cpus we know exist.  We keep the callin map
  279.  * with cpus at the bottom -- Cort
  280.  */
  281. if (cpu_nr > max_cpus)
  282. cpu_nr = max_cpus;
  283. for (i = 1; i < cpu_nr; i++) {
  284. int c;
  285. struct pt_regs regs;
  286. /* create a process for the processor */
  287. /* only regs.msr is actually used, and 0 is OK for it */
  288. memset(&regs, 0, sizeof(struct pt_regs));
  289. if (do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0) < 0)
  290. panic("failed fork for CPU %d", i);
  291. p = init_task.prev_task;
  292. if (!p)
  293. panic("No idle task for CPU %d", i);
  294. del_from_runqueue(p);
  295. unhash_process(p);
  296. init_tasks[i] = p;
  297. p->processor = i;
  298. p->cpus_runnable = 1 << i; /* we schedule the first task manually */
  299. current_set[i] = p;
  300. /*
  301.  * There was a cache flush loop here to flush the cache
  302.  * to memory for the first 8MB of RAM.  The cache flush
  303.  * has been pushed into the kick_cpu function for those
  304.  * platforms that need it.
  305.  */
  306. /* wake up cpus */
  307. smp_ops->kick_cpu(i);
  308. /*
  309.  * wait to see if the cpu made a callin (is actually up).
  310.  * use this value that I found through experimentation.
  311.  * -- Cort
  312.  */
  313. for ( c = 1000; c && !cpu_callin_map[i] ; c-- )
  314. udelay(100);
  315. if ( cpu_callin_map[i] )
  316. {
  317. char buf[32];
  318. sprintf(buf, "found cpu %d", i);
  319. if (ppc_md.progress) ppc_md.progress(buf, 0x350+i);
  320. printk("Processor %d found.n", i);
  321. smp_num_cpus++;
  322. } else {
  323. char buf[32];
  324. sprintf(buf, "didn't find cpu %d", i);
  325. if (ppc_md.progress) ppc_md.progress(buf, 0x360+i);
  326. printk("Processor %d is stuck.n", i);
  327. }
  328. }
  329. /* Setup CPU 0 last (important) */
  330. smp_ops->setup_cpu(0);
  331. if (smp_num_cpus < 2)
  332. smp_tb_synchronized = 1;
  333. }
  334. void __init smp_software_tb_sync(int cpu)
  335. {
  336. #define PASSES 4 /* 4 passes.. */
  337. int pass;
  338. int i, j;
  339. /* stop - start will be the number of timebase ticks it takes for cpu0
  340.  * to send a message to all others and the first reponse to show up.
  341.  *
  342.  * ASSUMPTION: this time is similiar for all cpus
  343.  * ASSUMPTION: the time to send a one-way message is ping/2
  344.  */
  345. register unsigned long start = 0;
  346. register unsigned long stop = 0;
  347. register unsigned long temp = 0;
  348. set_tb(0, 0);
  349. /* multiple passes to get in l1 cache.. */
  350. for (pass = 2; pass < 2+PASSES; pass++){
  351. if (cpu == 0){
  352. mb();
  353. for (i = j = 1; i < smp_num_cpus; i++, j++){
  354. /* skip stuck cpus */
  355. while (!cpu_callin_map[j])
  356. ++j;
  357. while (cpu_callin_map[j] != pass)
  358. barrier();
  359. }
  360. mb();
  361. tb_sync_flag = pass;
  362. start = get_tbl(); /* start timing */
  363. while (tb_sync_flag)
  364. mb();
  365. stop = get_tbl(); /* end timing */
  366. /* theoretically, the divisor should be 2, but
  367.  * I get better results on my dual mtx. someone
  368.  * please report results on other smp machines..
  369.  */
  370. tb_offset = (stop-start)/4;
  371. mb();
  372. tb_sync_flag = pass;
  373. udelay(10);
  374. mb();
  375. tb_sync_flag = 0;
  376. mb();
  377. set_tb(0,0);
  378. mb();
  379. } else {
  380. cpu_callin_map[cpu] = pass;
  381. mb();
  382. while (!tb_sync_flag)
  383. mb(); /* wait for cpu0 */
  384. mb();
  385. tb_sync_flag = 0; /* send response for timing */
  386. mb();
  387. while (!tb_sync_flag)
  388. mb();
  389. temp = tb_offset; /* make sure offset is loaded */
  390. while (tb_sync_flag)
  391. mb();
  392. set_tb(0,temp); /* now, set the timebase */
  393. mb();
  394. }
  395. }
  396. if (cpu == 0) {
  397. smp_tb_synchronized = 1;
  398. printk("smp_software_tb_sync: %d passes, final offset: %ldn",
  399. PASSES, tb_offset);
  400. }
  401. /* so time.c doesn't get confused */
  402. set_dec(tb_ticks_per_jiffy);
  403. last_jiffy_stamp(cpu) = 0;
  404. }
  405. void __init smp_commence(void)
  406. {
  407. /*
  408.  * Lets the callin's below out of their loop.
  409.  */
  410. if (ppc_md.progress) ppc_md.progress("smp_commence", 0x370);
  411. wmb();
  412. smp_commenced = 1;
  413. /* if the smp_ops->setup_cpu function has not already synched the
  414.  * timebases with a nicer hardware-based method, do so now
  415.  *
  416.  * I am open to suggestions for improvements to this method
  417.  * -- Troy <hozer@drgw.net>
  418.  *
  419.  * NOTE: if you are debugging, set smp_tb_synchronized for now
  420.  * since if this code runs pretty early and needs all cpus that
  421.  * reported in in smp_callin_map to be working
  422.  *
  423.  * NOTE2: this code doesn't seem to work on > 2 cpus. -- paulus/BenH
  424.  */
  425. if (!smp_tb_synchronized && smp_num_cpus == 2) {
  426. unsigned long flags;
  427. __save_and_cli(flags);
  428. smp_software_tb_sync(0);
  429. __restore_flags(flags);
  430. }
  431. }
  432. void __init smp_callin(void)
  433. {
  434. int cpu = current->processor;
  435.         smp_store_cpu_info(cpu);
  436. set_dec(tb_ticks_per_jiffy);
  437. cpu_callin_map[cpu] = 1;
  438. smp_ops->setup_cpu(cpu);
  439. /*
  440.  * This cpu is now "online".  Only set them online
  441.  * before they enter the loop below since write access
  442.  * to the below variable is _not_ guaranteed to be
  443.  * atomic.
  444.  *   -- Cort <cort@fsmlabs.com>
  445.  */
  446. cpu_online_map |= 1UL << smp_processor_id();
  447. while(!smp_commenced)
  448. barrier();
  449. /* see smp_commence for more info */
  450. if (!smp_tb_synchronized && smp_num_cpus == 2) {
  451. smp_software_tb_sync(cpu);
  452. }
  453. __sti();
  454. }
  455. /* intel needs this */
  456. void __init initialize_secondary(void)
  457. {
  458. }
  459. /* Activate a secondary processor. */
  460. int __init start_secondary(void *unused)
  461. {
  462. atomic_inc(&init_mm.mm_count);
  463. current->active_mm = &init_mm;
  464. smp_callin();
  465. return cpu_idle(NULL);
  466. }
  467. void __init smp_setup(char *str, int *ints)
  468. {
  469. }
  470. int __init setup_profiling_timer(unsigned int multiplier)
  471. {
  472. return 0;
  473. }
  474. void __init smp_store_cpu_info(int id)
  475. {
  476.         struct cpuinfo_PPC *c = &cpu_data[id];
  477. /* assume bogomips are same for everything */
  478.         c->loops_per_jiffy = loops_per_jiffy;
  479.         c->pvr = mfspr(PVR);
  480. }
  481. static int __init maxcpus(char *str)
  482. {
  483. get_option(&str, &max_cpus);
  484. return 1;
  485. }
  486. __setup("maxcpus=", maxcpus);