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