summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/usr/errl/errlmanager.H15
-rw-r--r--src/include/usr/ipmi/ipmisel.H9
-rw-r--r--src/usr/errl/errlmanager_common.C252
3 files changed, 177 insertions, 99 deletions
diff --git a/src/include/usr/errl/errlmanager.H b/src/include/usr/errl/errlmanager.H
index 745330537..7112a85eb 100644
--- a/src/include/usr/errl/errlmanager.H
+++ b/src/include/usr/errl/errlmanager.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2015 */
+/* Contributors Listed Below - COPYRIGHT 2011,2016 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -605,7 +605,9 @@ class SensorModifier
* stored in the rightmost bit so it's mask is 0x0000000000000001.
*/
enum {
- memory_plugging_error_mask=0x0000000000000001
+ memory_plugging_error_mask=0x0000000000000001,
+ bus_error_mask=0x0000000000000002,
+ membus_error_mask=0x00000000000000004,
};
public:
@@ -637,13 +639,14 @@ public:
*
* @param [in] i_sensorType Sensor type to be considered for modification
* @param [out] o_eventDirType EventDirType to be modified based on sensor
- * @param [out] o_specificOffset Offset to be modified based on sensor
+ * @param [out] o_specificOffset An array of offsets to modified based on
+ * sensor.
*
- * @return Returns a boolean, where a value of true indicates that the
- * sensor was modified.
+ * @return Returns a boolean, where a value of true indicates that the
+ * sensor was modified.
*/
bool modifySensor(uint8_t i_sensorType, uint8_t& o_eventDirType,
- uint8_t& o_specificOffset);
+ uint8_t& o_specificOffset);
};
#endif //CONFIG_BMC_IPMI
diff --git a/src/include/usr/ipmi/ipmisel.H b/src/include/usr/ipmi/ipmisel.H
index 7e16d3e3a..3ffa34e4a 100644
--- a/src/include/usr/ipmi/ipmisel.H
+++ b/src/include/usr/ipmi/ipmisel.H
@@ -124,6 +124,11 @@ namespace IPMISEL
event_data1_trans_monitor = 0x07,
event_data1_trans_informational = 0x08,
event_data1_invalid_offset = 0xFF,
+
+ // sel events for sensor specific offsets
+ mem_event_configuration_error = 0x07,
+ proc_event_correctable_mach_check_err = 0x0C,
+ mem_event_device_disabled = 0x04,
};
enum sel_generator_id
@@ -145,11 +150,11 @@ namespace IPMISEL
// Time when event was logged. LS byte first.
uint32_t timestamp;
- // Manufacturer ID
+ // Manufacturer ID
uint8_t manufactureId_data1;
uint8_t manufactureId_data2;
uint8_t manufactureId_data3;
-
+
// OEM defined
uint8_t event_data1;
uint8_t event_data2;
diff --git a/src/usr/errl/errlmanager_common.C b/src/usr/errl/errlmanager_common.C
index d2cc269a8..48f84eed6 100644
--- a/src/usr/errl/errlmanager_common.C
+++ b/src/usr/errl/errlmanager_common.C
@@ -32,11 +32,16 @@
#include <sys/mm.h>
#include <pnor/pnorif.H>
#include <errl/errludstring.H>
+#include <map>
+
namespace ERRORLOG
{
extern trace_desc_t* g_trac_errl;
+// the maximum number of targets that a callout is associated with
+#define MAX_NUM_TARGETS 2
+
const uint32_t PNOR_ERROR_LENGTH = 4096;
const uint32_t EMPTY_ERRLOG_IN_PNOR = 0xFFFFFFFF;
const uint32_t FIRST_BYTE_ERRLOG = 0xF0000000;
@@ -444,9 +449,9 @@ void getSensorOffsetBasedOnSeverity(errlHndl_t & io_err,
uint8_t & o_offset );
// helper function to gather sensor information
-void getSensorInfo(HWAS::callout_ud_t *i_ud,
- uint8_t &o_sensorNumber,
- uint8_t &o_eventOffset,
+uint8_t getSensorInfo(HWAS::callout_ud_t *i_ud,
+ uint8_t* o_sensorNumber,
+ uint8_t* o_eventOffset,
errlHndl_t& io_error );
// SensorModifier is a class that detects certain procedure callouts that
@@ -469,6 +474,19 @@ inline void SensorModifier::considerCallout(HWAS::callout_ud_t *i_ud)
{
iv_flag |= memory_plugging_error_mask;
}
+ else if (i_ud->type == HWAS::PROCEDURE_CALLOUT &&
+ (i_ud->procedure == HWAS::EPUB_PRC_PROC_AB_BUS ||
+ i_ud->procedure == HWAS::EPUB_PRC_PROC_XYZ_BUS ||
+ i_ud->procedure == HWAS::EPUB_PRC_EIBUS_ERROR)
+ )
+ {
+ iv_flag |= bus_error_mask;
+ }
+ else if (i_ud->type == HWAS::PROCEDURE_CALLOUT &&
+ i_ud->procedure == HWAS::EPUB_PRC_MEMBUS_ERROR)
+ {
+ iv_flag |= membus_error_mask;
+ }
};
// Modify the sensor if flag was set for that sensor.
@@ -478,16 +496,33 @@ inline bool SensorModifier::modifySensor(uint8_t i_sensorType,
bool l_retval = false;
if( (iv_flag & memory_plugging_error_mask) &&
// we had a memory configuration error
- i_sensorType == TARGETING::SENSOR_TYPE_MEMORY
- )
+ i_sensorType == TARGETING::SENSOR_TYPE_MEMORY)
{
o_eventDirType = IPMISEL::sensor_specific;
// 0x6f Sensor-specific Offset
- o_specificOffset = IPMISEL::event_data1_trans_monitor;
+ o_specificOffset = IPMISEL::mem_event_configuration_error;
// 0x07 Configuration Error
// modified
l_retval = true;
}
+ else if ( (iv_flag & bus_error_mask || iv_flag & membus_error_mask) &&
+ i_sensorType == TARGETING::SENSOR_TYPE_PROCESSOR)
+ {
+ o_eventDirType = IPMISEL::sensor_specific;
+ o_specificOffset = IPMISEL::proc_event_correctable_mach_check_err;
+ // 0x0Ch Correctable Machine Check Error
+ // modified;
+ l_retval = true;
+ }
+ else if ( (iv_flag & membus_error_mask) &&
+ i_sensorType == TARGETING::SENSOR_TYPE_MEMORY)
+ {
+ o_eventDirType = IPMISEL::sensor_specific;
+ o_specificOffset = IPMISEL::mem_event_device_disabled;
+ // 0x04 Memory device disabled
+ // modified;
+ l_retval = true;
+ }
return l_retval;
}
@@ -497,10 +532,10 @@ inline bool SensorModifier::modifySensor(uint8_t i_sensorType,
///////////////////////////////////////////////////////////////////////////////
void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels)
{
- TRACFCOMP(g_trac_errl, ENTER_MRK
+ TRACFCOMP(g_trac_errl,
+ ENTER_MRK
"sendErrLogToBmc errlogId 0x%.8x, i_sendSels %d",
io_err->eid(), i_sendSels);
-
do {
// keep track of procedure callouts that modify hardware callouts
SensorModifier l_modifier;
@@ -509,7 +544,7 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels)
if( io_err->getSkipShowingLog() )
{
TRACFCOMP( g_trac_errl, INFO_MRK
- "sendErrLogToBmc: %.8X is INFORMATIONAL/RECOVERED; skipping",
+ "sendErrLogToBmc: %.8X is INFORMATIONAL/RECOVERED; skipping",
io_err->eid());
break;
}
@@ -533,6 +568,7 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels)
(1 == (*it)->iv_header.iv_ver) &&
(ERRL_UDT_CALLOUT == (*it)->iv_header.iv_sst) )
{
+
HWAS::callout_ud_t *l_ud =
reinterpret_cast<HWAS::callout_ud_t*>((*it)->iv_pData);
@@ -542,7 +578,6 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels)
TRACFCOMP(g_trac_errl,
"sendErrLogToBmc new priority picked 0x%x > 0x%x",
l_ud->priority, l_priority );
-
// and update the priority
l_priority = l_ud->priority;
}
@@ -592,88 +627,119 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels)
break;
}
+ // list of sels to be sent
std::vector<IPMISEL::sel_info_t*> l_selEventList;
+
+ // bool default constructor initializes to false as per C++ standard
+ std::map<uint8_t, bool> l_sensorNumberEncountered;
+
if (i_sendSels)
{
l_selEventList.clear();
- for(size_t i = 0; i < l_callouts.size(); i++)
+ std::vector<HWAS::callout_ud_t*>::const_iterator i;
+ for(i = l_callouts.begin(); i != l_callouts.end(); ++i)
{
- 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;
+ uint8_t l_eventDirType[MAX_NUM_TARGETS] = {
+ IPMISEL::sensor_specific,
+ // this second element is only used for bus callouts
+ IPMISEL::sensor_specific};
+ uint8_t l_sensorNumber[MAX_NUM_TARGETS] = {
+ TARGETING::UTIL::INVALID_IPMI_SENSOR,
+ // this second element is only used for bus callouts
+ TARGETING::UTIL::INVALID_IPMI_SENSOR};
+ uint8_t l_eventOffset[MAX_NUM_TARGETS] = {
+ IPMISEL::event_data1_invalid_offset,
+ // this second element is only used for bus callouts
+ IPMISEL::event_data1_invalid_offset};
+ uint8_t l_sensorType[MAX_NUM_TARGETS] = { 0,
+ // this second element is only used for bus callouts
+ 0};
// simplify callout notation
- HWAS::callout_ud_t* l_ud = l_callouts.at(i);
+ HWAS::callout_ud_t* l_ud = *i;
// populate l_sensorNumber and l_eventOffset with values
- getSensorInfo( l_ud, l_sensorNumber, l_eventOffset, io_err);
+ uint8_t l_num_targets = getSensorInfo(l_ud, l_sensorNumber,
+ l_eventOffset, io_err);
// 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_sensorNumber ==
- TARGETING::UTIL::INVALID_IPMI_SENSOR )
+ // l_num_targets is 2 for bus callouts, 1 otherwise
+ for (size_t j=0; j < l_num_targets; ++j)
{
- l_sensorNumber =
- TARGETING::UTIL::getSensorNumber(NULL,
- TARGETING::SENSOR_NAME_SYSTEM_EVENT);
-
- l_eventOffset =
- SENSOR::UNDETERMINED_SYSTEM_HW_FAILURE;
+ // last ditch effort, if no sensor number is present at
+ // this point, just use the system event sensor
+ if( l_sensorNumber[j] ==
+ TARGETING::UTIL::INVALID_IPMI_SENSOR )
+ {
+ l_sensorNumber[j] =
+ TARGETING::UTIL::getSensorNumber(NULL,
+ TARGETING::SENSOR_NAME_SYSTEM_EVENT);
- }
+ l_eventOffset[j] =
+ 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;
- errlHndl_t e =
- SENSOR::SensorBase::getSensorType(
- l_sensorNumber,
- l_sensorType,unused);
+ // grab the sensor type so the bmc knows how to use the
+ // offset
+ uint8_t unused = 0;
+ errlHndl_t e =
+ SENSOR::SensorBase::getSensorType(
+ l_sensorNumber[j],
+ l_sensorType[j],unused);
- if( e )
- {
- TRACFCOMP(g_trac_errl,
- ERR_MRK"Failed to get sensor type for sensor %d",
- l_sensorNumber);
-
- l_sensorType = 0;
- // since we are in the commit path, lets just delete this
- // error and move on.
- delete e;
- }
+ if( e )
+ {
+ TRACFCOMP(g_trac_errl,
+ ERR_MRK"Failed to get sensor type for sensor %d",
+ l_sensorNumber[j]);
+ l_sensorType[j] = 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);
+ // this call will modify the sensor if any procedure
+ // callout is known to change its effect
+ bool l_wasModified = l_modifier.modifySensor(
+ l_sensorType[j], l_eventDirType[j], l_eventOffset[j]);
- // if no offset has been configured set it based on the severity
- if( l_eventOffset == IPMISEL::event_data1_invalid_offset )
- {
- getSensorOffsetBasedOnSeverity(io_err, l_eventDirType,
- l_eventOffset );
- }
+ // if no offset has been configured set it based on the
+ // severity
+ if(l_eventOffset[j] == IPMISEL::event_data1_invalid_offset)
+ {
+ getSensorOffsetBasedOnSeverity(io_err,
+ l_eventDirType[j], l_eventOffset[j]);
+ }
- // 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:"
+ // only send highest priority SELs or
+ // SELs of lesser priority that were modified
+ if (l_ud->priority == l_priority || l_wasModified)
+ {
+ // skip this iteration if we've seen this sensor
+ // number before
+ if (l_sensorNumberEncountered[l_sensorNumber[j]])
+ continue;
+ TRACFCOMP(g_trac_errl, INFO_MRK "sendErrLogToBmc:"
" sensor %.2x/%.2x event %x/%x, size %d",
- l_sensorType, l_sensorNumber,
- l_eventDirType, l_eventOffset, l_pelSize);
+ l_sensorType[j], l_sensorNumber[j],
+ l_eventDirType[j], l_eventOffset[j], l_pelSize);
- IPMISEL::sel_info_t *l_selEvent = new (IPMISEL::sel_info_t);
- l_selEvent->eventDirType = l_eventDirType;
- l_selEvent->sensorNumber = l_sensorNumber;
- l_selEvent->eventOffset = l_eventOffset;
- l_selEvent->sensorType = l_sensorType;
+ IPMISEL::sel_info_t *l_selEvent =
+ new(IPMISEL::sel_info_t);
+ l_selEvent->eventDirType = l_eventDirType[j];
+ l_selEvent->sensorNumber = l_sensorNumber[j];
+ l_selEvent->eventOffset = l_eventOffset[j];
+ l_selEvent->sensorType = l_sensorType[j];
- l_selEventList.push_back(l_selEvent);
- }
+ // add to the list that goes out on the wire
+ l_selEventList.push_back(l_selEvent);
+
+ // make a note we've seen this sensor number before
+ l_sensorNumberEncountered[l_sensorNumber[j]] = true;
+ }
+ } // for l_num_targets
} // for l_callouts
@@ -692,8 +758,7 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels)
{
// don't send sensor SELs
TRACFCOMP(g_trac_errl, INFO_MRK
- "sendErrLogToBmc: no sensor SELs, size %d",
- l_pelSize );
+ "sendErrLogToBmc: no sensor SELs, size %d", l_pelSize );
l_selEventList.clear();
IPMISEL::sel_info_t *l_selEvent = new (IPMISEL::sel_info_t);
uint8_t l_eventDirType = IPMISEL::sensor_specific;
@@ -718,28 +783,27 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels)
TRACFCOMP(g_trac_errl, EXIT_MRK "sendErrLogToBmc");
} // sendErrLogToBmc
-void getSensorInfo(HWAS::callout_ud_t *i_ud, uint8_t
- &o_sensorNumber, uint8_t &o_eventOffset,
+uint8_t getSensorInfo(HWAS::callout_ud_t *i_ud,
+ uint8_t* o_sensorNumber, uint8_t* o_eventOffset,
errlHndl_t &io_err )
{
+ uint8_t l_num_sensors = 1;
// reset the offset, we will test and configure it later
- o_eventOffset = IPMISEL::event_data1_invalid_offset;
+ *o_eventOffset = IPMISEL::event_data1_invalid_offset;
if( i_ud->type == HWAS::PROCEDURE_CALLOUT )
{
// for procedure callouts
- o_sensorNumber = TARGETING::UTIL::getSensorNumber(NULL,
+ *o_sensorNumber = TARGETING::UTIL::getSensorNumber(NULL,
TARGETING::SENSOR_NAME_SYSTEM_EVENT);
// For procedure callout, will have EPUB ID's.This data will be part of
// OEM SEL.
- o_eventOffset = i_ud->procedure;
-
- TRACFCOMP(g_trac_errl, ENTER_MRK
+ *o_eventOffset = i_ud->procedure;
+ TRACFCOMP(g_trac_errl,
"getSensorInfo o_eventOffset %d o_sensorNumber %d",
- o_eventOffset,o_sensorNumber);
-
+ o_eventOffset,*o_sensorNumber);
}
// if its a clock callout or a its a part callout and its not
// the VPD part or the SBE EEPROM, then use the backplane fault
@@ -750,40 +814,46 @@ void getSensorInfo(HWAS::callout_ud_t *i_ud, uint8_t
(i_ud->partType == HWAS::SBE_SEEPROM_PART_TYPE))
))
{
- o_sensorNumber = SENSOR::getBackPlaneFaultSensor();
+ *o_sensorNumber = SENSOR::getBackPlaneFaultSensor();
}
else
{
// for all other types there will be at least
// one target in the next user data section, we will use
- // that target to find the fault sensor. For a
- // bus callout, we will just use the first of the
- // bus target endpoints provided.
+ // that target to find the fault sensor.
//
// NOTE: if the provided target does not have a fault sensor, the
// physical path will be used to determine the parent FRU which has
// a fault sensor associated with it.
uint8_t * l_uData = (uint8_t *)(i_ud + 1);
TARGETING::Target *l_target = NULL;
- bool l_err = HWAS::retrieveTarget(l_uData,
- l_target, io_err);
-
+ bool l_err = HWAS::retrieveTarget(l_uData, l_target, io_err);
if (!l_err)
{
// got a target, now get the sensor number
- o_sensorNumber = SENSOR::getFaultSensorNumber(l_target);
+ *o_sensorNumber = SENSOR::getFaultSensorNumber(l_target);
}
else
{
// couldnt expand the target so we are unable to get
// a sensor number - use the event sensor for this one
- o_sensorNumber = TARGETING::UTIL::getSensorNumber(NULL,
+ *o_sensorNumber = TARGETING::UTIL::getSensorNumber(NULL,
TARGETING::SENSOR_NAME_SYSTEM_EVENT);
- o_eventOffset = SENSOR::UNDETERMINED_SYSTEM_HW_FAILURE;
-
+ *o_eventOffset = SENSOR::UNDETERMINED_SYSTEM_HW_FAILURE;
+ }
+ if (i_ud->type == HWAS::BUS_CALLOUT)
+ {
+ l_err = HWAS::retrieveTarget(l_uData, l_target, io_err);
+ if (!l_err)
+ {
+ o_sensorNumber[l_num_sensors] =
+ SENSOR::getFaultSensorNumber(l_target);
+ l_num_sensors++;
+ }
}
}
+ return l_num_sensors;
}
void getSensorOffsetBasedOnSeverity(errlHndl_t & io_err,
OpenPOWER on IntegriCloud