Received: from mail.onstor.com (66.201.51.107) by exch1.onstor.net
 (10.0.0.225) with Microsoft SMTP Server id 8.1.311.2; Sat, 2 May 2009
 04:01:46 -0700
Received: from psmtp.com ([64.18.0.72]) by mail.onstor.com with Microsoft
 SMTPSVC(6.0.3790.3959);	 Sat, 2 May 2009 04:01:45 -0700
Received: from source ([213.58.128.207]) by exprod5mx213.postini.com
 ([64.18.4.11]) with SMTP;	Sat, 02 May 2009 04:01:45 PDT
Received: from localhost.localdomain ([127.0.0.1]:43691 "EHLO
	ftp.linux-mips.org" rhost-flags-OK-OK-OK-FAIL) by ftp.linux-mips.org	with
 ESMTP id S20024955AbZEBLB1 (ORCPT	<rfc822;andy.sharp@onstor.com>); Sat, 2 May
 2009 12:01:27 +0100
Received: with ECARTIS (v1.0.0; list linux-mips); Sat, 02 May 2009 12:01:10
 +0100 (BST)
Received: from elvis.franken.de ([193.175.24.41]:56050 "EHLO elvis.franken.de"
	rhost-flags-OK-OK-OK-OK) by ftp.linux-mips.org with ESMTP	id
 S20024943AbZEBLBC (ORCPT <rfc822;linux-mips@linux-mips.org>);	Sat, 2 May 2009
 12:01:02 +0100
Received: from uucp (helo=solo.franken.de)	by elvis.franken.de with
 local-bsmtp (Exim 3.36 #1)	id 1M0Cxo-0004VQ-00; Sat, 02 May 2009 13:01:00
 +0200
Received: by solo.franken.de (Postfix, from userid 1000)	id 8B62AC2D1B; Sat,
  2 May 2009 13:00:55 +0200 (CEST)
From: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
To: "linux-mips@linux-mips.org" <linux-mips@linux-mips.org>
CC: "ralf@linux-mips.org" <ralf@linux-mips.org>
Sender: "linux-mips-bounce@linux-mips.org" <linux-mips-bounce@linux-mips.org>
Date: Sat, 2 May 2009 04:00:55 -0700
Subject: [PATCH] MIPS: check for R5k XKPHYS bug
Thread-Topic: [PATCH] MIPS: check for R5k XKPHYS bug
Thread-Index: AcnLFWM+9SP49sORT5euyMELDkDpow==
Message-ID: <20090502110055.8B62AC2D1B@solo.franken.de>
Accept-Language: en-US
Content-Language: en-US
X-MS-Exchange-Organization-AuthAs: Internal
X-MS-Exchange-Organization-AuthMechanism: 0b
X-MS-Exchange-Organization-AuthSource: exch1.onstor.net
X-MS-Has-Attach:
X-Auto-Response-Suppress: All
X-MS-TNEF-Correlator:
x-originalarrivaltime: 02 May 2009 11:01:45.0840 (UTC)
 FILETIME=[62295F00:01C9CB15]
x-ems-stamp: EttgmuXb8CNYMK1k1hOwjA==
x-ems-proccessed: 2K3Xl1OQTInXD6xxuA8z3Q==
errors-to: linux-mips-bounce@linux-mips.org
x-pstn-neptune: 2/1/0.50/69
x-pstn-levels: (S:67.10014/99.90000 CV:99.9000 FC:95.5390 LC:95.5390
 R:95.9108 P:95.9108 M:97.0282 C:98.6951 )
x-list: linux-mips
x-archive-position: 22600
x-ecartis-version: Ecartis v1.0.0
x-original-sender: tsbogend@alpha.franken.de
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0

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 =3D
 	"Enable CPU_R4000_WORKAROUNDS to rectify.";
 static char daddiwar[] __initdata =3D
 	"Enable CPU_DADDI_WORKAROUNDS to rectify.";
+static char xkphysllwar[] __initdata =3D
+	"CPU has ll xkphys bug.";
=20
 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);
 }
=20
+static u32 ll(u32 *p)
+{
+	u32 ret;
+
+	asm volatile(
+		"ll    %0, %1\n\t"
+		: "=3D&r" (ret)
+		: "m" (*p));
+
+	return ret;
+}
+
+void __init check_ll_xkphys(void)
+{
+	static u32 val;
+	u32 *p =3D (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) !=3D 0xffffffff) {
+		printk("yes, enabling workaround... ");
+		cpu_data[0].options &=3D ~MIPS_CPU_LLSC;
+		if (cpu_has_llsc !=3D (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();
 }
=20
 void __init check_bugs64(void)

