--- /n/sources/plan9/sys/src/cmd/aux/mkfile Thu Aug 16 22:50:45 2012 +++ /sys/src/cmd/aux/mkfile Fri Jul 12 00:00:00 2013 @@ -49,6 +49,7 @@ +#include +#include + +enum { + Dmistart = 0x000F0000, + Dmiend = 0x000FFFFF, + Dmisz = Dmiend+1 - Dmistart, +}; + +typedef struct Enum Enum; +typedef struct Item Item; +typedef struct Itemv Itemv; +typedef struct Smbuf Smbuf; +typedef struct Sm Sm; +typedef struct Smval Smval; +typedef uvlong uintmem; /* wierd */ + +struct Enum { + uint v; + char *s; +}; + +struct Smbuf { + uchar sig[4]; + uchar cksum; + uchar len; + uchar vers[2]; + uchar maxss[2]; /* maximum structure size */ + uchar eprev; /* entry point revision */ + uchar fma[5]; /* formatted area */ + uchar dmi[5]; /* _DMI_ */ + uchar dmicksum; + uchar stlen[2]; + uchar stpa[4]; /* structure table pa */ + uchar nstrut[2]; + uchar bcdrev; +}; + +struct Smval { + int type; + int hand; + int len; + + Item *i; + Itemv *v; +}; + +struct Sm { + Smbuf raw; + uintmem stpa; + uint stlen; + + uint n; /* count of structures */ + Smval *v; +}; + +struct Item{ + char *name; + int nbytes; + int type; + int offset; + char *fmt; + Enum *tab; +}; + +struct Itemv{ + union { + char *s; + uvlong i; + uchar uuid[16]; + }; +}; + +enum { + Biosinfo = 0, + Sysinfo = 1, + Module = 2, + Chassis = 3, + Cpu = 4, + Memctlr = 5, /* obs. */ + Memstk = 6, /* obs. */ + Cache = 7, + Conn = 8, + Slot = 9, + Obddev = 10, /* obs. */ + Oemstr = 11, + Sysconf = 12, + Bioslang = 13, + Groupa = 14, + Syslog = 15, /* requires extra poking around */ + Pmem = 16, + Mdev = 17, + Merror = 18, + Mmap = 19, + Mmdev = 20, + Pointer = 21, + Battery = 22, + Wdog = 23, + Hwsec = 24, + Syspwr = 25, + Vprobe = 26, + Fan = 27, + Tprobe = 28, + Cprobe = 29, + Bootinfo = 32, + Merror64 = 33, + Mgmt = 34, + Mgmtc = 35, + Mgmtdt = 36, + Memch = 37, + Ipmi = 38, + Ps = 39, + Obd = 41, + Inactive = 126, + End = 127, +}; + +Enum tabletab[] = { + 0, "biosinfo", + 1, "sysinfo", + 2, "module", + 3, "chassis", + 4, "cpu", + 5, "memctlr", + 6, "memstk", + 7, "cache", + 8, "conn", + 9, "slot", + 10, "obddev", + 11, "oemstr", + 12, "sysconf", + 13, "bioslang", + 14, "groupa", + 15, "syslog", + 16, "pmem", + 17, "mdev", + 18, "merror", + 19, "mmap", + 20, "mmdev", + 21, "pointer", + 22, "battery", + 23, "wdog", + 24, "hwsec", + 25, "syspwr", + 26, "vprobe", + 27, "fan", + 28, "tprobe", + 29, "cprobe", + 31, "bis", + 32, "bootinfo", + 33, "merror64", + 34, "mgmt", + 35, "mgmtc", + 36, "mgmtdt", + 37, "memch", + 38, "ipmi", + 39, "ps", + 41, "obd", + 126, "inactive", + 127, "end", + 0, nil, +}; + +uchar *dmianchor[0x20]; +int rfd = -1; +int prtype = -1; +int prhand = -1; +int verbose; +Biobuf outsb; +Biobuf *out; + +#define Bvprint(...) do if(verbose) Bprint(__VA_ARGS__); while(0) + +void +realmodefd(void) +{ + if(rfd != -1) + return; + rfd = open("/dev/realmodemem", OREAD); + if(rfd == -1) + sysfatal("open: %r"); +} + +void* +emalloc(usize sz) +{ + void *v; + + v = malloc(sz); + if(v == nil) + sysfatal("malloc: %r"); + memset(v, 0, sz); + setmalloctag(v, getcallerpc(&sz)); + return v; +} + +enum { + String, + Integer, + Uchar, + Enumf, + Enumbv, +}; + +Item biositems[] = { + "vendor", 1, String, -1, "%s", nil, + "version", 1, String, -1, "%s", nil, + "biosstartseg", 2, Integer, -1, "%#.4llux", nil, + "biosdate", 1, String, -1, "%s", nil, + "biosromsz", 1, Integer, -1, "%#.4llux", nil, // _+1<<16 + "biosflags", 8, Uchar, -1, "%.8H", nil, + "extflags0", 1, Integer, -1, "%.2llux", nil, + "extflags1", 1, Integer, -1, "%.2llux", nil, + "release0", 1, Integer, -1, "%.2llux", nil, + "release1", 1, Integer, -1, "%.2llux", nil, + "embedrelease0", 1, Integer, -1, "%.2llux", nil, + "embedrelease1", 1, Integer, -1, "%.2llux", nil, +}; + +Enum waketype[] = { + 0, "reserved", + 1, "other", + 2, "unknown", + 3, "apmtimer", + 4, "modem", + 5, "lan", + 6, "powersw", + 7, "pcipme", + 8, "powerrestored", + 0, nil, +}; + +Item sysitems[] = { + "mfg", 1, String, -1, "%s", nil, + "product", 1, String, -1, "%s", nil, + "version", 1, String, -1, "%s", nil, + "serial", 1, String, -1, "%s", nil, + "uuid", 16, Uchar, -1, "%.16H", nil, + "waketype", 1, Enumf, -1, "%s", waketype, + "sku", 1, String, -1, "%s", nil, + "family", 1, String, -1, "%s", nil, +}; + +Item moditems[] = { + "bbmfg", 1, String, -1, "%s", nil, + "product", 1, String, -1, "%s", nil, + "bbversion", 1, String, -1, "%s", nil, + "bbserial", 1, String, -1, "%s", nil, + "assettag", 1, String, -1, "%s", nil, + "features", 1, Integer, -1, "%#.2llux", nil, + "chassisloc", 1, String, -1, "%s", nil, + "chassishand", 2, Integer, -1, "%#.4llux", nil, + "bbtype", 1, Integer, -1, "%lld", nil, + /* continued object handles; 2 bytes each */ +}; + +Item chassisitems[] = { + "chassismfg", 1, String, -1, "%s", nil, + "chassistype", 1, Integer, -1, "%lld", nil, + "chassisver", 1, String, -1, "%s", nil, + "chassisserial", 1, String, -1, "%s", nil, + "chassisassettag", 1, String, -1, "%s", nil, + + "bootstate", 1, Integer, -1, "%lld", nil, + "powerst", 1, Integer, -1, "%lld", nil, + "thermalst", 1, Integer, -1, "%lld", nil, + "securityst", 1, Integer, -1, "%lld", nil, + + "height", 1, Integer, -1, "%lld", nil, + "powercord#", 1, Integer, -1, "%lld", nil, + "elementcnt", 1, Integer, -1, "%lld", nil, + + /* containted elements & sku number */ +}; + +Enum sockettype[] = { + 1, "other", + 2, "unknown", + 3, "daughter board", + 4, "zif socket", + 5, "replacable piggy back", + 6, "none", + 7, "lif socket", + 8, "slot 1", + 9, "slot 2", + 0xa, "370-pin socket", + 0xb, "slot a", + 0xc, "slot m", + 0xd, "socket 423", + 0xe, "socket a (socket 462)", + 0xf, "socket 478", + 0x10, "socket 754", + 0x11, "socket 940", + 0x12, "socket 939", + 0x13, "socket mPGA604", + 0x14, "socket lga771", + 0x15, "socket lga775", + 0x16, "socket s1", + 0x17, "socket am2", + 0x18, "socket f", + 0x19, "socket lga1366", + 0x1a, "socket g34", + 0x1b, "socket am3", + 0x1c, "socket c32", + 0x1d, "socket lga1156", + 0x1d, "socket lga1567", + 0x1f, "socket pga988a", + 0x20, "socket bg1288", + 0x21, "socket rpga988b", + 0x22, "socket bga1023", + 0x23, "socket bga1224", + 0x24, "socket bga1155", + 0x25, "socket bga1356", + 0x26, "socket lga2011", + 0x27, "socket fs1", + 0x28, "socket fs2", + 0x29, "socket fm1", + 0x2a, "socket fm2", + 0, nil, +}; + +Item cpuitems[] = { + "socket", 1, String, -1, "%s", nil, + "cputype", 1, Integer, -1, "%lld", nil, + "cpufamily", 1, Integer, -1, "%lld", nil, + "cpumfg", 1, String, -1, "%s", nil, + "cpuid", 8, Integer, -1, "%llux", nil, + "cpuvers", 1, String, -1, "%s", nil, + "cpuvolt", 1, Integer, -1, "%lld", nil, + "clockmhz", 2, Integer, -1, "%lld", nil, + "cpuspeed", 2, Integer, -1, "%lld", nil, + "cpuspeed (now)", 2, Integer, -1, "%lld", nil, + "cpustatus", 1, Integer, -1, "%lld", nil, + "cpuupgrade", 1, Enumf, -1, "%s", sockettype, + "cpul1", 2, Integer, -1, "%.2llux", nil, + "cpul2", 2, Integer, -1, "%.2llux", nil, + "cpul3", 2, Integer, -1, "%.2llux", nil, + "cpuserial", 1, String, -1, "%s", nil, + "cpuassettag", 1, String, -1, "%s", nil, + "cpupart#", 1, String, -1, "%s", nil, + "cpucore#", 1, Integer, -1, "%lld", nil, + "cpucoreen", 1, Integer, -1, "%lld", nil, + "cputhreadcnt", 1, Integer, -1, "%lld", nil, + "cpuenum", 2, Integer, -1, "%#.4llux", nil, + "cpufamily2", 2, Integer, -1, "%#.4llux", nil, +}; + +Enum ecctypetab[] = { + 1, "other", + 2, "unknown", + 3, "none", + 4, "8-bit parity", + 5, "32-bit ecc", + 6, "32-bit ecc", + 7, "32-bit ecc", + 8, "crc", + 0, nil, +}; + +/* bitfield */ +Enum ecccap[] = { + 1<<0, "other", + 1<<1, "unknown", + 1<<2, "none", + 1<<3, "single-bit", + 1<<4, "double-bit", + 1<<5, "error scrubbing", + 0, nil, +}; + +Enum interleave[] = { + 1, "other", + 2, "unknown", + 3, "one-way", + 4, "two-way", + 5, "four-way", + 6, "eight-way", + 7, "sixteen-way", + 0, nil, +}; + +Item memctlritems[] = { + "ecctype", 1, Enumf, -1, "%s", ecctypetab, + "ecccap", 1, Enumbv, -1, "%s", ecccap, + "interleavesupp", 1, Enumf, -1, "%s", interleave, + "interleavecurr", 1, Enumf, -1, "%s", interleave, + "maxmodsz", 1, Integer, -1, "%ℛ", nil, + "speedsupp", 2, Integer, -1, "%#.4llux", nil, + "typessupp", 2, Integer, -1, "%#.4llux", nil, + "voltages", 1, Integer, -1, "%#.2llux", nil, + "memslots", 1, Integer, -1, "%lld", nil, +/* "handles" 2*memslots, Integer, -1, "%#.4llux", nil, */ +/* "eccenabled" 1, Integer, -1, "%.2llux", nil, */ +}; + +int +fmtℛ(Fmt *f) +{ + char *prefix; + uint code; + + prefix = ""; + code = va_arg(f->args, uvlong); + if(f->flags & FmtSharp){ + switch(code){ + case 0x7d: + return fmtprint(f, "not determinable"); + case 0x7e: + return fmtprint(f, "installed but disabled"); + case 0x7f: + return fmtprint(f, "not installed"); + } + if(code & 0x80) + prefix = "dual-port "; + code &= ~0x80; + } + return fmtprint(f, "%s%dMB", prefix, 1<args, uvlong); + if(u & 0x8000) + return fmtprint(f, "%d kb", u&~0x8000); + return fmtprint(f, "%d mb", u); +} + +Item mdevitems[] = { + "paryhnd", 2, Integer, -1, "%#.4llux", nil, + "errhnd", 2, Integer, -1, "%#.4llux", nil, + "twidth", 2, Integer, -1, "%llud", nil, + "width", 2, Integer, -1, "%llud", nil, + "size", 2, Integer, -1, "%𝒮", nil, + "formfactor", 1, Enumf, -1, "%s", formfactor, + "deviceset", 1, Integer, -1, "%llud", nil, + "locator", 1, String, -1, "%s", nil, + "bankloc", 1, String, -1, "%s", nil, + "memtype", 1, Enumf, -1, "%s", mdevmemtype, + "typedetail", 2, Enumf, -1, "%s", typedetail, + "speed", 2, Integer, -1, "%llud Mhz", nil, + "mfgr", 1, String, -1, "%s", nil, + "serial", 1, String, -1, "%s", nil, + "assettag", 1, String, -1, "%s", nil, + "part#", 1, String, -1, "%s", nil, + "attr", 1, Integer, -1, "%.2llux", nil, // rank or zero + "xsize", 4, Integer, -1, "%#.4llud MB", nil, + "cfgspeed", 2, Integer, -1, "%llud Mhz", nil, +}; + +Enum errortype[] = { + 1, "other", + 2, "unknown", + 3, "ok", + 4, "bad read", + 5, "parity error", + 6, "single-bit error", + 7, "double-bit error", + 8, "muti-bit error", + 9, "nybble error", + 0xa, "cksum error", + 0xb, "crc error", + 0xc, "corrected single-bit error", + 0xd, "corrected error", + 0xe, "uncorrectable error", + 0, nil, +}; + +Enum errorgran[] = { + 1, "other", + 2, "unknown", + 3, "device", + 4, "memory partition", + 0, nil, +}; + +Enum memoryop[] = { + 1, "other", + 2, "unknown", + 3, "read", + 4, "write", + 0, nil, +}; + +Item merroritems[] = { + "errortype", 1, Enumf, -1, "%s", errortype, + "errorgran", 1, Enumf, -1, "%s", errorgran, + "errorop", 1, Enumf, -1, "%s", memoryop, + "syndrome", 4, Integer, -1, "%#.8llux", nil, + "physaddr", 4, Integer, -1, "%#.8llux", nil, + "devaddr", 4, Integer, -1, "%#.8llux", nil, + "resolution", 4, Integer, -1, "%#.8llux", nil, +}; + +Item mmapitems[] = { + "start", 4, Integer, -1, "%#.8llux kb", nil, + "end", 4, Integer, -1, "%#.8llux kb", nil, + "ahand", 2, Integer, -1, "%#.4llux", nil, + "partwidth", 1, Integer, -1, "%lld", nil, + "xstart", 8, Integer, -1, "%#.16llux", nil, + "xend", 8, Integer, -1, "%#.16llux", nil, +}; + +/* prec→multiplier, width→prec */ +int +fmt×(Fmt *f) +{ + uvlong kb, m; + + kb = va_arg(f->args, uvlong); + m = 1024; + if(f->flags & FmtPrec){ + f->flags &= ~FmtPrec; + m = f->prec; + } + if(f->flags & FmtWidth) + return fmtprint(f, "%#.*llux", f->width, kb*m); + return fmtprint(f, "%#.8llux", kb*m); +} + +Item mmdevitems[] = { + "start", 4, Integer, -1, "%8.1024×", nil, + "end", 4, Integer, -1, "%8.1024×", nil, + "dhand", 2, Integer, -1, "%#.4llux", nil, + "ahand", 2, Integer, -1, "%#.4llux", nil, + "row", 1, Integer, -1, "%lld", nil, + "interleave", 1, Integer, -1, "%lld", nil, + "idepth", 1, Integer, -1, "%lld", nil, + "xstart", 8, Integer, -1, "%#.16llux", nil, + "xend", 8, Integer, -1, "%#.16llux", nil, +}; + +Item ptritems[] = { + "type", 1, Integer, -1, "%lld", nil, + "interface", 1, Integer, -1, "%lld", nil, + "buttons", 1, Integer, -1, "%lld", nil, +}; + +Enum batterychemistry[] = { + 1, "other", + 2, "unknown", + 3, "lead acid", + 4, "nicad", + 5, "nimh", + 6, "lion", + 7, "zincair", + 8, "li polymer", + 0, nil, +}; + +Item batteryitems[] = { + "location", 1, String, -1, "%s", nil, + "mfgr", 1, String, -1, "%s", nil, + "mfgr date", 1, String, -1, "%s", nil, + "serial", 1, String, -1, "%s", nil, + "devname", 1, String, -1, "%s", nil, + + "chemistry", 1, Enumf, -1, "%s", batterychemistry, + "capacity", 2, Integer, -1, "%lld mWh", nil, + "voltage", 2, Integer, -1, "%lld mV", nil, + "sbds vers", 1, Integer, -1, "%lld", nil, + "maxerror%", 1, Integer, -1, "%lld", nil, + "sbds serial", 2, Integer, -1, "%.4llux", nil, + "sbds mfgdate", 2, Integer, -1, "%.4llux", nil, + "sbds chem", 1, String, -1, "%s", nil, + "capacity ×", 1, Integer, -1, "%lld", nil, + "oemword", 2, Integer, -1, "%llux", nil, +}; + +Item wdogitems[] = { + "cap", 1, Integer, -1, "%.2llux", nil, + "rstcount", 2, Integer, -1, "%lld", nil, + "rstlim", 2, Integer, -1, "%lld", nil, + "interval", 2, Integer, -1, "%lld min", nil, + "timeout", 2, Integer, -1, "%lld min", nil, +}; + +Item hwsecitems[] = { + "settings", 1, Integer, -1, "%.2llux", nil, +}; + +Item syspwritems[] = { + "month", 1, Integer, -1, "%.2llux", nil, + "mday", 1, Integer, -1, "%.2llux", nil, + "day", 1, Integer, -1, "%.2llux", nil, + "min", 1, Integer, -1, "%.2llux", nil, + "osec", 1, Integer, -1, "%.2llux", nil, +}; + +Item vprobeitems[] = { + "desc", 1, String, -1, "%s", nil, + "locstat", 1, Integer, -1, "%.2llux", nil, + + "max", 2, Integer, -1, "%.2llud mV", nil, + "min", 2, Integer, -1, "%.2llud mV", nil, + "res", 2, Integer, -1, "%.2llud mV", nil, + "tolerance", 2, Integer, -1, "%.2llud mV", nil, + "accuracy", 2, Integer, -1, "%.2llud mV", nil, + "oem", 4, Integer, -1, "%.8llux", nil, + "nominal", 2, Integer, -1, "%.2llud mV", nil, +}; + +Enum fantypestat[] = { + 1<<5, "other", + 2<<5, "unknown", + 3<<5, "ok", + 4<<5, "non-critical", + 5<<5, "critical", + 6<<5, "non-recoverable", + + 1, "other", + 2, "unknown", + 3, "fan", + 4, "centrifugal blower", + 5, "chip fan", + 6, "cabinet fan", + 7, "powersupply fan", + 8, "heat pipe", + 9, "integrated refrig", + 0xa, "active cooling", + 0xb, "passive cooling", + 0, nil, +}; + +Item fanitems[] = { + "tprobhnd", 2, Integer, -1, "%.4llux", nil, + "typestat", 1, Integer, -1, "%.2llux", nil, + "coolgroup", 1, Integer, -1, "%.2llux", nil, + "oem", 4, Integer, -1, "%.8llux", nil, + "nominalspd", 2, Integer, -1, "%.4lld", nil, + "description", 1, String, -1, "%s", nil, +}; + +Item tprobeitems[] = { + "desc", 1, String, -1, "%s", nil, + "locstat", 1, Integer, -1, "%.2llux", nil, + "max", 2, Integer, -1, "%.llud 1/10th °C", nil, + "min", 2, Integer, -1, "%.llud 1/10th °C", nil, + "res", 2, Integer, -1, "%.llud 1/10th °C", nil, + "tolerance", 2, Integer, -1, "%.llud 1/10th °C", nil, + "accuracy", 2, Integer, -1, "%.llud 1/10th °C", nil, + "oem", 4, Integer, -1, "%.8llux", nil, + "nominal", 2, Integer, -1, "%.llud 1/10th °C", nil, +}; + +Item cprobeitems[] = { + "desc", 1, String, -1, "%s", nil, + "locstat", 1, Integer, -1, "%.2llux", nil, + "max", 2, Integer, -1, "%.llud mA", nil, + "min", 2, Integer, -1, "%.llud mA", nil, + "res", 2, Integer, -1, "%.llud mA", nil, + "tolerance", 2, Integer, -1, "%.llud mA", nil, + "accuracy", 2, Integer, -1, "%.llud mA", nil, + "oem", 4, Integer, -1, "%.8llux", nil, + "nominal", 2, Integer, -1, "%.llud mA", nil, +}; + +Item bootinfoitems[] = { + "undefined", 6, Integer, -1, "%llux", nil, + "status", 10, Uchar, -1, "%.10H", nil, +}; + +Item memerr64items[] = { + "type", 1, Integer, -1, "%llud", nil, + "gran", 1, Integer, -1, "%llud", nil, + "operation", 1, Integer, -1, "%llud", nil, + "synrdome", 4, Integer, -1, "%.8llux", nil, + + "addr", 8, Integer, -1, "%.16llux", nil, + "devaddr", 8, Integer, -1, "%.16llux", nil, + "resolution", 4, Integer, -1, "%.8llux", nil, +}; + +Enum mgmtaddrtype[] = { + 1, "other", + 2, "unknown", + 3, "i/o port", + 4, "memory", + 5, "smbus", + 0, nil, +}; + +Item mgmtitems[] = { + "desc", 1, String, -1, "%s", nil, + "type", 1, Integer, -1, "%lld", nil, + "addr", 4, Integer, -1, "%#.8llx", nil, + "addrtype", 1, Enumf, -1, "%s", mgmtaddrtype, +}; + +Item mgmtcitems[] = { + "desc", 1, String, -1, "%s", nil, + "devhand", 2, Integer, -1, "%.4llux", nil, + "cmphand", 2, Integer, -1, "%.4llux", nil, + "thand", 2, Integer, -1, "%.4llux", nil, +}; + +Item mgmtdtitems[] = { + "low thresh", 2, Integer, -1, "%.4llud", nil, + "hi thresh", 2, Integer, -1, "%.4llud", nil, + "low crit thresh", 2, Integer, -1, "%.4llud", nil, + "hi crit thresh", 2, Integer, -1, "%.4llud", nil, + "low nr thresh", 2, Integer, -1, "%.4llud", nil, + "hi nr thresh", 2, Integer, -1, "%.4llud", nil, +}; + +Item memchanitems[] = { + "type", 1, Integer, -1, "%llud", nil, + "maxload", 1, Integer, -1, "%llud", nil, + "devcnt", 1, Integer, -1, "%llud", nil, + "load1", 1, Integer, -1, "%llud", nil, + "hndl1", 2, Integer, -1, "%.4llux", nil, +}; + +Item ipmiitems[] = { + "type", 1, Integer, -1, "%llud", nil, + "version", 1, Integer, -1, "%#.2llux", nil, + "i²c slaveaddr", 1, Integer, -1, "%#.2llux", nil, + "nvstoraddr", 1, Integer, -1, "%#.2llux", nil, + "pa", 8, Integer, -1, "%#.16llux", nil, + "pa modify", 1, Integer, -1, "%#.2llux", nil, + "irq#", 1, Integer, -1, "%#.2llux", nil, +}; + +Item psitems[] = { + "pwrgrp", 1, Integer, -1, "%llud", nil, + + "loc", 1, String, -1, "%s", nil, + "name", 1, String, -1, "%s", nil, + "mfg", 1, String, -1, "%s", nil, + "serial", 1, String, -1, "%s", nil, + "assetag", 1, String, -1, "%s", nil, + "part#", 1, String, -1, "%s", nil, + "rev", 1, String, -1, "%s", nil, + "pwrecap", 2, Integer, -1, "%llud mW", nil, + "flags", 2, Integer, -1, "%.4llux", nil, + "input v hdl", 2, Integer, -1, "%.4llux", nil, + "fan hdl", 2, Integer, -1, "%.4llux", nil, + "current hdl", 2, Integer, -1, "%.4llux", nil, +}; + +Item obditems[] = { + "name", 1, String, -1, "%s", nil, + "type", 1, Integer, -1, "%.2llux", nil, + "inst", 1, Integer, -1, "%.2llux", nil, + "segment", 1, Integer, -1, "%.2llux", nil, + "bus", 1, Integer, -1, "%.2llux", nil, + "devfn", 1, Integer, -1, "%.2llux", nil, +}; + +typedef struct Itemtab Itemtab; +struct Itemtab { + Item *tab; + int n; +}; + +Itemtab itemtab[] = { +[Biosinfo] biositems, nelem(biositems), +[Sysinfo] sysitems, nelem(sysitems), +[Module] moditems, nelem(moditems), +[Chassis] chassisitems, nelem(chassisitems), +[Cpu] cpuitems, nelem(cpuitems), +[Memctlr] memctlritems, nelem(memctlritems), +[Memstk] memstkitems, nelem(memstkitems), +[Cache] cacheitems, nelem(cacheitems), +[Conn] connitems, nelem(connitems), +[Slot] slotitems, nelem(slotitems), +[Oemstr] oemitems, nelem(oemitems), +[Sysconf] sysconfitems, nelem(sysconfitems), +[Bioslang] bioslangitems, nelem(bioslangitems), +[Syslog] syslogitems, nelem(syslogitems), +[Pmem] pmemitems, nelem(pmemitems), +[Mdev] mdevitems, nelem(mdevitems), +[Merror] merroritems, nelem(merroritems), +[Mmap] mmapitems, nelem(mmapitems), +[Mmdev] mmdevitems, nelem(mmdevitems), +[Pointer] ptritems, nelem(ptritems), +[Battery] batteryitems, nelem(batteryitems), +[Wdog] wdogitems, nelem(wdogitems), +[Hwsec] hwsecitems, nelem(hwsecitems), +[Syspwr] syspwritems, nelem(syspwritems), +[Vprobe] vprobeitems, nelem(vprobeitems), +[Fan] fanitems, nelem(fanitems), +[Tprobe] tprobeitems, nelem(tprobeitems), +[Cprobe] cprobeitems, nelem(cprobeitems), +[Bootinfo] bootinfoitems, nelem(bootinfoitems), +[Merror64] memerr64items, nelem(memerr64items), +[Mgmt] mgmtitems, nelem(mgmtitems), +[Mgmtc] mgmtcitems, nelem(mgmtcitems), +[Mgmtdt] mgmtdtitems, nelem(mgmtdtitems), +[Memch] memchanitems, nelem(memchanitems), +[Ipmi] ipmiitems, nelem(ipmiitems), +[Ps] psitems, nelem(psitems), +[Obd] obditems, nelem(obditems), +}; + +void +setoffsets(Item *tab, int n) +{ + int i, o; + + o = 4; + for(i = 0; i < n; i++){ + tab[i].offset = o; + o += tab[i].nbytes; + } +} + +void +tabinit(void) +{ + int i; + + for(i = 0; i < nelem(itemtab); i++) + setoffsets(itemtab[i].tab, itemtab[i].n); +} + +char* +getstring(uchar *p, int i, uchar *e) +{ + uchar *q; + + if(i == 0) + return nil; + for(;; i--){ + if(i == 1) + break; + p = memchr(p, 0, e - p - 1); + if(p == nil) + sysfatal("bad strings"); // return nil; + p++; + } + q = memchr(p, 0, e - p - 1); + if(q == nil || q-p == 0) + return nil; + return strdup((char*)p); +} + +void +crack(uchar *p, uchar *e, Item *tabi, Itemv *tabv, int n) +{ + int i, len; + Item *t; + Itemv *v; + + len = p[1]; + for(i = 0; i < n; i++){ + t = tabi + i; + v = tabv + i; + + if(p + t->offset + t->nbytes >= p+len){ + /* cheater way to protect against new std. versions */ + continue; + } + + switch(t->type){ + default: + sysfatal("bad type"); + case String: + v->s = getstring(p + len, p[t->offset], e); + break; + case Enumf: + case Enumbv: + case Integer: + if(p + t->offset + t->nbytes >= e) + sysfatal("range"); + v->i = getle(p + t->offset, t->nbytes); + break; + case Uchar: + if(p + t->offset + t->nbytes >= e) + sysfatal("range"); + memcpy(v->uuid, p + t->offset, t->nbytes); + break; + } + } +} + +void +dumpenum(Enum *p) +{ + for(; p->s != nil; p++) + Bprint(out, "%s %d\n", p->s, p->v); +} + +char* +enumtostr(Enum *p, uvlong i) +{ + for(; p->s != nil; p++) + if(i == p->v) + return p->s; + return nil; +} + +int +strtoenum(Enum *p, char *s) +{ + for(; p->s != nil; p++) + if(cistrcmp(s, p->s) == 0) + return p->v; + return -1; +} + +char* +enumbvtostr(Enum *p, uint i, char *s0, char *e) +{ + char *s; + + s = s0; + for(; p->s != nil; p++) + if(i & p->v){ + if(s != s0) + s = seprint(s, e, " "); + s = seprint(s, e, "%s", p->s); + } + if(s != s0) + return s0; + return nil; +} + +void +printitems(int type, Item *tabi, Itemv *tabv, int n) +{ + char *s, buf[128]; + int i; + Item *t; + Itemv *v; + +// Bprint(out, "type %d\n", type); + USED(type); + for(i = 0; i < n; i++){ + t = tabi + i; + v = tabv + i; + Bprint(out, " %-12s ", t->name); + switch(t->type){ + default: + sysfatal("bad type"); + case String: + Bprint(out, t->fmt, v->s); + break; + case Integer: + Bprint(out, t->fmt, v->i); + break; + case Uchar: + Bprint(out, t->fmt, v->uuid); + break; + case Enumf: + s = enumtostr(t->tab, v->i); + if(s != nil){ + Bprint(out, t->fmt, s); + Bprint(out, " (%#llux)", v->i); + } + else + Bprint(out, "%lld", v->i); + break; + case Enumbv: + s = enumbvtostr(t->tab, v->i, buf, buf+sizeof buf); + if(s != nil){ + Bprint(out, t->fmt, s); + Bprint(out, " (%#llux)", v->i); + } + else + Bprint(out, "%lld", v->i); + break; + } + Bprint(out, "\n"); + } +} + +uchar* +next(uchar *p, uchar *e) +{ + int ns; + + p += p[1]; + if(p >= e) + sysfatal("structures out-of-bounds"); + + for(ns = 0;; ns++){ + p = memchr(p, 0, e - p - 1); + if(p == nil) + sysfatal("bad strings"); + p++; + if(p[0] == 0){ + p++; + break; + } + } + USED(ns); + return p; +} + +Sm* +finddmi(void) +{ + uchar *buf, *p, *e; + int i, len; + Sm *sm; + Smval *val; + + realmodefd(); + buf = emalloc(Dmisz); + if(pread(rfd, buf, Dmisz, Dmistart) != Dmisz) + sysfatal("read: %r"); + + e = buf + Dmisz; + for(p = buf; p < e; p += 16) + if(memcmp(p, "_SM_", 4) == 0) + goto found; + sysfatal("no dmi structure"); +found: + Bvprint(out, "found at %#lux\n", p-buf+Dmistart); + len = p[5]; + /* do checksums */ + + sm = emalloc(len); + sm->raw = *(Smbuf*)p; + Bvprint(out, "dmi %ud.%ud\n", sm->raw.vers[0], sm->raw.vers[1]); + + sm->stpa = getle(sm->raw.stpa, 4); + sm->stlen = getle(sm->raw.stlen, 2); + Bvprint(out, "structure pa %llux len %d count %d\n", sm->stpa, sm->stlen, (uint)getle(sm->raw.nstrut, 2)); + + sm->n = getle(sm->raw.nstrut, 2); + sm->v = emalloc(sm->n*sizeof sm->v[0]); + + free(buf); + buf = emalloc(sm->stlen); + if(pread(rfd, buf, sm->stlen, sm->stpa) != sm->stlen) + sysfatal("read: %r"); + p = buf; + e = buf + sm->stlen; + for(i = 0; i < sm->n; i++){ + val = sm->v + i; + val->type = p[0]; + val->hand = getle(p+2, 2); + val->len = p[1]; + if(val->type < nelem(itemtab)){ + val->v = emalloc(itemtab[val->type].n*sizeof val->v[0]); + val->i = itemtab[val->type].tab; + crack(p, e, val->i, val->v, itemtab[val->type].n); + } + p = next(p, e); + } + return sm; +} + +void +printdmi(Sm *sm) +{ + int i; + Smval *val; + + for(i = 0; i < sm->n; i++){ + val = sm->v + i; + if(prtype != -1 && val->type != prtype) + continue; + if(prhand != -1 && val->hand != prhand) + continue; + Bprint(out, "%d: type %s %ud len %ud handle %ud\n", + i, enumtostr(tabletab, val->type), val->type, val->len, val->hand); + if(val->type < nelem(itemtab)) + printitems(val->type, itemtab[val->type].tab, val->v, itemtab[val->type].n); + } +} + +Smval* +handtosmval(Sm *sm, int hand) +{ + int i; + Smval *val; + + for(i = 0; i < sm->n; i++){ + val = sm->v + i; + if(val->hand == hand) + return val; + } + return nil; +} + +Itemv* +getval(char *name, Smval *v, int n) +{ + int i; + + for(i = 0; i < n; i++) + if(cistrcmp(name, v->i[i].name) == 0) + return v->v + i; + return nil; +} + +void +memhack(Sm *sm) +{ + int i, cnt; + uvlong start, end; + Itemv *v; + Smval *val, *mem; + + for(i = 0; i < sm->n; i++){ + val = sm->v + i; + if(val->type != Mmdev) + continue; + start = 0; + end = 0; + cnt = itemtab[val->type].n; + v = getval("start", val, cnt); + if(v != nil && v->i != 0xffffffff) + start = (v->i+0)*1024; + else{ + v = getval("xstart", val, cnt); + if(v != nil) + start = v->i; + } + + v = getval("end", val, cnt); + if(v != nil && v->i != 0xffffffff){ + end = v->i; + if((end & 0xffff) == 0xffff) + end++; + end *= 1024; + }else if((v = getval("xend", val, cnt)) != nil){ + end = v->i; + if((end & 0xffff) == 0xffff) + end++; + } + +// if(end == 0) +// continue; + + mem = handtosmval(sm, getval("dhand", val, cnt)->i); + if(mem == nil) + continue; + Bprint(out, "%#.16llux %#.16llux " + "%-15s %-20s" + "\n", + start, end, + getval("mfgr", mem, itemtab[Mdev].n)->s, + // getval("serial", mem, itemtab[Mdev].n)->s + getval("part#", mem, itemtab[Mdev].n)->s + ); + } +} + +fmtℬ(Fmt *f) +{ + int i; + uvlong v, t, c, m; + + v = va_arg(f->args, uvlong); + m = 1; + t = 0; + for(i = 0; i < 2*sizeof v; i++){ + c = v>>4*i & 0xf; + t += c*m; + m *= 10; + } + return fmtprint(f, "%lld", t); +} + +/* cmos address i/o ports 0x70/0x71 */ +Item type1header[] = { + "oem res", 5, Uchar, -1, "%.5H", nil, + "mewindow", 1, Integer, -1, "%ℬ", nil, + "meincr", 1, Integer, -1, "%lld", nil, + "logclearadr", 1, Integer, -1, "%#llux", nil, + "logclearbit", 1, Integer, -1, "%#llux", nil, + "cmoscksumstart", 1, Integer, -1, "%#llux", nil, + "cmoscksumcnt", 1, Integer, -1, "%#llux", nil, + "cmoscksumadr", 1, Integer, -1, "%#llux", nil, + "reserved", 3, Integer, -1, "%#llux", nil, + "headerrev", 1, Integer, -1, "%llud", nil, +}; + +Enum logtype[] = { + 0, "reserved", + 1, "single-bit ecc error", + 2, "multi-bit ecc error", + 3, "parity memory error", + 4, "bus timeout", + 5, "io channel check", + 6, "software nmi", + 7, "post memory resize", + 8, "post error", + 9, "pci parity error", + 0xa, "pci system error", + 0xb, "cpu failure", + 0xc, "eisa failsafe timer timeout", + 0xd, "correctable memory log disabled", + 0xe, "loging disabled (log spam)", + 0xf, "reserved (0xf)", + 0x10, "system physical limits exceeded", + 0x11, "watchdog reset", + 0x12, "system configuration info", + 0x13, "harddrive info", + 0x14, "system reconfigured", + 0x15, "uncorrectable cpu-complex error", + 0x16, "log cleared", + 0x17, "system boot", + 0x17, "system boot", +}; + +Enum varliabledatafmt[] = { + 0, "none", + 1, "handle", /* 2 bytes */ + 2, "multiple-event", /* 2 bytes */ + 3, "multiple-event handle", /* 4 bytes */ + 4, "post results bitmap", /* 8 bytes */ + 5, "system mgmt", /* 4 bytes */ + 6, "multiple-event sm", /* 8 bytes */ +}; + +Item logdesc[] = { + "type", 1, Integer, -1, "%lld", nil, + "datafmt", 1, Integer, -1, "%lld", nil, +}; + +Smval* +smmatch(Sm *sm, Smval *val, int type) +{ + int i; + + if(val == nil) + i = 0; + else + i = val - sm->v; + for(; i < sm->n; i++){ + val = sm->v + i; + if(val->type != type) + continue; + return val; + } + return nil; +} + +typedef struct Logfn Logfn; +typedef struct Log Log; + +struct Logfn { + char *name; + int (*open)(Log*); + void (*close)(Log*); + int (*read)(Log*, void*, int, uvlong); + int (*write)(Log*, void*, int, uvlong); +}; + +struct Log { + int fd; + Logfn *l; + + int valid; + int format; + uint len; + uvlong hdroffset; + uvlong dataoffset; + uvlong pa; + int access; +}; + +enum { + Biosmem0 = 0xff000000, + Biosmemsz = 16*1024*1024, +}; + +int +mmioopen(Log *l) +{ + if(l->pa >= 1ull<<32 || l->pa < Biosmem0){ + werrstr("mmio range: %#llux", l->pa); + return -1; + } + if(l->len > Biosmemsz){ + werrstr("mmio size: %#ux", l->len); + return -1; + } + return open("/dev/resmem", OREAD); +} + +void +mmioclose(Log *l) +{ + close(l->fd); +} + +int +mmioread(Log *l, void *a, int n, uvlong o) +{ + return pread(l->fd, a, n, o+l->pa); +} + +int +mmiowrite(Log *l, void *a, int n, uvlong o) +{ + return pwrite(l->fd, a, n, o+l->pa); +} + +Logfn logfntab[] = { +[3] {"mmio", mmioopen, mmioclose, mmioread, mmiowrite, }, +}; + +uvlong +getv(Smval *val, int cnt, char *s, uvlong dflt) +{ + Itemv *v; + + v = getval(s, val, cnt); + if(v != nil) + return v->i; + return dflt; +} + +typedef struct Loge Loge; +struct Loge { + uchar type; + uchar len; + uchar bcddate[6]; +}; + +void +loghack(Sm *sm) +{ + int cnt; + Smval *val; + Log log; + Loge e; + uintmem o; + + val = smmatch(sm, nil, Syslog); + if(val == nil) + return; + cnt = itemtab[val->type].n; + + memset(&log, 0, sizeof log); + log.valid = getv(val, cnt, "status", 0) & 1; + log.len = getv(val, cnt, "loglength", 0); + log.hdroffset = getv(val, cnt, "hdroffset", 0); + log.dataoffset = getv(val, cnt, "dataoffset", 0); + log.pa = getv(val, cnt, "pa", 0); + log.access = getv(val, cnt, "access", -1); + log.format = getv(val, cnt, "format", -1); + + if(log.valid == 0) + sysfatal("log invalid %lld", getv(val, cnt, "status", 0)); + if((uint)log.access >= nelem(logfntab) || logfntab[log.access].write == nil) + sysfatal("access method %d not supported", log.access); + if(log.format != 1) + sysfatal("unknown log hdr format %d", log.format); + + log.l = logfntab + log.access; + + print("access method %s\n", log.l->name); + + print("%lld %lld\n", getval("ndesc", val, cnt)->i, getval("desclen", val, cnt)->i); + + if((log.fd = log.l->open(&log)) == -1) + sysfatal("can't open log: %r"); + + char buf[32]; + + if(log.l->read(&log, buf, 16, log.hdroffset) != 16) + sysfatal("read: %r"); + print("%.16H\n", buf); + + for(o = log.dataoffset;; o += e.len){ + memset(&e, 0, sizeof e); + log.l->read(&log, buf, 8, o); + e.type = buf[0]; + if(e.type == 0xff) + break; + e.len = buf[1] & ~0x80; + if(e.len < 8) + break; + memcpy(e.bcddate, buf+2, 6); + + print("type %.2ux len %d date %#.6H\n", e.type, e.len, e.bcddate); + +// log.l->read(&log, buf, e.len, o); +// print("data %.*H", e.len-8, buf+8); + } + + log.l->close(&log); +} + +void +outinit(void) +{ + if(Binit(&outsb, 1, OWRITE) == -1) + sysfatal("Binit: %r"); + out = &outsb; +} + +void +outterm(void) +{ + Bterm(out); + out = nil; +} + +void +usage(void) +{ + fprint(2, "usage: dmi [-vmls] [-t type] [-h hand]\n"); + exits("usage"); +} + +void +main(int argc, char **argv) +{ + char *s, *p; + Sm *sm; + void (*f)(Sm*); + + fmtinstall(L'ℛ', fmtℛ); + fmtinstall(L'𝒮', fmt𝒮); + fmtinstall(L'×', fmt×); + fmtinstall(L'ℬ', fmtℬ); /* bcd */ + fmtinstall('H', encodefmt); + tabinit(); + outinit(); + f = printdmi; + ARGBEGIN{ + case 'v': + verbose = 1; + break; + case 't': + s = EARGF(usage()); + prtype = strtoul(s, &p, 0); + if(p == s) + prtype = strtoenum(tabletab, s); + if(prtype == -1) + sysfatal("bad type"); + break; + case 'h': + prhand = strtoul(EARGF(usage()), &p, 0); + break; + case 'l': + dumpenum(tabletab); + outterm(); + exits(""); + case 'm': + f = memhack; + break; + case 's': + f = loghack; + break; + default: + usage(); + }ARGEND + if(argc != 0) + usage(); + + sm = finddmi(); + f(sm); + outterm(); + exits(""); +} diff -Nru /sys/src/cmd/aux/dmi/mkfile /sys/src/cmd/aux/dmi/mkfile --- /sys/src/cmd/aux/dmi/mkfile Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/aux/dmi/mkfile Fri Jul 12 00:00:00 2013 @@ -0,0 +1,8 @@ +