Commit 3677a283 authored by Kevin Cernekee's avatar Kevin Cernekee Committed by Ralf Baechle

MIPS: BMIPS: Explicitly configure reset vectors prior to secondary boot

The secondary CPU's reset vector needs to be set to KSEG1 for a cold
boot (release from reset), or KSEG0 for a warm restart.  On a cold boot
KSEG0 may be unavailable (BMIPS4380), and on a warm restart KSEG1 may
be unavailable (XKS01 mode on 4380 or 5000).
Signed-off-by: default avatarKevin Cernekee <cernekee@gmail.com>
Cc: f.fainelli@gmail.com
Cc: mbizon@freebox.fr
Cc: jogo@openwrt.org
Cc: jfraser@broadcom.com
Cc: linux-mips@linux-mips.org
Cc: devicetree@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/8161/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 230b6ff5
...@@ -47,6 +47,8 @@ cpumask_t bmips_booted_mask; ...@@ -47,6 +47,8 @@ cpumask_t bmips_booted_mask;
#define RESET_FROM_KSEG0 0x80080800 #define RESET_FROM_KSEG0 0x80080800
#define RESET_FROM_KSEG1 0xa0080800 #define RESET_FROM_KSEG1 0xa0080800
static void bmips_set_reset_vec(int cpu, u32 val);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* initial $sp, $gp - used by arch/mips/kernel/bmips_vec.S */ /* initial $sp, $gp - used by arch/mips/kernel/bmips_vec.S */
...@@ -198,6 +200,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) ...@@ -198,6 +200,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle)
pr_info("SMP: Booting CPU%d...\n", cpu); pr_info("SMP: Booting CPU%d...\n", cpu);
if (cpumask_test_cpu(cpu, &bmips_booted_mask)) { if (cpumask_test_cpu(cpu, &bmips_booted_mask)) {
/* kseg1 might not exist if this CPU enabled XKS01 */
bmips_set_reset_vec(cpu, RESET_FROM_KSEG0);
switch (current_cpu_type()) { switch (current_cpu_type()) {
case CPU_BMIPS4350: case CPU_BMIPS4350:
case CPU_BMIPS4380: case CPU_BMIPS4380:
...@@ -207,8 +212,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) ...@@ -207,8 +212,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle)
bmips5000_send_ipi_single(cpu, 0); bmips5000_send_ipi_single(cpu, 0);
break; break;
} }
} } else {
else { bmips_set_reset_vec(cpu, RESET_FROM_KSEG1);
switch (current_cpu_type()) { switch (current_cpu_type()) {
case CPU_BMIPS4350: case CPU_BMIPS4350:
case CPU_BMIPS4380: case CPU_BMIPS4380:
...@@ -229,31 +235,12 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) ...@@ -229,31 +235,12 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle)
*/ */
static void bmips_init_secondary(void) static void bmips_init_secondary(void)
{ {
/* move NMI vector to kseg0, in case XKS01 is enabled */
void __iomem *cbr;
unsigned long old_vec;
unsigned long relo_vector;
int boot_cpu;
switch (current_cpu_type()) { switch (current_cpu_type()) {
case CPU_BMIPS4350: case CPU_BMIPS4350:
case CPU_BMIPS4380: case CPU_BMIPS4380:
cbr = BMIPS_GET_CBR();
boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
relo_vector = boot_cpu ? BMIPS_RELO_VECTOR_CONTROL_0 :
BMIPS_RELO_VECTOR_CONTROL_1;
old_vec = __raw_readl(cbr + relo_vector);
__raw_writel(old_vec & ~0x20000000, cbr + relo_vector);
clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0); clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
break; break;
case CPU_BMIPS5000: case CPU_BMIPS5000:
write_c0_brcm_bootvec(read_c0_brcm_bootvec() &
(smp_processor_id() & 0x01 ? ~0x20000000 : ~0x2000));
write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment