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