smp.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  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. calculate_cpu_foreign_map();
  378. cpumask_clear_cpu(cpu, &cpu_callin_map);
  379. local_irq_save(flags);
  380. fixup_irqs();
  381. local_irq_restore(flags);
  382. local_flush_tlb_all();
  383. return 0;
  384. }
  385. static void loongson3_cpu_die(unsigned int cpu)
  386. {
  387. while (per_cpu(cpu_state, cpu) != CPU_DEAD)
  388. cpu_relax();
  389. mb();
  390. }
  391. /* To shutdown a core in Loongson 3, the target core should go to CKSEG1 and
  392. * flush all L1 entries at first. Then, another core (usually Core 0) can
  393. * safely disable the clock of the target core. loongson3_play_dead() is
  394. * called via CKSEG1 (uncached and unmmaped) */
  395. static void loongson3a_r1_play_dead(int *state_addr)
  396. {
  397. register int val;
  398. register long cpuid, core, node, count;
  399. register void *addr, *base, *initfunc;
  400. __asm__ __volatile__(
  401. " .set push \n"
  402. " .set noreorder \n"
  403. " li %[addr], 0x80000000 \n" /* KSEG0 */
  404. "1: cache 0, 0(%[addr]) \n" /* flush L1 ICache */
  405. " cache 0, 1(%[addr]) \n"
  406. " cache 0, 2(%[addr]) \n"
  407. " cache 0, 3(%[addr]) \n"
  408. " cache 1, 0(%[addr]) \n" /* flush L1 DCache */
  409. " cache 1, 1(%[addr]) \n"
  410. " cache 1, 2(%[addr]) \n"
  411. " cache 1, 3(%[addr]) \n"
  412. " addiu %[sets], %[sets], -1 \n"
  413. " bnez %[sets], 1b \n"
  414. " addiu %[addr], %[addr], 0x20 \n"
  415. " li %[val], 0x7 \n" /* *state_addr = CPU_DEAD; */
  416. " sw %[val], (%[state_addr]) \n"
  417. " sync \n"
  418. " cache 21, (%[state_addr]) \n" /* flush entry of *state_addr */
  419. " .set pop \n"
  420. : [addr] "=&r" (addr), [val] "=&r" (val)
  421. : [state_addr] "r" (state_addr),
  422. [sets] "r" (cpu_data[smp_processor_id()].dcache.sets));
  423. __asm__ __volatile__(
  424. " .set push \n"
  425. " .set noreorder \n"
  426. " .set mips64 \n"
  427. " mfc0 %[cpuid], $15, 1 \n"
  428. " andi %[cpuid], 0x3ff \n"
  429. " dli %[base], 0x900000003ff01000 \n"
  430. " andi %[core], %[cpuid], 0x3 \n"
  431. " sll %[core], 8 \n" /* get core id */
  432. " or %[base], %[base], %[core] \n"
  433. " andi %[node], %[cpuid], 0xc \n"
  434. " dsll %[node], 42 \n" /* get node id */
  435. " or %[base], %[base], %[node] \n"
  436. "1: li %[count], 0x100 \n" /* wait for init loop */
  437. "2: bnez %[count], 2b \n" /* limit mailbox access */
  438. " addiu %[count], -1 \n"
  439. " ld %[initfunc], 0x20(%[base]) \n" /* get PC via mailbox */
  440. " beqz %[initfunc], 1b \n"
  441. " nop \n"
  442. " ld $sp, 0x28(%[base]) \n" /* get SP via mailbox */
  443. " ld $gp, 0x30(%[base]) \n" /* get GP via mailbox */
  444. " ld $a1, 0x38(%[base]) \n"
  445. " jr %[initfunc] \n" /* jump to initial PC */
  446. " nop \n"
  447. " .set pop \n"
  448. : [core] "=&r" (core), [node] "=&r" (node),
  449. [base] "=&r" (base), [cpuid] "=&r" (cpuid),
  450. [count] "=&r" (count), [initfunc] "=&r" (initfunc)
  451. : /* No Input */
  452. : "a1");
  453. }
  454. static void loongson3a_r2_play_dead(int *state_addr)
  455. {
  456. register int val;
  457. register long cpuid, core, node, count;
  458. register void *addr, *base, *initfunc;
  459. __asm__ __volatile__(
  460. " .set push \n"
  461. " .set noreorder \n"
  462. " li %[addr], 0x80000000 \n" /* KSEG0 */
  463. "1: cache 0, 0(%[addr]) \n" /* flush L1 ICache */
  464. " cache 0, 1(%[addr]) \n"
  465. " cache 0, 2(%[addr]) \n"
  466. " cache 0, 3(%[addr]) \n"
  467. " cache 1, 0(%[addr]) \n" /* flush L1 DCache */
  468. " cache 1, 1(%[addr]) \n"
  469. " cache 1, 2(%[addr]) \n"
  470. " cache 1, 3(%[addr]) \n"
  471. " addiu %[sets], %[sets], -1 \n"
  472. " bnez %[sets], 1b \n"
  473. " addiu %[addr], %[addr], 0x40 \n"
  474. " li %[addr], 0x80000000 \n" /* KSEG0 */
  475. "2: cache 2, 0(%[addr]) \n" /* flush L1 VCache */
  476. " cache 2, 1(%[addr]) \n"
  477. " cache 2, 2(%[addr]) \n"
  478. " cache 2, 3(%[addr]) \n"
  479. " cache 2, 4(%[addr]) \n"
  480. " cache 2, 5(%[addr]) \n"
  481. " cache 2, 6(%[addr]) \n"
  482. " cache 2, 7(%[addr]) \n"
  483. " cache 2, 8(%[addr]) \n"
  484. " cache 2, 9(%[addr]) \n"
  485. " cache 2, 10(%[addr]) \n"
  486. " cache 2, 11(%[addr]) \n"
  487. " cache 2, 12(%[addr]) \n"
  488. " cache 2, 13(%[addr]) \n"
  489. " cache 2, 14(%[addr]) \n"
  490. " cache 2, 15(%[addr]) \n"
  491. " addiu %[vsets], %[vsets], -1 \n"
  492. " bnez %[vsets], 2b \n"
  493. " addiu %[addr], %[addr], 0x40 \n"
  494. " li %[val], 0x7 \n" /* *state_addr = CPU_DEAD; */
  495. " sw %[val], (%[state_addr]) \n"
  496. " sync \n"
  497. " cache 21, (%[state_addr]) \n" /* flush entry of *state_addr */
  498. " .set pop \n"
  499. : [addr] "=&r" (addr), [val] "=&r" (val)
  500. : [state_addr] "r" (state_addr),
  501. [sets] "r" (cpu_data[smp_processor_id()].dcache.sets),
  502. [vsets] "r" (cpu_data[smp_processor_id()].vcache.sets));
  503. __asm__ __volatile__(
  504. " .set push \n"
  505. " .set noreorder \n"
  506. " .set mips64 \n"
  507. " mfc0 %[cpuid], $15, 1 \n"
  508. " andi %[cpuid], 0x3ff \n"
  509. " dli %[base], 0x900000003ff01000 \n"
  510. " andi %[core], %[cpuid], 0x3 \n"
  511. " sll %[core], 8 \n" /* get core id */
  512. " or %[base], %[base], %[core] \n"
  513. " andi %[node], %[cpuid], 0xc \n"
  514. " dsll %[node], 42 \n" /* get node id */
  515. " or %[base], %[base], %[node] \n"
  516. "1: li %[count], 0x100 \n" /* wait for init loop */
  517. "2: bnez %[count], 2b \n" /* limit mailbox access */
  518. " addiu %[count], -1 \n"
  519. " ld %[initfunc], 0x20(%[base]) \n" /* get PC via mailbox */
  520. " beqz %[initfunc], 1b \n"
  521. " nop \n"
  522. " ld $sp, 0x28(%[base]) \n" /* get SP via mailbox */
  523. " ld $gp, 0x30(%[base]) \n" /* get GP via mailbox */
  524. " ld $a1, 0x38(%[base]) \n"
  525. " jr %[initfunc] \n" /* jump to initial PC */
  526. " nop \n"
  527. " .set pop \n"
  528. : [core] "=&r" (core), [node] "=&r" (node),
  529. [base] "=&r" (base), [cpuid] "=&r" (cpuid),
  530. [count] "=&r" (count), [initfunc] "=&r" (initfunc)
  531. : /* No Input */
  532. : "a1");
  533. }
  534. static void loongson3b_play_dead(int *state_addr)
  535. {
  536. register int val;
  537. register long cpuid, core, node, count;
  538. register void *addr, *base, *initfunc;
  539. __asm__ __volatile__(
  540. " .set push \n"
  541. " .set noreorder \n"
  542. " li %[addr], 0x80000000 \n" /* KSEG0 */
  543. "1: cache 0, 0(%[addr]) \n" /* flush L1 ICache */
  544. " cache 0, 1(%[addr]) \n"
  545. " cache 0, 2(%[addr]) \n"
  546. " cache 0, 3(%[addr]) \n"
  547. " cache 1, 0(%[addr]) \n" /* flush L1 DCache */
  548. " cache 1, 1(%[addr]) \n"
  549. " cache 1, 2(%[addr]) \n"
  550. " cache 1, 3(%[addr]) \n"
  551. " addiu %[sets], %[sets], -1 \n"
  552. " bnez %[sets], 1b \n"
  553. " addiu %[addr], %[addr], 0x20 \n"
  554. " li %[val], 0x7 \n" /* *state_addr = CPU_DEAD; */
  555. " sw %[val], (%[state_addr]) \n"
  556. " sync \n"
  557. " cache 21, (%[state_addr]) \n" /* flush entry of *state_addr */
  558. " .set pop \n"
  559. : [addr] "=&r" (addr), [val] "=&r" (val)
  560. : [state_addr] "r" (state_addr),
  561. [sets] "r" (cpu_data[smp_processor_id()].dcache.sets));
  562. __asm__ __volatile__(
  563. " .set push \n"
  564. " .set noreorder \n"
  565. " .set mips64 \n"
  566. " mfc0 %[cpuid], $15, 1 \n"
  567. " andi %[cpuid], 0x3ff \n"
  568. " dli %[base], 0x900000003ff01000 \n"
  569. " andi %[core], %[cpuid], 0x3 \n"
  570. " sll %[core], 8 \n" /* get core id */
  571. " or %[base], %[base], %[core] \n"
  572. " andi %[node], %[cpuid], 0xc \n"
  573. " dsll %[node], 42 \n" /* get node id */
  574. " or %[base], %[base], %[node] \n"
  575. " dsrl %[node], 30 \n" /* 15:14 */
  576. " or %[base], %[base], %[node] \n"
  577. "1: li %[count], 0x100 \n" /* wait for init loop */
  578. "2: bnez %[count], 2b \n" /* limit mailbox access */
  579. " addiu %[count], -1 \n"
  580. " ld %[initfunc], 0x20(%[base]) \n" /* get PC via mailbox */
  581. " beqz %[initfunc], 1b \n"
  582. " nop \n"
  583. " ld $sp, 0x28(%[base]) \n" /* get SP via mailbox */
  584. " ld $gp, 0x30(%[base]) \n" /* get GP via mailbox */
  585. " ld $a1, 0x38(%[base]) \n"
  586. " jr %[initfunc] \n" /* jump to initial PC */
  587. " nop \n"
  588. " .set pop \n"
  589. : [core] "=&r" (core), [node] "=&r" (node),
  590. [base] "=&r" (base), [cpuid] "=&r" (cpuid),
  591. [count] "=&r" (count), [initfunc] "=&r" (initfunc)
  592. : /* No Input */
  593. : "a1");
  594. }
  595. void play_dead(void)
  596. {
  597. int *state_addr;
  598. unsigned int cpu = smp_processor_id();
  599. void (*play_dead_at_ckseg1)(int *);
  600. idle_task_exit();
  601. switch (read_c0_prid() & PRID_REV_MASK) {
  602. case PRID_REV_LOONGSON3A_R1:
  603. default:
  604. play_dead_at_ckseg1 =
  605. (void *)CKSEG1ADDR((unsigned long)loongson3a_r1_play_dead);
  606. break;
  607. case PRID_REV_LOONGSON3A_R2:
  608. play_dead_at_ckseg1 =
  609. (void *)CKSEG1ADDR((unsigned long)loongson3a_r2_play_dead);
  610. break;
  611. case PRID_REV_LOONGSON3B_R1:
  612. case PRID_REV_LOONGSON3B_R2:
  613. play_dead_at_ckseg1 =
  614. (void *)CKSEG1ADDR((unsigned long)loongson3b_play_dead);
  615. break;
  616. }
  617. state_addr = &per_cpu(cpu_state, cpu);
  618. mb();
  619. play_dead_at_ckseg1(state_addr);
  620. }
  621. static int loongson3_disable_clock(unsigned int cpu)
  622. {
  623. uint64_t core_id = cpu_data[cpu].core;
  624. uint64_t package_id = cpu_data[cpu].package;
  625. if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
  626. LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id));
  627. } else {
  628. if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG))
  629. LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3));
  630. }
  631. return 0;
  632. }
  633. static int loongson3_enable_clock(unsigned int cpu)
  634. {
  635. uint64_t core_id = cpu_data[cpu].core;
  636. uint64_t package_id = cpu_data[cpu].package;
  637. if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
  638. LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id);
  639. } else {
  640. if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG))
  641. LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3);
  642. }
  643. return 0;
  644. }
  645. static int register_loongson3_notifier(void)
  646. {
  647. return cpuhp_setup_state_nocalls(CPUHP_MIPS_SOC_PREPARE,
  648. "mips/loongson:prepare",
  649. loongson3_enable_clock,
  650. loongson3_disable_clock);
  651. }
  652. early_initcall(register_loongson3_notifier);
  653. #endif
  654. struct plat_smp_ops loongson3_smp_ops = {
  655. .send_ipi_single = loongson3_send_ipi_single,
  656. .send_ipi_mask = loongson3_send_ipi_mask,
  657. .init_secondary = loongson3_init_secondary,
  658. .smp_finish = loongson3_smp_finish,
  659. .boot_secondary = loongson3_boot_secondary,
  660. .smp_setup = loongson3_smp_setup,
  661. .prepare_cpus = loongson3_prepare_cpus,
  662. #ifdef CONFIG_HOTPLUG_CPU
  663. .cpu_disable = loongson3_cpu_disable,
  664. .cpu_die = loongson3_cpu_die,
  665. #endif
  666. };