bcm63xx: make smp kernels boot on older SoCs

Enhance BMIPS support so SMP kernels work on older chips.

Signed-off-by: Jonas Gorski <jogo@openwrt.org>

SVN-Revision: 37099
This commit is contained in:
Jonas Gorski 2013-06-30 13:10:00 +00:00
parent 66f8f30f47
commit e7d93889d7
21 changed files with 953 additions and 7 deletions

View File

@ -0,0 +1,67 @@
From d55975b74389b2cf1a38732062ff89303940f6e1 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Sat, 29 Jun 2013 11:46:56 +0200
Subject: [PATCH 01/10] MIPS: bmips: fix compilation for BMIPS5000
Replace the macro names in strings with actual macro invocation.
Fixes the following build error:
CC arch/mips/kernel/smp-bmips.o
{standard input}: Assembler messages:
{standard input}:951: Error: Unrecognized opcode `_ssnop'
{standard input}:952: Error: Unrecognized opcode `_ssnop'
(...)
make[6]: *** [arch/mips/kernel/smp-bmips.o] Error 1
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
arch/mips/include/asm/bmips.h | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
--- a/arch/mips/include/asm/bmips.h
+++ b/arch/mips/include/asm/bmips.h
@@ -70,15 +70,15 @@ static inline unsigned long bmips_read_z
".set noreorder\n"
"cache %1, 0(%2)\n"
"sync\n"
- "_ssnop\n"
- "_ssnop\n"
- "_ssnop\n"
- "_ssnop\n"
- "_ssnop\n"
- "_ssnop\n"
- "_ssnop\n"
+ __stringify(___ssnop) "\n"
+ __stringify(___ssnop) "\n"
+ __stringify(___ssnop) "\n"
+ __stringify(___ssnop) "\n"
+ __stringify(___ssnop) "\n"
+ __stringify(___ssnop) "\n"
+ __stringify(___ssnop) "\n"
"mfc0 %0, $28, 3\n"
- "_ssnop\n"
+ __stringify(___ssnop) "\n"
".set pop\n"
: "=&r" (ret)
: "i" (Index_Load_Tag_S), "r" (ZSCM_REG_BASE + offset)
@@ -92,13 +92,13 @@ static inline void bmips_write_zscm_reg(
".set push\n"
".set noreorder\n"
"mtc0 %0, $28, 3\n"
- "_ssnop\n"
- "_ssnop\n"
- "_ssnop\n"
+ __stringify(___ssnop) "\n"
+ __stringify(___ssnop) "\n"
+ __stringify(___ssnop) "\n"
"cache %1, 0(%2)\n"
- "_ssnop\n"
- "_ssnop\n"
- "_ssnop\n"
+ __stringify(___ssnop) "\n"
+ __stringify(___ssnop) "\n"
+ __stringify(___ssnop) "\n"
: /* no outputs */
: "r" (data),
"i" (Index_Store_Tag_S), "r" (ZSCM_REG_BASE + offset)

View File

@ -0,0 +1,31 @@
From 520f4bf75026cc60ba47946331966fb670b39cb0 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Thu, 27 Jun 2013 21:32:41 +0200
Subject: [PATCH 02/10] MIPS: allow asm/cpu.h to be included from assembly
Add guards around the enum to allow including cpu.h from assembly.
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
arch/mips/include/asm/cpu.h | 3 +++
1 file changed, 3 insertions(+)
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -225,6 +225,8 @@
#define FPIR_IMP_NONE 0x0000
+#if !defined(__ASSEMBLY__)
+
enum cpu_type_enum {
CPU_UNKNOWN,
@@ -277,6 +279,7 @@ enum cpu_type_enum {
CPU_LAST
};
+#endif /* !__ASSEMBLY */
/*
* ISA Level encodings

View File

@ -0,0 +1,36 @@
From 971b8b3d5101b3bb868e63f3eb96fe69b7110c61 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Thu, 27 Jun 2013 12:40:15 +0200
Subject: [PATCH 03/10] MIPS: bmips: add macros for testing the current bmips
CPU
Makes it easy to make code conditionally compiled for supported CPUs
without directly relying on #ifdefs.
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
arch/mips/include/asm/bmips.h | 11 +++++++++++
1 file changed, 11 insertions(+)
--- a/arch/mips/include/asm/bmips.h
+++ b/arch/mips/include/asm/bmips.h
@@ -45,8 +45,19 @@
#if !defined(__ASSEMBLY__)
#include <linux/cpumask.h>
+#include <asm/cpu-features.h>
#include <asm/r4kcache.h>
+#define cpu_is_bmips32() (current_cpu_type() == CPU_BMIPS32)
+#define cpu_is_bmips3300() (IS_ENABLED(CONFIG_CPU_BMIPS3300) && \
+ current_cpu_type() == CPU_BMIPS3300)
+#define cpu_is_bmips4350() (IS_ENABLED(CONFIG_CPU_BMIPS4350) && \
+ current_cpu_type() == CPU_BMIPS4350)
+#define cpu_is_bmips4380() (IS_ENABLED(CONFIG_CPU_BMIPS4380) && \
+ current_cpu_type() == CPU_BMIPS4380)
+#define cpu_is_bmips5000() (IS_ENABLED(CONFIG_CPU_BMIPS5000) && \
+ current_cpu_type() == CPU_BMIPS5000)
+
extern struct plat_smp_ops bmips_smp_ops;
extern char bmips_reset_nmi_vec;
extern char bmips_reset_nmi_vec_end;

View File

@ -0,0 +1,482 @@
From 12594762fcbec024cb424c9b77efb28402651667 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Thu, 27 Jun 2013 21:33:56 +0200
Subject: [PATCH 04/10] MIPS: bmips: change compile time checks to runtime
checks
Allow building for all bmips cpus at the same time by changing ifdefs
to checks for the cpu type, or adding appropriate checks to the
assembly.
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
arch/mips/kernel/bmips_vec.S | 55 +++++++---
arch/mips/kernel/smp-bmips.c | 241 ++++++++++++++++++++++--------------------
2 files changed, 172 insertions(+), 124 deletions(-)
--- a/arch/mips/kernel/bmips_vec.S
+++ b/arch/mips/kernel/bmips_vec.S
@@ -13,6 +13,7 @@
#include <asm/asm.h>
#include <asm/asmmacro.h>
#include <asm/cacheops.h>
+#include <asm/cpu.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/stackframe.h>
@@ -89,12 +90,18 @@ NESTED(bmips_reset_nmi_vec, PT_SIZE, sp)
beqz k0, bmips_smp_entry
#if defined(CONFIG_CPU_BMIPS5000)
+ mfc0 k0, CP0_PRID
+ li k1, PRID_IMP_BMIPS5000
+ andi k0, 0xff00
+ bne k0, k1, 1f
+
/* if we're not on core 0, this must be the SMP boot signal */
li k1, (3 << 25)
mfc0 k0, $22
and k0, k1
bnez k0, bmips_smp_entry
-#endif
+1:
+#endif /* CONFIG_CPU_BMIPS5000 */
#endif /* CONFIG_SMP */
/* nope, it's just a regular NMI */
@@ -137,7 +144,12 @@ bmips_smp_entry:
xori k0, 0x04
mtc0 k0, CP0_CONFIG
+ mfc0 k0, CP0_PRID
+ andi k0, 0xff00
#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
+ li k1, PRID_IMP_BMIPS43XX
+ bne k0, k1, 2f
+
/* initialize CPU1's local I-cache */
li k0, 0x80000000
li k1, 0x80010000
@@ -148,14 +160,21 @@ bmips_smp_entry:
1: cache Index_Store_Tag_I, 0(k0)
addiu k0, 16
bne k0, k1, 1b
-#elif defined(CONFIG_CPU_BMIPS5000)
+
+ b 3f
+2:
+#endif /* CONFIG_CPU_BMIPS4350 || CONFIG_CPU_BMIPS4380 */
+#if defined(CONFIG_CPU_BMIPS5000)
/* set exception vector base */
+ li k1, PRID_IMP_BMIPS5000
+ bne k0, k1, 3f
+
la k0, ebase
lw k0, 0(k0)
mtc0 k0, $15, 1
BARRIER
-#endif
-
+#endif /* CONFIG_CPU_BMIPS5000 */
+3:
/* jump back to kseg0 in case we need to remap the kseg1 area */
la k0, 1f
jr k0
@@ -221,8 +240,18 @@ END(bmips_smp_int_vec)
LEAF(bmips_enable_xks01)
#if defined(CONFIG_XKS01)
-
+ mfc0 t0, CP0_PRID
+ andi t2, t0, 0xff00
#if defined(CONFIG_CPU_BMIPS4380)
+ li t1, PRID_IMP_BMIPS43XX
+ bne t2, t1, 1f
+
+ andi t0, 0xff
+ addiu t1, t0, -PRID_REV_BMIPS4380_HI
+ bgtz t1, 2f
+ addiu t0, -PRID_REV_BMIPS4380_LO
+ bltz t0, 2f
+
mfc0 t0, $22, 3
li t1, 0x1ff0
li t2, (1 << 12) | (1 << 9)
@@ -231,7 +260,13 @@ LEAF(bmips_enable_xks01)
or t0, t2
mtc0 t0, $22, 3
BARRIER
-#elif defined(CONFIG_CPU_BMIPS5000)
+ b 2f
+1:
+#endif /* CONFIG_CPU_BMIPS4380 */
+#if defined(CONFIG_CPU_BMIPS5000)
+ li t1, PRID_IMP_BMIPS5000
+ bne t2, t1, 2f
+
mfc0 t0, $22, 5
li t1, 0x01ff
li t2, (1 << 8) | (1 << 5)
@@ -240,12 +275,8 @@ LEAF(bmips_enable_xks01)
or t0, t2
mtc0 t0, $22, 5
BARRIER
-#else
-
-#error Missing XKS01 setup
-
-#endif
-
+#endif /* CONFIG_CPU_BMIPS5000 */
+2:
#endif /* defined(CONFIG_XKS01) */
jr ra
--- a/arch/mips/kernel/smp-bmips.c
+++ b/arch/mips/kernel/smp-bmips.c
@@ -49,8 +49,11 @@ cpumask_t bmips_booted_mask;
unsigned long bmips_smp_boot_sp;
unsigned long bmips_smp_boot_gp;
+static void bmips43xx_send_ipi_single(int cpu, unsigned int action);
+static void bmips5000_send_ipi_single(int cpu, unsigned int action);
static void bmips_send_ipi_single(int cpu, unsigned int action);
-static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id);
+static irqreturn_t bmips43xx_ipi_interrupt(int irq, void *dev_id);
+static irqreturn_t bmips5000_ipi_interrupt(int irq, void *dev_id);
/* SW interrupts 0,1 are used for interprocessor signaling */
#define IPI0_IRQ (MIPS_CPU_IRQ_BASE + 0)
@@ -65,48 +68,49 @@ static void __init bmips_smp_setup(void)
{
int i, cpu = 1, boot_cpu = 0;
-#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
- /* arbitration priority */
- clear_c0_brcm_cmt_ctrl(0x30);
-
- /* NBK and weak order flags */
- set_c0_brcm_config_0(0x30000);
-
- /* Find out if we are running on TP0 or TP1 */
- boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
-
- /*
- * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other thread
- * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
- * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
- *
- * If booting from TP1, leave the existing CMT interrupt routing
- * such that TP0 responds to SW1 and TP1 responds to SW0.
- */
- if (boot_cpu == 0)
- change_c0_brcm_cmt_intr(0xf8018000,
+ if (cpu_is_bmips4350() || cpu_is_bmips4380()) {
+ /* arbitration priority */
+ clear_c0_brcm_cmt_ctrl(0x30);
+
+ /* NBK and weak order flags */
+ set_c0_brcm_config_0(0x30000);
+
+ /* Find out if we are running on TP0 or TP1 */
+ boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
+
+ /*
+ * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other
+ * thread
+ * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
+ * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
+ *
+ * If booting from TP1, leave the existing CMT interrupt routing
+ * such that TP0 responds to SW1 and TP1 responds to SW0.
+ */
+ if (boot_cpu == 0)
+ change_c0_brcm_cmt_intr(0xf8018000,
(0x02 << 27) | (0x03 << 15));
- else
- change_c0_brcm_cmt_intr(0xf8018000, (0x1d << 27));
-
- /* single core, 2 threads (2 pipelines) */
- max_cpus = 2;
-#elif defined(CONFIG_CPU_BMIPS5000)
- /* enable raceless SW interrupts */
- set_c0_brcm_config(0x03 << 22);
-
- /* route HW interrupt 0 to CPU0, HW interrupt 1 to CPU1 */
- change_c0_brcm_mode(0x1f << 27, 0x02 << 27);
+ else
+ change_c0_brcm_cmt_intr(0xf8018000, (0x1d << 27));
- /* N cores, 2 threads per core */
- max_cpus = (((read_c0_brcm_config() >> 6) & 0x03) + 1) << 1;
-
- /* clear any pending SW interrupts */
- for (i = 0; i < max_cpus; i++) {
- write_c0_brcm_action(ACTION_CLR_IPI(i, 0));
- write_c0_brcm_action(ACTION_CLR_IPI(i, 1));
+ /* single core, 2 threads (2 pipelines) */
+ max_cpus = 2;
+ } else if (cpu_is_bmips5000()) {
+ /* enable raceless SW interrupts */
+ set_c0_brcm_config(0x03 << 22);
+
+ /* route HW interrupt 0 to CPU0, HW interrupt 1 to CPU1 */
+ change_c0_brcm_mode(0x1f << 27, 0x02 << 27);
+
+ /* N cores, 2 threads per core */
+ max_cpus = (((read_c0_brcm_config() >> 6) & 0x03) + 1) << 1;
+
+ /* clear any pending SW interrupts */
+ for (i = 0; i < max_cpus; i++) {
+ write_c0_brcm_action(ACTION_CLR_IPI(i, 0));
+ write_c0_brcm_action(ACTION_CLR_IPI(i, 1));
+ }
}
-#endif
if (!bmips_smp_enabled)
max_cpus = 1;
@@ -134,6 +138,15 @@ static void __init bmips_smp_setup(void)
*/
static void bmips_prepare_cpus(unsigned int max_cpus)
{
+ irqreturn_t (*bmips_ipi_interrupt)(int irq, void *dev_id);
+
+ if (cpu_is_bmips4350() || cpu_is_bmips4380())
+ bmips_ipi_interrupt = bmips43xx_ipi_interrupt;
+ else if (cpu_is_bmips5000())
+ bmips_ipi_interrupt = bmips5000_ipi_interrupt;
+ else
+ return;
+
if (request_irq(IPI0_IRQ, bmips_ipi_interrupt, IRQF_PERCPU,
"smp_ipi0", NULL))
panic("Can't request IPI0 interrupt\n");
@@ -168,26 +181,26 @@ static void bmips_boot_secondary(int 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)) {
bmips_send_ipi_single(cpu, 0);
- else {
-#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
- /* Reset slave TP1 if booting from TP0 */
- if (cpu_logical_map(cpu) == 0)
- set_c0_brcm_cmt_ctrl(0x01);
-#elif defined(CONFIG_CPU_BMIPS5000)
- if (cpu & 0x01)
- write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
- else {
- /*
- * core N thread 0 was already booted; just
- * pulse the NMI line
- */
- bmips_write_zscm_reg(0x210, 0xc0000000);
- udelay(10);
- bmips_write_zscm_reg(0x210, 0x00);
+ } else {
+ if (cpu_is_bmips4350() || cpu_is_bmips4380()) {
+ /* Reset slave TP1 if booting from TP0 */
+ if (cpu_logical_map(cpu) == 0)
+ set_c0_brcm_cmt_ctrl(0x01);
+ } else if (cpu_is_bmips5000()) {
+ if (cpu & 0x01)
+ write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
+ else {
+ /*
+ * core N thread 0 was already booted; just
+ * pulse the NMI line
+ */
+ bmips_write_zscm_reg(0x210, 0xc0000000);
+ udelay(10);
+ bmips_write_zscm_reg(0x210, 0x00);
+ }
}
-#endif
cpumask_set_cpu(cpu, &bmips_booted_mask);
}
}
@@ -199,20 +212,21 @@ static void bmips_init_secondary(void)
{
/* move NMI vector to kseg0, in case XKS01 is enabled */
-#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
- void __iomem *cbr = BMIPS_GET_CBR();
- unsigned long old_vec;
-
- old_vec = __raw_readl(cbr + BMIPS_RELO_VECTOR_CONTROL_1);
- __raw_writel(old_vec & ~0x20000000, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
-
- clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
-#elif defined(CONFIG_CPU_BMIPS5000)
- write_c0_brcm_bootvec(read_c0_brcm_bootvec() &
- (smp_processor_id() & 0x01 ? ~0x20000000 : ~0x2000));
+ if (cpu_is_bmips4350() || cpu_is_bmips4380()) {
+ void __iomem *cbr = BMIPS_GET_CBR();
+ unsigned long old_vec;
+
+ old_vec = __raw_readl(cbr + BMIPS_RELO_VECTOR_CONTROL_1);
+ __raw_writel(old_vec & ~0x20000000,
+ cbr + BMIPS_RELO_VECTOR_CONTROL_1);
+
+ clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
+ } else if (cpu_is_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));
-#endif
+ write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
+ }
}
/*
@@ -237,8 +251,6 @@ static void bmips_cpus_done(void)
{
}
-#if defined(CONFIG_CPU_BMIPS5000)
-
/*
* BMIPS5000 raceless IPIs
*
@@ -247,12 +259,12 @@ static void bmips_cpus_done(void)
* IPI1 is used for SMP_CALL_FUNCTION
*/
-static void bmips_send_ipi_single(int cpu, unsigned int action)
+static void bmips5000_send_ipi_single(int cpu, unsigned int action)
{
write_c0_brcm_action(ACTION_SET_IPI(cpu, action == SMP_CALL_FUNCTION));
}
-static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id)
+static irqreturn_t bmips5000_ipi_interrupt(int irq, void *dev_id)
{
int action = irq - IPI0_IRQ;
@@ -266,8 +278,6 @@ static irqreturn_t bmips_ipi_interrupt(i
return IRQ_HANDLED;
}
-#else
-
/*
* BMIPS43xx racey IPIs
*
@@ -281,7 +291,7 @@ static irqreturn_t bmips_ipi_interrupt(i
static DEFINE_SPINLOCK(ipi_lock);
static DEFINE_PER_CPU(int, ipi_action_mask);
-static void bmips_send_ipi_single(int cpu, unsigned int action)
+static void bmips43xx_send_ipi_single(int cpu, unsigned int action)
{
unsigned long flags;
@@ -292,7 +302,7 @@ static void bmips_send_ipi_single(int cp
spin_unlock_irqrestore(&ipi_lock, flags);
}
-static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id)
+static irqreturn_t bmips43xx_ipi_interrupt(int irq, void *dev_id)
{
unsigned long flags;
int action, cpu = irq - IPI0_IRQ;
@@ -311,7 +321,13 @@ static irqreturn_t bmips_ipi_interrupt(i
return IRQ_HANDLED;
}
-#endif /* BMIPS type */
+static void bmips_send_ipi_single(int cpu, unsigned int action)
+{
+ if (cpu_is_bmips4350() || cpu_is_bmips4380())
+ bmips43xx_send_ipi_single(cpu, action);
+ else if (cpu_is_bmips5000())
+ bmips5000_send_ipi_single(cpu, action);
+}
static void bmips_send_ipi_mask(const struct cpumask *mask,
unsigned int action)
@@ -421,43 +437,44 @@ void __cpuinit bmips_ebase_setup(void)
BUG_ON(ebase != CKSEG0);
-#if defined(CONFIG_CPU_BMIPS4350)
- /*
- * BMIPS4350 cannot relocate the normal vectors, but it
- * can relocate the BEV=1 vectors. So CPU1 starts up at
- * the relocated BEV=1, IV=0 general exception vector @
- * 0xa000_0380.
- *
- * set_uncached_handler() is used here because:
- * - CPU1 will run this from uncached space
- * - None of the cacheflush functions are set up yet
- */
- set_uncached_handler(BMIPS_WARM_RESTART_VEC - CKSEG0,
- &bmips_smp_int_vec, 0x80);
- __sync();
- return;
-#elif defined(CONFIG_CPU_BMIPS4380)
- /*
- * 0x8000_0000: reset/NMI (initially in kseg1)
- * 0x8000_0400: normal vectors
- */
- new_ebase = 0x80000400;
- cbr = BMIPS_GET_CBR();
- __raw_writel(0x80080800, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
- __raw_writel(0xa0080800, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
-#elif defined(CONFIG_CPU_BMIPS5000)
- /*
- * 0x8000_0000: reset/NMI (initially in kseg1)
- * 0x8000_1000: normal vectors
- */
- new_ebase = 0x80001000;
- write_c0_brcm_bootvec(0xa0088008);
- write_c0_ebase(new_ebase);
- if (max_cpus > 2)
- bmips_write_zscm_reg(0xa0, 0xa008a008);
-#else
- return;
-#endif
+ if (cpu_is_bmips4350()) {
+ /*
+ * BMIPS4350 cannot relocate the normal vectors, but it
+ * can relocate the BEV=1 vectors. So CPU1 starts up at
+ * the relocated BEV=1, IV=0 general exception vector @
+ * 0xa000_0380.
+ *
+ * set_uncached_handler() is used here because:
+ * - CPU1 will run this from uncached space
+ * - None of the cacheflush functions are set up yet
+ */
+ set_uncached_handler(BMIPS_WARM_RESTART_VEC - CKSEG0,
+ &bmips_smp_int_vec, 0x80);
+ __sync();
+ return;
+ } else if (cpu_is_bmips4380()) {
+ /*
+ * 0x8000_0000: reset/NMI (initially in kseg1)
+ * 0x8000_0400: normal vectors
+ */
+ new_ebase = 0x80000400;
+ cbr = BMIPS_GET_CBR();
+ __raw_writel(0x80080800, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
+ __raw_writel(0xa0080800, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
+ } else if (cpu_is_bmips5000()) {
+ /*
+ * 0x8000_0000: reset/NMI (initially in kseg1)
+ * 0x8000_1000: normal vectors
+ */
+ new_ebase = 0x80001000;
+ write_c0_brcm_bootvec(0xa0088008);
+ write_c0_ebase(new_ebase);
+ if (max_cpus > 2)
+ bmips_write_zscm_reg(0xa0, 0xa008a008);
+ } else {
+ return;
+ }
+
board_nmi_handler_setup = &bmips_nmi_handler_setup;
ebase = new_ebase;
}

View File

@ -0,0 +1,126 @@
From 1ecac776e6c652e3059d4f4d9dd8369e89ebef81 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Thu, 27 Jun 2013 23:57:20 +0200
Subject: [PATCH 05/10] MIPS: bmips: merge CPU options into one option
Instead of treating each flavour as an exclusive CPU to select, make
BMIPS the only option and let SYS_HAS_CPU_BMIPS* decide for which
flavours to include support.
Run tested on BMIPS3300 and BMIPS4350, only build tested for BMIPS4380
and BMISP5000.
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
arch/mips/Kconfig | 77 +++++++++++++++++++++++++----------------------------
1 file changed, 36 insertions(+), 41 deletions(-)
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -130,6 +130,7 @@ config BCM63XX
select DMA_NONCOHERENT
select IRQ_CPU
select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_BMIPS
select SYS_HAS_CPU_BMIPS4350 if !BCM63XX_CPU_6338 && !BCM63XX_CPU_6345 && !BCM63XX_CPU_6348
select NR_CPUS_DEFAULT_2
select SYS_SUPPORTS_32BIT_KERNEL
@@ -1454,41 +1455,21 @@ config CPU_CAVIUM_OCTEON
can have up to 16 Mips64v2 cores and 8 integrated gigabit ethernets.
Full details can be found at http://www.caviumnetworks.com.
-config CPU_BMIPS3300
- bool "BMIPS3300"
- depends on SYS_HAS_CPU_BMIPS3300
- select CPU_BMIPS
- help
- Broadcom BMIPS3300 processors.
-
-config CPU_BMIPS4350
- bool "BMIPS4350"
- depends on SYS_HAS_CPU_BMIPS4350
- select CPU_BMIPS
- select SYS_SUPPORTS_SMP
- select SYS_SUPPORTS_HOTPLUG_CPU
- help
- Broadcom BMIPS4350 ("VIPER") processors.
-
-config CPU_BMIPS4380
- bool "BMIPS4380"
- depends on SYS_HAS_CPU_BMIPS4380
- select CPU_BMIPS
- select SYS_SUPPORTS_SMP
- select SYS_SUPPORTS_HOTPLUG_CPU
- help
- Broadcom BMIPS4380 processors.
-
-config CPU_BMIPS5000
- bool "BMIPS5000"
- depends on SYS_HAS_CPU_BMIPS5000
- select CPU_BMIPS
- select CPU_SUPPORTS_HIGHMEM
- select MIPS_CPU_SCACHE
- select SYS_SUPPORTS_SMP
- select SYS_SUPPORTS_HOTPLUG_CPU
+config CPU_BMIPS
+ bool "Broadcom BMIPS"
+ depends on SYS_HAS_CPU_BMIPS
+ select CPU_MIPS32
+ select CPU_BMIPS3300 if SYS_HAS_CPU_BMIPS3300
+ select CPU_BMIPS4350 if SYS_HAS_CPU_BMIPS4350
+ select CPU_BMIPS4350 if SYS_HAS_CPU_BMIPS4380
+ select CPU_BMIPS5000 if SYS_HAS_CPU_BMIPS5000
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select SWAP_IO_SPACE
+ select WEAK_ORDERING
help
- Broadcom BMIPS5000 processors.
+ Support for BMIPS3300/4350/4380 and BMIPS5000 processors.
config CPU_XLR
bool "Netlogic XLR SoC"
@@ -1569,14 +1550,25 @@ config CPU_LOONGSON1
select CPU_SUPPORTS_32BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
-config CPU_BMIPS
+config CPU_BMIPS3300
bool
- select CPU_MIPS32
- select CPU_SUPPORTS_32BIT_KERNEL
- select DMA_NONCOHERENT
- select IRQ_CPU
- select SWAP_IO_SPACE
- select WEAK_ORDERING
+
+config CPU_BMIPS4350
+ bool
+ select SYS_SUPPORTS_SMP
+ select SYS_SUPPORTS_HOTPLUG_CPU
+
+config CPU_BMIPS4380
+ bool
+ select SYS_SUPPORTS_SMP
+ select SYS_SUPPORTS_HOTPLUG_CPU
+
+config CPU_BMIPS5000
+ bool
+ select CPU_SUPPORTS_HIGHMEM
+ select MIPS_CPU_SCACHE
+ select SYS_SUPPORTS_SMP
+ select SYS_SUPPORTS_HOTPLUG_CPU
config SYS_HAS_CPU_LOONGSON2E
bool
@@ -1650,6 +1642,9 @@ config SYS_HAS_CPU_SB1
config SYS_HAS_CPU_CAVIUM_OCTEON
bool
+config SYS_HAS_CPU_BMIPS
+ bool
+
config SYS_HAS_CPU_BMIPS3300
bool

View File

@ -0,0 +1,72 @@
From 9d1e9d7abd2f2d067169fb0c62e34cf080bbd7a1 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 23 Jun 2013 12:25:49 +0200
Subject: [PATCH 06/10] MIPS: BCM63XX: let the individual SoCs select the
appropriate CPUs
Let each supported chip select the appropirate SYS_HAS_CPU_BMIPS*
option for its embedded processor, so support will be conditionally
included.
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
fix bmips selection
---
arch/mips/Kconfig | 1 -
arch/mips/bcm63xx/Kconfig | 8 ++++++++
2 files changed, 8 insertions(+), 1 deletion(-)
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -131,7 +131,6 @@ config BCM63XX
select IRQ_CPU
select SYS_HAS_CPU_MIPS32_R1
select SYS_HAS_CPU_BMIPS
- select SYS_HAS_CPU_BMIPS4350 if !BCM63XX_CPU_6338 && !BCM63XX_CPU_6345 && !BCM63XX_CPU_6348
select NR_CPUS_DEFAULT_2
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -3,33 +3,41 @@ menu "CPU support"
config BCM63XX_CPU_3368
bool "support 3368 CPU"
+ select SYS_HAS_CPU_BMIPS4350
select HW_HAS_PCI
config BCM63XX_CPU_6328
bool "support 6328 CPU"
+ select SYS_HAS_CPU_BMIPS4350
select HW_HAS_PCI
config BCM63XX_CPU_6338
bool "support 6338 CPU"
+ select SYS_HAS_CPU_BMIPS3300
select HW_HAS_PCI
config BCM63XX_CPU_6345
bool "support 6345 CPU"
+ select SYS_HAS_CPU_BMIPS3300
config BCM63XX_CPU_6348
bool "support 6348 CPU"
+ select SYS_HAS_CPU_BMIPS3300
select HW_HAS_PCI
config BCM63XX_CPU_6358
bool "support 6358 CPU"
+ select SYS_HAS_CPU_BMIPS4350
select HW_HAS_PCI
config BCM63XX_CPU_6362
bool "support 6362 CPU"
+ select SYS_HAS_CPU_BMIPS4350
select HW_HAS_PCI
config BCM63XX_CPU_6368
bool "support 6368 CPU"
+ select SYS_HAS_CPU_BMIPS4350
select HW_HAS_PCI
endmenu

View File

@ -0,0 +1,42 @@
From aa15ac91faccc3bf01a29670b1f9ae1945cea056 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 23 Jun 2013 14:04:51 +0200
Subject: [PATCH 07/10] MIPS: bmips: add a helper function for registering smp
ops
Add a helper similar to the generic register_XXX_smp_ops() for bmips.
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
arch/mips/include/asm/bmips.h | 13 +++++++++++++
1 file changed, 13 insertions(+)
--- a/arch/mips/include/asm/bmips.h
+++ b/arch/mips/include/asm/bmips.h
@@ -47,6 +47,7 @@
#include <linux/cpumask.h>
#include <asm/cpu-features.h>
#include <asm/r4kcache.h>
+#include <asm/smp-ops.h>
#define cpu_is_bmips32() (current_cpu_type() == CPU_BMIPS32)
#define cpu_is_bmips3300() (IS_ENABLED(CONFIG_CPU_BMIPS3300) && \
@@ -59,6 +60,18 @@
current_cpu_type() == CPU_BMIPS5000)
extern struct plat_smp_ops bmips_smp_ops;
+
+static inline int register_bmips_smp_ops(void)
+{
+#ifdef CONFIG_CPU_BMIPS
+ register_smp_ops(&bmips_smp_ops);
+
+ return 0;
+#else
+ return -ENODEV;
+#endif
+}
+
extern char bmips_reset_nmi_vec;
extern char bmips_reset_nmi_vec_end;
extern char bmips_smp_movevec;

View File

@ -0,0 +1,26 @@
From c489eace9492d1b8bedb314bdef169e719161bff Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Fri, 28 Jun 2013 00:08:16 +0200
Subject: [PATCH 08/10] MIPS: BCM63XX: always register bmips smp ops
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
arch/mips/bcm63xx/prom.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/arch/mips/bcm63xx/prom.c
+++ b/arch/mips/bcm63xx/prom.c
@@ -59,10 +59,10 @@ void __init prom_init(void)
/* do low level board init */
board_prom_init();
- if (IS_ENABLED(CONFIG_CPU_BMIPS4350) && IS_ENABLED(CONFIG_SMP)) {
- /* set up SMP */
- register_smp_ops(&bmips_smp_ops);
+ /* set up SMP */
+ register_bmips_smp_ops();
+ if (IS_ENABLED(CONFIG_CPU_BMIPS4350) && IS_ENABLED(CONFIG_SMP)) {
/*
* BCM6328 might not have its second CPU enabled, while BCM6358
* needs special handling for its shared TLB, so disable SMP

View File

@ -0,0 +1,21 @@
From 3a862fd3cc4f477ad2232370abfceca1ec2145ae Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Fri, 28 Jun 2013 00:10:07 +0200
Subject: [PATCH 09/10] MIPS: BCM63XX: change the guard to a BMIPS4350 check
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
arch/mips/bcm63xx/prom.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/mips/bcm63xx/prom.c
+++ b/arch/mips/bcm63xx/prom.c
@@ -62,7 +62,7 @@ void __init prom_init(void)
/* set up SMP */
register_bmips_smp_ops();
- if (IS_ENABLED(CONFIG_CPU_BMIPS4350) && IS_ENABLED(CONFIG_SMP)) {
+ if (cpu_is_bmips4350()) {
/*
* BCM6328 might not have its second CPU enabled, while BCM6358
* needs special handling for its shared TLB, so disable SMP

View File

@ -0,0 +1,36 @@
From 32d4b03c0aedb96022e86a67a560f6eaf488200a Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Fri, 28 Jun 2013 00:25:13 +0200
Subject: [PATCH 10/10] MIPS: BCM63XX: disable SMP also on BCM3368
BCM3368 has the same shared TLB as BCM6358.
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
arch/mips/bcm63xx/prom.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/arch/mips/bcm63xx/prom.c
+++ b/arch/mips/bcm63xx/prom.c
@@ -64,9 +64,9 @@ void __init prom_init(void)
if (cpu_is_bmips4350()) {
/*
- * BCM6328 might not have its second CPU enabled, while BCM6358
- * needs special handling for its shared TLB, so disable SMP
- * for now.
+ * BCM6328 might not have its second CPU enabled, while BCM3368
+ * and BCM6358 need special handling for their shared TLB, so
+ * disable SMP for now.
*/
if (BCMCPU_IS_6328()) {
reg = bcm_readl(BCM_6328_OTP_BASE +
@@ -74,7 +74,7 @@ void __init prom_init(void)
if (reg & OTP_6328_REG3_TP1_DISABLED)
bmips_smp_enabled = 0;
- } else if (BCMCPU_IS_6358()) {
+ } else if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) {
bmips_smp_enabled = 0;
}

View File

@ -16,8 +16,8 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -5,9 +5,16 @@ config BCM63XX_CPU_3368
bool "support 3368 CPU"
@@ -6,10 +6,17 @@ config BCM63XX_CPU_3368
select SYS_HAS_CPU_BMIPS4350
select HW_HAS_PCI
+config BCM63XX_OHCI
@ -28,29 +28,33 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
+
config BCM63XX_CPU_6328
bool "support 6328 CPU"
select SYS_HAS_CPU_BMIPS4350
select HW_HAS_PCI
+ select BCM63XX_OHCI
config BCM63XX_CPU_6338
bool "support 6338 CPU"
@@ -19,18 +26,22 @@ config BCM63XX_CPU_6345
config BCM63XX_CPU_6348
@@ -24,21 +31,25 @@ config BCM63XX_CPU_6348
bool "support 6348 CPU"
select SYS_HAS_CPU_BMIPS3300
select HW_HAS_PCI
+ select BCM63XX_OHCI
config BCM63XX_CPU_6358
bool "support 6358 CPU"
select SYS_HAS_CPU_BMIPS4350
select HW_HAS_PCI
+ select BCM63XX_OHCI
config BCM63XX_CPU_6362
bool "support 6362 CPU"
select SYS_HAS_CPU_BMIPS4350
select HW_HAS_PCI
+ select BCM63XX_OHCI
config BCM63XX_CPU_6368
bool "support 6368 CPU"
select SYS_HAS_CPU_BMIPS4350
select HW_HAS_PCI
+ select BCM63XX_OHCI
endmenu

View File

@ -19,7 +19,7 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -11,10 +11,17 @@ config BCM63XX_OHCI
@@ -12,11 +12,18 @@ config BCM63XX_OHCI
select USB_OHCI_BIG_ENDIAN_DESC if USB_OHCI_HCD
select USB_OHCI_BIG_ENDIAN_MMIO if USB_OHCI_HCD
@ -31,26 +31,29 @@ Signed-off-by: Florian Fainelli <florian@openwrt.org>
+
config BCM63XX_CPU_6328
bool "support 6328 CPU"
select SYS_HAS_CPU_BMIPS4350
select HW_HAS_PCI
select BCM63XX_OHCI
+ select BCM63XX_EHCI
config BCM63XX_CPU_6338
bool "support 6338 CPU"
@@ -32,16 +39,19 @@ config BCM63XX_CPU_6358
bool "support 6358 CPU"
@@ -38,18 +45,21 @@ config BCM63XX_CPU_6358
select SYS_HAS_CPU_BMIPS4350
select HW_HAS_PCI
select BCM63XX_OHCI
+ select BCM63XX_EHCI
config BCM63XX_CPU_6362
bool "support 6362 CPU"
select SYS_HAS_CPU_BMIPS4350
select HW_HAS_PCI
select BCM63XX_OHCI
+ select BCM63XX_EHCI
config BCM63XX_CPU_6368
bool "support 6368 CPU"
select SYS_HAS_CPU_BMIPS4350
select HW_HAS_PCI
select BCM63XX_OHCI
+ select BCM63XX_EHCI