[Top] [All Lists]

Re: 2.6 on IP22 (Indy)

To: Markus Dahms <>
Subject: Re: 2.6 on IP22 (Indy)
From: "Maciej W. Rozycki" <>
Date: Tue, 28 Jun 2005 10:05:30 +0100 (BST)
In-reply-to: <>
Original-recipient: rfc822;
References: <> <> <> <> <>
On Tue, 28 Jun 2005, Markus Dahms wrote:

> | CPU revision is: 00000430
> | FPU revision is: 00000500
> | ...
> | Checking for the multiply/shift bug... yes, workaround... no.
> | kernel panic - not syncing: Reliable operation impossible!
> | Configure for R4000 to enable the workaround.
> I configured the kernel for R4X00. There are a few references to
> CONFIG_CPU_R4000 in the source which doesn't seem to be a config
> option anymore, but I couldn't find a workaround somewhere...

 Well, yesterday evening I realized you mentioned the R4000 which has 
currently no way to run in the 64-bit mode with upstream Linux as there 
are grave errata in the CPU (in a couple of 64-bit instructions) that 
prevent reliable operation.  And I mean it -- with no workarounds enabled 
all I observed with my R4000 in my DECstation were random lock-ups, 
sometimes even before reaching userland (depending on stuff like cache 
alignment of some code with a given compilation).

 I implemented all the necessary workarounds and this includes Linux, GCC 
and binutils (further bits are needed for handcoded assembly programs if 
you want to run n32 or (n)64 userland; so far I've identified and fixed 
glibc and gmp).  If you'd like to use this system in the 64-bit mode you 
are most welcomed.  For this you can get toolchain bits from my site and I 
can supply you with a patch for Linux 2.4; I'll work on porting it to 2.6 
and actually applying upstream soon.

 As you may not be interested in binary RPM packages, you may just pull 
the necessary patches, which are all called "*-mips-nodaddi-*" and you 
have to make sure to rebuild all 64-bit binaries to be run on the R4000 
with either "-march=r4000" or "-mfix-r4000".  Unfortunately at the current 
state of affairs the GCC patch is not going to be accepted for inclusion 
upstream which means all the others have to live outside their respective 
official sources as well.

 I have successfully run 64-bit Linux on my R4000SC and early R4400SC 
which are both affected by these errata (but not exactly the same for both 
;-) ) for quite some time now.

 I have actually forgotten to mention you might indeed want to try a 
32-bit kernel as some low level bits differ and this is especially true 
given the above -- sorry about that.

> >> I'll also try the said patch (you're referring to "blast_scache nop ...",
> >> do you?).
> > Precisely.
> doesn't change anything, neither for R4000PC nor for R4600PC.

 Well, the R4600 case was easy -- proofreading revealed the bug.  There is 
a cp0 hazard between updating a TLB entry and using it for an instruction 
fetch and for the R4600 it requires two instructions to clear.  
Unfortunately our handlers currently only execute a lone "eret" after TLB 
update instructions, which for TLB faults on instruction fetches triggers 
this hazard.  For data transfers there is no hazard in the R4600 and this 
is why your system has been able to progress through `init'; otherwise you 
would not see any output from it.

 Here's a patch.  I'm inclined to apply it as obviously correct but I'll 
resist for a while to let you provide some feedback.  The same hazard 
conditions are present for the R4700 and the R5000.  I've included the 
R5000A as well which, given the name, I've assumed was just a minor update 
to the R5000; anyone please correct me if I am wrong (but we don't ever 
use this CPU ID in Linux, so that would be for documentation only).


diff -up --recursive --new-file 
--- linux-mips-2.6.12-rc4-20050526.macro/arch/mips/mm/tlbex.c   2005-04-29 
04:56:05.000000000 +0000
+++ linux-mips-2.6.12-rc4-20050526/arch/mips/mm/tlbex.c 2005-06-28 
01:14:39.000000000 +0000
@@ -828,11 +828,16 @@ static __init void build_tlb_write_entry
-       case CPU_R4300:
        case CPU_R4600:
        case CPU_R4700:
        case CPU_R5000:
        case CPU_R5000A:
+               i_nop(p);
+               tlbw(p);
+               i_nop(p);
+               break;
+       case CPU_R4300:
        case CPU_5KC:
        case CPU_TX49XX:
        case CPU_AU1000:

<Prev in Thread] Current Thread [Next in Thread>