Mercurial > mplayer.hg
annotate cpuinfo.c @ 29888:5c39c41f38e8
Deobfuscate the special hack to disable cache for live555.
Cache can not be used for it, since it does not provide any
data stream, the data is provided to the demuxer "behind
MPlayer's back".
author | reimar |
---|---|
date | Tue, 17 Nov 2009 19:23:55 +0000 |
parents | 4520c6c724a6 |
children | c1a3f1bbba26 |
rev | line source |
---|---|
22932 | 1 /* small utility to extract CPU information |
2 Used by configure to set CPU optimization levels on some operating | |
3 systems where /proc/cpuinfo is non-existent or unreliable. */ | |
4 | |
5 #include <stdio.h> | |
6 #include <sys/time.h> | |
7 #include <stdlib.h> | |
8 #include <string.h> | |
9 #include <unistd.h> | |
10 | |
11 #ifdef __MINGW32__ | |
12 #define MISSING_USLEEP | |
13 #include <windows.h> | |
14 #define sleep(t) Sleep(1000*t); | |
15 #endif | |
16 | |
17 #ifdef __BEOS__ | |
18 #define usleep(t) snooze(t) | |
19 #endif | |
20 | |
21 #ifdef M_UNIX | |
22 typedef long long int64_t; | |
23 #define MISSING_USLEEP | |
24 #else | |
25 #include <inttypes.h> | |
26 #endif | |
27 | |
28 #define CPUID_FEATURE_DEF(bit, desc, description) \ | |
29 { bit, desc } | |
30 | |
31 typedef struct cpuid_regs { | |
32 unsigned int eax; | |
33 unsigned int ebx; | |
34 unsigned int ecx; | |
35 unsigned int edx; | |
36 } cpuid_regs_t; | |
37 | |
38 static cpuid_regs_t | |
39 cpuid(int func) { | |
40 cpuid_regs_t regs; | |
41 #define CPUID ".byte 0x0f, 0xa2; " | |
42 #ifdef __x86_64__ | |
27754
08d18fe9da52
Change all occurrences of asm and __asm to __asm__, same as was done for FFmpeg.
diego
parents:
24964
diff
changeset
|
43 __asm__("mov %%rbx, %%rsi\n\t" |
22932 | 44 #else |
27754
08d18fe9da52
Change all occurrences of asm and __asm to __asm__, same as was done for FFmpeg.
diego
parents:
24964
diff
changeset
|
45 __asm__("mov %%ebx, %%esi\n\t" |
22932 | 46 #endif |
47 CPUID"\n\t" | |
48 #ifdef __x86_64__ | |
49 "xchg %%rsi, %%rbx\n\t" | |
50 #else | |
51 "xchg %%esi, %%ebx\n\t" | |
52 #endif | |
53 : "=a" (regs.eax), "=S" (regs.ebx), "=c" (regs.ecx), "=d" (regs.edx) | |
54 : "0" (func)); | |
55 return regs; | |
56 } | |
57 | |
58 | |
59 static int64_t | |
60 rdtsc(void) | |
61 { | |
62 uint64_t i; | |
63 #define RDTSC ".byte 0x0f, 0x31; " | |
27754
08d18fe9da52
Change all occurrences of asm and __asm to __asm__, same as was done for FFmpeg.
diego
parents:
24964
diff
changeset
|
64 __asm__ volatile (RDTSC : "=A"(i) : ); |
22932 | 65 return i; |
66 } | |
67 | |
68 static const char* | |
69 brandname(int i) | |
70 { | |
28597
96dfe52d18ff
cosmetics: const static --> static const, avoids the debug mode warning:
diego
parents:
27774
diff
changeset
|
71 static const char* brandmap[] = { |
22932 | 72 NULL, |
73 "Intel(R) Celeron(R) processor", | |
74 "Intel(R) Pentium(R) III processor", | |
75 "Intel(R) Pentium(R) III Xeon(tm) processor", | |
76 "Intel(R) Pentium(R) III processor", | |
77 NULL, | |
78 "Mobile Intel(R) Pentium(R) III processor-M", | |
79 "Mobile Intel(R) Celeron(R) processor" | |
80 }; | |
81 | |
82 if (i >= sizeof(brandmap)) | |
83 return NULL; | |
84 else | |
85 return brandmap[i]; | |
86 } | |
87 | |
88 static void | |
89 store32(char *d, unsigned int v) | |
90 { | |
91 d[0] = v & 0xff; | |
92 d[1] = (v >> 8) & 0xff; | |
93 d[2] = (v >> 16) & 0xff; | |
94 d[3] = (v >> 24) & 0xff; | |
95 } | |
96 | |
97 | |
98 int | |
28599
3ff0da40013d
cosmetics: Replace unused 'argc/argv' in main declarations by 'void'.
diego
parents:
28597
diff
changeset
|
99 main(void) |
22932 | 100 { |
101 cpuid_regs_t regs, regs_ext; | |
102 char idstr[13]; | |
103 unsigned max_cpuid; | |
104 unsigned max_ext_cpuid; | |
105 unsigned int amd_flags; | |
106 unsigned int amd_flags2; | |
107 const char *model_name = NULL; | |
108 int i; | |
109 char processor_name[49]; | |
110 | |
111 regs = cpuid(0); | |
112 max_cpuid = regs.eax; | |
113 /* printf("%d CPUID function codes\n", max_cpuid+1); */ | |
114 | |
115 store32(idstr+0, regs.ebx); | |
116 store32(idstr+4, regs.edx); | |
117 store32(idstr+8, regs.ecx); | |
118 idstr[12] = 0; | |
23346 | 119 printf("vendor_id\t: %s\n", idstr); |
22932 | 120 |
121 regs_ext = cpuid((1<<31) + 0); | |
122 max_ext_cpuid = regs_ext.eax; | |
123 if (max_ext_cpuid >= (1<<31) + 1) { | |
124 regs_ext = cpuid((1<<31) + 1); | |
125 amd_flags = regs_ext.edx; | |
126 amd_flags2 = regs_ext.ecx; | |
127 | |
128 if (max_ext_cpuid >= (1<<31) + 4) { | |
129 for (i = 2; i <= 4; i++) { | |
130 regs_ext = cpuid((1<<31) + i); | |
131 store32(processor_name + (i-2)*16, regs_ext.eax); | |
132 store32(processor_name + (i-2)*16 + 4, regs_ext.ebx); | |
133 store32(processor_name + (i-2)*16 + 8, regs_ext.ecx); | |
134 store32(processor_name + (i-2)*16 + 12, regs_ext.edx); | |
135 } | |
136 processor_name[48] = 0; | |
137 model_name = processor_name; | |
138 while (*model_name == ' ') { | |
139 model_name++; | |
140 } | |
141 } | |
142 } else { | |
143 amd_flags = 0; | |
144 amd_flags2 = 0; | |
145 } | |
146 | |
147 if (max_cpuid >= 1) { | |
148 static struct { | |
149 int bit; | |
150 char *desc; | |
151 } cap[] = { | |
152 CPUID_FEATURE_DEF(0, "fpu", "Floating-point unit on-chip"), | |
153 CPUID_FEATURE_DEF(1, "vme", "Virtual Mode Enhancements"), | |
154 CPUID_FEATURE_DEF(2, "de", "Debugging Extension"), | |
155 CPUID_FEATURE_DEF(3, "pse", "Page Size Extension"), | |
156 CPUID_FEATURE_DEF(4, "tsc", "Time Stamp Counter"), | |
157 CPUID_FEATURE_DEF(5, "msr", "Pentium Processor MSR"), | |
158 CPUID_FEATURE_DEF(6, "pae", "Physical Address Extension"), | |
159 CPUID_FEATURE_DEF(7, "mce", "Machine Check Exception"), | |
160 CPUID_FEATURE_DEF(8, "cx8", "CMPXCHG8B Instruction Supported"), | |
161 CPUID_FEATURE_DEF(9, "apic", "On-chip APIC Hardware Enabled"), | |
162 CPUID_FEATURE_DEF(11, "sep", "SYSENTER and SYSEXIT"), | |
163 CPUID_FEATURE_DEF(12, "mtrr", "Memory Type Range Registers"), | |
164 CPUID_FEATURE_DEF(13, "pge", "PTE Global Bit"), | |
165 CPUID_FEATURE_DEF(14, "mca", "Machine Check Architecture"), | |
166 CPUID_FEATURE_DEF(15, "cmov", "Conditional Move/Compare Instruction"), | |
167 CPUID_FEATURE_DEF(16, "pat", "Page Attribute Table"), | |
168 CPUID_FEATURE_DEF(17, "pse36", "Page Size Extension 36-bit"), | |
169 CPUID_FEATURE_DEF(18, "pn", "Processor Serial Number"), | |
170 CPUID_FEATURE_DEF(19, "clflush", "CFLUSH instruction"), | |
171 CPUID_FEATURE_DEF(21, "dts", "Debug Store"), | |
172 CPUID_FEATURE_DEF(22, "acpi", "Thermal Monitor and Clock Ctrl"), | |
173 CPUID_FEATURE_DEF(23, "mmx", "MMX Technology"), | |
174 CPUID_FEATURE_DEF(24, "fxsr", "FXSAVE/FXRSTOR"), | |
175 CPUID_FEATURE_DEF(25, "sse", "SSE Extensions"), | |
176 CPUID_FEATURE_DEF(26, "sse2", "SSE2 Extensions"), | |
177 CPUID_FEATURE_DEF(27, "ss", "Self Snoop"), | |
178 CPUID_FEATURE_DEF(28, "ht", "Multi-threading"), | |
179 CPUID_FEATURE_DEF(29, "tm", "Therm. Monitor"), | |
180 CPUID_FEATURE_DEF(30, "ia64", "IA-64 Processor"), | |
181 CPUID_FEATURE_DEF(31, "pbe", "Pend. Brk. EN."), | |
182 { -1 } | |
183 }; | |
184 static struct { | |
185 int bit; | |
186 char *desc; | |
187 } cap2[] = { | |
188 CPUID_FEATURE_DEF(0, "pni", "SSE3 Extensions"), | |
29072 | 189 CPUID_FEATURE_DEF(1, "pclmulqdq", "Carryless Multiplication"), |
190 CPUID_FEATURE_DEF(2, "dtes64", "64-bit Debug Store"), | |
22932 | 191 CPUID_FEATURE_DEF(3, "monitor", "MONITOR/MWAIT"), |
192 CPUID_FEATURE_DEF(4, "ds_cpl", "CPL Qualified Debug Store"), | |
193 CPUID_FEATURE_DEF(5, "vmx", "Virtual Machine Extensions"), | |
194 CPUID_FEATURE_DEF(6, "smx", "Safer Mode Extensions"), | |
195 CPUID_FEATURE_DEF(7, "est", "Enhanced Intel SpeedStep Technology"), | |
196 CPUID_FEATURE_DEF(8, "tm2", "Thermal Monitor 2"), | |
197 CPUID_FEATURE_DEF(9, "ssse3", "Supplemental SSE3"), | |
198 CPUID_FEATURE_DEF(10, "cid", "L1 Context ID"), | |
29072 | 199 CPUID_FEATURE_DEF(12, "fma", "Fused Multiply Add"), |
22932 | 200 CPUID_FEATURE_DEF(13, "cx16", "CMPXCHG16B Available"), |
23345 | 201 CPUID_FEATURE_DEF(14, "xtpr", "xTPR Disable"), |
202 CPUID_FEATURE_DEF(15, "pdcm", "Perf/Debug Capability MSR"), | |
203 CPUID_FEATURE_DEF(18, "dca", "Direct Cache Access"), | |
24964
195a578e07d4
Sync with Linux kernel with some latest feature bits.
zuxy
parents:
23804
diff
changeset
|
204 CPUID_FEATURE_DEF(19, "sse4_1", "SSE4.1 Extensions"), |
195a578e07d4
Sync with Linux kernel with some latest feature bits.
zuxy
parents:
23804
diff
changeset
|
205 CPUID_FEATURE_DEF(20, "sse4_2", "SSE4.2 Extensions"), |
29072 | 206 CPUID_FEATURE_DEF(21, "x2apic", "x2APIC Feature"), |
207 CPUID_FEATURE_DEF(22, "movbe", "MOVBE Instruction"), | |
23345 | 208 CPUID_FEATURE_DEF(23, "popcnt", "Pop Count Instruction"), |
29072 | 209 CPUID_FEATURE_DEF(25, "aes", "AES Instruction"), |
210 CPUID_FEATURE_DEF(26, "xsave", "XSAVE/XRSTOR Extensions"), | |
211 CPUID_FEATURE_DEF(27, "osxsave", "XSAVE/XRSTOR Enabled in the OS"), | |
212 CPUID_FEATURE_DEF(28, "avx", "Advanced Vector Extension"), | |
22932 | 213 { -1 } |
214 }; | |
215 static struct { | |
216 int bit; | |
217 char *desc; | |
218 } cap_amd[] = { | |
219 CPUID_FEATURE_DEF(11, "syscall", "SYSCALL and SYSRET"), | |
220 CPUID_FEATURE_DEF(19, "mp", "MP Capable"), | |
221 CPUID_FEATURE_DEF(20, "nx", "No-Execute Page Protection"), | |
222 CPUID_FEATURE_DEF(22, "mmxext", "MMX Technology (AMD Extensions)"), | |
223 CPUID_FEATURE_DEF(25, "fxsr_opt", "Fast FXSAVE/FXRSTOR"), | |
23344 | 224 CPUID_FEATURE_DEF(26, "pdpe1gb", "PDP Entry for 1GiB Page"), |
22932 | 225 CPUID_FEATURE_DEF(27, "rdtscp", "RDTSCP Instruction"), |
226 CPUID_FEATURE_DEF(29, "lm", "Long Mode Capable"), | |
227 CPUID_FEATURE_DEF(30, "3dnowext", "3DNow! Extensions"), | |
228 CPUID_FEATURE_DEF(31, "3dnow", "3DNow!"), | |
229 { -1 } | |
230 }; | |
231 static struct { | |
232 int bit; | |
233 char *desc; | |
234 } cap_amd2[] = { | |
235 CPUID_FEATURE_DEF(0, "lahf_lm", "LAHF/SAHF Supported in 64-bit Mode"), | |
236 CPUID_FEATURE_DEF(1, "cmp_legacy", "Chip Multi-Core"), | |
237 CPUID_FEATURE_DEF(2, "svm", "Secure Virtual Machine"), | |
23344 | 238 CPUID_FEATURE_DEF(3, "extapic", "Extended APIC Space"), |
29072 | 239 CPUID_FEATURE_DEF(4, "cr8_legacy", "CR8 Available in Legacy Mode"), |
23344 | 240 CPUID_FEATURE_DEF(5, "abm", "Advanced Bit Manipulation"), |
241 CPUID_FEATURE_DEF(6, "sse4a", "SSE4A Extensions"), | |
242 CPUID_FEATURE_DEF(7, "misalignsse", "Misaligned SSE Mode"), | |
243 CPUID_FEATURE_DEF(8, "3dnowprefetch", "3DNow! Prefetch/PrefetchW"), | |
244 CPUID_FEATURE_DEF(9, "osvw", "OS Visible Workaround"), | |
23804 | 245 CPUID_FEATURE_DEF(10, "ibs", "Instruction Based Sampling"), |
24964
195a578e07d4
Sync with Linux kernel with some latest feature bits.
zuxy
parents:
23804
diff
changeset
|
246 CPUID_FEATURE_DEF(11, "sse5", "SSE5 Extensions"), |
195a578e07d4
Sync with Linux kernel with some latest feature bits.
zuxy
parents:
23804
diff
changeset
|
247 CPUID_FEATURE_DEF(12, "skinit", "SKINIT, STGI, and DEV Support"), |
195a578e07d4
Sync with Linux kernel with some latest feature bits.
zuxy
parents:
23804
diff
changeset
|
248 CPUID_FEATURE_DEF(13, "wdt", "Watchdog Timer Support"), |
22932 | 249 { -1 } |
250 }; | |
251 unsigned int family, model, stepping; | |
252 | |
253 regs = cpuid(1); | |
254 family = (regs.eax >> 8) & 0xf; | |
255 model = (regs.eax >> 4) & 0xf; | |
256 stepping = regs.eax & 0xf; | |
257 | |
258 if (family == 0xf) | |
259 family += (regs.eax >> 20) & 0xff; | |
23009
41d042563508
Intel's Conroe-L makes use of extended models, so adjust CPU detection
diego
parents:
22932
diff
changeset
|
260 if (family == 0xf || family == 6) |
22932 | 261 model += ((regs.eax >> 16) & 0xf) << 4; |
262 | |
263 printf("cpu family\t: %d\n" | |
264 "model\t\t: %d\n" | |
265 "stepping\t: %d\n" , | |
266 family, | |
267 model, | |
268 stepping); | |
269 | |
270 if (strstr(idstr, "Intel") && !model_name) { | |
271 if (family == 6 && model == 0xb && stepping == 1) | |
272 model_name = "Intel (R) Celeron (R) processor"; | |
273 else | |
274 model_name = brandname(regs.ebx & 0xf); | |
23346 | 275 } |
22932 | 276 |
277 printf("flags\t\t:"); | |
278 for (i = 0; cap[i].bit >= 0; i++) { | |
279 if (regs.edx & (1 << cap[i].bit)) { | |
280 printf(" %s", cap[i].desc); | |
281 } | |
282 } | |
283 for (i = 0; cap2[i].bit >= 0; i++) { | |
284 if (regs.ecx & (1 << cap2[i].bit)) { | |
285 printf(" %s", cap2[i].desc); | |
286 } | |
287 } | |
288 /* k6_mtrr is supported by some AMD K6-2/K6-III CPUs but | |
289 it is not indicated by a CPUID feature bit, so we | |
290 have to check the family, model and stepping instead. */ | |
291 if (strstr(idstr, "AMD") && | |
23346 | 292 family == 5 && |
28931 | 293 (model >= 9 || (model == 8 && stepping >= 8))) |
22932 | 294 printf(" %s", "k6_mtrr"); |
295 /* similar for cyrix_arr. */ | |
296 if (strstr(idstr, "Cyrix") && | |
28931 | 297 (family == 5 && (model < 4 || family == 6))) |
22932 | 298 printf(" %s", "cyrix_arr"); |
299 /* as well as centaur_mcr. */ | |
300 if (strstr(idstr, "Centaur") && | |
301 family == 5) | |
302 printf(" %s", "centaur_mcr"); | |
23346 | 303 |
22932 | 304 for (i = 0; cap_amd[i].bit >= 0; i++) { |
305 if (amd_flags & (1 << cap_amd[i].bit)) { | |
306 printf(" %s", cap_amd[i].desc); | |
307 } | |
308 } | |
309 for (i = 0; cap_amd2[i].bit >= 0; i++) { | |
310 if (amd_flags2 & (1 << cap_amd2[i].bit)) { | |
311 printf(" %s", cap_amd2[i].desc); | |
312 } | |
313 } | |
314 printf("\n"); | |
315 | |
316 if (regs.edx & (1 << 4)) { | |
317 int64_t tsc_start, tsc_end; | |
318 struct timeval tv_start, tv_end; | |
319 int usec_delay; | |
320 | |
321 tsc_start = rdtsc(); | |
322 gettimeofday(&tv_start, NULL); | |
323 #ifdef MISSING_USLEEP | |
324 sleep(1); | |
325 #else | |
326 usleep(100000); | |
327 #endif | |
328 tsc_end = rdtsc(); | |
329 gettimeofday(&tv_end, NULL); | |
330 | |
331 usec_delay = 1000000 * (tv_end.tv_sec - tv_start.tv_sec) | |
332 + (tv_end.tv_usec - tv_start.tv_usec); | |
333 | |
23345 | 334 printf("cpu MHz\t\t: %.3f\n", |
22932 | 335 (double)(tsc_end-tsc_start) / usec_delay); |
336 } | |
337 } | |
338 | |
339 printf("model name\t: "); | |
340 if (model_name) | |
341 printf("%s\n", model_name); | |
342 else | |
23346 | 343 printf("Unknown %s CPU\n", idstr); |
22932 | 344 } |