]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/aux/cpuid.c
exec(2): fix prototypes
[plan9front.git] / sys / src / cmd / aux / cpuid.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4
5 #define CUT(x, a, b) (((x)&((1<<((b)+1))-1))>>(a))
6
7 typedef struct Res {
8         ulong ax, bx, cx, dx;
9 } Res;
10
11 Biobuf *out;
12
13 uchar _cpuid[] = {
14         0x5E,                   /* POP SI (PC) */
15         0x5D,                   /* POP BP (Res&) */
16         0x58,                   /* POP AX */
17         0x59,                   /* POP CX */
18
19         0x51,                   /* PUSH CX */
20         0x50,                   /* PUSH AX */
21         0x55,                   /* PUSH BP */
22         0x56,                   /* PUSH SI */
23
24         0x31, 0xDB,             /* XOR BX, BX */
25         0x31, 0xD2,             /* XOR DX, DX */
26
27         0x0F, 0xA2,             /* CPUID */
28
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) */
33         0xC3,                   /* RET */
34 };
35
36 Res (*cpuid)(ulong ax, ulong cx) = (Res(*)(ulong, ulong)) _cpuid;
37
38 void
39 func0(ulong)
40 {
41         Res r;
42         char buf[13];
43
44         r = cpuid(0, 0);
45         ((ulong *) buf)[0] = r.bx;
46         ((ulong *) buf)[1] = r.dx;
47         ((ulong *) buf)[2] = r.cx;
48         buf[13] = 0;
49         Bprint(out, "vendor %s\n", buf);
50 }
51
52 void
53 printbits(char *id, ulong x, char **s)
54 {
55         int i, j;
56
57         for(i = 0, j = 0; i < 32; i++)
58                 if((x & (1<<i)) != 0 && s[i] != nil){
59                         if(j++ % 16 == 0){
60                                 if(j != 1)
61                                         Bprint(out, "\n");
62                                 Bprint(out, "%s ", id);
63                         }
64                         Bprint(out, "%s ", s[i]);
65                 }
66         if(j % 16 != 0)
67                 Bprint(out, "\n");
68 }
69
70 void
71 func1(ulong)
72 {
73         Res r;
74         static char *bitsdx[32] = {
75                 [0]             "fpu",  "vme",   "de",   "pse",
76                 [4]             "tsc",  "msr",   "pae",  "mce",
77                 [8]             "cx8",  "apic",  nil,    "sep",
78                 [12]    "mtrr", "pge",   "mca",  "cmov",
79                 [16]    "pat",  "pse36", "pn",   "clflush",
80                 [20]    nil,    "dts",   "acpi", "mmx",
81                 [24]    "fxsr", "sse",   "sse2", "ss",
82                 [28]    "ht",   "tm",    "ia64", "pbe",
83         };
84         static char *bitscx[32] = {
85                 [0]             "pni",         "pclmulqdq", "dtes64", "monitor",
86                 [4]             "ds_cpl",      "vmx",       "smx",    "est",
87                 [8]             "tm2",         "ssse3",     "cid",    nil,
88                 [12]    "fma",         "cx16",      "xtpr",   "pdcm",
89                 [16]    nil,           "pcid",      "dca",    "sse4_1",
90                 [20]    "sse4_2",      "x2apic",    "movbe",  "popcnt",
91                 [24]    "tscdeadline", "aes",       "xsave",  "osxsave",
92                 [28]    "avx",         "f16c",      "rdrnd",  "hypervisor",
93         };
94
95         r = cpuid(1, 0);
96         Bprint(out, "procmodel %.8ulx / %.8ulx\n", r.ax, r.bx);
97         printbits("features", r.dx, bitsdx);
98         printbits("features", r.cx, bitscx);
99 }
100
101 void
102 func13(ulong)
103 {
104         Res r;
105         static char *bitsax[32] = {
106                 [0]     "xsaveopt",
107         };
108
109         r = cpuid(13, 1);
110         printbits("features", r.ax, bitsax);
111 }
112
113 void
114 extfunc1(ulong ax)
115 {
116         Res r;
117         static char *bitsdx[32] = {
118                 [0]             "fpu",  "vme",   "de",      "pse",
119                 [4]             "tsc",  "msr",   "pae",     "mce",
120                 [8]             "cx8",  "apic",  nil,       "syscall",
121                 [12]    "mtrr", "pge",   "mca",     "cmov",
122                 [16]    "pat",  "pse36", nil,       "mp",
123                 [20]    "nx",   nil,     "mmx+",    "mmx",
124                 [24]    "fxsr", "ffxsr", "pg1g",    "tscp",
125                 [28]    nil,    "lm",    "3dnow!+", "3dnow!",
126         };
127         static char *bitscx[32] = {
128                 [0]             "ahf64",   "cmp",   "svm",   "eas",
129                 [4]             "cr8d",    "lzcnt", "sse4a", "msse",
130                 [8]             "3dnow!p", "osvw",  "ibs",   "xop",
131                 [12]    "skinit",  "wdt",   nil,     "lwp",
132                 [16]    "fma4",    "tce",   nil,     "nodeid",
133                 [20]    nil,       "tbm",   "topx",  "pcx_core",
134                 [24]    "pcx_nb",  nil,     nil,     nil,
135                 [28]    nil,       nil,     nil,     nil,
136         };
137
138         r = cpuid(ax, 0);
139         Bprint(out, "extmodel %.8ulx / %.8ulx\n", r.ax, r.bx);
140         printbits("extfeatures", r.dx, bitsdx);
141         printbits("extfeatures", r.cx, bitscx);
142 }
143
144 void
145 extfunc2(ulong ax)
146 {
147         char buf[49];
148         int i;
149         Res r;
150         char *p;
151
152         if(ax != 0x80000004)
153                 return;
154         buf[48] = 0;
155         for(i = 0; i < 3; i++){
156                 r = cpuid(0x80000002 + i, 0);
157                 ((ulong *) buf)[4 * i + 0] = r.ax;
158                 ((ulong *) buf)[4 * i + 1] = r.bx;
159                 ((ulong *) buf)[4 * i + 2] = r.cx;
160                 ((ulong *) buf)[4 * i + 3] = r.dx;
161         }
162         p = buf;
163         while(*p == ' ')
164                 p++;
165         Bprint(out, "procname %s\n", p);
166 }
167
168 void
169 extfunc8(ulong ax)
170 {
171         Res r;
172
173         r = cpuid(ax, 0);
174         Bprint(out, "physbits %uld\n", CUT(r.ax, 0, 7));
175         Bprint(out, "virtbits %uld\n", CUT(r.ax, 8, 15));
176         if(CUT(r.ax, 16, 23) != 0)
177                 Bprint(out, "guestbits %uld\n", CUT(r.ax, 16, 23));
178 }
179
180 void (*funcs[])(ulong) = {
181         [0]     func0,
182         [1]     func1,
183         [13]    func13,
184 };
185
186 void (*extfuncs[])(ulong) = {
187         [1] extfunc1,
188         [2] extfunc2,
189         [3] extfunc2,
190         [4] extfunc2,
191         [8] extfunc8,
192 };
193
194 void
195 stdfunc(ulong ax)
196 {
197         Res r;
198
199         r = cpuid(ax, 0);
200         Bprint(out, "%.8ulx %.8ulx %.8ulx %.8ulx %.8ulx\n", ax, r.ax, r.bx, r.cx, r.dx);
201 }
202
203 char Egreg[] = "this information is classified";
204
205 void
206 notehand(void *, char *s)
207 {
208         if(strncmp(s, "sys:", 4) == 0)
209                 sysfatal(Egreg);
210         noted(NDFLT);
211 }
212
213 void
214 main(int argc, char **argv)
215 {
216         Res r;
217         int i, rflag, aflag;
218         ulong w;
219         static Biobuf buf;
220
221         rflag = aflag = 0;
222         ARGBEGIN {
223         case 'r': rflag++; break;
224         case 'a': aflag++; break;
225         } ARGEND;
226         notify(notehand);
227         /* first long in a.out header */
228         w = *(ulong *)(((uintptr)main)&~0xfff);
229         notify(nil);
230         switch(w){
231         default:
232                 sysfatal(Egreg);
233         case 0x978a0000:        /* amd64 */
234                 /* patch out POP BP -> POP AX */
235                 _cpuid[1] = 0x58;
236         case 0xeb010000:        /* 386 */
237                 break;
238         }
239         Binit(&buf, 1, OWRITE);
240         out = &buf;
241         r = cpuid(0, 0);
242         for(i = 0; i <= r.ax; i++)
243                 if(i >= nelem(funcs) || funcs[i] == nil || rflag){
244                         if(rflag || aflag)
245                                 stdfunc(i);
246                 }else
247                         funcs[i](i);
248         r = cpuid(0x80000000, 0);
249         r.ax -= 0x80000000;
250         for(i = 0; i <= r.ax; i++)
251                 if(i >= nelem(extfuncs) || extfuncs[i] == nil || rflag){
252                         if(rflag || aflag)
253                                 stdfunc(0x80000000 | i);
254                 }else
255                         extfuncs[i](0x80000000 | i);
256         Bterm(out);
257 }