smp.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965
  1. /*
  2. * linux/arch/m32r/kernel/smp.c
  3. *
  4. * M32R SMP support routines.
  5. *
  6. * Copyright (c) 2001, 2002 Hitoshi Yamamoto
  7. *
  8. * Taken from i386 version.
  9. * (c) 1995 Alan Cox, Building #3 <alan@redhat.com>
  10. * (c) 1998-99, 2000 Ingo Molnar <mingo@redhat.com>
  11. *
  12. * This code is released under the GNU General Public License version 2 or
  13. * later.
  14. */
  15. #undef DEBUG_SMP
  16. #include <linux/irq.h>
  17. #include <linux/interrupt.h>
  18. #include <linux/spinlock.h>
  19. #include <linux/mm.h>
  20. #include <linux/smp.h>
  21. #include <linux/profile.h>
  22. #include <linux/cpu.h>
  23. #include <asm/cacheflush.h>
  24. #include <asm/pgalloc.h>
  25. #include <asm/atomic.h>
  26. #include <asm/io.h>
  27. #include <asm/mmu_context.h>
  28. #include <asm/m32r.h>
  29. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  30. /* Data structures and variables */
  31. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  32. /*
  33. * Structure and data for smp_call_function(). This is designed to minimise
  34. * static memory requirements. It also looks cleaner.
  35. */
  36. static DEFINE_SPINLOCK(call_lock);
  37. struct call_data_struct {
  38. void (*func) (void *info);
  39. void *info;
  40. atomic_t started;
  41. atomic_t finished;
  42. int wait;
  43. } __attribute__ ((__aligned__(SMP_CACHE_BYTES)));
  44. static struct call_data_struct *call_data;
  45. /*
  46. * For flush_cache_all()
  47. */
  48. static DEFINE_SPINLOCK(flushcache_lock);
  49. static volatile unsigned long flushcache_cpumask = 0;
  50. /*
  51. * For flush_tlb_others()
  52. */
  53. static volatile cpumask_t flush_cpumask;
  54. static struct mm_struct *flush_mm;
  55. static struct vm_area_struct *flush_vma;
  56. static volatile unsigned long flush_va;
  57. static DEFINE_SPINLOCK(tlbstate_lock);
  58. #define FLUSH_ALL 0xffffffff
  59. DECLARE_PER_CPU(int, prof_multiplier);
  60. DECLARE_PER_CPU(int, prof_old_multiplier);
  61. DECLARE_PER_CPU(int, prof_counter);
  62. extern spinlock_t ipi_lock[];
  63. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  64. /* Function Prototypes */
  65. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  66. void smp_send_reschedule(int);
  67. void smp_reschedule_interrupt(void);
  68. void smp_flush_cache_all(void);
  69. void smp_flush_cache_all_interrupt(void);
  70. void smp_flush_tlb_all(void);
  71. static void flush_tlb_all_ipi(void *);
  72. void smp_flush_tlb_mm(struct mm_struct *);
  73. void smp_flush_tlb_range(struct vm_area_struct *, unsigned long, \
  74. unsigned long);
  75. void smp_flush_tlb_page(struct vm_area_struct *, unsigned long);
  76. static void flush_tlb_others(cpumask_t, struct mm_struct *,
  77. struct vm_area_struct *, unsigned long);
  78. void smp_invalidate_interrupt(void);
  79. void smp_send_stop(void);
  80. static void stop_this_cpu(void *);
  81. int smp_call_function(void (*) (void *), void *, int, int);
  82. void smp_call_function_interrupt(void);
  83. void smp_send_timer(void);
  84. void smp_ipi_timer_interrupt(struct pt_regs *);
  85. void smp_local_timer_interrupt(struct pt_regs *);
  86. void send_IPI_allbutself(int, int);
  87. static void send_IPI_mask(cpumask_t, int, int);
  88. unsigned long send_IPI_mask_phys(cpumask_t, int, int);
  89. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  90. /* Rescheduling request Routines */
  91. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  92. /*==========================================================================*
  93. * Name: smp_send_reschedule
  94. *
  95. * Description: This routine requests other CPU to execute rescheduling.
  96. * 1.Send 'RESCHEDULE_IPI' to other CPU.
  97. * Request other CPU to execute 'smp_reschedule_interrupt()'.
  98. *
  99. * Born on Date: 2002.02.05
  100. *
  101. * Arguments: cpu_id - Target CPU ID
  102. *
  103. * Returns: void (cannot fail)
  104. *
  105. * Modification log:
  106. * Date Who Description
  107. * ---------- --- --------------------------------------------------------
  108. *
  109. *==========================================================================*/
  110. void smp_send_reschedule(int cpu_id)
  111. {
  112. WARN_ON(cpu_is_offline(cpu_id));
  113. send_IPI_mask(cpumask_of_cpu(cpu_id), RESCHEDULE_IPI, 1);
  114. }
  115. /*==========================================================================*
  116. * Name: smp_reschedule_interrupt
  117. *
  118. * Description: This routine executes on CPU which received
  119. * 'RESCHEDULE_IPI'.
  120. * Rescheduling is processed at the exit of interrupt
  121. * operation.
  122. *
  123. * Born on Date: 2002.02.05
  124. *
  125. * Arguments: NONE
  126. *
  127. * Returns: void (cannot fail)
  128. *
  129. * Modification log:
  130. * Date Who Description
  131. * ---------- --- --------------------------------------------------------
  132. *
  133. *==========================================================================*/
  134. void smp_reschedule_interrupt(void)
  135. {
  136. /* nothing to do */
  137. }
  138. /*==========================================================================*
  139. * Name: smp_flush_cache_all
  140. *
  141. * Description: This routine sends a 'INVALIDATE_CACHE_IPI' to all other
  142. * CPUs in the system.
  143. *
  144. * Born on Date: 2003-05-28
  145. *
  146. * Arguments: NONE
  147. *
  148. * Returns: void (cannot fail)
  149. *
  150. * Modification log:
  151. * Date Who Description
  152. * ---------- --- --------------------------------------------------------
  153. *
  154. *==========================================================================*/
  155. void smp_flush_cache_all(void)
  156. {
  157. cpumask_t cpumask;
  158. unsigned long *mask;
  159. preempt_disable();
  160. cpumask = cpu_online_map;
  161. cpu_clear(smp_processor_id(), cpumask);
  162. spin_lock(&flushcache_lock);
  163. mask=cpus_addr(cpumask);
  164. atomic_set_mask(*mask, (atomic_t *)&flushcache_cpumask);
  165. send_IPI_mask(cpumask, INVALIDATE_CACHE_IPI, 0);
  166. _flush_cache_copyback_all();
  167. while (flushcache_cpumask)
  168. mb();
  169. spin_unlock(&flushcache_lock);
  170. preempt_enable();
  171. }
  172. void smp_flush_cache_all_interrupt(void)
  173. {
  174. _flush_cache_copyback_all();
  175. clear_bit(smp_processor_id(), &flushcache_cpumask);
  176. }
  177. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  178. /* TLB flush request Routins */
  179. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  180. /*==========================================================================*
  181. * Name: smp_flush_tlb_all
  182. *
  183. * Description: This routine flushes all processes TLBs.
  184. * 1.Request other CPU to execute 'flush_tlb_all_ipi()'.
  185. * 2.Execute 'do_flush_tlb_all_local()'.
  186. *
  187. * Born on Date: 2002.02.05
  188. *
  189. * Arguments: NONE
  190. *
  191. * Returns: void (cannot fail)
  192. *
  193. * Modification log:
  194. * Date Who Description
  195. * ---------- --- --------------------------------------------------------
  196. *
  197. *==========================================================================*/
  198. void smp_flush_tlb_all(void)
  199. {
  200. unsigned long flags;
  201. preempt_disable();
  202. local_irq_save(flags);
  203. __flush_tlb_all();
  204. local_irq_restore(flags);
  205. smp_call_function(flush_tlb_all_ipi, 0, 1, 1);
  206. preempt_enable();
  207. }
  208. /*==========================================================================*
  209. * Name: flush_tlb_all_ipi
  210. *
  211. * Description: This routine flushes all local TLBs.
  212. * 1.Execute 'do_flush_tlb_all_local()'.
  213. *
  214. * Born on Date: 2002.02.05
  215. *
  216. * Arguments: *info - not used
  217. *
  218. * Returns: void (cannot fail)
  219. *
  220. * Modification log:
  221. * Date Who Description
  222. * ---------- --- --------------------------------------------------------
  223. *
  224. *==========================================================================*/
  225. static void flush_tlb_all_ipi(void *info)
  226. {
  227. __flush_tlb_all();
  228. }
  229. /*==========================================================================*
  230. * Name: smp_flush_tlb_mm
  231. *
  232. * Description: This routine flushes the specified mm context TLB's.
  233. *
  234. * Born on Date: 2002.02.05
  235. *
  236. * Arguments: *mm - a pointer to the mm struct for flush TLB
  237. *
  238. * Returns: void (cannot fail)
  239. *
  240. * Modification log:
  241. * Date Who Description
  242. * ---------- --- --------------------------------------------------------
  243. *
  244. *==========================================================================*/
  245. void smp_flush_tlb_mm(struct mm_struct *mm)
  246. {
  247. int cpu_id = smp_processor_id();
  248. cpumask_t cpu_mask;
  249. unsigned long *mmc = &mm->context[cpu_id];
  250. unsigned long flags;
  251. preempt_disable();
  252. cpu_mask = mm->cpu_vm_mask;
  253. cpu_clear(cpu_id, cpu_mask);
  254. if (*mmc != NO_CONTEXT) {
  255. local_irq_save(flags);
  256. *mmc = NO_CONTEXT;
  257. if (mm == current->mm)
  258. activate_context(mm);
  259. else
  260. cpu_clear(cpu_id, mm->cpu_vm_mask);
  261. local_irq_restore(flags);
  262. }
  263. if (!cpus_empty(cpu_mask))
  264. flush_tlb_others(cpu_mask, mm, NULL, FLUSH_ALL);
  265. preempt_enable();
  266. }
  267. /*==========================================================================*
  268. * Name: smp_flush_tlb_range
  269. *
  270. * Description: This routine flushes a range of pages.
  271. *
  272. * Born on Date: 2002.02.05
  273. *
  274. * Arguments: *mm - a pointer to the mm struct for flush TLB
  275. * start - not used
  276. * end - not used
  277. *
  278. * Returns: void (cannot fail)
  279. *
  280. * Modification log:
  281. * Date Who Description
  282. * ---------- --- --------------------------------------------------------
  283. *
  284. *==========================================================================*/
  285. void smp_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
  286. unsigned long end)
  287. {
  288. smp_flush_tlb_mm(vma->vm_mm);
  289. }
  290. /*==========================================================================*
  291. * Name: smp_flush_tlb_page
  292. *
  293. * Description: This routine flushes one page.
  294. *
  295. * Born on Date: 2002.02.05
  296. *
  297. * Arguments: *vma - a pointer to the vma struct include va
  298. * va - virtual address for flush TLB
  299. *
  300. * Returns: void (cannot fail)
  301. *
  302. * Modification log:
  303. * Date Who Description
  304. * ---------- --- --------------------------------------------------------
  305. *
  306. *==========================================================================*/
  307. void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
  308. {
  309. struct mm_struct *mm = vma->vm_mm;
  310. int cpu_id = smp_processor_id();
  311. cpumask_t cpu_mask;
  312. unsigned long *mmc = &mm->context[cpu_id];
  313. unsigned long flags;
  314. preempt_disable();
  315. cpu_mask = mm->cpu_vm_mask;
  316. cpu_clear(cpu_id, cpu_mask);
  317. #ifdef DEBUG_SMP
  318. if (!mm)
  319. BUG();
  320. #endif
  321. if (*mmc != NO_CONTEXT) {
  322. local_irq_save(flags);
  323. va &= PAGE_MASK;
  324. va |= (*mmc & MMU_CONTEXT_ASID_MASK);
  325. __flush_tlb_page(va);
  326. local_irq_restore(flags);
  327. }
  328. if (!cpus_empty(cpu_mask))
  329. flush_tlb_others(cpu_mask, mm, vma, va);
  330. preempt_enable();
  331. }
  332. /*==========================================================================*
  333. * Name: flush_tlb_others
  334. *
  335. * Description: This routine requests other CPU to execute flush TLB.
  336. * 1.Setup parmeters.
  337. * 2.Send 'INVALIDATE_TLB_IPI' to other CPU.
  338. * Request other CPU to execute 'smp_invalidate_interrupt()'.
  339. * 3.Wait for other CPUs operation finished.
  340. *
  341. * Born on Date: 2002.02.05
  342. *
  343. * Arguments: cpumask - bitmap of target CPUs
  344. * *mm - a pointer to the mm struct for flush TLB
  345. * *vma - a pointer to the vma struct include va
  346. * va - virtual address for flush TLB
  347. *
  348. * Returns: void (cannot fail)
  349. *
  350. * Modification log:
  351. * Date Who Description
  352. * ---------- --- --------------------------------------------------------
  353. *
  354. *==========================================================================*/
  355. static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
  356. struct vm_area_struct *vma, unsigned long va)
  357. {
  358. unsigned long *mask;
  359. #ifdef DEBUG_SMP
  360. unsigned long flags;
  361. __save_flags(flags);
  362. if (!(flags & 0x0040)) /* Interrupt Disable NONONO */
  363. BUG();
  364. #endif /* DEBUG_SMP */
  365. /*
  366. * A couple of (to be removed) sanity checks:
  367. *
  368. * - we do not send IPIs to not-yet booted CPUs.
  369. * - current CPU must not be in mask
  370. * - mask must exist :)
  371. */
  372. BUG_ON(cpus_empty(cpumask));
  373. BUG_ON(cpu_isset(smp_processor_id(), cpumask));
  374. BUG_ON(!mm);
  375. /* If a CPU which we ran on has gone down, OK. */
  376. cpus_and(cpumask, cpumask, cpu_online_map);
  377. if (cpus_empty(cpumask))
  378. return;
  379. /*
  380. * i'm not happy about this global shared spinlock in the
  381. * MM hot path, but we'll see how contended it is.
  382. * Temporarily this turns IRQs off, so that lockups are
  383. * detected by the NMI watchdog.
  384. */
  385. spin_lock(&tlbstate_lock);
  386. flush_mm = mm;
  387. flush_vma = vma;
  388. flush_va = va;
  389. mask=cpus_addr(cpumask);
  390. atomic_set_mask(*mask, (atomic_t *)&flush_cpumask);
  391. /*
  392. * We have to send the IPI only to
  393. * CPUs affected.
  394. */
  395. send_IPI_mask(cpumask, INVALIDATE_TLB_IPI, 0);
  396. while (!cpus_empty(flush_cpumask)) {
  397. /* nothing. lockup detection does not belong here */
  398. mb();
  399. }
  400. flush_mm = NULL;
  401. flush_vma = NULL;
  402. flush_va = 0;
  403. spin_unlock(&tlbstate_lock);
  404. }
  405. /*==========================================================================*
  406. * Name: smp_invalidate_interrupt
  407. *
  408. * Description: This routine executes on CPU which received
  409. * 'INVALIDATE_TLB_IPI'.
  410. * 1.Flush local TLB.
  411. * 2.Report flush TLB process was finished.
  412. *
  413. * Born on Date: 2002.02.05
  414. *
  415. * Arguments: NONE
  416. *
  417. * Returns: void (cannot fail)
  418. *
  419. * Modification log:
  420. * Date Who Description
  421. * ---------- --- --------------------------------------------------------
  422. *
  423. *==========================================================================*/
  424. void smp_invalidate_interrupt(void)
  425. {
  426. int cpu_id = smp_processor_id();
  427. unsigned long *mmc = &flush_mm->context[cpu_id];
  428. if (!cpu_isset(cpu_id, flush_cpumask))
  429. return;
  430. if (flush_va == FLUSH_ALL) {
  431. *mmc = NO_CONTEXT;
  432. if (flush_mm == current->active_mm)
  433. activate_context(flush_mm);
  434. else
  435. cpu_clear(cpu_id, flush_mm->cpu_vm_mask);
  436. } else {
  437. unsigned long va = flush_va;
  438. if (*mmc != NO_CONTEXT) {
  439. va &= PAGE_MASK;
  440. va |= (*mmc & MMU_CONTEXT_ASID_MASK);
  441. __flush_tlb_page(va);
  442. }
  443. }
  444. cpu_clear(cpu_id, flush_cpumask);
  445. }
  446. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  447. /* Stop CPU request Routins */
  448. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  449. /*==========================================================================*
  450. * Name: smp_send_stop
  451. *
  452. * Description: This routine requests stop all CPUs.
  453. * 1.Request other CPU to execute 'stop_this_cpu()'.
  454. *
  455. * Born on Date: 2002.02.05
  456. *
  457. * Arguments: NONE
  458. *
  459. * Returns: void (cannot fail)
  460. *
  461. * Modification log:
  462. * Date Who Description
  463. * ---------- --- --------------------------------------------------------
  464. *
  465. *==========================================================================*/
  466. void smp_send_stop(void)
  467. {
  468. smp_call_function(stop_this_cpu, NULL, 1, 0);
  469. }
  470. /*==========================================================================*
  471. * Name: stop_this_cpu
  472. *
  473. * Description: This routine halt CPU.
  474. *
  475. * Born on Date: 2002.02.05
  476. *
  477. * Arguments: NONE
  478. *
  479. * Returns: void (cannot fail)
  480. *
  481. * Modification log:
  482. * Date Who Description
  483. * ---------- --- --------------------------------------------------------
  484. *
  485. *==========================================================================*/
  486. static void stop_this_cpu(void *dummy)
  487. {
  488. int cpu_id = smp_processor_id();
  489. /*
  490. * Remove this CPU:
  491. */
  492. cpu_clear(cpu_id, cpu_online_map);
  493. /*
  494. * PSW IE = 1;
  495. * IMASK = 0;
  496. * goto SLEEP
  497. */
  498. local_irq_disable();
  499. outl(0, M32R_ICU_IMASK_PORTL);
  500. inl(M32R_ICU_IMASK_PORTL); /* dummy read */
  501. local_irq_enable();
  502. for ( ; ; );
  503. }
  504. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  505. /* Call function Routins */
  506. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  507. /*==========================================================================*
  508. * Name: smp_call_function
  509. *
  510. * Description: This routine sends a 'CALL_FUNCTION_IPI' to all other CPUs
  511. * in the system.
  512. *
  513. * Born on Date: 2002.02.05
  514. *
  515. * Arguments: *func - The function to run. This must be fast and
  516. * non-blocking.
  517. * *info - An arbitrary pointer to pass to the function.
  518. * nonatomic - currently unused.
  519. * wait - If true, wait (atomically) until function has
  520. * completed on other CPUs.
  521. *
  522. * Returns: 0 on success, else a negative status code. Does not return
  523. * until remote CPUs are nearly ready to execute <<func>> or
  524. * are or have executed.
  525. *
  526. * Cautions: You must not call this function with disabled interrupts or
  527. * from a hardware interrupt handler, you may call it from a
  528. * bottom half handler.
  529. *
  530. * Modification log:
  531. * Date Who Description
  532. * ---------- --- --------------------------------------------------------
  533. *
  534. *==========================================================================*/
  535. int smp_call_function(void (*func) (void *info), void *info, int nonatomic,
  536. int wait)
  537. {
  538. struct call_data_struct data;
  539. int cpus;
  540. #ifdef DEBUG_SMP
  541. unsigned long flags;
  542. __save_flags(flags);
  543. if (!(flags & 0x0040)) /* Interrupt Disable NONONO */
  544. BUG();
  545. #endif /* DEBUG_SMP */
  546. /* Holding any lock stops cpus from going down. */
  547. spin_lock(&call_lock);
  548. cpus = num_online_cpus() - 1;
  549. if (!cpus) {
  550. spin_unlock(&call_lock);
  551. return 0;
  552. }
  553. /* Can deadlock when called with interrupts disabled */
  554. WARN_ON(irqs_disabled());
  555. data.func = func;
  556. data.info = info;
  557. atomic_set(&data.started, 0);
  558. data.wait = wait;
  559. if (wait)
  560. atomic_set(&data.finished, 0);
  561. call_data = &data;
  562. mb();
  563. /* Send a message to all other CPUs and wait for them to respond */
  564. send_IPI_allbutself(CALL_FUNCTION_IPI, 0);
  565. /* Wait for response */
  566. while (atomic_read(&data.started) != cpus)
  567. barrier();
  568. if (wait)
  569. while (atomic_read(&data.finished) != cpus)
  570. barrier();
  571. spin_unlock(&call_lock);
  572. return 0;
  573. }
  574. /*==========================================================================*
  575. * Name: smp_call_function_interrupt
  576. *
  577. * Description: This routine executes on CPU which received
  578. * 'CALL_FUNCTION_IPI'.
  579. *
  580. * Born on Date: 2002.02.05
  581. *
  582. * Arguments: NONE
  583. *
  584. * Returns: void (cannot fail)
  585. *
  586. * Modification log:
  587. * Date Who Description
  588. * ---------- --- --------------------------------------------------------
  589. *
  590. *==========================================================================*/
  591. void smp_call_function_interrupt(void)
  592. {
  593. void (*func) (void *info) = call_data->func;
  594. void *info = call_data->info;
  595. int wait = call_data->wait;
  596. /*
  597. * Notify initiating CPU that I've grabbed the data and am
  598. * about to execute the function
  599. */
  600. mb();
  601. atomic_inc(&call_data->started);
  602. /*
  603. * At this point the info structure may be out of scope unless wait==1
  604. */
  605. irq_enter();
  606. (*func)(info);
  607. irq_exit();
  608. if (wait) {
  609. mb();
  610. atomic_inc(&call_data->finished);
  611. }
  612. }
  613. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  614. /* Timer Routins */
  615. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  616. /*==========================================================================*
  617. * Name: smp_send_timer
  618. *
  619. * Description: This routine sends a 'LOCAL_TIMER_IPI' to all other CPUs
  620. * in the system.
  621. *
  622. * Born on Date: 2002.02.05
  623. *
  624. * Arguments: NONE
  625. *
  626. * Returns: void (cannot fail)
  627. *
  628. * Modification log:
  629. * Date Who Description
  630. * ---------- --- --------------------------------------------------------
  631. *
  632. *==========================================================================*/
  633. void smp_send_timer(void)
  634. {
  635. send_IPI_allbutself(LOCAL_TIMER_IPI, 1);
  636. }
  637. /*==========================================================================*
  638. * Name: smp_send_timer
  639. *
  640. * Description: This routine executes on CPU which received
  641. * 'LOCAL_TIMER_IPI'.
  642. *
  643. * Born on Date: 2002.02.05
  644. *
  645. * Arguments: *regs - a pointer to the saved regster info
  646. *
  647. * Returns: void (cannot fail)
  648. *
  649. * Modification log:
  650. * Date Who Description
  651. * ---------- --- --------------------------------------------------------
  652. *
  653. *==========================================================================*/
  654. void smp_ipi_timer_interrupt(struct pt_regs *regs)
  655. {
  656. irq_enter();
  657. smp_local_timer_interrupt(regs);
  658. irq_exit();
  659. }
  660. /*==========================================================================*
  661. * Name: smp_local_timer_interrupt
  662. *
  663. * Description: Local timer interrupt handler. It does both profiling and
  664. * process statistics/rescheduling.
  665. * We do profiling in every local tick, statistics/rescheduling
  666. * happen only every 'profiling multiplier' ticks. The default
  667. * multiplier is 1 and it can be changed by writing the new
  668. * multiplier value into /proc/profile.
  669. *
  670. * Born on Date: 2002.02.05
  671. *
  672. * Arguments: *regs - a pointer to the saved regster info
  673. *
  674. * Returns: void (cannot fail)
  675. *
  676. * Original: arch/i386/kernel/apic.c
  677. *
  678. * Modification log:
  679. * Date Who Description
  680. * ---------- --- --------------------------------------------------------
  681. * 2003-06-24 hy use per_cpu structure.
  682. *==========================================================================*/
  683. void smp_local_timer_interrupt(struct pt_regs *regs)
  684. {
  685. int user = user_mode(regs);
  686. int cpu_id = smp_processor_id();
  687. /*
  688. * The profiling function is SMP safe. (nothing can mess
  689. * around with "current", and the profiling counters are
  690. * updated with atomic operations). This is especially
  691. * useful with a profiling multiplier != 1
  692. */
  693. profile_tick(CPU_PROFILING, regs);
  694. if (--per_cpu(prof_counter, cpu_id) <= 0) {
  695. /*
  696. * The multiplier may have changed since the last time we got
  697. * to this point as a result of the user writing to
  698. * /proc/profile. In this case we need to adjust the APIC
  699. * timer accordingly.
  700. *
  701. * Interrupts are already masked off at this point.
  702. */
  703. per_cpu(prof_counter, cpu_id)
  704. = per_cpu(prof_multiplier, cpu_id);
  705. if (per_cpu(prof_counter, cpu_id)
  706. != per_cpu(prof_old_multiplier, cpu_id))
  707. {
  708. per_cpu(prof_old_multiplier, cpu_id)
  709. = per_cpu(prof_counter, cpu_id);
  710. }
  711. update_process_times(user);
  712. }
  713. }
  714. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  715. /* Send IPI Routins */
  716. /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
  717. /*==========================================================================*
  718. * Name: send_IPI_allbutself
  719. *
  720. * Description: This routine sends a IPI to all other CPUs in the system.
  721. *
  722. * Born on Date: 2002.02.05
  723. *
  724. * Arguments: ipi_num - Number of IPI
  725. * try - 0 : Send IPI certainly.
  726. * !0 : The following IPI is not sended when Target CPU
  727. * has not received the before IPI.
  728. *
  729. * Returns: void (cannot fail)
  730. *
  731. * Modification log:
  732. * Date Who Description
  733. * ---------- --- --------------------------------------------------------
  734. *
  735. *==========================================================================*/
  736. void send_IPI_allbutself(int ipi_num, int try)
  737. {
  738. cpumask_t cpumask;
  739. cpumask = cpu_online_map;
  740. cpu_clear(smp_processor_id(), cpumask);
  741. send_IPI_mask(cpumask, ipi_num, try);
  742. }
  743. /*==========================================================================*
  744. * Name: send_IPI_mask
  745. *
  746. * Description: This routine sends a IPI to CPUs in the system.
  747. *
  748. * Born on Date: 2002.02.05
  749. *
  750. * Arguments: cpu_mask - Bitmap of target CPUs logical ID
  751. * ipi_num - Number of IPI
  752. * try - 0 : Send IPI certainly.
  753. * !0 : The following IPI is not sended when Target CPU
  754. * has not received the before IPI.
  755. *
  756. * Returns: void (cannot fail)
  757. *
  758. * Modification log:
  759. * Date Who Description
  760. * ---------- --- --------------------------------------------------------
  761. *
  762. *==========================================================================*/
  763. static void send_IPI_mask(cpumask_t cpumask, int ipi_num, int try)
  764. {
  765. cpumask_t physid_mask, tmp;
  766. int cpu_id, phys_id;
  767. int num_cpus = num_online_cpus();
  768. if (num_cpus <= 1) /* NO MP */
  769. return;
  770. cpus_and(tmp, cpumask, cpu_online_map);
  771. BUG_ON(!cpus_equal(cpumask, tmp));
  772. physid_mask = CPU_MASK_NONE;
  773. for_each_cpu_mask(cpu_id, cpumask){
  774. if ((phys_id = cpu_to_physid(cpu_id)) != -1)
  775. cpu_set(phys_id, physid_mask);
  776. }
  777. send_IPI_mask_phys(physid_mask, ipi_num, try);
  778. }
  779. /*==========================================================================*
  780. * Name: send_IPI_mask_phys
  781. *
  782. * Description: This routine sends a IPI to other CPUs in the system.
  783. *
  784. * Born on Date: 2002.02.05
  785. *
  786. * Arguments: cpu_mask - Bitmap of target CPUs physical ID
  787. * ipi_num - Number of IPI
  788. * try - 0 : Send IPI certainly.
  789. * !0 : The following IPI is not sended when Target CPU
  790. * has not received the before IPI.
  791. *
  792. * Returns: IPICRi regster value.
  793. *
  794. * Modification log:
  795. * Date Who Description
  796. * ---------- --- --------------------------------------------------------
  797. *
  798. *==========================================================================*/
  799. unsigned long send_IPI_mask_phys(cpumask_t physid_mask, int ipi_num,
  800. int try)
  801. {
  802. spinlock_t *ipilock;
  803. unsigned long flags = 0;
  804. volatile unsigned long *ipicr_addr;
  805. unsigned long ipicr_val;
  806. unsigned long my_physid_mask;
  807. unsigned long mask = cpus_addr(physid_mask)[0];
  808. if (mask & ~physids_coerce(phys_cpu_present_map))
  809. BUG();
  810. if (ipi_num >= NR_IPIS)
  811. BUG();
  812. mask <<= IPI_SHIFT;
  813. ipilock = &ipi_lock[ipi_num];
  814. ipicr_addr = (volatile unsigned long *)(M32R_ICU_IPICR_ADDR
  815. + (ipi_num << 2));
  816. my_physid_mask = ~(1 << smp_processor_id());
  817. /*
  818. * lock ipi_lock[i]
  819. * check IPICRi == 0
  820. * write IPICRi (send IPIi)
  821. * unlock ipi_lock[i]
  822. */
  823. __asm__ __volatile__ (
  824. ";; LOCK ipi_lock[i] \n\t"
  825. ".fillinsn \n"
  826. "1: \n\t"
  827. "mvfc %1, psw \n\t"
  828. "clrpsw #0x40 -> nop \n\t"
  829. DCACHE_CLEAR("r4", "r5", "%2")
  830. "lock r4, @%2 \n\t"
  831. "addi r4, #-1 \n\t"
  832. "unlock r4, @%2 \n\t"
  833. "mvtc %1, psw \n\t"
  834. "bnez r4, 2f \n\t"
  835. LOCK_SECTION_START(".balign 4 \n\t")
  836. ".fillinsn \n"
  837. "2: \n\t"
  838. "ld r4, @%2 \n\t"
  839. "blez r4, 2b \n\t"
  840. "bra 1b \n\t"
  841. LOCK_SECTION_END
  842. ";; CHECK IPICRi == 0 \n\t"
  843. ".fillinsn \n"
  844. "3: \n\t"
  845. "ld %0, @%3 \n\t"
  846. "and %0, %6 \n\t"
  847. "beqz %0, 4f \n\t"
  848. "bnez %5, 5f \n\t"
  849. "bra 3b \n\t"
  850. ";; WRITE IPICRi (send IPIi) \n\t"
  851. ".fillinsn \n"
  852. "4: \n\t"
  853. "st %4, @%3 \n\t"
  854. ";; UNLOCK ipi_lock[i] \n\t"
  855. ".fillinsn \n"
  856. "5: \n\t"
  857. "ldi r4, #1 \n\t"
  858. "st r4, @%2 \n\t"
  859. : "=&r"(ipicr_val)
  860. : "r"(flags), "r"(&ipilock->slock), "r"(ipicr_addr),
  861. "r"(mask), "r"(try), "r"(my_physid_mask)
  862. : "memory", "r4"
  863. #ifdef CONFIG_CHIP_M32700_TS1
  864. , "r5"
  865. #endif /* CONFIG_CHIP_M32700_TS1 */
  866. );
  867. return ipicr_val;
  868. }