smp.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  1. /*
  2. * Copyright (C) 2010, 2011, 2012, Lemote, Inc.
  3. * Author: Chen Huacai, chenhc@lemote.com
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation; either version 2
  8. * of the License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. */
  16. #include <linux/init.h>
  17. #include <linux/cpu.h>
  18. #include <linux/sched.h>
  19. #include <linux/smp.h>
  20. #include <linux/cpufreq.h>
  21. #include <asm/processor.h>
  22. #include <asm/time.h>
  23. #include <asm/clock.h>
  24. #include <asm/tlbflush.h>
  25. #include <asm/cacheflush.h>
  26. #include <loongson.h>
  27. #include <workarounds.h>
  28. #include "smp.h"
  29. DEFINE_PER_CPU(int, cpu_state);
  30. static void *ipi_set0_regs[16];
  31. static void *ipi_clear0_regs[16];
  32. static void *ipi_status0_regs[16];
  33. static void *ipi_en0_regs[16];
  34. static void *ipi_mailbox_buf[16];
  35. static uint32_t core0_c0count[NR_CPUS];
  36. /* read a 32bit value from ipi register */
  37. #define loongson3_ipi_read32(addr) readl(addr)
  38. /* read a 64bit value from ipi register */
  39. #define loongson3_ipi_read64(addr) readq(addr)
  40. /* write a 32bit value to ipi register */
  41. #define loongson3_ipi_write32(action, addr) \
  42. do { \
  43. writel(action, addr); \
  44. __wbflush(); \
  45. } while (0)
  46. /* write a 64bit value to ipi register */
  47. #define loongson3_ipi_write64(action, addr) \
  48. do { \
  49. writeq(action, addr); \
  50. __wbflush(); \
  51. } while (0)
  52. static void ipi_set0_regs_init(void)
  53. {
  54. ipi_set0_regs[0] = (void *)
  55. (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + SET0);
  56. ipi_set0_regs[1] = (void *)
  57. (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + SET0);
  58. ipi_set0_regs[2] = (void *)
  59. (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + SET0);
  60. ipi_set0_regs[3] = (void *)
  61. (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + SET0);
  62. ipi_set0_regs[4] = (void *)
  63. (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + SET0);
  64. ipi_set0_regs[5] = (void *)
  65. (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + SET0);
  66. ipi_set0_regs[6] = (void *)
  67. (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + SET0);
  68. ipi_set0_regs[7] = (void *)
  69. (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + SET0);
  70. ipi_set0_regs[8] = (void *)
  71. (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + SET0);
  72. ipi_set0_regs[9] = (void *)
  73. (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + SET0);
  74. ipi_set0_regs[10] = (void *)
  75. (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + SET0);
  76. ipi_set0_regs[11] = (void *)
  77. (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + SET0);
  78. ipi_set0_regs[12] = (void *)
  79. (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + SET0);
  80. ipi_set0_regs[13] = (void *)
  81. (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + SET0);
  82. ipi_set0_regs[14] = (void *)
  83. (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + SET0);
  84. ipi_set0_regs[15] = (void *)
  85. (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + SET0);
  86. }
  87. static void ipi_clear0_regs_init(void)
  88. {
  89. ipi_clear0_regs[0] = (void *)
  90. (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + CLEAR0);
  91. ipi_clear0_regs[1] = (void *)
  92. (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + CLEAR0);
  93. ipi_clear0_regs[2] = (void *)
  94. (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + CLEAR0);
  95. ipi_clear0_regs[3] = (void *)
  96. (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + CLEAR0);
  97. ipi_clear0_regs[4] = (void *)
  98. (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + CLEAR0);
  99. ipi_clear0_regs[5] = (void *)
  100. (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + CLEAR0);
  101. ipi_clear0_regs[6] = (void *)
  102. (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + CLEAR0);
  103. ipi_clear0_regs[7] = (void *)
  104. (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + CLEAR0);
  105. ipi_clear0_regs[8] = (void *)
  106. (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + CLEAR0);
  107. ipi_clear0_regs[9] = (void *)
  108. (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + CLEAR0);
  109. ipi_clear0_regs[10] = (void *)
  110. (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + CLEAR0);
  111. ipi_clear0_regs[11] = (void *)
  112. (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + CLEAR0);
  113. ipi_clear0_regs[12] = (void *)
  114. (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + CLEAR0);
  115. ipi_clear0_regs[13] = (void *)
  116. (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + CLEAR0);
  117. ipi_clear0_regs[14] = (void *)
  118. (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + CLEAR0);
  119. ipi_clear0_regs[15] = (void *)
  120. (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + CLEAR0);
  121. }
  122. static void ipi_status0_regs_init(void)
  123. {
  124. ipi_status0_regs[0] = (void *)
  125. (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + STATUS0);
  126. ipi_status0_regs[1] = (void *)
  127. (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + STATUS0);
  128. ipi_status0_regs[2] = (void *)
  129. (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + STATUS0);
  130. ipi_status0_regs[3] = (void *)
  131. (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + STATUS0);
  132. ipi_status0_regs[4] = (void *)
  133. (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + STATUS0);
  134. ipi_status0_regs[5] = (void *)
  135. (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + STATUS0);
  136. ipi_status0_regs[6] = (void *)
  137. (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + STATUS0);
  138. ipi_status0_regs[7] = (void *)
  139. (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + STATUS0);
  140. ipi_status0_regs[8] = (void *)
  141. (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + STATUS0);
  142. ipi_status0_regs[9] = (void *)
  143. (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + STATUS0);
  144. ipi_status0_regs[10] = (void *)
  145. (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + STATUS0);
  146. ipi_status0_regs[11] = (void *)
  147. (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + STATUS0);
  148. ipi_status0_regs[12] = (void *)
  149. (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + STATUS0);
  150. ipi_status0_regs[13] = (void *)
  151. (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + STATUS0);
  152. ipi_status0_regs[14] = (void *)
  153. (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + STATUS0);
  154. ipi_status0_regs[15] = (void *)
  155. (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + STATUS0);
  156. }
  157. static void ipi_en0_regs_init(void)
  158. {
  159. ipi_en0_regs[0] = (void *)
  160. (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + EN0);
  161. ipi_en0_regs[1] = (void *)
  162. (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + EN0);
  163. ipi_en0_regs[2] = (void *)
  164. (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + EN0);
  165. ipi_en0_regs[3] = (void *)
  166. (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + EN0);
  167. ipi_en0_regs[4] = (void *)
  168. (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + EN0);
  169. ipi_en0_regs[5] = (void *)
  170. (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + EN0);
  171. ipi_en0_regs[6] = (void *)
  172. (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + EN0);
  173. ipi_en0_regs[7] = (void *)
  174. (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + EN0);
  175. ipi_en0_regs[8] = (void *)
  176. (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + EN0);
  177. ipi_en0_regs[9] = (void *)
  178. (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + EN0);
  179. ipi_en0_regs[10] = (void *)
  180. (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + EN0);
  181. ipi_en0_regs[11] = (void *)
  182. (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + EN0);
  183. ipi_en0_regs[12] = (void *)
  184. (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + EN0);
  185. ipi_en0_regs[13] = (void *)
  186. (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + EN0);
  187. ipi_en0_regs[14] = (void *)
  188. (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + EN0);
  189. ipi_en0_regs[15] = (void *)
  190. (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + EN0);
  191. }
  192. static void ipi_mailbox_buf_init(void)
  193. {
  194. ipi_mailbox_buf[0] = (void *)
  195. (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + BUF);
  196. ipi_mailbox_buf[1] = (void *)
  197. (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + BUF);
  198. ipi_mailbox_buf[2] = (void *)
  199. (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + BUF);
  200. ipi_mailbox_buf[3] = (void *)
  201. (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + BUF);
  202. ipi_mailbox_buf[4] = (void *)
  203. (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + BUF);
  204. ipi_mailbox_buf[5] = (void *)
  205. (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + BUF);
  206. ipi_mailbox_buf[6] = (void *)
  207. (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + BUF);
  208. ipi_mailbox_buf[7] = (void *)
  209. (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + BUF);
  210. ipi_mailbox_buf[8] = (void *)
  211. (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + BUF);
  212. ipi_mailbox_buf[9] = (void *)
  213. (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + BUF);
  214. ipi_mailbox_buf[10] = (void *)
  215. (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + BUF);
  216. ipi_mailbox_buf[11] = (void *)
  217. (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + BUF);
  218. ipi_mailbox_buf[12] = (void *)
  219. (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + BUF);
  220. ipi_mailbox_buf[13] = (void *)
  221. (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + BUF);
  222. ipi_mailbox_buf[14] = (void *)
  223. (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + BUF);
  224. ipi_mailbox_buf[15] = (void *)
  225. (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + BUF);
  226. }
  227. /*
  228. * Simple enough, just poke the appropriate ipi register
  229. */
  230. static void loongson3_send_ipi_single(int cpu, unsigned int action)
  231. {
  232. loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(cpu)]);
  233. }
  234. static void
  235. loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action)
  236. {
  237. unsigned int i;
  238. for_each_cpu(i, mask)
  239. loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(i)]);
  240. }
  241. void loongson3_ipi_interrupt(struct pt_regs *regs)
  242. {
  243. int i, cpu = smp_processor_id();
  244. unsigned int action, c0count;
  245. /* Load the ipi register to figure out what we're supposed to do */
  246. action = loongson3_ipi_read32(ipi_status0_regs[cpu_logical_map(cpu)]);
  247. /* Clear the ipi register to clear the interrupt */
  248. loongson3_ipi_write32((u32)action, ipi_clear0_regs[cpu_logical_map(cpu)]);
  249. if (action & SMP_RESCHEDULE_YOURSELF)
  250. scheduler_ipi();
  251. if (action & SMP_CALL_FUNCTION) {
  252. irq_enter();
  253. generic_smp_call_function_interrupt();
  254. irq_exit();
  255. }
  256. if (action & SMP_ASK_C0COUNT) {
  257. BUG_ON(cpu != 0);
  258. c0count = read_c0_count();
  259. c0count = c0count ? c0count : 1;
  260. for (i = 1; i < nr_cpu_ids; i++)
  261. core0_c0count[i] = c0count;
  262. __wbflush(); /* Let others see the result ASAP */
  263. }
  264. }
  265. #define MAX_LOOPS 800
  266. /*
  267. * SMP init and finish on secondary CPUs
  268. */
  269. static void loongson3_init_secondary(void)
  270. {
  271. int i;
  272. uint32_t initcount;
  273. unsigned int cpu = smp_processor_id();
  274. unsigned int imask = STATUSF_IP7 | STATUSF_IP6 |
  275. STATUSF_IP3 | STATUSF_IP2;
  276. /* Set interrupt mask, but don't enable */
  277. change_c0_status(ST0_IM, imask);
  278. for (i = 0; i < num_possible_cpus(); i++)
  279. loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(i)]);
  280. per_cpu(cpu_state, cpu) = CPU_ONLINE;
  281. cpu_data[cpu].core =
  282. cpu_logical_map(cpu) % loongson_sysconf.cores_per_package;
  283. cpu_data[cpu].package =
  284. cpu_logical_map(cpu) / loongson_sysconf.cores_per_package;
  285. i = 0;
  286. core0_c0count[cpu] = 0;
  287. loongson3_send_ipi_single(0, SMP_ASK_C0COUNT);
  288. while (!core0_c0count[cpu]) {
  289. i++;
  290. cpu_relax();
  291. }
  292. if (i > MAX_LOOPS)
  293. i = MAX_LOOPS;
  294. if (cpu_data[cpu].package)
  295. initcount = core0_c0count[cpu] + i;
  296. else /* Local access is faster for loops */
  297. initcount = core0_c0count[cpu] + i/2;
  298. write_c0_count(initcount);
  299. }
  300. static void loongson3_smp_finish(void)
  301. {
  302. int cpu = smp_processor_id();
  303. write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ);
  304. local_irq_enable();
  305. loongson3_ipi_write64(0,
  306. (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0));
  307. pr_info("CPU#%d finished, CP0_ST=%x\n",
  308. smp_processor_id(), read_c0_status());
  309. }
  310. static void __init loongson3_smp_setup(void)
  311. {
  312. int i = 0, num = 0; /* i: physical id, num: logical id */
  313. init_cpu_possible(cpu_none_mask);
  314. /* For unified kernel, NR_CPUS is the maximum possible value,
  315. * loongson_sysconf.nr_cpus is the really present value */
  316. while (i < loongson_sysconf.nr_cpus) {
  317. if (loongson_sysconf.reserved_cpus_mask & (1<<i)) {
  318. /* Reserved physical CPU cores */
  319. __cpu_number_map[i] = -1;
  320. } else {
  321. __cpu_number_map[i] = num;
  322. __cpu_logical_map[num] = i;
  323. set_cpu_possible(num, true);
  324. num++;
  325. }
  326. i++;
  327. }
  328. pr_info("Detected %i available CPU(s)\n", num);
  329. while (num < loongson_sysconf.nr_cpus) {
  330. __cpu_logical_map[num] = -1;
  331. num++;
  332. }
  333. ipi_set0_regs_init();
  334. ipi_clear0_regs_init();
  335. ipi_status0_regs_init();
  336. ipi_en0_regs_init();
  337. ipi_mailbox_buf_init();
  338. cpu_data[0].core = cpu_logical_map(0) % loongson_sysconf.cores_per_package;
  339. cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package;
  340. }
  341. static void __init loongson3_prepare_cpus(unsigned int max_cpus)
  342. {
  343. init_cpu_present(cpu_possible_mask);
  344. per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
  345. }
  346. /*
  347. * Setup the PC, SP, and GP of a secondary processor and start it runing!
  348. */
  349. static void loongson3_boot_secondary(int cpu, struct task_struct *idle)
  350. {
  351. unsigned long startargs[4];
  352. pr_info("Booting CPU#%d...\n", cpu);
  353. /* startargs[] are initial PC, SP and GP for secondary CPU */
  354. startargs[0] = (unsigned long)&smp_bootstrap;
  355. startargs[1] = (unsigned long)__KSTK_TOS(idle);
  356. startargs[2] = (unsigned long)task_thread_info(idle);
  357. startargs[3] = 0;
  358. pr_debug("CPU#%d, func_pc=%lx, sp=%lx, gp=%lx\n",
  359. cpu, startargs[0], startargs[1], startargs[2]);
  360. loongson3_ipi_write64(startargs[3],
  361. (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x18));
  362. loongson3_ipi_write64(startargs[2],
  363. (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x10));
  364. loongson3_ipi_write64(startargs[1],
  365. (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x8));
  366. loongson3_ipi_write64(startargs[0],
  367. (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0));
  368. }
  369. #ifdef CONFIG_HOTPLUG_CPU
  370. static int loongson3_cpu_disable(void)
  371. {
  372. unsigned long flags;
  373. unsigned int cpu = smp_processor_id();
  374. if (cpu == 0)
  375. return -EBUSY;
  376. set_cpu_online(cpu, false);
  377. cpumask_clear_cpu(cpu, &cpu_callin_map);
  378. local_irq_save(flags);
  379. fixup_irqs();
  380. local_irq_restore(flags);
  381. local_flush_tlb_all();
  382. return 0;
  383. }
  384. static void loongson3_cpu_die(unsigned int cpu)
  385. {
  386. while (per_cpu(cpu_state, cpu) != CPU_DEAD)
  387. cpu_relax();
  388. mb();
  389. }
  390. /* To shutdown a core in Loongson 3, the target core should go to CKSEG1 and
  391. * flush all L1 entries at first. Then, another core (usually Core 0) can
  392. * safely disable the clock of the target core. loongson3_play_dead() is
  393. * called via CKSEG1 (uncached and unmmaped) */
  394. static void loongson3a_r1_play_dead(int *state_addr)
  395. {
  396. register int val;
  397. register long cpuid, core, node, count;
  398. register void *addr, *base, *initfunc;
  399. __asm__ __volatile__(
  400. " .set push \n"
  401. " .set noreorder \n"
  402. " li %[addr], 0x80000000 \n" /* KSEG0 */
  403. "1: cache 0, 0(%[addr]) \n" /* flush L1 ICache */
  404. " cache 0, 1(%[addr]) \n"
  405. " cache 0, 2(%[addr]) \n"
  406. " cache 0, 3(%[addr]) \n"
  407. " cache 1, 0(%[addr]) \n" /* flush L1 DCache */
  408. " cache 1, 1(%[addr]) \n"
  409. " cache 1, 2(%[addr]) \n"
  410. " cache 1, 3(%[addr]) \n"
  411. " addiu %[sets], %[sets], -1 \n"
  412. " bnez %[sets], 1b \n"
  413. " addiu %[addr], %[addr], 0x20 \n"
  414. " li %[val], 0x7 \n" /* *state_addr = CPU_DEAD; */
  415. " sw %[val], (%[state_addr]) \n"
  416. " sync \n"
  417. " cache 21, (%[state_addr]) \n" /* flush entry of *state_addr */
  418. " .set pop \n"
  419. : [addr] "=&r" (addr), [val] "=&r" (val)
  420. : [state_addr] "r" (state_addr),
  421. [sets] "r" (cpu_data[smp_processor_id()].dcache.sets));
  422. __asm__ __volatile__(
  423. " .set push \n"
  424. " .set noreorder \n"
  425. " .set mips64 \n"
  426. " mfc0 %[cpuid], $15, 1 \n"
  427. " andi %[cpuid], 0x3ff \n"
  428. " dli %[base], 0x900000003ff01000 \n"
  429. " andi %[core], %[cpuid], 0x3 \n"
  430. " sll %[core], 8 \n" /* get core id */
  431. " or %[base], %[base], %[core] \n"
  432. " andi %[node], %[cpuid], 0xc \n"
  433. " dsll %[node], 42 \n" /* get node id */
  434. " or %[base], %[base], %[node] \n"
  435. "1: li %[count], 0x100 \n" /* wait for init loop */
  436. "2: bnez %[count], 2b \n" /* limit mailbox access */
  437. " addiu %[count], -1 \n"
  438. " ld %[initfunc], 0x20(%[base]) \n" /* get PC via mailbox */
  439. " beqz %[initfunc], 1b \n"
  440. " nop \n"
  441. " ld $sp, 0x28(%[base]) \n" /* get SP via mailbox */
  442. " ld $gp, 0x30(%[base]) \n" /* get GP via mailbox */
  443. " ld $a1, 0x38(%[base]) \n"
  444. " jr %[initfunc] \n" /* jump to initial PC */
  445. " nop \n"
  446. " .set pop \n"
  447. : [core] "=&r" (core), [node] "=&r" (node),
  448. [base] "=&r" (base), [cpuid] "=&r" (cpuid),
  449. [count] "=&r" (count), [initfunc] "=&r" (initfunc)
  450. : /* No Input */
  451. : "a1");
  452. }
  453. static void loongson3a_r2_play_dead(int *state_addr)
  454. {
  455. register int val;
  456. register long cpuid, core, node, count;
  457. register void *addr, *base, *initfunc;
  458. __asm__ __volatile__(
  459. " .set push \n"
  460. " .set noreorder \n"
  461. " li %[addr], 0x80000000 \n" /* KSEG0 */
  462. "1: cache 0, 0(%[addr]) \n" /* flush L1 ICache */
  463. " cache 0, 1(%[addr]) \n"
  464. " cache 0, 2(%[addr]) \n"
  465. " cache 0, 3(%[addr]) \n"
  466. " cache 1, 0(%[addr]) \n" /* flush L1 DCache */
  467. " cache 1, 1(%[addr]) \n"
  468. " cache 1, 2(%[addr]) \n"
  469. " cache 1, 3(%[addr]) \n"
  470. " addiu %[sets], %[sets], -1 \n"
  471. " bnez %[sets], 1b \n"
  472. " addiu %[addr], %[addr], 0x40 \n"
  473. " li %[addr], 0x80000000 \n" /* KSEG0 */
  474. "2: cache 2, 0(%[addr]) \n" /* flush L1 VCache */
  475. " cache 2, 1(%[addr]) \n"
  476. " cache 2, 2(%[addr]) \n"
  477. " cache 2, 3(%[addr]) \n"
  478. " cache 2, 4(%[addr]) \n"
  479. " cache 2, 5(%[addr]) \n"
  480. " cache 2, 6(%[addr]) \n"
  481. " cache 2, 7(%[addr]) \n"
  482. " cache 2, 8(%[addr]) \n"
  483. " cache 2, 9(%[addr]) \n"
  484. " cache 2, 10(%[addr]) \n"
  485. " cache 2, 11(%[addr]) \n"
  486. " cache 2, 12(%[addr]) \n"
  487. " cache 2, 13(%[addr]) \n"
  488. " cache 2, 14(%[addr]) \n"
  489. " cache 2, 15(%[addr]) \n"
  490. " addiu %[vsets], %[vsets], -1 \n"
  491. " bnez %[vsets], 2b \n"
  492. " addiu %[addr], %[addr], 0x40 \n"
  493. " li %[val], 0x7 \n" /* *state_addr = CPU_DEAD; */
  494. " sw %[val], (%[state_addr]) \n"
  495. " sync \n"
  496. " cache 21, (%[state_addr]) \n" /* flush entry of *state_addr */
  497. " .set pop \n"
  498. : [addr] "=&r" (addr), [val] "=&r" (val)
  499. : [state_addr] "r" (state_addr),
  500. [sets] "r" (cpu_data[smp_processor_id()].dcache.sets),
  501. [vsets] "r" (cpu_data[smp_processor_id()].vcache.sets));
  502. __asm__ __volatile__(
  503. " .set push \n"
  504. " .set noreorder \n"
  505. " .set mips64 \n"
  506. " mfc0 %[cpuid], $15, 1 \n"
  507. " andi %[cpuid], 0x3ff \n"
  508. " dli %[base], 0x900000003ff01000 \n"
  509. " andi %[core], %[cpuid], 0x3 \n"
  510. " sll %[core], 8 \n" /* get core id */
  511. " or %[base], %[base], %[core] \n"
  512. " andi %[node], %[cpuid], 0xc \n"
  513. " dsll %[node], 42 \n" /* get node id */
  514. " or %[base], %[base], %[node] \n"
  515. "1: li %[count], 0x100 \n" /* wait for init loop */
  516. "2: bnez %[count], 2b \n" /* limit mailbox access */
  517. " addiu %[count], -1 \n"
  518. " ld %[initfunc], 0x20(%[base]) \n" /* get PC via mailbox */
  519. " beqz %[initfunc], 1b \n"
  520. " nop \n"
  521. " ld $sp, 0x28(%[base]) \n" /* get SP via mailbox */
  522. " ld $gp, 0x30(%[base]) \n" /* get GP via mailbox */
  523. " ld $a1, 0x38(%[base]) \n"
  524. " jr %[initfunc] \n" /* jump to initial PC */
  525. " nop \n"
  526. " .set pop \n"
  527. : [core] "=&r" (core), [node] "=&r" (node),
  528. [base] "=&r" (base), [cpuid] "=&r" (cpuid),
  529. [count] "=&r" (count), [initfunc] "=&r" (initfunc)
  530. : /* No Input */
  531. : "a1");
  532. }
  533. static void loongson3b_play_dead(int *state_addr)
  534. {
  535. register int val;
  536. register long cpuid, core, node, count;
  537. register void *addr, *base, *initfunc;
  538. __asm__ __volatile__(
  539. " .set push \n"
  540. " .set noreorder \n"
  541. " li %[addr], 0x80000000 \n" /* KSEG0 */
  542. "1: cache 0, 0(%[addr]) \n" /* flush L1 ICache */
  543. " cache 0, 1(%[addr]) \n"
  544. " cache 0, 2(%[addr]) \n"
  545. " cache 0, 3(%[addr]) \n"
  546. " cache 1, 0(%[addr]) \n" /* flush L1 DCache */
  547. " cache 1, 1(%[addr]) \n"
  548. " cache 1, 2(%[addr]) \n"
  549. " cache 1, 3(%[addr]) \n"
  550. " addiu %[sets], %[sets], -1 \n"
  551. " bnez %[sets], 1b \n"
  552. " addiu %[addr], %[addr], 0x20 \n"
  553. " li %[val], 0x7 \n" /* *state_addr = CPU_DEAD; */
  554. " sw %[val], (%[state_addr]) \n"
  555. " sync \n"
  556. " cache 21, (%[state_addr]) \n" /* flush entry of *state_addr */
  557. " .set pop \n"
  558. : [addr] "=&r" (addr), [val] "=&r" (val)
  559. : [state_addr] "r" (state_addr),
  560. [sets] "r" (cpu_data[smp_processor_id()].dcache.sets));
  561. __asm__ __volatile__(
  562. " .set push \n"
  563. " .set noreorder \n"
  564. " .set mips64 \n"
  565. " mfc0 %[cpuid], $15, 1 \n"
  566. " andi %[cpuid], 0x3ff \n"
  567. " dli %[base], 0x900000003ff01000 \n"
  568. " andi %[core], %[cpuid], 0x3 \n"
  569. " sll %[core], 8 \n" /* get core id */
  570. " or %[base], %[base], %[core] \n"
  571. " andi %[node], %[cpuid], 0xc \n"
  572. " dsll %[node], 42 \n" /* get node id */
  573. " or %[base], %[base], %[node] \n"
  574. " dsrl %[node], 30 \n" /* 15:14 */
  575. " or %[base], %[base], %[node] \n"
  576. "1: li %[count], 0x100 \n" /* wait for init loop */
  577. "2: bnez %[count], 2b \n" /* limit mailbox access */
  578. " addiu %[count], -1 \n"
  579. " ld %[initfunc], 0x20(%[base]) \n" /* get PC via mailbox */
  580. " beqz %[initfunc], 1b \n"
  581. " nop \n"
  582. " ld $sp, 0x28(%[base]) \n" /* get SP via mailbox */
  583. " ld $gp, 0x30(%[base]) \n" /* get GP via mailbox */
  584. " ld $a1, 0x38(%[base]) \n"
  585. " jr %[initfunc] \n" /* jump to initial PC */
  586. " nop \n"
  587. " .set pop \n"
  588. : [core] "=&r" (core), [node] "=&r" (node),
  589. [base] "=&r" (base), [cpuid] "=&r" (cpuid),
  590. [count] "=&r" (count), [initfunc] "=&r" (initfunc)
  591. : /* No Input */
  592. : "a1");
  593. }
  594. void play_dead(void)
  595. {
  596. int *state_addr;
  597. unsigned int cpu = smp_processor_id();
  598. void (*play_dead_at_ckseg1)(int *);
  599. idle_task_exit();
  600. switch (read_c0_prid() & PRID_REV_MASK) {
  601. case PRID_REV_LOONGSON3A_R1:
  602. default:
  603. play_dead_at_ckseg1 =
  604. (void *)CKSEG1ADDR((unsigned long)loongson3a_r1_play_dead);
  605. break;
  606. case PRID_REV_LOONGSON3A_R2:
  607. play_dead_at_ckseg1 =
  608. (void *)CKSEG1ADDR((unsigned long)loongson3a_r2_play_dead);
  609. break;
  610. case PRID_REV_LOONGSON3B_R1:
  611. case PRID_REV_LOONGSON3B_R2:
  612. play_dead_at_ckseg1 =
  613. (void *)CKSEG1ADDR((unsigned long)loongson3b_play_dead);
  614. break;
  615. }
  616. state_addr = &per_cpu(cpu_state, cpu);
  617. mb();
  618. play_dead_at_ckseg1(state_addr);
  619. }
  620. void loongson3_disable_clock(int cpu)
  621. {
  622. uint64_t core_id = cpu_data[cpu].core;
  623. uint64_t package_id = cpu_data[cpu].package;
  624. if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
  625. LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id));
  626. } else {
  627. if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG))
  628. LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3));
  629. }
  630. }
  631. void loongson3_enable_clock(int cpu)
  632. {
  633. uint64_t core_id = cpu_data[cpu].core;
  634. uint64_t package_id = cpu_data[cpu].package;
  635. if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
  636. LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id);
  637. } else {
  638. if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG))
  639. LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3);
  640. }
  641. }
  642. #define CPU_POST_DEAD_FROZEN (CPU_POST_DEAD | CPU_TASKS_FROZEN)
  643. static int loongson3_cpu_callback(struct notifier_block *nfb,
  644. unsigned long action, void *hcpu)
  645. {
  646. unsigned int cpu = (unsigned long)hcpu;
  647. switch (action) {
  648. case CPU_POST_DEAD:
  649. case CPU_POST_DEAD_FROZEN:
  650. pr_info("Disable clock for CPU#%d\n", cpu);
  651. loongson3_disable_clock(cpu);
  652. break;
  653. case CPU_UP_PREPARE:
  654. case CPU_UP_PREPARE_FROZEN:
  655. pr_info("Enable clock for CPU#%d\n", cpu);
  656. loongson3_enable_clock(cpu);
  657. break;
  658. }
  659. return NOTIFY_OK;
  660. }
  661. static int register_loongson3_notifier(void)
  662. {
  663. hotcpu_notifier(loongson3_cpu_callback, 0);
  664. return 0;
  665. }
  666. early_initcall(register_loongson3_notifier);
  667. #endif
  668. struct plat_smp_ops loongson3_smp_ops = {
  669. .send_ipi_single = loongson3_send_ipi_single,
  670. .send_ipi_mask = loongson3_send_ipi_mask,
  671. .init_secondary = loongson3_init_secondary,
  672. .smp_finish = loongson3_smp_finish,
  673. .boot_secondary = loongson3_boot_secondary,
  674. .smp_setup = loongson3_smp_setup,
  675. .prepare_cpus = loongson3_prepare_cpus,
  676. #ifdef CONFIG_HOTPLUG_CPU
  677. .cpu_disable = loongson3_cpu_disable,
  678. .cpu_die = loongson3_cpu_die,
  679. #endif
  680. };