On Tue, Nov 04, 2014 at 02:13:23PM +0800, Huacai Chen wrote: > In CPU manual Loongson-3 is MIPS64R2 compatible, but during tests we > found that its EI/DI instructions have problems. So we just set the ISA > level to MIPS64R1. That's a bit a heavyhanded move - it will disable ALL R2 optimizations and feature support - try running git grep -w cpu_has_mips_r2 arch/mips. Also it will cause the kernel to missreport the CPU has R1 or as in case of the Loongson 2 with this patch even as MIPS III which in turn will mean certain programs will fail to detect and exploit the full capabilities of the CPU. Was this really intended? I doubt it. I suggest a bit of a less heavy-handed approach as illustrated in below incomplete patch. Would that work for you? Ralf Signed-off-by: Ralf Baechle <ralf@xxxxxxxxxxxxxx> arch/mips/include/asm/asmmacro.h | 3 ++- arch/mips/include/asm/irqflags.h | 7 ++++--- arch/mips/include/asm/mach-ip22/war.h | 1 + arch/mips/include/asm/mach-loongson/war.h | 1 + arch/mips/include/asm/war.h | 7 +++++++ 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h index 6caf876..d477c34 100644 --- a/arch/mips/include/asm/asmmacro.h +++ b/arch/mips/include/asm/asmmacro.h @@ -11,6 +11,7 @@ #include <asm/hazards.h> #include <asm/asm-offsets.h> #include <asm/msa.h> +#include <asm/war.h> #ifdef CONFIG_32BIT #include <asm/asmmacro-32.h> @@ -19,7 +20,7 @@ #include <asm/asmmacro-64.h> #endif -#ifdef CONFIG_CPU_MIPSR2 +#if defined(CONFIG_CPU_MIPSR2) && !LOONGSON3_EI_DI_WAR .macro local_irq_enable reg=t0 ei irq_enable_hazard diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h index 0fa5fdc..fcfd371 100644 --- a/arch/mips/include/asm/irqflags.h +++ b/arch/mips/include/asm/irqflags.h @@ -16,6 +16,7 @@ #include <linux/compiler.h> #include <linux/stringify.h> #include <asm/hazards.h> +#include <asm/war.h> #ifdef CONFIG_CPU_MIPSR2 @@ -59,7 +60,7 @@ static inline void arch_local_irq_restore(unsigned long flags) " .set push \n" " .set noreorder \n" " .set noat \n" -#if defined(CONFIG_IRQ_CPU) +#if defined(CONFIG_IRQ_CPU) && !LOONGSON3_EI_DI_WAR /* * Slow, but doesn't suffer from a relatively unlikely race * condition we're having since days 1. @@ -89,7 +90,7 @@ static inline void __arch_local_irq_restore(unsigned long flags) " .set push \n" " .set noreorder \n" " .set noat \n" -#if defined(CONFIG_IRQ_CPU) +#if defined(CONFIG_IRQ_CPU) && !LOONGSON3_EI_DI_WAR /* * Slow, but doesn't suffer from a relatively unlikely race * condition we're having since days 1. @@ -126,7 +127,7 @@ static inline void arch_local_irq_enable(void) " .set push \n" " .set reorder \n" " .set noat \n" -#if defined(CONFIG_CPU_MIPSR2) +#if defined(CONFIG_CPU_MIPSR2) && !LOONGSON3_EI_DI_WAR " ei \n" #else " mfc0 $1,$12 \n" diff --git a/arch/mips/include/asm/mach-ip22/war.h b/arch/mips/include/asm/mach-ip22/war.h index fba6405..3520b0a 100644 --- a/arch/mips/include/asm/mach-ip22/war.h +++ b/arch/mips/include/asm/mach-ip22/war.h @@ -18,6 +18,7 @@ #define R5432_CP0_INTERRUPT_WAR 0 #define BCM1250_M3_WAR 0 #define SIBYTE_1956_WAR 0 +#define LOONGSON3_EI_DI_WAR 0 #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 diff --git a/arch/mips/include/asm/mach-loongson/war.h b/arch/mips/include/asm/mach-loongson/war.h index f2570df..cf5385f 100644 --- a/arch/mips/include/asm/mach-loongson/war.h +++ b/arch/mips/include/asm/mach-loongson/war.h @@ -14,6 +14,7 @@ #define R5432_CP0_INTERRUPT_WAR 0 #define BCM1250_M3_WAR 0 #define SIBYTE_1956_WAR 0 +#define LOONGSON3_EI_DI_WAR 1 #define MIPS4K_ICACHE_REFILL_WAR 0 #define MIPS_CACHE_SYNC_WAR 0 #define TX49XX_ICACHE_INDEX_INV_WAR 0 diff --git a/arch/mips/include/asm/war.h b/arch/mips/include/asm/war.h index 9344e24..ceb9030 100644 --- a/arch/mips/include/asm/war.h +++ b/arch/mips/include/asm/war.h @@ -233,4 +233,11 @@ #error Check setting of MIPS34K_MISSED_ITLB_WAR for your platform #endif +/* + * On certain Loongson 3 cores DI/EI don't work properly. + */ +#ifndef LOONGSON3_EI_DI_WAR +#error Check setting of LOONGSON3_EI_DI_WAR for your platform +#endif + #endif /* _ASM_WAR_H */