2 * Contains CPU specific errata definitions
4 * Copyright (C) 2014 ARM Ltd.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #define pr_fmt(fmt) "alternative: " fmt
21 #include <linux/types.h>
23 #include <asm/cputype.h>
24 #include <asm/cpufeature.h>
26 #define MIDR_CORTEX_A53 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
27 #define MIDR_CORTEX_A57 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
30 * Add a struct or another datatype to the union below if you need
31 * different means to detect an affected CPU.
33 struct arm64_cpu_capabilities
{
36 bool (*is_affected
)(struct arm64_cpu_capabilities
*);
40 u32 midr_range_min
, midr_range_max
;
45 #define CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \
46 MIDR_ARCHITECTURE_MASK)
48 static bool __maybe_unused
49 is_affected_midr_range(struct arm64_cpu_capabilities
*entry
)
51 u32 midr
= read_cpuid_id();
53 if ((midr
& CPU_MODEL_MASK
) != entry
->midr_model
)
56 midr
&= MIDR_REVISION_MASK
| MIDR_VARIANT_MASK
;
58 return (midr
>= entry
->midr_range_min
&& midr
<= entry
->midr_range_max
);
61 #define MIDR_RANGE(model, min, max) \
62 .is_affected = is_affected_midr_range, \
63 .midr_model = model, \
64 .midr_range_min = min, \
67 struct arm64_cpu_capabilities arm64_errata
[] = {
69 /* Cortex-A53 r0p[012] */
70 .desc
= "ARM errata 826319, 827319, 824069",
71 .capability
= ARM64_WORKAROUND_CLEAN_CACHE
,
72 MIDR_RANGE(MIDR_CORTEX_A53
, 0x00, 0x02),
75 /* Cortex-A57 r0p0 - r1p2 */
76 .desc
= "ARM erratum 832075",
77 .capability
= ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE
,
78 MIDR_RANGE(MIDR_CORTEX_A57
, 0x00, 0x12),
84 void check_local_cpu_errata(void)
86 struct arm64_cpu_capabilities
*cpus
= arm64_errata
;
89 for (i
= 0; cpus
[i
].desc
; i
++) {
90 if (!cpus
[i
].is_affected(&cpus
[i
]))
93 if (!cpus_have_cap(cpus
[i
].capability
))
94 pr_info("enabling workaround for %s\n", cpus
[i
].desc
);
95 cpus_set_cap(cpus
[i
].capability
);