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