| From 03029acd024ac886296f8ed0cbc711d9b81b26da Mon Sep 17 00:00:00 2001 |
| From: Brian Horton <brianh@linux.ibm.com> |
| Date: Mon, 2 Mar 2015 12:12:28 -0600 |
| Subject: [PATCH] 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 |
| --- |
| src/include/usr/ipmi/ipmisel.H | 18 ++++++++++-- |
| src/usr/errl/errlmanager_common.C | 4 ++- |
| src/usr/ipmi/ipmisel.C | 61 ++++++++++++++++++++++++++++++++------- |
| 3 files changed, 70 insertions(+), 13 deletions(-) |
| |
| diff --git a/src/include/usr/ipmi/ipmisel.H b/src/include/usr/ipmi/ipmisel.H |
| index de2dd32..91e3651 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,22 @@ 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_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 a64ed3b..6c68818 100644 |
| --- a/src/usr/errl/errlmanager_common.C |
| +++ b/src/usr/errl/errlmanager_common.C |
| @@ -135,7 +135,9 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err) |
| "sendErrLogToBmc: sensor %.2x/%.2x, size %d", |
| l_sensorType, l_sensorNumber, l_pelSize); |
| IPMISEL::sendESEL(l_pelData, l_pelSize, |
| - io_err->eid(), IPMISEL::event_unspecified, |
| + io_err->eid(), |
| + IPMISEL::event_transition, |
| + IPMISEL::event_data1_trans_to_non_recoverable, |
| l_sensorType, l_sensorNumber); |
| |
| // free the buffer |
| diff --git a/src/usr/ipmi/ipmisel.C b/src/usr/ipmi/ipmisel.C |
| index c05c60f..49dcee6 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 |
| -- |
| 1.8.2.2 |
| |