smp.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:18k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * 
  3.  *
  4.  * SMP support for ppc.
  5.  *
  6.  * Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great
  7.  * deal of code from the sparc and intel versions.
  8.  *
  9.  * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
  10.  *
  11.  * PowerPC-64 Support added by Dave Engebretsen, Peter Bergner, and
  12.  * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
  13.  *
  14.  *      This program is free software; you can redistribute it and/or
  15.  *      modify it under the terms of the GNU General Public License
  16.  *      as published by the Free Software Foundation; either version
  17.  *      2 of the License, or (at your option) any later version.
  18.  */
  19. #include <linux/config.h>
  20. #include <linux/kernel.h>
  21. #include <linux/sched.h>
  22. #include <linux/smp.h>
  23. #include <linux/smp_lock.h>
  24. #include <linux/interrupt.h>
  25. #include <linux/kernel_stat.h>
  26. #include <linux/delay.h>
  27. #define __KERNEL_SYSCALLS__
  28. #include <linux/unistd.h>
  29. #include <linux/init.h>
  30. /* #include <linux/openpic.h> */
  31. #include <linux/spinlock.h>
  32. #include <linux/cache.h>
  33. #include <asm/ptrace.h>
  34. #include <asm/atomic.h>
  35. #include <asm/irq.h>
  36. #include <asm/page.h>
  37. #include <asm/pgtable.h>
  38. #include <asm/hardirq.h>
  39. #include <asm/softirq.h>
  40. #include <asm/init.h>
  41. #include <asm/io.h>
  42. #include <asm/prom.h>
  43. #include <asm/smp.h>
  44. #include <asm/naca.h>
  45. #include <asm/paca.h>
  46. #include <asm/iSeries/LparData.h>
  47. #include <asm/iSeries/HvCall.h>
  48. #include <asm/iSeries/HvCallCfg.h>
  49. #include <asm/time.h>
  50. #include <asm/ppcdebug.h>
  51. #include "open_pic.h"
  52. #include <asm/machdep.h>
  53. #if defined(CONFIG_DUMP) || defined(CONFIG_DUMP_MODULE)
  54. int (*dump_ipi_function_ptr)(struct pt_regs *);
  55. #include <linux/dump.h>
  56. #endif
  57. #ifdef CONFIG_KDB
  58. #include <linux/kdb.h>
  59. #endif
  60. int smp_threads_ready = 0;
  61. volatile int smp_commenced = 0;
  62. int smp_num_cpus = 1;
  63. int smp_tb_synchronized = 0;
  64. extern atomic_t ipi_recv;
  65. extern atomic_t ipi_sent;
  66. spinlock_t kernel_flag __cacheline_aligned = SPIN_LOCK_UNLOCKED;
  67. cycles_t cacheflush_time;
  68. static int max_cpus __initdata = NR_CPUS;
  69. unsigned long cpu_online_map;
  70. volatile unsigned long cpu_callin_map[NR_CPUS] = {0,};
  71. #define TB_SYNC_PASSES 4
  72. volatile unsigned long __initdata tb_sync_flag = 0;
  73. volatile unsigned long __initdata tb_offset = 0;
  74. extern unsigned char stab_array[];
  75. int start_secondary(void *);
  76. extern int cpu_idle(void *unused);
  77. void smp_call_function_interrupt(void);
  78. void smp_message_pass(int target, int msg, unsigned long data, int wait);
  79. static unsigned long iSeries_smp_message[NR_CPUS];
  80. void xics_setup_cpu(void);
  81. void xics_cause_IPI(int cpu);
  82. /*
  83.  * XICS only has a single IPI, so encode the messages per CPU
  84.  */
  85. volatile unsigned long xics_ipi_message[NR_CPUS] = {0};
  86. #define smp_message_pass(t,m,d,w) 
  87.     do {     atomic_inc(&ipi_sent); 
  88.      ppc_md.smp_message_pass((t),(m),(d),(w)); 
  89.        } while(0)
  90. #ifdef CONFIG_KDB
  91. /* save regs here before calling kdb_ipi */
  92. struct pt_regs *kdb_smp_regs[NR_CPUS]; 
  93. /* called for each processor.. drop each into kdb. */
  94. void smp_kdb_stop_proc(void)
  95. {
  96.     kdb_ipi(kdb_smp_regs[smp_processor_id()], NULL);
  97. }
  98. void smp_kdb_stop(void)
  99. {
  100.   int ret=0;
  101.   ret =    smp_call_function(smp_kdb_stop_proc, NULL, 1, 0);
  102. }
  103. #endif
  104. static inline void set_tb(unsigned int upper, unsigned int lower)
  105. {
  106. mtspr(SPRN_TBWL, 0);
  107. mtspr(SPRN_TBWU, upper);
  108. mtspr(SPRN_TBWL, lower);
  109. }
  110. void iSeries_smp_message_recv( struct pt_regs * regs )
  111. {
  112. int cpu = smp_processor_id();
  113. int msg;
  114. if ( smp_num_cpus < 2 )
  115. return;
  116. for ( msg = 0; msg < 4; ++msg )
  117. if ( test_and_clear_bit( msg, &iSeries_smp_message[cpu] ) )
  118. smp_message_recv( msg, regs );
  119. }
  120. static void smp_iSeries_message_pass(int target, int msg, unsigned long data, int wait)
  121. {
  122. int i;
  123. for (i = 0; i < smp_num_cpus; ++i) {
  124. if ( (target == MSG_ALL) || 
  125.                     (target == i) || 
  126.                     ((target == MSG_ALL_BUT_SELF) && (i != smp_processor_id())) ) {
  127. set_bit( msg, &iSeries_smp_message[i] );
  128. HvCall_sendIPI(&(paca[i]));
  129. }
  130. }
  131. }
  132. static int smp_iSeries_numProcs(void)
  133. {
  134. unsigned np, i;
  135. struct ItLpPaca * lpPaca;
  136. np = 0;
  137.         for (i=0; i < MAX_PACAS; ++i) {
  138.                 lpPaca = paca[i].xLpPacaPtr;
  139.                 if ( lpPaca->xDynProcStatus < 2 ) {
  140.                         ++np;
  141.                 }
  142.         }
  143. return np;
  144. }
  145. static int smp_iSeries_probe(void)
  146. {
  147. unsigned i;
  148. unsigned np;
  149. struct ItLpPaca * lpPaca;
  150. np = 0;
  151. for (i=0; i < MAX_PACAS; ++i) {
  152. lpPaca = paca[i].xLpPacaPtr;
  153. if ( lpPaca->xDynProcStatus < 2 ) {
  154. ++np;
  155. paca[i].next_jiffy_update_tb = paca[0].next_jiffy_update_tb;
  156. }
  157. }
  158. smp_tb_synchronized = 1;
  159. return np;
  160. }
  161. static void smp_iSeries_kick_cpu(int nr)
  162. {
  163. struct ItLpPaca * lpPaca;
  164. /* Verify we have a Paca for processor nr */
  165. if ( ( nr <= 0 ) ||
  166.      ( nr >= MAX_PACAS ) )
  167. return;
  168. /* Verify that our partition has a processor nr */
  169. lpPaca = paca[nr].xLpPacaPtr;
  170. if ( lpPaca->xDynProcStatus >= 2 )
  171. return;
  172. /* The information for processor bringup must
  173.  * be written out to main store before we release
  174.  * the processor.
  175.  */
  176. mb();
  177. /* The processor is currently spinning, waiting
  178.  * for the xProcStart field to become non-zero
  179.  * After we set xProcStart, the processor will
  180.  * continue on to secondary_start in iSeries_head.S
  181.  */
  182. paca[nr].xProcStart = 1;
  183. }
  184. static void smp_iSeries_setup_cpu(int nr)
  185. {
  186. }
  187. /* This is called very early. */
  188. void smp_init_iSeries(void)
  189. {
  190. ppc_md.smp_message_pass = smp_iSeries_message_pass;
  191. ppc_md.smp_probe        = smp_iSeries_probe;
  192. ppc_md.smp_kick_cpu     = smp_iSeries_kick_cpu;
  193. ppc_md.smp_setup_cpu    = smp_iSeries_setup_cpu;
  194. naca->processorCount = smp_iSeries_numProcs();
  195. }
  196. static void
  197. smp_openpic_message_pass(int target, int msg, unsigned long data, int wait)
  198. {
  199. /* make sure we're sending something that translates to an IPI */
  200. if ( msg > 0x3 ){
  201. printk("SMP %d: smp_message_pass: unknown msg %dn",
  202.        smp_processor_id(), msg);
  203. return;
  204. }
  205. switch ( target )
  206. {
  207. case MSG_ALL:
  208. openpic_cause_IPI(msg, 0xffffffff);
  209. break;
  210. case MSG_ALL_BUT_SELF:
  211. openpic_cause_IPI(msg,
  212.   0xffffffff & ~(1 << smp_processor_id()));
  213. break;
  214. default:
  215. openpic_cause_IPI(msg, 1<<target);
  216. break;
  217. }
  218. }
  219. static int
  220. smp_chrp_probe(void)
  221. {
  222. if (naca->processorCount > 1)
  223. openpic_request_IPIs();
  224. return naca->processorCount;
  225. }
  226. static void
  227. smp_kick_cpu(int nr)
  228. {
  229. /* Verify we have a Paca for processor nr */
  230. if ( ( nr <= 0 ) ||
  231.      ( nr >= MAX_PACAS ) )
  232. return;
  233. /* The information for processor bringup must
  234.  * be written out to main store before we release
  235.  * the processor.
  236.  */
  237. mb();
  238. /* The processor is currently spinning, waiting
  239.  * for the xProcStart field to become non-zero
  240.  * After we set xProcStart, the processor will
  241.  * continue on to secondary_start in iSeries_head.S
  242.  */
  243. paca[nr].xProcStart = 1;
  244. }
  245. static void smp_space_timers( unsigned nr )
  246. {
  247. unsigned long offset, i;
  248. offset = tb_ticks_per_jiffy / nr;
  249. for ( i=1; i<nr; ++i ) {
  250. paca[i].next_jiffy_update_tb = paca[i-1].next_jiffy_update_tb + offset;
  251. }
  252. }
  253. static void
  254. smp_chrp_setup_cpu(int cpu_nr)
  255. {
  256. static atomic_t ready = ATOMIC_INIT(1);
  257. static volatile int frozen = 0;
  258. if (naca->platform == PLATFORM_PSERIES_LPAR) {
  259. /* timebases already synced under the hypervisor. */
  260. paca[cpu_nr].next_jiffy_update_tb = tb_last_stamp = get_tb();
  261. if (cpu_nr == 0) {
  262. naca->tb_orig_stamp = tb_last_stamp;
  263. /* Should update naca->stamp_xsec.
  264.  * For now we leave it which means the time can be some
  265.  * number of msecs off until someone does a settimeofday()
  266.  */
  267. }
  268. smp_tb_synchronized = 1;
  269. } else {
  270. if (cpu_nr == 0) {
  271. /* wait for all the others */
  272. while (atomic_read(&ready) < smp_num_cpus)
  273. barrier();
  274. atomic_set(&ready, 1);
  275. /* freeze the timebase */
  276. rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
  277. mb();
  278. frozen = 1;
  279. set_tb(0, 0);
  280. paca[0].next_jiffy_update_tb = 0;
  281. smp_space_timers(smp_num_cpus);
  282. while (atomic_read(&ready) < smp_num_cpus)
  283. barrier();
  284. /* thaw the timebase again */
  285. rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
  286. mb();
  287. frozen = 0;
  288. tb_last_stamp = get_tb();
  289. naca->tb_orig_stamp = tb_last_stamp;
  290. smp_tb_synchronized = 1;
  291. } else {
  292. atomic_inc(&ready);
  293. while (!frozen)
  294. barrier();
  295. set_tb(0, 0);
  296. mb();
  297. atomic_inc(&ready);
  298. while (frozen)
  299. barrier();
  300. }
  301. }
  302. if (OpenPIC_Addr) {
  303. do_openpic_setup_cpu();
  304. } else {
  305.   if (cpu_nr > 0)
  306.     xics_setup_cpu();
  307. }
  308. }
  309. static void
  310. smp_xics_message_pass(int target, int msg, unsigned long data, int wait)
  311. {
  312. int i;
  313. for (i = 0; i < smp_num_cpus; ++i) {
  314. if (target == MSG_ALL || target == i
  315.     || (target == MSG_ALL_BUT_SELF
  316. && i != smp_processor_id())) {
  317. set_bit(msg, &xics_ipi_message[i]);
  318. mb();
  319. xics_cause_IPI(i);
  320. }
  321. }
  322. }
  323. static int
  324. smp_xics_probe(void)
  325. {
  326. return naca->processorCount;
  327. }
  328. /* This is called very early */
  329. void smp_init_pSeries(void)
  330. {
  331. if(naca->interrupt_controller == IC_OPEN_PIC) {
  332. ppc_md.smp_message_pass = smp_openpic_message_pass;
  333. ppc_md.smp_probe        = smp_chrp_probe;
  334. ppc_md.smp_kick_cpu     = smp_kick_cpu;
  335. ppc_md.smp_setup_cpu    = smp_chrp_setup_cpu;
  336. } else {
  337. ppc_md.smp_message_pass = smp_xics_message_pass;
  338. ppc_md.smp_probe        = smp_xics_probe;
  339. ppc_md.smp_kick_cpu     = smp_kick_cpu;
  340. ppc_md.smp_setup_cpu    = smp_chrp_setup_cpu;
  341. }
  342. }
  343. void smp_local_timer_interrupt(struct pt_regs * regs)
  344. {
  345. if (!--(get_paca()->prof_counter)) {
  346. update_process_times(user_mode(regs));
  347. (get_paca()->prof_counter)=get_paca()->prof_multiplier;
  348. }
  349. }
  350. void smp_message_recv(int msg, struct pt_regs *regs)
  351. {
  352. atomic_inc(&ipi_recv);
  353. switch( msg ) {
  354. case PPC_MSG_CALL_FUNCTION:
  355. #ifdef CONFIG_KDB
  356. kdb_smp_regs[smp_processor_id()]=regs;
  357. #endif
  358. smp_call_function_interrupt();
  359. break;
  360. case PPC_MSG_RESCHEDULE: 
  361. current->need_resched = 1;
  362. break;
  363. #ifdef CONFIG_XMON
  364. case PPC_MSG_XMON_BREAK:
  365.         /* ToDo: need a nmi way to handle this.  Soft disable? */
  366. #if defined(CONFIG_DUMP) || defined(CONFIG_DUMP_MODULE)
  367.         if (dump_ipi_function_ptr) {
  368. printk(KERN_ALERT "got dump ipi...n");
  369. dump_ipi_function_ptr(regs);
  370. } else
  371. #endif
  372. xmon(regs);
  373. break;
  374. #endif /* CONFIG_XMON */
  375. default:
  376. printk("SMP %d: smp_message_recv(): unknown msg %dn",
  377.        smp_processor_id(), msg);
  378. break;
  379. }
  380. }
  381. void smp_send_reschedule(int cpu)
  382. {
  383. smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0);
  384. }
  385. #ifdef CONFIG_XMON
  386. void smp_send_xmon_break(int cpu)
  387. {
  388. smp_message_pass(cpu, PPC_MSG_XMON_BREAK, 0, 0);
  389. }
  390. #endif /* CONFIG_XMON */
  391. #if defined(CONFIG_DUMP) || defined(CONFIG_DUMP_MODULE)
  392. void dump_send_ipi(int (*dump_ipi_callback)(struct pt_regs *))
  393. {
  394. dump_ipi_function_ptr = dump_ipi_callback;
  395. if (dump_ipi_callback) {
  396. printk(KERN_ALERT "dump_send_ipi...n");
  397. mb();
  398. smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_XMON_BREAK, 0, 0);
  399. }
  400. }
  401. #endif
  402. static void stop_this_cpu(void *dummy)
  403. {
  404. __cli();
  405. while (1)
  406. ;
  407. }
  408. void smp_send_stop(void)
  409. {
  410. smp_call_function(stop_this_cpu, NULL, 1, 0);
  411. smp_num_cpus = 1;
  412. }
  413. /*
  414.  * Structure and data for smp_call_function(). This is designed to minimise
  415.  * static memory requirements. It also looks cleaner.
  416.  * Stolen from the i386 version.
  417.  */
  418. static spinlock_t call_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
  419. static struct call_data_struct {
  420. void (*func) (void *info);
  421. void *info;
  422. atomic_t started;
  423. atomic_t finished;
  424. int wait;
  425. } *call_data;
  426. /*
  427.  * This function sends a 'generic call function' IPI to all other CPUs
  428.  * in the system.
  429.  *
  430.  * [SUMMARY] Run a function on all other CPUs.
  431.  * <func> The function to run. This must be fast and non-blocking.
  432.  * <info> An arbitrary pointer to pass to the function.
  433.  * <nonatomic> currently unused.
  434.  * <wait> If true, wait (atomically) until function has completed on other CPUs.
  435.  * [RETURNS] 0 on success, else a negative status code. Does not return until
  436.  * remote CPUs are nearly ready to execute <<func>> or are or have executed.
  437.  *
  438.  * You must not call this function with disabled interrupts or from a
  439.  * hardware interrupt handler or from a bottom half handler.
  440.  */
  441. int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
  442. int wait)
  443. struct call_data_struct data;
  444. int ret = -1, cpus = smp_num_cpus-1;
  445. int timeout;
  446. if (!cpus)
  447. return 0;
  448. data.func = func;
  449. data.info = info;
  450. atomic_set(&data.started, 0);
  451. data.wait = wait;
  452. if (wait)
  453. atomic_set(&data.finished, 0);
  454. spin_lock_bh(&call_lock);
  455. call_data = &data;
  456. /* Send a message to all other CPUs and wait for them to respond */
  457. smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION, 0, 0);
  458. /* Wait for response */
  459. timeout = 8000000;
  460. while (atomic_read(&data.started) != cpus) {
  461. HMT_low();
  462. if (--timeout == 0) {
  463. printk("smp_call_function on cpu %d: other cpus not responding (%d)n",
  464.        smp_processor_id(), atomic_read(&data.started));
  465. #ifdef CONFIG_XMON
  466.                         xmon(0);
  467. #endif
  468. #ifdef CONFIG_KDB
  469. kdb(KDB_REASON_CALL,0, (kdb_eframe_t) 0);
  470. #endif
  471. #ifdef CONFIG_PPC_ISERIES
  472. HvCall_terminateMachineSrc();
  473. #endif
  474. goto out;
  475. }
  476. barrier();
  477. udelay(1);
  478. }
  479. if (wait) {
  480. timeout = 1000000;
  481. while (atomic_read(&data.finished) != cpus) {
  482. HMT_low();
  483. if (--timeout == 0) {
  484. printk("smp_call_function on cpu %d: other cpus not finishing (%d/%d)n",
  485.        smp_processor_id(), atomic_read(&data.finished), atomic_read(&data.started));
  486. #ifdef CONFIG_PPC_ISERIES
  487. HvCall_terminateMachineSrc();
  488. #endif
  489. goto out;
  490. }
  491. barrier();
  492. udelay(1);
  493. }
  494. }
  495. ret = 0;
  496.  out:
  497. HMT_medium();
  498. spin_unlock_bh(&call_lock);
  499. return ret;
  500. }
  501. void smp_call_function_interrupt(void)
  502. {
  503. void (*func) (void *info) = call_data->func;
  504. void *info = call_data->info;
  505. int wait = call_data->wait;
  506. /*
  507.  * Notify initiating CPU that I've grabbed the data and am
  508.  * about to execute the function
  509.  */
  510. atomic_inc(&call_data->started);
  511. /*
  512.  * At this point the info structure may be out of scope unless wait==1
  513.  */
  514. (*func)(info);
  515. if (wait)
  516. atomic_inc(&call_data->finished);
  517. }
  518. extern unsigned long decr_overclock;
  519. void __init smp_boot_cpus(void)
  520. {
  521. extern struct current_set_struct current_set[];
  522. extern void __secondary_start_chrp(void);
  523. int i, cpu_nr;
  524. struct task_struct *p;
  525. unsigned long sp;
  526. printk("Entering SMP Mode...n");
  527. PPCDBG(PPCDBG_SMP, "smp_boot_cpus: start.  NR_CPUS = 0x%lxn", NR_CPUS);
  528. smp_num_cpus = 1;
  529.         smp_store_cpu_info(0);
  530. cpu_online_map = 1UL;
  531. /*
  532.  * assume for now that the first cpu booted is
  533.  * cpu 0, the master -- Cort
  534.  */
  535. cpu_callin_map[0] = 1;
  536. current->processor = 0;
  537. init_idle();
  538. for (i = 0; i < NR_CPUS; i++) {
  539. paca[i].prof_counter = 1;
  540. paca[i].prof_multiplier = 1;
  541. if(i != 0) {
  542.         /*
  543.  * Processor 0's segment table is statically 
  544.  * initialized to real address 0x5000.  The
  545.  * Other processor's tables are created and
  546.  * initialized here.
  547.  */
  548. paca[i].xStab_data.virt = (unsigned long)&stab_array[PAGE_SIZE * (i-1)];
  549. memset((void *)paca[i].xStab_data.virt, 0, PAGE_SIZE); 
  550. paca[i].xStab_data.real = __v2a(paca[i].xStab_data.virt);
  551. paca[i].default_decr = tb_ticks_per_jiffy / decr_overclock;
  552. }
  553. }
  554. /*
  555.  * XXX very rough, assumes 20 bus cycles to read a cache line,
  556.  * timebase increments every 4 bus cycles, 32kB L1 data cache.
  557.  */
  558. cacheflush_time = 5 * 1024;
  559. /* Probe arch for CPUs */
  560. cpu_nr = ppc_md.smp_probe();
  561. printk("Probe found %d CPUsn", cpu_nr);
  562. /*
  563.  * only check for cpus we know exist.  We keep the callin map
  564.  * with cpus at the bottom -- Cort
  565.  */
  566. if (cpu_nr > max_cpus)
  567. cpu_nr = max_cpus;
  568. #ifdef CONFIG_PPC_ISERIES
  569. smp_space_timers( cpu_nr );
  570. #endif
  571. printk("Waiting for %d CPUsn", cpu_nr-1);
  572. for ( i = 1 ; i < cpu_nr; i++ ) {
  573. int c;
  574. struct pt_regs regs;
  575. /* create a process for the processor */
  576. /* we don't care about the values in regs since we'll
  577.    never reschedule the forked task. */
  578. /* We DO care about one bit in the pt_regs we
  579.    pass to do_fork.  That is the MSR_FP bit in
  580.    regs.msr.  If that bit is on, then do_fork
  581.    (via copy_thread) will call giveup_fpu.
  582.    giveup_fpu will get a pointer to our (current's)
  583.    last register savearea via current->thread.regs
  584.    and using that pointer will turn off the MSR_FP,
  585.    MSR_FE0 and MSR_FE1 bits.  At this point, this
  586.    pointer is pointing to some arbitrary point within
  587.    our stack */
  588. memset(&regs, 0, sizeof(struct pt_regs));
  589. if (do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0) < 0)
  590. panic("failed fork for CPU %d", i);
  591. p = init_task.prev_task;
  592. if (!p)
  593. panic("No idle task for CPU %d", i);
  594. PPCDBG(PPCDBG_SMP,"tProcessor %d, task = 0x%lxn", i, p);
  595. del_from_runqueue(p);
  596. unhash_process(p);
  597. init_tasks[i] = p;
  598. p->processor = i;
  599. p->cpus_runnable = 1 << i; /* we schedule the first task manually */
  600. current_set[i].task = p;
  601. sp = ((unsigned long)p) + sizeof(union task_union)
  602. - STACK_FRAME_OVERHEAD;
  603. current_set[i].sp_real = (void *)__v2a(sp);
  604. /* wake up cpus */
  605. ppc_md.smp_kick_cpu(i);
  606. /*
  607.  * wait to see if the cpu made a callin (is actually up).
  608.  * use this value that I found through experimentation.
  609.  * -- Cort
  610.  */
  611. for ( c = 5000; c && !cpu_callin_map[i] ; c-- ) {
  612. udelay(100);
  613. }
  614. if ( cpu_callin_map[i] )
  615. {
  616. printk("Processor %d found.n", i);
  617. PPCDBG(PPCDBG_SMP, "tProcessor %d found.n", i);
  618. /* this sync's the decr's -- Cort */
  619. smp_num_cpus++;
  620. } else {
  621. printk("Processor %d is stuck.n", i);
  622. PPCDBG(PPCDBG_SMP, "tProcessor %d is stuck.n", i);
  623. }
  624. }
  625. /* Setup CPU 0 last (important) */
  626. ppc_md.smp_setup_cpu(0);
  627. if (smp_num_cpus < 2) {
  628.         tb_last_stamp = get_tb();
  629. smp_tb_synchronized = 1;
  630. }
  631. }
  632. void __init smp_commence(void)
  633. {
  634. /*
  635.  * Lets the callin's below out of their loop.
  636.  */
  637. PPCDBG(PPCDBG_SMP, "smp_commence: startn"); 
  638. wmb();
  639. smp_commenced = 1;
  640. }
  641. void __init smp_callin(void)
  642. {
  643. int cpu = current->processor;
  644.         smp_store_cpu_info(cpu);
  645. set_dec(paca[cpu].default_decr);
  646. cpu_callin_map[cpu] = 1;
  647. ppc_md.smp_setup_cpu(cpu);
  648. init_idle();
  649. set_bit(smp_processor_id(), &cpu_online_map);
  650. while(!smp_commenced) {
  651. barrier();
  652. }
  653. __sti();
  654. }
  655. /* intel needs this */
  656. void __init initialize_secondary(void)
  657. {
  658. }
  659. /* Activate a secondary processor. */
  660. int start_secondary(void *unused)
  661. {
  662. int cpu; 
  663. cpu = current->processor;
  664. atomic_inc(&init_mm.mm_count);
  665. current->active_mm = &init_mm;
  666. smp_callin();
  667. /* Go into the idle loop. */
  668. return cpu_idle(NULL);
  669. }
  670. void __init smp_setup(char *str, int *ints)
  671. {
  672. }
  673. int setup_profiling_timer(unsigned int multiplier)
  674. {
  675. return 0;
  676. }
  677. /* this function is called for each processor
  678.  */
  679. void __init smp_store_cpu_info(int id)
  680. {
  681.         paca[id].pvr = _get_PVR();
  682. }
  683. static int __init maxcpus(char *str)
  684. {
  685. get_option(&str, &max_cpus);
  686. return 1;
  687. }
  688. __setup("maxcpus=", maxcpus);