diff options
| author | Brian Horton <brianh@linux.ibm.com> | 2014-10-16 11:40:21 -0500 | 
|---|---|---|
| committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2015-01-22 16:59:09 -0600 | 
| commit | 1bc13e89d35eacba76589ac3c5158d54ce73b35b (patch) | |
| tree | 749478e2e2fb8c250c682d49dae2c9a524d4f8cb | |
| parent | abf9c4a78fcac4e2951e504523ea04cecda59b63 (diff) | |
| download | talos-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.H | 142 | ||||
| -rw-r--r-- | src/include/usr/errl/errlmanager.H | 111 | ||||
| -rw-r--r-- | src/include/usr/errl/errlprvt.H | 5 | ||||
| -rw-r--r-- | src/usr/errl/errlmanager.C | 237 | ||||
| -rw-r--r-- | src/usr/ipmi/ipmirp.C | 3 | 
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); | 

