diff options
author | Maciej W. Rozycki <macro@linux-mips.org> | 2007-10-23 07:43:11 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2008-01-29 05:14:54 -0500 |
commit | 20d60d9973c3b441902b0a3f4f6f7e7ade08f77d (patch) | |
tree | 2dbadcb5600fcb486612ec30d972e6c29195ee1d /include/asm-mips/bugs.h | |
parent | 2b22c034d04d3632a339d14d5803c8f94e412608 (diff) |
[MIPS] R4000/R4400 errata workarounds
This is the gereric part of R4000/R4400 errata workarounds. They include
compiler and assembler support as well as some source code modifications
to address the problems with some combinations of multiply/divide+shift
instructions as well as the daddi and daddiu instructions.
Changes included are as follows:
1. New Kconfig options to select workarounds by platforms as necessary.
2. Arch top-level Makefile to pass necessary options to the compiler; also
incompatible configurations are detected (-mno-sym32 unsupported as
horribly intrusive for little gain).
3. Bug detection updated and shuffled -- the multiply/divide+shift problem
is lethal enough that if not worked around it makes the kernel crash in
time_init() because of a division by zero; the daddiu erratum might
also trigger early potentially, though I have not observed it. On the
other hand the daddi detection code requires the exception subsystem to
have been initialised (and is there mainly for information).
4. r4k_daddiu_bug() added so that the existence of the erratum can be
queried by code at the run time as necessary; useful for generated code
like TLB fault and copy/clear page handlers.
5. __udelay() updated as it uses multiplication in inline assembly.
Note that -mdaddi requires modified toolchain (which has been maintained
by myself and available from my site for ~4years now -- versions covered
are GCC 2.95.4 - 4.1.2 and binutils from 2.13 onwards). The -mfix-r4000
and -mfix-r4400 have been standard for a while though.
Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'include/asm-mips/bugs.h')
-rw-r--r-- | include/asm-mips/bugs.h | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/include/asm-mips/bugs.h b/include/asm-mips/bugs.h index 0d7f9c1f5546..9dc10df32078 100644 --- a/include/asm-mips/bugs.h +++ b/include/asm-mips/bugs.h | |||
@@ -1,19 +1,34 @@ | |||
1 | /* | 1 | /* |
2 | * This is included by init/main.c to check for architecture-dependent bugs. | 2 | * This is included by init/main.c to check for architecture-dependent bugs. |
3 | * | 3 | * |
4 | * Copyright (C) 2007 Maciej W. Rozycki | ||
5 | * | ||
4 | * Needs: | 6 | * Needs: |
5 | * void check_bugs(void); | 7 | * void check_bugs(void); |
6 | */ | 8 | */ |
7 | #ifndef _ASM_BUGS_H | 9 | #ifndef _ASM_BUGS_H |
8 | #define _ASM_BUGS_H | 10 | #define _ASM_BUGS_H |
9 | 11 | ||
12 | #include <linux/bug.h> | ||
10 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
14 | |||
11 | #include <asm/cpu.h> | 15 | #include <asm/cpu.h> |
12 | #include <asm/cpu-info.h> | 16 | #include <asm/cpu-info.h> |
13 | 17 | ||
18 | extern int daddiu_bug; | ||
19 | |||
20 | extern void check_bugs64_early(void); | ||
21 | |||
14 | extern void check_bugs32(void); | 22 | extern void check_bugs32(void); |
15 | extern void check_bugs64(void); | 23 | extern void check_bugs64(void); |
16 | 24 | ||
25 | static inline void check_bugs_early(void) | ||
26 | { | ||
27 | #ifdef CONFIG_64BIT | ||
28 | check_bugs64_early(); | ||
29 | #endif | ||
30 | } | ||
31 | |||
17 | static inline void check_bugs(void) | 32 | static inline void check_bugs(void) |
18 | { | 33 | { |
19 | unsigned int cpu = smp_processor_id(); | 34 | unsigned int cpu = smp_processor_id(); |
@@ -25,4 +40,14 @@ static inline void check_bugs(void) | |||
25 | #endif | 40 | #endif |
26 | } | 41 | } |
27 | 42 | ||
43 | static inline int r4k_daddiu_bug(void) | ||
44 | { | ||
45 | #ifdef CONFIG_64BIT | ||
46 | WARN_ON(daddiu_bug < 0); | ||
47 | return daddiu_bug != 0; | ||
48 | #else | ||
49 | return 0; | ||
50 | #endif | ||
51 | } | ||
52 | |||
28 | #endif /* _ASM_BUGS_H */ | 53 | #endif /* _ASM_BUGS_H */ |