smp.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) 2010, 2011, 2012, Lemote, Inc.
  4. * Author: Chen Huacai, [email protected]
  5. */
  6. #include <irq.h>
  7. #include <linux/init.h>
  8. #include <linux/cpu.h>
  9. #include <linux/sched.h>
  10. #include <linux/sched/hotplug.h>
  11. #include <linux/sched/task_stack.h>
  12. #include <linux/smp.h>
  13. #include <linux/cpufreq.h>
  14. #include <linux/kexec.h>
  15. #include <asm/processor.h>
  16. #include <asm/time.h>
  17. #include <asm/tlbflush.h>
  18. #include <asm/cacheflush.h>
  19. #include <loongson.h>
  20. #include <loongson_regs.h>
  21. #include <workarounds.h>
  22. #include "smp.h"
  23. DEFINE_PER_CPU(int, cpu_state);
  24. #define LS_IPI_IRQ (MIPS_CPU_IRQ_BASE + 6)
  25. static void *ipi_set0_regs[16];
  26. static void *ipi_clear0_regs[16];
  27. static void *ipi_status0_regs[16];
  28. static void *ipi_en0_regs[16];
  29. static void *ipi_mailbox_buf[16];
  30. static uint32_t core0_c0count[NR_CPUS];
  31. /* read a 32bit value from ipi register */
  32. #define loongson3_ipi_read32(addr) readl(addr)
  33. /* read a 64bit value from ipi register */
  34. #define loongson3_ipi_read64(addr) readq(addr)
  35. /* write a 32bit value to ipi register */
  36. #define loongson3_ipi_write32(action, addr) \
  37. do { \
  38. writel(action, addr); \
  39. __wbflush(); \
  40. } while (0)
  41. /* write a 64bit value to ipi register */
  42. #define loongson3_ipi_write64(action, addr) \
  43. do { \
  44. writeq(action, addr); \
  45. __wbflush(); \
  46. } while (0)
  47. static u32 (*ipi_read_clear)(int cpu);
  48. static void (*ipi_write_action)(int cpu, u32 action);
  49. static void (*ipi_write_enable)(int cpu);
  50. static void (*ipi_clear_buf)(int cpu);
  51. static void (*ipi_write_buf)(int cpu, struct task_struct *idle);
  52. /* send mail via Mail_Send register for 3A4000+ CPU */
  53. static void csr_mail_send(uint64_t data, int cpu, int mailbox)
  54. {
  55. uint64_t val;
  56. /* send high 32 bits */
  57. val = CSR_MAIL_SEND_BLOCK;
  58. val |= (CSR_MAIL_SEND_BOX_HIGH(mailbox) << CSR_MAIL_SEND_BOX_SHIFT);
  59. val |= (cpu << CSR_MAIL_SEND_CPU_SHIFT);
  60. val |= (data & CSR_MAIL_SEND_H32_MASK);
  61. csr_writeq(val, LOONGSON_CSR_MAIL_SEND);
  62. /* send low 32 bits */
  63. val = CSR_MAIL_SEND_BLOCK;
  64. val |= (CSR_MAIL_SEND_BOX_LOW(mailbox) << CSR_MAIL_SEND_BOX_SHIFT);
  65. val |= (cpu << CSR_MAIL_SEND_CPU_SHIFT);
  66. val |= (data << CSR_MAIL_SEND_BUF_SHIFT);
  67. csr_writeq(val, LOONGSON_CSR_MAIL_SEND);
  68. };
  69. static u32 csr_ipi_read_clear(int cpu)
  70. {
  71. u32 action;
  72. /* Load the ipi register to figure out what we're supposed to do */
  73. action = csr_readl(LOONGSON_CSR_IPI_STATUS);
  74. /* Clear the ipi register to clear the interrupt */
  75. csr_writel(action, LOONGSON_CSR_IPI_CLEAR);
  76. return action;
  77. }
  78. static void csr_ipi_write_action(int cpu, u32 action)
  79. {
  80. unsigned int irq = 0;
  81. while ((irq = ffs(action))) {
  82. uint32_t val = CSR_IPI_SEND_BLOCK;
  83. val |= (irq - 1);
  84. val |= (cpu << CSR_IPI_SEND_CPU_SHIFT);
  85. csr_writel(val, LOONGSON_CSR_IPI_SEND);
  86. action &= ~BIT(irq - 1);
  87. }
  88. }
  89. static void csr_ipi_write_enable(int cpu)
  90. {
  91. csr_writel(0xffffffff, LOONGSON_CSR_IPI_EN);
  92. }
  93. static void csr_ipi_clear_buf(int cpu)
  94. {
  95. csr_writeq(0, LOONGSON_CSR_MAIL_BUF0);
  96. }
  97. static void csr_ipi_write_buf(int cpu, struct task_struct *idle)
  98. {
  99. unsigned long startargs[4];
  100. /* startargs[] are initial PC, SP and GP for secondary CPU */
  101. startargs[0] = (unsigned long)&smp_bootstrap;
  102. startargs[1] = (unsigned long)__KSTK_TOS(idle);
  103. startargs[2] = (unsigned long)task_thread_info(idle);
  104. startargs[3] = 0;
  105. pr_debug("CPU#%d, func_pc=%lx, sp=%lx, gp=%lx\n",
  106. cpu, startargs[0], startargs[1], startargs[2]);
  107. csr_mail_send(startargs[3], cpu_logical_map(cpu), 3);
  108. csr_mail_send(startargs[2], cpu_logical_map(cpu), 2);
  109. csr_mail_send(startargs[1], cpu_logical_map(cpu), 1);
  110. csr_mail_send(startargs[0], cpu_logical_map(cpu), 0);
  111. }
  112. static u32 legacy_ipi_read_clear(int cpu)
  113. {
  114. u32 action;
  115. /* Load the ipi register to figure out what we're supposed to do */
  116. action = loongson3_ipi_read32(ipi_status0_regs[cpu_logical_map(cpu)]);
  117. /* Clear the ipi register to clear the interrupt */
  118. loongson3_ipi_write32(action, ipi_clear0_regs[cpu_logical_map(cpu)]);
  119. return action;
  120. }
  121. static void legacy_ipi_write_action(int cpu, u32 action)
  122. {
  123. loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu]);
  124. }
  125. static void legacy_ipi_write_enable(int cpu)
  126. {
  127. loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(cpu)]);
  128. }
  129. static void legacy_ipi_clear_buf(int cpu)
  130. {
  131. loongson3_ipi_write64(0, ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x0);
  132. }
  133. static void legacy_ipi_write_buf(int cpu, struct task_struct *idle)
  134. {
  135. unsigned long startargs[4];
  136. /* startargs[] are initial PC, SP and GP for secondary CPU */
  137. startargs[0] = (unsigned long)&smp_bootstrap;
  138. startargs[1] = (unsigned long)__KSTK_TOS(idle);
  139. startargs[2] = (unsigned long)task_thread_info(idle);
  140. startargs[3] = 0;
  141. pr_debug("CPU#%d, func_pc=%lx, sp=%lx, gp=%lx\n",
  142. cpu, startargs[0], startargs[1], startargs[2]);
  143. loongson3_ipi_write64(startargs[3],
  144. ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x18);
  145. loongson3_ipi_write64(startargs[2],
  146. ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x10);
  147. loongson3_ipi_write64(startargs[1],
  148. ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x8);
  149. loongson3_ipi_write64(startargs[0],
  150. ipi_mailbox_buf[cpu_logical_map(cpu)] + 0x0);
  151. }
  152. static void csr_ipi_probe(void)
  153. {
  154. if (cpu_has_csr() && csr_readl(LOONGSON_CSR_FEATURES) & LOONGSON_CSRF_IPI) {
  155. ipi_read_clear = csr_ipi_read_clear;
  156. ipi_write_action = csr_ipi_write_action;
  157. ipi_write_enable = csr_ipi_write_enable;
  158. ipi_clear_buf = csr_ipi_clear_buf;
  159. ipi_write_buf = csr_ipi_write_buf;
  160. } else {
  161. ipi_read_clear = legacy_ipi_read_clear;
  162. ipi_write_action = legacy_ipi_write_action;
  163. ipi_write_enable = legacy_ipi_write_enable;
  164. ipi_clear_buf = legacy_ipi_clear_buf;
  165. ipi_write_buf = legacy_ipi_write_buf;
  166. }
  167. }
  168. static void ipi_set0_regs_init(void)
  169. {
  170. ipi_set0_regs[0] = (void *)
  171. (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + SET0);
  172. ipi_set0_regs[1] = (void *)
  173. (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + SET0);
  174. ipi_set0_regs[2] = (void *)
  175. (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + SET0);
  176. ipi_set0_regs[3] = (void *)
  177. (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + SET0);
  178. ipi_set0_regs[4] = (void *)
  179. (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + SET0);
  180. ipi_set0_regs[5] = (void *)
  181. (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + SET0);
  182. ipi_set0_regs[6] = (void *)
  183. (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + SET0);
  184. ipi_set0_regs[7] = (void *)
  185. (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + SET0);
  186. ipi_set0_regs[8] = (void *)
  187. (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + SET0);
  188. ipi_set0_regs[9] = (void *)
  189. (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + SET0);
  190. ipi_set0_regs[10] = (void *)
  191. (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + SET0);
  192. ipi_set0_regs[11] = (void *)
  193. (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + SET0);
  194. ipi_set0_regs[12] = (void *)
  195. (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + SET0);
  196. ipi_set0_regs[13] = (void *)
  197. (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + SET0);
  198. ipi_set0_regs[14] = (void *)
  199. (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + SET0);
  200. ipi_set0_regs[15] = (void *)
  201. (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + SET0);
  202. }
  203. static void ipi_clear0_regs_init(void)
  204. {
  205. ipi_clear0_regs[0] = (void *)
  206. (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + CLEAR0);
  207. ipi_clear0_regs[1] = (void *)
  208. (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + CLEAR0);
  209. ipi_clear0_regs[2] = (void *)
  210. (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + CLEAR0);
  211. ipi_clear0_regs[3] = (void *)
  212. (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + CLEAR0);
  213. ipi_clear0_regs[4] = (void *)
  214. (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + CLEAR0);
  215. ipi_clear0_regs[5] = (void *)
  216. (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + CLEAR0);
  217. ipi_clear0_regs[6] = (void *)
  218. (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + CLEAR0);
  219. ipi_clear0_regs[7] = (void *)
  220. (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + CLEAR0);
  221. ipi_clear0_regs[8] = (void *)
  222. (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + CLEAR0);
  223. ipi_clear0_regs[9] = (void *)
  224. (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + CLEAR0);
  225. ipi_clear0_regs[10] = (void *)
  226. (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + CLEAR0);
  227. ipi_clear0_regs[11] = (void *)
  228. (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + CLEAR0);
  229. ipi_clear0_regs[12] = (void *)
  230. (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + CLEAR0);
  231. ipi_clear0_regs[13] = (void *)
  232. (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + CLEAR0);
  233. ipi_clear0_regs[14] = (void *)
  234. (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + CLEAR0);
  235. ipi_clear0_regs[15] = (void *)
  236. (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + CLEAR0);
  237. }
  238. static void ipi_status0_regs_init(void)
  239. {
  240. ipi_status0_regs[0] = (void *)
  241. (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + STATUS0);
  242. ipi_status0_regs[1] = (void *)
  243. (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + STATUS0);
  244. ipi_status0_regs[2] = (void *)
  245. (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + STATUS0);
  246. ipi_status0_regs[3] = (void *)
  247. (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + STATUS0);
  248. ipi_status0_regs[4] = (void *)
  249. (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + STATUS0);
  250. ipi_status0_regs[5] = (void *)
  251. (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + STATUS0);
  252. ipi_status0_regs[6] = (void *)
  253. (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + STATUS0);
  254. ipi_status0_regs[7] = (void *)
  255. (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + STATUS0);
  256. ipi_status0_regs[8] = (void *)
  257. (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + STATUS0);
  258. ipi_status0_regs[9] = (void *)
  259. (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + STATUS0);
  260. ipi_status0_regs[10] = (void *)
  261. (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + STATUS0);
  262. ipi_status0_regs[11] = (void *)
  263. (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + STATUS0);
  264. ipi_status0_regs[12] = (void *)
  265. (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + STATUS0);
  266. ipi_status0_regs[13] = (void *)
  267. (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + STATUS0);
  268. ipi_status0_regs[14] = (void *)
  269. (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + STATUS0);
  270. ipi_status0_regs[15] = (void *)
  271. (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + STATUS0);
  272. }
  273. static void ipi_en0_regs_init(void)
  274. {
  275. ipi_en0_regs[0] = (void *)
  276. (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + EN0);
  277. ipi_en0_regs[1] = (void *)
  278. (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + EN0);
  279. ipi_en0_regs[2] = (void *)
  280. (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + EN0);
  281. ipi_en0_regs[3] = (void *)
  282. (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + EN0);
  283. ipi_en0_regs[4] = (void *)
  284. (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + EN0);
  285. ipi_en0_regs[5] = (void *)
  286. (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + EN0);
  287. ipi_en0_regs[6] = (void *)
  288. (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + EN0);
  289. ipi_en0_regs[7] = (void *)
  290. (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + EN0);
  291. ipi_en0_regs[8] = (void *)
  292. (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + EN0);
  293. ipi_en0_regs[9] = (void *)
  294. (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + EN0);
  295. ipi_en0_regs[10] = (void *)
  296. (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + EN0);
  297. ipi_en0_regs[11] = (void *)
  298. (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + EN0);
  299. ipi_en0_regs[12] = (void *)
  300. (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + EN0);
  301. ipi_en0_regs[13] = (void *)
  302. (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + EN0);
  303. ipi_en0_regs[14] = (void *)
  304. (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + EN0);
  305. ipi_en0_regs[15] = (void *)
  306. (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + EN0);
  307. }
  308. static void ipi_mailbox_buf_init(void)
  309. {
  310. ipi_mailbox_buf[0] = (void *)
  311. (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + BUF);
  312. ipi_mailbox_buf[1] = (void *)
  313. (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + BUF);
  314. ipi_mailbox_buf[2] = (void *)
  315. (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + BUF);
  316. ipi_mailbox_buf[3] = (void *)
  317. (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + BUF);
  318. ipi_mailbox_buf[4] = (void *)
  319. (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + BUF);
  320. ipi_mailbox_buf[5] = (void *)
  321. (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + BUF);
  322. ipi_mailbox_buf[6] = (void *)
  323. (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + BUF);
  324. ipi_mailbox_buf[7] = (void *)
  325. (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + BUF);
  326. ipi_mailbox_buf[8] = (void *)
  327. (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + BUF);
  328. ipi_mailbox_buf[9] = (void *)
  329. (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + BUF);
  330. ipi_mailbox_buf[10] = (void *)
  331. (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + BUF);
  332. ipi_mailbox_buf[11] = (void *)
  333. (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + BUF);
  334. ipi_mailbox_buf[12] = (void *)
  335. (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + BUF);
  336. ipi_mailbox_buf[13] = (void *)
  337. (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + BUF);
  338. ipi_mailbox_buf[14] = (void *)
  339. (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + BUF);
  340. ipi_mailbox_buf[15] = (void *)
  341. (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + BUF);
  342. }
  343. /*
  344. * Simple enough, just poke the appropriate ipi register
  345. */
  346. static void loongson3_send_ipi_single(int cpu, unsigned int action)
  347. {
  348. ipi_write_action(cpu_logical_map(cpu), (u32)action);
  349. }
  350. static void
  351. loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action)
  352. {
  353. unsigned int i;
  354. for_each_cpu(i, mask)
  355. ipi_write_action(cpu_logical_map(i), (u32)action);
  356. }
  357. static irqreturn_t loongson3_ipi_interrupt(int irq, void *dev_id)
  358. {
  359. int i, cpu = smp_processor_id();
  360. unsigned int action, c0count;
  361. action = ipi_read_clear(cpu);
  362. if (action & SMP_RESCHEDULE_YOURSELF)
  363. scheduler_ipi();
  364. if (action & SMP_CALL_FUNCTION) {
  365. irq_enter();
  366. generic_smp_call_function_interrupt();
  367. irq_exit();
  368. }
  369. if (action & SMP_ASK_C0COUNT) {
  370. BUG_ON(cpu != 0);
  371. c0count = read_c0_count();
  372. c0count = c0count ? c0count : 1;
  373. for (i = 1; i < nr_cpu_ids; i++)
  374. core0_c0count[i] = c0count;
  375. __wbflush(); /* Let others see the result ASAP */
  376. }
  377. return IRQ_HANDLED;
  378. }
  379. #define MAX_LOOPS 800
  380. /*
  381. * SMP init and finish on secondary CPUs
  382. */
  383. static void loongson3_init_secondary(void)
  384. {
  385. int i;
  386. uint32_t initcount;
  387. unsigned int cpu = smp_processor_id();
  388. unsigned int imask = STATUSF_IP7 | STATUSF_IP6 |
  389. STATUSF_IP3 | STATUSF_IP2;
  390. /* Set interrupt mask, but don't enable */
  391. change_c0_status(ST0_IM, imask);
  392. ipi_write_enable(cpu);
  393. per_cpu(cpu_state, cpu) = CPU_ONLINE;
  394. cpu_set_core(&cpu_data[cpu],
  395. cpu_logical_map(cpu) % loongson_sysconf.cores_per_package);
  396. cpu_data[cpu].package =
  397. cpu_logical_map(cpu) / loongson_sysconf.cores_per_package;
  398. i = 0;
  399. core0_c0count[cpu] = 0;
  400. loongson3_send_ipi_single(0, SMP_ASK_C0COUNT);
  401. while (!core0_c0count[cpu]) {
  402. i++;
  403. cpu_relax();
  404. }
  405. if (i > MAX_LOOPS)
  406. i = MAX_LOOPS;
  407. if (cpu_data[cpu].package)
  408. initcount = core0_c0count[cpu] + i;
  409. else /* Local access is faster for loops */
  410. initcount = core0_c0count[cpu] + i/2;
  411. write_c0_count(initcount);
  412. }
  413. static void loongson3_smp_finish(void)
  414. {
  415. int cpu = smp_processor_id();
  416. write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ);
  417. local_irq_enable();
  418. ipi_clear_buf(cpu);
  419. pr_info("CPU#%d finished, CP0_ST=%x\n",
  420. smp_processor_id(), read_c0_status());
  421. }
  422. static void __init loongson3_smp_setup(void)
  423. {
  424. int i = 0, num = 0; /* i: physical id, num: logical id */
  425. init_cpu_possible(cpu_none_mask);
  426. /* For unified kernel, NR_CPUS is the maximum possible value,
  427. * loongson_sysconf.nr_cpus is the really present value
  428. */
  429. while (i < loongson_sysconf.nr_cpus) {
  430. if (loongson_sysconf.reserved_cpus_mask & (1<<i)) {
  431. /* Reserved physical CPU cores */
  432. __cpu_number_map[i] = -1;
  433. } else {
  434. __cpu_number_map[i] = num;
  435. __cpu_logical_map[num] = i;
  436. set_cpu_possible(num, true);
  437. /* Loongson processors are always grouped by 4 */
  438. cpu_set_cluster(&cpu_data[num], i / 4);
  439. num++;
  440. }
  441. i++;
  442. }
  443. pr_info("Detected %i available CPU(s)\n", num);
  444. while (num < loongson_sysconf.nr_cpus) {
  445. __cpu_logical_map[num] = -1;
  446. num++;
  447. }
  448. csr_ipi_probe();
  449. ipi_set0_regs_init();
  450. ipi_clear0_regs_init();
  451. ipi_status0_regs_init();
  452. ipi_en0_regs_init();
  453. ipi_mailbox_buf_init();
  454. ipi_write_enable(0);
  455. cpu_set_core(&cpu_data[0],
  456. cpu_logical_map(0) % loongson_sysconf.cores_per_package);
  457. cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package;
  458. }
  459. static void __init loongson3_prepare_cpus(unsigned int max_cpus)
  460. {
  461. if (request_irq(LS_IPI_IRQ, loongson3_ipi_interrupt,
  462. IRQF_PERCPU | IRQF_NO_SUSPEND, "SMP_IPI", NULL))
  463. pr_err("Failed to request IPI IRQ\n");
  464. init_cpu_present(cpu_possible_mask);
  465. per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
  466. }
  467. /*
  468. * Setup the PC, SP, and GP of a secondary processor and start it runing!
  469. */
  470. static int loongson3_boot_secondary(int cpu, struct task_struct *idle)
  471. {
  472. pr_info("Booting CPU#%d...\n", cpu);
  473. ipi_write_buf(cpu, idle);
  474. return 0;
  475. }
  476. #ifdef CONFIG_HOTPLUG_CPU
  477. static int loongson3_cpu_disable(void)
  478. {
  479. unsigned long flags;
  480. unsigned int cpu = smp_processor_id();
  481. set_cpu_online(cpu, false);
  482. calculate_cpu_foreign_map();
  483. local_irq_save(flags);
  484. clear_c0_status(ST0_IM);
  485. local_irq_restore(flags);
  486. local_flush_tlb_all();
  487. return 0;
  488. }
  489. static void loongson3_cpu_die(unsigned int cpu)
  490. {
  491. while (per_cpu(cpu_state, cpu) != CPU_DEAD)
  492. cpu_relax();
  493. mb();
  494. }
  495. /* To shutdown a core in Loongson 3, the target core should go to CKSEG1 and
  496. * flush all L1 entries at first. Then, another core (usually Core 0) can
  497. * safely disable the clock of the target core. loongson3_play_dead() is
  498. * called via CKSEG1 (uncached and unmmaped)
  499. */
  500. static void loongson3_type1_play_dead(int *state_addr)
  501. {
  502. register int val;
  503. register long cpuid, core, node, count;
  504. register void *addr, *base, *initfunc;
  505. __asm__ __volatile__(
  506. " .set push \n"
  507. " .set noreorder \n"
  508. " li %[addr], 0x80000000 \n" /* KSEG0 */
  509. "1: cache 0, 0(%[addr]) \n" /* flush L1 ICache */
  510. " cache 0, 1(%[addr]) \n"
  511. " cache 0, 2(%[addr]) \n"
  512. " cache 0, 3(%[addr]) \n"
  513. " cache 1, 0(%[addr]) \n" /* flush L1 DCache */
  514. " cache 1, 1(%[addr]) \n"
  515. " cache 1, 2(%[addr]) \n"
  516. " cache 1, 3(%[addr]) \n"
  517. " addiu %[sets], %[sets], -1 \n"
  518. " bnez %[sets], 1b \n"
  519. " addiu %[addr], %[addr], 0x20 \n"
  520. " li %[val], 0x7 \n" /* *state_addr = CPU_DEAD; */
  521. " sw %[val], (%[state_addr]) \n"
  522. " sync \n"
  523. " cache 21, (%[state_addr]) \n" /* flush entry of *state_addr */
  524. " .set pop \n"
  525. : [addr] "=&r" (addr), [val] "=&r" (val)
  526. : [state_addr] "r" (state_addr),
  527. [sets] "r" (cpu_data[smp_processor_id()].dcache.sets));
  528. __asm__ __volatile__(
  529. " .set push \n"
  530. " .set noreorder \n"
  531. " .set mips64 \n"
  532. " mfc0 %[cpuid], $15, 1 \n"
  533. " andi %[cpuid], 0x3ff \n"
  534. " dli %[base], 0x900000003ff01000 \n"
  535. " andi %[core], %[cpuid], 0x3 \n"
  536. " sll %[core], 8 \n" /* get core id */
  537. " or %[base], %[base], %[core] \n"
  538. " andi %[node], %[cpuid], 0xc \n"
  539. " dsll %[node], 42 \n" /* get node id */
  540. " or %[base], %[base], %[node] \n"
  541. "1: li %[count], 0x100 \n" /* wait for init loop */
  542. "2: bnez %[count], 2b \n" /* limit mailbox access */
  543. " addiu %[count], -1 \n"
  544. " ld %[initfunc], 0x20(%[base]) \n" /* get PC via mailbox */
  545. " beqz %[initfunc], 1b \n"
  546. " nop \n"
  547. " ld $sp, 0x28(%[base]) \n" /* get SP via mailbox */
  548. " ld $gp, 0x30(%[base]) \n" /* get GP via mailbox */
  549. " ld $a1, 0x38(%[base]) \n"
  550. " jr %[initfunc] \n" /* jump to initial PC */
  551. " nop \n"
  552. " .set pop \n"
  553. : [core] "=&r" (core), [node] "=&r" (node),
  554. [base] "=&r" (base), [cpuid] "=&r" (cpuid),
  555. [count] "=&r" (count), [initfunc] "=&r" (initfunc)
  556. : /* No Input */
  557. : "a1");
  558. }
  559. static void loongson3_type2_play_dead(int *state_addr)
  560. {
  561. register int val;
  562. register long cpuid, core, node, count;
  563. register void *addr, *base, *initfunc;
  564. __asm__ __volatile__(
  565. " .set push \n"
  566. " .set noreorder \n"
  567. " li %[addr], 0x80000000 \n" /* KSEG0 */
  568. "1: cache 0, 0(%[addr]) \n" /* flush L1 ICache */
  569. " cache 0, 1(%[addr]) \n"
  570. " cache 0, 2(%[addr]) \n"
  571. " cache 0, 3(%[addr]) \n"
  572. " cache 1, 0(%[addr]) \n" /* flush L1 DCache */
  573. " cache 1, 1(%[addr]) \n"
  574. " cache 1, 2(%[addr]) \n"
  575. " cache 1, 3(%[addr]) \n"
  576. " addiu %[sets], %[sets], -1 \n"
  577. " bnez %[sets], 1b \n"
  578. " addiu %[addr], %[addr], 0x20 \n"
  579. " li %[val], 0x7 \n" /* *state_addr = CPU_DEAD; */
  580. " sw %[val], (%[state_addr]) \n"
  581. " sync \n"
  582. " cache 21, (%[state_addr]) \n" /* flush entry of *state_addr */
  583. " .set pop \n"
  584. : [addr] "=&r" (addr), [val] "=&r" (val)
  585. : [state_addr] "r" (state_addr),
  586. [sets] "r" (cpu_data[smp_processor_id()].dcache.sets));
  587. __asm__ __volatile__(
  588. " .set push \n"
  589. " .set noreorder \n"
  590. " .set mips64 \n"
  591. " mfc0 %[cpuid], $15, 1 \n"
  592. " andi %[cpuid], 0x3ff \n"
  593. " dli %[base], 0x900000003ff01000 \n"
  594. " andi %[core], %[cpuid], 0x3 \n"
  595. " sll %[core], 8 \n" /* get core id */
  596. " or %[base], %[base], %[core] \n"
  597. " andi %[node], %[cpuid], 0xc \n"
  598. " dsll %[node], 42 \n" /* get node id */
  599. " or %[base], %[base], %[node] \n"
  600. " dsrl %[node], 30 \n" /* 15:14 */
  601. " or %[base], %[base], %[node] \n"
  602. "1: li %[count], 0x100 \n" /* wait for init loop */
  603. "2: bnez %[count], 2b \n" /* limit mailbox access */
  604. " addiu %[count], -1 \n"
  605. " ld %[initfunc], 0x20(%[base]) \n" /* get PC via mailbox */
  606. " beqz %[initfunc], 1b \n"
  607. " nop \n"
  608. " ld $sp, 0x28(%[base]) \n" /* get SP via mailbox */
  609. " ld $gp, 0x30(%[base]) \n" /* get GP via mailbox */
  610. " ld $a1, 0x38(%[base]) \n"
  611. " jr %[initfunc] \n" /* jump to initial PC */
  612. " nop \n"
  613. " .set pop \n"
  614. : [core] "=&r" (core), [node] "=&r" (node),
  615. [base] "=&r" (base), [cpuid] "=&r" (cpuid),
  616. [count] "=&r" (count), [initfunc] "=&r" (initfunc)
  617. : /* No Input */
  618. : "a1");
  619. }
  620. static void loongson3_type3_play_dead(int *state_addr)
  621. {
  622. register int val;
  623. register long cpuid, core, node, count;
  624. register void *addr, *base, *initfunc;
  625. __asm__ __volatile__(
  626. " .set push \n"
  627. " .set noreorder \n"
  628. " li %[addr], 0x80000000 \n" /* KSEG0 */
  629. "1: cache 0, 0(%[addr]) \n" /* flush L1 ICache */
  630. " cache 0, 1(%[addr]) \n"
  631. " cache 0, 2(%[addr]) \n"
  632. " cache 0, 3(%[addr]) \n"
  633. " cache 1, 0(%[addr]) \n" /* flush L1 DCache */
  634. " cache 1, 1(%[addr]) \n"
  635. " cache 1, 2(%[addr]) \n"
  636. " cache 1, 3(%[addr]) \n"
  637. " addiu %[sets], %[sets], -1 \n"
  638. " bnez %[sets], 1b \n"
  639. " addiu %[addr], %[addr], 0x40 \n"
  640. " li %[addr], 0x80000000 \n" /* KSEG0 */
  641. "2: cache 2, 0(%[addr]) \n" /* flush L1 VCache */
  642. " cache 2, 1(%[addr]) \n"
  643. " cache 2, 2(%[addr]) \n"
  644. " cache 2, 3(%[addr]) \n"
  645. " cache 2, 4(%[addr]) \n"
  646. " cache 2, 5(%[addr]) \n"
  647. " cache 2, 6(%[addr]) \n"
  648. " cache 2, 7(%[addr]) \n"
  649. " cache 2, 8(%[addr]) \n"
  650. " cache 2, 9(%[addr]) \n"
  651. " cache 2, 10(%[addr]) \n"
  652. " cache 2, 11(%[addr]) \n"
  653. " cache 2, 12(%[addr]) \n"
  654. " cache 2, 13(%[addr]) \n"
  655. " cache 2, 14(%[addr]) \n"
  656. " cache 2, 15(%[addr]) \n"
  657. " addiu %[vsets], %[vsets], -1 \n"
  658. " bnez %[vsets], 2b \n"
  659. " addiu %[addr], %[addr], 0x40 \n"
  660. " li %[val], 0x7 \n" /* *state_addr = CPU_DEAD; */
  661. " sw %[val], (%[state_addr]) \n"
  662. " sync \n"
  663. " cache 21, (%[state_addr]) \n" /* flush entry of *state_addr */
  664. " .set pop \n"
  665. : [addr] "=&r" (addr), [val] "=&r" (val)
  666. : [state_addr] "r" (state_addr),
  667. [sets] "r" (cpu_data[smp_processor_id()].dcache.sets),
  668. [vsets] "r" (cpu_data[smp_processor_id()].vcache.sets));
  669. __asm__ __volatile__(
  670. " .set push \n"
  671. " .set noreorder \n"
  672. " .set mips64 \n"
  673. " mfc0 %[cpuid], $15, 1 \n"
  674. " andi %[cpuid], 0x3ff \n"
  675. " dli %[base], 0x900000003ff01000 \n"
  676. " andi %[core], %[cpuid], 0x3 \n"
  677. " sll %[core], 8 \n" /* get core id */
  678. " or %[base], %[base], %[core] \n"
  679. " andi %[node], %[cpuid], 0xc \n"
  680. " dsll %[node], 42 \n" /* get node id */
  681. " or %[base], %[base], %[node] \n"
  682. "1: li %[count], 0x100 \n" /* wait for init loop */
  683. "2: bnez %[count], 2b \n" /* limit mailbox access */
  684. " addiu %[count], -1 \n"
  685. " lw %[initfunc], 0x20(%[base]) \n" /* check lower 32-bit as jump indicator */
  686. " beqz %[initfunc], 1b \n"
  687. " nop \n"
  688. " ld %[initfunc], 0x20(%[base]) \n" /* get PC (whole 64-bit) via mailbox */
  689. " ld $sp, 0x28(%[base]) \n" /* get SP via mailbox */
  690. " ld $gp, 0x30(%[base]) \n" /* get GP via mailbox */
  691. " ld $a1, 0x38(%[base]) \n"
  692. " jr %[initfunc] \n" /* jump to initial PC */
  693. " nop \n"
  694. " .set pop \n"
  695. : [core] "=&r" (core), [node] "=&r" (node),
  696. [base] "=&r" (base), [cpuid] "=&r" (cpuid),
  697. [count] "=&r" (count), [initfunc] "=&r" (initfunc)
  698. : /* No Input */
  699. : "a1");
  700. }
  701. void play_dead(void)
  702. {
  703. int prid_imp, prid_rev, *state_addr;
  704. unsigned int cpu = smp_processor_id();
  705. void (*play_dead_at_ckseg1)(int *);
  706. idle_task_exit();
  707. prid_imp = read_c0_prid() & PRID_IMP_MASK;
  708. prid_rev = read_c0_prid() & PRID_REV_MASK;
  709. if (prid_imp == PRID_IMP_LOONGSON_64G) {
  710. play_dead_at_ckseg1 =
  711. (void *)CKSEG1ADDR((unsigned long)loongson3_type3_play_dead);
  712. goto out;
  713. }
  714. switch (prid_rev) {
  715. case PRID_REV_LOONGSON3A_R1:
  716. default:
  717. play_dead_at_ckseg1 =
  718. (void *)CKSEG1ADDR((unsigned long)loongson3_type1_play_dead);
  719. break;
  720. case PRID_REV_LOONGSON3B_R1:
  721. case PRID_REV_LOONGSON3B_R2:
  722. play_dead_at_ckseg1 =
  723. (void *)CKSEG1ADDR((unsigned long)loongson3_type2_play_dead);
  724. break;
  725. case PRID_REV_LOONGSON3A_R2_0:
  726. case PRID_REV_LOONGSON3A_R2_1:
  727. case PRID_REV_LOONGSON3A_R3_0:
  728. case PRID_REV_LOONGSON3A_R3_1:
  729. play_dead_at_ckseg1 =
  730. (void *)CKSEG1ADDR((unsigned long)loongson3_type3_play_dead);
  731. break;
  732. }
  733. out:
  734. state_addr = &per_cpu(cpu_state, cpu);
  735. mb();
  736. play_dead_at_ckseg1(state_addr);
  737. }
  738. static int loongson3_disable_clock(unsigned int cpu)
  739. {
  740. uint64_t core_id = cpu_core(&cpu_data[cpu]);
  741. uint64_t package_id = cpu_data[cpu].package;
  742. if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
  743. LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id));
  744. } else {
  745. if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG))
  746. LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3));
  747. }
  748. return 0;
  749. }
  750. static int loongson3_enable_clock(unsigned int cpu)
  751. {
  752. uint64_t core_id = cpu_core(&cpu_data[cpu]);
  753. uint64_t package_id = cpu_data[cpu].package;
  754. if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
  755. LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id);
  756. } else {
  757. if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG))
  758. LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3);
  759. }
  760. return 0;
  761. }
  762. static int register_loongson3_notifier(void)
  763. {
  764. return cpuhp_setup_state_nocalls(CPUHP_MIPS_SOC_PREPARE,
  765. "mips/loongson:prepare",
  766. loongson3_enable_clock,
  767. loongson3_disable_clock);
  768. }
  769. early_initcall(register_loongson3_notifier);
  770. #endif
  771. const struct plat_smp_ops loongson3_smp_ops = {
  772. .send_ipi_single = loongson3_send_ipi_single,
  773. .send_ipi_mask = loongson3_send_ipi_mask,
  774. .init_secondary = loongson3_init_secondary,
  775. .smp_finish = loongson3_smp_finish,
  776. .boot_secondary = loongson3_boot_secondary,
  777. .smp_setup = loongson3_smp_setup,
  778. .prepare_cpus = loongson3_prepare_cpus,
  779. #ifdef CONFIG_HOTPLUG_CPU
  780. .cpu_disable = loongson3_cpu_disable,
  781. .cpu_die = loongson3_cpu_die,
  782. #endif
  783. #ifdef CONFIG_KEXEC
  784. .kexec_nonboot_cpu = kexec_nonboot_cpu_jump,
  785. #endif
  786. };