diff options
author | Chris Cain <cjcain@us.ibm.com> | 2015-02-24 16:13:42 -0600 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2015-02-28 05:53:20 -0600 |
commit | f3d348bde5bd0fbd9a707fd1635bcb3a90d9210d (patch) | |
tree | 52961091c8a645eb99e3adc1d88d59d6687dc162 /src/usr/htmgt/occError.C | |
parent | 29581aca6a1ed02d3374e5688e5f32fcb6f104bc (diff) | |
download | talos-hostboot-f3d348bde5bd0fbd9a707fd1635bcb3a90d9210d.tar.gz talos-hostboot-f3d348bde5bd0fbd9a707fd1635bcb3a90d9210d.zip |
Support for OCC error reporting
Change-Id: If8cce2f960b28cda2f039f68e9527df92f9233f2
RTC: 121729
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/15971
Tested-by: Jenkins Server
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/htmgt/occError.C')
-rw-r--r-- | src/usr/htmgt/occError.C | 357 |
1 files changed, 234 insertions, 123 deletions
diff --git a/src/usr/htmgt/occError.C b/src/usr/htmgt/occError.C index 8b2963b43..00e4cc0e1 100644 --- a/src/usr/htmgt/occError.C +++ b/src/usr/htmgt/occError.C @@ -1,11 +1,11 @@ /* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ -/* $Source: src/usr/htmgt/tmgtutility.C $ */ +/* $Source: src/usr/htmgt/occError.C $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014 */ +/* Contributors Listed Below - COPYRIGHT 2014,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -31,16 +31,64 @@ #include <ecmdDataBufferBase.H> #include <hwpf/hwp/occ/occAccess.H> +#include <console/consoleif.H> +#include <targeting/targplatutil.H> namespace HTMGT { + // Translate OCC priorty + bool elogXlateSrciPriority(const uint8_t i_priority, + HWAS::callOutPriority & o_priority) + { + bool l_found = false; + uint8_t l_index = 0x00; + + // Loop through the occPriorityXlate until we find a priority or + // reach the end of the struct. + // TODO RTC 124739 - convert to use lower_bound + while (l_index < OCC_SRCI_PRIORITY_XLATE_SIZE) + { + //If the priority matches then return the SRC. + if (i_priority == occPriorityXlateTbl[l_index].occPriority) + { + o_priority = occPriorityXlateTbl[l_index].errlPriority; + l_found = true; + break; + } + l_index++; + } + return l_found; + } + + + // Translate component id + bool elogGetTranslationData(const uint8_t i_compId, + tmgtCompxlateType &o_dataType, + uint32_t &o_compData) + { + bool l_found = false; + + // TODO RTC 124739 - convert to use lower_bound + for (uint16_t l_index = 0 ; l_index < TMGT_MAX_COMP_IDS ; l_index++) + { + if (i_compId == tmgt_compXlateTable[l_index].compId) + { + o_dataType = tmgt_compXlateTable[l_index].dataType; + o_compData = tmgt_compXlateTable[l_index].data; + l_found = true; + break; + } + } + return l_found; + } + + // Process elog entry from OCC poll response - void occProcessElog(Occ * i_occ, - const uint8_t i_id, - const uint32_t i_address, - const uint16_t i_length) + void Occ::occProcessElog(const uint8_t i_id, + const uint32_t i_address, + const uint16_t i_length) { errlHndl_t l_errlHndl = NULL; @@ -50,7 +98,7 @@ namespace HTMGT ecmdDataBufferBase l_buffer(l_length*8); // convert to bits // HBOCC is only defined for HTMGT #ifdef CONFIG_HTMGT - l_errlHndl = HBOCC::readSRAM(i_occ->getTarget(), i_address, l_buffer); + l_errlHndl = HBOCC::readSRAM(iv_target, i_address, l_buffer); #endif if (NULL == l_errlHndl) { @@ -62,17 +110,14 @@ namespace HTMGT TMGT_BIN("OCC ELOG", l_occElog, 256); const uint32_t l_occSrc = OCCC_COMP_ID | l_occElog->reasonCode; - ERRORLOG::errlSeverity_t l_errlSeverity = + ERRORLOG::errlSeverity_t severity = ERRORLOG::ERRL_SEV_INFORMATIONAL; -#if 0 - // TODO: RTC 109224 - determine correct severity/actions - // Process Severity + // Translate Severity const uint8_t l_occSeverity = l_occElog->severity; - const uint8_t l_occActions = l_occElog->actions; if (l_occSeverity < OCC_SEV_ACTION_XLATE_SIZE) { - l_errlSeverity = + severity = occSeverityErrorActionXlate[l_occSeverity].occErrlSeverity; } else @@ -81,15 +126,14 @@ namespace HTMGT " (severity = 0x%02X)", l_occElog->severity); } - // Process elog Actions + // Process Actions bool l_occReset = false; - elogProcessActions(l_occActions, l_occReset, l_errlSeverity); + elogProcessActions(l_occElog->actions, l_occReset, severity); if (l_occReset == true) { iv_needsReset = true; - UPDATE_SAFE_MODE_REASON(l_occSrc, iv_huid, true); + OccManager::updateSafeModeReason(l_occSrc, iv_instance); } -#endif // Create OCC error log // NOTE: word 4 (used by extended reason code) to save off OCC @@ -99,7 +143,7 @@ namespace HTMGT // parsed with the OCC src tags const occErrlUsrDtls_t *l_usrDtls_ptr = (occErrlUsrDtls_t *) ((uint8_t*)l_occElog+sizeof(occErrlEntry_t)+ - (l_occElog->numCallouts * sizeof(occErrlCallout_t)) ); + (l_occElog->maxCallouts * sizeof(occErrlCallout_t)) ); bldErrLog(l_errlHndl, (htmgtModuleId)(l_usrDtls_ptr->modId & 0x00FF), (htmgtReasonCode)l_occSrc, // occ reason code @@ -107,141 +151,109 @@ namespace HTMGT l_usrDtls_ptr->userData2, l_usrDtls_ptr->userData3, ((l_usrDtls_ptr->modId & 0xFF00) << 16 ) | - l_occElog->userData4, // extended reason code - l_errlSeverity); + l_occElog->reserved, // extended reason code + severity); -#if 0 - // TODO: RTC 109224 // Add callout information + const uint8_t l_max_callouts = l_occElog->maxCallouts; bool l_bad_fru_data = false; - uint8_t l_callout_num = 0; - if (! ((ERRL_SEV_INFORMATIONAL == l_errlSeverity) && - (TMGT_ERRL_ACTIONS_MANUFACTURING_ERROR & l_occActions)) ) + uint8_t numCallouts = 0; + uint8_t calloutIndex = 0; + while (calloutIndex < l_max_callouts) { - // Only add callouts if this is MFG error and system not in - // MFG (in MFG severity would not be Info) - uint8_t l_index = 0; - uint8_t l_count = 1; - - const uint8_t l_max_callout = l_occElog->numCallouts; - // The beginning address of callout data - l_index = sizeof(occErrlEntry_t); - do { - occErrlCallout_t *l_callout_ptr = NULL; - l_callout_ptr = (occErrlCallout_t *) - ((uint8_t*)l_occElog+l_index); - if (l_callout_ptr->type != 0) + const occErrlCallout_t callout = + l_occElog->callout[calloutIndex]; + if (callout.type != 0) + { + HWAS::callOutPriority priority; + bool l_success = true; + l_success = elogXlateSrciPriority(callout.priority, + priority); + if (l_success == true) { - srciPriority l_priority; - bool l_success = true; - l_success = - elogXlateSrciPriority(l_callout_ptr->priority, - l_priority); - if (l_success == true) - { - l_success = elogAddCallout(l_errlHndl, - l_errlSeverity, - l_priority, - *l_callout_ptr, - l_callout_num); - if (l_success == false) - { - l_bad_fru_data = true; - } - } - else + l_success = elogAddCallout(l_errlHndl, + priority, + callout, + numCallouts); + if (l_success == false) { l_bad_fru_data = true; - TMGT_ERR("occProcessElog: Priority translate" - " failure (priority = 0x%02X)", - l_callout_ptr->priority); } - l_index += sizeof(occErrlCallout_t); - } // if (l_type != 0) + } else - { // make sure all the remaining callout data are zeros, - // otherwise mark bad fru data - uint8_t *l_ptr = (uint8_t*)l_occElog+l_index; - uint8_t l_len = (l_max_callout-l_count+1)* - sizeof(occErrlCallout_t); - while (l_len != 0) + { + l_bad_fru_data = true; + TMGT_ERR("occProcessElog: Priority translate" + " failure (priority = 0x%02X)", + callout.priority); + } + } + else + { // make sure all the remaining callout data are zeros, + // otherwise mark bad fru data + const occErrlCallout_t zeros = { 0 }; + while (calloutIndex < l_max_callouts) + { + if (memcmp(&l_occElog->callout[calloutIndex], + &zeros, sizeof(occErrlCallout_t))) { - if (*l_ptr != 0x00) - { - TMGT_ERR("occProcessElog: The remaining" - " callout data should be all zeros"); - l_bad_fru_data = true; - break; - } - l_len--; - l_ptr++; + TMGT_ERR("occProcessElog: The remaining" + " callout data should be all zeros"); + l_bad_fru_data = true; + break; } - break; + ++calloutIndex; } - l_count++; - } while (l_count <= l_max_callout); - } - else - { - TMGT_ERR("MFG error found outside MFG; callouts will not be" - " added to log (OCC severity=0x%02X, actions=0x%02X)", - l_occSeverity, l_occActions); - const uint8_t l_callout_length = l_occElog->numCallouts * 12; - const char *l_callout_ptr = (char *)((uint8_t*)l_occElog+ - sizeof(occErrlEntry_t)); - // Add raw callout data from the OCC - l_errlHndl->addUsrDtls(l_callout_ptr, - l_callout_length, - TMGT_COMP_ID, - TMGT_VERSION, - TMGT_ERROR_DATA_TYPE); + break; + } + ++calloutIndex; } // Any bad fru data found ? - errlHndl_t l_errlHndl2 = NULL; + errlHndl_t err2 = NULL; if (l_bad_fru_data == true) { + TMGT_BIN("Callout Data", &l_occElog->callout[0], + sizeof(occErrlCallout)*ERRL_MAX_CALLOUTS); /*@ * @errortype * @refcode LIC_REFCODE * @subsys EPUB_FIRMWARE_SP * @reasoncode HTMGT_RC_OCC_ERROR_LOG * @moduleid HTMGT_MOD_BAD_FRU_CALLOUTS - * @userdata1 OCC elog id - * @userdata2 Number of good callouts + * @userdata1[0-15] OCC elog id + * @userdata1[16-31] Bad callout index * @devdesc Bad FRU data received in OCC error log */ - bldErrLog(l_errlHndl2, HTMGT_MOD_BAD_FRU_CALLOUTS, + bldErrLog(err2, HTMGT_MOD_BAD_FRU_CALLOUTS, HTMGT_RC_OCC_ERROR_LOG, - i_id, l_callout_num, 0, 0, ERRL_SEV_INFORMATIONAL); - ERRORLOG::errlCommit(l_errlHndl2, HTMGT_COMP_ID); + i_id, calloutIndex, 0, 0, + ERRORLOG::ERRL_SEV_INFORMATIONAL); + ERRORLOG::errlCommit(err2, HTMGT_COMP_ID); } - // Check callout number and severity - if ((l_callout_num == 0) && - (l_errlSeverity != ERRL_SEV_INFORMATIONAL)) + if ((numCallouts == 0) && + (severity != ERRORLOG::ERRL_SEV_INFORMATIONAL)) { TMGT_ERR("occProcessElog: No FRU callouts found for OCC%d" " elog_id:0x%02X, severity:0x%0X", - iv_instance, i_id, l_errlSeverity); + iv_instance, i_id, severity); /*@ * @errortype * @refcode LIC_REFCODE * @subsys EPUB_FIRMWARE_SP * @reasoncode HTMGT_RC_OCC_ERROR_LOG * @moduleid HTMGT_MOD_MISMATCHING_SEVERITY - * @userdata1 OCC elog id - * @userdata2 OCC severity - * @userdata3 - * @userdata4 + * @userdata1[0-15] OCC elog id + * @userdata1[16-31] OCC severity * @devdesc No FRU callouts found for non-info OCC Error Log */ - bldErrLog(l_errlHndl2, HTMGT_MOD_MISMATCHING_SEVERITY, + bldErrLog(err2, HTMGT_MOD_MISMATCHING_SEVERITY, HTMGT_RC_OCC_ERROR_LOG, - i_id, l_errlSeverity, 0, 0, ERRL_SEV_INFORMATIONAL); - ERRORLOG::errlCommit(l_errlHndl2, HTMGT_COMP_ID); + i_id, severity, 0, 0, + ERRORLOG::ERRL_SEV_INFORMATIONAL); + ERRORLOG::errlCommit(err2, HTMGT_COMP_ID); } -#endif // Add full OCC error log data as a User Details section l_errlHndl->addFFDC(OCCC_COMP_ID, @@ -249,27 +261,18 @@ namespace HTMGT i_length, 1, // version 0); // subsection - -#if 0 - // TODO: RTC 109224 - // Add additional data - addTmgtElogData(l_errlHndl); - addThermalElogData(l_errlHndl); -#endif - - // Commit Error (or terminate if required) ERRORLOG::errlCommit(l_errlHndl, HTMGT_COMP_ID); // Clear elog const uint8_t l_cmdData[1] = {i_id}; - OccCmd l_cmd(i_occ, OCC_CMD_CLEAR_ERROR_LOG, + OccCmd l_cmd(this, OCC_CMD_CLEAR_ERROR_LOG, sizeof(l_cmdData), l_cmdData); l_errlHndl = l_cmd.sendOccCmd(); if (l_errlHndl != NULL) { TMGT_ERR("occProcessElog: Failed to clear elog id %d to" " OCC%d (rc=0x%04X)", - i_id, i_occ, l_errlHndl->reasonCode()); + i_id, iv_instance, l_errlHndl->reasonCode()); ERRORLOG::errlCommit(l_errlHndl, HTMGT_COMP_ID); } } @@ -283,6 +286,114 @@ namespace HTMGT } // end Occ::occProcessElog() + // Add callout to specified elog + bool Occ::elogAddCallout(errlHndl_t & io_errlHndl, + HWAS::callOutPriority & i_priority, + const occErrlCallout_t i_callout, + uint8_t & io_callout_num) + { + bool l_success = true; + + TMGT_INF("elogAddCallout: Add callout type:0x%02X, value:0x%016llX," + " priority:0x%02X", + i_callout.type,i_callout.calloutValue, i_priority); + + if (i_callout.type == OCC_CALLOUT_TYPE_SENSOR) + { + const uint32_t sensor = (uint32_t)i_callout.calloutValue; + TARGETING::Target * target = + TARGETING::UTIL::getSensorTarget(sensor); + if (NULL != target) + { + io_errlHndl->addHwCallout(target, i_priority, + HWAS::NO_DECONFIG, + HWAS::GARD_NULL); + io_callout_num++; + } + else + { + TMGT_ERR("elogAddCallout: Unable to find target for " + "sensor 0x%04X", sensor); + } + } + else if (i_callout.type == OCC_CALLOUT_TYPE_COMPONENT_ID) + { + tmgtCompxlateType l_compDataType; + uint32_t l_compData = 0; + const uint8_t l_compId = (i_callout.calloutValue & 0xFF); + + if (elogGetTranslationData(l_compId, l_compDataType, l_compData)) + { + switch(l_compDataType) + { + case TMGT_COMP_DATA_SYMBOLIC_FRU: + TMGT_INF("elogAddCallout: symbolic callout: 0x%08X", + l_compData); + break; + case TMGT_COMP_DATA_PROCEDURE: + io_errlHndl->addProcedureCallout( + (HWAS::epubProcedureID)l_compData, + i_priority); + io_callout_num++; + break; + case TMGT_COMP_DATA_END_OF_TABLE: + break; + default: + TMGT_ERR("elogAddCallout: Invalid component id 0x%02X", + l_compId); + l_success = false; + } + } + else + { + TMGT_ERR("elogAddCallout: Component id translate failure" + " (id=0x%02X)", l_compId); + l_success = false; + } + } + else + { + TMGT_ERR("elogAddCallout: Invalid callout type (type=%d)", + i_callout.type); + l_success = false; + } + + return l_success;; + + } // end Occ::elogAddCallout() + + + void Occ::elogProcessActions(const uint8_t i_actions, + bool & o_occReset, + ERRORLOG::errlSeverity_t & o_errlSeverity) + { + if (i_actions & TMGT_ERRL_ACTIONS_RESET_REQUIRED) + { + o_occReset = true; + iv_failed = true; + iv_resetReason = OCC_RESET_REASON_OCC_REQUEST; + + TMGT_INF("elogProcessActions: OCC%d requested reset", + iv_instance); + } + + if (i_actions & TMGT_ERRL_ACTIONS_SAFE_MODE_REQUIRED) + { + o_occReset = true; + iv_failed = true; + iv_resetReason = OCC_RESET_REASON_CRIT_FAILURE; + iv_resetCount = OCC_RESET_COUNT_THRESHOLD; + + TMGT_INF("elogProcessActions: OCC%d requested safe mode", + iv_instance); + TMGT_CONSOLE("OCC%d requested system enter safe mode", + iv_instance); + } + + } // end Occ::elogProcessActions() + + + } // end namespace |