Home | History | Annotate | Download | only in x86_64
      1 #ifndef _CPU_X86_64_H
      2 #define _CPU_X86_64_H
      3 
      4 /* x86_64 cpu.h  */
      5 
      6 static inline uint64_t rdtsc(void)
      7 {
      8     uint64_t v;
      9     asm volatile("rdtsc" : "=A" (v));
     10     return v;
     11 }
     12 
     13 static inline uint32_t rdtscl(void)
     14 {
     15     uint32_t v;
     16     asm volatile("rdtsc" : "=a" (v) : : "edx");
     17     return v;
     18 }
     19 
     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  */
     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  */
     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 
     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 
     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 
     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 
     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 
     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 
    104 static inline void wrmsr(uint64_t v, uint32_t msr)
    105 {
    106     asm volatile("wrmsr" : : "A" (v), "c" (msr));
    107 }
    108 
    109 static inline void cpu_relax(void)
    110 {
    111     asm volatile("rep ; nop" : : : "memory");
    112 }
    113 
    114 static inline void hlt(void)
    115 {
    116     asm volatile("hlt" : : : "memory");
    117 }
    118 
    119 static inline void cli(void)
    120 {
    121     asm volatile("cli" : : : "memory");
    122 }
    123 
    124 static inline void sti(void)
    125 {
    126     asm volatile("sti" : : : "memory");
    127 }
    128 #endif
    129