5 #define CUT(x, a, b) (((x)&((1<<((b)+1))-1))>>(a))
14 0x5E, /* POP SI (PC) */
15 0x5D, /* POP BP (Res&) */
24 0x31, 0xDB, /* XOR BX, BX */
25 0x31, 0xD2, /* XOR DX, DX */
27 0x0F, 0xA2, /* CPUID */
29 0x89, 0x45, 0x00, /* MOV AX, 0(BP) */
30 0x89, 0x5d, 0x04, /* MOV BX, 4(BP) */
31 0x89, 0x4d, 0x08, /* MOV CX, 8(BP) */
32 0x89, 0x55, 0x0C, /* MOV DX, 12(BP) */
36 Res (*cpuid)(ulong ax, ulong cx) = (Res(*)(ulong, ulong)) _cpuid;
45 ((ulong *) buf)[0] = r.bx;
46 ((ulong *) buf)[1] = r.dx;
47 ((ulong *) buf)[2] = r.cx;
49 Bprint(out, "vendor %s\n", buf);
53 printbits(char *id, ulong x, char **s)
57 for(i = 0, j = 0; i < 32; i++)
58 if((x & (1<<i)) != 0 && s[i] != nil){
62 Bprint(out, "%s ", id);
64 Bprint(out, "%s ", s[i]);
75 static char *bitsdx[32] = {
76 [0] "fpu", "vme", "de", "pse",
77 [4] "tsc", "msr", "pae", "mce",
78 [8] "cx8", "apic", nil, "sep",
79 [12] "mtrr", "pge", "mca", "cmov",
80 [16] "pat", "pse36", "pn", "clflush",
81 [20] nil, "dts", "acpi", "mmx",
82 [24] "fxsr", "sse", "sse2", "ss",
83 [28] "ht", "tm", "ia64", "pbe",
85 static char *bitscx[32] = {
86 [0] "pni", "pclmulqdq", "dtes64", "monitor",
87 [4] "ds_cpl", "vmx", "smx", "est",
88 [8] "tm2", "ssse3", "cid", nil,
89 [12] "fma", "cx16", "xtpr", "pdcm",
90 [16] nil, "pcid", "dca", "sse4_1",
91 [20] "sse4_2", "x2apic", "movbe", "popcnt",
92 [24] "tscdeadline", "aes", "xsave", "osxsave",
93 [28] "avx", "f16c", "rdrnd", "hypervisor",
97 Bprint(out, "procmodel %.8ulx / %.8ulx\n", r.ax, r.bx);
98 family = r.ax >> 8 & 0xf;
99 model = r.ax >> 8 & 0xf;
101 family += r.ax >> 20 & 0xff;
102 if(family == 6 || family == 15)
103 model += r.ax >> 12 & 0xf0;
104 Bprint(out, "typefammod %.1x %.2x %.3x %.1x\n", (int)(r.ax >> 12 & 3), family, model, (int)(r.ax & 0xf));
105 printbits("features", r.dx, bitsdx);
106 printbits("features", r.cx, bitscx);
113 static char *bitsax[32] = {
118 printbits("features", r.ax, bitsax);
125 static char *bitsdx[32] = {
126 [0] "fpu", "vme", "de", "pse",
127 [4] "tsc", "msr", "pae", "mce",
128 [8] "cx8", "apic", nil, "syscall",
129 [12] "mtrr", "pge", "mca", "cmov",
130 [16] "pat", "pse36", nil, "mp",
131 [20] "nx", nil, "mmx+", "mmx",
132 [24] "fxsr", "ffxsr", "pg1g", "tscp",
133 [28] nil, "lm", "3dnow!+", "3dnow!",
135 static char *bitscx[32] = {
136 [0] "ahf64", "cmp", "svm", "eas",
137 [4] "cr8d", "lzcnt", "sse4a", "msse",
138 [8] "3dnow!p", "osvw", "ibs", "xop",
139 [12] "skinit", "wdt", nil, "lwp",
140 [16] "fma4", "tce", nil, "nodeid",
141 [20] nil, "tbm", "topx", "pcx_core",
142 [24] "pcx_nb", nil, nil, nil,
143 [28] nil, nil, nil, nil,
147 Bprint(out, "extmodel %.8ulx / %.8ulx\n", r.ax, r.bx);
148 printbits("extfeatures", r.dx, bitsdx);
149 printbits("extfeatures", r.cx, bitscx);
163 for(i = 0; i < 3; i++){
164 r = cpuid(0x80000002 + i, 0);
165 ((ulong *) buf)[4 * i + 0] = r.ax;
166 ((ulong *) buf)[4 * i + 1] = r.bx;
167 ((ulong *) buf)[4 * i + 2] = r.cx;
168 ((ulong *) buf)[4 * i + 3] = r.dx;
173 Bprint(out, "procname %s\n", p);
182 Bprint(out, "physbits %uld\n", CUT(r.ax, 0, 7));
183 Bprint(out, "virtbits %uld\n", CUT(r.ax, 8, 15));
184 if(CUT(r.ax, 16, 23) != 0)
185 Bprint(out, "guestbits %uld\n", CUT(r.ax, 16, 23));
188 void (*funcs[])(ulong) = {
194 void (*extfuncs[])(ulong) = {
208 Bprint(out, "%.8ulx %.8ulx %.8ulx %.8ulx %.8ulx\n", ax, r.ax, r.bx, r.cx, r.dx);
211 char Egreg[] = "this information is classified";
214 notehand(void *, char *s)
216 if(strncmp(s, "sys:", 4) == 0)
222 main(int argc, char **argv)
231 case 'r': rflag++; break;
232 case 'a': aflag++; break;
235 /* first long in a.out header */
236 w = *(ulong *)(((uintptr)main)&~0xfff);
241 case 0x978a0000: /* amd64 */
242 /* patch out POP BP -> POP AX */
244 case 0xeb010000: /* 386 */
247 Binit(&buf, 1, OWRITE);
250 for(i = 0; i <= r.ax; i++)
251 if(i >= nelem(funcs) || funcs[i] == nil || rflag){
256 r = cpuid(0x80000000, 0);
257 if(r.ax < 0x80000000)
260 for(i = 0; i <= r.ax; i++)
261 if(i >= nelem(extfuncs) || extfuncs[i] == nil || rflag){
263 stdfunc(0x80000000 | i);
265 extfuncs[i](0x80000000 | i);