summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/ipmi/ipmisel.H86
-rw-r--r--src/usr/errl/errlmanager_common.C76
-rw-r--r--src/usr/ipmi/ipmisel.C156
3 files changed, 224 insertions, 94 deletions
diff --git a/src/include/usr/ipmi/ipmisel.H b/src/include/usr/ipmi/ipmisel.H
index 86adb07bd..7e16d3e3a 100644
--- a/src/include/usr/ipmi/ipmisel.H
+++ b/src/include/usr/ipmi/ipmisel.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2015 */
+/* Contributors Listed Below - COPYRIGHT 2014,2016 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -50,6 +50,14 @@ namespace IPMISEL
MSG_LAST_TYPE = MSG_STATE_SHUTDOWN,
};
+ typedef struct sel_info
+ {
+ uint8_t eventDirType;
+ uint8_t sensorNumber;
+ uint8_t eventOffset;
+ uint8_t sensorType;
+ }sel_info_t;
+
enum sel_size_constants
{
// size of the partial_add_esel request (command) data
@@ -66,20 +74,16 @@ namespace IPMISEL
* @param[in] pointer to eSEL data
* @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
+ * @param[in] callout list,which has sel event details
*/
void sendESEL(uint8_t* i_eselData, uint32_t i_dataSize,
- uint32_t i_eid,
- uint8_t i_eventDirType, uint8_t i_eventOffset,
- uint8_t i_sensorType, uint8_t i_sensorNumber);
+ uint32_t i_eid,std::vector<sel_info_t*>&i_calloutList);
// per IPMI Spec, section 32.1 SEL Event Records
enum sel_record_type
{
record_type_system_event = 0x02,
+ record_type_oem_sel_for_procedure_callout = 0xDE,
record_type_ami_esel = 0xDF,
};
@@ -127,6 +131,52 @@ namespace IPMISEL
generator_id_ami = 0x2000,
};
+ struct oemSelRecord
+ {
+ // ID used for SEL Record access. The Record ID values 0000h and FFFFh
+ // have special meaning in the Event Access commands and must not be
+ // used as Record ID values for stored SEL Event Records.
+ uint16_t recordID;
+
+ // [7:0] - Record Type
+ // C0h-DFh = OEM system event record
+ uint8_t record_type;
+
+ // Time when event was logged. LS byte first.
+ uint32_t timestamp;
+
+ // Manufacturer ID
+ uint8_t manufactureId_data1;
+ uint8_t manufactureId_data2;
+ uint8_t manufactureId_data3;
+
+ // OEM defined
+ uint8_t event_data1;
+ uint8_t event_data2;
+ uint8_t event_data3;
+ uint8_t event_data4;
+ uint8_t event_data5;
+ uint8_t event_data6;
+
+
+ // ctor
+ oemSelRecord():
+ recordID(0),
+ record_type(0),
+ timestamp(0),
+ manufactureId_data1(0),
+ manufactureId_data2(0),
+ manufactureId_data3(0),
+ event_data1(0),
+ event_data2(0),
+ event_data3(0),
+ event_data4(0),
+ event_data5(0),
+ event_data6(0)
+ { };
+
+ } PACKED; //oemSelRecord
+
struct selRecord
{
// ID used for SEL Record access. The Record ID values 0000h and FFFFh
@@ -205,22 +255,38 @@ namespace IPMISEL
struct eselInitData
{
size_t dataSize;
+ std::vector <sel_info_t*> selInfoList;
uint8_t eSel[sizeof(selRecord)];
+ uint8_t oemSel[sizeof(oemSelRecord)];
uint8_t *eSelExtra;
+ bool selEvent;
+ uint8_t eselRecord[2];
// ctor
- eselInitData(selRecord* i_eSEL,
+ eselInitData(std::vector <sel_info_t*> &i_eventList,
uint8_t* i_extraData, uint32_t i_dataSize)
{
dataSize = i_dataSize;
- memcpy(eSel,i_eSEL,sizeof(selRecord));
+ selInfoList = i_eventList;
eSelExtra = new uint8_t[i_dataSize];
memcpy(eSelExtra, i_extraData, i_dataSize);
+ selEvent = false;
+ memset (eselRecord,0,sizeof(eselRecord));
}
// dtor
~eselInitData()
{
+ std::vector<sel_info_t*>::iterator it;
+ for (it = selInfoList.begin(); it != selInfoList.end();
+ ++it)
+ {
+ sel_info_t* l_sel = *it;
+ if (l_sel)
+ {
+ delete l_sel;
+ }
+ }
delete eSelExtra;
}
};
diff --git a/src/usr/errl/errlmanager_common.C b/src/usr/errl/errlmanager_common.C
index 7006fb2bd..d2cc269a8 100644
--- a/src/usr/errl/errlmanager_common.C
+++ b/src/usr/errl/errlmanager_common.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015 */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -497,8 +497,6 @@ inline bool SensorModifier::modifySensor(uint8_t i_sensorType,
///////////////////////////////////////////////////////////////////////////////
void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels)
{
- bool l_selSent = false;
-
TRACFCOMP(g_trac_errl, ENTER_MRK
"sendErrLogToBmc errlogId 0x%.8x, i_sendSels %d",
io_err->eid(), i_sendSels);
@@ -594,8 +592,10 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels)
break;
}
+ std::vector<IPMISEL::sel_info_t*> l_selEventList;
if (i_sendSels)
{
+ l_selEventList.clear();
for(size_t i = 0; i < l_callouts.size(); i++)
{
uint8_t l_eventDirType = IPMISEL::sensor_specific;
@@ -628,7 +628,6 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels)
// 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,
@@ -637,8 +636,8 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels)
if( e )
{
TRACFCOMP(g_trac_errl,
- ERR_MRK"Failed to get sensor type for sensor %d",
- l_sensorNumber);
+ 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
@@ -658,15 +657,6 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels)
l_eventOffset );
}
- uint32_t selSize = l_pelSize;
-
- // if we sent an eSEL then set the PEL size to zero such
- // that we don't send another eSEL for the same error log
- if (l_selSent)
- {
- selSize = 0;
- }
-
// only send highest priority SELs or
// SELs of lesser priority that were modified
if (l_ud->priority == l_priority || l_wasModified)
@@ -674,18 +664,29 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels)
TRACFCOMP(g_trac_errl, INFO_MRK "sendErrLogToBmc:"
" sensor %.2x/%.2x event %x/%x, size %d",
l_sensorType, l_sensorNumber,
- l_eventDirType, l_eventOffset, selSize );
+ l_eventDirType, l_eventOffset, l_pelSize);
- IPMISEL::sendESEL(l_pelData, selSize,
- io_err->eid(),
- l_eventDirType, l_eventOffset,
- l_sensorType,
- l_sensorNumber);
+ 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;
- l_selSent = true;
+ l_selEventList.push_back(l_selEvent);
}
} // for l_callouts
+
+ if (l_selEventList.size())
+ {
+ IPMISEL::sendESEL(l_pelData, l_pelSize,
+ io_err->eid(),
+ l_selEventList);
+ TRACFCOMP(g_trac_errl, INFO_MRK
+ "sendErrLogToBmc callout size %d",
+ l_selEventList.size());
+ }
+
}
else
{
@@ -693,13 +694,20 @@ void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err, bool i_sendSels)
TRACFCOMP(g_trac_errl, INFO_MRK
"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;
uint8_t l_eventOffset = IPMISEL::event_data1_invalid_offset;
+
+ l_selEvent->eventDirType = l_eventDirType;
+ l_selEvent->sensorNumber = TARGETING::UTIL::INVALID_IPMI_SENSOR;
+ l_selEvent->eventOffset = l_eventOffset;
+ l_selEvent->sensorType = SENSOR::INVALID_TYPE;
+
+ l_selEventList.push_back(l_selEvent);
+
IPMISEL::sendESEL(l_pelData, l_pelSize,
- io_err->eid(),
- l_eventDirType, l_eventOffset,
- SENSOR::INVALID_TYPE, TARGETING::UTIL::INVALID_IPMI_SENSOR);
+ io_err->eid(), l_selEventList);
}
// free the buffer
@@ -720,15 +728,17 @@ void getSensorInfo(HWAS::callout_ud_t *i_ud, uint8_t
if( i_ud->type == HWAS::PROCEDURE_CALLOUT )
{
- // for procedure callouts generate sel using the system event
- // sensor
+ // for procedure callouts
o_sensorNumber = TARGETING::UTIL::getSensorNumber(NULL,
- TARGETING::SENSOR_NAME_SYSTEM_EVENT);
+ 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;
- // use the generic offset to indicate there is more work
- // required to figure out what went wrong, ie. follow
- // the procedure in the elog
- o_eventOffset = SENSOR::UNDETERMINED_SYSTEM_HW_FAILURE;
+ TRACFCOMP(g_trac_errl, ENTER_MRK
+ "getSensorInfo o_eventOffset %d o_sensorNumber %d",
+ o_eventOffset,o_sensorNumber);
}
// if its a clock callout or a its a part callout and its not
diff --git a/src/usr/ipmi/ipmisel.C b/src/usr/ipmi/ipmisel.C
index 31f3ac021..02eb00fe3 100644
--- a/src/usr/ipmi/ipmisel.C
+++ b/src/usr/ipmi/ipmisel.C
@@ -37,8 +37,12 @@
#include <sys/task.h>
#include <initservice/taskargs.H>
#include <initservice/initserviceif.H>
+#include <targeting/common/commontargeting.H>
+#include <targeting/common/util.H>
+#include <targeting/common/utilFilter.H>
#include <errl/errlmanager.H>
+using namespace TARGETING;
//Defined in ipmidd.C
extern trace_desc_t * g_trac_ipmi;
@@ -83,11 +87,9 @@ enum esel_retry
namespace IPMISEL
{
void sendESEL(uint8_t* i_eselData, uint32_t i_dataSize,
- uint32_t i_eid,
- uint8_t i_eventDirType, uint8_t i_eventOffset,
- uint8_t i_sensorType, uint8_t i_sensorNumber )
+ uint32_t i_eid, std::vector<sel_info_t*>&i_selEventList)
{
- IPMI_TRAC(ENTER_MRK "sendESEL()");
+ IPMI_TRAC(ENTER_MRK "sendESEL() %d",i_selEventList.size());
#ifdef __HOSTBOOT_RUNTIME
// HBRT doesn't send a msg, but use the msg structure to pass the data
@@ -99,19 +101,8 @@ void sendESEL(uint8_t* i_eselData, uint32_t i_dataSize,
#endif
msg->type = MSG_SEND_ESEL;
msg->data[0] = i_eid;
-
- // create the sel record of information
- selRecord l_sel;
- 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 = i_eventOffset;
-
- eselInitData *eselData =
- new eselInitData(&l_sel, i_eselData, i_dataSize);
+ eselInitData *eselData =
+ new eselInitData(i_selEventList, i_eselData, i_dataSize);
msg->extra_data = eselData;
@@ -131,7 +122,7 @@ void sendESEL(uint8_t* i_eselData, uint32_t i_dataSize,
#endif
IPMI_TRAC(EXIT_MRK "sendESEL");
return;
-} // sendESEL
+}
/*
* @brief process esel msg
@@ -144,36 +135,81 @@ void process_esel(msg_t *i_msg)
eselInitData * l_data =
(eselInitData*)(i_msg->extra_data);
IPMI_TRAC(ENTER_MRK "process_esel");
+ selRecord l_eSel;
+ oemSelRecord l_oemSel;
- uint32_t l_send_count = MAX_SEND_COUNT;
- while (l_send_count > 0)
+ do
{
- // try to send the eles to the bmc
- send_esel(l_data, l_err, l_cc);
-
- // if no error but last completion code was:
- if ((l_err == NULL) &&
- ((l_cc == IPMI::CC_BADRESV) || // lost reservation
- (l_cc == IPMI::CC_TIMEOUT))) // timeout
+ IPMI_TRAC(ENTER_MRK"sel list size %d", l_data->selInfoList.size());
+ std::vector<sel_info_t*>::iterator it;
+ for (it = l_data->selInfoList.begin(); it != l_data->selInfoList.end();
+ ++it)
{
- // update our count and pause
- l_send_count--;
- if (l_send_count)
+ sel_info_t *l_sel = *it;
+ memset(l_data->oemSel,0,sizeof(oemSelRecord));
+ memset(l_data->eSel,0,sizeof(selRecord));
+ l_data->selEvent = true;
+
+ //If sensor type is sys event then need to send the oem sel
+ //to handle procedure callout
+ if (l_sel->sensorType == TARGETING::SENSOR_TYPE_SYS_EVENT)
{
- IPMI_TRAC("process_esel: sleeping; retry_count %d",
- l_send_count);
- // sleep 3 times - 2ms, 32ms, 512ms. if we can't get this
- // through by then, the system must really be busy...
- nanosleep(0,
- SLEEP_BASE << (4 * (MAX_SEND_COUNT - l_send_count - 1)));
- continue;
+ //oem sel data
+ l_data->selEvent = false;
+ l_oemSel.record_type =
+ record_type_oem_sel_for_procedure_callout;
+ l_oemSel.event_data1 = l_sel->eventOffset;
+ l_sel->eventOffset = SENSOR::UNDETERMINED_SYSTEM_HW_FAILURE;
+ memcpy(l_data->oemSel,&l_oemSel,sizeof(oemSelRecord));
}
- }
- // else it did get sent down OR it didn't because of a bad error
- break;
+ //sel data
+ l_eSel.record_type = record_type_system_event;
+ l_eSel.generator_id = generator_id_ami;
+ l_eSel.evm_format_version = format_ipmi_version_2_0;
+ l_eSel.sensor_type = l_sel->sensorType;
+ l_eSel.sensor_number = l_sel->sensorNumber;
+ l_eSel.event_dir_type = l_sel->eventDirType;
+ l_eSel.event_data1 = l_sel->eventOffset;
+ memcpy(l_data->eSel,&l_eSel,sizeof(selRecord));
+
+
+ uint32_t l_send_count = MAX_SEND_COUNT;
+ while (l_send_count > 0)
+ {
+ // try to send the eles to the bmc
+ send_esel(l_data, l_err, l_cc);
+
+ // if no error but last completion code was:
+ if ((l_err == NULL) &&
+ ((l_cc == IPMI::CC_BADRESV) || // lost reservation
+ (l_cc == IPMI::CC_TIMEOUT))) // timeout
+ {
+ // update our count and pause
+ l_send_count--;
+ if (l_send_count)
+ {
+ IPMI_TRAC("process_esel: sleeping; retry_count %d",
+ l_send_count);
+ // sleep 3 times - 2ms, 32ms, 512ms. if we can't get this
+ // through by then, the system must really be busy...
+ nanosleep(0,
+ SLEEP_BASE << (4 * (MAX_SEND_COUNT - l_send_count - 1)));
+ continue;
+ }
+ }
+ else
+ {
+ //if we enter this, then pel data has logged successfully,
+ //so we don't need to log again, make the size to zero.
+ l_data->dataSize = 0;
+ }
+ // else it did get sent down OR it didn't because of a bad error
+ break;
+ } // while
+ } // for
- } // while
+ }while(0);
if(l_err)
{
@@ -212,10 +248,12 @@ void send_esel(eselInitData * i_data,
uint8_t* data = NULL;
size_t len = 0;
- uint8_t esel_recordID[2] = {0,0};
+
uint8_t sel_recordID[2] = {0,0};
+ uint8_t esel_recordID[2] = {0,0};
- do{
+ do
+ {
const size_t l_eSELlen = i_data->dataSize;
if (l_eSELlen == 0)
@@ -348,6 +386,10 @@ void send_esel(eselInitData * i_data,
// there's a major BMC bug...)
storeReserveRecord(esel_recordID,data);
} // while eSELindex
+ if (o_cc == IPMI::CC_OK)
+ {
+ memcpy(i_data->eselRecord,esel_recordID,sizeof(esel_recordID));
+ }
}while(0);
// if eSEL wasn't created due to an error, we don't want to continue
@@ -356,7 +398,7 @@ void send_esel(eselInitData * i_data,
// caller wants us to NOT create sensor SEL
if ((i_data->eSel[offsetof(selRecord,sensor_type)] == SENSOR::INVALID_TYPE) &&
(i_data->eSel[offsetof(selRecord,sensor_number)] == TARGETING::UTIL::INVALID_IPMI_SENSOR)
- )
+ )
{
IPMI_TRAC(INFO_MRK "Invalid sensor type/number - NOT sending sensor SELs");
}
@@ -372,13 +414,25 @@ void send_esel(eselInitData * i_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
- // and mark the event_data1 to indicate this is OEM data
- data[offsetof(selRecord,event_data1)] |= 0xA0;
- data[offsetof(selRecord,event_data2)] = esel_recordID[1];
- data[offsetof(selRecord,event_data3)] = esel_recordID[0];
+
+ // send standard SEL event
+ if (i_data->selEvent)
+ {
+ // copy in the SEL event record data
+ memcpy(data, i_data->eSel, len);
+ // copy the eSEL recordID (if it was created) into the extra data area
+ // and mark the event_data1 to indicate this is OEM data
+ data[offsetof(selRecord,event_data1)] |= 0xA0;
+ data[offsetof(selRecord,event_data2)] = i_data->eselRecord[1];
+ data[offsetof(selRecord,event_data3)] = i_data->eselRecord[0];
+ }
+ else //send OEM SEL event
+ {
+ // copy in the SEL event record data
+ memcpy(data, i_data->oemSel, len);
+ data[offsetof(oemSelRecord,event_data5)] = i_data->eselRecord[1];
+ data[offsetof(oemSelRecord,event_data6)] =i_data->eselRecord[0];
+ }
// use local cc so that we don't corrupt the esel from above
IPMI::completion_code l_cc = IPMI::CC_UNKBAD;
OpenPOWER on IntegriCloud