Home | History | Annotate | Download | only in asm
      1 #ifndef __ASM_X86_MSR_H_
      2 #define __ASM_X86_MSR_H_
      3 
      4 #include <asm/msr-index.h>
      5 
      6 #ifndef __ASSEMBLY__
      7 # include <linux/types.h>
      8 #endif
      9 
     10 #ifdef __i386__
     11 
     12 
     13 #else   /* __i386__ */
     14 
     15 #ifndef __ASSEMBLY__
     16 #include <linux/errno.h>
     17 /*
     18  * Access to machine-specific registers (available on 586 and better only)
     19  * Note: the rd* operations modify the parameters directly (without using
     20  * pointer indirection), this allows gcc to optimize better
     21  */
     22 
     23 #define rdmsr(msr,val1,val2) \
     24        __asm__ __volatile__("rdmsr" \
     25 			    : "=a" (val1), "=d" (val2) \
     26 			    : "c" (msr))
     27 
     28 
     29 #define rdmsrl(msr,val) do { unsigned long a__,b__; \
     30        __asm__ __volatile__("rdmsr" \
     31 			    : "=a" (a__), "=d" (b__) \
     32 			    : "c" (msr)); \
     33        val = a__ | (b__<<32); \
     34 } while(0)
     35 
     36 #define wrmsr(msr,val1,val2) \
     37      __asm__ __volatile__("wrmsr" \
     38 			  : /* no outputs */ \
     39 			  : "c" (msr), "a" (val1), "d" (val2))
     40 
     41 #define wrmsrl(msr,val) wrmsr(msr,(__u32)((__u64)(val)),((__u64)(val))>>32)
     42 
     43 #define rdtsc(low,high) \
     44      __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
     45 
     46 #define rdtscl(low) \
     47      __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx")
     48 
     49 #define rdtscp(low,high,aux) \
     50      __asm__ __volatile__ (".byte 0x0f,0x01,0xf9" : "=a" (low), "=d" (high), "=c" (aux))
     51 
     52 #define rdtscll(val) do { \
     53      unsigned int __a,__d; \
     54      __asm__ __volatile__("rdtsc" : "=a" (__a), "=d" (__d)); \
     55      (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \
     56 } while(0)
     57 
     58 #define rdtscpll(val, aux) do { \
     59      unsigned long __a, __d; \
     60      __asm__ __volatile__ (".byte 0x0f,0x01,0xf9" : "=a" (__a), "=d" (__d), "=c" (aux)); \
     61      (val) = (__d << 32) | __a; \
     62 } while (0)
     63 
     64 #define write_tsc(val1,val2) wrmsr(0x10, val1, val2)
     65 
     66 #define write_rdtscp_aux(val) wrmsr(0xc0000103, val, 0)
     67 
     68 #define rdpmc(counter,low,high) \
     69      __asm__ __volatile__("rdpmc" \
     70 			  : "=a" (low), "=d" (high) \
     71 			  : "c" (counter))
     72 
     73 
     74 static __inline__ void cpuid(int op, unsigned int *eax, unsigned int *ebx,
     75 			 unsigned int *ecx, unsigned int *edx)
     76 {
     77 	__asm__("cpuid"
     78 		: "=a" (*eax),
     79 		  "=b" (*ebx),
     80 		  "=c" (*ecx),
     81 		  "=d" (*edx)
     82 		: "0" (op));
     83 }
     84 
     85 /* Some CPUID calls want 'count' to be placed in ecx */
     86 static __inline__ void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
     87 			       int *edx)
     88 {
     89 	__asm__("cpuid"
     90 		: "=a" (*eax),
     91 		  "=b" (*ebx),
     92 		  "=c" (*ecx),
     93 		  "=d" (*edx)
     94 		: "0" (op), "c" (count));
     95 }
     96 
     97 /*
     98  * CPUID functions returning a single datum
     99  */
    100 static __inline__ unsigned int cpuid_eax(unsigned int op)
    101 {
    102 	unsigned int eax;
    103 
    104 	__asm__("cpuid"
    105 		: "=a" (eax)
    106 		: "0" (op)
    107 		: "bx", "cx", "dx");
    108 	return eax;
    109 }
    110 static __inline__ unsigned int cpuid_ebx(unsigned int op)
    111 {
    112 	unsigned int eax, ebx;
    113 
    114 	__asm__("cpuid"
    115 		: "=a" (eax), "=b" (ebx)
    116 		: "0" (op)
    117 		: "cx", "dx" );
    118 	return ebx;
    119 }
    120 static __inline__ unsigned int cpuid_ecx(unsigned int op)
    121 {
    122 	unsigned int eax, ecx;
    123 
    124 	__asm__("cpuid"
    125 		: "=a" (eax), "=c" (ecx)
    126 		: "0" (op)
    127 		: "bx", "dx" );
    128 	return ecx;
    129 }
    130 static __inline__ unsigned int cpuid_edx(unsigned int op)
    131 {
    132 	unsigned int eax, edx;
    133 
    134 	__asm__("cpuid"
    135 		: "=a" (eax), "=d" (edx)
    136 		: "0" (op)
    137 		: "bx", "cx");
    138 	return edx;
    139 }
    140 
    141 #endif  /* __ASSEMBLY__ */
    142 
    143 #endif  /* !__i386__ */
    144 
    145 #endif
    146