]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/aux/cpuid.c
aux/cpuid: fix wrong extfunc1 bits
[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                 "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", "cx8", "apic",
67                 nil, "sep", "mtrr", "pge", "mca", "cmov", "pat", "pse36", "pn", "clflush",
68                 nil, "dts", "acpi", "mmx", "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
69         };
70         static char *bitscx[32] = {
71                 "pni", "pclmulqdq", "dtes64", "monitor", "ds_cpl", "vmx", "smx", "est", "tm2", "ssse3",
72                 "cid", nil, "fma", "cx16", "xtpr", "pdcm", nil, "pcid", "dca", "sse4_1", "sse4_2", "x2apic",
73                 "movbe", "popcnt", "tscdeadline", "aes", "xsave", "osxsave", "avx", 
74                 "f16c", "rdrnd", "hypervisor"
75         };
76
77         r = cpuid(1, 0);
78         Bprint(out, "procmodel %.8ulx / %.8ulx\n", r.ax, r.bx);
79         printbits("features", r.dx, bitsdx);
80         printbits("features", r.cx, bitscx);
81 }
82
83 void
84 extfunc1(ulong ax)
85 {
86         Res r;
87         static char *bitsdx[32] = {
88                 "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", "cx8", "apic",
89                 nil, "syscall", "mtrr", "pge", "mca", "cmov", "pat", "pse36", nil, "mp",
90                 "nx", nil, "mmx+", "mmx", "fxsr", "ffxsr", "pg1g", "tscp", nil, "lm", "3dnow!+", "3dnow!"
91         };
92         static char *bitscx[32] = {
93                 "ahf64", "cmp", "svm", "eas", "cr8d", "lzcnt", "sse4a", "msse", "3dnow!p", "osvw", "ibs",
94                 "xop", "skinit", "wdt", nil, "lwp", "fma4", "tce", nil, "nodeid", nil, "tbm", "topx",
95                 "pcx_core", "pcx_nb",
96         };
97
98         r = cpuid(ax, 0);
99         Bprint(out, "extmodel %.8ulx / %.8ulx\n", r.ax, r.bx);
100         printbits("extfeatures", r.dx, bitsdx);
101         printbits("extfeatures", r.cx, bitscx);
102 }
103
104 void
105 extfunc2(ulong ax)
106 {
107         char buf[49];
108         int i;
109         Res r;
110         char *p;
111
112         if(ax != 0x80000004)
113                 return;
114         buf[48] = 0;
115         for(i = 0; i < 3; i++){
116                 r = cpuid(0x80000002 + i, 0);
117                 ((ulong *) buf)[4 * i + 0] = r.ax;
118                 ((ulong *) buf)[4 * i + 1] = r.bx;
119                 ((ulong *) buf)[4 * i + 2] = r.cx;
120                 ((ulong *) buf)[4 * i + 3] = r.dx;
121         }
122         p = buf;
123         while(*p == ' ')
124                 p++;
125         Bprint(out, "procname %s\n", p);
126 }
127
128 void
129 extfunc8(ulong ax)
130 {
131         Res r;
132
133         r = cpuid(ax, 0);
134         Bprint(out, "physbits %uld\n", CUT(r.ax, 0, 7));
135         Bprint(out, "virtbits %uld\n", CUT(r.ax, 8, 15));
136         if(CUT(r.ax, 16, 23) != 0)
137                 Bprint(out, "guestbits %uld\n", CUT(r.ax, 16, 23));
138 }
139
140 void (*funcs[])(ulong) = {
141         [0] func0,
142         [1] func1,
143 };
144
145 void (*extfuncs[])(ulong) = {
146         [1] extfunc1,
147         [2] extfunc2,
148         [3] extfunc2,
149         [4] extfunc2,
150         [8] extfunc8,
151 };
152
153 void
154 stdfunc(ulong ax)
155 {
156         Res r;
157
158         r = cpuid(ax, 0);
159         Bprint(out, "%.8ulx %.8ulx %.8ulx %.8ulx %.8ulx\n", ax, r.ax, r.bx, r.cx, r.dx);
160 }
161
162 char Egreg[] = "this information is classified";
163
164 void
165 notehand(void *, char *s)
166 {
167         if(strncmp(s, "sys:", 4) == 0)
168                 sysfatal(Egreg);
169         noted(NDFLT);
170 }
171
172 void
173 main(int argc, char **argv)
174 {
175         Res r;
176         int i, rflag, aflag;
177         ulong w;
178         static Biobuf buf;
179
180         rflag = aflag = 0;
181         ARGBEGIN {
182         case 'r': rflag++; break;
183         case 'a': aflag++; break;
184         } ARGEND;
185         notify(notehand);
186         w = *(ulong *)0x1000;
187         notify(nil);
188         if(w != 0xeb010000)
189                 sysfatal(Egreg);
190         Binit(&buf, 1, OWRITE);
191         out = &buf;
192         r = cpuid(0, 0);
193         for(i = 0; i <= r.ax; i++)
194                 if(i >= nelem(funcs) || funcs[i] == nil || rflag){
195                         if(rflag || aflag)
196                                 stdfunc(i);
197                 }else
198                         funcs[i](i);
199         r = cpuid(0x80000000, 0);
200         r.ax -= 0x80000000;
201         for(i = 0; i <= r.ax; i++)
202                 if(i >= nelem(extfuncs) || extfuncs[i] == nil || rflag){
203                         if(rflag || aflag)
204                                 stdfunc(0x80000000 | i);
205                 }else
206                         extfuncs[i](0x80000000 | i);
207         Bterm(out);
208 }