linux/arch/mips/include/asm/war.h

74 lines
2.2 KiB
C
Raw Normal View History

/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2002, 2004, 2007 by Ralf Baechle
[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>
2007-10-23 12:43:11 +01:00
* Copyright (C) 2007 Maciej W. Rozycki
*/
#ifndef _ASM_WAR_H
#define _ASM_WAR_H
[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>
2007-10-23 12:43:11 +01:00
/*
* Work around certain R4000 CPU errata (as implemented by GCC):
*
* - A double-word or a variable shift may give an incorrect result
* if executed immediately after starting an integer division:
* "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0",
* erratum #28
* "MIPS R4000MC Errata, Processor Revision 2.2 and 3.0", erratum
* #19
*
* - A double-word or a variable shift may give an incorrect result
* if executed while an integer multiplication is in progress:
* "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0",
* errata #16 & #28
*
* - An integer division may give an incorrect result if started in
* a delay slot of a taken branch or a jump:
* "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0",
* erratum #52
*/
#ifdef CONFIG_CPU_R4000_WORKAROUNDS
#define R4000_WAR 1
#else
#define R4000_WAR 0
#endif
/*
* Work around certain R4400 CPU errata (as implemented by GCC):
*
* - A double-word or a variable shift may give an incorrect result
* if executed immediately after starting an integer division:
* "MIPS R4400MC Errata, Processor Revision 1.0", erratum #10
* "MIPS R4400MC Errata, Processor Revision 2.0 & 3.0", erratum #4
*/
#ifdef CONFIG_CPU_R4400_WORKAROUNDS
#define R4400_WAR 1
#else
#define R4400_WAR 0
#endif
/*
* Work around the "daddi" and "daddiu" CPU errata:
*
* - The `daddi' instruction fails to trap on overflow.
* "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0",
* erratum #23
*
* - The `daddiu' instruction can produce an incorrect result.
* "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0",
* erratum #41
* "MIPS R4000MC Errata, Processor Revision 2.2 and 3.0", erratum
* #15
* "MIPS R4400PC/SC Errata, Processor Revision 1.0", erratum #7
* "MIPS R4400MC Errata, Processor Revision 1.0", erratum #5
*/
#ifdef CONFIG_CPU_DADDI_WORKAROUNDS
#define DADDI_WAR 1
#else
#define DADDI_WAR 0
#endif
#endif /* _ASM_WAR_H */