aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/include/asm/cpufeature.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/include/asm/cpufeature.h')
-rw-r--r--arch/arm64/include/asm/cpufeature.h42
1 files changed, 26 insertions, 16 deletions
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 7099f26e3702..758d74fedfad 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -9,6 +9,8 @@
9#ifndef __ASM_CPUFEATURE_H 9#ifndef __ASM_CPUFEATURE_H
10#define __ASM_CPUFEATURE_H 10#define __ASM_CPUFEATURE_H
11 11
12#include <linux/jump_label.h>
13
12#include <asm/hwcap.h> 14#include <asm/hwcap.h>
13#include <asm/sysreg.h> 15#include <asm/sysreg.h>
14 16
@@ -37,8 +39,9 @@
37#define ARM64_WORKAROUND_CAVIUM_27456 12 39#define ARM64_WORKAROUND_CAVIUM_27456 12
38#define ARM64_HAS_32BIT_EL0 13 40#define ARM64_HAS_32BIT_EL0 13
39#define ARM64_HYP_OFFSET_LOW 14 41#define ARM64_HYP_OFFSET_LOW 14
42#define ARM64_MISMATCHED_CACHE_LINE_SIZE 15
40 43
41#define ARM64_NCAPS 15 44#define ARM64_NCAPS 16
42 45
43#ifndef __ASSEMBLY__ 46#ifndef __ASSEMBLY__
44 47
@@ -63,7 +66,7 @@ struct arm64_ftr_bits {
63 enum ftr_type type; 66 enum ftr_type type;
64 u8 shift; 67 u8 shift;
65 u8 width; 68 u8 width;
66 s64 safe_val; /* safe value for discrete features */ 69 s64 safe_val; /* safe value for FTR_EXACT features */
67}; 70};
68 71
69/* 72/*
@@ -72,13 +75,14 @@ struct arm64_ftr_bits {
72 * @sys_val Safe value across the CPUs (system view) 75 * @sys_val Safe value across the CPUs (system view)
73 */ 76 */
74struct arm64_ftr_reg { 77struct arm64_ftr_reg {
75 u32 sys_id; 78 const char *name;
76 const char *name; 79 u64 strict_mask;
77 u64 strict_mask; 80 u64 sys_val;
78 u64 sys_val; 81 const struct arm64_ftr_bits *ftr_bits;
79 struct arm64_ftr_bits *ftr_bits;
80}; 82};
81 83
84extern struct arm64_ftr_reg arm64_ftr_reg_ctrel0;
85
82/* scope of capability check */ 86/* scope of capability check */
83enum { 87enum {
84 SCOPE_SYSTEM, 88 SCOPE_SYSTEM,
@@ -109,6 +113,7 @@ struct arm64_cpu_capabilities {
109}; 113};
110 114
111extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS); 115extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
116extern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS];
112 117
113bool this_cpu_has_cap(unsigned int cap); 118bool this_cpu_has_cap(unsigned int cap);
114 119
@@ -121,16 +126,21 @@ static inline bool cpus_have_cap(unsigned int num)
121{ 126{
122 if (num >= ARM64_NCAPS) 127 if (num >= ARM64_NCAPS)
123 return false; 128 return false;
124 return test_bit(num, cpu_hwcaps); 129 if (__builtin_constant_p(num))
130 return static_branch_unlikely(&cpu_hwcap_keys[num]);
131 else
132 return test_bit(num, cpu_hwcaps);
125} 133}
126 134
127static inline void cpus_set_cap(unsigned int num) 135static inline void cpus_set_cap(unsigned int num)
128{ 136{
129 if (num >= ARM64_NCAPS) 137 if (num >= ARM64_NCAPS) {
130 pr_warn("Attempt to set an illegal CPU capability (%d >= %d)\n", 138 pr_warn("Attempt to set an illegal CPU capability (%d >= %d)\n",
131 num, ARM64_NCAPS); 139 num, ARM64_NCAPS);
132 else 140 } else {
133 __set_bit(num, cpu_hwcaps); 141 __set_bit(num, cpu_hwcaps);
142 static_branch_enable(&cpu_hwcap_keys[num]);
143 }
134} 144}
135 145
136static inline int __attribute_const__ 146static inline int __attribute_const__
@@ -157,7 +167,7 @@ cpuid_feature_extract_unsigned_field(u64 features, int field)
157 return cpuid_feature_extract_unsigned_field_width(features, field, 4); 167 return cpuid_feature_extract_unsigned_field_width(features, field, 4);
158} 168}
159 169
160static inline u64 arm64_ftr_mask(struct arm64_ftr_bits *ftrp) 170static inline u64 arm64_ftr_mask(const struct arm64_ftr_bits *ftrp)
161{ 171{
162 return (u64)GENMASK(ftrp->shift + ftrp->width - 1, ftrp->shift); 172 return (u64)GENMASK(ftrp->shift + ftrp->width - 1, ftrp->shift);
163} 173}
@@ -170,7 +180,7 @@ cpuid_feature_extract_field(u64 features, int field, bool sign)
170 cpuid_feature_extract_unsigned_field(features, field); 180 cpuid_feature_extract_unsigned_field(features, field);
171} 181}
172 182
173static inline s64 arm64_ftr_value(struct arm64_ftr_bits *ftrp, u64 val) 183static inline s64 arm64_ftr_value(const struct arm64_ftr_bits *ftrp, u64 val)
174{ 184{
175 return (s64)cpuid_feature_extract_field(val, ftrp->shift, ftrp->sign); 185 return (s64)cpuid_feature_extract_field(val, ftrp->shift, ftrp->sign);
176} 186}
@@ -193,11 +203,11 @@ void __init setup_cpu_features(void);
193void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps, 203void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
194 const char *info); 204 const char *info);
195void enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps); 205void enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps);
196void check_local_cpu_errata(void); 206void check_local_cpu_capabilities(void);
197void __init enable_errata_workarounds(void);
198 207
199void verify_local_cpu_errata(void); 208void update_cpu_errata_workarounds(void);
200void verify_local_cpu_capabilities(void); 209void __init enable_errata_workarounds(void);
210void verify_local_cpu_errata_workarounds(void);
201 211
202u64 read_system_reg(u32 id); 212u64 read_system_reg(u32 id);
203 213