summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Horton <brianh@linux.ibm.com>2014-10-16 11:40:21 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2015-01-22 16:59:09 -0600
commit1bc13e89d35eacba76589ac3c5158d54ce73b35b (patch)
tree749478e2e2fb8c250c682d49dae2c9a524d4f8cb
parentabf9c4a78fcac4e2951e504523ea04cecda59b63 (diff)
downloadtalos-hostboot-1bc13e89d35eacba76589ac3c5158d54ce73b35b.tar.gz
talos-hostboot-1bc13e89d35eacba76589ac3c5158d54ce73b35b.zip
add SEL/eSEL support
in errlmanager, convert errlog to SEL/eSEL format, prepare to send to BMC via IPMI Change-Id: I11e246264840ff756e92b97673e4742b9d03daad RTC: 114908 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/14238 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r--src/include/usr/errl/errlipmi.H142
-rw-r--r--src/include/usr/errl/errlmanager.H111
-rw-r--r--src/include/usr/errl/errlprvt.H5
-rw-r--r--src/usr/errl/errlmanager.C237
-rw-r--r--src/usr/ipmi/ipmirp.C3
5 files changed, 391 insertions, 107 deletions
diff --git a/src/include/usr/errl/errlipmi.H b/src/include/usr/errl/errlipmi.H
new file mode 100644
index 000000000..836b0d1a1
--- /dev/null
+++ b/src/include/usr/errl/errlipmi.H
@@ -0,0 +1,142 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/errl/errlipmi.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2014,2015 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef ERRLIPMI_H
+#define ERRLIPMI_H
+/**
+ * @file errlipmi.H
+ *
+ * @brief Error Log for IPMI SEL/eSEL formats
+ *
+ * This header file contains the definition of error structures for ipmi
+ *
+ */
+
+/*****************************************************************************/
+// I n c l u d e s
+/*****************************************************************************/
+#include <stdint.h>
+
+namespace ERRORLOG
+{
+
+// per MegaRAC SP-X spec
+// The size of the eSEL is configurable via PRJ
+// it can be set to 2KB per eSEL packet.
+static const uint32_t ESEL_MAX_SIZE = 2 * KILOBYTE;
+
+// per MegaRAC SP-X spec
+static const uint8_t SEL_RECORD_TYPE = 0xDE;
+static const uint8_t ESEL_RECORD_TYPE = 0xDF;
+
+// per MegaRAC SP-X spec
+static const uint8_t ESEL_EVENT_DATA_1 = 0xAA;
+
+
+// per MegaRAC SP-X spec
+static const uint16_t SEL_GENERATOR_ID = 0x2000;
+
+// per MegaRAC SP-X spec
+static const uint8_t SEL_FORMAT_VERSION = 0x04;
+
+
+// per IPMI Spec, section 32.1 SEL Event Records
+struct selRecord
+{
+
+ // 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
+ // 02h = system event record
+ // C0h-DFh = OEM timestamped, bytes 8-16 OEM defined
+ // E0h-FFh = OEM non-timestamped, bytes 4-16 OEM defined
+ uint8_t record_type;
+
+ // Time when event was logged. LS byte first.
+ uint32_t timestamp;
+
+ // RqSA & LUN if event was generated from IPMB. Software ID if event was
+ // generated from system software.
+ // Byte 1
+ // [7:1] - 7-bit I2C. Slave Address, or 7-bit system software ID
+ // [0] 0b = ID is IPMB Slave Address
+ // 1b = system software ID
+ // Byte 2
+ // [7:4] - Channel number. Channel that event message was received over.
+ // 0h if the event message was received via the system interface,
+ // primary IPMB, or internally generated by the BMC.
+ // [3:2] - reserved. Write as 00b.
+ // [1:0] - IPMB device LUN if byte 1 holds Slave Address. 00b otherwise.
+ uint16_t generator_id;
+
+ // Event Message format version
+ // (=04h for events in this specification,
+ // 03h for IPMI v1.0 Event Messages.)
+ uint8_t evm_format_version;
+
+ // Sensor Type Code for sensor that generated the event
+ uint8_t sensor_type;
+
+ // Number of sensor that generated the event
+ uint8_t sensor_number;
+
+ // Event Dir
+ // [7 ] 0b = Assertion event.
+ // 1b = Deassertion event.
+ // Event Type
+ // Type of trigger for the event, e.g. critical threshold going high,
+ // state asserted, etc. Also indicates class of the event. E.g.
+ // discrete, threshold, or OEM. The Event Type field is encoded
+ // using the Event/Reading Type Code.
+ // [6:0] - Event Type Code
+
+ uint8_t event_dir_type;
+
+ uint8_t event_data1;
+ uint8_t event_data2;
+ uint8_t event_data3;
+
+ // ctor
+ selRecord():
+ recordID(0),
+ record_type(0),
+ timestamp(0),
+ generator_id(SEL_GENERATOR_ID),
+ evm_format_version(SEL_FORMAT_VERSION),
+ sensor_type(0),
+ sensor_number(0),
+ event_dir_type(0),
+ event_data1(0),
+ event_data2(0),
+ event_data3(0)
+ { };
+
+} PACKED;
+
+} // End namespace
+
+#endif //ERRLIPMI_H
diff --git a/src/include/usr/errl/errlmanager.H b/src/include/usr/errl/errlmanager.H
index 38291e546..07d4b79af 100644
--- a/src/include/usr/errl/errlmanager.H
+++ b/src/include/usr/errl/errlmanager.H
@@ -39,6 +39,7 @@
#include <util/singleton.H>
#include <errl/errlentry.H>
#include <errldisplay/errldisplay.H>
+#include <errl/errlipmi.H>
#include <sys/sync.h>
#include <kernel/timemgr.H>
#include <hbotcompid.H>
@@ -80,6 +81,7 @@ enum errlManagerNeeds
PNOR,
TARG,
MBOX,
+ IPMI,
ERRLDISP,
} ;
@@ -146,7 +148,7 @@ public:
* @brief Sends msg to errlmanager telling what resources are ready
*
* This is called by resources that the ErrlManager needs, which start up
- * AFTER ErrlManager starts. Currently, that's PNOR MBOX and TARGeting.
+ * AFTER ErrlManager starts.
*
* It is a static function because a module cannot call an interface on a
* singleton in another module
@@ -221,6 +223,7 @@ private:
ERRLOG_ACCESS_MBOX_TYPE = 0x00000035 | MBOX::FIRST_SECURE_MSG,
ERRLOG_ACCESS_TARG_TYPE = 0x00000036 | MBOX::FIRST_SECURE_MSG,
ERRLOG_ACCESS_ERRLDISP_TYPE = 0x00000037 | MBOX::FIRST_SECURE_MSG,
+ ERRLOG_ACCESS_IPMI_TYPE = 0x00000038 | MBOX::FIRST_SECURE_MSG,
};
/**
@@ -300,7 +303,7 @@ private:
* @param[in,out] io_err Error log handle to be committed
*
*/
- void sendErrLogToMbox ( errlHndl_t& io_err );
+ void sendErrLogToFSP ( errlHndl_t& io_err );
/**
* @brief Create a mailbox message with the error log and send it to Fsp.
@@ -435,16 +438,27 @@ private:
*/
void setACKInFlattened(uint32_t i_position);
+#ifdef CONFIG_BMC_IPMI
+ /**
+ * @brief Create an ipmi message with the error log and send it to BMC
+ *
+ * @param[in,out] io_err Error log handle to be committed
+ *
+ */
+ void sendErrLogToBmc(errlHndl_t &io_err);
+#endif
+
/**
* @brief errorlog-into-PNOR variables
*/
char *iv_pnorAddr; // HBEL section in PNOR
uint32_t iv_maxErrlInPnor; // max number of errorlogs that will fit
uint32_t iv_pnorOpenSlot; // current open slot available for an errorlog
- bool iv_isSpBaseServices; // do we need to send to FSP
- bool iv_isMboxEnabled; // are we able to send to FSP
- bool iv_nonInfoCommitted; //< Keeps track of any non-informational logs.
- bool iv_isErrlDisplayEnabled; // are we able to use the errorDisplay
+ bool iv_isSpBaseServices; // do we need to send to FSP
+ bool iv_isMboxEnabled; // are we able to send to FSP
+ bool iv_isIpmiEnabled; // are we able to send to BMC via IPMI
+ bool iv_nonInfoCommitted; // Keeps track of any non-informational logs.
+ bool iv_isErrlDisplayEnabled; // are we able to use the errorDisplay
// Errl flags which represent processing needed by the errl
// represented as a bit field (8 bits)
@@ -454,89 +468,49 @@ private:
PNOR_FLAG = 0x01,
MBOX_FLAG = 0x02,
ERRLDISP_FLAG = 0x04,
+ IPMI_FLAG = 0x08,
+ ALL_FLAGS = PNOR_FLAG | MBOX_FLAG
+ #ifdef CONFIG_BMC_IPMI
+ | IPMI_FLAG
+ #endif
#ifdef CONFIG_CONSOLE_OUTPUT_ERRORDISPLAY
- ALL_FLAGS = PNOR_FLAG | MBOX_FLAG | ERRLDISP_FLAG,
- #else
- ALL_FLAGS = PNOR_FLAG | MBOX_FLAG,
+ | ERRLDISP_FLAG
#endif
};
// List of messages errl manager needs to handle
// The unint8_t is a bit field to indiciate what needs to be done
- std::list<std::pair<errlHndl_t, uint8_t> > iv_errlList;
-
- typedef std::list<std::pair<errlHndl_t, uint8_t> >::iterator ErrlListItr_t;
-
- /**
- * @brief checks if the pnor flag is set
- *
- * @param[in] i_pair - pair of errl and bitfield of flags
- * @return True if PNOR flag is set
- *
- */
- static bool _isPnorFlagSet(const std::pair<errlHndl_t, uint8_t> &i_pair)
- {
- return (i_pair.second & PNOR_FLAG);
- }
-
- /**
- * @brief checks if the mbox flag is set
- *
- * @param[in] i_pair - pair of errl and bitfield of flagst
- * @return True if mbox flag is set
- *
- */
- static bool _isMboxFlagSet(const std::pair<errlHndl_t, uint8_t> &i_pair)
- {
- return (i_pair.second & MBOX_FLAG);
- }
+ typedef std::pair<errlHndl_t, uint8_t> ErrlFlagPair_t;
+ typedef std::list<ErrlFlagPair_t> ErrlList_t;
+ typedef ErrlList_t::iterator ErrlListItr_t;
+ ErrlList_t iv_errlList;
/**
- * @brief checks if the errldisp flag is set
+ * @brief checks if the flag is set
*
* @param[in] i_pair - pair of errl and bitfield of flags
- * @return True if errldisp flag is set
- *
- */
- static bool _isErrlDispFlagSet(const std::pair<errlHndl_t, uint8_t> &i_pair)
- {
- return (i_pair.second & ERRLDISP_FLAG);
- }
-
- /**
- * @brief clears the pnor flag, indicating complete
- *
- * @param[in/out] io_pair - pair of errl and bitfield of flags
- * @return NA
- *
- */
- static void _clearPnorFlag(std::pair<errlHndl_t, uint8_t> &io_pair)
- {
- io_pair.second &= ~PNOR_FLAG;
- }
-
- /**
- * @brief clears the mbox flag, indicating complete
- *
- * @param[in/out] io_pair - pair of errl and bitfield of flags
- * @return NA
+ * @param[in] i_flag - specific flag
+ * @return True if specified flag is set
*
*/
- static void _clearMboxFlag(std::pair<errlHndl_t, uint8_t> &io_pair)
+ static bool _isFlagSet(const ErrlFlagPair_t &i_pair,
+ const ERRLOG_FLAGS i_flag)
{
- io_pair.second &= ~MBOX_FLAG;
+ return (i_pair.second & i_flag);
}
/**
- * @brief clears the errldisp flag, indicating complete
+ * @brief clears the flag, indicating complete
*
* @param[in/out] io_pair - pair of errl and bitfield of flags
+ * @param[in] i_flag - specific flag
* @return NA
*
*/
- static void _clearErrlDispFlag(std::pair<errlHndl_t, uint8_t> &io_pair)
+ static void _clearFlag(ErrlFlagPair_t &io_pair,
+ const ERRLOG_FLAGS i_flag)
{
- io_pair.second &= ~ERRLDISP_FLAG;
+ io_pair.second &= ~i_flag;
}
/**
@@ -549,8 +523,7 @@ private:
* @return True if an erase occurred, otherwise false
*
*/
- bool _updateErrlListIter(std::list< std::pair<errlHndl_t, uint8_t> >
- ::iterator & io_it);
+ bool _updateErrlListIter(ErrlListItr_t & io_it);
};
diff --git a/src/include/usr/errl/errlprvt.H b/src/include/usr/errl/errlprvt.H
index 5a779187c..b3cc68d91 100644
--- a/src/include/usr/errl/errlprvt.H
+++ b/src/include/usr/errl/errlprvt.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2014 */
+/* Contributors Listed Below - COPYRIGHT 2011,2015 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -44,6 +46,7 @@ class ErrlPrvt
// you would expect to be part of ErrlEntry are actually instance data
// in this class.
friend class ErrlEntry;
+ friend class ErrlManager;
private:
diff --git a/src/usr/errl/errlmanager.C b/src/usr/errl/errlmanager.C
index 24209326c..5f9294381 100644
--- a/src/usr/errl/errlmanager.C
+++ b/src/usr/errl/errlmanager.C
@@ -51,6 +51,7 @@
#include <console/consoleif.H>
#include <config.h>
#include <functional>
+#include <util/lockfree/counter.H>
namespace ERRORLOG
{
@@ -120,7 +121,8 @@ ErrlManager::ErrlManager() :
iv_maxErrlInPnor(0),
iv_pnorOpenSlot(0),
iv_isSpBaseServices(true), // queue msgs for fsp until we find we shouldn't
- iv_isMboxEnabled(false), // but mbox isn't ready yet..
+ iv_isMboxEnabled(false), // assume mbox isn't ready yet..
+ iv_isIpmiEnabled(false), // assume ipmi isn't ready yet..
iv_nonInfoCommitted(false),
iv_isErrlDisplayEnabled(false)
{
@@ -271,13 +273,14 @@ void ErrlManager::errlogMsgHndlr ()
{
iv_isSpBaseServices = false;
- // if there are queued msgs, delete the errors that
- // have been fully processed
+ // if there are queued errors, clear the Mbox flag
+ // since they will never be sent, which will delete
+ // the errors that have been fully processed
ErrlListItr_t it = iv_errlList.begin();
while(it != iv_errlList.end())
{
// Mark MBOX processing complete
- _clearMboxFlag(*it);
+ _clearFlag(*it, MBOX_FLAG);
_updateErrlListIter(it);
}
}
@@ -324,17 +327,18 @@ void ErrlManager::errlogMsgHndlr ()
assert(0);
}
- // if error(s) came in before MBOX was ready,
- // the msg(s) would be on this list. send it now.
+ // if errors came in before MBOX was ready,
+ // the errors would be on this list. send them now.
ErrlListItr_t it = iv_errlList.begin();
while(it != iv_errlList.end())
{
// Check if MBOX processing is needed
- if (_isMboxFlagSet(*it))
+ if (_isFlagSet(*it, MBOX_FLAG))
{
+ // send errlog
+ sendErrLogToFSP(it->first);
// Mark MBOX processing complete
- sendErrLogToMbox(it->first);
- _clearMboxFlag(*it);
+ _clearFlag(*it, MBOX_FLAG);
}
_updateErrlListIter(it);
}
@@ -346,7 +350,7 @@ void ErrlManager::errlogMsgHndlr ()
while(it != iv_errlList.end())
{
// Mark MBOX processing complete
- _clearMboxFlag(*it);
+ _clearFlag(*it, MBOX_FLAG);
_updateErrlListIter(it);
}
}
@@ -357,6 +361,36 @@ void ErrlManager::errlogMsgHndlr ()
// go back and wait for a next msg
break;
}
+ case ERRLOG_ACCESS_IPMI_TYPE:
+ {
+#ifdef CONFIG_BMC_IPMI
+ // IPMI is up and running now.
+ iv_isIpmiEnabled = true;
+
+ // if we can now send msgs, do it.
+ // if errors came in before IPMI was ready,
+ // the errors would be on this list. send them now.
+ ErrlListItr_t it = iv_errlList.begin();
+ while(it != iv_errlList.end())
+ {
+ // Check if IPMI processing is needed
+ if (_isFlagSet(*it, IPMI_FLAG))
+ {
+ // send errorlog
+ sendErrLogToBmc(it->first);
+ // Mark IPMI processing complete
+ _clearFlag(*it, IPMI_FLAG);
+ }
+ _updateErrlListIter(it);
+ }
+#endif
+
+ //We are done with the msg
+ msg_free(theMsg);
+
+ // go back and wait for a next msg
+ break;
+ }
case ERRLOG_ACCESS_ERRLDISP_TYPE:
{
#ifdef CONFIG_CONSOLE_OUTPUT_ERRORDISPLAY
@@ -371,13 +405,13 @@ void ErrlManager::errlogMsgHndlr ()
while(it != iv_errlList.end())
{
// Check if ERRLDISP processing is needed
- if (_isErrlDispFlagSet(*it))
+ if (_isFlagSet(*it, ERRLDISP_FLAG))
{
ERRORLOGDISPLAY::errLogDisplay().msgDisplay
(it->first,
((it->first->reasonCode()) & 0xFF00));
// Mark ERRLDISP processing complete
- _clearErrlDispFlag(*it);
+ _clearFlag(*it, ERRLDISP_FLAG);
}
_updateErrlListIter(it);
}
@@ -390,25 +424,24 @@ void ErrlManager::errlogMsgHndlr ()
case ERRLOG_NEEDS_TO_BE_COMMITTED_TYPE:
{
// Extract error log handle from the message. We need the
- // error log handle to pass along to saveErrLogEntry and
- // sendErrLogToMbox
+ // error log handle to pass along
errlHndl_t l_err = (errlHndl_t) theMsg->extra_data;
- //Ask the ErrlEntry to assign commit component, commit time
+ // Ask the ErrlEntry to assign commit component, commit time
l_err->commit( (compId_t) theMsg->data[0] );
// Pair with all flags set to add to the errlList
- std::pair<errlHndl_t, uint8_t> l_pair(l_err, ALL_FLAGS);
+ ErrlFlagPair_t l_pair(l_err, ALL_FLAGS);
- // Display errl to errldisplay
#ifdef CONFIG_CONSOLE_OUTPUT_ERRORDISPLAY
+ // Display errl to errldisplay
if (iv_isErrlDisplayEnabled)
{
ERRORLOGDISPLAY::errLogDisplay().msgDisplay
(l_err,
( (l_err->reasonCode()) & 0xFF00));
// Mark ERRLDISP processing complete on this error
- _clearErrlDispFlag(l_pair);
+ _clearFlag(l_pair, ERRLDISP_FLAG);
}
#endif
//Save the error log to PNOR
@@ -418,7 +451,7 @@ void ErrlManager::errlogMsgHndlr ()
if (l_savedToPnor)
{
// Mark PNOR processing complete on this error
- _clearPnorFlag(l_pair);
+ _clearFlag(l_pair, PNOR_FLAG);
}
#ifdef STORE_ERRL_IN_L3
@@ -427,19 +460,31 @@ void ErrlManager::errlogMsgHndlr ()
saveErrLogEntry ( l_err );
#endif
- // Try to send the error log if someone is there to receive
+ //Try to send the error log if someone is there to receive
if (!iv_isSpBaseServices)
{
// Mark MBOX processing complete on this error
- _clearMboxFlag(l_pair);
+ _clearFlag(l_pair, MBOX_FLAG);
}
else if (iv_isSpBaseServices && iv_isMboxEnabled)
{
- sendErrLogToMbox(l_err);
+ sendErrLogToFSP(l_err);
+
// Mark MBOX processing complete on this error
- _clearMboxFlag(l_pair);
+ _clearFlag(l_pair, MBOX_FLAG);
}
+#ifdef CONFIG_BMC_IPMI
+ if (iv_isIpmiEnabled)
+ {
+ // convert to SEL/eSEL and send to BMC over IPMI
+ sendErrLogToBmc(l_err);
+
+ // Mark IPMI processing complete on this error
+ _clearFlag(l_pair, IPMI_FLAG);
+ }
+#endif
+
//Ask the ErrlEntry to process any callouts
l_err->processCallout();
@@ -495,7 +540,7 @@ void ErrlManager::errlogMsgHndlr ()
{
// We found the errlog
// Mark PNOR processing complete
- _clearPnorFlag(*it);
+ _clearFlag(*it, PNOR_FLAG);
_updateErrlListIter(it);
}
}
@@ -505,8 +550,9 @@ void ErrlManager::errlogMsgHndlr ()
// We didn't have room before in PNOR to save an
// error log, so try now since we just ACKed one.
ErrlListItr_t it = std::find_if(iv_errlList.begin(),
- iv_errlList.end(),
- _isPnorFlagSet);
+ iv_errlList.end(),
+ bind2nd(ptr_fun(_isFlagSet),
+ PNOR_FLAG));
// Check if such errl was found
if (it != iv_errlList.end())
@@ -517,7 +563,7 @@ void ErrlManager::errlogMsgHndlr ()
if (l_savedToPnor)
{
// Mark PNOR processing complete
- _clearPnorFlag(*it);
+ _clearFlag(*it, PNOR_FLAG);
_updateErrlListIter(it);
}
// else, still couldn't save it (for some reason) so
@@ -556,13 +602,13 @@ void ErrlManager::errlogMsgHndlr ()
///////////////////////////////////////////////////////////////////////////////
-// ErrlManager::sendErrLogToMbox()
+// ErrlManager::sendErrLogToFSP()
///////////////////////////////////////////////////////////////////////////////
-void ErrlManager::sendErrLogToMbox ( errlHndl_t& io_err )
+void ErrlManager::sendErrLogToFSP ( errlHndl_t& io_err )
{
msg_t *msg = NULL;
- TRACFCOMP( g_trac_errl, ENTER_MRK"ErrlManager::sendErrLogToMbox" );
+ TRACFCOMP( g_trac_errl, ENTER_MRK"ErrlManager::sendErrLogToFSP" );
do
{
//Create a mailbox message to send to FSP
@@ -605,8 +651,8 @@ void ErrlManager::sendErrLogToMbox ( errlHndl_t& io_err )
}
} while (0);
- TRACFCOMP( g_trac_errl, EXIT_MRK"ErrlManager::sendErrLogToMbox" );
-} // sendErrLogToMbox
+ TRACFCOMP( g_trac_errl, EXIT_MRK"ErrlManager::sendErrLogToFSP" );
+} // sendErrLogToFSP
///////////////////////////////////////////////////////////////////////////////
// Handling commit error log.
@@ -750,6 +796,9 @@ void ErrlManager::sendResourcesMsg(errlManagerNeeds i_needs)
case MBOX:
msg->type = ERRORLOG::ErrlManager::ERRLOG_ACCESS_MBOX_TYPE;
break;
+ case IPMI:
+ msg->type = ERRORLOG::ErrlManager::ERRLOG_ACCESS_IPMI_TYPE;
+ break;
case ERRLDISP:
msg->type = ERRORLOG::ErrlManager::ERRLOG_ACCESS_ERRLDISP_TYPE;
break;
@@ -822,7 +871,7 @@ void ErrlManager::sendErrlogToMessageQueue ( errlHndl_t& io_err,
} while (0);
TRACFCOMP( g_trac_errl, EXIT_MRK"ErrlManager::sendErrlogToMessageQueue" );
return;
-}
+} // sendErrlogToMessageQueue
///////////////////////////////////////////////////////////////////////////////
// ErrlManager::errlogShutdown()
@@ -834,11 +883,11 @@ void ErrlManager::errlogShutdown()
while (!iv_errlList.empty())
{
// Get errl and its flags
- std::pair<errlHndl_t, uint8_t> l_pair = iv_errlList.front();
+ ErrlFlagPair_t l_pair = iv_errlList.front();
// If still true that means it was not processed
TRACFCOMP(g_trac_errl, INFO_MRK "Failed to fully process Errl(eid %.8x) - Errl Flags Bitfield = 0x%X",
- l_pair.second);
+ l_pair.first->eid(), l_pair.second);
delete l_pair.first;
l_pair.first = NULL;
@@ -991,7 +1040,7 @@ void ErrlManager::setupPnorInfo()
while(it != iv_errlList.end())
{
// Check if PNOR processing is needed
- if (_isPnorFlagSet(*it))
+ if (_isFlagSet(*it, PNOR_FLAG))
{
//ACK it if no one is there to receive
bool l_savedToPnor = saveErrLogToPnor(it->first);
@@ -1000,7 +1049,7 @@ void ErrlManager::setupPnorInfo()
if (l_savedToPnor)
{
// Mark PNOR processing complete
- _clearPnorFlag(*it);
+ _clearFlag(*it, PNOR_FLAG);
_updateErrlListIter(it);
}
else
@@ -1234,4 +1283,118 @@ bool ErrlManager::_updateErrlListIter(ErrlListItr_t & io_it)
return l_removed;
}
+#ifdef CONFIG_BMC_IPMI
+void ErrlManager::sendErrLogToBmc(errlHndl_t &io_err)
+{
+ TRACFCOMP(g_trac_errl, ENTER_MRK
+ "sendErrLogToBmc errlogId 0x%.8x", io_err->eid());
+
+ do {
+
+ // if it's an INFORMATIONAL log, we don't want to waste the cycles
+ if (io_err->sev() == ERRORLOG::ERRL_SEV_INFORMATIONAL)
+ {
+ TRACFCOMP( g_trac_errl, INFO_MRK
+ "sendErrLogToBmc: INFORMATIONAL log, skipping");
+ break;
+ }
+
+ // TODO: RTC 117526
+ // look through the error log and determine what callouts there are,
+ // and what the corresponding sensors are. if there aren't any, then
+ // break;
+
+ // flatten into bufffer, truncate to 2K
+ uint32_t l_plidSize = io_err->flattenedSize();
+ if (l_plidSize > (ESEL_MAX_SIZE - sizeof(selRecord)))
+ {
+ TRACFCOMP( g_trac_errl, INFO_MRK
+ "sendErrLogToBmc: msg size %d > 2K, truncating.",
+ l_plidSize);
+ l_plidSize = ESEL_MAX_SIZE - sizeof(selRecord);
+ }
+
+ uint8_t *l_plidData = new uint8_t[l_plidSize];
+ uint32_t l_errSize = io_err->flatten (l_plidData,
+ l_plidSize, true /* truncate */);
+
+ if (l_errSize ==0)
+ {
+ // flatten didn't work
+ TRACFCOMP( g_trac_errl, ERR_MRK
+ "sendErrLogToBmc: could not flatten data - not sending");
+ delete [] l_plidData;
+ break;
+ }
+
+ static uint16_t cv_recordID = 0;
+
+ // 0x0000 and 0xffff are reserved; handle wrap
+ uint16_t l_nextRecordID = cv_recordID++;
+ if (l_nextRecordID == 0xffff)
+ {
+ // force a wrap
+ TRACFCOMP( g_trac_errl, ERR_MRK
+ "sendErrLogToBmc: wrapping on recordID!");
+ cv_recordID = 1;
+ l_nextRecordID = cv_recordID;
+ }
+ selRecord *l_sel = new selRecord();
+ l_sel->recordID = l_nextRecordID;
+ uint16_t eSelRecordID = cv_recordID++;
+
+ l_sel->record_type = SEL_RECORD_TYPE; // per AMI spec - SEL
+ l_sel->timestamp = io_err->iv_Private.iv_committed;
+ l_sel->generator_id = SEL_GENERATOR_ID;
+ l_sel->evm_format_version = SEL_FORMAT_VERSION;
+ // TODO: RTC 117526 - sensor data
+ l_sel->sensor_type = 1;
+ l_sel->sensor_number = 1;
+ l_sel->event_dir_type = 1;
+ l_sel->event_data1 = ESEL_EVENT_DATA_1; // per AMI spec
+ l_sel->event_data2 = ((eSelRecordID & 0xFF00) >> 8);
+ l_sel->event_data3 = (eSelRecordID & 0x00FF);
+
+
+ // first part is a selRecord
+ selRecord *l_esel = new selRecord();
+ l_esel->recordID = eSelRecordID;
+ l_esel->record_type = ESEL_RECORD_TYPE; // per AMI spec - eSEL
+ l_esel->timestamp = io_err->iv_Private.iv_committed;
+ l_esel->generator_id = SEL_GENERATOR_ID;
+ l_esel->evm_format_version = SEL_FORMAT_VERSION;
+ l_esel->sensor_type = 1; // per AMI spec
+ l_esel->sensor_number = 1; // per AMI spec
+ l_esel->event_dir_type = 1; // per AMI spec
+ l_esel->event_data1 = ESEL_EVENT_DATA_1; // per AMI spec
+ l_esel->event_data2 = 0; // per AMI spec
+ l_esel->event_data3 = 0; // per AMI spec
+
+ // send it to the BMC over IPMI
+ TRACFCOMP(g_trac_errl, INFO_MRK "sendErrLogToBmc: sent SEL %d, eSEL %d",
+ l_sel->recordID, l_esel->recordID);
+
+ // TODO: RTC 117454 call IPMI send_sel i/f when it's ready
+#if 0
+ errlHndl_t l_err = sendSel(&l_sel, &l_esel, &l_plidData, l_plidSize);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_errl, ERR_MRK "sendSel(%d,%d,%d) returned error",
+ l_sel->recordID, l_esel->recordID, l_plidSize);
+ errlCommit(l_err, IPMI_COMP_ID);
+ }
+#else
+ // free the buffers
+ delete l_sel;
+ delete l_esel;
+ delete [] l_plidData;
+#endif
+
+
+ } while(0);
+
+ TRACFCOMP(g_trac_errl, EXIT_MRK "sendErrLogToBmc");
+} // sendErrLogToBmc
+#endif
+
} // End namespace
diff --git a/src/usr/ipmi/ipmirp.C b/src/usr/ipmi/ipmirp.C
index fba8262d1..9112fdabd 100644
--- a/src/usr/ipmi/ipmirp.C
+++ b/src/usr/ipmi/ipmirp.C
@@ -462,6 +462,9 @@ void IpmiRP::execute(void)
// Wait for an event message read it and handle it if no one else does
task_create( &IpmiRP::last_chance_event_handler, NULL);
+ // call ErrlManager function - tell him that IPMI is ready!
+ ERRORLOG::ErrlManager::errlResourceReady(ERRORLOG::IPMI);
+
while (true)
{
msg_t* msg = msg_wait(iv_msgQ);
OpenPOWER on IntegriCloud