1 #ifndef __ASM_ARM_CPUFEATURE_H
2 #define __ASM_ARM_CPUFEATURE_H
3
4 #ifdef CONFIG_ARM_64
5 #define cpu_feature64(c, feat) ((c)->pfr64.feat)
6 #define boot_cpu_feature64(feat) (boot_cpu_data.pfr64.feat)
7
8 #define cpu_has_el0_32 (boot_cpu_feature64(el0) == 2)
9 #define cpu_has_el0_64 (boot_cpu_feature64(el0) >= 1)
10 #define cpu_has_el1_32 (boot_cpu_feature64(el1) == 2)
11 #define cpu_has_el1_64 (boot_cpu_feature64(el1) >= 1)
12 #define cpu_has_el2_32 (boot_cpu_feature64(el2) == 2)
13 #define cpu_has_el2_64 (boot_cpu_feature64(el2) >= 1)
14 #define cpu_has_el3_32 (boot_cpu_feature64(el3) == 2)
15 #define cpu_has_el3_64 (boot_cpu_feature64(el3) >= 1)
16 #define cpu_has_fp (boot_cpu_feature64(fp) < 8)
17 #define cpu_has_simd (boot_cpu_feature64(simd) < 8)
18 #define cpu_has_gicv3 (boot_cpu_feature64(gic) == 1)
19 #endif
20
21 #define cpu_feature32(c, feat) ((c)->pfr32.feat)
22 #define boot_cpu_feature32(feat) (boot_cpu_data.pfr32.feat)
23
24 #define cpu_has_arm (boot_cpu_feature32(arm) == 1)
25 #define cpu_has_thumb (boot_cpu_feature32(thumb) >= 1)
26 #define cpu_has_thumb2 (boot_cpu_feature32(thumb) >= 3)
27 #define cpu_has_jazelle (boot_cpu_feature32(jazelle) > 0)
28 #define cpu_has_thumbee (boot_cpu_feature32(thumbee) == 1)
29 #define cpu_has_aarch32 (cpu_has_arm || cpu_has_thumb)
30
31 #ifdef CONFIG_ARM_32
32 #define cpu_has_gentimer (boot_cpu_feature32(gentimer) == 1)
33 #else
34 #define cpu_has_gentimer (1)
35 #endif
36 #define cpu_has_security (boot_cpu_feature32(security) > 0)
37
38 #define ARM64_WORKAROUND_CLEAN_CACHE 0
39 #define ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE 1
40 #define ARM32_WORKAROUND_766422 2
41 #define ARM64_WORKAROUND_834220 3
42 #define LIVEPATCH_FEATURE 4
43 #define SKIP_SYNCHRONIZE_SERROR_ENTRY_EXIT 5
44 #define ARM_HARDEN_BRANCH_PREDICTOR 6
45 #define ARM_SSBD 7
46 #define ARM_SMCCC_1_1 8
47 #define ARM64_WORKAROUND_AT_SPECULATE 9
48
49 #define ARM_NCAPS 10
50
51 #ifndef __ASSEMBLY__
52
53 #include <xen/types.h>
54 #include <xen/lib.h>
55 #include <xen/bitops.h>
56
57 extern DECLARE_BITMAP(cpu_hwcaps, ARM_NCAPS);
58
cpus_have_cap(unsigned int num)59 static inline bool cpus_have_cap(unsigned int num)
60 {
61 if ( num >= ARM_NCAPS )
62 return false;
63
64 return test_bit(num, cpu_hwcaps);
65 }
66
cpu_nr_siblings(unsigned int cpu)67 static inline int cpu_nr_siblings(unsigned int cpu)
68 {
69 return 1;
70 }
71
72 /* System capability check for constant cap */
73 #define cpus_have_const_cap(num) ({ \
74 register_t __ret; \
75 \
76 asm volatile (ALTERNATIVE("mov %0, #0", \
77 "mov %0, #1", \
78 num) \
79 : "=r" (__ret)); \
80 \
81 unlikely(__ret); \
82 })
83
cpus_set_cap(unsigned int num)84 static inline void cpus_set_cap(unsigned int num)
85 {
86 if (num >= ARM_NCAPS)
87 printk(XENLOG_WARNING "Attempt to set an illegal CPU capability (%d >= %d)\n",
88 num, ARM_NCAPS);
89 else
90 __set_bit(num, cpu_hwcaps);
91 }
92
93 struct arm_cpu_capabilities {
94 const char *desc;
95 u16 capability;
96 bool (*matches)(const struct arm_cpu_capabilities *);
97 int (*enable)(void *); /* Called on every active CPUs */
98 union {
99 struct { /* To be used for eratum handling only */
100 u32 midr_model;
101 u32 midr_range_min, midr_range_max;
102 };
103 };
104 };
105
106 void update_cpu_capabilities(const struct arm_cpu_capabilities *caps,
107 const char *info);
108
109 void enable_cpu_capabilities(const struct arm_cpu_capabilities *caps);
110 int enable_nonboot_cpu_caps(const struct arm_cpu_capabilities *caps);
111
112 /*
113 * capabilities of CPUs
114 */
115 struct cpuinfo_arm {
116 union {
117 uint32_t bits;
118 struct {
119 unsigned long revision:4;
120 unsigned long part_number:12;
121 unsigned long architecture:4;
122 unsigned long variant:4;
123 unsigned long implementer:8;
124 };
125 } midr;
126 union {
127 register_t bits;
128 struct {
129 unsigned long aff0:8;
130 unsigned long aff1:8;
131 unsigned long aff2:8;
132 unsigned long mt:1; /* Multi-thread, iff MP == 1 */
133 unsigned long __res0:5;
134 unsigned long up:1; /* UP system, iff MP == 1 */
135 unsigned long mp:1; /* MP extensions */
136
137 #ifdef CONFIG_ARM_64
138 unsigned long aff3:8;
139 unsigned long __res1:24;
140 #endif
141 };
142 } mpidr;
143
144 #ifdef CONFIG_ARM_64
145 /* 64-bit CPUID registers. */
146 union {
147 uint64_t bits[2];
148 struct {
149 unsigned long el0:4;
150 unsigned long el1:4;
151 unsigned long el2:4;
152 unsigned long el3:4;
153 unsigned long fp:4; /* Floating Point */
154 unsigned long simd:4; /* Advanced SIMD */
155 unsigned long gic:4; /* GIC support */
156 unsigned long __res0:28;
157 unsigned long csv2:4;
158 unsigned long __res1:4;
159 };
160 } pfr64;
161
162 struct {
163 uint64_t bits[2];
164 } dbg64;
165
166 struct {
167 uint64_t bits[2];
168 } aux64;
169
170 union {
171 uint64_t bits[2];
172 struct {
173 unsigned long pa_range:4;
174 unsigned long asid_bits:4;
175 unsigned long bigend:4;
176 unsigned long secure_ns:4;
177 unsigned long bigend_el0:4;
178 unsigned long tgranule_16K:4;
179 unsigned long tgranule_64K:4;
180 unsigned long tgranule_4K:4;
181 unsigned long __res0:32;
182
183 unsigned long hafdbs:4;
184 unsigned long vmid_bits:4;
185 unsigned long vh:4;
186 unsigned long hpds:4;
187 unsigned long lo:4;
188 unsigned long pan:4;
189 unsigned long __res1:8;
190 unsigned long __res2:32;
191 };
192 } mm64;
193
194 struct {
195 uint64_t bits[2];
196 } isa64;
197
198 #endif
199
200 /*
201 * 32-bit CPUID registers. On ARMv8 these describe the properties
202 * when running in 32-bit mode.
203 */
204 union {
205 uint32_t bits[2];
206 struct {
207 unsigned long arm:4;
208 unsigned long thumb:4;
209 unsigned long jazelle:4;
210 unsigned long thumbee:4;
211 unsigned long __res0:16;
212
213 unsigned long progmodel:4;
214 unsigned long security:4;
215 unsigned long mprofile:4;
216 unsigned long virt:4;
217 unsigned long gentimer:4;
218 unsigned long __res1:12;
219 };
220 } pfr32;
221
222 struct {
223 uint32_t bits[1];
224 } dbg32;
225
226 struct {
227 uint32_t bits[1];
228 } aux32;
229
230 struct {
231 uint32_t bits[4];
232 } mm32;
233
234 struct {
235 uint32_t bits[6];
236 } isa32;
237 };
238
239 extern struct cpuinfo_arm boot_cpu_data;
240
241 extern void identify_cpu(struct cpuinfo_arm *);
242
243 extern struct cpuinfo_arm cpu_data[];
244 #define current_cpu_data cpu_data[smp_processor_id()]
245
246 #endif /* __ASSEMBLY__ */
247
248 #endif
249 /*
250 * Local variables:
251 * mode: C
252 * c-file-style: "BSD"
253 * c-basic-offset: 4
254 * indent-tabs-mode: nil
255 * End:
256 */
257