summaryrefslogtreecommitdiffstats
path: root/src/usr/errl
diff options
context:
space:
mode:
authorMars J Wilks <mjwilks@us.ibm.com>2015-09-09 09:06:15 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2015-09-30 09:26:07 -0500
commitbc98d0b885dcfef970a2135c18ce7d55ab68b366 (patch)
treef7ad9c8d7326ee9c011edba35d59bcfbcde0b047 /src/usr/errl
parent2257ff8dba986bc5efe691f400fce104829bfe33 (diff)
downloadtalos-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/errl')
-rw-r--r--src/usr/errl/errlmanager_common.C150
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
{
OpenPOWER on IntegriCloud