1 #ifndef _CPU_X86_64_H
2 #define _CPU_X86_64_H
3
4 /* x86_64 cpu.h */
5
rdtsc(void)6 static inline uint64_t rdtsc(void)
7 {
8 uint64_t v;
9 asm volatile("rdtsc" : "=A" (v));
10 return v;
11 }
12
rdtscl(void)13 static inline uint32_t rdtscl(void)
14 {
15 uint32_t v;
16 asm volatile("rdtsc" : "=a" (v) : : "edx");
17 return v;
18 }
19
native_cpuid(unsigned int * eax,unsigned int * ebx,unsigned int * ecx,unsigned int * edx)20 static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
21 unsigned int *ecx, unsigned int *edx)
22 {
23 /* ecx is often an input as well as an output. */
24 asm volatile("cpuid"
25 : "=a" (*eax),
26 "=b" (*ebx),
27 "=c" (*ecx),
28 "=d" (*edx)
29 : "0" (*eax), "2" (*ecx)
30 : "memory");
31 }
32 /*
33 * Generic CPUID function
34 * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
35 * resulting in stale register contents being returned.
36 */
cpuid(uint32_t op,uint32_t * eax,uint32_t * ebx,uint32_t * ecx,uint32_t * edx)37 static inline void cpuid(uint32_t op,
38 uint32_t *eax, uint32_t *ebx,
39 uint32_t *ecx, uint32_t *edx)
40 {
41 *eax = op;
42 *ecx = 0;
43 native_cpuid(eax, ebx, ecx, edx);
44 }
45
46 /*
47 * CPUID functions returning a single datum
48 */
cpuid_eax(uint32_t op)49 static inline uint32_t cpuid_eax(uint32_t op)
50 {
51 uint32_t eax, ebx, ecx, edx;
52
53 cpuid(op, &eax, &ebx, &ecx, &edx);
54
55 return eax;
56 }
57
cpuid_ebx(uint32_t op)58 static inline uint32_t cpuid_ebx(uint32_t op)
59 {
60 uint32_t eax, ebx, ecx, edx;
61
62 cpuid(op, &eax, &ebx, &ecx, &edx);
63
64 return ebx;
65 }
66
cpuid_ecx(uint32_t op)67 static inline uint32_t cpuid_ecx(uint32_t op)
68 {
69 uint32_t eax, ebx, ecx, edx;
70
71 cpuid(op, &eax, &ebx, &ecx, &edx);
72
73 return ecx;
74 }
75
cpuid_edx(uint32_t op)76 static inline uint32_t cpuid_edx(uint32_t op)
77 {
78 uint32_t eax, ebx, ecx, edx;
79
80 cpuid(op, &eax, &ebx, &ecx, &edx);
81
82 return edx;
83 }
84
cpuid_count(uint32_t op,uint32_t cnt,uint32_t * eax,uint32_t * ebx,uint32_t * ecx,uint32_t * edx)85 static inline void cpuid_count(uint32_t op, uint32_t cnt,
86 uint32_t * eax, uint32_t * ebx,
87 uint32_t * ecx, uint32_t * edx)
88 {
89 asm volatile("movl %%ebx,%1 ; "
90 "cpuid ; "
91 "xchgl %1,%%ebx"
92 : "=a" (*eax), "=SD" (*ebx), "=c" (*ecx), "=d" (*edx)
93 : "a"(op), "c"(cnt));
94 }
95
rdmsr(uint32_t msr)96 static inline uint64_t rdmsr(uint32_t msr)
97 {
98 uint64_t v;
99
100 asm volatile("rdmsr" : "=A" (v) : "c"(msr));
101 return v;
102 }
103
wrmsr(uint64_t v,uint32_t msr)104 static inline void wrmsr(uint64_t v, uint32_t msr)
105 {
106 asm volatile("wrmsr" : : "A" (v), "c" (msr));
107 }
108
cpu_relax(void)109 static inline void cpu_relax(void)
110 {
111 asm volatile("rep ; nop" : : : "memory");
112 }
113
hlt(void)114 static inline void hlt(void)
115 {
116 asm volatile("hlt" : : : "memory");
117 }
118
cli(void)119 static inline void cli(void)
120 {
121 asm volatile("cli" : : : "memory");
122 }
123
sti(void)124 static inline void sti(void)
125 {
126 asm volatile("sti" : : : "memory");
127 }
128 #endif
129