mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-05-10 18:47:22 +00:00
ID: 85 - Supermicro memory ecc error display
Commit adds memory ECC error display for Supermicro boards and adds a Supermicro oem sensor type for SEL.
This commit is contained in:
parent
3a852a8849
commit
2d7fe32687
@ -281,7 +281,8 @@ typedef enum IPMI_OEM {
|
|||||||
IPMI_OEM_KONTRON = 15000,
|
IPMI_OEM_KONTRON = 15000,
|
||||||
IPMI_OEM_PPS = 16394,
|
IPMI_OEM_PPS = 16394,
|
||||||
IPMI_OEM_AMI = 20974,
|
IPMI_OEM_AMI = 20974,
|
||||||
IPMI_OEM_NOKIA_SIEMENS_NETWORKS = 28458
|
IPMI_OEM_NOKIA_SIEMENS_NETWORKS = 28458,
|
||||||
|
IPMI_OEM_SUPERMICRO_47488 = 47488
|
||||||
} IPMI_OEM;
|
} IPMI_OEM;
|
||||||
|
|
||||||
extern const struct valstr completion_code_vals[];
|
extern const struct valstr completion_code_vals[];
|
||||||
|
@ -107,6 +107,7 @@ struct standard_spec_sel_rec{
|
|||||||
#define SENSOR_TYPE_OEM_NFATAL_ERROR 0xC2
|
#define SENSOR_TYPE_OEM_NFATAL_ERROR 0xC2
|
||||||
#define SENSOR_TYPE_OEM_FATAL_ERROR 0xC3
|
#define SENSOR_TYPE_OEM_FATAL_ERROR 0xC3
|
||||||
#define SENSOR_TYPE_TXT_CMD_ERROR 0x20
|
#define SENSOR_TYPE_TXT_CMD_ERROR 0x20
|
||||||
|
#define SENSOR_TYPE_SUPERMICRO_OEM 0xD0
|
||||||
/* End of Macro for DELL Specific */
|
/* End of Macro for DELL Specific */
|
||||||
#define SEL_OEM_TS_DATA_LEN 6
|
#define SEL_OEM_TS_DATA_LEN 6
|
||||||
#define SEL_OEM_NOTS_DATA_LEN 13
|
#define SEL_OEM_NOTS_DATA_LEN 13
|
||||||
@ -676,6 +677,56 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu
|
|||||||
{ 0x00, 0x00, 0x00, 0x00, NULL, NULL },
|
{ 0x00, 0x00, 0x00, 0x00, NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static uint16_t supermicro_x9dal[] = {
|
||||||
|
0x0635
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t supermicro_x9db[] = {
|
||||||
|
0x0733, 0x0722, 0x0703, 0x0721, 0x0716, 0x0637
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t supermicro_x9sb[] = {
|
||||||
|
0x0651
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t supermicro_x9[] = {
|
||||||
|
0x0635, 0x0733, 0x0722, 0x0703, 0x0721, 0x0716, 0x0637, 0x0651
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t supermicro_b8[] = {
|
||||||
|
0x000A, 0x061c, 0x0620, 0x0101, 0x061f, 0x0612, 0x061e
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t supermicro_h8[] = {
|
||||||
|
0xa111, 0x0408, 0x0811, 0x1411, 0x0911, 0x1211, 0x1011, 0xcd11, 0x1111, 0xbe11, 0xce11, 0xbd11,
|
||||||
|
0xbc11, 0xa911, 0xaa11, 0xbd11, 0xcb11, 0xad11, 0xa811, 0xac11, 0xaf11, 0xa511, 0xa011, 0x1611,
|
||||||
|
0x2511, 0xbf11, 0x1511, 0x2211, 0x2411, 0x1911, 0xab11, 0xd011, 0xae11, 0xca11, 0x0409, 0xa211,
|
||||||
|
0xa311, 0x1311, 0xba11, 0xa711, 0xd111, 0x1711, 0xcf11, 0x2011, 0x1811
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t supermicro_p8[] = {
|
||||||
|
0x6480, 0x7380, 0x6280, 0x7480, 0x5980
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t supermicro_x8[] = {
|
||||||
|
0xa880, 0x0403, 0x0100, 0x0601, 0x0001, 0x0404, 0x0606, 0x0608, 0x0632, 0x0400, 0x0401, 0x0006,
|
||||||
|
0x040a, 0xf280, 0x060f, 0x0609, 0x0008, 0x0613, 0x061b, 0x0007, 0x0600, 0x060c, 0x060d, 0x0614,
|
||||||
|
0x060c, 0x0003, 0x040b, 0x0621, 0x0610, 0x0638, 0xf380, 0x060b, 0x040d, 0x0605, 0x062d, 0x060e,
|
||||||
|
0x061a, 0xf580, 0x062e, 0x0009
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t supermicro_X8[] = {
|
||||||
|
0x000A, 0x061c, 0x0620, 0x0101, 0x061f, 0x0612, 0x061e, 0xa111, 0x0408, 0x0811, 0x1411, 0x0911,
|
||||||
|
0x1211, 0x1011, 0xcd11, 0x1111, 0xbe11, 0xce11, 0xbd11, 0xbc11, 0xa911, 0xaa11, 0xbd11, 0xcb11,
|
||||||
|
0xad11, 0xa811, 0xac11, 0xaf11, 0xa511, 0xa011, 0x1611, 0x2511, 0xbf11, 0x1511, 0x2211, 0x2411,
|
||||||
|
0x1911, 0xab11, 0xd011, 0xae11, 0xca11, 0x0409, 0xa211, 0xa311, 0x1311, 0xba11, 0xa711, 0xd111,
|
||||||
|
0x1711, 0xcf11, 0x2011, 0x1811, 0x6480, 0x7380, 0x6280, 0x7480, 0x5980, 0xa880, 0x0403, 0x0100,
|
||||||
|
0x0601, 0x0001, 0x0404, 0x0606, 0x0608, 0x0632, 0x0400, 0x0401, 0x0006, 0x040a, 0xf280, 0x060f,
|
||||||
|
0x0609, 0x0008, 0x0613, 0x061b, 0x0007, 0x0600, 0x060c, 0x060d, 0x0614, 0x060c, 0x0003, 0x040b,
|
||||||
|
0x0621, 0x0610, 0x0638, 0xf380, 0x060b, 0x040d, 0x0605, 0x062d, 0x060e, 0x061a, 0xf580, 0x062e,
|
||||||
|
0x0009
|
||||||
|
};
|
||||||
|
|
||||||
int ipmi_sel_main(struct ipmi_intf *, int, char **);
|
int ipmi_sel_main(struct ipmi_intf *, int, char **);
|
||||||
void ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt);
|
void ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt);
|
||||||
void ipmi_sel_print_std_entry_verbose(struct ipmi_intf * intf, struct sel_event_record * evt);
|
void ipmi_sel_print_std_entry_verbose(struct ipmi_intf * intf, struct sel_event_record * evt);
|
||||||
|
@ -322,7 +322,6 @@ ipmi_get_oem(struct ipmi_intf * intf)
|
|||||||
return IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id);
|
return IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ipmi_sel_add_entry(struct ipmi_intf * intf, struct sel_event_record * rec)
|
ipmi_sel_add_entry(struct ipmi_intf * intf, struct sel_event_record * rec)
|
||||||
{
|
{
|
||||||
@ -526,6 +525,115 @@ get_newisys_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
|
|||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
get_supermicro_evt_desc(struct ipmi_intf *intf, struct sel_event_record *rec)
|
||||||
|
{
|
||||||
|
struct ipmi_rs *rsp;
|
||||||
|
struct ipmi_rq req;
|
||||||
|
char *desc = NULL;
|
||||||
|
char *str;
|
||||||
|
int chipset_type = 1;
|
||||||
|
int data1;
|
||||||
|
int data2;
|
||||||
|
int data3;
|
||||||
|
int length;
|
||||||
|
int sensor_type;
|
||||||
|
uint8_t i = 0;
|
||||||
|
uint16_t oem_id = 0;
|
||||||
|
/* Get the OEM event Bytes of the SEL Records byte 13, 14, 15 to
|
||||||
|
* data1,data2,data3
|
||||||
|
*/
|
||||||
|
data1 = rec->sel_type.standard_type.event_data[0];
|
||||||
|
data2 = rec->sel_type.standard_type.event_data[1];
|
||||||
|
data3 = rec->sel_type.standard_type.event_data[2];
|
||||||
|
/* Check for the Standard Event type == 0x6F */
|
||||||
|
if (rec->sel_type.standard_type.event_type != 0x6F) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* Allocate mem for te Description string */
|
||||||
|
desc = (char *)malloc(SIZE_OF_DESC);
|
||||||
|
if (desc == NULL) {
|
||||||
|
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(desc,0,SIZE_OF_DESC);
|
||||||
|
sensor_type = rec->sel_type.standard_type.sensor_type;
|
||||||
|
switch (sensor_type) {
|
||||||
|
case SENSOR_TYPE_MEMORY:
|
||||||
|
memset(&req, 0, sizeof (req));
|
||||||
|
req.msg.netfn = IPMI_NETFN_APP;
|
||||||
|
req.msg.lun = 0;
|
||||||
|
req.msg.cmd = BMC_GET_DEVICE_ID;
|
||||||
|
req.msg.data = NULL;
|
||||||
|
req.msg.data_len = 0;
|
||||||
|
|
||||||
|
rsp = intf->sendrecv(intf, &req);
|
||||||
|
if (rsp == NULL) {
|
||||||
|
lprintf(LOG_ERR, " Error getting system info");
|
||||||
|
if (desc != NULL) {
|
||||||
|
free(desc);
|
||||||
|
desc = NULL;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
} else if (rsp->ccode > 0) {
|
||||||
|
lprintf(LOG_ERR, " Error getting system info: %s",
|
||||||
|
val2str(rsp->ccode, completion_code_vals));
|
||||||
|
if (desc != NULL) {
|
||||||
|
free(desc);
|
||||||
|
desc = NULL;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* check the chipset type */
|
||||||
|
oem_id = ipmi_get_oem_id(intf);
|
||||||
|
if (oem_id == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
length = sizeof(supermicro_X8);
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
if (oem_id == supermicro_X8[i]) {
|
||||||
|
chipset_type = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
length = sizeof(supermicro_x9);
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
if (oem_id == supermicro_x9[i]) {
|
||||||
|
chipset_type = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (chipset_type == 0) {
|
||||||
|
snprintf(desc, SIZE_OF_DESC, "@DIMM%2X(CPU%x)",
|
||||||
|
data2,
|
||||||
|
(data3 & 0x03) + 1);
|
||||||
|
} else if (chipset_type == 1) {
|
||||||
|
snprintf(desc, SIZE_OF_DESC, "@DIMM%c%c(CPU%x)",
|
||||||
|
(data2 >> 4) + 0x40 + (data3 & 0x3) * 4,
|
||||||
|
(data2 & 0xf) + 0x27, (data3 & 0x03) + 1);
|
||||||
|
} else if (chipset_type == 2) {
|
||||||
|
snprintf(desc, SIZE_OF_DESC, "@DIMM%c%c(CPU%x)",
|
||||||
|
(data2 >> 4) + 0x40 + (data3 & 0x3) * 3,
|
||||||
|
(data2 & 0xf) + 0x27, (data3 & 0x03) + 1);
|
||||||
|
} else {
|
||||||
|
snprintf(desc, SIZE_OF_DESC, "");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SENSOR_TYPE_SUPERMICRO_OEM:
|
||||||
|
if (data1 == 0x80 && data3 == 0xFF) {
|
||||||
|
if (data2 == 0x0) {
|
||||||
|
snprintf(desc, SIZE_OF_DESC, "BMC unexpected reset");
|
||||||
|
} else if (data2 == 0x1) {
|
||||||
|
snprintf(desc, SIZE_OF_DESC, "BMC cold reset");
|
||||||
|
} else if (data2 == 0x2) {
|
||||||
|
snprintf(desc, SIZE_OF_DESC, "BMC warm reset");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function : Decoding the SEL OEM Bytes for the DELL Platforms.
|
* Function : Decoding the SEL OEM Bytes for the DELL Platforms.
|
||||||
* Description : The below fucntion will decode the SEL Events OEM Bytes for the Dell specific Sensors only.
|
* Description : The below fucntion will decode the SEL Events OEM Bytes for the Dell specific Sensors only.
|
||||||
@ -1067,6 +1175,10 @@ ipmi_get_oem_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
|
|||||||
case IPMI_OEM_DELL: // Dell Decoding of the OEM Bytes from SEL Record.
|
case IPMI_OEM_DELL: // Dell Decoding of the OEM Bytes from SEL Record.
|
||||||
desc = get_dell_evt_desc(intf, rec);
|
desc = get_dell_evt_desc(intf, rec);
|
||||||
break;
|
break;
|
||||||
|
case IPMI_OEM_SUPERMICRO:
|
||||||
|
case IPMI_OEM_SUPERMICRO_47488:
|
||||||
|
desc = get_supermicro_evt_desc(intf, rec);
|
||||||
|
break;
|
||||||
case IPMI_OEM_UNKNOWN:
|
case IPMI_OEM_UNKNOWN:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1092,7 +1204,6 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char
|
|||||||
*desc = ipmi_get_oem_desc(intf, rec);
|
*desc = ipmi_get_oem_desc(intf, rec);
|
||||||
return;
|
return;
|
||||||
} else if (rec->sel_type.standard_type.event_type == 0x6f) {
|
} else if (rec->sel_type.standard_type.event_type == 0x6f) {
|
||||||
|
|
||||||
if( rec->sel_type.standard_type.sensor_type >= 0xC0 && rec->sel_type.standard_type.sensor_type < 0xF0) {
|
if( rec->sel_type.standard_type.sensor_type >= 0xC0 && rec->sel_type.standard_type.sensor_type < 0xF0) {
|
||||||
IPMI_OEM iana = ipmi_get_oem(intf);
|
IPMI_OEM iana = ipmi_get_oem(intf);
|
||||||
|
|
||||||
@ -1116,12 +1227,27 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char
|
|||||||
sfx = ipmi_get_oem_desc(intf, rec);
|
sfx = ipmi_get_oem_desc(intf, rec);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case IPMI_OEM_SUPERMICRO:
|
||||||
|
case IPMI_OEM_SUPERMICRO_47488:
|
||||||
|
evt = sensor_specific_types;
|
||||||
|
code = rec->sel_type.standard_type.sensor_type;
|
||||||
|
sfx = ipmi_get_oem_desc(intf, rec);
|
||||||
|
break;
|
||||||
/* add your oem sensor assignation here */
|
/* add your oem sensor assignation here */
|
||||||
}
|
}
|
||||||
if( evt == NULL ){
|
if( evt == NULL ){
|
||||||
lprintf(LOG_DEBUG, "oem sensor type %x using standard type supplied description",
|
lprintf(LOG_DEBUG, "oem sensor type %x using standard type supplied description",
|
||||||
rec->sel_type.standard_type.sensor_type );
|
rec->sel_type.standard_type.sensor_type );
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
switch (ipmi_get_oem(intf)) {
|
||||||
|
case IPMI_OEM_SUPERMICRO:
|
||||||
|
case IPMI_OEM_SUPERMICRO_47488:
|
||||||
|
evt = sensor_specific_types;
|
||||||
|
code = rec->sel_type.standard_type.sensor_type;
|
||||||
|
sfx = ipmi_get_oem_desc(intf, rec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if( evt == NULL ){
|
if( evt == NULL ){
|
||||||
evt = sensor_specific_types;
|
evt = sensor_specific_types;
|
||||||
@ -1210,6 +1336,9 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char
|
|||||||
if(0x01 == offset)
|
if(0x01 == offset)
|
||||||
flag = 0x01;
|
flag = 0x01;
|
||||||
break;
|
break;
|
||||||
|
case SENSOR_TYPE_SUPERMICRO_OEM:
|
||||||
|
flag = 0x02;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1222,6 +1351,10 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memset(*desc, 0, 48 + SIZE_OF_DESC);
|
memset(*desc, 0, 48 + SIZE_OF_DESC);
|
||||||
|
if (flag == 0x02) {
|
||||||
|
sprintf(*desc, "%s", sfx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
sprintf(*desc, "(%s)",sfx);
|
sprintf(*desc, "(%s)",sfx);
|
||||||
}
|
}
|
||||||
free(sfx);
|
free(sfx);
|
||||||
@ -1776,10 +1909,17 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (evt->sel_type.standard_type.event_type == 0x6f) {
|
else if (evt->sel_type.standard_type.event_type == 0x6f) {
|
||||||
|
int print_sensor = 1;
|
||||||
|
switch (ipmi_get_oem(intf)) {
|
||||||
|
case IPMI_OEM_SUPERMICRO:
|
||||||
|
case IPMI_OEM_SUPERMICRO_47488:
|
||||||
|
print_sensor = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Sensor-Specific Discrete
|
* Sensor-Specific Discrete
|
||||||
*/
|
*/
|
||||||
if (evt->sel_type.standard_type.sensor_type == 0xC &&
|
if (print_sensor && evt->sel_type.standard_type.sensor_type == 0xC && /*TODO*/
|
||||||
evt->sel_type.standard_type.sensor_num == 0 &&
|
evt->sel_type.standard_type.sensor_num == 0 &&
|
||||||
(evt->sel_type.standard_type.event_data[0] & 0x30) == 0x20) {
|
(evt->sel_type.standard_type.event_data[0] & 0x30) == 0x20) {
|
||||||
/* break down memory ECC reporting if we can */
|
/* break down memory ECC reporting if we can */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user