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).
Maciej
patch-mips-2.6.12-rc4-20050526-tlbex-r4600-0
diff -up --recursive --new-file
linux-mips-2.6.12-rc4-20050526.macro/arch/mips/mm/tlbex.c
linux-mips-2.6.12-rc4-20050526/arch/mips/mm/tlbex.c
--- 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
i_nop(p);
break;
- 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: