dmi: check both the AC and ID flags at the same time
[syslinux.git] / com32 / include / x86 / cpu.h
blobf61e43898fde1d950264e698e6ade36fa11efa7d
1 #ifndef _X86_CPU_H
2 #define _X86_CPU_H
4 #include <klibc/compiler.h>
5 #include <inttypes.h>
6 #include <stdbool.h>
7 #include <x86/regs.h>
9 static inline __constfunc unsigned long cpu_has_eflags(unsigned long flags)
11 unsigned long f1, f2;
13 if (__builtin_constant_p(flags)) {
14 if (!(flags & ~(unsigned long)KNOWN_EFLAGS))
15 return flags; /* We know we have them all */
18 asm("pushf ; "
19 "pushf ; "
20 "pop %0 ; "
21 "mov %0,%1 ; "
22 "xor %2,%1 ; "
23 "push %1 ; "
24 "popf ; "
25 "pushf ; "
26 "pop %1 ; "
27 "popf"
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)
40 uint32_t eax, edx;
41 asm volatile("rdtsc" : "=a" (eax), "=d" (edx));
42 return eax + ((uint64_t)edx << 32);
45 static inline uint32_t rdtscl(void)
47 uint32_t v;
48 asm volatile("rdtsc" : "=a" (v) : : "edx");
49 return v;
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 ; "
58 "cpuid ; "
59 "xchgl %1,%%ebx"
60 : "=a" (*eax), "=SD" (*ebx), "=c" (*ecx), "=d" (*edx)
61 : "a"(op), "c"(cnt));
62 #else
63 asm volatile("cpuid"
64 : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
65 : "a"(op), "c"(cnt));
66 #endif
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);
81 return eax;
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);
89 return ebx;
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);
97 return ecx;
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);
105 return edx;
108 static inline uint64_t rdmsr(uint32_t msr)
110 uint32_t eax, edx;
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)
118 uint32_t eax = v;
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)
126 unsigned long v;
127 asm volatile("mov %%cr0,%0" : "=r" (v));
128 return 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)
138 unsigned long v;
139 asm volatile("mov %%cr4,%0" : "=r" (v));
140 return 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)
150 uint32_t v;
151 asm("stmxcsr %0" : "=m" (v));
152 return 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)
187 unsigned long v;
189 asm volatile("pushf ; pop %0" : "=rm" (v));
190 return 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)
202 return get_eflags();
205 static inline irq_state_t irq_save(void)
207 irq_state_t v = irq_state();
208 cli();
209 return v;
212 static inline void irq_restore(irq_state_t v)
214 set_eflags(v);
217 #endif /* _X86_CPU_H */