zonefs: convert zonefs to use the new mount api
[sfrench/cifs-2.6.git] / arch / x86 / include / asm / cpuid.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * CPUID-related helpers/definitions
4  */
5
6 #ifndef _ASM_X86_CPUID_H
7 #define _ASM_X86_CPUID_H
8
9 #include <asm/string.h>
10
11 struct cpuid_regs {
12         u32 eax, ebx, ecx, edx;
13 };
14
15 enum cpuid_regs_idx {
16         CPUID_EAX = 0,
17         CPUID_EBX,
18         CPUID_ECX,
19         CPUID_EDX,
20 };
21
22 #ifdef CONFIG_X86_32
23 extern int have_cpuid_p(void);
24 #else
25 static inline int have_cpuid_p(void)
26 {
27         return 1;
28 }
29 #endif
30 static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
31                                 unsigned int *ecx, unsigned int *edx)
32 {
33         /* ecx is often an input as well as an output. */
34         asm volatile("cpuid"
35             : "=a" (*eax),
36               "=b" (*ebx),
37               "=c" (*ecx),
38               "=d" (*edx)
39             : "0" (*eax), "2" (*ecx)
40             : "memory");
41 }
42
43 #define native_cpuid_reg(reg)                                   \
44 static inline unsigned int native_cpuid_##reg(unsigned int op)  \
45 {                                                               \
46         unsigned int eax = op, ebx, ecx = 0, edx;               \
47                                                                 \
48         native_cpuid(&eax, &ebx, &ecx, &edx);                   \
49                                                                 \
50         return reg;                                             \
51 }
52
53 /*
54  * Native CPUID functions returning a single datum.
55  */
56 native_cpuid_reg(eax)
57 native_cpuid_reg(ebx)
58 native_cpuid_reg(ecx)
59 native_cpuid_reg(edx)
60
61 #ifdef CONFIG_PARAVIRT_XXL
62 #include <asm/paravirt.h>
63 #else
64 #define __cpuid                 native_cpuid
65 #endif
66
67 /*
68  * Generic CPUID function
69  * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
70  * resulting in stale register contents being returned.
71  */
72 static inline void cpuid(unsigned int op,
73                          unsigned int *eax, unsigned int *ebx,
74                          unsigned int *ecx, unsigned int *edx)
75 {
76         *eax = op;
77         *ecx = 0;
78         __cpuid(eax, ebx, ecx, edx);
79 }
80
81 /* Some CPUID calls want 'count' to be placed in ecx */
82 static inline void cpuid_count(unsigned int op, int count,
83                                unsigned int *eax, unsigned int *ebx,
84                                unsigned int *ecx, unsigned int *edx)
85 {
86         *eax = op;
87         *ecx = count;
88         __cpuid(eax, ebx, ecx, edx);
89 }
90
91 /*
92  * CPUID functions returning a single datum
93  */
94 static inline unsigned int cpuid_eax(unsigned int op)
95 {
96         unsigned int eax, ebx, ecx, edx;
97
98         cpuid(op, &eax, &ebx, &ecx, &edx);
99
100         return eax;
101 }
102
103 static inline unsigned int cpuid_ebx(unsigned int op)
104 {
105         unsigned int eax, ebx, ecx, edx;
106
107         cpuid(op, &eax, &ebx, &ecx, &edx);
108
109         return ebx;
110 }
111
112 static inline unsigned int cpuid_ecx(unsigned int op)
113 {
114         unsigned int eax, ebx, ecx, edx;
115
116         cpuid(op, &eax, &ebx, &ecx, &edx);
117
118         return ecx;
119 }
120
121 static inline unsigned int cpuid_edx(unsigned int op)
122 {
123         unsigned int eax, ebx, ecx, edx;
124
125         cpuid(op, &eax, &ebx, &ecx, &edx);
126
127         return edx;
128 }
129
130 static __always_inline bool cpuid_function_is_indexed(u32 function)
131 {
132         switch (function) {
133         case 4:
134         case 7:
135         case 0xb:
136         case 0xd:
137         case 0xf:
138         case 0x10:
139         case 0x12:
140         case 0x14:
141         case 0x17:
142         case 0x18:
143         case 0x1d:
144         case 0x1e:
145         case 0x1f:
146         case 0x8000001d:
147                 return true;
148         }
149
150         return false;
151 }
152
153 #define for_each_possible_hypervisor_cpuid_base(function) \
154         for (function = 0x40000000; function < 0x40010000; function += 0x100)
155
156 static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves)
157 {
158         uint32_t base, eax, signature[3];
159
160         for_each_possible_hypervisor_cpuid_base(base) {
161                 cpuid(base, &eax, &signature[0], &signature[1], &signature[2]);
162
163                 if (!memcmp(sig, signature, 12) &&
164                     (leaves == 0 || ((eax - base) >= leaves)))
165                         return base;
166         }
167
168         return 0;
169 }
170
171 #endif /* _ASM_X86_CPUID_H */