Mercurial > mplayer.hg
annotate TOOLS/cpuinfo.c @ 18408:6484274d41e5
1.252: [previously applied by rynaldo, #1.157]
1.251: console message review: countless spelling/grammar/wording fixes
Part I (incomplete patch)
1.250: [previously applied by diego, #1.155]
1.249: [previously applied by diego, #1.156]
1.248: [previously applied by reynaldo. #1.154]
author | kraymer |
---|---|
date | Tue, 09 May 2006 13:34:39 +0000 |
parents | 4471c5a962ec |
children | 744aa553e4a1 |
rev | line source |
---|---|
12960 | 1 /* small utility to extract CPU information |
17041 | 2 Used by configure to set CPU optimization levels on some operating |
3 systems where /proc/cpuinfo is non-existent or unreliable. */ | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
4 |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
5 #include <stdio.h> |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
6 #include <sys/time.h> |
17040
0bfb87188015
correct k6_mtrr detection, add a great deal of infos about newer processors
gpoirier
parents:
13612
diff
changeset
|
7 #include <stdlib.h> |
0bfb87188015
correct k6_mtrr detection, add a great deal of infos about newer processors
gpoirier
parents:
13612
diff
changeset
|
8 #include <string.h> |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
9 |
9764 | 10 #ifdef __MINGW32__ |
11 #include <sys/timeb.h> | |
17041 | 12 void gettimeofday(struct timeval* t,void* timezone) { |
13 struct timeb timebuffer; | |
14 ftime( &timebuffer ); | |
15 t->tv_sec=timebuffer.time; | |
16 t->tv_usec=1000*timebuffer.millitm; | |
9764 | 17 } |
18 #define MISSING_USLEEP | |
19 #define sleep(t) _sleep(1000*t); | |
20 #endif | |
21 | |
13612 | 22 #ifdef __BEOS__ |
23 #define usleep(t) snooze(t) | |
24 #endif | |
25 | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
26 #ifdef M_UNIX |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
27 typedef long long int64_t; |
17041 | 28 #define MISSING_USLEEP |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
29 #else |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
30 #include <inttypes.h> |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
31 #endif |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
32 |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
33 |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
34 typedef struct cpuid_regs { |
17041 | 35 unsigned int eax; |
36 unsigned int ebx; | |
37 unsigned int ecx; | |
38 unsigned int edx; | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
39 } cpuid_regs_t; |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
40 |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
41 static cpuid_regs_t |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
42 cpuid(int func) { |
17041 | 43 cpuid_regs_t regs; |
44 #define CPUID ".byte 0x0f, 0xa2; " | |
45 asm("push %%ebx; " | |
46 "movl %4,%%eax; " CPUID | |
47 "movl %%eax,%0; movl %%ebx,%1; movl %%ecx,%2; movl %%edx,%3; " | |
48 "pop %%ebx" | |
49 : "=m" (regs.eax), "=m" (regs.ebx), "=m" (regs.ecx), "=m" (regs.edx) | |
50 : "g" (func) | |
51 : "%eax", "%ecx", "%edx"); | |
52 return regs; | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
53 } |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
54 |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
55 |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
56 static int64_t |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
57 rdtsc(void) |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
58 { |
17041 | 59 unsigned int i, j; |
60 #define RDTSC ".byte 0x0f, 0x31; " | |
61 asm(RDTSC : "=a"(i), "=d"(j) : ); | |
62 return ((int64_t)j<<32) + (int64_t)i; | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
63 } |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
64 |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
65 |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
66 static void |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
67 store32(char *d, unsigned int v) |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
68 { |
17041 | 69 d[0] = v & 0xff; |
70 d[1] = (v >> 8) & 0xff; | |
71 d[2] = (v >> 16) & 0xff; | |
72 d[3] = (v >> 24) & 0xff; | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
73 } |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
74 |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
75 |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
76 int |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
77 main(int argc, char **argv) |
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
78 { |
17041 | 79 cpuid_regs_t regs, regs_ext; |
80 char idstr[13]; | |
81 unsigned max_cpuid; | |
82 unsigned max_ext_cpuid; | |
83 unsigned int amd_flags; | |
84 unsigned int amd_flags2; | |
85 char *model_name = "Unknown CPU"; | |
86 int i; | |
87 char processor_name[49]; | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
88 |
17041 | 89 regs = cpuid(0); |
90 max_cpuid = regs.eax; | |
91 /* printf("%d CPUID function codes\n", max_cpuid+1); */ | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
92 |
17041 | 93 store32(idstr+0, regs.ebx); |
94 store32(idstr+4, regs.edx); | |
95 store32(idstr+8, regs.ecx); | |
96 idstr[12] = 0; | |
97 printf("vendor_id\t: %s\n", idstr); | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
98 |
17041 | 99 if (strcmp(idstr, "GenuineIntel") == 0) |
100 model_name = "Unknown Intel CPU"; | |
101 else if (strcmp(idstr, "AuthenticAMD") == 0) | |
102 model_name = "Unknown AMD CPU"; | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
103 |
17041 | 104 regs_ext = cpuid((1<<31) + 0); |
105 max_ext_cpuid = regs_ext.eax; | |
106 if (max_ext_cpuid >= (1<<31) + 1) { | |
107 regs_ext = cpuid((1<<31) + 1); | |
108 amd_flags = regs_ext.edx; | |
109 amd_flags2 = regs_ext.ecx; | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
110 |
17041 | 111 if (max_ext_cpuid >= (1<<31) + 4) { |
112 for (i = 2; i <= 4; i++) { | |
113 regs_ext = cpuid((1<<31) + i); | |
114 store32(processor_name + (i-2)*16, regs_ext.eax); | |
115 store32(processor_name + (i-2)*16 + 4, regs_ext.ebx); | |
116 store32(processor_name + (i-2)*16 + 8, regs_ext.ecx); | |
117 store32(processor_name + (i-2)*16 + 12, regs_ext.edx); | |
118 } | |
119 processor_name[48] = 0; | |
120 model_name = processor_name; | |
121 } | |
122 } else { | |
123 amd_flags = 0; | |
124 amd_flags2 = 0; | |
125 } | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
126 |
17041 | 127 if (max_cpuid >= 1) { |
128 static struct { | |
129 int bit; | |
130 char *desc;; | |
131 char *description; | |
132 } cap[] = { | |
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 { 28, "htt", "Multi-threading" }, | |
160 { 29, "tm", "Therm. Monitor" }, | |
161 { 30, "ia64", "IA-64 Processor" }, | |
162 { 31, "pbe", "Pend. Brk. EN." }, | |
163 { -1 } | |
164 }; | |
165 static struct { | |
166 int bit; | |
167 char *desc; | |
168 char *description; | |
169 } cap2[] = { | |
170 { 0, "sse3", "SSE3 Extensions" }, | |
171 { 3, "monitor", "MONITOR/MWAIT" }, | |
172 { 4, "ds-cpl", "CPL Qualified Debug Store" }, | |
173 { 5, "vmx", "Virtual Machine Extensions" }, | |
174 { 7, "est", "Enhanced Intel SpeedStep Technology" }, | |
175 { 8, "tm2", "Thermal Monitor 2" }, | |
176 { 10, "cnxt-id", "L1 Context ID" }, | |
177 { 13, "cmpxchg16b", "CMPXCHG16B Available" }, | |
178 { -1 } | |
179 }; | |
180 static struct { | |
181 int bit; | |
182 char *desc;; | |
183 char *description; | |
184 } cap_amd[] = { | |
185 { 11, "syscall", "SYSCALL and SYSRET" }, | |
186 { 19, "mp", "MP Capable" }, | |
187 { 20, "nx", "No-Execute Page Protection" }, | |
188 { 22, "mmxext","MMX Technology (AMD Extensions)" }, | |
189 { 25, "fxsr_opt", "Fast FXSAVE/FXRSTOR" }, | |
190 { 27, "rdtscp", "RDTSCP Instruction" }, | |
191 { 30, "3dnowext","3Dnow! Extensions" }, | |
192 { 31, "3dnow", "3Dnow!" }, | |
193 { -1 } | |
194 }; | |
195 static struct { | |
196 int bit; | |
197 char *desc; | |
198 char *description; | |
199 } cap_amd2[] = { | |
200 { 0, "lahf_lm", "LAHF/SAHF Supported in 64-bit Mode" }, | |
201 { 1, "cmp_legacy", "Chip Multi-Core" }, | |
202 { 2, "svm", "Secure Virtual Machine" }, | |
203 { 4, "cr8", "CR8 Available in Legacy Mode" }, | |
204 { -1 } | |
205 }; | |
206 unsigned int family, model, stepping; | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
207 |
17041 | 208 regs = cpuid(1); |
209 printf("cpu family\t: %d\n" | |
210 "model\t\t: %d\n" | |
211 "stepping\t: %d\n" , | |
212 family = (regs.eax >> 8) & 0xf, | |
213 model = (regs.eax >> 4) & 0xf, | |
214 stepping = regs.eax & 0xf); | |
215 | |
216 printf("flags\t\t:"); | |
217 for (i = 0; cap[i].bit >= 0; i++) { | |
218 if (regs.edx & (1 << cap[i].bit)) { | |
219 printf(" %s", cap[i].desc); | |
220 } | |
221 } | |
222 for (i = 0; cap2[i].bit >= 0; i++) { | |
223 if (regs.ecx & (1 << cap[i].bit)) { | |
224 printf(" %s", cap2[i].desc); | |
225 } | |
226 } | |
227 /* k6_mtrr is supported by some AMD K6-2/K6-III CPUs but | |
228 it is not indicated by a CPUID feature bit, so we | |
229 have to check the family, model and stepping instead. */ | |
230 if (strstr(idstr, "AMD") && | |
231 family == 5 && | |
232 (model >= 9 || model == 8 && stepping >= 8)) | |
233 printf(" %s", "k6_mtrr"); | |
17040
0bfb87188015
correct k6_mtrr detection, add a great deal of infos about newer processors
gpoirier
parents:
13612
diff
changeset
|
234 |
17041 | 235 for (i = 0; cap_amd[i].bit >= 0; i++) { |
236 if (amd_flags & (1 << cap_amd[i].bit)) { | |
237 printf(" %s", cap_amd[i].desc); | |
238 } | |
239 } | |
240 for (i = 0; cap_amd2[i].bit >= 0; i++) { | |
241 if (amd_flags2 & (1 << cap_amd2[i].bit)) { | |
242 printf(" %s", cap_amd2[i].desc); | |
243 } | |
244 } | |
245 printf("\n"); | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
246 |
17041 | 247 if (regs.edx & (1 << 4)) { |
248 int64_t tsc_start, tsc_end; | |
249 struct timeval tv_start, tv_end; | |
250 int usec_delay; | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
251 |
17041 | 252 tsc_start = rdtsc(); |
253 gettimeofday(&tv_start, NULL); | |
254 #ifdef MISSING_USLEEP | |
255 sleep(1); | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
256 #else |
17041 | 257 usleep(100000); |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
258 #endif |
17041 | 259 tsc_end = rdtsc(); |
260 gettimeofday(&tv_end, NULL); | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
261 |
17041 | 262 usec_delay = 1000000 * (tv_end.tv_sec - tv_start.tv_sec) |
263 + (tv_end.tv_usec - tv_start.tv_usec); | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
264 |
17041 | 265 printf("cpu MHz\t\t: %.3f\n", |
266 (double)(tsc_end-tsc_start) / usec_delay); | |
267 } | |
268 } | |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
269 |
17041 | 270 printf("model name\t: %s\n", model_name); |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
271 |
17041 | 272 exit(0); |
1038
b36fb1ae4b53
applied solaris8/netbsd/other fixes patch by J¸«ärgen Keil <jk@tools.de>
arpi_esp
parents:
diff
changeset
|
273 } |