diff options
author | Brian Horton <brianh@linux.ibm.com> | 2015-03-02 12:12:28 -0600 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2015-03-11 00:45:57 -0500 |
commit | bda236e6e0c7d3aa5165160abbd5ead92ac0a68e (patch) | |
tree | 3aeb5c836873cacb78083b25a98092c5a4a86a4c /src | |
parent | 788ec2a6d01df562f38352443bacd68c9cb0c633 (diff) | |
download | talos-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.H | 20 | ||||
-rw-r--r-- | src/usr/errl/errlmanager_common.C | 43 | ||||
-rw-r--r-- | src/usr/ipmi/ipmisel.C | 61 |
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 |