diff options
Diffstat (limited to 'util/oem_supermicro.c')
-rw-r--r-- | util/oem_supermicro.c | 90 |
1 files changed, 72 insertions, 18 deletions
diff --git a/util/oem_supermicro.c b/util/oem_supermicro.c index 0c4a001..47838da 100644 --- a/util/oem_supermicro.c +++ b/util/oem_supermicro.c @@ -49,6 +49,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endif #endif #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <time.h> #include "ipmicmd.h" @@ -66,7 +67,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. void set_loglevel(int level); /*prototype */ extern char fsm_debug; /*mem_if.c*/ -static char * progver = "2.98"; +static char * progver = "2.99"; static char * progname = "ismcoem"; static int verbose = 0; static char fdebug = 0; @@ -426,34 +427,70 @@ int decode_sensor_supermicro(uchar *sdr,uchar *reading,char *pstring, int slen) return(rv); } +#define NPAIRS 26 +char rgpair[NPAIRS] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; int decode_mem_supermicro(int prod, uchar b2, uchar b3, char *desc, int *psz) { - int array, dimm, n; + int cpu, pair, dimm, n; int rv = -1; + int ver = 0; uchar bdata; if ((desc == NULL) || (psz == NULL)) return -1; - if (b2 == 0xff) bdata = b3; /*ff is reserved*/ - else bdata = b2; /* normal case */ - array = (bdata & 0xc0) >> 6; + if (b2 == 0xff) { ver = 1; bdata = b3; } /*ff is reserved*/ + else { ver = 2; bdata = b2; } /* normal case */ +#ifdef SMC_OLD + /* normal method for other vendors */ + cpu = (bdata & 0xc0) >> 6; dimm = bdata & 0x3f; + /* SuperMicro advertised method (wrong) */ /* bdata = 0x10 (16.) means CPU 1, DIMM 6 */ - array = bdata / 10; + cpu = bdata / 10; dimm = bdata % 10; - +#endif #ifdef DMIOK - /* Use DMI if we get confirmation about array/dimm indices. */ + /* Use DMI if we get confirmation about cpu/dimm indices. */ if (! is_remote()) { fsm_debug = fdebug; - rv = get_MemDesc(array,dimm,desc,psz); + rv = get_MemDesc(cpu,dimm,desc,psz); /* if (rv != 0) desc has "DIMM[%d}" */ } #endif - - if (rv != 0) { - n = sprintf(desc,"DIMM%d/CPU%d",dimm,array); - *psz = n; - rv = 0; + /* ver 0 previous SuperMicro firmware returned all zeros here. + * ver 1 returns data3 with some info (X9) + * ver 2 returns data2 with some info (X9,X10) + * There have been bugs in these SuperMicro events, but this + * has been derived from test data by comparing BIOS data. */ + if (ver == 0) { + cpu = (bdata & 0xc0) >> 6; + dimm =bdata & 0x3f; + pair = 0; + n = sprintf(desc,"CPU%d/DIMM%d",cpu,dimm); + } else if (ver == 1) { + cpu = 1; + if (bdata > 0x80) cpu = 2; + pair = (bdata & 0x70) >> 4; + if (pair > NPAIRS) pair = NPAIRS - 1; + dimm = (bdata & 0x07) + 1; /*convert to 1-based*/ + n = sprintf(desc,"P%d_DIMM%c%d",cpu,rgpair[pair],dimm); + } else { + /* ver 2 method: 2A 80 = P1_DIMMB1 */ + /* SuperMicro says: + * pair: %c (data2 >> 4) + 0x40 + (data3 & 0x3) * 3, (='B') + * dimm: %c (data2 & 0xf) + 0x27, + * cpu: %x (data3 & 0x03) + 1); + */ + cpu = (b3 & 0x0F) + 1; /*0x80=CPU1, 0x81=CPU2*/ + pair = ((bdata & 0xF0) >> 4) - 1; /*0x10=pairA, 0x20=pairB*/ + if (pair < 0) pair = 0; + if (pair > NPAIRS) pair = NPAIRS - 1; + dimm = (bdata & 0x0F) - 9; /*0x0A=dimmX1, 0x0B=dimmX2*/ + n = sprintf(desc,"P%d_DIMM%c%d",cpu,rgpair[pair],dimm); } + if (fdebug) + printf("decode_mem_supermicro: v%d bdata=%02x(%d) cpu=%d dimm=%d pair=%d\n",ver,bdata,bdata,cpu,dimm,pair); + + *psz = n; + rv = 0; return(rv); } /*end decode_mem_supermicro*/ @@ -481,6 +518,7 @@ int decode_sel_supermicro(uchar *evt, char *outbuf, int outsz, char fdesc, int sevid; ushort genid; uchar snum; + uchar data1, data2, data3; fdebug = fdbg; sevid = SEV_INFO; @@ -489,13 +527,16 @@ int decode_sel_supermicro(uchar *evt, char *outbuf, int outsz, char fdesc, snum = evt[11]; timestamp = evt[3] + (evt[4] << 8) + (evt[5] << 16) + (evt[6] << 24); genid = evt[7] | (evt[8] << 8); + data1 = evt[13]; + data2 = evt[14]; + data3 = evt[15]; if (rectype == 0x02) { sprintf(mybuf,"%02x [%02x %02x %02x]", evt[12],evt[13],evt[14],evt[15]); switch(evt[10]) { /*sensor type*/ - case 0xC0: /* CPU Temp Sensor */ + case 0xC0: /* CPU Temp Sensor */ type_str = "OEM_CpuTemp"; - switch((evt[13] &0x0f)) { /*offset/data1 l.o. nibble*/ + switch((evt[13] & 0x0f)) { /*offset/data1 l.o. nibble*/ case 0x02: /* CPU Temp Sensor Overheat event offset */ if (evt[12] & 0x80) { /*EvTyp==0xF0 if deassert*/ pstr = "CpuTemp Overheat OK"; sevid = SEV_INFO; @@ -507,7 +548,7 @@ int decode_sel_supermicro(uchar *evt, char *outbuf, int outsz, char fdesc, default: pstr = "CpuTemp Event"; break; } break; - case 0xC2: /* CPLD Event */ + case 0xC2: /* CPLD Event */ type_str = "OEM_CPLD"; switch((evt[13] & 0x0f)) { /* data1 usu 0xa0*/ case 0x00: @@ -519,7 +560,20 @@ int decode_sel_supermicro(uchar *evt, char *outbuf, int outsz, char fdesc, default: pstr = "CPLD Event"; break; } break; - default: /*other sensor types*/ + case 0xD0: /* BMC Event */ + type_str = "OEM_BMC"; + pstr = "BMC unknown event"; + sevid = SEV_CRIT; + if (data1 == 0x80 && data3 == 0xFF) { + switch(data2) { + case 0x00: pstr = "BMC unexpected reset"; break; + case 0x01: pstr = "BMC cold reset"; break; + case 0x02: pstr = "BMC warm reset"; break; + } + } + break; + case 0xC8: /* Observed Event */ + default: /*other sensor types*/ break; } } |