diff options
author | aiju <aiju@phicode.de> | 2012-08-24 18:49:25 +0200 |
---|---|---|
committer | aiju <aiju@phicode.de> | 2012-08-24 18:49:25 +0200 |
commit | 6edb672951d130524adbe5d7ff19f1f6d610cefc (patch) | |
tree | 1da4104c60001ad80d3a34171e2f2c818e348c75 | |
parent | c42a535fe9517c5faa9beaae64f0d5123321ae72 (diff) |
added aux/cpuid
-rw-r--r-- | sys/src/cmd/aux/cpuid.c | 208 | ||||
-rw-r--r-- | sys/src/cmd/aux/mkfile | 1 |
2 files changed, 209 insertions, 0 deletions
diff --git a/sys/src/cmd/aux/cpuid.c b/sys/src/cmd/aux/cpuid.c new file mode 100644 index 000000000..8312445cf --- /dev/null +++ b/sys/src/cmd/aux/cpuid.c @@ -0,0 +1,208 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +#define CUT(x, a, b) (((x)&((1<<(b))-1))>>(a)) + +typedef struct Res { + ulong ax, bx, cx, dx; +} Res; + +Biobuf *out; + +uchar _cpuid[] = { + 0x8B, 0x44, 0x24, 0x08, /* MOV 8(SP), AX */ + 0x31, 0xDB, /* XOR BX, BX */ + 0x8B, 0x4C, 0x24, 0x0C, /* MOV 12(SP), CX */ + 0x31, 0xD2, /* XOR DX, DX */ + 0x0F, 0xA2, /* CPUID */ + 0x8B, 0x7C, 0x24, 0x04, /* MOV 4(SP), DI */ + 0x89, 0x07, /* MOV AX, (DI) */ + 0x89, 0x5F, 0x04, /* MOV BX, 4(DI) */ + 0x89, 0x4F, 0x08, /* MOV CX, 8(DI) */ + 0x89, 0x57, 0x0C, /* MOV DX, 12(DI) */ + 0xC3 /* RET */ +}; + +Res (*cpuid)(ulong ax, ulong cx) = (Res(*)(ulong, ulong)) _cpuid; + +void +func0(ulong) +{ + Res r; + char buf[13]; + + r = cpuid(0, 0); + ((ulong *) buf)[0] = r.bx; + ((ulong *) buf)[1] = r.dx; + ((ulong *) buf)[2] = r.cx; + buf[13] = 0; + Bprint(out, "vendor %s\n", buf); +} + +void +printbits(char *id, ulong x, char **s) +{ + int i, j; + + for(i = 0, j = 0; i < 32; i++) + if((x & (1<<i)) != 0 && s[i] != nil){ + if(j++ % 16 == 0){ + if(j != 1) + Bprint(out, "\n"); + Bprint(out, "%s ", id); + } + Bprint(out, "%s ", s[i]); + } + if(j % 16 != 0) + Bprint(out, "\n"); +} + +void +func1(ulong) +{ + Res r; + static char *bitsdx[32] = { + "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", "cx8", "apic", + nil, "sep", "mtrr", "pge", "mca", "cmov", "pat", "pse36", "pn", "clflush", + nil, "dts", "acpi", "mmx", "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe", + }; + static char *bitscx[32] = { + "pni", "pclmulqdq", "dtes64", "monitor", "ds_cpl", "vmx", "smx", "est", "tm2", "ssse3", + "cid", nil, "fma", "cx16", "xtpr", "pdcm", nil, "pcid", "dca", "sse4_1", "sse4_2", "x2apic", + "movbe", "popcnt", "tscdeadline", "aes", "xsave", "osxsave", "avx", + "f16c", "rdrnd", "hypervisor" + }; + + r = cpuid(1, 0); + Bprint(out, "procmodel %.8ulx / %.8ulx\n", r.ax, r.bx); + printbits("features", r.dx, bitsdx); + printbits("features", r.cx, bitscx); +} + +void +extfunc1(ulong ax) +{ + Res r; + static char *bitsdx[32] = { + "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", "cx8", "apic", "sep", "mtrr", "pge", + "mca", "cmov", "pat", "fcmov", "pse36", nil, "mp", "nx", nil, "mmx+", "mmx", nil, + "ffxsr", "pg1g", "tscp", nil, "lm", "3dnow!+", "3dnow" + }; + static char *bitscx[32] = { + "ahf64", "cmp", "svm", "eas", "cr8d", "lzcnt", "sse4a", "msse", "3dnow!p", "osvw", "ibs", + "xop", "skinit", "wdt", nil, "lwp", "fma4", "tce", nil, "nodeid", nil, "tbm", "topx", + "pcx_core", "pcx_nb", + }; + + r = cpuid(ax, 0); + Bprint(out, "extmodel %.8ulx / %.8ulx\n", r.ax, r.bx); + printbits("extfeatures", r.dx, bitsdx); + printbits("extfeatures", r.cx, bitscx); +} + +void +extfunc2(ulong ax) +{ + char buf[49]; + int i; + Res r; + char *p; + + if(ax != 0x80000004) + return; + buf[48] = 0; + for(i = 0; i < 3; i++){ + r = cpuid(0x80000002 + i, 0); + ((ulong *) buf)[4 * i + 0] = r.ax; + ((ulong *) buf)[4 * i + 1] = r.bx; + ((ulong *) buf)[4 * i + 2] = r.cx; + ((ulong *) buf)[4 * i + 3] = r.dx; + } + p = buf; + while(*p == ' ') + p++; + Bprint(out, "procname %s\n", p); +} + +void +extfunc8(ulong ax) +{ + Res r; + + r = cpuid(ax, 0); + Bprint(out, "physbits %uld\n", CUT(r.ax, 0, 7)); + Bprint(out, "virtbits %uld\n", CUT(r.ax, 8, 15)); + if(CUT(r.ax, 16, 23) != 0) + Bprint(out, "guestbits %uld\n", CUT(r.ax, 16, 23)); +} + +void (*funcs[])(ulong) = { + [0] func0, + [1] func1, +}; + +void (*extfuncs[])(ulong) = { + [1] extfunc1, + [2] extfunc2, + [3] extfunc2, + [4] extfunc2, + [8] extfunc8, +}; + +void +stdfunc(ulong ax) +{ + Res r; + + r = cpuid(ax, 0); + Bprint(out, "%.8ulx %.8ulx %.8ulx %.8ulx %.8ulx\n", ax, r.ax, r.bx, r.cx, r.dx); +} + +char Egreg[] = "this information is classified"; + +void +notehand(void *, char *s) +{ + if(strncmp(s, "sys:", 4) == 0) + sysfatal(Egreg); + noted(NDFLT); +} + +void +main(int argc, char **argv) +{ + Res r; + int i, rflag, aflag; + ulong w; + static Biobuf buf; + + rflag = aflag = 0; + ARGBEGIN { + case 'r': rflag++; break; + case 'a': aflag++; break; + } ARGEND; + notify(notehand); + w = *(ulong *)0x1000; + notify(nil); + if(w != 0xeb010000) + sysfatal(Egreg); + Binit(&buf, 1, OWRITE); + out = &buf; + r = cpuid(0, 0); + for(i = 0; i <= r.ax; i++) + if(i >= nelem(funcs) || funcs[i] == nil || rflag){ + if(rflag || aflag) + stdfunc(i); + }else + funcs[i](i); + r = cpuid(0x80000000, 0); + r.ax -= 0x80000000; + for(i = 0; i <= r.ax; i++) + if(i >= nelem(extfuncs) || extfuncs[i] == nil || rflag){ + if(rflag || aflag) + stdfunc(0x80000000 | i); + }else + extfuncs[i](0x80000000 | i); + Bterm(out); +} diff --git a/sys/src/cmd/aux/mkfile b/sys/src/cmd/aux/mkfile index 4299dbfda..0017e2cb9 100644 --- a/sys/src/cmd/aux/mkfile +++ b/sys/src/cmd/aux/mkfile @@ -11,6 +11,7 @@ TARG=\ cddb\ cdsh\ clog\ + cpuid\ consolefs\ data2s\ depend\ |