4 #include <klibc/compiler.h>
9 static inline __constfunc
unsigned long cpu_has_eflags(unsigned long flags
)
13 if (__builtin_constant_p(flags
)) {
14 if (!(flags
& ~(unsigned long)KNOWN_EFLAGS
))
15 return flags
; /* We know we have them all */
28 : "=&r" (f1
), "=&r" (f2
) : "ri" (flags
));
30 return (f1
^ f2
) & flags
;
33 static inline __constfunc
bool cpu_has_eflag(unsigned long flag
)
35 return cpu_has_eflags(flag
) != 0;
38 static inline uint64_t rdtsc(void)
41 asm volatile("rdtsc" : "=a" (eax
), "=d" (edx
));
42 return eax
+ ((uint64_t)edx
<< 32);
45 static inline uint32_t rdtscl(void)
48 asm volatile("rdtsc" : "=a" (v
) : : "edx");
52 static inline void cpuid_count(uint32_t op
, uint32_t cnt
,
53 uint32_t *eax
, uint32_t *ebx
,
54 uint32_t *ecx
, uint32_t *edx
)
56 #if defined(__i386__) && defined(__PIC__)
57 asm volatile("movl %%ebx,%1 ; "
60 : "=a" (*eax
), "=SD" (*ebx
), "=c" (*ecx
), "=d" (*edx
)
64 : "=a" (*eax
), "=b" (*ebx
), "=c" (*ecx
), "=d" (*edx
)
69 static inline void cpuid(uint32_t op
,
70 uint32_t *eax
, uint32_t *ebx
,
71 uint32_t *ecx
, uint32_t *edx
)
73 cpuid_count(op
, 0, eax
, ebx
, ecx
, edx
);
76 static inline __constfunc
uint32_t cpuid_eax(uint32_t level
)
78 uint32_t eax
, ebx
, ecx
, edx
;
80 cpuid_count(level
, 0, &eax
, &ebx
, &ecx
, &edx
);
84 static inline __constfunc
uint32_t cpuid_ebx(uint32_t level
)
86 uint32_t eax
, ebx
, ecx
, edx
;
88 cpuid_count(level
, 0, &eax
, &ebx
, &ecx
, &edx
);
92 static inline __constfunc
uint32_t cpuid_ecx(uint32_t level
)
94 uint32_t eax
, ebx
, ecx
, edx
;
96 cpuid_count(level
, 0, &eax
, &ebx
, &ecx
, &edx
);
100 static inline __constfunc
uint32_t cpuid_edx(uint32_t level
)
102 uint32_t eax
, ebx
, ecx
, edx
;
104 cpuid_count(level
, 0, &eax
, &ebx
, &ecx
, &edx
);
108 static inline uint64_t rdmsr(uint32_t msr
)
112 asm volatile("rdmsr" : "=a" (eax
), "=d" (edx
) : "c" (msr
));
113 return eax
+ ((uint64_t)edx
<< 32);
116 static inline void wrmsr(uint64_t v
, uint32_t msr
)
119 uint32_t edx
= v
>> 32;
121 asm volatile("wrmsr" : : "a" (eax
), "d" (edx
), "c" (msr
));
124 static inline unsigned long long get_cr0(void)
127 asm volatile("mov %%cr0,%0" : "=r" (v
));
131 static inline void set_cr0(unsigned long v
)
133 asm volatile("mov %0,%%cr0" : : "r" (v
));
136 static inline unsigned long get_cr4(void)
139 asm volatile("mov %%cr4,%0" : "=r" (v
));
143 static inline void set_cr4(unsigned long v
)
145 asm volatile("mov %0,%%cr4" : : "r" (v
));
148 static inline uint32_t get_mxcsr(void)
151 asm("stmxcsr %0" : "=m" (v
));
155 static inline void set_mxcsr(uint32_t v
)
157 asm volatile("ldmxcsr %0" : : "m" (v
));
160 static inline void fninit(void)
162 asm volatile("fninit");
165 static inline void cpu_relax(void)
167 asm volatile("rep ; nop");
170 static inline void hlt(void)
172 asm volatile("hlt" : : : "memory");
175 static inline void cli(void)
177 asm volatile("cli" : : : "memory");
180 static inline void sti(void)
182 asm volatile("sti" : : : "memory");
185 static inline unsigned long get_eflags(void)
189 asm volatile("pushf ; pop %0" : "=rm" (v
));
193 static inline void set_eflags(unsigned long v
)
195 asm volatile("push %0 ; popf" : : "g" (v
) : "memory");
198 typedef unsigned long irq_state_t
;
200 static inline irq_state_t
irq_state(void)
205 static inline irq_state_t
irq_save(void)
207 irq_state_t v
= irq_state();
212 static inline void irq_restore(irq_state_t v
)
217 #endif /* _X86_CPU_H */