#include <stdbool.h>
#include <stdint.h>
#include <cpufeature.h>
+#include <sys/cpu.h>
#include <klibc/compiler.h>
#define PAGE_SIZE 4096
};
/*
- * Generic CPUID function
- * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
- * resulting in stale register contents being returned.
- */
-static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
-{
- __asm__("cpuid"
- : "=a" (*eax),
- "=b" (*ebx),
- "=c" (*ecx),
- "=d" (*edx)
- : "0" (op), "c"(0));
-}
-
-static inline __constfunc unsigned int cpuid_eax(unsigned int op)
-{
- unsigned int eax;
-
- __asm__("cpuid"
- : "=a" (eax)
- : "0" (op)
- : "bx", "cx", "dx");
- return eax;
-}
-
-static inline __constfunc unsigned int cpuid_ecx(unsigned int op)
-{
- unsigned int eax, ecx;
-
- __asm__("cpuid"
- : "=a" (eax), "=c" (ecx)
- : "0" (op)
- : "bx", "dx" );
- return ecx;
-}
-static inline __constfunc unsigned int cpuid_edx(unsigned int op)
-{
- unsigned int eax, edx;
-
- __asm__("cpuid"
- : "=a" (eax), "=d" (edx)
- : "0" (op)
- : "bx", "cx");
- return edx;
-}
-
-/* Standard macro to see if a specific flag is changeable */
-static inline __constfunc bool cpu_has_eflag(uint32_t flag)
-{
- uint32_t f1, f2;
-
- asm("pushfl\n\t"
- "pushfl\n\t"
- "popl %0\n\t"
- "movl %0,%1\n\t"
- "xorl %2,%0\n\t"
- "pushl %0\n\t"
- "popfl\n\t"
- "pushfl\n\t"
- "popl %0\n\t"
- "popfl\n\t"
- : "=&r" (f1), "=&r" (f2)
- : "ir" (flag));
-
- return ((f1^f2) & flag) != 0;
-}
-
-/*
* Structure definitions for SMP machines following the
* Intel Multiprocessing Specification 1.1 and 1.4.
*/
#ifndef _CPU_H
#define _CPU_H
-#include <inttypes.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <klibc/compiler.h>
static inline uint64_t rdtsc(void)
{
return v;
}
-static inline uint32_t cpuid_eax(uint32_t level)
+static inline void cpuid_count(uint32_t op, uint32_t cnt,
+ uint32_t *eax, uint32_t *ebx,
+ uint32_t *ecx, uint32_t *edx)
+{
+ asm("cpuid" : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
+ : "a" (op), "c" (cnt));
+}
+static inline void cpuid(uint32_t op, uint32_t *eax, uint32_t *ebx,
+ uint32_t *ecx, uint32_t *edx)
+{
+ return cpuid_count(op, 0, eax, ebx, ecx, edx);
+}
+static inline __constfunc uint32_t cpuid_eax(uint32_t level)
{
uint32_t v;
asm("cpuid" : "=a" (v) : "a" (level) : "ebx", "ecx", "edx");
return v;
}
-static inline uint32_t cpuid_ebx(uint32_t level)
+static inline __constfunc uint32_t cpuid_ebx(uint32_t level)
{
uint32_t v;
asm("cpuid" : "=b" (v), "+a" (level) : : "ecx", "edx");
return v;
}
-static inline uint32_t cpuid_ecx(uint32_t level)
+static inline __constfunc uint32_t cpuid_ecx(uint32_t level)
{
uint32_t v;
asm("cpuid" : "=c" (v), "+a" (level) : : "ebx", "edx");
return v;
}
-static inline uint32_t cpuid_edx(uint32_t level)
+static inline __constfunc uint32_t cpuid_edx(uint32_t level)
{
uint32_t v;
return v;
}
+/* Standard macro to see if a specific flag is changeable */
+static inline __constfunc bool cpu_has_eflag(uint32_t flag)
+{
+ uint32_t f1, f2;
+
+ asm("pushfl\n\t"
+ "pushfl\n\t"
+ "popl %0\n\t"
+ "movl %0,%1\n\t"
+ "xorl %2,%0\n\t"
+ "pushl %0\n\t"
+ "popfl\n\t"
+ "pushfl\n\t"
+ "popl %0\n\t"
+ "popfl\n\t"
+ : "=&r" (f1), "=&r" (f2)
+ : "ir" (flag));
+
+ return ((f1^f2) & flag) != 0;
+}
+
static inline uint64_t rdmsr(uint32_t msr)
{
uint64_t v;