diff options
author | Glauber de Oliveira Costa <gcosta@redhat.com> | 2008-01-30 07:31:03 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:31:03 -0500 |
commit | c758ecf62ad94ddfeb4e7d8a5498bdcb2e3c85db (patch) | |
tree | 6a7b8b629bbe935c78cf3933b0cfe25253c563a9 | |
parent | 4e87173eacfd0d798aeeba14026893797826bc93 (diff) |
x86: unify cpuid functions
cpuid is not very different between i386 and x86_64.
We move away the x86_64 version from msr.h, and
unify them at processor.h, where they belong.
cpuid() paravirt then comes for free.
Signed-off-by: Glauber de Oliveira Costa <gcosta@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | include/asm-x86/msr.h | 67 | ||||
-rw-r--r-- | include/asm-x86/processor.h | 78 | ||||
-rw-r--r-- | include/asm-x86/processor_32.h | 69 |
3 files changed, 78 insertions, 136 deletions
diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h index 5c95d0be1132..0648b2d57a38 100644 --- a/include/asm-x86/msr.h +++ b/include/asm-x86/msr.h | |||
@@ -203,73 +203,6 @@ static inline int wrmsr_safe(u32 __msr, u32 __low, u32 __high) | |||
203 | : "c" (counter)) | 203 | : "c" (counter)) |
204 | 204 | ||
205 | 205 | ||
206 | static inline void cpuid(int op, unsigned int *eax, unsigned int *ebx, | ||
207 | unsigned int *ecx, unsigned int *edx) | ||
208 | { | ||
209 | __asm__("cpuid" | ||
210 | : "=a" (*eax), | ||
211 | "=b" (*ebx), | ||
212 | "=c" (*ecx), | ||
213 | "=d" (*edx) | ||
214 | : "0" (op)); | ||
215 | } | ||
216 | |||
217 | /* Some CPUID calls want 'count' to be placed in ecx */ | ||
218 | static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx, | ||
219 | int *edx) | ||
220 | { | ||
221 | __asm__("cpuid" | ||
222 | : "=a" (*eax), | ||
223 | "=b" (*ebx), | ||
224 | "=c" (*ecx), | ||
225 | "=d" (*edx) | ||
226 | : "0" (op), "c" (count)); | ||
227 | } | ||
228 | |||
229 | /* | ||
230 | * CPUID functions returning a single datum | ||
231 | */ | ||
232 | static inline unsigned int cpuid_eax(unsigned int op) | ||
233 | { | ||
234 | unsigned int eax; | ||
235 | |||
236 | __asm__("cpuid" | ||
237 | : "=a" (eax) | ||
238 | : "0" (op) | ||
239 | : "bx", "cx", "dx"); | ||
240 | return eax; | ||
241 | } | ||
242 | static inline unsigned int cpuid_ebx(unsigned int op) | ||
243 | { | ||
244 | unsigned int eax, ebx; | ||
245 | |||
246 | __asm__("cpuid" | ||
247 | : "=a" (eax), "=b" (ebx) | ||
248 | : "0" (op) | ||
249 | : "cx", "dx" ); | ||
250 | return ebx; | ||
251 | } | ||
252 | static inline unsigned int cpuid_ecx(unsigned int op) | ||
253 | { | ||
254 | unsigned int eax, ecx; | ||
255 | |||
256 | __asm__("cpuid" | ||
257 | : "=a" (eax), "=c" (ecx) | ||
258 | : "0" (op) | ||
259 | : "bx", "dx" ); | ||
260 | return ecx; | ||
261 | } | ||
262 | static inline unsigned int cpuid_edx(unsigned int op) | ||
263 | { | ||
264 | unsigned int eax, edx; | ||
265 | |||
266 | __asm__("cpuid" | ||
267 | : "=a" (eax), "=d" (edx) | ||
268 | : "0" (op) | ||
269 | : "bx", "cx"); | ||
270 | return edx; | ||
271 | } | ||
272 | |||
273 | #ifdef __KERNEL__ | 206 | #ifdef __KERNEL__ |
274 | 207 | ||
275 | /* wrmsr with exception handling */ | 208 | /* wrmsr with exception handling */ |
diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h index 46e1c04e309c..dea81b70895d 100644 --- a/include/asm-x86/processor.h +++ b/include/asm-x86/processor.h | |||
@@ -1,5 +1,83 @@ | |||
1 | #ifndef __ASM_X86_PROCESSOR_H | ||
2 | #define __ASM_X86_PROCESSOR_H | ||
3 | |||
4 | static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, | ||
5 | unsigned int *ecx, unsigned int *edx) | ||
6 | { | ||
7 | /* ecx is often an input as well as an output. */ | ||
8 | __asm__("cpuid" | ||
9 | : "=a" (*eax), | ||
10 | "=b" (*ebx), | ||
11 | "=c" (*ecx), | ||
12 | "=d" (*edx) | ||
13 | : "0" (*eax), "2" (*ecx)); | ||
14 | } | ||
15 | |||
16 | |||
1 | #ifdef CONFIG_X86_32 | 17 | #ifdef CONFIG_X86_32 |
2 | # include "processor_32.h" | 18 | # include "processor_32.h" |
3 | #else | 19 | #else |
4 | # include "processor_64.h" | 20 | # include "processor_64.h" |
5 | #endif | 21 | #endif |
22 | |||
23 | #ifndef CONFIG_PARAVIRT | ||
24 | #define __cpuid native_cpuid | ||
25 | #endif | ||
26 | |||
27 | /* | ||
28 | * Generic CPUID function | ||
29 | * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx | ||
30 | * resulting in stale register contents being returned. | ||
31 | */ | ||
32 | static inline void cpuid(unsigned int op, | ||
33 | unsigned int *eax, unsigned int *ebx, | ||
34 | unsigned int *ecx, unsigned int *edx) | ||
35 | { | ||
36 | *eax = op; | ||
37 | *ecx = 0; | ||
38 | __cpuid(eax, ebx, ecx, edx); | ||
39 | } | ||
40 | |||
41 | /* Some CPUID calls want 'count' to be placed in ecx */ | ||
42 | static inline void cpuid_count(unsigned int op, int count, | ||
43 | unsigned int *eax, unsigned int *ebx, | ||
44 | unsigned int *ecx, unsigned int *edx) | ||
45 | { | ||
46 | *eax = op; | ||
47 | *ecx = count; | ||
48 | __cpuid(eax, ebx, ecx, edx); | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * CPUID functions returning a single datum | ||
53 | */ | ||
54 | static inline unsigned int cpuid_eax(unsigned int op) | ||
55 | { | ||
56 | unsigned int eax, ebx, ecx, edx; | ||
57 | |||
58 | cpuid(op, &eax, &ebx, &ecx, &edx); | ||
59 | return eax; | ||
60 | } | ||
61 | static inline unsigned int cpuid_ebx(unsigned int op) | ||
62 | { | ||
63 | unsigned int eax, ebx, ecx, edx; | ||
64 | |||
65 | cpuid(op, &eax, &ebx, &ecx, &edx); | ||
66 | return ebx; | ||
67 | } | ||
68 | static inline unsigned int cpuid_ecx(unsigned int op) | ||
69 | { | ||
70 | unsigned int eax, ebx, ecx, edx; | ||
71 | |||
72 | cpuid(op, &eax, &ebx, &ecx, &edx); | ||
73 | return ecx; | ||
74 | } | ||
75 | static inline unsigned int cpuid_edx(unsigned int op) | ||
76 | { | ||
77 | unsigned int eax, ebx, ecx, edx; | ||
78 | |||
79 | cpuid(op, &eax, &ebx, &ecx, &edx); | ||
80 | return edx; | ||
81 | } | ||
82 | |||
83 | #endif | ||
diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h index 6846cc346400..0d83da198127 100644 --- a/include/asm-x86/processor_32.h +++ b/include/asm-x86/processor_32.h | |||
@@ -133,18 +133,6 @@ extern void detect_ht(struct cpuinfo_x86 *c); | |||
133 | static inline void detect_ht(struct cpuinfo_x86 *c) {} | 133 | static inline void detect_ht(struct cpuinfo_x86 *c) {} |
134 | #endif | 134 | #endif |
135 | 135 | ||
136 | static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, | ||
137 | unsigned int *ecx, unsigned int *edx) | ||
138 | { | ||
139 | /* ecx is often an input as well as an output. */ | ||
140 | __asm__("cpuid" | ||
141 | : "=a" (*eax), | ||
142 | "=b" (*ebx), | ||
143 | "=c" (*ecx), | ||
144 | "=d" (*edx) | ||
145 | : "0" (*eax), "2" (*ecx)); | ||
146 | } | ||
147 | |||
148 | #define load_cr3(pgdir) write_cr3(__pa(pgdir)) | 136 | #define load_cr3(pgdir) write_cr3(__pa(pgdir)) |
149 | 137 | ||
150 | /* | 138 | /* |
@@ -580,7 +568,6 @@ static inline void native_set_iopl_mask(unsigned mask) | |||
580 | #include <asm/paravirt.h> | 568 | #include <asm/paravirt.h> |
581 | #else | 569 | #else |
582 | #define paravirt_enabled() 0 | 570 | #define paravirt_enabled() 0 |
583 | #define __cpuid native_cpuid | ||
584 | 571 | ||
585 | static inline void load_sp0(struct tss_struct *tss, struct thread_struct *thread) | 572 | static inline void load_sp0(struct tss_struct *tss, struct thread_struct *thread) |
586 | { | 573 | { |
@@ -598,62 +585,6 @@ static inline void load_sp0(struct tss_struct *tss, struct thread_struct *thread | |||
598 | #define set_iopl_mask native_set_iopl_mask | 585 | #define set_iopl_mask native_set_iopl_mask |
599 | #endif /* CONFIG_PARAVIRT */ | 586 | #endif /* CONFIG_PARAVIRT */ |
600 | 587 | ||
601 | /* | ||
602 | * Generic CPUID function | ||
603 | * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx | ||
604 | * resulting in stale register contents being returned. | ||
605 | */ | ||
606 | static inline void cpuid(unsigned int op, | ||
607 | unsigned int *eax, unsigned int *ebx, | ||
608 | unsigned int *ecx, unsigned int *edx) | ||
609 | { | ||
610 | *eax = op; | ||
611 | *ecx = 0; | ||
612 | __cpuid(eax, ebx, ecx, edx); | ||
613 | } | ||
614 | |||
615 | /* Some CPUID calls want 'count' to be placed in ecx */ | ||
616 | static inline void cpuid_count(unsigned int op, int count, | ||
617 | unsigned int *eax, unsigned int *ebx, | ||
618 | unsigned int *ecx, unsigned int *edx) | ||
619 | { | ||
620 | *eax = op; | ||
621 | *ecx = count; | ||
622 | __cpuid(eax, ebx, ecx, edx); | ||
623 | } | ||
624 | |||
625 | /* | ||
626 | * CPUID functions returning a single datum | ||
627 | */ | ||
628 | static inline unsigned int cpuid_eax(unsigned int op) | ||
629 | { | ||
630 | unsigned int eax, ebx, ecx, edx; | ||
631 | |||
632 | cpuid(op, &eax, &ebx, &ecx, &edx); | ||
633 | return eax; | ||
634 | } | ||
635 | static inline unsigned int cpuid_ebx(unsigned int op) | ||
636 | { | ||
637 | unsigned int eax, ebx, ecx, edx; | ||
638 | |||
639 | cpuid(op, &eax, &ebx, &ecx, &edx); | ||
640 | return ebx; | ||
641 | } | ||
642 | static inline unsigned int cpuid_ecx(unsigned int op) | ||
643 | { | ||
644 | unsigned int eax, ebx, ecx, edx; | ||
645 | |||
646 | cpuid(op, &eax, &ebx, &ecx, &edx); | ||
647 | return ecx; | ||
648 | } | ||
649 | static inline unsigned int cpuid_edx(unsigned int op) | ||
650 | { | ||
651 | unsigned int eax, ebx, ecx, edx; | ||
652 | |||
653 | cpuid(op, &eax, &ebx, &ecx, &edx); | ||
654 | return edx; | ||
655 | } | ||
656 | |||
657 | /* generic versions from gas */ | 588 | /* generic versions from gas */ |
658 | #define GENERIC_NOP1 ".byte 0x90\n" | 589 | #define GENERIC_NOP1 ".byte 0x90\n" |
659 | #define GENERIC_NOP2 ".byte 0x89,0xf6\n" | 590 | #define GENERIC_NOP2 ".byte 0x89,0xf6\n" |