176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifndef _CPU_X86_64_H 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define _CPU_X86_64_H 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* x86_64 cpu.h */ 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline uint64_t rdtsc(void) 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint64_t v; 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman asm volatile("rdtsc" : "=A" (v)); 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return v; 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline uint32_t rdtscl(void) 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint32_t v; 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman asm volatile("rdtsc" : "=a" (v) : : "edx"); 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return v; 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void native_cpuid(unsigned int *eax, unsigned int *ebx, 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int *ecx, unsigned int *edx) 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* ecx is often an input as well as an output. */ 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman asm volatile("cpuid" 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "=a" (*eax), 2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "=b" (*ebx), 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "=c" (*ecx), 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "=d" (*edx) 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "0" (*eax), "2" (*ecx) 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "memory"); 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Generic CPUID function 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * resulting in stale register contents being returned. 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void cpuid(uint32_t op, 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint32_t *eax, uint32_t *ebx, 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint32_t *ecx, uint32_t *edx) 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *eax = op; 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *ecx = 0; 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman native_cpuid(eax, ebx, ecx, edx); 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * CPUID functions returning a single datum 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline uint32_t cpuid_eax(uint32_t op) 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint32_t eax, ebx, ecx, edx; 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cpuid(op, &eax, &ebx, &ecx, &edx); 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return eax; 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline uint32_t cpuid_ebx(uint32_t op) 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint32_t eax, ebx, ecx, edx; 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cpuid(op, &eax, &ebx, &ecx, &edx); 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ebx; 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline uint32_t cpuid_ecx(uint32_t op) 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint32_t eax, ebx, ecx, edx; 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cpuid(op, &eax, &ebx, &ecx, &edx); 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ecx; 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline uint32_t cpuid_edx(uint32_t op) 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint32_t eax, ebx, ecx, edx; 7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman cpuid(op, &eax, &ebx, &ecx, &edx); 8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return edx; 8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void cpuid_count(uint32_t op, uint32_t cnt, 8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint32_t * eax, uint32_t * ebx, 8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint32_t * ecx, uint32_t * edx) 8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman asm volatile("movl %%ebx,%1 ; " 9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "cpuid ; " 9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "xchgl %1,%%ebx" 9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "=a" (*eax), "=SD" (*ebx), "=c" (*ecx), "=d" (*edx) 9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman : "a"(op), "c"(cnt)); 9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline uint64_t rdmsr(uint32_t msr) 9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint64_t v; 9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman asm volatile("rdmsr" : "=A" (v) : "c"(msr)); 10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return v; 10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void wrmsr(uint64_t v, uint32_t msr) 10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman asm volatile("wrmsr" : : "A" (v), "c" (msr)); 10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void cpu_relax(void) 11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman asm volatile("rep ; nop" : : : "memory"); 11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void hlt(void) 11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman asm volatile("hlt" : : : "memory"); 11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void cli(void) 12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman asm volatile("cli" : : : "memory"); 12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void sti(void) 12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman asm volatile("sti" : : : "memory"); 12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 129