diff options
author | Mars J Wilks <mjwilks@us.ibm.com> | 2015-09-09 09:06:15 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2015-09-30 09:26:07 -0500 |
commit | bc98d0b885dcfef970a2135c18ce7d55ab68b366 (patch) | |
tree | f7ad9c8d7326ee9c011edba35d59bcfbcde0b047 /src/usr | |
parent | 2257ff8dba986bc5efe691f400fce104829bfe33 (diff) | |
download | talos-hostboot-bc98d0b885dcfef970a2135c18ce7d55ab68b366.tar.gz talos-hostboot-bc98d0b885dcfef970a2135c18ce7d55ab68b366.zip |
DIMM Plugging Errors
This adds logic to change memory sensors to the sensor-specific offset
'Configuration error' whenever a memory plugging error appears in
an error log.
Change-Id: I94a58d55b8c81d106f77b00ee37c4d70a12a9fca
RTC:130381
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/20409
Tested-by: Jenkins Server
Tested-by: Jenkins OP Build CI
Tested-by: Jenkins OP HW
Tested-by: FSP CI Jenkins
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r-- | src/usr/errl/errlmanager_common.C | 150 |
1 files changed, 96 insertions, 54 deletions
diff --git a/src/usr/errl/errlmanager_common.C b/src/usr/errl/errlmanager_common.C index 51ed8fa77..0020ee14e 100644 --- a/src/usr/errl/errlmanager_common.C +++ b/src/usr/errl/errlmanager_common.C @@ -449,6 +449,49 @@ void getSensorInfo(HWAS::callout_ud_t *i_ud, uint8_t &o_eventOffset, errlHndl_t& io_error ); +// SensorModifier is a class that detects certain procedure callouts that +// can override the sensors generated by hardware callouts. +// For example, a memory plugging error can override a hardware callout +// of type memory in order to indicate a "configuration error" occured +// See errlmanager.H for more info + +// The constructor initializes flags for procedure callouts. +inline SensorModifier::SensorModifier() +{ + iv_flag = 0; +}; + +// Consider this callout as a potential sensor modifier +inline void SensorModifier::considerCallout(HWAS::callout_ud_t *i_ud) +{ + if (i_ud->type == HWAS::PROCEDURE_CALLOUT && + i_ud->procedure == HWAS::EPUB_PRC_MEMORY_PLUGGING_ERROR) + { + iv_flag |= memory_plugging_error_mask; + } +}; + +// Modify the sensor if flag was set for that sensor. +inline bool SensorModifier::modifySensor(uint8_t i_sensorType, + uint8_t& o_eventDirType, uint8_t& o_specificOffset) +{ + bool l_retval = false; + if( (iv_flag & memory_plugging_error_mask) && + // we had a memory configuration error + i_sensorType == TARGETING::SENSOR_TYPE_MEMORY + ) + { + o_eventDirType = IPMISEL::sensor_specific; + // 0x6f Sensor-specific Offset + o_specificOffset = IPMISEL::event_data1_trans_monitor; + // 0x07 Configuration Error + // modified + l_retval = true; + } + return l_retval; +} + + /////////////////////////////////////////////////////////////////////////////// // ErrlManager::sendErrLogToBmc() /////////////////////////////////////////////////////////////////////////////// @@ -459,6 +502,8 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels) io_err->eid(), i_sendSels); do { + // keep track of procedure callouts that modify hardware callouts + SensorModifier l_modifier; // Decide whether we want to skip the error log if( io_err->getSkipShowingLog() ) @@ -469,13 +514,15 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels) break; } - std::vector<std::pair<uint8_t, uint8_t> > l_sensorNumbers; + // two pass algorithm to find the highest priority callout + // then send SELs for only the highest priority callouts + std::vector< HWAS::callout_ud_t* > l_callouts; HWAS::callOutPriority l_priority = HWAS::SRCI_PRIORITY_NONE; if (i_sendSels) { // look thru the errlog for any Callout UserDetail sections - // to determine the sensor information for the SEL - // create a vector of sensor numbers and offsets + // to later determine the sensor information for each SEL + // create a vector of callouts during the first pass for(std::vector<ErrlUD*>::const_iterator it = io_err->iv_SectionVector.begin(); it != io_err->iv_SectionVector.end(); @@ -489,43 +536,21 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels) HWAS::callout_ud_t *l_ud = reinterpret_cast<HWAS::callout_ud_t*>((*it)->iv_pData); - // if this callout isn't higher than any previous callout - if (l_ud->priority < l_priority) - { - continue; // on to the next - } - - // if greater, than clear out the previous list + // if this callout is higher than any previous callout if (l_ud->priority > l_priority) { TRACFCOMP(g_trac_errl, "sendErrLogToBmc new priority picked 0x%x > 0x%x", l_ud->priority, l_priority ); - //remove previous sensor data - l_sensorNumbers.clear(); - // and update the priority l_priority = l_ud->priority; } + // consider as a potential modifier of other callouts + l_modifier.considerCallout(l_ud); - // greater than or equal - save this sensor - - //get the sensor number for the target - uint8_t l_sensorNumber = - TARGETING::UTIL::INVALID_IPMI_SENSOR; - uint8_t l_eventOffset = - IPMISEL::event_data1_invalid_offset; - - getSensorInfo( l_ud, l_sensorNumber, l_eventOffset, - io_err); - - TRACFCOMP(g_trac_errl, - "l_sensorNumber = 0x%x, l_eventOffset = 0x%x", - l_sensorNumber, l_eventOffset ); - - l_sensorNumbers.push_back( - std::make_pair(l_sensorNumber, l_eventOffset)); + // add to list to be traversed in second pass + l_callouts.push_back(l_ud); } // if callout } // for each SectionVector } // if i_sendSels @@ -555,49 +580,61 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels) if (i_sendSels) { - for(size_t i = 0; i < l_sensorNumbers.size(); i++) + for(size_t i = 0; i < l_callouts.size(); i++) { - uint8_t l_eventDirType = IPMISEL::sensor_specific; + uint8_t l_eventDirType = IPMISEL::sensor_specific; + uint8_t l_sensorNumber = TARGETING::UTIL::INVALID_IPMI_SENSOR; + uint8_t l_eventOffset = IPMISEL::event_data1_invalid_offset; + + // simplify callout notation + HWAS::callout_ud_t* l_ud = l_callouts.at(i); + + // populate l_sensorNumber and l_eventOffset with values + getSensorInfo( l_ud, l_sensorNumber, l_eventOffset, io_err); - // if the offset is unknown after this then it will - // be updated based on elog severity below - uint8_t l_eventOffset = l_sensorNumbers.at(i).second ; + // if the offset is unknown at this point then it will + // be updated below by getSensorOffsetBasedOnSeverity // last ditch effort, if no sensor number is present at this // point, just use the system event sensor - if( l_sensorNumbers.at(i).first == + if( l_sensorNumber == TARGETING::UTIL::INVALID_IPMI_SENSOR ) { - l_sensorNumbers.at(i).first = + l_sensorNumber = TARGETING::UTIL::getSensorNumber(NULL, TARGETING::SENSOR_NAME_SYSTEM_EVENT); - l_sensorNumbers.at(i).second = + l_eventOffset = SENSOR::UNDETERMINED_SYSTEM_HW_FAILURE; } // grab the sensor type so the bmc knows how to use the offset uint8_t unused = 0; - uint8_t l_SensorType = 0; + uint8_t l_sensorType = 0; errlHndl_t e = SENSOR::SensorBase::getSensorType( - l_sensorNumbers.at(i).first, - l_SensorType,unused); + l_sensorNumber, + l_sensorType,unused); if( e ) { TRACFCOMP(g_trac_errl, ERR_MRK"Failed to get sensor type for sensor %d", - l_sensorNumbers.at(i).first); + l_sensorNumber); - l_SensorType = 0; + l_sensorType = 0; // since we are in the commit path, lets just delete this // error and move on. delete e; } + // this call will modify the sensor if any procedure callout is + // known to change its effect + bool l_wasModified = l_modifier.modifySensor(l_sensorType, + l_eventDirType, l_eventOffset); + // if no offset has been configured set it based on the severity if( l_eventOffset == IPMISEL::event_data1_invalid_offset ) { @@ -609,17 +646,22 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels) // pel data, otherwise we send no data uint32_t selSize = ( i == 0 ) ? l_pelSize:0; - TRACFCOMP(g_trac_errl, INFO_MRK - "sendErrLogToBmc: sensor %.2x/%.2x event %x/%x, size %d", - l_SensorType, l_sensorNumbers.at(i).first, - l_eventDirType, l_eventOffset, selSize ); - - IPMISEL::sendESEL(l_pelData, selSize, - io_err->eid(), - l_eventDirType, l_eventOffset, - l_SensorType, - l_sensorNumbers.at(i).first); - } // for l_sensorNumbers + // only send highest priority SELs or + // SELs of lesser priority that were modified + if (l_ud->priority == l_priority || l_wasModified) + { + TRACFCOMP(g_trac_errl, INFO_MRK "sendErrLogToBmc:" + " sensor %.2x/%.2x event %x/%x, size %d", + l_sensorType, l_sensorNumber, + l_eventDirType, l_eventOffset, selSize ); + + IPMISEL::sendESEL(l_pelData, selSize, + io_err->eid(), + l_eventDirType, l_eventOffset, + l_sensorType, + l_sensorNumber); + } + } // for l_callouts } else { |