~ubuntu-branches/ubuntu/wily/gmerlin-encoders/wily-proposed

« back to all changes in this revision

Viewing changes to utils/cpuinfo.c

  • Committer: Bazaar Package Importer
  • Author(s): IOhannes m zmoelnig (gpg-key at iem)
  • Date: 2011-01-15 20:19:05 UTC
  • Revision ID: james.westby@ubuntu.com-20110115201905-qign5pihv1b977ct
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * cpuinfo.c from the MPlayer project's TOOLS/ directory
 
3
 *
 
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'.
 
7
 *
 
8
 * NOTE: Only for the X86 cpu family.
 
9
*/
 
10
#include <stdio.h>
 
11
#include <sys/time.h>
 
12
#include <stdlib.h>
 
13
#include <unistd.h>
 
14
#include <string.h>
 
15
 
 
16
#ifdef __MINGW32__
 
17
#include <sys/timeb.h>
 
18
void gettimeofday(struct timeval* t,void* timezone)
 
19
{       struct timeb timebuffer;
 
20
        ftime( &timebuffer );
 
21
        t->tv_sec=timebuffer.time;
 
22
        t->tv_usec=1000*timebuffer.millitm;
 
23
}
 
24
#define MISSING_USLEEP
 
25
#define sleep(t) _sleep(1000*t);
 
26
#endif
 
27
 
 
28
#ifdef M_UNIX
 
29
typedef long long int64_t;
 
30
#define MISSING_USLEEP
 
31
#else
 
32
#include <inttypes.h>
 
33
#endif
 
34
 
 
35
 
 
36
typedef struct cpuid_regs {
 
37
        unsigned int eax;
 
38
        unsigned int ebx;
 
39
        unsigned int ecx;
 
40
        unsigned int edx;
 
41
} cpuid_regs_t;
 
42
 
 
43
static cpuid_regs_t
 
44
cpuid(int func) {
 
45
        cpuid_regs_t regs;
 
46
#define CPUID   ".byte 0x0f, 0xa2; "
 
47
        asm("push %%ebx; "
 
48
            "movl %4,%%eax; " CPUID
 
49
            "movl %%eax,%0; movl %%ebx,%1; movl %%ecx,%2; movl %%edx,%3;"
 
50
            "pop %%ebx"
 
51
            : "=m" (regs.eax), "=m" (regs.ebx), "=m" (regs.ecx), "=m" (regs.edx)
 
52
            : "g" (func)
 
53
            : "%eax", "%ecx", "%edx");
 
54
        return regs;
 
55
}
 
56
 
 
57
 
 
58
static int64_t
 
59
rdtsc(void)
 
60
{
 
61
        unsigned int i, j;
 
62
#define RDTSC   ".byte 0x0f, 0x31; "
 
63
        asm(RDTSC : "=a"(i), "=d"(j) : );
 
64
        return ((int64_t)j<<32) + (int64_t)i;
 
65
}
 
66
 
 
67
 
 
68
static void
 
69
store32(char *d, unsigned int v)
 
70
{
 
71
        d[0] =  v        & 0xff;
 
72
        d[1] = (v >>  8) & 0xff;
 
73
        d[2] = (v >> 16) & 0xff;
 
74
        d[3] = (v >> 24) & 0xff;
 
75
}
 
76
 
 
77
 
 
78
int
 
79
main(int argc, char **argv)
 
80
{
 
81
        cpuid_regs_t regs, regs_ext;
 
82
        char idstr[13];
 
83
        unsigned max_cpuid;
 
84
        unsigned max_ext_cpuid;
 
85
        unsigned int amd_flags;
 
86
        unsigned int cpuType, cpuModel;
 
87
        char *model_name = "Unknown CPU";
 
88
        int i;
 
89
        char processor_name[49];
 
90
 
 
91
        regs = cpuid(0);
 
92
        max_cpuid = regs.eax;
 
93
        /* printf("%d CPUID function codes\n", max_cpuid+1); */
 
94
 
 
95
        store32(idstr+0, regs.ebx);
 
96
        store32(idstr+4, regs.edx);
 
97
        store32(idstr+8, regs.ecx);
 
98
        idstr[12] = 0;
 
99
        printf("vendor_id\t: %s\n", idstr); 
 
100
 
 
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";
 
105
 
 
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;
 
111
 
 
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);
 
119
                }
 
120
                processor_name[48] = 0;
 
121
                model_name = processor_name;
 
122
            }
 
123
        } else {
 
124
            amd_flags = 0;
 
125
        }
 
126
 
 
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
                        { 29, "tm",    "Therm. Monitor" },
 
160
                        { -1 }
 
161
                };
 
162
                static struct {
 
163
                        int bit;
 
164
                        char *desc;;
 
165
                        char *description;
 
166
                } cap_amd[] = {
 
167
                        { 22, "mmxext","MMX Technology (AMD Extensions)" },
 
168
                        { 30, "3dnowext","3Dnow! Extensions" },
 
169
                        { 31, "3dnow", "3Dnow!" },
 
170
                        { 32, "k6_mtrr", "Memory Type Range Registers" },
 
171
                        { -1 }
 
172
                };
 
173
                int i;
 
174
 
 
175
                regs = cpuid(1);
 
176
 
 
177
                cpuType = (regs.eax >> 8) & 0xf;
 
178
                cpuModel = (regs.eax >> 4) & 0xf;
 
179
 
 
180
                if (cpuType == 0xf)
 
181
                   cpuType = 0xf + ((regs.eax >> 20) & 0xf); // extended family
 
182
                if (cpuType == 0xf || cpuType == 6)
 
183
                   cpuModel |= ((regs.eax >> 16) & 0xf) << 4;
 
184
 
 
185
                printf("cpu family\t: %d\n"
 
186
                       "model\t\t: %d\n"
 
187
                       "stepping\t: %d\n" ,
 
188
                        cpuType,
 
189
                        cpuModel,
 
190
                        regs.eax        & 0xf);
 
191
                
 
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);
 
196
                        }
 
197
                }
 
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);
 
201
                        }
 
202
                }
 
203
                printf("\n");
 
204
 
 
205
                if (regs.edx & (1 << 4)) {
 
206
                        int64_t tsc_start, tsc_end;
 
207
                        struct timeval tv_start, tv_end;
 
208
                        int usec_delay;
 
209
 
 
210
                        tsc_start = rdtsc();
 
211
                        gettimeofday(&tv_start, NULL);
 
212
#ifdef  MISSING_USLEEP
 
213
                        sleep(1);
 
214
#else
 
215
                        usleep(100000);
 
216
#endif
 
217
                        tsc_end = rdtsc();
 
218
                        gettimeofday(&tv_end, NULL);
 
219
 
 
220
                        usec_delay = 1000000 * (tv_end.tv_sec - tv_start.tv_sec)
 
221
                                + (tv_end.tv_usec - tv_start.tv_usec);
 
222
 
 
223
                        printf("cpu MHz\t\t: %.3f\n", 
 
224
                                (double)(tsc_end-tsc_start) / usec_delay);
 
225
                }
 
226
        }
 
227
 
 
228
        printf("model name\t: %s\n", model_name);
 
229
 
 
230
        exit(0);
 
231
}