* [PATCH V2 1/8] MIPS: BMIPS: Fix up Kconfig settings
@ 2011-11-11 6:30 Kevin Cernekee
2011-11-11 6:30 ` [PATCH V2 2/8] MIPS: Clean up whitespace warning in hazards.h Kevin Cernekee
` (7 more replies)
0 siblings, 8 replies; 24+ messages in thread
From: Kevin Cernekee @ 2011-11-11 6:30 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Factor out common BMIPS options into "CPU_BMIPS". Add L2 cache for
BMIPS5000. Add CPU_MIPS32 to satisfy checks in page.h, r4k_switch.S,
tlb-r4k.c, etc.
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
---
arch/mips/Kconfig | 34 ++++++++++++++--------------------
1 files changed, 14 insertions(+), 20 deletions(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index d46f1da..e7587ac 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1413,51 +1413,36 @@ config CPU_CAVIUM_OCTEON
config CPU_BMIPS3300
bool "BMIPS3300"
depends on SYS_HAS_CPU_BMIPS3300
- select DMA_NONCOHERENT
- select IRQ_CPU
- select SWAP_IO_SPACE
- select SYS_SUPPORTS_32BIT_KERNEL
- select WEAK_ORDERING
+ select CPU_BMIPS
help
Broadcom BMIPS3300 processors.
config CPU_BMIPS4350
bool "BMIPS4350"
depends on SYS_HAS_CPU_BMIPS4350
- select CPU_SUPPORTS_32BIT_KERNEL
- select DMA_NONCOHERENT
- select IRQ_CPU
- select SWAP_IO_SPACE
+ select CPU_BMIPS
select SYS_SUPPORTS_SMP
select SYS_SUPPORTS_HOTPLUG_CPU
- select WEAK_ORDERING
help
Broadcom BMIPS4350 ("VIPER") processors.
config CPU_BMIPS4380
bool "BMIPS4380"
depends on SYS_HAS_CPU_BMIPS4380
- select CPU_SUPPORTS_32BIT_KERNEL
- select DMA_NONCOHERENT
- select IRQ_CPU
- select SWAP_IO_SPACE
+ select CPU_BMIPS
select SYS_SUPPORTS_SMP
select SYS_SUPPORTS_HOTPLUG_CPU
- select WEAK_ORDERING
help
Broadcom BMIPS4380 processors.
config CPU_BMIPS5000
bool "BMIPS5000"
depends on SYS_HAS_CPU_BMIPS5000
- select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_BMIPS
select CPU_SUPPORTS_HIGHMEM
- select DMA_NONCOHERENT
- select IRQ_CPU
- select SWAP_IO_SPACE
+ select MIPS_CPU_SCACHE
select SYS_SUPPORTS_SMP
select SYS_SUPPORTS_HOTPLUG_CPU
- select WEAK_ORDERING
help
Broadcom BMIPS5000 processors.
@@ -1518,6 +1503,15 @@ config CPU_LOONGSON2
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
+config CPU_BMIPS
+ bool
+ select CPU_MIPS32
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select SWAP_IO_SPACE
+ select WEAK_ORDERING
+
config SYS_HAS_CPU_LOONGSON2E
bool
--
1.7.6.3
^ permalink raw reply related [flat|nested] 24+ messages in thread* [PATCH V2 2/8] MIPS: Clean up whitespace warning in hazards.h 2011-11-11 6:30 [PATCH V2 1/8] MIPS: BMIPS: Fix up Kconfig settings Kevin Cernekee @ 2011-11-11 6:30 ` Kevin Cernekee 2011-11-11 18:03 ` Ralf Baechle 2011-11-11 6:30 ` [PATCH V2 3/8] MIPS: BMIPS: Add CFLAGS, Makefile entries for BMIPS Kevin Cernekee ` (6 subsequent siblings) 7 siblings, 1 reply; 24+ messages in thread From: Kevin Cernekee @ 2011-11-11 6:30 UTC (permalink / raw) To: Ralf Baechle; +Cc: linux-mips Use a tab on second and subsequent lines of multiline #if's, for consistency with the next commit. Signed-off-by: Kevin Cernekee <cernekee@gmail.com> --- arch/mips/include/asm/hazards.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/include/asm/hazards.h b/arch/mips/include/asm/hazards.h index 4e33216..8f630e4 100644 --- a/arch/mips/include/asm/hazards.h +++ b/arch/mips/include/asm/hazards.h @@ -139,8 +139,8 @@ do { \ } while (0) #elif defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \ - defined(CONFIG_CPU_LOONGSON2) || defined(CONFIG_CPU_R10000) || \ - defined(CONFIG_CPU_R5500) + defined(CONFIG_CPU_LOONGSON2) || defined(CONFIG_CPU_R10000) || \ + defined(CONFIG_CPU_R5500) /* * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. -- 1.7.6.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH V2 2/8] MIPS: Clean up whitespace warning in hazards.h 2011-11-11 6:30 ` [PATCH V2 2/8] MIPS: Clean up whitespace warning in hazards.h Kevin Cernekee @ 2011-11-11 18:03 ` Ralf Baechle 0 siblings, 0 replies; 24+ messages in thread From: Ralf Baechle @ 2011-11-11 18:03 UTC (permalink / raw) To: Kevin Cernekee; +Cc: linux-mips Queued for 3.3. Thanks, Ralf ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH V2 3/8] MIPS: BMIPS: Add CFLAGS, Makefile entries for BMIPS 2011-11-11 6:30 [PATCH V2 1/8] MIPS: BMIPS: Fix up Kconfig settings Kevin Cernekee 2011-11-11 6:30 ` [PATCH V2 2/8] MIPS: Clean up whitespace warning in hazards.h Kevin Cernekee @ 2011-11-11 6:30 ` Kevin Cernekee 2011-11-11 12:58 ` Ralf Baechle 2011-11-11 6:30 ` [PATCH V2 4/8] MIPS: BMIPS: Add set/clear CP0 macros for BMIPS operations Kevin Cernekee ` (5 subsequent siblings) 7 siblings, 1 reply; 24+ messages in thread From: Kevin Cernekee @ 2011-11-11 6:30 UTC (permalink / raw) To: Ralf Baechle; +Cc: linux-mips Add CONFIG_CPU_BMIPS* in all of the right places, so that BMIPS kernel images will compile and run. Signed-off-by: Kevin Cernekee <cernekee@gmail.com> --- arch/mips/Makefile | 1 + arch/mips/include/asm/hazards.h | 3 ++- arch/mips/include/asm/module.h | 2 ++ 3 files changed, 5 insertions(+), 1 deletions(-) diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 9b4cb00..ae5cfa7 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -157,6 +157,7 @@ ifeq (,$(findstring march=octeon, $(cflags-$(CONFIG_CPU_CAVIUM_OCTEON)))) cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -Wa,-march=octeon endif cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1 +cflags-$(CONFIG_CPU_BMIPS) += -march=mips32 -Wa,-mips32 -Wa,--trap cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,) cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,) diff --git a/arch/mips/include/asm/hazards.h b/arch/mips/include/asm/hazards.h index 8f630e4..b4c20e4 100644 --- a/arch/mips/include/asm/hazards.h +++ b/arch/mips/include/asm/hazards.h @@ -87,7 +87,8 @@ do { \ : "=r" (tmp)); \ } while (0) -#elif defined(CONFIG_CPU_MIPSR1) && !defined(CONFIG_MIPS_ALCHEMY) +#elif (defined(CONFIG_CPU_MIPSR1) && !defined(CONFIG_MIPS_ALCHEMY)) || \ + defined(CONFIG_CPU_BMIPS) /* * These are slightly complicated by the fact that we guarantee R1 kernels to diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h index bc01a02..c392df2 100644 --- a/arch/mips/include/asm/module.h +++ b/arch/mips/include/asm/module.h @@ -120,6 +120,8 @@ search_module_dbetables(unsigned long addr) #define MODULE_PROC_FAMILY "OCTEON " #elif defined CONFIG_CPU_XLR #define MODULE_PROC_FAMILY "XLR " +#elif defined CONFIG_CPU_BMIPS +#define MODULE_PROC_FAMILY "BMIPS " #else #error MODULE_PROC_FAMILY undefined for your processor configuration #endif -- 1.7.6.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH V2 3/8] MIPS: BMIPS: Add CFLAGS, Makefile entries for BMIPS 2011-11-11 6:30 ` [PATCH V2 3/8] MIPS: BMIPS: Add CFLAGS, Makefile entries for BMIPS Kevin Cernekee @ 2011-11-11 12:58 ` Ralf Baechle 2011-11-11 16:57 ` Kevin Cernekee 0 siblings, 1 reply; 24+ messages in thread From: Ralf Baechle @ 2011-11-11 12:58 UTC (permalink / raw) To: Kevin Cernekee; +Cc: linux-mips On Thu, Nov 10, 2011 at 10:30:26PM -0800, Kevin Cernekee wrote: > +cflags-$(CONFIG_CPU_BMIPS) += -march=mips32 -Wa,-mips32 -Wa,--trap > +#define MODULE_PROC_FAMILY "BMIPS " If BMIPS is just a MIPS32 with no relevant extensions to the instruction set, why don't you just call it a MIPS32 processor and use something like CPU_MIPS32_R2? It's small things like that which can sometimes avoid many unnecessary recompilations which really saves times when rebuilding all defconfigs on a way to slow machine :) Ralf ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH V2 3/8] MIPS: BMIPS: Add CFLAGS, Makefile entries for BMIPS 2011-11-11 12:58 ` Ralf Baechle @ 2011-11-11 16:57 ` Kevin Cernekee 2011-11-11 17:20 ` Ralf Baechle 2011-11-11 18:03 ` Ralf Baechle 0 siblings, 2 replies; 24+ messages in thread From: Kevin Cernekee @ 2011-11-11 16:57 UTC (permalink / raw) To: Ralf Baechle; +Cc: linux-mips On Fri, Nov 11, 2011 at 4:58 AM, Ralf Baechle <ralf@linux-mips.org> wrote: > If BMIPS is just a MIPS32 with no relevant extensions to the instruction > set, why don't you just call it a MIPS32 processor and use something > like CPU_MIPS32_R2? > > It's small things like that which can sometimes avoid many unnecessary > recompilations which really saves times when rebuilding all defconfigs > on a way to slow machine :) At a high level, the CONFIG_CPU_BMIPS* settings are used to make compile-time decisions that differentiate BMIPS from standard MIPS32, and that differentiate the BMIPS CPUs from one another. Present and future uses include: Figuring out which set of proprietary BMIPS CP0 registers / core registers to use, where they are located, bit fields, etc. Per-BMIPS SMP operations and capabilities Per-BMIPS performance counter access cpu-feature-overrides.h HIGHMEM, SMP, and other basic features eDSP instruction set (different on each BMIPS, and BMIPS-specific) Cache architecture and BMIPS-specific cache optimizations Some of these could potentially be replaced with a "switch (current_cpu_type())" but others are a little trickier (i.e. they show up in low-level PM resume code, exception vectors, or other sensitive places). It is true that BMIPS uses -mips32 for compilation. If the criteria for adding a new CONFIG_CPU_* choice is whether it selects a new instruction set or compilation flags, do you think it makes sense to remove BMIPS* from the "CPU selection" menu, enable CONFIG_CPU_MIPS32_R1 for BMIPS platforms, and call our options something different? e.g. CONFIG_BMIPS CONFIG_BMIPS3300 CONFIG_BMIPS4350 CONFIG_BMIPS4380 CONFIG_BMIPS5000 ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH V2 3/8] MIPS: BMIPS: Add CFLAGS, Makefile entries for BMIPS 2011-11-11 16:57 ` Kevin Cernekee @ 2011-11-11 17:20 ` Ralf Baechle 2011-11-12 14:11 ` Florian Fainelli 2011-11-11 18:03 ` Ralf Baechle 1 sibling, 1 reply; 24+ messages in thread From: Ralf Baechle @ 2011-11-11 17:20 UTC (permalink / raw) To: Kevin Cernekee; +Cc: linux-mips On Fri, Nov 11, 2011 at 08:57:39AM -0800, Kevin Cernekee wrote: > At a high level, the CONFIG_CPU_BMIPS* settings are used to make > compile-time decisions that differentiate BMIPS from standard MIPS32, > and that differentiate the BMIPS CPUs from one another. > > > Present and future uses include: > > Figuring out which set of proprietary BMIPS CP0 registers / core > registers to use, where they are located, bit fields, etc. > > Per-BMIPS SMP operations and capabilities > > Per-BMIPS performance counter access > > cpu-feature-overrides.h > > HIGHMEM, SMP, and other basic features > > eDSP instruction set (different on each BMIPS, and BMIPS-specific) > > Cache architecture and BMIPS-specific cache optimizations > > > Some of these could potentially be replaced with a "switch > (current_cpu_type())" but others are a little trickier (i.e. they show > up in low-level PM resume code, exception vectors, or other sensitive > places). > > > It is true that BMIPS uses -mips32 for compilation. If the criteria > for adding a new CONFIG_CPU_* choice is whether it selects a new > instruction set or compilation flags, do you think it makes sense to > remove BMIPS* from the "CPU selection" menu, enable > CONFIG_CPU_MIPS32_R1 for BMIPS platforms, and call our options > something different? e.g. > > CONFIG_BMIPS > CONFIG_BMIPS3300 > CONFIG_BMIPS4350 > CONFIG_BMIPS4380 > CONFIG_BMIPS5000 Fair enough; sorting that kind of thing will need some effort across the tree at some point in the future. I notice there seems to be only CPU core support; are you planning to submit board support code as well? Ralf ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH V2 3/8] MIPS: BMIPS: Add CFLAGS, Makefile entries for BMIPS 2011-11-11 17:20 ` Ralf Baechle @ 2011-11-12 14:11 ` Florian Fainelli 0 siblings, 0 replies; 24+ messages in thread From: Florian Fainelli @ 2011-11-12 14:11 UTC (permalink / raw) To: Ralf Baechle; +Cc: Kevin Cernekee, linux-mips Le vendredi 11 novembre 2011 18:20:39, Ralf Baechle a écrit : > On Fri, Nov 11, 2011 at 08:57:39AM -0800, Kevin Cernekee wrote: > > At a high level, the CONFIG_CPU_BMIPS* settings are used to make > > compile-time decisions that differentiate BMIPS from standard MIPS32, > > and that differentiate the BMIPS CPUs from one another. > > > > > > Present and future uses include: > > > > Figuring out which set of proprietary BMIPS CP0 registers / core > > registers to use, where they are located, bit fields, etc. > > > > Per-BMIPS SMP operations and capabilities > > > > Per-BMIPS performance counter access > > > > cpu-feature-overrides.h > > > > HIGHMEM, SMP, and other basic features > > > > eDSP instruction set (different on each BMIPS, and BMIPS-specific) > > > > Cache architecture and BMIPS-specific cache optimizations > > > > > > Some of these could potentially be replaced with a "switch > > (current_cpu_type())" but others are a little trickier (i.e. they show > > up in low-level PM resume code, exception vectors, or other sensitive > > places). > > > > > > It is true that BMIPS uses -mips32 for compilation. If the criteria > > for adding a new CONFIG_CPU_* choice is whether it selects a new > > instruction set or compilation flags, do you think it makes sense to > > remove BMIPS* from the "CPU selection" menu, enable > > CONFIG_CPU_MIPS32_R1 for BMIPS platforms, and call our options > > something different? e.g. > > > > CONFIG_BMIPS > > CONFIG_BMIPS3300 > > CONFIG_BMIPS4350 > > CONFIG_BMIPS4380 > > CONFIG_BMIPS5000 > > Fair enough; sorting that kind of thing will need some effort across > the tree at some point in the future. > > I notice there seems to be only CPU core support; are you planning > to submit board support code as well? BCM63xx and BCM47xx use BMIPS CPUs and can already take advantage of this core CPU support code. -- Florian ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH V2 3/8] MIPS: BMIPS: Add CFLAGS, Makefile entries for BMIPS 2011-11-11 16:57 ` Kevin Cernekee 2011-11-11 17:20 ` Ralf Baechle @ 2011-11-11 18:03 ` Ralf Baechle 1 sibling, 0 replies; 24+ messages in thread From: Ralf Baechle @ 2011-11-11 18:03 UTC (permalink / raw) To: Kevin Cernekee; +Cc: linux-mips Queued for 3.3. Thanks, Ral ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH V2 4/8] MIPS: BMIPS: Add set/clear CP0 macros for BMIPS operations 2011-11-11 6:30 [PATCH V2 1/8] MIPS: BMIPS: Fix up Kconfig settings Kevin Cernekee 2011-11-11 6:30 ` [PATCH V2 2/8] MIPS: Clean up whitespace warning in hazards.h Kevin Cernekee 2011-11-11 6:30 ` [PATCH V2 3/8] MIPS: BMIPS: Add CFLAGS, Makefile entries for BMIPS Kevin Cernekee @ 2011-11-11 6:30 ` Kevin Cernekee 2011-11-11 18:04 ` Ralf Baechle 2011-11-11 6:30 ` [PATCH V2 5/8] MIPS: BMIPS: Introduce bmips.h Kevin Cernekee ` (4 subsequent siblings) 7 siblings, 1 reply; 24+ messages in thread From: Kevin Cernekee @ 2011-11-11 6:30 UTC (permalink / raw) To: Ralf Baechle; +Cc: linux-mips Several BMIPS-specific CP0 registers are used for SMP boot and other operations. Signed-off-by: Kevin Cernekee <cernekee@gmail.com> --- arch/mips/include/asm/mipsregs.h | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 2ea7b81..7f87d82 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -1106,7 +1106,7 @@ do { \ #define read_c0_brcm_reset() __read_32bit_c0_register($22, 5) #define write_c0_brcm_reset(val) __write_32bit_c0_register($22, 5, val) -/* BMIPS4380 */ +/* BMIPS43xx */ #define read_c0_brcm_cmt_intr() __read_32bit_c0_register($22, 1) #define write_c0_brcm_cmt_intr(val) __write_32bit_c0_register($22, 1, val) @@ -1667,6 +1667,13 @@ __BUILD_SET_C0(config) __BUILD_SET_C0(intcontrol) __BUILD_SET_C0(intctl) __BUILD_SET_C0(srsmap) +__BUILD_SET_C0(brcm_config_0) +__BUILD_SET_C0(brcm_bus_pll) +__BUILD_SET_C0(brcm_reset) +__BUILD_SET_C0(brcm_cmt_intr) +__BUILD_SET_C0(brcm_cmt_ctrl) +__BUILD_SET_C0(brcm_config) +__BUILD_SET_C0(brcm_mode) #endif /* !__ASSEMBLY__ */ -- 1.7.6.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH V2 4/8] MIPS: BMIPS: Add set/clear CP0 macros for BMIPS operations 2011-11-11 6:30 ` [PATCH V2 4/8] MIPS: BMIPS: Add set/clear CP0 macros for BMIPS operations Kevin Cernekee @ 2011-11-11 18:04 ` Ralf Baechle 0 siblings, 0 replies; 24+ messages in thread From: Ralf Baechle @ 2011-11-11 18:04 UTC (permalink / raw) To: Kevin Cernekee; +Cc: linux-mips Queued for 3.3. Thanks, Ral ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH V2 5/8] MIPS: BMIPS: Introduce bmips.h 2011-11-11 6:30 [PATCH V2 1/8] MIPS: BMIPS: Fix up Kconfig settings Kevin Cernekee ` (2 preceding siblings ...) 2011-11-11 6:30 ` [PATCH V2 4/8] MIPS: BMIPS: Add set/clear CP0 macros for BMIPS operations Kevin Cernekee @ 2011-11-11 6:30 ` Kevin Cernekee 2011-11-11 13:32 ` Ralf Baechle 2011-11-11 18:04 ` Ralf Baechle 2011-11-11 6:30 ` [PATCH V2 6/8] MIPS: Add NMI notifier Kevin Cernekee ` (3 subsequent siblings) 7 siblings, 2 replies; 24+ messages in thread From: Kevin Cernekee @ 2011-11-11 6:30 UTC (permalink / raw) To: Ralf Baechle; +Cc: linux-mips bmips.h contains BMIPS definitions that are useful for SMP, vector relocation, performance counters, etc. Signed-off-by: Kevin Cernekee <cernekee@gmail.com> --- V2: Rewrite all of bmips_{read,write}_zscm_reg in assembly. Add bmips_cpu_offset. arch/mips/include/asm/bmips.h | 109 +++++++++++++++++++++++++++++++++++++++++ 1 files changed, 109 insertions(+), 0 deletions(-) create mode 100644 arch/mips/include/asm/bmips.h diff --git a/arch/mips/include/asm/bmips.h b/arch/mips/include/asm/bmips.h new file mode 100644 index 0000000..1ec4a6e --- /dev/null +++ b/arch/mips/include/asm/bmips.h @@ -0,0 +1,109 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2011 by Kevin Cernekee (cernekee@gmail.com) + * + * Definitions for BMIPS processors + */ +#ifndef _ASM_BMIPS_H +#define _ASM_BMIPS_H + +#include <linux/compiler.h> +#include <linux/linkage.h> +#include <asm/addrspace.h> +#include <asm/mipsregs.h> + +/* NOTE: the CBR register returns a PA, and it can be above 0xff00_0000 */ +#define BMIPS_GET_CBR() ((void __iomem *)(CKSEG1 | \ + (unsigned long) \ + ((read_c0_brcm_cbr() >> 18) << 18))) + +#define BMIPS_RAC_CONFIG 0x00000000 +#define BMIPS_RAC_ADDRESS_RANGE 0x00000004 +#define BMIPS_RAC_CONFIG_1 0x00000008 +#define BMIPS_L2_CONFIG 0x0000000c +#define BMIPS_LMB_CONTROL 0x0000001c +#define BMIPS_SYSTEM_BASE 0x00000020 +#define BMIPS_PERF_GLOBAL_CONTROL 0x00020000 +#define BMIPS_PERF_CONTROL_0 0x00020004 +#define BMIPS_PERF_CONTROL_1 0x00020008 +#define BMIPS_PERF_COUNTER_0 0x00020010 +#define BMIPS_PERF_COUNTER_1 0x00020014 +#define BMIPS_PERF_COUNTER_2 0x00020018 +#define BMIPS_PERF_COUNTER_3 0x0002001c +#define BMIPS_RELO_VECTOR_CONTROL_0 0x00030000 +#define BMIPS_RELO_VECTOR_CONTROL_1 0x00038000 + +#define BMIPS_NMI_RESET_VEC 0x80000000 +#define BMIPS_WARM_RESTART_VEC 0x80000380 + +#define ZSCM_REG_BASE 0x97000000 + +#if !defined(__ASSEMBLY__) + +#include <linux/cpumask.h> +#include <asm/r4kcache.h> + +extern struct plat_smp_ops bmips_smp_ops; +extern char bmips_reset_nmi_vec; +extern char bmips_reset_nmi_vec_end; +extern char bmips_smp_movevec; +extern char bmips_smp_int_vec; +extern char bmips_smp_int_vec_end; + +extern int bmips_smp_enabled; +extern int bmips_cpu_offset; +extern cpumask_t bmips_booted_mask; + +extern void bmips_ebase_setup(void); +extern asmlinkage void plat_wired_tlb_setup(void); + +static inline unsigned long bmips_read_zscm_reg(unsigned int offset) +{ + unsigned long ret; + + __asm__ __volatile__( + ".set push\n" + ".set noreorder\n" + "cache %1, 0(%2)\n" + "sync\n" + "ssnop\n" + "ssnop\n" + "ssnop\n" + "ssnop\n" + "ssnop\n" + "ssnop\n" + "ssnop\n" + "mfc0 %0, $28, 3\n" + "ssnop\n" + ".set pop\n" + : "=&r" (ret) + : "i" (Index_Load_Tag_S), "r" (ZSCM_REG_BASE + offset) + : "memory"); + return ret; +} + +static inline void bmips_write_zscm_reg(unsigned int offset, unsigned long data) +{ + __asm__ __volatile__( + ".set push\n" + ".set noreorder\n" + "mtc0 %0, $28, 3\n" + "ssnop\n" + "ssnop\n" + "ssnop\n" + "cache %1, 0(%2)\n" + "ssnop\n" + "ssnop\n" + "ssnop\n" + : /* no outputs */ + : "r" (data), + "i" (Index_Store_Tag_S), "r" (ZSCM_REG_BASE + offset) + : "memory"); +} + +#endif /* !defined(__ASSEMBLY__) */ + +#endif /* _ASM_BMIPS_H */ -- 1.7.6.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH V2 5/8] MIPS: BMIPS: Introduce bmips.h 2011-11-11 6:30 ` [PATCH V2 5/8] MIPS: BMIPS: Introduce bmips.h Kevin Cernekee @ 2011-11-11 13:32 ` Ralf Baechle 2011-11-11 18:04 ` Ralf Baechle 1 sibling, 0 replies; 24+ messages in thread From: Ralf Baechle @ 2011-11-11 13:32 UTC (permalink / raw) To: Kevin Cernekee; +Cc: linux-mips On Thu, Nov 10, 2011 at 10:30:28PM -0800, Kevin Cernekee wrote: > + __asm__ __volatile__( > + ".set push\n" > + ".set noreorder\n" > + "cache %1, 0(%2)\n" > + "sync\n" > + "ssnop\n" Ssnop was added relatively recently to gas and the kernel supports building with much older toolchains. To get around this <asm/hazard.h> defines a _ssnop macro. Ralf ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH V2 5/8] MIPS: BMIPS: Introduce bmips.h 2011-11-11 6:30 ` [PATCH V2 5/8] MIPS: BMIPS: Introduce bmips.h Kevin Cernekee 2011-11-11 13:32 ` Ralf Baechle @ 2011-11-11 18:04 ` Ralf Baechle 1 sibling, 0 replies; 24+ messages in thread From: Ralf Baechle @ 2011-11-11 18:04 UTC (permalink / raw) To: Kevin Cernekee; +Cc: linux-mips Dropped; using the replacement you sent. Thanks, Ralf ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH V2 6/8] MIPS: Add NMI notifier 2011-11-11 6:30 [PATCH V2 1/8] MIPS: BMIPS: Fix up Kconfig settings Kevin Cernekee ` (3 preceding siblings ...) 2011-11-11 6:30 ` [PATCH V2 5/8] MIPS: BMIPS: Introduce bmips.h Kevin Cernekee @ 2011-11-11 6:30 ` Kevin Cernekee 2011-11-11 13:34 ` Ralf Baechle 2011-11-11 18:04 ` Ralf Baechle 2011-11-11 6:30 ` [PATCH V2 7/8] MIPS: Add board_ebase_setup() Kevin Cernekee ` (2 subsequent siblings) 7 siblings, 2 replies; 24+ messages in thread From: Kevin Cernekee @ 2011-11-11 6:30 UTC (permalink / raw) To: Ralf Baechle; +Cc: linux-mips Allow the board support code to register a raw notifier callback for NMI, similar to what is done for CU2 exceptions. Signed-off-by: Kevin Cernekee <cernekee@gmail.com> --- V2: Use a raw notifier instead of a function pointer for NMI events. arch/mips/include/asm/traps.h | 12 ++++++++++++ arch/mips/kernel/traps.c | 9 +++++++++ 2 files changed, 21 insertions(+), 0 deletions(-) diff --git a/arch/mips/include/asm/traps.h b/arch/mips/include/asm/traps.h index 90ff2f4..4edab87 100644 --- a/arch/mips/include/asm/traps.h +++ b/arch/mips/include/asm/traps.h @@ -25,4 +25,16 @@ extern void (*board_nmi_handler_setup)(void); extern void (*board_ejtag_handler_setup)(void); extern void (*board_bind_eic_interrupt)(int irq, int regset); +extern int register_nmi_notifier(struct notifier_block *nb); + +#define nmi_notifier(fn, pri) \ +({ \ + static struct notifier_block fn##_nb = { \ + .notifier_call = fn, \ + .priority = pri \ + }; \ + \ + register_nmi_notifier(&fn##_nb); \ +}) + #endif /* _ASM_TRAPS_H */ diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 5c8a49d..33945aa 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1339,9 +1339,18 @@ void ejtag_exception_handler(struct pt_regs *regs) /* * NMI exception handler. + * No lock; only written during early bootup by CPU 0. */ +static RAW_NOTIFIER_HEAD(nmi_chain); + +int register_nmi_notifier(struct notifier_block *nb) +{ + return raw_notifier_chain_register(&nmi_chain, nb); +} + NORET_TYPE void ATTRIB_NORET nmi_exception_handler(struct pt_regs *regs) { + raw_notifier_call_chain(&nmi_chain, 0, regs); bust_spinlocks(1); printk("NMI taken!!!!\n"); die("NMI", regs); -- 1.7.6.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH V2 6/8] MIPS: Add NMI notifier 2011-11-11 6:30 ` [PATCH V2 6/8] MIPS: Add NMI notifier Kevin Cernekee @ 2011-11-11 13:34 ` Ralf Baechle 2011-11-11 18:04 ` Ralf Baechle 1 sibling, 0 replies; 24+ messages in thread From: Ralf Baechle @ 2011-11-11 13:34 UTC (permalink / raw) To: Kevin Cernekee; +Cc: linux-mips On Thu, Nov 10, 2011 at 10:30:29PM -0800, Kevin Cernekee wrote: > + * No lock; only written during early bootup by CPU 0. And if that wasn't the case, an NMI might come at any time, even with the lock already being held which would result in a deadlock. NMIs are nasty stuff - and on MIPS they're just slightly more evil. Ralf ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH V2 6/8] MIPS: Add NMI notifier 2011-11-11 6:30 ` [PATCH V2 6/8] MIPS: Add NMI notifier Kevin Cernekee 2011-11-11 13:34 ` Ralf Baechle @ 2011-11-11 18:04 ` Ralf Baechle 1 sibling, 0 replies; 24+ messages in thread From: Ralf Baechle @ 2011-11-11 18:04 UTC (permalink / raw) To: Kevin Cernekee; +Cc: linux-mips Queued for 3.3. Thanks, Ralf ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH V2 7/8] MIPS: Add board_ebase_setup() 2011-11-11 6:30 [PATCH V2 1/8] MIPS: BMIPS: Fix up Kconfig settings Kevin Cernekee ` (4 preceding siblings ...) 2011-11-11 6:30 ` [PATCH V2 6/8] MIPS: Add NMI notifier Kevin Cernekee @ 2011-11-11 6:30 ` Kevin Cernekee 2011-11-11 18:05 ` Ralf Baechle 2011-11-11 6:30 ` [PATCH V2 8/8] MIPS: BMIPS: Add SMP support code for BMIPS43xx/BMIPS5000 Kevin Cernekee 2011-11-11 18:03 ` [PATCH V2 1/8] MIPS: BMIPS: Fix up Kconfig settings Ralf Baechle 7 siblings, 1 reply; 24+ messages in thread From: Kevin Cernekee @ 2011-11-11 6:30 UTC (permalink / raw) To: Ralf Baechle; +Cc: linux-mips Some systems need to relocate the MIPS exception vector base during trap initialization. Add a hook to make this possible. Signed-off-by: Kevin Cernekee <cernekee@gmail.com> --- arch/mips/include/asm/traps.h | 1 + arch/mips/kernel/traps.c | 3 +++ 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/arch/mips/include/asm/traps.h b/arch/mips/include/asm/traps.h index 4edab87..ff74aec 100644 --- a/arch/mips/include/asm/traps.h +++ b/arch/mips/include/asm/traps.h @@ -24,6 +24,7 @@ extern int (*board_be_handler)(struct pt_regs *regs, int is_fixup); extern void (*board_nmi_handler_setup)(void); extern void (*board_ejtag_handler_setup)(void); extern void (*board_bind_eic_interrupt)(int irq, int regset); +extern void (*board_ebase_setup)(void); extern int register_nmi_notifier(struct notifier_block *nb); diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 33945aa..c18dfd4 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -91,6 +91,7 @@ int (*board_be_handler)(struct pt_regs *regs, int is_fixup); void (*board_nmi_handler_setup)(void); void (*board_ejtag_handler_setup)(void); void (*board_bind_eic_interrupt)(int irq, int regset); +void (*board_ebase_setup)(void); static void show_raw_backtrace(unsigned long reg29) @@ -1691,6 +1692,8 @@ void __init trap_init(void) ebase += (read_c0_ebase() & 0x3ffff000); } + if (board_ebase_setup) + board_ebase_setup(); per_cpu_trap_init(); /* -- 1.7.6.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH V2 7/8] MIPS: Add board_ebase_setup() 2011-11-11 6:30 ` [PATCH V2 7/8] MIPS: Add board_ebase_setup() Kevin Cernekee @ 2011-11-11 18:05 ` Ralf Baechle 0 siblings, 0 replies; 24+ messages in thread From: Ralf Baechle @ 2011-11-11 18:05 UTC (permalink / raw) To: Kevin Cernekee; +Cc: linux-mips Queued for 3.3. Thanks, Ralf ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH V2 8/8] MIPS: BMIPS: Add SMP support code for BMIPS43xx/BMIPS5000 2011-11-11 6:30 [PATCH V2 1/8] MIPS: BMIPS: Fix up Kconfig settings Kevin Cernekee ` (5 preceding siblings ...) 2011-11-11 6:30 ` [PATCH V2 7/8] MIPS: Add board_ebase_setup() Kevin Cernekee @ 2011-11-11 6:30 ` Kevin Cernekee 2011-11-11 18:05 ` Ralf Baechle 2011-11-12 14:31 ` Florian Fainelli 2011-11-11 18:03 ` [PATCH V2 1/8] MIPS: BMIPS: Fix up Kconfig settings Ralf Baechle 7 siblings, 2 replies; 24+ messages in thread From: Kevin Cernekee @ 2011-11-11 6:30 UTC (permalink / raw) To: Ralf Baechle; +Cc: linux-mips Initial commit of BMIPS SMP support code. Smoke-tested on a variety of BMIPS4350, BMIPS4380, and BMIPS5000 platforms. Signed-off-by: Kevin Cernekee <cernekee@gmail.com> --- V2: Move XKS01 option into this patch. Remove dependency on local_flush_tlb_all_mm(), per the discussion earlier this week. Allow platform-configurable variables to be accessed in !CONFIG_SMP mode, so the platform code does not need unnecessary #ifdefs. Remove the code that clears the FPU registers. Fix the jump to the NMI vector. Add bmips_cpu_offset. arch/mips/Kconfig | 3 + arch/mips/kernel/Makefile | 1 + arch/mips/kernel/bmips_vec.S | 254 +++++++++++++++++++++++ arch/mips/kernel/smp-bmips.c | 457 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 715 insertions(+), 0 deletions(-) create mode 100644 arch/mips/kernel/bmips_vec.S create mode 100644 arch/mips/kernel/smp-bmips.c diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index e7587ac..9c4a610 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1986,6 +1986,9 @@ config CPU_HAS_SMARTMIPS config CPU_HAS_WB bool +config XKS01 + bool + # # Vectored interrupt mode is an R2 feature # diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 1a96618..0198321 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -58,6 +58,7 @@ obj-$(CONFIG_CPU_XLR) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SMP_UP) += smp-up.o +obj-$(CONFIG_CPU_BMIPS) += smp-bmips.o bmips_vec.o obj-$(CONFIG_MIPS_MT) += mips-mt.o obj-$(CONFIG_MIPS_MT_FPAFF) += mips-mt-fpaff.o diff --git a/arch/mips/kernel/bmips_vec.S b/arch/mips/kernel/bmips_vec.S new file mode 100644 index 0000000..fd7e0f4 --- /dev/null +++ b/arch/mips/kernel/bmips_vec.S @@ -0,0 +1,254 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2011 by Kevin Cernekee (cernekee@gmail.com) + * + * Reset/NMI/re-entry vectors for BMIPS processors + */ + +#include <linux/init.h> + +#include <asm/asm.h> +#include <asm/asmmacro.h> +#include <asm/cacheops.h> +#include <asm/regdef.h> +#include <asm/mipsregs.h> +#include <asm/stackframe.h> +#include <asm/addrspace.h> +#include <asm/bmips.h> + + .macro BARRIER + .set mips32 + ssnop + ssnop + ssnop + .set mips0 + .endm + + __CPUINIT + +/*********************************************************************** + * Alternate CPU1 startup vector for BMIPS4350 + * + * On some systems the bootloader has already started CPU1 and configured + * it to resume execution at 0x8000_0200 (!BEV IV vector) when it is + * triggered by the SW1 interrupt. If that is the case we try to move + * it to a more convenient place: BMIPS_WARM_RESTART_VEC @ 0x8000_0380. + ***********************************************************************/ + +LEAF(bmips_smp_movevec) + la k0, 1f + li k1, CKSEG1 + or k0, k1 + jr k0 + +1: + /* clear IV, pending IPIs */ + mtc0 zero, CP0_CAUSE + + /* re-enable IRQs to wait for SW1 */ + li k0, ST0_IE | ST0_BEV | STATUSF_IP1 + mtc0 k0, CP0_STATUS + + /* set up CPU1 CBR; move BASE to 0xa000_0000 */ + li k0, 0xff400000 + mtc0 k0, $22, 6 + li k1, CKSEG1 | BMIPS_RELO_VECTOR_CONTROL_1 + or k0, k1 + li k1, 0xa0080000 + sw k1, 0(k0) + + /* wait here for SW1 interrupt from bmips_boot_secondary() */ + wait + + la k0, bmips_reset_nmi_vec + li k1, CKSEG1 + or k0, k1 + jr k0 +END(bmips_smp_movevec) + +/*********************************************************************** + * Reset/NMI vector + * For BMIPS processors that can relocate their exception vectors, this + * entire function gets copied to 0x8000_0000. + ***********************************************************************/ + +NESTED(bmips_reset_nmi_vec, PT_SIZE, sp) + .set push + .set noat + .align 4 + +#ifdef CONFIG_SMP + /* if the NMI bit is clear, assume this is a CPU1 reset instead */ + li k1, (1 << 19) + mfc0 k0, CP0_STATUS + and k0, k1 + beqz k0, bmips_smp_entry + +#if defined(CONFIG_CPU_BMIPS5000) + /* 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 +#endif /* CONFIG_SMP */ + + /* nope, it's just a regular NMI */ + SAVE_ALL + move a0, sp + + /* clear EXL, ERL, BEV so that TLB refills still work */ + mfc0 k0, CP0_STATUS + li k1, ST0_ERL | ST0_EXL | ST0_BEV | ST0_IE + or k0, k1 + xor k0, k1 + mtc0 k0, CP0_STATUS + BARRIER + + /* jump to the NMI handler function */ + la k0, nmi_handler + jr k0 + + RESTORE_ALL + .set mips3 + eret + +/*********************************************************************** + * CPU1 reset vector (used for the initial boot only) + * This is still part of bmips_reset_nmi_vec(). + ***********************************************************************/ + +#ifdef CONFIG_SMP + +bmips_smp_entry: + + /* set up CP0 STATUS; enable FPU */ + li k0, 0x30000000 + mtc0 k0, CP0_STATUS + BARRIER + + /* set local CP0 CONFIG to make kseg0 cacheable, write-back */ + mfc0 k0, CP0_CONFIG + ori k0, 0x07 + xori k0, 0x04 + mtc0 k0, CP0_CONFIG + +#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380) + /* initialize CPU1's local I-cache */ + li k0, 0x80000000 + li k1, 0x80010000 + mtc0 zero, $28 + mtc0 zero, $28, 1 + BARRIER + +1: cache Index_Store_Tag_I, 0(k0) + addiu k0, 16 + bne k0, k1, 1b +#elif defined(CONFIG_CPU_BMIPS5000) + /* set exception vector base */ + la k0, ebase + lw k0, 0(k0) + mtc0 k0, $15, 1 + BARRIER +#endif + + /* jump back to kseg0 in case we need to remap the kseg1 area */ + la k0, 1f + jr k0 +1: + la k0, bmips_enable_xks01 + jalr k0 + + /* use temporary stack to set up upper memory TLB */ + li sp, BMIPS_WARM_RESTART_VEC + la k0, plat_wired_tlb_setup + jalr k0 + + /* switch to permanent stack and continue booting */ + + .global bmips_secondary_reentry +bmips_secondary_reentry: + la k0, bmips_smp_boot_sp + lw sp, 0(k0) + la k0, bmips_smp_boot_gp + lw gp, 0(k0) + la k0, start_secondary + jr k0 + +#endif /* CONFIG_SMP */ + + .align 4 + .global bmips_reset_nmi_vec_end +bmips_reset_nmi_vec_end: + +END(bmips_reset_nmi_vec) + + .set pop + .previous + +/*********************************************************************** + * CPU1 warm restart vector (used for second and subsequent boots). + * Also used for S2 standby recovery (PM). + * This entire function gets copied to (BMIPS_WARM_RESTART_VEC) + ***********************************************************************/ + +LEAF(bmips_smp_int_vec) + + .align 4 + mfc0 k0, CP0_STATUS + ori k0, 0x01 + xori k0, 0x01 + mtc0 k0, CP0_STATUS + eret + + .align 4 + .global bmips_smp_int_vec_end +bmips_smp_int_vec_end: + +END(bmips_smp_int_vec) + +/*********************************************************************** + * XKS01 support + * Certain CPUs support extending kseg0 to 1024MB. + ***********************************************************************/ + + __CPUINIT + +LEAF(bmips_enable_xks01) + +#if defined(CONFIG_XKS01) + +#if defined(CONFIG_CPU_BMIPS4380) + mfc0 t0, $22, 3 + li t1, 0x1ff0 + li t2, (1 << 12) | (1 << 9) + or t0, t1 + xor t0, t1 + or t0, t2 + mtc0 t0, $22, 3 + BARRIER +#elif defined(CONFIG_CPU_BMIPS5000) + mfc0 t0, $22, 5 + li t1, 0x01ff + li t2, (1 << 8) | (1 << 5) + or t0, t1 + xor t0, t1 + or t0, t2 + mtc0 t0, $22, 5 + BARRIER +#else + +#error Missing XKS01 setup + +#endif + +#endif /* defined(CONFIG_XKS01) */ + + jr ra + +END(bmips_enable_xks01) + + .previous diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c new file mode 100644 index 0000000..bbcdd51 --- /dev/null +++ b/arch/mips/kernel/smp-bmips.c @@ -0,0 +1,457 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2011 by Kevin Cernekee (cernekee@gmail.com) + * + * SMP support for BMIPS + */ + +#include <linux/version.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <linux/delay.h> +#include <linux/smp.h> +#include <linux/interrupt.h> +#include <linux/spinlock.h> +#include <linux/init.h> +#include <linux/cpu.h> +#include <linux/cpumask.h> +#include <linux/reboot.h> +#include <linux/io.h> +#include <linux/compiler.h> +#include <linux/linkage.h> +#include <linux/bug.h> + +#include <asm/time.h> +#include <asm/pgtable.h> +#include <asm/processor.h> +#include <asm/system.h> +#include <asm/bootinfo.h> +#include <asm/pmon.h> +#include <asm/cacheflush.h> +#include <asm/tlbflush.h> +#include <asm/mipsregs.h> +#include <asm/bmips.h> +#include <asm/traps.h> +#include <asm/barrier.h> + +static int __maybe_unused max_cpus = 1; + +/* these may be configured by the platform code */ +int bmips_smp_enabled = 1; +int bmips_cpu_offset; +cpumask_t bmips_booted_mask; + +#ifdef CONFIG_SMP + +/* initial $sp, $gp - used by arch/mips/kernel/bmips_vec.S */ +unsigned long bmips_smp_boot_sp; +unsigned long bmips_smp_boot_gp; + +static void bmips_send_ipi_single(int cpu, unsigned int action); +static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id); + +/* SW interrupts 0,1 are used for interprocessor signaling */ +#define IPI0_IRQ (MIPS_CPU_IRQ_BASE + 0) +#define IPI1_IRQ (MIPS_CPU_IRQ_BASE + 1) + +#define CPUNUM(cpu, shift) (((cpu) + bmips_cpu_offset) << (shift)) +#define ACTION_CLR_IPI(cpu, ipi) (0x2000 | CPUNUM(cpu, 9) | ((ipi) << 8)) +#define ACTION_SET_IPI(cpu, ipi) (0x3000 | CPUNUM(cpu, 9) | ((ipi) << 8)) +#define ACTION_BOOT_THREAD(cpu) (0x08 | CPUNUM(cpu, 0)) + +static void __init bmips_smp_setup(void) +{ + int i; + +#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); + + /* + * 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 + */ + change_c0_brcm_cmt_intr(0xf8018000, + (0x02 << 27) | (0x03 << 15)); + + /* 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); + + /* 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; + + /* this can be overridden by the BSP */ + if (!board_ebase_setup) + board_ebase_setup = &bmips_ebase_setup; + + for (i = 0; i < max_cpus; i++) { + __cpu_number_map[i] = 1; + __cpu_logical_map[i] = 1; + set_cpu_possible(i, 1); + set_cpu_present(i, 1); + } +} + +/* + * IPI IRQ setup - runs on CPU0 + */ +static void bmips_prepare_cpus(unsigned int max_cpus) +{ + if (request_irq(IPI0_IRQ, bmips_ipi_interrupt, IRQF_PERCPU, + "smp_ipi0", NULL)) + panic("Can't request IPI0 interrupt\n"); + if (request_irq(IPI1_IRQ, bmips_ipi_interrupt, IRQF_PERCPU, + "smp_ipi1", NULL)) + panic("Can't request IPI1 interrupt\n"); +} + +/* + * Tell the hardware to boot CPUx - runs on CPU0 + */ +static void bmips_boot_secondary(int cpu, struct task_struct *idle) +{ + bmips_smp_boot_sp = __KSTK_TOS(idle); + bmips_smp_boot_gp = (unsigned long)task_thread_info(idle); + mb(); + + /* + * Initial boot sequence for secondary CPU: + * bmips_reset_nmi_vec @ a000_0000 -> + * bmips_smp_entry -> + * plat_wired_tlb_setup (cached function call; optional) -> + * start_secondary (cached jump) + * + * Warm restart sequence: + * play_dead WAIT loop -> + * bmips_smp_int_vec @ BMIPS_WARM_RESTART_VEC -> + * eret to play_dead -> + * bmips_secondary_reentry -> + * start_secondary + */ + + printk(KERN_INFO "SMP: Booting CPU%d...\n", cpu); + + if (cpumask_test_cpu(cpu, &bmips_booted_mask)) + bmips_send_ipi_single(cpu, 0); + else { +#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380) + 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); + } +#endif + cpumask_set_cpu(cpu, &bmips_booted_mask); + } +} + +/* + * Early setup - runs on secondary CPU after cache probe + */ +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)); + + write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); +#endif + + /* make sure there won't be a timer interrupt for a little while */ + write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ); + + irq_enable_hazard(); + set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ1 | IE_IRQ5 | ST0_IE); + irq_enable_hazard(); +} + +/* + * Late setup - runs on secondary CPU before entering the idle loop + */ +static void bmips_smp_finish(void) +{ + printk(KERN_INFO "SMP: CPU%d is running\n", smp_processor_id()); +} + +/* + * Runs on CPU0 after all CPUs have been booted + */ +static void bmips_cpus_done(void) +{ +} + +#if defined(CONFIG_CPU_BMIPS5000) + +/* + * BMIPS5000 raceless IPIs + * + * Each CPU has two inbound SW IRQs which are independent of all other CPUs. + * IPI0 is used for SMP_RESCHEDULE_YOURSELF + * IPI1 is used for SMP_CALL_FUNCTION + */ + +static void bmips_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) +{ + int action = irq - IPI0_IRQ; + + write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), action)); + + if (action == 0) + scheduler_ipi(); + else + smp_call_function_interrupt(); + + return IRQ_HANDLED; +} + +#else + +/* + * BMIPS43xx racey IPIs + * + * We use one inbound SW IRQ for each CPU. + * + * A spinlock must be held in order to keep CPUx from accidentally clearing + * an incoming IPI when it writes CP0 CAUSE to raise an IPI on CPUy. The + * same spinlock is used to protect the action masks. + */ + +static DEFINE_SPINLOCK(ipi_lock); +static DEFINE_PER_CPU(int, ipi_action_mask); + +static void bmips_send_ipi_single(int cpu, unsigned int action) +{ + unsigned long flags; + + spin_lock_irqsave(&ipi_lock, flags); + set_c0_cause(cpu ? C_SW1 : C_SW0); + per_cpu(ipi_action_mask, cpu) |= action; + irq_enable_hazard(); + spin_unlock_irqrestore(&ipi_lock, flags); +} + +static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id) +{ + unsigned long flags; + int action, cpu = irq - IPI0_IRQ; + + spin_lock_irqsave(&ipi_lock, flags); + action = __get_cpu_var(ipi_action_mask); + per_cpu(ipi_action_mask, cpu) = 0; + clear_c0_cause(cpu ? C_SW1 : C_SW0); + spin_unlock_irqrestore(&ipi_lock, flags); + + if (action & SMP_RESCHEDULE_YOURSELF) + scheduler_ipi(); + if (action & SMP_CALL_FUNCTION) + smp_call_function_interrupt(); + + return IRQ_HANDLED; +} + +#endif /* BMIPS type */ + +static void bmips_send_ipi_mask(const struct cpumask *mask, + unsigned int action) +{ + unsigned int i; + + for_each_cpu(i, mask) + bmips_send_ipi_single(i, action); +} + +#ifdef CONFIG_HOTPLUG_CPU + +static int bmips_cpu_disable(void) +{ + unsigned int cpu = smp_processor_id(); + + if (cpu == 0) + return -EBUSY; + + printk(KERN_INFO "SMP: CPU%d is offline\n", cpu); + + cpu_clear(cpu, cpu_online_map); + cpu_clear(cpu, cpu_callin_map); + + local_flush_tlb_all(); + local_flush_icache_range(0, ~0); + + return 0; +} + +static void bmips_cpu_die(unsigned int cpu) +{ +} + +void __ref play_dead(void) +{ + idle_task_exit(); + + /* flush data cache */ + _dma_cache_wback_inv(0, ~0); + + /* + * Wakeup is on SW0 or SW1; disable everything else + * Use BEV !IV (BMIPS_WARM_RESTART_VEC) to avoid the regular Linux + * IRQ handlers; this clears ST0_IE and returns immediately. + */ + clear_c0_cause(CAUSEF_IV | C_SW0 | C_SW1); + change_c0_status(IE_IRQ5 | IE_IRQ1 | IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV, + IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV); + irq_disable_hazard(); + + /* + * wait for SW interrupt from bmips_boot_secondary(), then jump + * back to start_secondary() + */ + __asm__ __volatile__( + " wait\n" + " j bmips_secondary_reentry\n" + : : : "memory"); +} + +#endif /* CONFIG_HOTPLUG_CPU */ + +struct plat_smp_ops bmips_smp_ops = { + .smp_setup = bmips_smp_setup, + .prepare_cpus = bmips_prepare_cpus, + .boot_secondary = bmips_boot_secondary, + .smp_finish = bmips_smp_finish, + .init_secondary = bmips_init_secondary, + .cpus_done = bmips_cpus_done, + .send_ipi_single = bmips_send_ipi_single, + .send_ipi_mask = bmips_send_ipi_mask, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_disable = bmips_cpu_disable, + .cpu_die = bmips_cpu_die, +#endif +}; + +#endif /* CONFIG_SMP */ + +/*********************************************************************** + * BMIPS vector relocation + * This is primarily used for SMP boot, but it is applicable to some + * UP BMIPS systems as well. + ***********************************************************************/ + +static void __cpuinit bmips_wr_vec(unsigned long dst, char *start, char *end) +{ + memcpy((void *)dst, start, end - start); + dma_cache_wback((unsigned long)start, end - start); + local_flush_icache_range(dst, dst + (end - start)); + instruction_hazard(); +} + +static inline void __cpuinit bmips_nmi_handler_setup(void) +{ + bmips_wr_vec(BMIPS_NMI_RESET_VEC, &bmips_reset_nmi_vec, + &bmips_reset_nmi_vec_end); + bmips_wr_vec(BMIPS_WARM_RESTART_VEC, &bmips_smp_int_vec, + &bmips_smp_int_vec_end); +} + +void __cpuinit bmips_ebase_setup(void) +{ + unsigned long new_ebase = ebase; + void __iomem __maybe_unused *cbr; + + 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 + board_nmi_handler_setup = &bmips_nmi_handler_setup; + ebase = new_ebase; +} + +asmlinkage void __weak plat_wired_tlb_setup(void) +{ + /* + * Called when starting/restarting a secondary CPU. + * Kernel stacks and other important data might only be accessible + * once the wired entries are present. + */ +} -- 1.7.6.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH V2 8/8] MIPS: BMIPS: Add SMP support code for BMIPS43xx/BMIPS5000 2011-11-11 6:30 ` [PATCH V2 8/8] MIPS: BMIPS: Add SMP support code for BMIPS43xx/BMIPS5000 Kevin Cernekee @ 2011-11-11 18:05 ` Ralf Baechle 2011-11-12 14:31 ` Florian Fainelli 1 sibling, 0 replies; 24+ messages in thread From: Ralf Baechle @ 2011-11-11 18:05 UTC (permalink / raw) To: Kevin Cernekee; +Cc: linux-mips Dropped; using the replacement you sent. Ralf ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH V2 8/8] MIPS: BMIPS: Add SMP support code for BMIPS43xx/BMIPS5000 2011-11-11 6:30 ` [PATCH V2 8/8] MIPS: BMIPS: Add SMP support code for BMIPS43xx/BMIPS5000 Kevin Cernekee 2011-11-11 18:05 ` Ralf Baechle @ 2011-11-12 14:31 ` Florian Fainelli 2011-11-12 16:07 ` Kevin Cernekee 1 sibling, 1 reply; 24+ messages in thread From: Florian Fainelli @ 2011-11-12 14:31 UTC (permalink / raw) To: Kevin Cernekee; +Cc: Ralf Baechle, linux-mips Hello Kevin, Le vendredi 11 novembre 2011 07:30:31, Kevin Cernekee a écrit : > Initial commit of BMIPS SMP support code. Smoke-tested on a variety of > BMIPS4350, BMIPS4380, and BMIPS5000 platforms. > > Signed-off-by: Kevin Cernekee <cernekee@gmail.com> > --- > > V2: > > Move XKS01 option into this patch. > > Remove dependency on local_flush_tlb_all_mm(), per the discussion > earlier this week. > > Allow platform-configurable variables to be accessed in !CONFIG_SMP > mode, so the platform code does not need unnecessary #ifdefs. > > Remove the code that clears the FPU registers. > > Fix the jump to the NMI vector. > > Add bmips_cpu_offset. I have two questions regarding this patchset: - considering that BMIPS4350 has a shared TLB, is it still working fine? I must say that I have not yet tested on e.g: BCM6358 - there a couple of places in the code where we have: #if defined (CONFIG_BMIPS_4350) || defined (CONFIG_BMIPS_4380) ... do something #elif defined(CONFIG_BMIPS_4380) can we turn this into a #if BMIPS43xx case .. #endif #if BMIPS5000 ... #endif to allow a single image supporting both BMIPS43xx and BMIPS5000? By the time we are initializing the CPUs for SMP, we should be able to use runtime checks on the BMIPS CPU variant. Thanks. -- Florian ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH V2 8/8] MIPS: BMIPS: Add SMP support code for BMIPS43xx/BMIPS5000 2011-11-12 14:31 ` Florian Fainelli @ 2011-11-12 16:07 ` Kevin Cernekee 0 siblings, 0 replies; 24+ messages in thread From: Kevin Cernekee @ 2011-11-12 16:07 UTC (permalink / raw) To: Florian Fainelli, Ralf Baechle; +Cc: linux-mips On Sat, Nov 12, 2011 at 6:31 AM, Florian Fainelli <ffainelli@freebox.fr> wrote: > - considering that BMIPS4350 has a shared TLB, is it still working fine? I must > say that I have not yet tested on e.g: BCM6358 BCM6368 (which I did test) has a private TLB for each thread. I have not tested any of the shared TLB chips. It is possible that more work will be required to cover the shared TLB case. > - there a couple of places in the code where we have: > > #if defined (CONFIG_BMIPS_4350) || defined (CONFIG_BMIPS_4380) > ... do something > #elif defined(CONFIG_BMIPS_4380) > > can we turn this into a #if BMIPS43xx case .. #endif #if BMIPS5000 ... #endif > to allow a single image supporting both BMIPS43xx and BMIPS5000? Although it would be easy to check current_cpu_type() for the cases in smp-bmips.c, there are other decisions (not in this patchset) that are harder to make at runtime. One obvious case is cpu-feature-overrides.h; other cases include low-level code sequences in the exception vectors, power management standby/resume/reentry assembly code, HIGHMEM and cache configuration, memory map, etc. Side note: one of Ralf's earlier comments on this patch was a request to use pr_info() instead of printk(). This somehow fell off my TODO list. I will fix it and submit V4 later today. ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH V2 1/8] MIPS: BMIPS: Fix up Kconfig settings 2011-11-11 6:30 [PATCH V2 1/8] MIPS: BMIPS: Fix up Kconfig settings Kevin Cernekee ` (6 preceding siblings ...) 2011-11-11 6:30 ` [PATCH V2 8/8] MIPS: BMIPS: Add SMP support code for BMIPS43xx/BMIPS5000 Kevin Cernekee @ 2011-11-11 18:03 ` Ralf Baechle 7 siblings, 0 replies; 24+ messages in thread From: Ralf Baechle @ 2011-11-11 18:03 UTC (permalink / raw) To: Kevin Cernekee; +Cc: linux-mips Queued for 3.3. Thanks, Ralf ^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2011-11-12 16:07 UTC | newest] Thread overview: 24+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-11-11 6:30 [PATCH V2 1/8] MIPS: BMIPS: Fix up Kconfig settings Kevin Cernekee 2011-11-11 6:30 ` [PATCH V2 2/8] MIPS: Clean up whitespace warning in hazards.h Kevin Cernekee 2011-11-11 18:03 ` Ralf Baechle 2011-11-11 6:30 ` [PATCH V2 3/8] MIPS: BMIPS: Add CFLAGS, Makefile entries for BMIPS Kevin Cernekee 2011-11-11 12:58 ` Ralf Baechle 2011-11-11 16:57 ` Kevin Cernekee 2011-11-11 17:20 ` Ralf Baechle 2011-11-12 14:11 ` Florian Fainelli 2011-11-11 18:03 ` Ralf Baechle 2011-11-11 6:30 ` [PATCH V2 4/8] MIPS: BMIPS: Add set/clear CP0 macros for BMIPS operations Kevin Cernekee 2011-11-11 18:04 ` Ralf Baechle 2011-11-11 6:30 ` [PATCH V2 5/8] MIPS: BMIPS: Introduce bmips.h Kevin Cernekee 2011-11-11 13:32 ` Ralf Baechle 2011-11-11 18:04 ` Ralf Baechle 2011-11-11 6:30 ` [PATCH V2 6/8] MIPS: Add NMI notifier Kevin Cernekee 2011-11-11 13:34 ` Ralf Baechle 2011-11-11 18:04 ` Ralf Baechle 2011-11-11 6:30 ` [PATCH V2 7/8] MIPS: Add board_ebase_setup() Kevin Cernekee 2011-11-11 18:05 ` Ralf Baechle 2011-11-11 6:30 ` [PATCH V2 8/8] MIPS: BMIPS: Add SMP support code for BMIPS43xx/BMIPS5000 Kevin Cernekee 2011-11-11 18:05 ` Ralf Baechle 2011-11-12 14:31 ` Florian Fainelli 2011-11-12 16:07 ` Kevin Cernekee 2011-11-11 18:03 ` [PATCH V2 1/8] MIPS: BMIPS: Fix up Kconfig settings Ralf Baechle
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.