2f56f15e767d36a2a000e323c7da1eefbea920e7
[openwrt/svn-archive/archive.git] / target / linux / brcm63xx / patches-3.13 / 009-MIPS-BMIPS-change-compile-time-checks-to-runtime-che.patch
1 From 7d790bd6cab314462a29ba194e243b8b1d529524 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 V2 03/13] MIPS: BMIPS: change compile time checks to runtime
5 checks
6
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
9 assembly.
10
11 Since BMIPS43XX and BMIPS5000 require different IPI implementations,
12 split the SMP ops into one for each, so the runtime overhead is only
13 at registration time for them.
14
15 Signed-off-by: Jonas Gorski <jogo@openwrt.org>
16 ---
17 V1 -> V2:
18 * use switch (cpu_type()) instead of if () else if () ...
19 * split the smp ops into bmips43xx and bmips5000
20
21 arch/mips/bcm63xx/prom.c | 2 +-
22 arch/mips/include/asm/bmips.h | 3 +-
23 arch/mips/kernel/bmips_vec.S | 55 ++++++--
24 arch/mips/kernel/smp-bmips.c | 312 +++++++++++++++++++++++++-----------------
25 4 files changed, 235 insertions(+), 137 deletions(-)
26
27 --- a/arch/mips/bcm63xx/prom.c
28 +++ b/arch/mips/bcm63xx/prom.c
29 @@ -61,7 +61,7 @@ void __init prom_init(void)
30
31 if (IS_ENABLED(CONFIG_CPU_BMIPS4350) && IS_ENABLED(CONFIG_SMP)) {
32 /* set up SMP */
33 - register_smp_ops(&bmips_smp_ops);
34 + register_smp_ops(&bmips43xx_smp_ops);
35
36 /*
37 * BCM6328 might not have its second CPU enabled, while BCM3368
38 --- a/arch/mips/include/asm/bmips.h
39 +++ b/arch/mips/include/asm/bmips.h
40 @@ -47,7 +47,8 @@
41 #include <linux/cpumask.h>
42 #include <asm/r4kcache.h>
43
44 -extern struct plat_smp_ops bmips_smp_ops;
45 +extern struct plat_smp_ops bmips43xx_smp_ops;
46 +extern struct plat_smp_ops bmips5000_smp_ops;
47 extern char bmips_reset_nmi_vec;
48 extern char bmips_reset_nmi_vec_end;
49 extern char bmips_smp_movevec;
50 --- a/arch/mips/kernel/bmips_vec.S
51 +++ b/arch/mips/kernel/bmips_vec.S
52 @@ -13,6 +13,7 @@
53 #include <asm/asm.h>
54 #include <asm/asmmacro.h>
55 #include <asm/cacheops.h>
56 +#include <asm/cpu.h>
57 #include <asm/regdef.h>
58 #include <asm/mipsregs.h>
59 #include <asm/stackframe.h>
60 @@ -91,12 +92,18 @@ NESTED(bmips_reset_nmi_vec, PT_SIZE, sp)
61 beqz k0, bmips_smp_entry
62
63 #if defined(CONFIG_CPU_BMIPS5000)
64 + mfc0 k0, CP0_PRID
65 + li k1, PRID_IMP_BMIPS5000
66 + andi k0, 0xff00
67 + bne k0, k1, 1f
68 +
69 /* if we're not on core 0, this must be the SMP boot signal */
70 li k1, (3 << 25)
71 mfc0 k0, $22
72 and k0, k1
73 bnez k0, bmips_smp_entry
74 -#endif
75 +1:
76 +#endif /* CONFIG_CPU_BMIPS5000 */
77 #endif /* CONFIG_SMP */
78
79 /* nope, it's just a regular NMI */
80 @@ -139,7 +146,12 @@ bmips_smp_entry:
81 xori k0, 0x04
82 mtc0 k0, CP0_CONFIG
83
84 + mfc0 k0, CP0_PRID
85 + andi k0, 0xff00
86 #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
87 + li k1, PRID_IMP_BMIPS43XX
88 + bne k0, k1, 2f
89 +
90 /* initialize CPU1's local I-cache */
91 li k0, 0x80000000
92 li k1, 0x80010000
93 @@ -150,14 +162,21 @@ bmips_smp_entry:
94 1: cache Index_Store_Tag_I, 0(k0)
95 addiu k0, 16
96 bne k0, k1, 1b
97 -#elif defined(CONFIG_CPU_BMIPS5000)
98 +
99 + b 3f
100 +2:
101 +#endif /* CONFIG_CPU_BMIPS4350 || CONFIG_CPU_BMIPS4380 */
102 +#if defined(CONFIG_CPU_BMIPS5000)
103 /* set exception vector base */
104 + li k1, PRID_IMP_BMIPS5000
105 + bne k0, k1, 3f
106 +
107 la k0, ebase
108 lw k0, 0(k0)
109 mtc0 k0, $15, 1
110 BARRIER
111 -#endif
112 -
113 +#endif /* CONFIG_CPU_BMIPS5000 */
114 +3:
115 /* jump back to kseg0 in case we need to remap the kseg1 area */
116 la k0, 1f
117 jr k0
118 @@ -221,8 +240,18 @@ END(bmips_smp_int_vec)
119 LEAF(bmips_enable_xks01)
120
121 #if defined(CONFIG_XKS01)
122 -
123 + mfc0 t0, CP0_PRID
124 + andi t2, t0, 0xff00
125 #if defined(CONFIG_CPU_BMIPS4380)
126 + li t1, PRID_IMP_BMIPS43XX
127 + bne t2, t1, 1f
128 +
129 + andi t0, 0xff
130 + addiu t1, t0, -PRID_REV_BMIPS4380_HI
131 + bgtz t1, 2f
132 + addiu t0, -PRID_REV_BMIPS4380_LO
133 + bltz t0, 2f
134 +
135 mfc0 t0, $22, 3
136 li t1, 0x1ff0
137 li t2, (1 << 12) | (1 << 9)
138 @@ -231,7 +260,13 @@ LEAF(bmips_enable_xks01)
139 or t0, t2
140 mtc0 t0, $22, 3
141 BARRIER
142 -#elif defined(CONFIG_CPU_BMIPS5000)
143 + b 2f
144 +1:
145 +#endif /* CONFIG_CPU_BMIPS4380 */
146 +#if defined(CONFIG_CPU_BMIPS5000)
147 + li t1, PRID_IMP_BMIPS5000
148 + bne t2, t1, 2f
149 +
150 mfc0 t0, $22, 5
151 li t1, 0x01ff
152 li t2, (1 << 8) | (1 << 5)
153 @@ -240,12 +275,8 @@ LEAF(bmips_enable_xks01)
154 or t0, t2
155 mtc0 t0, $22, 5
156 BARRIER
157 -#else
158 -
159 -#error Missing XKS01 setup
160 -
161 -#endif
162 -
163 +#endif /* CONFIG_CPU_BMIPS5000 */
164 +2:
165 #endif /* defined(CONFIG_XKS01) */
166
167 jr ra
168 --- a/arch/mips/kernel/smp-bmips.c
169 +++ b/arch/mips/kernel/smp-bmips.c
170 @@ -49,8 +49,10 @@ cpumask_t bmips_booted_mask;
171 unsigned long bmips_smp_boot_sp;
172 unsigned long bmips_smp_boot_gp;
173
174 -static void bmips_send_ipi_single(int cpu, unsigned int action);
175 -static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id);
176 +static void bmips43xx_send_ipi_single(int cpu, unsigned int action);
177 +static void bmips5000_send_ipi_single(int cpu, unsigned int action);
178 +static irqreturn_t bmips43xx_ipi_interrupt(int irq, void *dev_id);
179 +static irqreturn_t bmips5000_ipi_interrupt(int irq, void *dev_id);
180
181 /* SW interrupts 0,1 are used for interprocessor signaling */
182 #define IPI0_IRQ (MIPS_CPU_IRQ_BASE + 0)
183 @@ -64,49 +66,58 @@ static irqreturn_t bmips_ipi_interrupt(i
184 static void __init bmips_smp_setup(void)
185 {
186 int i, cpu = 1, boot_cpu = 0;
187 -
188 -#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
189 int cpu_hw_intr;
190
191 - /* arbitration priority */
192 - clear_c0_brcm_cmt_ctrl(0x30);
193 -
194 - /* NBK and weak order flags */
195 - set_c0_brcm_config_0(0x30000);
196 -
197 - /* Find out if we are running on TP0 or TP1 */
198 - boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
199 -
200 - /*
201 - * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other thread
202 - * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
203 - * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
204 - */
205 - if (boot_cpu == 0)
206 - cpu_hw_intr = 0x02;
207 - else
208 - cpu_hw_intr = 0x1d;
209 -
210 - change_c0_brcm_cmt_intr(0xf8018000, (cpu_hw_intr << 27) | (0x03 << 15));
211 -
212 - /* single core, 2 threads (2 pipelines) */
213 - max_cpus = 2;
214 -#elif defined(CONFIG_CPU_BMIPS5000)
215 - /* enable raceless SW interrupts */
216 - set_c0_brcm_config(0x03 << 22);
217 -
218 - /* route HW interrupt 0 to CPU0, HW interrupt 1 to CPU1 */
219 - change_c0_brcm_mode(0x1f << 27, 0x02 << 27);
220 -
221 - /* N cores, 2 threads per core */
222 - max_cpus = (((read_c0_brcm_config() >> 6) & 0x03) + 1) << 1;
223 + switch (current_cpu_type()) {
224 + case CPU_BMIPS4350:
225 + case CPU_BMIPS4380:
226 + /* arbitration priority */
227 + clear_c0_brcm_cmt_ctrl(0x30);
228 +
229 + /* NBK and weak order flags */
230 + set_c0_brcm_config_0(0x30000);
231 +
232 + /* Find out if we are running on TP0 or TP1 */
233 + boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
234 +
235 + /*
236 + * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other
237 + * thread
238 + * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
239 + * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
240 + */
241 + if (boot_cpu == 0)
242 + cpu_hw_intr = 0x02;
243 + else
244 + cpu_hw_intr = 0x1d;
245 +
246 + change_c0_brcm_cmt_intr(0xf8018000,
247 + (cpu_hw_intr << 27) | (0x03 << 15));
248 +
249 + /* single core, 2 threads (2 pipelines) */
250 + max_cpus = 2;
251 +
252 + break;
253 + case CPU_BMIPS5000:
254 + /* enable raceless SW interrupts */
255 + set_c0_brcm_config(0x03 << 22);
256 +
257 + /* route HW interrupt 0 to CPU0, HW interrupt 1 to CPU1 */
258 + change_c0_brcm_mode(0x1f << 27, 0x02 << 27);
259 +
260 + /* N cores, 2 threads per core */
261 + max_cpus = (((read_c0_brcm_config() >> 6) & 0x03) + 1) << 1;
262 +
263 + /* clear any pending SW interrupts */
264 + for (i = 0; i < max_cpus; i++) {
265 + write_c0_brcm_action(ACTION_CLR_IPI(i, 0));
266 + write_c0_brcm_action(ACTION_CLR_IPI(i, 1));
267 + }
268
269 - /* clear any pending SW interrupts */
270 - for (i = 0; i < max_cpus; i++) {
271 - write_c0_brcm_action(ACTION_CLR_IPI(i, 0));
272 - write_c0_brcm_action(ACTION_CLR_IPI(i, 1));
273 + break;
274 + default:
275 + max_cpus = 1;
276 }
277 -#endif
278
279 if (!bmips_smp_enabled)
280 max_cpus = 1;
281 @@ -134,6 +145,20 @@ static void __init bmips_smp_setup(void)
282 */
283 static void bmips_prepare_cpus(unsigned int max_cpus)
284 {
285 + irqreturn_t (*bmips_ipi_interrupt)(int irq, void *dev_id);
286 +
287 + switch (current_cpu_type()) {
288 + case CPU_BMIPS4350:
289 + case CPU_BMIPS4380:
290 + bmips_ipi_interrupt = bmips43xx_ipi_interrupt;
291 + break;
292 + case CPU_BMIPS5000:
293 + bmips_ipi_interrupt = bmips5000_ipi_interrupt;
294 + break;
295 + default:
296 + return;
297 + }
298 +
299 if (request_irq(IPI0_IRQ, bmips_ipi_interrupt, IRQF_PERCPU,
300 "smp_ipi0", NULL))
301 panic("Can't request IPI0 interrupt");
302 @@ -168,26 +193,39 @@ static void bmips_boot_secondary(int cpu
303
304 pr_info("SMP: Booting CPU%d...\n", cpu);
305
306 - if (cpumask_test_cpu(cpu, &bmips_booted_mask))
307 - bmips_send_ipi_single(cpu, 0);
308 + if (cpumask_test_cpu(cpu, &bmips_booted_mask)) {
309 + switch (current_cpu_type()) {
310 + case CPU_BMIPS4350:
311 + case CPU_BMIPS4380:
312 + bmips43xx_send_ipi_single(cpu, 0);
313 + break;
314 + case CPU_BMIPS5000:
315 + bmips5000_send_ipi_single(cpu, 0);
316 + break;
317 + }
318 + }
319 else {
320 -#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
321 - /* Reset slave TP1 if booting from TP0 */
322 - if (cpu_logical_map(cpu) == 1)
323 - set_c0_brcm_cmt_ctrl(0x01);
324 -#elif defined(CONFIG_CPU_BMIPS5000)
325 - if (cpu & 0x01)
326 - write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
327 - else {
328 - /*
329 - * core N thread 0 was already booted; just
330 - * pulse the NMI line
331 - */
332 - bmips_write_zscm_reg(0x210, 0xc0000000);
333 - udelay(10);
334 - bmips_write_zscm_reg(0x210, 0x00);
335 + switch (current_cpu_type()) {
336 + case CPU_BMIPS4350:
337 + case CPU_BMIPS4380:
338 + /* Reset slave TP1 if booting from TP0 */
339 + if (cpu_logical_map(cpu) == 1)
340 + set_c0_brcm_cmt_ctrl(0x01);
341 + break;
342 + case CPU_BMIPS5000:
343 + if (cpu & 0x01)
344 + write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
345 + else {
346 + /*
347 + * core N thread 0 was already booted; just
348 + * pulse the NMI line
349 + */
350 + bmips_write_zscm_reg(0x210, 0xc0000000);
351 + udelay(10);
352 + bmips_write_zscm_reg(0x210, 0x00);
353 + }
354 + break;
355 }
356 -#endif
357 cpumask_set_cpu(cpu, &bmips_booted_mask);
358 }
359 }
360 @@ -199,26 +237,32 @@ static void bmips_init_secondary(void)
361 {
362 /* move NMI vector to kseg0, in case XKS01 is enabled */
363
364 -#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
365 - void __iomem *cbr = BMIPS_GET_CBR();
366 + void __iomem *cbr;
367 unsigned long old_vec;
368 unsigned long relo_vector;
369 int boot_cpu;
370
371 - boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
372 - relo_vector = boot_cpu ? BMIPS_RELO_VECTOR_CONTROL_0 :
373 - BMIPS_RELO_VECTOR_CONTROL_1;
374 -
375 - old_vec = __raw_readl(cbr + relo_vector);
376 - __raw_writel(old_vec & ~0x20000000, cbr + relo_vector);
377 -
378 - clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
379 -#elif defined(CONFIG_CPU_BMIPS5000)
380 - write_c0_brcm_bootvec(read_c0_brcm_bootvec() &
381 - (smp_processor_id() & 0x01 ? ~0x20000000 : ~0x2000));
382 + switch (current_cpu_type()) {
383 + case CPU_BMIPS4350:
384 + case CPU_BMIPS4380:
385 + cbr = BMIPS_GET_CBR();
386 +
387 + boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
388 + relo_vector = boot_cpu ? BMIPS_RELO_VECTOR_CONTROL_0 :
389 + BMIPS_RELO_VECTOR_CONTROL_1;
390 +
391 + old_vec = __raw_readl(cbr + relo_vector);
392 + __raw_writel(old_vec & ~0x20000000, cbr + relo_vector);
393 +
394 + clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
395 + break;
396 + case CPU_BMIPS5000:
397 + write_c0_brcm_bootvec(read_c0_brcm_bootvec() &
398 + (smp_processor_id() & 0x01 ? ~0x20000000 : ~0x2000));
399
400 - write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
401 -#endif
402 + write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
403 + break;
404 + }
405 }
406
407 /*
408 @@ -243,8 +287,6 @@ static void bmips_cpus_done(void)
409 {
410 }
411
412 -#if defined(CONFIG_CPU_BMIPS5000)
413 -
414 /*
415 * BMIPS5000 raceless IPIs
416 *
417 @@ -253,12 +295,12 @@ static void bmips_cpus_done(void)
418 * IPI1 is used for SMP_CALL_FUNCTION
419 */
420
421 -static void bmips_send_ipi_single(int cpu, unsigned int action)
422 +static void bmips5000_send_ipi_single(int cpu, unsigned int action)
423 {
424 write_c0_brcm_action(ACTION_SET_IPI(cpu, action == SMP_CALL_FUNCTION));
425 }
426
427 -static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id)
428 +static irqreturn_t bmips5000_ipi_interrupt(int irq, void *dev_id)
429 {
430 int action = irq - IPI0_IRQ;
431
432 @@ -272,7 +314,14 @@ static irqreturn_t bmips_ipi_interrupt(i
433 return IRQ_HANDLED;
434 }
435
436 -#else
437 +static void bmips5000_send_ipi_mask(const struct cpumask *mask,
438 + unsigned int action)
439 +{
440 + unsigned int i;
441 +
442 + for_each_cpu(i, mask)
443 + bmips5000_send_ipi_single(i, action);
444 +}
445
446 /*
447 * BMIPS43xx racey IPIs
448 @@ -287,7 +336,7 @@ static irqreturn_t bmips_ipi_interrupt(i
449 static DEFINE_SPINLOCK(ipi_lock);
450 static DEFINE_PER_CPU(int, ipi_action_mask);
451
452 -static void bmips_send_ipi_single(int cpu, unsigned int action)
453 +static void bmips43xx_send_ipi_single(int cpu, unsigned int action)
454 {
455 unsigned long flags;
456
457 @@ -298,7 +347,7 @@ static void bmips_send_ipi_single(int cp
458 spin_unlock_irqrestore(&ipi_lock, flags);
459 }
460
461 -static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id)
462 +static irqreturn_t bmips43xx_ipi_interrupt(int irq, void *dev_id)
463 {
464 unsigned long flags;
465 int action, cpu = irq - IPI0_IRQ;
466 @@ -317,15 +366,13 @@ static irqreturn_t bmips_ipi_interrupt(i
467 return IRQ_HANDLED;
468 }
469
470 -#endif /* BMIPS type */
471 -
472 -static void bmips_send_ipi_mask(const struct cpumask *mask,
473 +static void bmips43xx_send_ipi_mask(const struct cpumask *mask,
474 unsigned int action)
475 {
476 unsigned int i;
477
478 for_each_cpu(i, mask)
479 - bmips_send_ipi_single(i, action);
480 + bmips43xx_send_ipi_single(i, action);
481 }
482
483 #ifdef CONFIG_HOTPLUG_CPU
484 @@ -381,15 +428,30 @@ void __ref play_dead(void)
485
486 #endif /* CONFIG_HOTPLUG_CPU */
487
488 -struct plat_smp_ops bmips_smp_ops = {
489 +struct plat_smp_ops bmips43xx_smp_ops = {
490 + .smp_setup = bmips_smp_setup,
491 + .prepare_cpus = bmips_prepare_cpus,
492 + .boot_secondary = bmips_boot_secondary,
493 + .smp_finish = bmips_smp_finish,
494 + .init_secondary = bmips_init_secondary,
495 + .cpus_done = bmips_cpus_done,
496 + .send_ipi_single = bmips43xx_send_ipi_single,
497 + .send_ipi_mask = bmips43xx_send_ipi_mask,
498 +#ifdef CONFIG_HOTPLUG_CPU
499 + .cpu_disable = bmips_cpu_disable,
500 + .cpu_die = bmips_cpu_die,
501 +#endif
502 +};
503 +
504 +struct plat_smp_ops bmips5000_smp_ops = {
505 .smp_setup = bmips_smp_setup,
506 .prepare_cpus = bmips_prepare_cpus,
507 .boot_secondary = bmips_boot_secondary,
508 .smp_finish = bmips_smp_finish,
509 .init_secondary = bmips_init_secondary,
510 .cpus_done = bmips_cpus_done,
511 - .send_ipi_single = bmips_send_ipi_single,
512 - .send_ipi_mask = bmips_send_ipi_mask,
513 + .send_ipi_single = bmips5000_send_ipi_single,
514 + .send_ipi_mask = bmips5000_send_ipi_mask,
515 #ifdef CONFIG_HOTPLUG_CPU
516 .cpu_disable = bmips_cpu_disable,
517 .cpu_die = bmips_cpu_die,
518 @@ -427,43 +489,47 @@ void bmips_ebase_setup(void)
519
520 BUG_ON(ebase != CKSEG0);
521
522 -#if defined(CONFIG_CPU_BMIPS4350)
523 - /*
524 - * BMIPS4350 cannot relocate the normal vectors, but it
525 - * can relocate the BEV=1 vectors. So CPU1 starts up at
526 - * the relocated BEV=1, IV=0 general exception vector @
527 - * 0xa000_0380.
528 - *
529 - * set_uncached_handler() is used here because:
530 - * - CPU1 will run this from uncached space
531 - * - None of the cacheflush functions are set up yet
532 - */
533 - set_uncached_handler(BMIPS_WARM_RESTART_VEC - CKSEG0,
534 - &bmips_smp_int_vec, 0x80);
535 - __sync();
536 - return;
537 -#elif defined(CONFIG_CPU_BMIPS4380)
538 - /*
539 - * 0x8000_0000: reset/NMI (initially in kseg1)
540 - * 0x8000_0400: normal vectors
541 - */
542 - new_ebase = 0x80000400;
543 - cbr = BMIPS_GET_CBR();
544 - __raw_writel(0x80080800, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
545 - __raw_writel(0xa0080800, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
546 -#elif defined(CONFIG_CPU_BMIPS5000)
547 - /*
548 - * 0x8000_0000: reset/NMI (initially in kseg1)
549 - * 0x8000_1000: normal vectors
550 - */
551 - new_ebase = 0x80001000;
552 - write_c0_brcm_bootvec(0xa0088008);
553 - write_c0_ebase(new_ebase);
554 - if (max_cpus > 2)
555 - bmips_write_zscm_reg(0xa0, 0xa008a008);
556 -#else
557 - return;
558 -#endif
559 + switch (current_cpu_type()) {
560 + case CPU_BMIPS4350:
561 + /*
562 + * BMIPS4350 cannot relocate the normal vectors, but it
563 + * can relocate the BEV=1 vectors. So CPU1 starts up at
564 + * the relocated BEV=1, IV=0 general exception vector @
565 + * 0xa000_0380.
566 + *
567 + * set_uncached_handler() is used here because:
568 + * - CPU1 will run this from uncached space
569 + * - None of the cacheflush functions are set up yet
570 + */
571 + set_uncached_handler(BMIPS_WARM_RESTART_VEC - CKSEG0,
572 + &bmips_smp_int_vec, 0x80);
573 + __sync();
574 + return;
575 + case CPU_BMIPS4380:
576 + /*
577 + * 0x8000_0000: reset/NMI (initially in kseg1)
578 + * 0x8000_0400: normal vectors
579 + */
580 + new_ebase = 0x80000400;
581 + cbr = BMIPS_GET_CBR();
582 + __raw_writel(0x80080800, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
583 + __raw_writel(0xa0080800, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
584 + break;
585 + case CPU_BMIPS5000:
586 + /*
587 + * 0x8000_0000: reset/NMI (initially in kseg1)
588 + * 0x8000_1000: normal vectors
589 + */
590 + new_ebase = 0x80001000;
591 + write_c0_brcm_bootvec(0xa0088008);
592 + write_c0_ebase(new_ebase);
593 + if (max_cpus > 2)
594 + bmips_write_zscm_reg(0xa0, 0xa008a008);
595 + break;
596 + default:
597 + return;
598 + }
599 +
600 board_nmi_handler_setup = &bmips_nmi_handler_setup;
601 ebase = new_ebase;
602 }