1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
#ifndef _CPU_H
#define _CPU_H
#include <stdbool.h>
#include <stdint.h>
#include <klibc/compiler.h>
static inline uint64_t rdtsc(void)
{
uint64_t v;
asm volatile("rdtsc" : "=A" (v));
return v;
}
static inline uint32_t rdtscl(void)
{
uint32_t v;
asm volatile("rdtsc" : "=a" (v) : : "edx");
return v;
}
static inline void cpuid_count(uint32_t op, uint32_t cnt,
uint32_t * eax, uint32_t * ebx,
uint32_t * ecx, uint32_t * edx)
{
asm volatile("movl %%ebx,%1 ; "
"cpuid ; "
"xchgl %1,%%ebx"
: "=a" (*eax), "=SD" (*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)
{
cpuid_count(op, 0, eax, ebx, ecx, edx);
}
static inline __constfunc uint32_t cpuid_eax(uint32_t level)
{
uint32_t v;
asm volatile("pushl %%ebx ; "
"cpuid ; "
"popl %%ebx"
: "=a" (v)
: "a"(level)
: "ecx", "edx");
return v;
}
static inline __constfunc uint32_t cpuid_ebx(uint32_t level)
{
uint32_t v;
asm volatile("movl %%ebx,%0 ; "
"cpuid ; "
"xchgl %0,%%ebx"
: "=SD" (v), "+a" (level)
: : "ecx", "edx");
return v;
}
static inline __constfunc uint32_t cpuid_ecx(uint32_t level)
{
uint32_t v;
asm volatile("pushl %%ebx ; "
"cpuid ; "
"popl %%ebx"
: "=c" (v), "+a" (level)
: : "edx");
return v;
}
static inline __constfunc uint32_t cpuid_edx(uint32_t level)
{
uint32_t v;
asm volatile("pushl %%ebx ; "
"cpuid ; "
"popl %%ebx"
: "=d" (v), "+a" (level)
: : "ecx");
return v;
}
/* Standard macro to see if a specific flag is changeable */
static inline __constfunc bool cpu_has_eflag(uint32_t flag)
{
uint32_t f0, f1;
asm("pushfl ; "
"pushfl ; "
"popl %0 ; "
"movl %0,%1 ; "
"xorl %2,%1 ; "
"pushl %1 ; "
"popfl ; "
"pushfl ; "
"popl %1 ; "
"popfl"
: "=&r" (f0), "=&r" (f1)
: "ri" (flag));
return !!((f0^f1) & flag);
}
static inline uint64_t rdmsr(uint32_t msr)
{
uint64_t v;
asm volatile("rdmsr" : "=A" (v) : "c"(msr));
return v;
}
static inline void wrmsr(uint64_t v, uint32_t msr)
{
asm volatile("wrmsr" : : "A" (v), "c" (msr));
}
static inline void cpu_relax(void)
{
asm volatile("rep ; nop");
}
static inline void hlt(void)
{
asm volatile("hlt");
}
static inline void cli(void)
{
asm volatile("cli");
}
static inline void sti(void)
{
asm volatile("sti");
}
#endif
|