2014-11-14 15:54:09 +00:00
/*
* Contains CPU specific errata definitions
*
* Copyright ( C ) 2014 ARM Ltd .
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include <linux/types.h>
# include <asm/cpu.h>
# include <asm/cputype.h>
# include <asm/cpufeature.h>
2014-11-14 15:54:10 +00:00
static bool __maybe_unused
2016-04-22 12:25:31 +01:00
is_affected_midr_range ( const struct arm64_cpu_capabilities * entry , int scope )
2014-11-14 15:54:10 +00:00
{
2016-04-22 12:25:31 +01:00
WARN_ON ( scope ! = SCOPE_LOCAL_CPU | | preemptible ( ) ) ;
2016-02-02 12:46:24 +00:00
return MIDR_IS_CPU_MODEL_RANGE ( read_cpuid_id ( ) , entry - > midr_model ,
entry - > midr_range_min ,
entry - > midr_range_max ) ;
2014-11-14 15:54:10 +00:00
}
2016-09-09 14:07:16 +01:00
static bool
has_mismatched_cache_line_size ( const struct arm64_cpu_capabilities * entry ,
int scope )
{
WARN_ON ( scope ! = SCOPE_LOCAL_CPU | | preemptible ( ) ) ;
return ( read_cpuid_cachetype ( ) & arm64_ftr_reg_ctrel0 . strict_mask ) ! =
( arm64_ftr_reg_ctrel0 . sys_val & arm64_ftr_reg_ctrel0 . strict_mask ) ;
}
2016-10-18 11:27:46 +01:00
static int cpu_enable_trap_ctr_access ( void * __unused )
2016-09-09 14:07:16 +01:00
{
/* Clear SCTLR_EL1.UCT */
config_sctlr_el1 ( SCTLR_EL1_UCT , 0 ) ;
2016-10-18 11:27:46 +01:00
return 0 ;
2016-09-09 14:07:16 +01:00
}
2014-11-14 15:54:10 +00:00
# define MIDR_RANGE(model, min, max) \
2016-04-22 12:25:31 +01:00
. def_scope = SCOPE_LOCAL_CPU , \
2015-03-27 13:09:23 +00:00
. matches = is_affected_midr_range , \
2014-11-14 15:54:10 +00:00
. midr_model = model , \
. midr_range_min = min , \
. midr_range_max = max
2017-02-01 14:38:46 +00:00
# define MIDR_ALL_VERSIONS(model) \
. def_scope = SCOPE_LOCAL_CPU , \
. matches = is_affected_midr_range , \
. midr_model = model , \
. midr_range_min = 0 , \
. midr_range_max = ( MIDR_VARIANT_MASK | MIDR_REVISION_MASK )
2015-03-27 13:09:23 +00:00
const struct arm64_cpu_capabilities arm64_errata [ ] = {
2014-11-14 15:54:12 +00:00
# if defined(CONFIG_ARM64_ERRATUM_826319) || \
defined ( CONFIG_ARM64_ERRATUM_827319 ) | | \
defined ( CONFIG_ARM64_ERRATUM_824069 )
2014-11-14 15:54:10 +00:00
{
/* Cortex-A53 r0p[012] */
. desc = " ARM errata 826319, 827319, 824069 " ,
. capability = ARM64_WORKAROUND_CLEAN_CACHE ,
MIDR_RANGE ( MIDR_CORTEX_A53 , 0x00 , 0x02 ) ,
2016-06-28 18:07:32 +01:00
. enable = cpu_enable_cache_maint_trap ,
2014-11-14 15:54:10 +00:00
} ,
2014-11-14 15:54:12 +00:00
# endif
# ifdef CONFIG_ARM64_ERRATUM_819472
{
/* Cortex-A53 r0p[01] */
. desc = " ARM errata 819472 " ,
. capability = ARM64_WORKAROUND_CLEAN_CACHE ,
MIDR_RANGE ( MIDR_CORTEX_A53 , 0x00 , 0x01 ) ,
2016-06-28 18:07:32 +01:00
. enable = cpu_enable_cache_maint_trap ,
2014-11-14 15:54:12 +00:00
} ,
# endif
# ifdef CONFIG_ARM64_ERRATUM_832075
2014-11-14 15:54:10 +00:00
{
2014-11-14 15:54:11 +00:00
/* Cortex-A57 r0p0 - r1p2 */
. desc = " ARM erratum 832075 " ,
. capability = ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE ,
2017-01-13 14:12:09 +01:00
MIDR_RANGE ( MIDR_CORTEX_A57 ,
MIDR_CPU_VAR_REV ( 0 , 0 ) ,
MIDR_CPU_VAR_REV ( 1 , 2 ) ) ,
2014-11-14 15:54:11 +00:00
} ,
2015-03-23 19:07:02 +00:00
# endif
2015-11-16 10:28:18 +00:00
# ifdef CONFIG_ARM64_ERRATUM_834220
{
/* Cortex-A57 r0p0 - r1p2 */
. desc = " ARM erratum 834220 " ,
. capability = ARM64_WORKAROUND_834220 ,
2017-01-13 14:12:09 +01:00
MIDR_RANGE ( MIDR_CORTEX_A57 ,
MIDR_CPU_VAR_REV ( 0 , 0 ) ,
MIDR_CPU_VAR_REV ( 1 , 2 ) ) ,
2015-11-16 10:28:18 +00:00
} ,
# endif
2015-03-23 19:07:02 +00:00
# ifdef CONFIG_ARM64_ERRATUM_845719
{
/* Cortex-A53 r0p[01234] */
. desc = " ARM erratum 845719 " ,
. capability = ARM64_WORKAROUND_845719 ,
MIDR_RANGE ( MIDR_CORTEX_A53 , 0x00 , 0x04 ) ,
} ,
2015-09-21 22:58:35 +02:00
# endif
# ifdef CONFIG_CAVIUM_ERRATUM_23154
{
/* Cavium ThunderX, pass 1.x */
. desc = " Cavium erratum 23154 " ,
. capability = ARM64_WORKAROUND_CAVIUM_23154 ,
MIDR_RANGE ( MIDR_THUNDERX , 0x00 , 0x01 ) ,
} ,
2016-02-24 17:44:57 -08:00
# endif
# ifdef CONFIG_CAVIUM_ERRATUM_27456
{
/* Cavium ThunderX, T88 pass 1.x - 2.1 */
. desc = " Cavium erratum 27456 " ,
. capability = ARM64_WORKAROUND_CAVIUM_27456 ,
2017-01-13 14:12:09 +01:00
MIDR_RANGE ( MIDR_THUNDERX ,
MIDR_CPU_VAR_REV ( 0 , 0 ) ,
MIDR_CPU_VAR_REV ( 1 , 1 ) ) ,
2016-02-24 17:44:57 -08:00
} ,
2016-07-07 10:18:17 +05:30
{
/* Cavium ThunderX, T81 pass 1.0 */
. desc = " Cavium erratum 27456 " ,
. capability = ARM64_WORKAROUND_CAVIUM_27456 ,
MIDR_RANGE ( MIDR_THUNDERX_81XX , 0x00 , 0x00 ) ,
} ,
2017-06-09 12:49:48 +01:00
# endif
# ifdef CONFIG_CAVIUM_ERRATUM_30115
{
/* Cavium ThunderX, T88 pass 1.x - 2.2 */
. desc = " Cavium erratum 30115 " ,
. capability = ARM64_WORKAROUND_CAVIUM_30115 ,
MIDR_RANGE ( MIDR_THUNDERX , 0x00 ,
( 1 < < MIDR_VARIANT_SHIFT ) | 2 ) ,
} ,
{
/* Cavium ThunderX, T81 pass 1.0 - 1.2 */
. desc = " Cavium erratum 30115 " ,
. capability = ARM64_WORKAROUND_CAVIUM_30115 ,
MIDR_RANGE ( MIDR_THUNDERX_81XX , 0x00 , 0x02 ) ,
} ,
{
/* Cavium ThunderX, T83 pass 1.0 */
. desc = " Cavium erratum 30115 " ,
. capability = ARM64_WORKAROUND_CAVIUM_30115 ,
MIDR_RANGE ( MIDR_THUNDERX_83XX , 0x00 , 0x00 ) ,
} ,
2014-11-14 15:54:12 +00:00
# endif
2016-09-09 14:07:16 +01:00
{
. desc = " Mismatched cache line size " ,
. capability = ARM64_MISMATCHED_CACHE_LINE_SIZE ,
. matches = has_mismatched_cache_line_size ,
. def_scope = SCOPE_LOCAL_CPU ,
. enable = cpu_enable_trap_ctr_access ,
} ,
2017-02-08 15:08:37 -05:00
# ifdef CONFIG_QCOM_FALKOR_ERRATUM_1003
{
. desc = " Qualcomm Technologies Falkor erratum 1003 " ,
. capability = ARM64_WORKAROUND_QCOM_FALKOR_E1003 ,
MIDR_RANGE ( MIDR_QCOM_FALKOR_V1 ,
MIDR_CPU_VAR_REV ( 0 , 0 ) ,
MIDR_CPU_VAR_REV ( 0 , 0 ) ) ,
} ,
# endif
2017-01-31 12:50:19 -05:00
# ifdef CONFIG_QCOM_FALKOR_ERRATUM_1009
{
. desc = " Qualcomm Technologies Falkor erratum 1009 " ,
. capability = ARM64_WORKAROUND_REPEAT_TLBI ,
MIDR_RANGE ( MIDR_QCOM_FALKOR_V1 ,
MIDR_CPU_VAR_REV ( 0 , 0 ) ,
MIDR_CPU_VAR_REV ( 0 , 0 ) ) ,
} ,
2017-03-20 17:18:06 +00:00
# endif
# ifdef CONFIG_ARM64_ERRATUM_858921
{
/* Cortex-A73 all versions */
. desc = " ARM erratum 858921 " ,
. capability = ARM64_WORKAROUND_858921 ,
MIDR_ALL_VERSIONS ( MIDR_CORTEX_A73 ) ,
} ,
2017-01-31 12:50:19 -05:00
# endif
2014-11-14 15:54:11 +00:00
{
2014-11-14 15:54:10 +00:00
}
2014-11-14 15:54:09 +00:00
} ;
2016-04-22 12:25:34 +01:00
/*
* The CPU Errata work arounds are detected and applied at boot time
* and the related information is freed soon after . If the new CPU requires
* an errata not detected at boot , fail this CPU .
*/
2016-09-09 14:07:09 +01:00
void verify_local_cpu_errata_workarounds ( void )
2016-04-22 12:25:34 +01:00
{
const struct arm64_cpu_capabilities * caps = arm64_errata ;
for ( ; caps - > matches ; caps + + )
if ( ! cpus_have_cap ( caps - > capability ) & &
caps - > matches ( caps , SCOPE_LOCAL_CPU ) ) {
pr_crit ( " CPU%d: Requires work around for %s, not detected "
" at boot time \n " ,
smp_processor_id ( ) ,
caps - > desc ? : " an erratum " ) ;
cpu_die_early ( ) ;
}
}
2016-09-09 14:07:09 +01:00
void update_cpu_errata_workarounds ( void )
2014-11-14 15:54:09 +00:00
{
2015-10-19 14:24:49 +01:00
update_cpu_capabilities ( arm64_errata , " enabling workaround for " ) ;
2014-11-14 15:54:09 +00:00
}
2016-06-28 18:07:30 +01:00
void __init enable_errata_workarounds ( void )
{
enable_cpu_capabilities ( arm64_errata ) ;
}