comparison TOOLS/cpuinfo.c @ 18511:744aa553e4a1

Various improvement, fix build on AMD-64 and icc Original Thred: Date: Apr 25, 2006 2:23 PM Subject: Re: [MPlayer-dev-eng] Re: [PATCH] Various improvement in TOOLS/cpuinfo.c
author gpoirier
date Sun, 14 May 2006 20:24:47 +0000
parents 4471c5a962ec
children 31c96e2b64b4
comparison
equal deleted inserted replaced
18510:0107ab06df49 18511:744aa553e4a1
4 4
5 #include <stdio.h> 5 #include <stdio.h>
6 #include <sys/time.h> 6 #include <sys/time.h>
7 #include <stdlib.h> 7 #include <stdlib.h>
8 #include <string.h> 8 #include <string.h>
9 #include <unistd.h>
9 10
10 #ifdef __MINGW32__ 11 #ifdef __MINGW32__
11 #include <sys/timeb.h> 12 #include <sys/timeb.h>
12 void gettimeofday(struct timeval* t,void* timezone) { 13 void gettimeofday(struct timeval* t,void* timezone) {
13 struct timeb timebuffer; 14 struct timeb timebuffer;
40 41
41 static cpuid_regs_t 42 static cpuid_regs_t
42 cpuid(int func) { 43 cpuid(int func) {
43 cpuid_regs_t regs; 44 cpuid_regs_t regs;
44 #define CPUID ".byte 0x0f, 0xa2; " 45 #define CPUID ".byte 0x0f, 0xa2; "
45 asm("push %%ebx; " 46 asm( CPUID
46 "movl %4,%%eax; " CPUID 47 : "=a" (regs.eax), "=b" (regs.ebx), "=c" (regs.ecx), "=d" (regs.edx)
47 "movl %%eax,%0; movl %%ebx,%1; movl %%ecx,%2; movl %%edx,%3; " 48 : "0" (func));
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; 49 return regs;
53 } 50 }
54 51
55 52
56 static int64_t 53 static int64_t
57 rdtsc(void) 54 rdtsc(void)
58 { 55 {
59 unsigned int i, j; 56 unsigned int i, j;
60 #define RDTSC ".byte 0x0f, 0x31; " 57 #define RDTSC ".byte 0x0f, 0x31; "
61 asm(RDTSC : "=a"(i), "=d"(j) : ); 58 asm volatile (RDTSC : "=a"(i), "=d"(j) : );
62 return ((int64_t)j<<32) + (int64_t)i; 59 return ((int64_t)j<<32) + (int64_t)i;
63 } 60 }
64 61
62 static const char*
63 brandname(int i)
64 {
65 const static char* brandmap[] = {
66 NULL,
67 "Intel(R) Celeron(R) processor",
68 "Intel(R) Pentium(R) III processor",
69 "Intel(R) Pentium(R) III Xeon(tm) processor",
70 "Intel(R) Pentium(R) III processor",
71 NULL,
72 "Mobile Intel(R) Pentium(R) III processor-M",
73 "Mobile Intel(R) Celeron(R) processor"
74 };
75
76 if (i >= sizeof(brandmap))
77 return NULL;
78 else
79 return brandmap[i];
80 }
65 81
66 static void 82 static void
67 store32(char *d, unsigned int v) 83 store32(char *d, unsigned int v)
68 { 84 {
69 d[0] = v & 0xff; 85 d[0] = v & 0xff;
80 char idstr[13]; 96 char idstr[13];
81 unsigned max_cpuid; 97 unsigned max_cpuid;
82 unsigned max_ext_cpuid; 98 unsigned max_ext_cpuid;
83 unsigned int amd_flags; 99 unsigned int amd_flags;
84 unsigned int amd_flags2; 100 unsigned int amd_flags2;
85 char *model_name = "Unknown CPU"; 101 const char *model_name = NULL;
86 int i; 102 int i;
87 char processor_name[49]; 103 char processor_name[49];
88 104
89 regs = cpuid(0); 105 regs = cpuid(0);
90 max_cpuid = regs.eax; 106 max_cpuid = regs.eax;
93 store32(idstr+0, regs.ebx); 109 store32(idstr+0, regs.ebx);
94 store32(idstr+4, regs.edx); 110 store32(idstr+4, regs.edx);
95 store32(idstr+8, regs.ecx); 111 store32(idstr+8, regs.ecx);
96 idstr[12] = 0; 112 idstr[12] = 0;
97 printf("vendor_id\t: %s\n", idstr); 113 printf("vendor_id\t: %s\n", idstr);
98
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";
103 114
104 regs_ext = cpuid((1<<31) + 0); 115 regs_ext = cpuid((1<<31) + 0);
105 max_ext_cpuid = regs_ext.eax; 116 max_ext_cpuid = regs_ext.eax;
106 if (max_ext_cpuid >= (1<<31) + 1) { 117 if (max_ext_cpuid >= (1<<31) + 1) {
107 regs_ext = cpuid((1<<31) + 1); 118 regs_ext = cpuid((1<<31) + 1);
137 { 4, "tsc", "Time Stamp Counter" }, 148 { 4, "tsc", "Time Stamp Counter" },
138 { 5, "msr", "Pentium Processor MSR" }, 149 { 5, "msr", "Pentium Processor MSR" },
139 { 6, "pae", "Physical Address Extension" }, 150 { 6, "pae", "Physical Address Extension" },
140 { 7, "mce", "Machine Check Exception" }, 151 { 7, "mce", "Machine Check Exception" },
141 { 8, "cx8", "CMPXCHG8B Instruction Supported" }, 152 { 8, "cx8", "CMPXCHG8B Instruction Supported" },
142 { 9, "apic", "On-chip CPIC Hardware Enabled" }, 153 { 9, "apic", "On-chip APIC Hardware Enabled" },
143 { 11, "sep", "SYSENTER and SYSEXIT" }, 154 { 11, "sep", "SYSENTER and SYSEXIT" },
144 { 12, "mtrr", "Memory Type Range Registers" }, 155 { 12, "mtrr", "Memory Type Range Registers" },
145 { 13, "pge", "PTE Global Bit" }, 156 { 13, "pge", "PTE Global Bit" },
146 { 14, "mca", "Machine Check Architecture" }, 157 { 14, "mca", "Machine Check Architecture" },
147 { 15, "cmov", "Conditional Move/Compare Instruction" }, 158 { 15, "cmov", "Conditional Move/Compare Instruction" },
148 { 16, "pat", "Page Attribute Table" }, 159 { 16, "pat", "Page Attribute Table" },
149 { 17, "pse36", "Page Size Extension 36-bit" }, 160 { 17, "pse36", "Page Size Extension 36-bit" },
150 { 18, "psn", "Processor Serial Number" }, 161 { 18, "pn", "Processor Serial Number" },
151 { 19, "cflsh", "CFLUSH instruction" }, 162 { 19, "cflsh", "CFLUSH instruction" },
152 { 21, "ds", "Debug Store" }, 163 { 21, "dts", "Debug Store" },
153 { 22, "acpi", "Thermal Monitor and Clock Ctrl" }, 164 { 22, "acpi", "Thermal Monitor and Clock Ctrl" },
154 { 23, "mmx", "MMX Technology" }, 165 { 23, "mmx", "MMX Technology" },
155 { 24, "fxsr", "FXSAVE/FXRSTOR" }, 166 { 24, "fxsr", "FXSAVE/FXRSTOR" },
156 { 25, "sse", "SSE Extensions" }, 167 { 25, "sse", "SSE Extensions" },
157 { 26, "sse2", "SSE2 Extensions" }, 168 { 26, "sse2", "SSE2 Extensions" },
158 { 27, "ss", "Self Snoop" }, 169 { 27, "ss", "Self Snoop" },
159 { 28, "htt", "Multi-threading" }, 170 { 28, "ht", "Multi-threading" },
160 { 29, "tm", "Therm. Monitor" }, 171 { 29, "tm", "Therm. Monitor" },
161 { 30, "ia64", "IA-64 Processor" }, 172 { 30, "ia64", "IA-64 Processor" },
162 { 31, "pbe", "Pend. Brk. EN." }, 173 { 31, "pbe", "Pend. Brk. EN." },
163 { -1 } 174 { -1 }
164 }; 175 };
165 static struct { 176 static struct {
166 int bit; 177 int bit;
167 char *desc; 178 char *desc;
168 char *description; 179 char *description;
169 } cap2[] = { 180 } cap2[] = {
170 { 0, "sse3", "SSE3 Extensions" }, 181 { 0, "pni", "SSE3 Extensions" },
171 { 3, "monitor", "MONITOR/MWAIT" }, 182 { 3, "monitor", "MONITOR/MWAIT" },
172 { 4, "ds-cpl", "CPL Qualified Debug Store" }, 183 { 4, "ds_cpl", "CPL Qualified Debug Store" },
173 { 5, "vmx", "Virtual Machine Extensions" }, 184 { 5, "vmx", "Virtual Machine Extensions" },
174 { 7, "est", "Enhanced Intel SpeedStep Technology" }, 185 { 7, "est", "Enhanced Intel SpeedStep Technology" },
175 { 8, "tm2", "Thermal Monitor 2" }, 186 { 8, "tm2", "Thermal Monitor 2" },
176 { 10, "cnxt-id", "L1 Context ID" }, 187 { 10, "cid", "L1 Context ID" },
177 { 13, "cmpxchg16b", "CMPXCHG16B Available" }, 188 { 13, "cx16", "CMPXCHG16B Available" },
189 { 14, "xtpr", "xTPR Disable" },
178 { -1 } 190 { -1 }
179 }; 191 };
180 static struct { 192 static struct {
181 int bit; 193 int bit;
182 char *desc;; 194 char *desc;;
186 { 19, "mp", "MP Capable" }, 198 { 19, "mp", "MP Capable" },
187 { 20, "nx", "No-Execute Page Protection" }, 199 { 20, "nx", "No-Execute Page Protection" },
188 { 22, "mmxext","MMX Technology (AMD Extensions)" }, 200 { 22, "mmxext","MMX Technology (AMD Extensions)" },
189 { 25, "fxsr_opt", "Fast FXSAVE/FXRSTOR" }, 201 { 25, "fxsr_opt", "Fast FXSAVE/FXRSTOR" },
190 { 27, "rdtscp", "RDTSCP Instruction" }, 202 { 27, "rdtscp", "RDTSCP Instruction" },
191 { 30, "3dnowext","3Dnow! Extensions" }, 203 { 29, "lm", "Long Mode Capable" },
192 { 31, "3dnow", "3Dnow!" }, 204 { 30, "3dnowext","3DNow! Extensions" },
205 { 31, "3dnow", "3DNow!" },
193 { -1 } 206 { -1 }
194 }; 207 };
195 static struct { 208 static struct {
196 int bit; 209 int bit;
197 char *desc; 210 char *desc;
198 char *description; 211 char *description;
199 } cap_amd2[] = { 212 } cap_amd2[] = {
200 { 0, "lahf_lm", "LAHF/SAHF Supported in 64-bit Mode" }, 213 { 0, "lahf_lm", "LAHF/SAHF Supported in 64-bit Mode" },
201 { 1, "cmp_legacy", "Chip Multi-Core" }, 214 { 1, "cmp_legacy", "Chip Multi-Core" },
202 { 2, "svm", "Secure Virtual Machine" }, 215 { 2, "svm", "Secure Virtual Machine" },
203 { 4, "cr8", "CR8 Available in Legacy Mode" }, 216 { 4, "cr8legacy", "CR8 Available in Legacy Mode" },
204 { -1 } 217 { -1 }
205 }; 218 };
206 unsigned int family, model, stepping; 219 unsigned int family, model, stepping;
207 220
208 regs = cpuid(1); 221 regs = cpuid(1);
222 family = (regs.eax >> 8) & 0xf;
223 model = (regs.eax >> 4) & 0xf;
224 stepping = regs.eax & 0xf;
225
226 if (family == 0xf)
227 {
228 family += (regs.eax >> 20) & 0xff;
229 model += ((regs.eax >> 16) & 0xf) << 4;
230 }
231
209 printf("cpu family\t: %d\n" 232 printf("cpu family\t: %d\n"
210 "model\t\t: %d\n" 233 "model\t\t: %d\n"
211 "stepping\t: %d\n" , 234 "stepping\t: %d\n" ,
212 family = (regs.eax >> 8) & 0xf, 235 family,
213 model = (regs.eax >> 4) & 0xf, 236 model,
214 stepping = regs.eax & 0xf); 237 stepping);
215 238
239 if (strstr(idstr, "Intel") && !model_name) {
240 if (family == 6 && model == 0xb && stepping == 1)
241 model_name = "Intel (R) Celeron (R) processor";
242 else
243 model_name = brandname(regs.ebx & 0xf);
244 }
245
216 printf("flags\t\t:"); 246 printf("flags\t\t:");
217 for (i = 0; cap[i].bit >= 0; i++) { 247 for (i = 0; cap[i].bit >= 0; i++) {
218 if (regs.edx & (1 << cap[i].bit)) { 248 if (regs.edx & (1 << cap[i].bit)) {
219 printf(" %s", cap[i].desc); 249 printf(" %s", cap[i].desc);
220 } 250 }
221 } 251 }
222 for (i = 0; cap2[i].bit >= 0; i++) { 252 for (i = 0; cap2[i].bit >= 0; i++) {
223 if (regs.ecx & (1 << cap[i].bit)) { 253 if (regs.ecx & (1 << cap2[i].bit)) {
224 printf(" %s", cap2[i].desc); 254 printf(" %s", cap2[i].desc);
225 } 255 }
226 } 256 }
227 /* k6_mtrr is supported by some AMD K6-2/K6-III CPUs but 257 /* 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 258 it is not indicated by a CPUID feature bit, so we
229 have to check the family, model and stepping instead. */ 259 have to check the family, model and stepping instead. */
230 if (strstr(idstr, "AMD") && 260 if (strstr(idstr, "AMD") &&
231 family == 5 && 261 family == 5 &&
232 (model >= 9 || model == 8 && stepping >= 8)) 262 (model >= 9 || model == 8 && stepping >= 8))
233 printf(" %s", "k6_mtrr"); 263 printf(" %s", "k6_mtrr");
234 264 /* similar for cyrix_arr. */
265 if (strstr(idstr, "Cyrix") &&
266 (family == 5 && model < 4 || family == 6))
267 printf(" %s", "cyrix_arr");
268
235 for (i = 0; cap_amd[i].bit >= 0; i++) { 269 for (i = 0; cap_amd[i].bit >= 0; i++) {
236 if (amd_flags & (1 << cap_amd[i].bit)) { 270 if (amd_flags & (1 << cap_amd[i].bit)) {
237 printf(" %s", cap_amd[i].desc); 271 printf(" %s", cap_amd[i].desc);
238 } 272 }
239 } 273 }
265 printf("cpu MHz\t\t: %.3f\n", 299 printf("cpu MHz\t\t: %.3f\n",
266 (double)(tsc_end-tsc_start) / usec_delay); 300 (double)(tsc_end-tsc_start) / usec_delay);
267 } 301 }
268 } 302 }
269 303
270 printf("model name\t: %s\n", model_name); 304 printf("model name\t: ");
271 305 if (model_name)
272 exit(0); 306 printf("%s\n", model_name);
273 } 307 else
308 printf("Unknown %s CPU\n", idstr);
309 }