1 /*
2 * Licensed under the terms of the GNU GPL License version 2.
3 *
4 * Generic routines for retrieving cpuid registers.
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <fcntl.h>
11 #include <sys/stat.h>
12 #include <sys/types.h>
13 #include <unistd.h>
14 #include <errno.h>
15 #include <x86info.h>
16
17 /* returns zero on success */
native_cpuid(unsigned int cpunr,unsigned long long idx,unsigned int * eax,unsigned int * ebx,unsigned int * ecx,unsigned int * edx)18 int native_cpuid(unsigned int cpunr, unsigned long long idx,
19 unsigned int *eax, unsigned int *ebx,
20 unsigned int *ecx, unsigned int *edx)
21 {
22 unsigned int a = 0, b = 0, c = 0, d = 0;
23
24 c = idx >> 32;
25
26 bind_cpu(cpunr);
27
28 asm("cpuid"
29 : "=a" (a),
30 "=b" (b),
31 "+c" (c),
32 "=d" (d)
33 : "0" ((unsigned int)idx));
34
35 if (eax!=NULL)
36 *eax = a;
37 if (ebx!=NULL)
38 *ebx = b;
39 if (ecx!=NULL)
40 *ecx = c;
41 if (edx!=NULL)
42 *edx = d;
43
44 return 0;
45 }
46
cpuid4(unsigned int CPU_number,unsigned long long idx,unsigned int * eax,unsigned int * ebx,unsigned int * ecx,unsigned int * edx)47 void cpuid4(unsigned int CPU_number, unsigned long long idx,
48 unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
49 {
50 cpuid(CPU_number, 4 | (idx << 32), eax, ebx, ecx, edx);
51 }
52
53 /* Some CPUID calls want 'count' to be placed in ecx */
cpuid_count(unsigned int CPU_number,unsigned int op,int count,unsigned int * eax,unsigned int * ebx,unsigned int * ecx,unsigned int * edx)54 void cpuid_count(unsigned int CPU_number, unsigned int op, int count,
55 unsigned int *eax, unsigned int *ebx,
56 unsigned int *ecx, unsigned int *edx)
57 {
58 *ecx = count;
59 cpuid(CPU_number, op, eax, ebx, ecx, edx);
60 }
61
cpuid_ebx(unsigned int CPU_number,unsigned int op)62 unsigned int cpuid_ebx(unsigned int CPU_number, unsigned int op)
63 {
64 unsigned int eax, ebx, ecx, edx;
65
66 cpuid(CPU_number, op, &eax, &ebx, &ecx, &edx);
67
68 return ebx;
69 }
70
71
dump_raw_cpuid(int cpunum,unsigned int begin,unsigned int end)72 void dump_raw_cpuid(int cpunum, unsigned int begin, unsigned int end)
73 {
74 unsigned int i;
75 unsigned int eax, ebx, ecx, edx;
76
77 /* Dump all the CPUID results in raw hex */
78 for (i = begin; i <= end; i++) {
79 ecx = 0;
80 cpuid(cpunum, i, &eax, &ebx, &ecx, &edx);
81 printf("eax in: 0x%08x, eax = %08x ebx = %08x ecx = %08x edx = %08x\n", i, eax, ebx, ecx, edx);
82 }
83 printf("\n");
84 }
85