1 From 12594762fcbec024cb424c9b77efb28402651667 Mon Sep 17 00:00:00 2001
2 From: Jonas Gorski <jogo@openwrt.org>
3 Date: Thu, 27 Jun 2013 21:33:56 +0200
4 Subject: [PATCH 04/10] MIPS: bmips: change compile time checks to runtime
7 Allow building for all bmips cpus at the same time by changing ifdefs
8 to checks for the cpu type, or adding appropriate checks to the
11 Signed-off-by: Jonas Gorski <jogo@openwrt.org>
13 arch/mips/kernel/bmips_vec.S | 55 +++++++---
14 arch/mips/kernel/smp-bmips.c | 241 ++++++++++++++++++++++--------------------
15 2 files changed, 172 insertions(+), 124 deletions(-)
17 --- a/arch/mips/kernel/bmips_vec.S
18 +++ b/arch/mips/kernel/bmips_vec.S
21 #include <asm/asmmacro.h>
22 #include <asm/cacheops.h>
24 #include <asm/regdef.h>
25 #include <asm/mipsregs.h>
26 #include <asm/stackframe.h>
27 @@ -89,12 +90,18 @@ NESTED(bmips_reset_nmi_vec, PT_SIZE, sp)
28 beqz k0, bmips_smp_entry
30 #if defined(CONFIG_CPU_BMIPS5000)
32 + li k1, PRID_IMP_BMIPS5000
36 /* if we're not on core 0, this must be the SMP boot signal */
40 bnez k0, bmips_smp_entry
43 +#endif /* CONFIG_CPU_BMIPS5000 */
44 #endif /* CONFIG_SMP */
46 /* nope, it's just a regular NMI */
47 @@ -137,7 +144,12 @@ bmips_smp_entry:
53 #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
54 + li k1, PRID_IMP_BMIPS43XX
57 /* initialize CPU1's local I-cache */
60 @@ -148,14 +160,21 @@ bmips_smp_entry:
61 1: cache Index_Store_Tag_I, 0(k0)
64 -#elif defined(CONFIG_CPU_BMIPS5000)
68 +#endif /* CONFIG_CPU_BMIPS4350 || CONFIG_CPU_BMIPS4380 */
69 +#if defined(CONFIG_CPU_BMIPS5000)
70 /* set exception vector base */
71 + li k1, PRID_IMP_BMIPS5000
80 +#endif /* CONFIG_CPU_BMIPS5000 */
82 /* jump back to kseg0 in case we need to remap the kseg1 area */
85 @@ -221,8 +240,18 @@ END(bmips_smp_int_vec)
86 LEAF(bmips_enable_xks01)
88 #if defined(CONFIG_XKS01)
92 #if defined(CONFIG_CPU_BMIPS4380)
93 + li t1, PRID_IMP_BMIPS43XX
97 + addiu t1, t0, -PRID_REV_BMIPS4380_HI
99 + addiu t0, -PRID_REV_BMIPS4380_LO
104 li t2, (1 << 12) | (1 << 9)
105 @@ -231,7 +260,13 @@ LEAF(bmips_enable_xks01)
109 -#elif defined(CONFIG_CPU_BMIPS5000)
112 +#endif /* CONFIG_CPU_BMIPS4380 */
113 +#if defined(CONFIG_CPU_BMIPS5000)
114 + li t1, PRID_IMP_BMIPS5000
119 li t2, (1 << 8) | (1 << 5)
120 @@ -240,12 +275,8 @@ LEAF(bmips_enable_xks01)
126 -#error Missing XKS01 setup
130 +#endif /* CONFIG_CPU_BMIPS5000 */
132 #endif /* defined(CONFIG_XKS01) */
135 --- a/arch/mips/kernel/smp-bmips.c
136 +++ b/arch/mips/kernel/smp-bmips.c
137 @@ -49,8 +49,11 @@ cpumask_t bmips_booted_mask;
138 unsigned long bmips_smp_boot_sp;
139 unsigned long bmips_smp_boot_gp;
141 +static void bmips43xx_send_ipi_single(int cpu, unsigned int action);
142 +static void bmips5000_send_ipi_single(int cpu, unsigned int action);
143 static void bmips_send_ipi_single(int cpu, unsigned int action);
144 -static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id);
145 +static irqreturn_t bmips43xx_ipi_interrupt(int irq, void *dev_id);
146 +static irqreturn_t bmips5000_ipi_interrupt(int irq, void *dev_id);
148 /* SW interrupts 0,1 are used for interprocessor signaling */
149 #define IPI0_IRQ (MIPS_CPU_IRQ_BASE + 0)
150 @@ -65,48 +68,49 @@ static void __init bmips_smp_setup(void)
152 int i, cpu = 1, boot_cpu = 0;
154 -#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
155 - /* arbitration priority */
156 - clear_c0_brcm_cmt_ctrl(0x30);
158 - /* NBK and weak order flags */
159 - set_c0_brcm_config_0(0x30000);
161 - /* Find out if we are running on TP0 or TP1 */
162 - boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
165 - * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other thread
166 - * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
167 - * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
169 - * If booting from TP1, leave the existing CMT interrupt routing
170 - * such that TP0 responds to SW1 and TP1 responds to SW0.
173 - change_c0_brcm_cmt_intr(0xf8018000,
174 + if (cpu_is_bmips4350() || cpu_is_bmips4380()) {
175 + /* arbitration priority */
176 + clear_c0_brcm_cmt_ctrl(0x30);
178 + /* NBK and weak order flags */
179 + set_c0_brcm_config_0(0x30000);
181 + /* Find out if we are running on TP0 or TP1 */
182 + boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
185 + * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other
187 + * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
188 + * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
190 + * If booting from TP1, leave the existing CMT interrupt routing
191 + * such that TP0 responds to SW1 and TP1 responds to SW0.
194 + change_c0_brcm_cmt_intr(0xf8018000,
195 (0x02 << 27) | (0x03 << 15));
197 - change_c0_brcm_cmt_intr(0xf8018000, (0x1d << 27));
199 - /* single core, 2 threads (2 pipelines) */
201 -#elif defined(CONFIG_CPU_BMIPS5000)
202 - /* enable raceless SW interrupts */
203 - set_c0_brcm_config(0x03 << 22);
205 - /* route HW interrupt 0 to CPU0, HW interrupt 1 to CPU1 */
206 - change_c0_brcm_mode(0x1f << 27, 0x02 << 27);
208 + change_c0_brcm_cmt_intr(0xf8018000, (0x1d << 27));
210 - /* N cores, 2 threads per core */
211 - max_cpus = (((read_c0_brcm_config() >> 6) & 0x03) + 1) << 1;
213 - /* clear any pending SW interrupts */
214 - for (i = 0; i < max_cpus; i++) {
215 - write_c0_brcm_action(ACTION_CLR_IPI(i, 0));
216 - write_c0_brcm_action(ACTION_CLR_IPI(i, 1));
217 + /* single core, 2 threads (2 pipelines) */
219 + } else if (cpu_is_bmips5000()) {
220 + /* enable raceless SW interrupts */
221 + set_c0_brcm_config(0x03 << 22);
223 + /* route HW interrupt 0 to CPU0, HW interrupt 1 to CPU1 */
224 + change_c0_brcm_mode(0x1f << 27, 0x02 << 27);
226 + /* N cores, 2 threads per core */
227 + max_cpus = (((read_c0_brcm_config() >> 6) & 0x03) + 1) << 1;
229 + /* clear any pending SW interrupts */
230 + for (i = 0; i < max_cpus; i++) {
231 + write_c0_brcm_action(ACTION_CLR_IPI(i, 0));
232 + write_c0_brcm_action(ACTION_CLR_IPI(i, 1));
237 if (!bmips_smp_enabled)
239 @@ -134,6 +138,15 @@ static void __init bmips_smp_setup(void)
241 static void bmips_prepare_cpus(unsigned int max_cpus)
243 + irqreturn_t (*bmips_ipi_interrupt)(int irq, void *dev_id);
245 + if (cpu_is_bmips4350() || cpu_is_bmips4380())
246 + bmips_ipi_interrupt = bmips43xx_ipi_interrupt;
247 + else if (cpu_is_bmips5000())
248 + bmips_ipi_interrupt = bmips5000_ipi_interrupt;
252 if (request_irq(IPI0_IRQ, bmips_ipi_interrupt, IRQF_PERCPU,
254 panic("Can't request IPI0 interrupt\n");
255 @@ -168,26 +181,26 @@ static void bmips_boot_secondary(int cpu
257 pr_info("SMP: Booting CPU%d...\n", cpu);
259 - if (cpumask_test_cpu(cpu, &bmips_booted_mask))
260 + if (cpumask_test_cpu(cpu, &bmips_booted_mask)) {
261 bmips_send_ipi_single(cpu, 0);
263 -#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
264 - /* Reset slave TP1 if booting from TP0 */
265 - if (cpu_logical_map(cpu) == 0)
266 - set_c0_brcm_cmt_ctrl(0x01);
267 -#elif defined(CONFIG_CPU_BMIPS5000)
269 - write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
272 - * core N thread 0 was already booted; just
273 - * pulse the NMI line
275 - bmips_write_zscm_reg(0x210, 0xc0000000);
277 - bmips_write_zscm_reg(0x210, 0x00);
279 + if (cpu_is_bmips4350() || cpu_is_bmips4380()) {
280 + /* Reset slave TP1 if booting from TP0 */
281 + if (cpu_logical_map(cpu) == 0)
282 + set_c0_brcm_cmt_ctrl(0x01);
283 + } else if (cpu_is_bmips5000()) {
285 + write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
288 + * core N thread 0 was already booted; just
289 + * pulse the NMI line
291 + bmips_write_zscm_reg(0x210, 0xc0000000);
293 + bmips_write_zscm_reg(0x210, 0x00);
297 cpumask_set_cpu(cpu, &bmips_booted_mask);
300 @@ -199,20 +212,21 @@ static void bmips_init_secondary(void)
302 /* move NMI vector to kseg0, in case XKS01 is enabled */
304 -#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
305 - void __iomem *cbr = BMIPS_GET_CBR();
306 - unsigned long old_vec;
308 - old_vec = __raw_readl(cbr + BMIPS_RELO_VECTOR_CONTROL_1);
309 - __raw_writel(old_vec & ~0x20000000, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
311 - clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
312 -#elif defined(CONFIG_CPU_BMIPS5000)
313 - write_c0_brcm_bootvec(read_c0_brcm_bootvec() &
314 - (smp_processor_id() & 0x01 ? ~0x20000000 : ~0x2000));
315 + if (cpu_is_bmips4350() || cpu_is_bmips4380()) {
316 + void __iomem *cbr = BMIPS_GET_CBR();
317 + unsigned long old_vec;
319 + old_vec = __raw_readl(cbr + BMIPS_RELO_VECTOR_CONTROL_1);
320 + __raw_writel(old_vec & ~0x20000000,
321 + cbr + BMIPS_RELO_VECTOR_CONTROL_1);
323 + clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
324 + } else if (cpu_is_bmips5000()) {
325 + write_c0_brcm_bootvec(read_c0_brcm_bootvec() &
326 + (smp_processor_id() & 0x01 ? ~0x20000000 : ~0x2000));
328 - write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
330 + write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
335 @@ -237,8 +251,6 @@ static void bmips_cpus_done(void)
339 -#if defined(CONFIG_CPU_BMIPS5000)
342 * BMIPS5000 raceless IPIs
344 @@ -247,12 +259,12 @@ static void bmips_cpus_done(void)
345 * IPI1 is used for SMP_CALL_FUNCTION
348 -static void bmips_send_ipi_single(int cpu, unsigned int action)
349 +static void bmips5000_send_ipi_single(int cpu, unsigned int action)
351 write_c0_brcm_action(ACTION_SET_IPI(cpu, action == SMP_CALL_FUNCTION));
354 -static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id)
355 +static irqreturn_t bmips5000_ipi_interrupt(int irq, void *dev_id)
357 int action = irq - IPI0_IRQ;
359 @@ -266,8 +278,6 @@ static irqreturn_t bmips_ipi_interrupt(i
366 * BMIPS43xx racey IPIs
368 @@ -281,7 +291,7 @@ static irqreturn_t bmips_ipi_interrupt(i
369 static DEFINE_SPINLOCK(ipi_lock);
370 static DEFINE_PER_CPU(int, ipi_action_mask);
372 -static void bmips_send_ipi_single(int cpu, unsigned int action)
373 +static void bmips43xx_send_ipi_single(int cpu, unsigned int action)
377 @@ -292,7 +302,7 @@ static void bmips_send_ipi_single(int cp
378 spin_unlock_irqrestore(&ipi_lock, flags);
381 -static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id)
382 +static irqreturn_t bmips43xx_ipi_interrupt(int irq, void *dev_id)
385 int action, cpu = irq - IPI0_IRQ;
386 @@ -311,7 +321,13 @@ static irqreturn_t bmips_ipi_interrupt(i
390 -#endif /* BMIPS type */
391 +static void bmips_send_ipi_single(int cpu, unsigned int action)
393 + if (cpu_is_bmips4350() || cpu_is_bmips4380())
394 + bmips43xx_send_ipi_single(cpu, action);
395 + else if (cpu_is_bmips5000())
396 + bmips5000_send_ipi_single(cpu, action);
399 static void bmips_send_ipi_mask(const struct cpumask *mask,
401 @@ -421,43 +437,44 @@ void __cpuinit bmips_ebase_setup(void)
403 BUG_ON(ebase != CKSEG0);
405 -#if defined(CONFIG_CPU_BMIPS4350)
407 - * BMIPS4350 cannot relocate the normal vectors, but it
408 - * can relocate the BEV=1 vectors. So CPU1 starts up at
409 - * the relocated BEV=1, IV=0 general exception vector @
412 - * set_uncached_handler() is used here because:
413 - * - CPU1 will run this from uncached space
414 - * - None of the cacheflush functions are set up yet
416 - set_uncached_handler(BMIPS_WARM_RESTART_VEC - CKSEG0,
417 - &bmips_smp_int_vec, 0x80);
420 -#elif defined(CONFIG_CPU_BMIPS4380)
422 - * 0x8000_0000: reset/NMI (initially in kseg1)
423 - * 0x8000_0400: normal vectors
425 - new_ebase = 0x80000400;
426 - cbr = BMIPS_GET_CBR();
427 - __raw_writel(0x80080800, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
428 - __raw_writel(0xa0080800, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
429 -#elif defined(CONFIG_CPU_BMIPS5000)
431 - * 0x8000_0000: reset/NMI (initially in kseg1)
432 - * 0x8000_1000: normal vectors
434 - new_ebase = 0x80001000;
435 - write_c0_brcm_bootvec(0xa0088008);
436 - write_c0_ebase(new_ebase);
438 - bmips_write_zscm_reg(0xa0, 0xa008a008);
442 + if (cpu_is_bmips4350()) {
444 + * BMIPS4350 cannot relocate the normal vectors, but it
445 + * can relocate the BEV=1 vectors. So CPU1 starts up at
446 + * the relocated BEV=1, IV=0 general exception vector @
449 + * set_uncached_handler() is used here because:
450 + * - CPU1 will run this from uncached space
451 + * - None of the cacheflush functions are set up yet
453 + set_uncached_handler(BMIPS_WARM_RESTART_VEC - CKSEG0,
454 + &bmips_smp_int_vec, 0x80);
457 + } else if (cpu_is_bmips4380()) {
459 + * 0x8000_0000: reset/NMI (initially in kseg1)
460 + * 0x8000_0400: normal vectors
462 + new_ebase = 0x80000400;
463 + cbr = BMIPS_GET_CBR();
464 + __raw_writel(0x80080800, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
465 + __raw_writel(0xa0080800, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
466 + } else if (cpu_is_bmips5000()) {
468 + * 0x8000_0000: reset/NMI (initially in kseg1)
469 + * 0x8000_1000: normal vectors
471 + new_ebase = 0x80001000;
472 + write_c0_brcm_bootvec(0xa0088008);
473 + write_c0_ebase(new_ebase);
475 + bmips_write_zscm_reg(0xa0, 0xa008a008);
480 board_nmi_handler_setup = &bmips_nmi_handler_setup;