Mercurial > mplayer.hg
annotate cpuinfo.c @ 24515:c5c0cb0e90d2
getch2: Fix incorrect test
Keycode length wasn't checked in one case because of missing
parentheses. This was accidentally broken in my previous commit to the
file. Most likely the error had no practical effect; the length checks
are unreliable in any case as they can be satisfied by unrelated
data corresponding to other keypresses.
author | uau |
---|---|
date | Sat, 15 Sep 2007 18:13:56 +0000 |
parents | 10ac5a193118 |
children | 195a578e07d4 |
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 #if defined(__MINGW32__) && (__MINGW32_MAJOR_VERSION <= 3) && (__MINGW32_MINOR_VERSION < 10) | |
12 #include <sys/timeb.h> | |
13 void gettimeofday(struct timeval* t,void* timezone) { | |
14 struct timeb timebuffer; | |
15 ftime( &timebuffer ); | |
16 t->tv_sec=timebuffer.time; | |
17 t->tv_usec=1000*timebuffer.millitm; | |
18 } | |
19 #endif | |
20 #ifdef __MINGW32__ | |
21 #define MISSING_USLEEP | |
22 #include <windows.h> | |
23 #define sleep(t) Sleep(1000*t); | |
24 #endif | |
25 | |
26 #ifdef __BEOS__ | |
27 #define usleep(t) snooze(t) | |
28 #endif | |
29 | |
30 #ifdef M_UNIX | |
31 typedef long long int64_t; | |
32 #define MISSING_USLEEP | |
33 #else | |
34 #include <inttypes.h> | |
35 #endif | |
36 | |
37 #define CPUID_FEATURE_DEF(bit, desc, description) \ | |
38 { bit, desc } | |
39 | |
40 typedef struct cpuid_regs { | |
41 unsigned int eax; | |
42 unsigned int ebx; | |
43 unsigned int ecx; | |
44 unsigned int edx; | |
45 } cpuid_regs_t; | |
46 | |
47 static cpuid_regs_t | |
48 cpuid(int func) { | |
49 cpuid_regs_t regs; | |
50 #define CPUID ".byte 0x0f, 0xa2; " | |
51 #ifdef __x86_64__ | |
52 asm("mov %%rbx, %%rsi\n\t" | |
53 #else | |
23346 | 54 asm("mov %%ebx, %%esi\n\t" |
22932 | 55 #endif |
56 CPUID"\n\t" | |
57 #ifdef __x86_64__ | |
58 "xchg %%rsi, %%rbx\n\t" | |
59 #else | |
60 "xchg %%esi, %%ebx\n\t" | |
61 #endif | |
62 : "=a" (regs.eax), "=S" (regs.ebx), "=c" (regs.ecx), "=d" (regs.edx) | |
63 : "0" (func)); | |
64 return regs; | |
65 } | |
66 | |
67 | |
68 static int64_t | |
69 rdtsc(void) | |
70 { | |
71 uint64_t i; | |
72 #define RDTSC ".byte 0x0f, 0x31; " | |
73 asm volatile (RDTSC : "=A"(i) : ); | |
74 return i; | |
75 } | |
76 | |
77 static const char* | |
78 brandname(int i) | |
79 { | |
80 const static char* brandmap[] = { | |
81 NULL, | |
82 "Intel(R) Celeron(R) processor", | |
83 "Intel(R) Pentium(R) III processor", | |
84 "Intel(R) Pentium(R) III Xeon(tm) processor", | |
85 "Intel(R) Pentium(R) III processor", | |
86 NULL, | |
87 "Mobile Intel(R) Pentium(R) III processor-M", | |
88 "Mobile Intel(R) Celeron(R) processor" | |
89 }; | |
90 | |
91 if (i >= sizeof(brandmap)) | |
92 return NULL; | |
93 else | |
94 return brandmap[i]; | |
95 } | |
96 | |
97 static void | |
98 store32(char *d, unsigned int v) | |
99 { | |
100 d[0] = v & 0xff; | |
101 d[1] = (v >> 8) & 0xff; | |
102 d[2] = (v >> 16) & 0xff; | |
103 d[3] = (v >> 24) & 0xff; | |
104 } | |
105 | |
106 | |
107 int | |
108 main(int argc, char **argv) | |
109 { | |
110 cpuid_regs_t regs, regs_ext; | |
111 char idstr[13]; | |
112 unsigned max_cpuid; | |
113 unsigned max_ext_cpuid; | |
114 unsigned int amd_flags; | |
115 unsigned int amd_flags2; | |
116 const char *model_name = NULL; | |
117 int i; | |
118 char processor_name[49]; | |
119 | |
120 regs = cpuid(0); | |
121 max_cpuid = regs.eax; | |
122 /* printf("%d CPUID function codes\n", max_cpuid+1); */ | |
123 | |
124 store32(idstr+0, regs.ebx); | |
125 store32(idstr+4, regs.edx); | |
126 store32(idstr+8, regs.ecx); | |
127 idstr[12] = 0; | |
23346 | 128 printf("vendor_id\t: %s\n", idstr); |
22932 | 129 |
130 regs_ext = cpuid((1<<31) + 0); | |
131 max_ext_cpuid = regs_ext.eax; | |
132 if (max_ext_cpuid >= (1<<31) + 1) { | |
133 regs_ext = cpuid((1<<31) + 1); | |
134 amd_flags = regs_ext.edx; | |
135 amd_flags2 = regs_ext.ecx; | |
136 | |
137 if (max_ext_cpuid >= (1<<31) + 4) { | |
138 for (i = 2; i <= 4; i++) { | |
139 regs_ext = cpuid((1<<31) + i); | |
140 store32(processor_name + (i-2)*16, regs_ext.eax); | |
141 store32(processor_name + (i-2)*16 + 4, regs_ext.ebx); | |
142 store32(processor_name + (i-2)*16 + 8, regs_ext.ecx); | |
143 store32(processor_name + (i-2)*16 + 12, regs_ext.edx); | |
144 } | |
145 processor_name[48] = 0; | |
146 model_name = processor_name; | |
147 while (*model_name == ' ') { | |
148 model_name++; | |
149 } | |
150 } | |
151 } else { | |
152 amd_flags = 0; | |
153 amd_flags2 = 0; | |
154 } | |
155 | |
156 if (max_cpuid >= 1) { | |
157 static struct { | |
158 int bit; | |
159 char *desc; | |
160 } cap[] = { | |
161 CPUID_FEATURE_DEF(0, "fpu", "Floating-point unit on-chip"), | |
162 CPUID_FEATURE_DEF(1, "vme", "Virtual Mode Enhancements"), | |
163 CPUID_FEATURE_DEF(2, "de", "Debugging Extension"), | |
164 CPUID_FEATURE_DEF(3, "pse", "Page Size Extension"), | |
165 CPUID_FEATURE_DEF(4, "tsc", "Time Stamp Counter"), | |
166 CPUID_FEATURE_DEF(5, "msr", "Pentium Processor MSR"), | |
167 CPUID_FEATURE_DEF(6, "pae", "Physical Address Extension"), | |
168 CPUID_FEATURE_DEF(7, "mce", "Machine Check Exception"), | |
169 CPUID_FEATURE_DEF(8, "cx8", "CMPXCHG8B Instruction Supported"), | |
170 CPUID_FEATURE_DEF(9, "apic", "On-chip APIC Hardware Enabled"), | |
171 CPUID_FEATURE_DEF(11, "sep", "SYSENTER and SYSEXIT"), | |
172 CPUID_FEATURE_DEF(12, "mtrr", "Memory Type Range Registers"), | |
173 CPUID_FEATURE_DEF(13, "pge", "PTE Global Bit"), | |
174 CPUID_FEATURE_DEF(14, "mca", "Machine Check Architecture"), | |
175 CPUID_FEATURE_DEF(15, "cmov", "Conditional Move/Compare Instruction"), | |
176 CPUID_FEATURE_DEF(16, "pat", "Page Attribute Table"), | |
177 CPUID_FEATURE_DEF(17, "pse36", "Page Size Extension 36-bit"), | |
178 CPUID_FEATURE_DEF(18, "pn", "Processor Serial Number"), | |
179 CPUID_FEATURE_DEF(19, "clflush", "CFLUSH instruction"), | |
180 CPUID_FEATURE_DEF(21, "dts", "Debug Store"), | |
181 CPUID_FEATURE_DEF(22, "acpi", "Thermal Monitor and Clock Ctrl"), | |
182 CPUID_FEATURE_DEF(23, "mmx", "MMX Technology"), | |
183 CPUID_FEATURE_DEF(24, "fxsr", "FXSAVE/FXRSTOR"), | |
184 CPUID_FEATURE_DEF(25, "sse", "SSE Extensions"), | |
185 CPUID_FEATURE_DEF(26, "sse2", "SSE2 Extensions"), | |
186 CPUID_FEATURE_DEF(27, "ss", "Self Snoop"), | |
187 CPUID_FEATURE_DEF(28, "ht", "Multi-threading"), | |
188 CPUID_FEATURE_DEF(29, "tm", "Therm. Monitor"), | |
189 CPUID_FEATURE_DEF(30, "ia64", "IA-64 Processor"), | |
190 CPUID_FEATURE_DEF(31, "pbe", "Pend. Brk. EN."), | |
191 { -1 } | |
192 }; | |
193 static struct { | |
194 int bit; | |
195 char *desc; | |
196 } cap2[] = { | |
197 CPUID_FEATURE_DEF(0, "pni", "SSE3 Extensions"), | |
198 CPUID_FEATURE_DEF(3, "monitor", "MONITOR/MWAIT"), | |
199 CPUID_FEATURE_DEF(4, "ds_cpl", "CPL Qualified Debug Store"), | |
200 CPUID_FEATURE_DEF(5, "vmx", "Virtual Machine Extensions"), | |
201 CPUID_FEATURE_DEF(6, "smx", "Safer Mode Extensions"), | |
202 CPUID_FEATURE_DEF(7, "est", "Enhanced Intel SpeedStep Technology"), | |
203 CPUID_FEATURE_DEF(8, "tm2", "Thermal Monitor 2"), | |
204 CPUID_FEATURE_DEF(9, "ssse3", "Supplemental SSE3"), | |
205 CPUID_FEATURE_DEF(10, "cid", "L1 Context ID"), | |
206 CPUID_FEATURE_DEF(13, "cx16", "CMPXCHG16B Available"), | |
23345 | 207 CPUID_FEATURE_DEF(14, "xtpr", "xTPR Disable"), |
208 CPUID_FEATURE_DEF(15, "pdcm", "Perf/Debug Capability MSR"), | |
209 CPUID_FEATURE_DEF(18, "dca", "Direct Cache Access"), | |
210 CPUID_FEATURE_DEF(19, "sse41", "SSE4.1 Extensions"), | |
211 CPUID_FEATURE_DEF(20, "sse42", "SSE4.2 Extensions"), | |
212 CPUID_FEATURE_DEF(23, "popcnt", "Pop Count Instruction"), | |
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"), |
22932 | 239 CPUID_FEATURE_DEF(4, "cr8legacy", "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"), |
22932 | 246 { -1 } |
247 }; | |
248 unsigned int family, model, stepping; | |
249 | |
250 regs = cpuid(1); | |
251 family = (regs.eax >> 8) & 0xf; | |
252 model = (regs.eax >> 4) & 0xf; | |
253 stepping = regs.eax & 0xf; | |
254 | |
255 if (family == 0xf) | |
256 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
|
257 if (family == 0xf || family == 6) |
22932 | 258 model += ((regs.eax >> 16) & 0xf) << 4; |
259 | |
260 printf("cpu family\t: %d\n" | |
261 "model\t\t: %d\n" | |
262 "stepping\t: %d\n" , | |
263 family, | |
264 model, | |
265 stepping); | |
266 | |
267 if (strstr(idstr, "Intel") && !model_name) { | |
268 if (family == 6 && model == 0xb && stepping == 1) | |
269 model_name = "Intel (R) Celeron (R) processor"; | |
270 else | |
271 model_name = brandname(regs.ebx & 0xf); | |
23346 | 272 } |
22932 | 273 |
274 printf("flags\t\t:"); | |
275 for (i = 0; cap[i].bit >= 0; i++) { | |
276 if (regs.edx & (1 << cap[i].bit)) { | |
277 printf(" %s", cap[i].desc); | |
278 } | |
279 } | |
280 for (i = 0; cap2[i].bit >= 0; i++) { | |
281 if (regs.ecx & (1 << cap2[i].bit)) { | |
282 printf(" %s", cap2[i].desc); | |
283 } | |
284 } | |
285 /* k6_mtrr is supported by some AMD K6-2/K6-III CPUs but | |
286 it is not indicated by a CPUID feature bit, so we | |
287 have to check the family, model and stepping instead. */ | |
288 if (strstr(idstr, "AMD") && | |
23346 | 289 family == 5 && |
22932 | 290 (model >= 9 || model == 8 && stepping >= 8)) |
291 printf(" %s", "k6_mtrr"); | |
292 /* similar for cyrix_arr. */ | |
293 if (strstr(idstr, "Cyrix") && | |
294 (family == 5 && model < 4 || family == 6)) | |
295 printf(" %s", "cyrix_arr"); | |
296 /* as well as centaur_mcr. */ | |
297 if (strstr(idstr, "Centaur") && | |
298 family == 5) | |
299 printf(" %s", "centaur_mcr"); | |
23346 | 300 |
22932 | 301 for (i = 0; cap_amd[i].bit >= 0; i++) { |
302 if (amd_flags & (1 << cap_amd[i].bit)) { | |
303 printf(" %s", cap_amd[i].desc); | |
304 } | |
305 } | |
306 for (i = 0; cap_amd2[i].bit >= 0; i++) { | |
307 if (amd_flags2 & (1 << cap_amd2[i].bit)) { | |
308 printf(" %s", cap_amd2[i].desc); | |
309 } | |
310 } | |
311 printf("\n"); | |
312 | |
313 if (regs.edx & (1 << 4)) { | |
314 int64_t tsc_start, tsc_end; | |
315 struct timeval tv_start, tv_end; | |
316 int usec_delay; | |
317 | |
318 tsc_start = rdtsc(); | |
319 gettimeofday(&tv_start, NULL); | |
320 #ifdef MISSING_USLEEP | |
321 sleep(1); | |
322 #else | |
323 usleep(100000); | |
324 #endif | |
325 tsc_end = rdtsc(); | |
326 gettimeofday(&tv_end, NULL); | |
327 | |
328 usec_delay = 1000000 * (tv_end.tv_sec - tv_start.tv_sec) | |
329 + (tv_end.tv_usec - tv_start.tv_usec); | |
330 | |
23345 | 331 printf("cpu MHz\t\t: %.3f\n", |
22932 | 332 (double)(tsc_end-tsc_start) / usec_delay); |
333 } | |
334 } | |
335 | |
336 printf("model name\t: "); | |
337 if (model_name) | |
338 printf("%s\n", model_name); | |
339 else | |
23346 | 340 printf("Unknown %s CPU\n", idstr); |
22932 | 341 } |