3 * Determine x86 CPU model number
5 * (c) 2009 Mark Wooding
8 /*----- Licensing notice --------------------------------------------------*
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 /*----- Header files ------------------------------------------------------*/
31 #include <mLib/mdwopt.h>
32 #include <mLib/quis.h>
33 #include <mLib/report.h>
35 #if !defined(__GNUC__) || !defined(__i386__)
36 # error "This isn't going to work."
39 /*----- Data structures ---------------------------------------------------*/
41 struct cpuid
{ unsigned eax
, ebx
, ecx
, edx
; };
43 /*----- Main code ---------------------------------------------------------*/
45 static inline void cpuid(unsigned leaf
, struct cpuid
*c
)
58 static void identify(unsigned f
)
61 unsigned stepping
, model
, family
, type
, extmodel
, extfamily
;
62 unsigned dispfamily
, dispmodel
;
65 stepping
= (c
.eax
>> 0) & 0x0f;
66 model
= (c
.eax
>> 4) & 0x0f;
67 family
= (c
.eax
>> 8) & 0x0f;
68 type
= (c
.eax
>> 12) & 0x03;
69 extmodel
= (c
.eax
>> 16) & 0x0f;
70 extfamily
= (c
.eax
>> 20) & 0xff;
72 dispfamily
= family
+ (family
== 0x0f ? extfamily
: 0);
73 dispmodel
= model
| (family
== 0x06 || family
== 0x0f ? extmodel
<< 4 : 0);
76 printf("%02X_%02XH\n", dispfamily
, dispmodel
);
78 printf("type = %d\n", type
);
79 printf("family = %d", dispfamily
);
81 printf(" (base = %d, extended = %d)", family
, extfamily
);
83 printf("model = %d", dispmodel
);
84 if (family
== 0x06 || family
== 0x0f)
85 printf(" (base = %d, extended = %d)", model
, extmodel
);
87 printf("stepping = %d\n", type
);
91 static void dump(unsigned leaf
)
99 printf("%08x: %08x %08x %08x %08x\n", leaf
, c
.eax
, c
.ebx
, c
.ecx
, c
.edx
);
107 static void usage(FILE *fp
)
108 { pquis(fp
, "Usage: $ [-v] [-i | -d | [-s] LEAF | -x LEAF]\n"); }
110 static void version(void)
111 { pquis(stdout
, "$, version " VERSION
); }
113 static void help(void)
115 version(); putchar('\n'); usage(stdout
);
117 Shows information about the host's processor. You may find cpuid(1) more\n\
122 -h, --help This useless help text.\n\
123 -V, --version Program's version number.\n\
124 -u, --usage Short usage summary.\n\
126 -v, --verbose Show more detailed information.\n\
128 -i, --identify Show CPU display-model designation. [default]\n\
129 -s, --show=LEAF Show named leaf of CPUID data.\n\
130 -x, --extended=LEAF Show named extended leaf of CPUID data.\n\
131 -d, --dump Dump all CPUID information.\n");
134 int main(int argc
, char *argv
[])
140 const char *leafstr
= 0;
141 unsigned long leaf
= -1;
155 static const struct option opts
[] = {
156 { "help", 0, 0, 'h' },
157 { "version", 0, 0, 'V' },
158 { "usage", 0, 0, 'u' },
159 { "verbose", 0, 0, 'v' },
160 { "identify", 0, 0, 'i' },
161 { "dump", 0, 0, 'd' },
162 { "show", OPTF_ARGREQ
, 0, 's' },
163 { "extended", OPTF_ARGREQ
, 0, 'x' },
167 if ((i
= mdwopt(argc
, argv
, "hVu" "v" "ids:x:", opts
, 0, 0, 0)) < 0)
183 if (mode
) f
|= f_bogus
;
187 if (mode
) f
|= f_bogus
;
191 if (mode
) f
|= f_bogus
;
196 if (mode
) f
|= f_bogus
;
206 argv
+= optind
; argc
-= optind
;
207 if ((f
& f_bogus
) || argc
> 1 || (mode
&& argc
)) {
218 leaf
= strtoul(leafstr
, &q
, 0);
219 if (q
== leafstr
|| *q
|| errno
|| leaf
> 0xffffffff)
220 die(EXIT_FAILURE
, "bad leaf value: %s", leafstr
);
233 if (!(f
& f_verbose
))
234 printf("%08x %08x %08x %08x\n", c
.eax
, c
.ebx
, c
.ecx
, c
.edx
);
236 printf("EAX = %08x\n", c
.eax
);
237 printf("EBX = %08x\n", c
.ebx
);
238 printf("ECX = %08x\n", c
.ecx
);
239 printf("EDX = %08x\n", c
.edx
);
253 /*----- That's all, folks -------------------------------------------------*/