linux-mips
[Top] [All Lists]

[PATCH] MIPS: check for R5k XKPHYS bug

To: linux-mips@linux-mips.org
Subject: [PATCH] MIPS: check for R5k XKPHYS bug
From: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Date: Sat, 2 May 2009 13:00:55 +0200 (CEST)
Cc: ralf@linux-mips.org
Original-recipient: rfc822;linux-mips@linux-mips.org
Sender: linux-mips-bounce@linux-mips.org
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@alpha.franken.de>
---

 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)

<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH] MIPS: check for R5k XKPHYS bug, Thomas Bogendoerfer <=