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