2
* cpuinfo.c from the MPlayer project's TOOLS/ directory
4
* This program is used by the top level cpuinfo.sh script during ./configure
5
* for systems which do not have /proc/cpuinfo. The output of this program is
6
* formatted the same as 'cat /proc/cpuinfo'.
8
* NOTE: Only for the X86 cpu family.
17
#include <sys/timeb.h>
18
void gettimeofday(struct timeval* t,void* timezone)
19
{ struct timeb timebuffer;
21
t->tv_sec=timebuffer.time;
22
t->tv_usec=1000*timebuffer.millitm;
24
#define MISSING_USLEEP
25
#define sleep(t) _sleep(1000*t);
29
typedef long long int64_t;
30
#define MISSING_USLEEP
36
typedef struct cpuid_regs {
46
#define CPUID ".byte 0x0f, 0xa2; "
48
"movl %4,%%eax; " CPUID
49
"movl %%eax,%0; movl %%ebx,%1; movl %%ecx,%2; movl %%edx,%3;"
51
: "=m" (regs.eax), "=m" (regs.ebx), "=m" (regs.ecx), "=m" (regs.edx)
53
: "%eax", "%ecx", "%edx");
62
#define RDTSC ".byte 0x0f, 0x31; "
63
asm(RDTSC : "=a"(i), "=d"(j) : );
64
return ((int64_t)j<<32) + (int64_t)i;
69
store32(char *d, unsigned int v)
72
d[1] = (v >> 8) & 0xff;
73
d[2] = (v >> 16) & 0xff;
74
d[3] = (v >> 24) & 0xff;
79
main(int argc, char **argv)
81
cpuid_regs_t regs, regs_ext;
84
unsigned max_ext_cpuid;
85
unsigned int amd_flags;
86
unsigned int cpuType, cpuModel;
87
char *model_name = "Unknown CPU";
89
char processor_name[49];
93
/* printf("%d CPUID function codes\n", max_cpuid+1); */
95
store32(idstr+0, regs.ebx);
96
store32(idstr+4, regs.edx);
97
store32(idstr+8, regs.ecx);
99
printf("vendor_id\t: %s\n", idstr);
101
if (strcmp(idstr, "GenuineIntel") == 0)
102
model_name = "Unknown Intel CPU";
103
else if (strcmp(idstr, "AuthenticAMD") == 0)
104
model_name = "Unknown AMD CPU";
106
regs_ext = cpuid((1<<31) + 0);
107
max_ext_cpuid = regs_ext.eax;
108
if (max_ext_cpuid >= (1<<31) + 1) {
109
regs_ext = cpuid((1<<31) + 1);
110
amd_flags = regs_ext.edx;
112
if (max_ext_cpuid >= (1<<31) + 4) {
113
for (i = 2; i <= 4; i++) {
114
regs_ext = cpuid((1<<31) + i);
115
store32(processor_name + (i-2)*16, regs_ext.eax);
116
store32(processor_name + (i-2)*16 + 4, regs_ext.ebx);
117
store32(processor_name + (i-2)*16 + 8, regs_ext.ecx);
118
store32(processor_name + (i-2)*16 + 12, regs_ext.edx);
120
processor_name[48] = 0;
121
model_name = processor_name;
127
if (max_cpuid >= 1) {
133
{ 0, "fpu", "Floating-point unit on-chip" },
134
{ 1, "vme", "Virtual Mode Enhancements" },
135
{ 2, "de", "Debugging Extension" },
136
{ 3, "pse", "Page Size Extension" },
137
{ 4, "tsc", "Time Stamp Counter" },
138
{ 5, "msr", "Pentium Processor MSR" },
139
{ 6, "pae", "Physical Address Extension" },
140
{ 7, "mce", "Machine Check Exception" },
141
{ 8, "cx8", "CMPXCHG8B Instruction Supported" },
142
{ 9, "apic", "On-chip CPIC Hardware Enabled" },
143
{ 11, "sep", "SYSENTER and SYSEXIT" },
144
{ 12, "mtrr", "Memory Type Range Registers" },
145
{ 13, "pge", "PTE Global Bit" },
146
{ 14, "mca", "Machine Check Architecture" },
147
{ 15, "cmov", "Conditional Move/Compare Instruction" },
148
{ 16, "pat", "Page Attribute Table" },
149
{ 17, "pse36", "Page Size Extension 36-bit" },
150
{ 18, "psn", "Processor Serial Number" },
151
{ 19, "cflsh", "CFLUSH instruction" },
152
{ 21, "ds", "Debug Store" },
153
{ 22, "acpi", "Thermal Monitor and Clock Ctrl" },
154
{ 23, "mmx", "MMX Technology" },
155
{ 24, "fxsr", "FXSAVE/FXRSTOR" },
156
{ 25, "sse", "SSE Extensions" },
157
{ 26, "sse2", "SSE2 Extensions" },
158
{ 27, "ss", "Self Snoop" },
159
{ 29, "tm", "Therm. Monitor" },
167
{ 22, "mmxext","MMX Technology (AMD Extensions)" },
168
{ 30, "3dnowext","3Dnow! Extensions" },
169
{ 31, "3dnow", "3Dnow!" },
170
{ 32, "k6_mtrr", "Memory Type Range Registers" },
177
cpuType = (regs.eax >> 8) & 0xf;
178
cpuModel = (regs.eax >> 4) & 0xf;
181
cpuType = 0xf + ((regs.eax >> 20) & 0xf); // extended family
182
if (cpuType == 0xf || cpuType == 6)
183
cpuModel |= ((regs.eax >> 16) & 0xf) << 4;
185
printf("cpu family\t: %d\n"
192
printf("flags\t\t:");
193
for (i = 0; cap[i].bit >= 0; i++) {
194
if (regs.edx & (1 << cap[i].bit)) {
195
printf(" %s", cap[i].desc);
198
for (i = 0; cap_amd[i].bit >= 0; i++) {
199
if (amd_flags & (1 << cap_amd[i].bit)) {
200
printf(" %s", cap_amd[i].desc);
205
if (regs.edx & (1 << 4)) {
206
int64_t tsc_start, tsc_end;
207
struct timeval tv_start, tv_end;
211
gettimeofday(&tv_start, NULL);
212
#ifdef MISSING_USLEEP
218
gettimeofday(&tv_end, NULL);
220
usec_delay = 1000000 * (tv_end.tv_sec - tv_start.tv_sec)
221
+ (tv_end.tv_usec - tv_start.tv_usec);
223
printf("cpu MHz\t\t: %.3f\n",
224
(double)(tsc_end-tsc_start) / usec_delay);
228
printf("model name\t: %s\n", model_name);