[PATCH] MIPS: check for R5k XKPHYS bug

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



R5k CPUs have a bug, where ll access to XKPHYS addresses don't work.
Check for this bug and enable workaround, if possible.

Signed-off-by: Thomas Bogendoerfer <tsbogend@xxxxxxxxxxxxxxxx>
---

 arch/mips/kernel/cpu-bugs64.c |   36 ++++++++++++++++++++++++++++++++++++
 1 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c
index 02b7713..8e55649 100644
--- a/arch/mips/kernel/cpu-bugs64.c
+++ b/arch/mips/kernel/cpu-bugs64.c
@@ -26,6 +26,8 @@ static char r4kwar[] __initdata =
 	"Enable CPU_R4000_WORKAROUNDS to rectify.";
 static char daddiwar[] __initdata =
 	"Enable CPU_DADDI_WORKAROUNDS to rectify.";
+static char xkphysllwar[] __initdata =
+	"CPU has ll xkphys bug.";
 
 static inline void align_mod(const int align, const int mod)
 {
@@ -307,10 +309,44 @@ static inline void check_daddiu(void)
 	panic(bug64hit, !DADDI_WAR ? daddiwar : nowar);
 }
 
+static u32 ll(u32 *p)
+{
+	u32 ret;
+
+	asm volatile(
+		"ll    %0, %1\n\t"
+		: "=&r" (ret)
+		: "m" (*p));
+
+	return ret;
+}
+
+void __init check_ll_xkphys(void)
+{
+	static u32 val;
+	u32 *p = (u32 *)PHYS_TO_XKPHYS(K_CALG_NONCOHERENT,
+				       CPHYSADDR((unsigned long)&val));
+
+	printk("Checking for the ll/lld xkphys bug... ");
+	memset(p, 0xff, sizeof(val));
+	if (ll(p) != 0xffffffff) {
+		printk("yes, enabling workaround... ");
+		cpu_data[0].options &= ~MIPS_CPU_LLSC;
+		if (cpu_has_llsc != (cpu_data[0].options & MIPS_CPU_LLSC)) {
+			printk("failed.\n");
+			panic(bug64hit, xkphysllwar);
+		}
+		printk("ok.\n");
+	} else
+		printk("no.\n");
+}
+
+
 void __init check_bugs64_early(void)
 {
 	check_mult_sh();
 	check_daddiu();
+	check_ll_xkphys();
 }
 
 void __init check_bugs64(void)


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux