summaryrefslogtreecommitdiffstats
path: root/src/usr/errl/errlmanager.C
diff options
context:
space:
mode:
authorBrian Horton <brianh@linux.ibm.com>2015-06-02 10:13:20 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2015-09-03 14:33:02 -0500
commit06e40c4aa3efe6f006dc7971ad58f08f42117ea3 (patch)
treee7bcc5a38340a630c17126bc3782064e2c0b9274 /src/usr/errl/errlmanager.C
parent4ae690e4eeb9297ed59ff932cc4184d23896234d (diff)
downloadtalos-hostboot-06e40c4aa3efe6f006dc7971ad58f08f42117ea3.tar.gz
talos-hostboot-06e40c4aa3efe6f006dc7971ad58f08f42117ea3.zip
add support to write errlog to PNOR during runtime
Change-Id: Ia2b211d8ebf489e92f2bc3d281d92175a6b61f30 Depends-On: I170d6586062b6e4684a55782df83a1b19ed7d937 Depends-On: Id8c44b0dcdb5714c163ac6485a53216786f9fbcf Depends-On: I626bce5c8c0c8b7d0a44408280de178c7a86a83f RTC: 123419 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/18233 Tested-by: Jenkins Server Tested-by: Jenkins OP Build CI Reviewed-by: STEPHEN M. CPREK <smcprek@us.ibm.com> Tested-by: Jenkins OP HW Reviewed-by: WILLIAM G. HOFFA <wghoffa@us.ibm.com> Tested-by: FSP CI Jenkins Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/errl/errlmanager.C')
-rw-r--r--src/usr/errl/errlmanager.C436
1 files changed, 1 insertions, 435 deletions
diff --git a/src/usr/errl/errlmanager.C b/src/usr/errl/errlmanager.C
index 3ae08dde2..dea951ce4 100644
--- a/src/usr/errl/errlmanager.C
+++ b/src/usr/errl/errlmanager.C
@@ -92,10 +92,6 @@ char* g_ErrlStorage;
#endif
-const uint32_t PNOR_ERROR_LENGTH = 4096;
-const uint32_t EMPTY_ERRLOG_IN_PNOR = 0xFFFFFFFF;
-const uint32_t FIRST_BYTE_ERRLOG = 0xF0000000;
-
// Comparator function to check if a eid and a plid are equal
bool compareEidToPlid(const uint32_t i_plid,
const std::pair<errlHndl_t, uint8_t> i_pair)
@@ -754,13 +750,6 @@ void ErrlManager::saveErrLogEntry( errlHndl_t& io_err )
///////////////////////////////////////////////////////////////////////////////
-// Atomically increment log id and return it.
-uint32_t ErrlManager::getUniqueErrId()
-{
- return (__sync_add_and_fetch(&iv_currLogId, 1));
-}
-
-///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void ErrlManager::setHwasProcessCalloutFn(HWAS::processCalloutFn i_fn)
{
@@ -771,21 +760,6 @@ void ErrlManager::setHwasProcessCalloutFn(HWAS::processCalloutFn i_fn)
}
///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-// Global function (not a method on an object) to commit the error log.
-void errlCommit(errlHndl_t& io_err, compId_t i_committerComp )
-{
- ERRORLOG::theErrlManager::instance().commitErrLog(io_err, i_committerComp );
- return;
-}
-
-// Global function (not a method on an object) to get the hidden logs flag.
-uint8_t getHiddenLogsEnable( )
-{
- return ERRORLOG::theErrlManager::instance().iv_hiddenErrLogsEnable;
-}
-
-///////////////////////////////////////////////////////////////////////////////
// Global function (not a method on an object) to commit the error log.
void ErrlManager::errlResourceReady(errlManagerNeeds i_needs)
{
@@ -946,15 +920,7 @@ void ErrlManager::errlogShutdown()
// Ensure that all the error logs are pushed out to PNOR
// prior to the PNOR resource provider shutting down.
- int l_rc = mm_remove_pages(FLUSH, (void *) iv_pnorAddr,
- iv_maxErrlInPnor * PNOR_ERROR_LENGTH);
- if( l_rc )
- {
- //If mm_remove_pages returns none zero for error then
- //log an error trace in this case.
- TRACFCOMP(g_trac_errl, ERR_MRK "Fail to flush the page %p size %d",
- iv_pnorAddr, iv_maxErrlInPnor * PNOR_ERROR_LENGTH);
- }
+ PNOR::flush(PNOR::HB_ERRLOGS);
// Un-register error log message queue from the shutdown
INITSERVICE::unregisterShutdownEvent( iv_msgQ);
@@ -976,355 +942,6 @@ void ErrlManager::errlogShutdown()
return;
}
-// ------------------------------------------------------------------
-// setupPnorInfo
-// ------------------------------------------------------------------
-void ErrlManager::setupPnorInfo()
-{
- TRACFCOMP( g_trac_errl, ENTER_MRK"setupPnorInfo" );
-
- do
- {
- // Get SPD PNOR section info from PNOR RP
- PNOR::SectionInfo_t info;
- errlHndl_t err = PNOR::getSectionInfo( PNOR::HB_ERRLOGS, info );
-
- if (err)
- {
- TRACFCOMP( g_trac_errl, INFO_MRK"setupPnorInfo getSectionInfo failed");
- assert(err == NULL);
- break;
- }
-
- TRACFCOMP( g_trac_errl, INFO_MRK"setupPnorInfo sectionInfo id %d name \"%s\" size %d",
- info.id, info.name, info.size );
-
- // Set the globals appropriately
- iv_pnorAddr = reinterpret_cast<char *> (info.vaddr);
- iv_maxErrlInPnor = info.size / PNOR_ERROR_LENGTH;
-
- TRACFCOMP( g_trac_errl, INFO_MRK"setupPnorInfo iv_pnorAddr %p maxErrlInPnor %d",
- iv_pnorAddr, iv_maxErrlInPnor );
-
- // initial value, in case PNOR is empty - start at this end slot
- // so that our first save will increment and wrap correctly
- iv_pnorOpenSlot = (iv_maxErrlInPnor - 1);
-
- // walk thru memory, finding error logs and determine the highest ID
- uint32_t l_maxId = 0;
- for (uint32_t i = 0; i < iv_maxErrlInPnor; i++)
- {
- if (!isSlotEmpty(i))
- {
- uint32_t l_id = readEidFromFlattened(i);
- // If id is not from HB (0x9XXXXXXX) grab plid instead
- if ( (l_id & FIRST_BYTE_ERRLOG) != ERRLOG_PLID_BASE )
- {
- l_id = readPlidFromFlattened(i);
- }
- if (l_id > l_maxId )
- {
- l_maxId = l_id;
-
- // set this - start at this 'max' slot so that our first
- // save will increment correctly
- iv_pnorOpenSlot = i;
- }
- // also check if it's ACKed or not
- if (!isSlotACKed(i))
- {
- TRACFCOMP( g_trac_errl,
- INFO_MRK"setupPnorInfo slot %d eid %.8X was not ACKed.",
- i, l_id);
-
-#ifdef CONFIG_BMC_IPMI
- // for IPMI systems, unflatten to send down to the BMC
- err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE, 0,0);
- char *l_errlAddr = iv_pnorAddr + (PNOR_ERROR_LENGTH * i);
- uint64_t rc = err->unflatten(l_errlAddr, PNOR_ERROR_LENGTH);
- if (rc != 0)
- {
- // unflatten didn't work, nothing we can do
- TRACFCOMP( g_trac_errl,
- ERR_MRK"setupPnorInfo unflatten failed on slot %d eid %.8X.",
- i, l_id);
- }
- else
- {
- // Decide if we need to skip the error log
- setErrlSkipFlag(err);
- if(err->getSkipShowingLog())
- {
- // skip it, go to the next one
- continue;
- }
- if (iv_isIpmiEnabled)
- {
- // convert to SEL/eSEL and send to BMC over IPMI
- sendErrLogToBmc(err);
- delete err;
- }
- else
- {
- TRACFCOMP( g_trac_errl,
- INFO_MRK"setupPnorInfo pushing slot %d eid %.8X to iv_errList.",
- i, l_id);
- // Pair with IPMI flag to add to the errlList
- // so that it'll get sent down when IPMI is up
-#ifdef CONFIG_CONSOLE_OUTPUT_ERRORDISPLAY
- ErrlFlagPair_t l_pair(err, IPMI_FLAG | ERRLDISP_FLAG);
-#else
- ErrlFlagPair_t l_pair(err, IPMI_FLAG);
-#endif
- iv_errlList.push_back(l_pair);
- }
- }
-#else
- // for FSP system, this shouldn't ever happen.
- setACKInFlattened(i);
-#endif
- } // not ACKed
- } // not empty
- } // for
-
- // bump the current eid to 1 past the max eid found
- while (!__sync_bool_compare_and_swap(&iv_currLogId, iv_currLogId,
- (iv_currLogId & ERRLOG_PLID_BASE_MASK) +
- (l_maxId & ERRLOG_PLID_MASK) + 1));
- TRACFCOMP( g_trac_errl, INFO_MRK"setupPnorInfo reseting LogId 0x%X", iv_currLogId);
-
- // if error(s) came in before PNOR was ready,
- // the error log(s) would be on this list. save now.
- ErrlListItr_t it = iv_errlList.begin();
- while(it != iv_errlList.end())
- {
- // Check if PNOR processing is needed
- if (_isFlagSet(*it, PNOR_FLAG))
- {
- //ACK it if no one is there to receive
- bool l_savedToPnor = saveErrLogToPnor(it->first);
-
- // check if we actually saved the msg to PNOR
- if (l_savedToPnor)
- {
- // Mark PNOR processing complete
- _clearFlag(*it, PNOR_FLAG);
- _updateErrlListIter(it);
- }
- else
- {
- // still couldn't save it (PNOR maybe full) so
- // it's still on the list.
- break; // get out of this while loop.
- }
- }
- else
- {
- ++it;
- }
- }
- } while (0);
-
- TRACFCOMP( g_trac_errl, EXIT_MRK"setupPnorInfo");
-} // setupPnorInfo
-
-///////////////////////////////////////////////////////////////////////////////
-// ErrlManager::incrementPnorOpenSlot()
-///////////////////////////////////////////////////////////////////////////////
-bool ErrlManager::incrementPnorOpenSlot()
-{
- uint32_t initialSlot = iv_pnorOpenSlot; // starting slot
- do
- {
- iv_pnorOpenSlot++;
- if (iv_pnorOpenSlot == iv_maxErrlInPnor)
- { // wrap
- iv_pnorOpenSlot = 0;
- }
- } while ( !isSlotEmpty(iv_pnorOpenSlot) &&
- !isSlotACKed(iv_pnorOpenSlot) &&
- (iv_pnorOpenSlot != initialSlot));
-
- // if we got a different slot, return true; else false - no open slots
- return (iv_pnorOpenSlot != initialSlot);
-} // incrementPnorOpenSlot
-
-///////////////////////////////////////////////////////////////////////////////
-// ErrlManager::saveErrLogToPnor()
-///////////////////////////////////////////////////////////////////////////////
-bool ErrlManager::saveErrLogToPnor( errlHndl_t& io_err)
-{
- bool rc = false;
- TRACFCOMP( g_trac_errl, ENTER_MRK"saveErrLogToPnor eid=%.8x", io_err->eid());
-
- do
- {
- // Decide whether or not to skip error log
- if( io_err->getSkipShowingLog() )
- {
- TRACFCOMP( g_trac_errl, INFO_MRK"saveErrLogToPnor: INFORMATIONAL/RECOVERED log, skipping");
- break;
- }
-
- // save our current slot, and see if there's an open slot
- uint32_t l_previousSlot = iv_pnorOpenSlot; // in case flatten fails
-
- if ((iv_pnorAddr != NULL) && incrementPnorOpenSlot())
- {
- // flatten into PNOR, truncate to the slot size
- char *l_pnorAddr =
- iv_pnorAddr + (PNOR_ERROR_LENGTH * iv_pnorOpenSlot);
- TRACDBIN( g_trac_errl, INFO_MRK"saveErrLogToPnor: l_pnorAddr before",
- l_pnorAddr, 128);
- uint64_t l_errSize = io_err->flatten(l_pnorAddr,
- PNOR_ERROR_LENGTH, true);
- if (l_errSize !=0)
- {
- TRACFCOMP( g_trac_errl, INFO_MRK"saveErrLogToPnor: %d bytes flattened into %p, slot %d",
- l_errSize, l_pnorAddr, iv_pnorOpenSlot );
-
- TRACDBIN( g_trac_errl, INFO_MRK"saveErrLogToPnor: l_pnorAddr after",
- l_pnorAddr, 128);
-
- // Ensure that this error log is pushed out to PNOR
- int l_rc = mm_remove_pages(FLUSH,
- (void *) l_pnorAddr, l_errSize);
- if( l_rc )
- {
- //If mm_remove_pages returns none zero for error then
- //log an error trace in this case.
- TRACFCOMP(g_trac_errl, ERR_MRK "Fail to flush the page %p size %d",
- l_pnorAddr, PNOR_ERROR_LENGTH);
- }
- }
- else
- {
- // flatten didn't work, so still return true - we don't want
- // to try to save this errlog.
-
- TRACFCOMP( g_trac_errl, ERR_MRK"saveErrLogToPnor: could not flatten data");
- // restore slot so that our next save will find this slot
- iv_pnorOpenSlot = l_previousSlot;
- }
- rc = true;
- }
- // else no open slot - return false
- } while( 0 );
-
- TRACFCOMP( g_trac_errl, EXIT_MRK"saveErrLogToPnor returning %s",
- rc ? "true" : "false");
- return rc;
-} // saveErrLogToPnor
-
-///////////////////////////////////////////////////////////////////////////////
-// ErrlManager::ackErrLogInPnor()
-///////////////////////////////////////////////////////////////////////////////
-bool ErrlManager::ackErrLogInPnor( uint32_t i_errEid )
-{
- TRACFCOMP( g_trac_errl, ENTER_MRK"ackErrLogInPnor(%.8x)", i_errEid);
- bool rc = true;
-
- // look for an un-ACKed log that matches this eid
- uint32_t i;
- for (i = 0; i < iv_maxErrlInPnor; i++)
- {
- if (!isSlotEmpty(i) && !isSlotACKed(i))
- {
- uint32_t l_eid = readEidFromFlattened(i);
- if (l_eid == i_errEid)
- {
- TRACDCOMP( g_trac_errl, INFO_MRK"ackErrLogInPnor: match in slot %d", i);
- setACKInFlattened(i);
- break;
- }
- }
- } // for
-
- // if we made it through the loop w/out breaking early
- if (i == iv_maxErrlInPnor)
- {
- //could not find the errorlog to mark for acknowledgment
- TRACDCOMP( g_trac_errl, ERR_MRK"ackErrLogInPnor failed to find the error log" );
- rc = false;
- }
-
- TRACFCOMP( g_trac_errl, EXIT_MRK"ackErrLogInPnor returning %s",
- rc ? "true" : "false");
- return rc;
-} // ackErrLogInPnor
-
-
-bool ErrlManager::isSlotEmpty(uint32_t i_position)
-{
- // checks the first word of the flattened errlog, which should be a
- // pelsectionheader - which will NEVER be 0xFFFFFFFF if it's valid.
- char * l_pnorAddr = iv_pnorAddr + (PNOR_ERROR_LENGTH * i_position);
- bool rc = (memcmp(l_pnorAddr, &EMPTY_ERRLOG_IN_PNOR, sizeof(uint32_t))
- == 0);
- TRACDCOMP( g_trac_errl, "isSlotEmpty: slot %d @ %p is %s",
- i_position, l_pnorAddr, rc ? "empty" : "not empty");
- return rc;
-}
-
-// readEidFromFlattened()
-// i_position MUST be valid errlog (not EMPTY_ERRLOG_IN_PNOR)
-uint32_t ErrlManager::readEidFromFlattened(uint32_t i_position)
-{
- const char * l_pnorAddr = iv_pnorAddr + (PNOR_ERROR_LENGTH * i_position);
- const pelPrivateHeaderSection_t *pPH =
- reinterpret_cast<const pelPrivateHeaderSection_t *>(l_pnorAddr);
- TRACDCOMP(g_trac_errl, "readEid(%d): eid %.8x", i_position, pPH->eid);
-
- return pPH->eid;
-}
-
-// readPlidFromFlattened()
-// i_position MUST be valid errlog (not EMPTY_ERRLOG_IN_PNOR)
-uint32_t ErrlManager::readPlidFromFlattened(uint32_t i_position)
-{
- const char * l_pnorAddr = iv_pnorAddr + (PNOR_ERROR_LENGTH * i_position);
- const pelPrivateHeaderSection_t *pPH =
- reinterpret_cast<const pelPrivateHeaderSection_t *>(l_pnorAddr);
- TRACDCOMP(g_trac_errl, "readEid(%d): plid %.8x", i_position, pPH->plid);
-
- return pPH->plid;
-}
-
-// isSlotACKed()
-// i_position MUST be valid errlog (not EMPTY_ERRLOG_IN_PNOR)
-bool ErrlManager::isSlotACKed(uint32_t i_position)
-{
- const char * l_pnorAddr = iv_pnorAddr + (PNOR_ERROR_LENGTH * i_position);
- l_pnorAddr += sizeof(pelPrivateHeaderSection_t);
- l_pnorAddr += sizeof(pelUserHeaderSection_t);
- const pelSRCSection_t *pSRC =
- reinterpret_cast<const pelSRCSection_t *>(l_pnorAddr);
-
- TRACDCOMP(g_trac_errl, "isSlotACKed(%d): word5 %08x - %s",
- i_position, pSRC->word5,
- (pSRC->word5 & ErrlSrc::ACK_BIT) ? "not ACKed" : "ACKed");
-
- return (pSRC->word5 & ErrlSrc::ACK_BIT) ? false : true;
-}
-
-// setACKInFlattened()
-void ErrlManager::setACKInFlattened(uint32_t i_position)
-{
- char * l_pnorErrlAddr = iv_pnorAddr + (PNOR_ERROR_LENGTH * i_position);
- char * l_pnorAddr = l_pnorErrlAddr + sizeof(pelPrivateHeaderSection_t);
- l_pnorAddr += sizeof(pelUserHeaderSection_t);
- pelSRCSection_t *pSRC = reinterpret_cast<pelSRCSection_t *>(l_pnorAddr);
-
- pSRC->word5 &= ~(ErrlSrc::ACK_BIT);
-
- TRACDCOMP(g_trac_errl, "setACKInFlattened(%d): word5 %08x - %s",
- i_position, pSRC->word5,
- (pSRC->word5 & ErrlSrc::ACK_BIT) ? "not ACKed" : "ACKed");
-
- return;
-}
-
bool ErrlManager::_updateErrlListIter(ErrlListItr_t & io_it)
{
bool l_removed = false;
@@ -1344,55 +961,4 @@ bool ErrlManager::_updateErrlListIter(ErrlListItr_t & io_it)
return l_removed;
}
-void ErrlManager::setErrlSkipFlag(errlHndl_t io_err)
-{
- // Note: iv_skipShowingLog is set to True by default
- //0 = Prevent INFORMATIONAL/RECOVERED error logs from being processed.
- //1 = Send only INFORMATIONAL error logs.
- //2 = Send only RECOVERED error logs.
- //3 = Allow all hidden error logs to be processed.
-
- //Check severity
- switch (io_err->sev())
- {
- case ERRORLOG::ERRL_SEV_INFORMATIONAL:
-
- // check if we are allowing info logs through.
- if((iv_hiddenErrLogsEnable ==
- TARGETING::
- HIDDEN_ERRLOGS_ENABLE_ALLOW_INFORMATIONAL)||
- (iv_hiddenErrLogsEnable ==
- TARGETING::
- HIDDEN_ERRLOGS_ENABLE_ALLOW_ALL_LOGS))
- {
- io_err->setSkipShowingLog(false);
- }
- break;
-
- case ERRORLOG::ERRL_SEV_RECOVERED:
-
- // check if we are allowing recovered logs through.
- if(((iv_hiddenErrLogsEnable ==
- TARGETING::
- HIDDEN_ERRLOGS_ENABLE_ALLOW_RECOVERED) ||
- (iv_hiddenErrLogsEnable ==
- TARGETING::
- HIDDEN_ERRLOGS_ENABLE_ALLOW_ALL_LOGS)) &&
- !iv_isSpBaseServices)
- {
- //Recovered error logs that are encountered
- //before targeting and initservice are loaded,
- //will still be queued for sending to PNOR/IPMI
- io_err->setSkipShowingLog(false);
- }
- break;
-
- default:
-
- // For any error log that is not INFORMATIONAL
- // or RECOVERED, we want to show the log
- io_err->setSkipShowingLog(false);
- }
-} // setErrlSkipFlag
-
} // End namespace
OpenPOWER on IntegriCloud