summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBrian Horton <brianh@linux.ibm.com>2015-03-02 12:12:28 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2015-03-11 00:45:57 -0500
commitbda236e6e0c7d3aa5165160abbd5ead92ac0a68e (patch)
tree3aeb5c836873cacb78083b25a98092c5a4a86a4c /src
parent788ec2a6d01df562f38352443bacd68c9cb0c633 (diff)
downloadtalos-hostboot-bda236e6e0c7d3aa5165160abbd5ead92ac0a68e.tar.gz
talos-hostboot-bda236e6e0c7d3aa5165160abbd5ead92ac0a68e.zip
change error log to SEL processing
for hostboot runtime, do not send eSEL (AMI bug) for hostboot ipl, send down SEL following eSEL Change-Id: I86ee9766e27548c3f7f72fbdbfd76c8a8be7da73 RTC: 124971 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/16107 Tested-by: Jenkins Server Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: Brian Silver <bsilver@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/ipmi/ipmisel.H20
-rw-r--r--src/usr/errl/errlmanager_common.C43
-rw-r--r--src/usr/ipmi/ipmisel.C61
3 files changed, 108 insertions, 16 deletions
diff --git a/src/include/usr/ipmi/ipmisel.H b/src/include/usr/ipmi/ipmisel.H
index de2dd3218..af808515d 100644
--- a/src/include/usr/ipmi/ipmisel.H
+++ b/src/include/usr/ipmi/ipmisel.H
@@ -65,11 +65,13 @@ namespace IPMISEL
* @param[in] size of eSEL data
* @param[in] eid of errorlog for this eSEL (for ack)
* @param[in] event_dir_type for this eSEL
+ * @param[in] event_offset for this eSEL
* @param[in] sensorType that caused the error/eSEL
* @param[in] sensorNumber that caused the error/eSEL
*/
void sendESEL(uint8_t* i_eselData, uint32_t i_dataSize,
- uint32_t i_eid, uint8_t i_eventDirType,
+ uint32_t i_eid,
+ uint8_t i_eventDirType, uint8_t i_eventOffset,
uint8_t i_sensorType, uint8_t i_sensorNumber);
// per IPMI Spec, section 32.1 SEL Event Records
@@ -85,6 +87,7 @@ namespace IPMISEL
format_ipmi_version_2_0 = 0x04,
};
+ // event_type, per section 42.1 of the IPMI spec
enum sel_event_dir_type
{
event_unspecified = 0x00,
@@ -93,11 +96,24 @@ namespace IPMISEL
event_predictive = 0x04,
event_limit = 0x05,
event_permformance = 0x06,
+ event_transition = 0x07,
+ event_OEM = 0x70,
};
enum sel_event_data
{
- event_data1_ami = 0xAA,
+ event_data1_ami = 0xAA,
+ event_data1_deasserted = 0x00,
+ event_data1_asserted = 0x01,
+ event_data1_trans_to_ok = 0x00,
+ event_data1_trans_to_noncrit_from_ok = 0x01,
+ event_data1_trans_to_crit_from_less = 0x02,
+ event_data1_trans_to_non_recv_from_less = 0x03,
+ event_data1_trans_to_non_crit_from_more = 0x04,
+ event_data1_trans_to_crit_from_non_r = 0x05,
+ event_data1_trans_to_non_recoverable = 0x06,
+ event_data1_trans_monitor = 0x07,
+ event_data1_trans_informational = 0x08,
};
enum sel_generator_id
diff --git a/src/usr/errl/errlmanager_common.C b/src/usr/errl/errlmanager_common.C
index a64ed3beb..fb4175092 100644
--- a/src/usr/errl/errlmanager_common.C
+++ b/src/usr/errl/errlmanager_common.C
@@ -100,7 +100,9 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err)
l_sensorType, unused );
if( e )
{
- TRACFCOMP(g_trac_errl, ERR_MRK"Failed to get sensor type for sensor %d",l_sensorNumber);
+ TRACFCOMP(g_trac_errl,
+ ERR_MRK"Failed to get sensor type for sensor %d",
+ l_sensorNumber);
// since we are in the commit path, lets just delete this
// error and move on.
delete e;
@@ -130,12 +132,45 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err)
break;
}
+ uint8_t l_eventDirType = IPMISEL::event_transition;
+ uint8_t l_eventOffset = IPMISEL::event_data1_trans_to_non_recoverable;
+ switch (io_err->sev())
+ {
+ case ERRORLOG::ERRL_SEV_INFORMATIONAL:
+ l_eventDirType = IPMISEL::event_transition;
+ l_eventOffset = IPMISEL::event_data1_trans_informational;
+ break;
+ case ERRL_SEV_RECOVERED:
+ l_eventDirType = IPMISEL::event_transition;
+ l_eventOffset = IPMISEL::event_data1_trans_to_ok;
+ break;
+ case ERRL_SEV_PREDICTIVE:
+ l_eventDirType = IPMISEL::event_predictive;
+ l_eventOffset = IPMISEL::event_data1_trans_to_noncrit_from_ok;
+ break;
+ case ERRL_SEV_UNRECOVERABLE:
+ l_eventDirType = IPMISEL::event_transition;
+ l_eventOffset = IPMISEL::event_data1_trans_to_non_recoverable;
+ break;
+ case ERRL_SEV_CRITICAL_SYS_TERM:
+ l_eventDirType = IPMISEL::event_transition;
+ l_eventOffset = IPMISEL::event_data1_trans_to_crit_from_non_r;
+ break;
+ case ERRL_SEV_UNKNOWN:
+ l_eventDirType = IPMISEL::event_state;
+ l_eventOffset = IPMISEL::event_data1_asserted;
+ break;
+ }
+
// send it to the BMC over IPMI
TRACFCOMP(g_trac_errl, INFO_MRK
- "sendErrLogToBmc: sensor %.2x/%.2x, size %d",
- l_sensorType, l_sensorNumber, l_pelSize);
+ "sendErrLogToBmc: sensor %.2x/%.2x event %x/%x, size %d",
+ l_sensorType, l_sensorNumber,
+ l_eventDirType, l_eventOffset,
+ l_pelSize);
IPMISEL::sendESEL(l_pelData, l_pelSize,
- io_err->eid(), IPMISEL::event_unspecified,
+ io_err->eid(),
+ l_eventDirType, l_eventOffset,
l_sensorType, l_sensorNumber);
// free the buffer
diff --git a/src/usr/ipmi/ipmisel.C b/src/usr/ipmi/ipmisel.C
index c05c60f26..49dcee670 100644
--- a/src/usr/ipmi/ipmisel.C
+++ b/src/usr/ipmi/ipmisel.C
@@ -82,7 +82,8 @@ enum esel_retry
namespace IPMISEL
{
void sendESEL(uint8_t* i_eselData, uint32_t i_dataSize,
- uint32_t i_eid, uint8_t i_eventDirType,
+ uint32_t i_eid,
+ uint8_t i_eventDirType, uint8_t i_eventOffset,
uint8_t i_sensorType, uint8_t i_sensorNumber)
{
IPMI_TRAC(ENTER_MRK "sendESEL()");
@@ -100,13 +101,13 @@ void sendESEL(uint8_t* i_eselData, uint32_t i_dataSize,
// create the sel record of information
selRecord l_sel;
- l_sel.record_type = record_type_ami_esel;
+ l_sel.record_type = record_type_system_event;
l_sel.generator_id = generator_id_ami;
l_sel.evm_format_version = format_ipmi_version_2_0;
l_sel.sensor_type = i_sensorType;
l_sel.sensor_number = i_sensorNumber;
l_sel.event_dir_type = i_eventDirType;
- l_sel.event_data1 = event_data1_ami;
+ l_sel.event_data1 = i_eventOffset;
eselInitData *eselData =
new eselInitData(&l_sel, i_eselData, i_dataSize);
@@ -216,13 +217,16 @@ void send_esel(eselInitData * i_data,
{
IPMI_TRAC(ENTER_MRK "send_esel");
uint8_t* data = NULL;
- const size_t l_eSELlen = i_data->dataSize;
size_t len = 0;
- uint8_t reserveID[2] = {0,0};
uint8_t esel_recordID[2] = {0,0};
+ uint8_t sel_recordID[2] = {0,0};
+#ifndef __HOSTBOOT_RUNTIME
+// TODO RTC: 124972 take this out when runtime supports the eSEL
do{
+ const size_t l_eSELlen = i_data->dataSize;
+ uint8_t reserveID[2] = {0,0};
// we need to send down the extended sel data (eSEL), which is
// longer than the protocol buffer, so we need to do a reservation and
// call the AMI partial_add_esel command multiple times
@@ -258,6 +262,9 @@ void send_esel(eselInitData * i_data,
// copy in the SEL event record data
memcpy(&data[PARTIAL_ADD_ESEL_REQ], i_data->eSel,
sizeof(selRecord));
+ // update to make this what AMI eSEL wants
+ data[PARTIAL_ADD_ESEL_REQ + offsetof(selRecord,record_type)] = record_type_ami_esel;
+ data[PARTIAL_ADD_ESEL_REQ + offsetof(selRecord,event_data1)] = event_data1_ami;
o_cc = IPMI::CC_UNKBAD;
TRACFBIN( g_trac_ipmi, INFO_MRK"1st partial_add_esel:", data, len);
@@ -338,17 +345,51 @@ void send_esel(eselInitData * i_data,
// BMC returns the recordID, it's always the same (unless
// there's a major BMC bug...)
storeReserveRecord(esel_recordID,data);
+ } // while eSELindex
+ }while(0);
+#endif
+
+ // if eSEL wasn't created due to an error, we don't want to continue
+ if(o_err == NULL)
+ {
+ // if the eSEL wasn't created due to a bad completion code, we will
+ // still try to send down a SEL that we create, which will contain
+ // the eSEL recordID (if it was successful)
+ delete [] data;
+ len = sizeof(IPMISEL::selRecord);
+ data = new uint8_t[len];
+
+ // copy in the SEL event record data
+ memcpy(data, i_data->eSel, sizeof(IPMISEL::selRecord));
+ // copy the eSEL recordID (if it was created) into the extra data area
+ data[offsetof(selRecord,event_data2)] = esel_recordID[1];
+ data[offsetof(selRecord,event_data3)] = esel_recordID[0];
+
+ // use local cc so that we don't corrupt the esel from above
+ IPMI::completion_code l_cc = IPMI::CC_UNKBAD;
+ TRACFBIN( g_trac_ipmi, INFO_MRK"add_sel:", data, len);
+ o_err = IPMI::sendrecv(IPMI::add_sel(),l_cc,len,data);
+ if(o_err)
+ {
+ IPMI_TRAC(ERR_MRK "error from add_sel");
}
- if(o_err || (o_cc != IPMI::CC_OK))
+ else if (l_cc != IPMI::CC_OK)
{
- break;
+ IPMI_TRAC(ERR_MRK "failed add_sel, l_cc %02x", l_cc);
}
- }while(0);
+ else
+ {
+ // if CC_OK, then len = 2 and data contains the recordID of the new SEL
+ storeReserveRecord(sel_recordID,data);
+ }
+ }
delete[] data;
- IPMI_TRAC(EXIT_MRK "send_esel (o_err %.8X, o_cc x%.2x, recID=x%x%x)",
- o_err ? o_err->plid() : NULL, o_cc, esel_recordID[1], esel_recordID[0]);
+ IPMI_TRAC(EXIT_MRK
+ "send_esel o_err=%.8X, o_cc=x%.2x, sel recID=x%x%x, esel recID=x%x%x",
+ o_err ? o_err->plid() : NULL, o_cc, sel_recordID[1], sel_recordID[0],
+ esel_recordID[1], esel_recordID[0]);
return;
} // send_esel
OpenPOWER on IntegriCloud