brcm63xx: update bmips patches with upstream submission
[openwrt.git] / target / linux / brcm63xx / patches-3.10 / 062-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 @@ -93,12 +94,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 @@ -141,7 +148,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 @@ -152,14 +164,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 @@ -225,8 +244,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 @@ -235,7 +264,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 @@ -244,12 +279,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\n");
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 __cpuinit 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  }