smp.c 28 KB

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