summaryrefslogtreecommitdiff
path: root/util/oem_supermicro.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/oem_supermicro.c')
-rw-r--r--util/oem_supermicro.c90
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;
}
}