/alps/pcitool

To get this branch, use:
bzr branch http://darksoft.org/webbzr/alps/pcitool
330 by Suren A. Chilingaryan
Support for 64-bit registes
1
#define _POSIX_C_SOURCE 200112L
2
#define _GNU_SOURCE
3
4
#include <stdio.h>
5
#include <string.h>
6
#include <stdint.h>
7
#include <unistd.h>
8
#include <stdint.h>
9
#include <assert.h>
10
#include <ctype.h>
11
#include <time.h>
12
#include <sched.h>
13
#include <arpa/inet.h>
14
#include <sys/time.h>
15
16
#include "pci.h"
17
#include "tools.h"
18
#include "error.h"
19
20
static void pcilib_run_cpuid(uint32_t eax, uint32_t ecx, uint32_t* abcd) {
21
    uint32_t ebx = 0, edx;
22
# if defined( __i386__ ) && defined ( __PIC__ )
23
     /* in case of PIC under 32-bit EBX cannot be clobbered */
24
    __asm__ ( "movl %%ebx, %%edi \n\t cpuid \n\t xchgl %%ebx, %%edi" : "=D" (ebx),
25
# else
26
    __asm__ ( "cpuid" : "+b" (ebx),
27
# endif
28
              "+a" (eax), "+c" (ecx), "=d" (edx) );
29
    abcd[0] = eax; abcd[1] = ebx; abcd[2] = ecx; abcd[3] = edx;
30
}
31
32
static int pcilib_check_xcr0_ymm() {
33
    uint32_t xcr0;
34
    __asm__ ("xgetbv" : "=a" (xcr0) : "c" (0) : "%edx" );
35
    return ((xcr0 & 6) == 6); /* checking if xmm and ymm state are enabled in XCR0 */
36
}
37
38
static int pcilib_check_4th_gen_intel_core_features() {
39
    uint32_t abcd[4];
40
    uint32_t fma_movbe_osxsave_mask = ((1 << 12) | (1 << 22) | (1 << 27));
41
    uint32_t avx2_bmi12_mask = (1 << 5) | (1 << 3) | (1 << 8);
42
43
    /* CPUID.(EAX=01H, ECX=0H):ECX.FMA[bit 12]==1   && 
44
       CPUID.(EAX=01H, ECX=0H):ECX.MOVBE[bit 22]==1 && 
45
       CPUID.(EAX=01H, ECX=0H):ECX.OSXSAVE[bit 27]==1 */
46
    pcilib_run_cpuid( 1, 0, abcd );
47
    if ( (abcd[2] & fma_movbe_osxsave_mask) != fma_movbe_osxsave_mask ) 
48
        return 0;
49
50
    if ( ! pcilib_check_xcr0_ymm() )
51
        return 0;
52
53
    /*  CPUID.(EAX=07H, ECX=0H):EBX.AVX2[bit 5]==1  &&
54
        CPUID.(EAX=07H, ECX=0H):EBX.BMI1[bit 3]==1  &&
55
        CPUID.(EAX=07H, ECX=0H):EBX.BMI2[bit 8]==1  */
56
    pcilib_run_cpuid( 7, 0, abcd );
57
    if ( (abcd[1] & avx2_bmi12_mask) != avx2_bmi12_mask ) 
58
        return 0;
59
60
    /* CPUID.(EAX=80000001H):ECX.LZCNT[bit 5]==1 */
61
    pcilib_run_cpuid( 0x80000001, 0, abcd );
62
    if ( (abcd[2] & (1 << 5)) == 0)
63
        return 0;
64
65
    return 1;
66
}
67
68
static int pcilib_detect_cpu_gen() {
69
    if (pcilib_check_4th_gen_intel_core_features())
70
	return 4;
71
    return 0;
72
}
73
74
int pcilib_get_cpu_gen() {
75
    int gen = -1;
76
77
    if (gen < 0 )
78
        gen = pcilib_detect_cpu_gen();
79
80
    return gen;
81
}
82
83
int pcilib_get_page_mask() {
84
    int pagesize,pagemask,temp;
85
86
    pagesize = sysconf(_SC_PAGESIZE);
87
88
    for( pagemask=0, temp = pagesize; temp != 1; ) {
89
	temp = (temp >> 1);
90
	pagemask = (pagemask << 1)+1;
91
    }
92
    return pagemask;
93
}
94
95
int pcilib_get_cpu_count() {
96
    int err;
97
98
    int cpu_count;
99
    cpu_set_t mask;
100
101
    err = sched_getaffinity(getpid(), sizeof(mask), &mask);
102
    if (err) return 1;
103
104
#ifdef CPU_COUNT
105
    cpu_count = CPU_COUNT(&mask);
106
#else
107
    for (cpu_count = 0; cpu_count < CPU_SETSIZE; cpu_count++) {
108
	if (!CPU_ISSET(cpu_count, &mask)) break;
109
    }
110
#endif
111
112
    if (!cpu_count) cpu_count = PCILIB_DEFAULT_CPU_COUNT;
113
    return cpu_count;    
114
}
115