/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* $Source: src/usr/errldisplay/errldisplay.C $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2013,2019 */ /* [+] Google Inc. */ /* [+] 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 */ /** * @file /src/usr/errl/display/errldisplay.C * * @brief Implementation of ErrlDisplay class * This will display human-readable dumps of error log entries. * * The strings displayed are automatically extracted from source code by * the script ../errl/parser/genErrlParsers.pl * * The base image is limited to 512K, and inclusion of the error strings * in the base make it grow beyond that limit, so the text and display * functions are put into the extended image. * * The errl module in the base image will provide an interface for the * display functions to register with it. * When an errl is generated, the base image will see if a display function * has been registered. If so, then it will be called to display the error. * If not, then the base image will display the raw error data and save the * error information into a list. * When the display function does register itself, the errl module in the * base image will pretty-print all of the pending errors from the list * it generated before that point. */ /*****************************************************************************/ // I n c l u d e s /*****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef CONFIG_CONSOLE_OUTPUT_FFDCDISPLAY //Generated hearder files for HWP parsing #include #include #include namespace PRDF { namespace HOSTBOOT { PrdrErrSigTable & GetErrorSigTable() { static PrdrErrSigTable l_sigTable = PrdrErrSigTable(); return l_sigTable; } } } #endif namespace ERRORLOGDISPLAY { // Trace definition trace_desc_t* g_trac_errldisp = NULL; TRAC_INIT(&g_trac_errldisp, "ERRLDISP", KILOBYTE, TRACE::BUFFER_SLOW); /** * @brief Default error log to display when we can't find one in the errorInfo * table. * * The data tables and size variables * static errLogInfo errorInfo [] * static compTableInfo compTable [] * static uint16_t errorInfoTableSize * static uint16_t compTableSize * are automatically generated by the ../errl/parser/genErrlTable.pl script * and placed in the file $GENDIR/errldisplaydata.C */ static const ErrLogDisplay::errLogInfo unknownErrorInfo = { 0, // Module Id 0, // Reason Code "", // Description "unknown", // Module Name "unknown", // Reason "", // User Data 1 string "" // User Data 2 string }; ErrLogDisplay& errLogDisplay() { return Singleton::instance(); } const ErrLogDisplay::errLogInfo* ErrLogDisplay::findErrLogInfo ( uint8_t i_moduleId, uint16_t i_reasonCode) { // Create local errLogInfo to search for struct ErrLogDisplay::errLogInfo l_errLogInfo = {i_moduleId,i_reasonCode, NULL,NULL,NULL,NULL,NULL}; errLogInfo* l_result = std::lower_bound(errorInfo, errorInfo + errorInfoTableSize, l_errLogInfo, ErrLogDisplay::errorLogInfoCompare); // Check if the lower_bound found the correct result if ( (l_result != (errorInfo + errorInfoTableSize)) && (l_result->moduleId == i_moduleId) && (l_result->reasonCode == i_reasonCode) ) { return l_result; } // Couldn't find it, so return the default unknown structure. return &unknownErrorInfo; } const char * ErrLogDisplay::findComponentName (compId_t i_compId) { // Create local compTableInfo to search for struct ErrLogDisplay::compTableInfo l_compTableInfo = {i_compId, NULL}; compTableInfo* l_result = std::lower_bound(compTable, compTable + compTableSize, l_compTableInfo, ErrLogDisplay::compTableCompare); // Check if the lower_bound found the correct result if ( (l_result != (compTable + errorInfoTableSize)) && (l_result->value == i_compId) ) { return l_result->name; } return "unknown"; } void displayCalloutTarget (uint8_t * epRaw, size_t& o_size) { // Data is formatted as a callout_ud_t followed by an entity path. // Note that in error data unused entity path elements are // eliminated, so use data to find the length const uint8_t pathTypeLength = *epRaw; //# of ep elements (2 bytes each) are in lower nibble of first elem //Master sentinel is 0xF0 so size is correct @ 1 o_size = ((pathTypeLength & 0x0F) * 2)+1; const char * ep_str = "MASTER PROCESSOR SENTINEL"; char * tmp_str = NULL; if( *epRaw != HWAS::TARGET_IS_SENTINEL ) { TARGETING::EntityPath ep; if ((o_size > sizeof(TARGETING::EntityPath))) { ep_str = "MALFORMED UD Entity Path"; o_size = 0; //stay safe } else { memcpy (reinterpret_cast(&ep), epRaw,o_size); tmp_str = ep.toString(); ep_str = tmp_str; } } CONSOLE::displayf(NULL, " Target : %s", ep_str); free(tmp_str); } void ErrLogDisplay::displayPrdf (uint64_t i_ud1, uint64_t i_ud2) { //PRD stores the HUID of the callout in top word of ud1 // and the signature in the top word of ud2 uint32_t l_huid = i_ud1 >> 32; uint32_t l_sig = i_ud2 >> 32; CONSOLE::displayf(NULL, " PRD Signature : 0x%X 0x%X", l_huid, l_sig); #ifdef CONFIG_CONSOLE_OUTPUT_FFDCDISPLAY //Find the Target from the HUID TARGETING::Target* l_pTopLevel = NULL; TARGETING::targetService().getTopLevelTarget(l_pTopLevel); TARGETING::Target * l_target = l_pTopLevel->getTargetFromHuid(l_huid); if(l_target) { TARGETING::TYPE l_targetType = l_target->getAttr(); const char * l_nameStr = PRDF::HOSTBOOT::GetErrorSigTable()[l_targetType][l_sig].first; const char * l_descStr = PRDF::HOSTBOOT::GetErrorSigTable()[l_targetType][l_sig].second; TARGETING::ATTR_FAPI_NAME_type l_fapiStr = {0}; l_target->tryGetAttr(l_fapiStr); if(l_nameStr) { CONSOLE::displayf(NULL, " Signature Description : %s (%s) %s", l_fapiStr, l_nameStr, l_descStr); } else { CONSOLE::displayf(NULL, " Signature Description : %s UNKNOWN", l_fapiStr); } } #endif } void ErrLogDisplay::displayCallout (void *data, size_t size) { CONSOLE::displayf(NULL, "------------------------------------------------"); // Parse encoded callout data. See ErrlUserDetailsCallout class in // errludcallout.C for (undocumented) encoding details. if (size >= sizeof(HWAS::callout_ud_t)) { HWAS::callout_ud_t* callout = reinterpret_cast(data); size_t displayTarget = 0; bool displayGard = false; HWAS::GARD_ErrorType l_gard = HWAS::GARD_Fatal; bool displayDeconfig = false; HWAS::DeconfigEnum l_deconfig = HWAS::DECONFIG; switch ( callout->type ) { case HWAS::CLOCK_CALLOUT: switch (callout->clockType) { #define case_CLOCK_TYPE(_type) \ case HWAS::_type: CONSOLE::displayf(NULL, " Clock Type : %s", #_type); break; case_CLOCK_TYPE(TODCLK_TYPE) case_CLOCK_TYPE(MEMCLK_TYPE) case_CLOCK_TYPE(OSCREFCLK_TYPE) case_CLOCK_TYPE(OSCPCICLK_TYPE) default: CONSOLE::displayf(NULL, " Clock Type : UNKNOWN 0x%X", callout->clockType); } // switch clockType #undef case_CLOCK_TYPE displayGard = true; l_gard = callout->clkGardErrorType; displayDeconfig = true; l_deconfig = callout->clkDeconfigState; displayTarget = 1; break; case HWAS::PART_CALLOUT: switch (callout->partType) { #define case_PART_TYPE(_type) \ case HWAS::_type: CONSOLE::displayf(NULL, " Part Type : %s", #_type); break; case_PART_TYPE(FLASH_CONTROLLER_PART_TYPE) case_PART_TYPE(PNOR_PART_TYPE) case_PART_TYPE(SBE_SEEPROM_PART_TYPE) case_PART_TYPE(VPD_PART_TYPE) case_PART_TYPE(LPC_SLAVE_PART_TYPE) case_PART_TYPE(GPIO_EXPANDER_PART_TYPE) case_PART_TYPE(SPIVID_SLAVE_PART_TYPE) case_PART_TYPE(BPM_CABLE_PART_TYPE) case_PART_TYPE(NV_CONTROLLER_PART_TYPE) case_PART_TYPE(BPM_PART_TYPE) default: CONSOLE::displayf(NULL, " Part Type : UNKNOWN 0x%X", callout->partType); } // switch partType #undef case_PART_TYPE displayGard = true; l_gard = callout->partGardErrorType; displayDeconfig = true; l_deconfig = callout->partDeconfigState; displayTarget = 1; break; case HWAS::BUS_CALLOUT: switch (callout->busType) { #define case_BUS_TYPE(_type) \ case HWAS::_type: CONSOLE::displayf(NULL, " Bus Type : %s", #_type); break; case_BUS_TYPE(FSI_BUS_TYPE) case_BUS_TYPE(DMI_BUS_TYPE) case_BUS_TYPE(A_BUS_TYPE) case_BUS_TYPE(X_BUS_TYPE) case_BUS_TYPE(I2C_BUS_TYPE) case_BUS_TYPE(PSI_BUS_TYPE) case_BUS_TYPE(O_BUS_TYPE) default: CONSOLE::displayf(NULL, " Bus Type : UNKNOWN 0x%X", callout->busType); } // switch partType #undef case_BUS_TYPE // Data is formatted as a callout_ud_t followed by 2 entity // paths representing each side of the link. displayTarget = 2; break; case HWAS::HW_CALLOUT: CONSOLE::displayf(NULL, " Callout type : Hardware Callout"); CONSOLE::displayf(NULL, " CPU id : %d", callout->cpuid); displayGard = true; l_gard = callout->gardErrorType; displayDeconfig = true; l_deconfig = callout->deconfigState; displayTarget = 1; break; case HWAS::PROCEDURE_CALLOUT: CONSOLE::displayf(NULL, " Callout type : Procedure Callout"); switch (callout->procedure) { #define case_PROCEDURE(_type) \ case HWAS::_type: CONSOLE::displayf(NULL, " Procedure : %s", #_type); break; case_PROCEDURE(EPUB_PRC_NONE) case_PROCEDURE(EPUB_PRC_FIND_DECONFIGURED_PART) case_PROCEDURE(EPUB_PRC_SP_CODE) case_PROCEDURE(EPUB_PRC_PHYP_CODE) case_PROCEDURE(EPUB_PRC_ALL_PROCS) case_PROCEDURE(EPUB_PRC_ALL_MEMCRDS) case_PROCEDURE(EPUB_PRC_INVALID_PART) case_PROCEDURE(EPUB_PRC_LVL_SUPP) case_PROCEDURE(EPUB_PRC_PROCPATH) case_PROCEDURE(EPUB_PRC_NO_VPD_FOR_FRU) case_PROCEDURE(EPUB_PRC_MEMORY_PLUGGING_ERROR) case_PROCEDURE(EPUB_PRC_FSI_PATH) case_PROCEDURE(EPUB_PRC_PROC_AB_BUS) case_PROCEDURE(EPUB_PRC_PROC_XYZ_BUS) case_PROCEDURE(EPUB_PRC_MEMBUS_ERROR) case_PROCEDURE(EPUB_PRC_EIBUS_ERROR) case_PROCEDURE(EPUB_PRC_POWER_ERROR) case_PROCEDURE(EPUB_PRC_MEMORY_UE) case_PROCEDURE(EPUB_PRC_PERFORMANCE_DEGRADED) case_PROCEDURE(EPUB_PRC_HB_CODE) case_PROCEDURE(EPUB_PRC_TOD_CLOCK_ERR) case_PROCEDURE(EPUB_PRC_COOLING_SYSTEM_ERR) case_PROCEDURE(EPUB_PRC_FW_VERIFICATION_ERR) case_PROCEDURE(EPUB_PRC_GPU_ISOLATION_PROCEDURE) default: CONSOLE::displayf(NULL, " Procedure : UNKNOWN: 0x%X", callout->procedure); break; } // switch procedure #undef case_PROCEDURE break; case HWAS::SENSOR_CALLOUT: CONSOLE::displayf(NULL, " Sensor ID : 0x%x", callout->sensorId); switch (callout->sensorType) { #define case_SENSOR_TYPE(_type) \ case HWAS::_type: CONSOLE::displayf(NULL, " Sensor Type : %s", #_type); break; case_SENSOR_TYPE(UNKNOWN_SENSOR) case_SENSOR_TYPE(GPU_FUNC_SENSOR) case_SENSOR_TYPE(GPU_TEMPERATURE_SENSOR) case_SENSOR_TYPE(GPU_MEMORY_TEMP_SENSOR) default: CONSOLE::displayf(NULL, " Sensor Type : UNKNOWN 0x%X", callout->sensorType); } // switch sensorType #undef case_SENSOR_TYPE break; case HWAS::I2C_DEVICE_CALLOUT: CONSOLE::displayf(nullptr, " Callout type : I2C Device Callout"); break; default: CONSOLE::displayf(NULL, " Callout type : UNKNOWN: 0x%X", callout->type); break; } /////////////////////////// // Display all the common stuff /////////////////////////// //Display the number of targets indicated above uint8_t * epRaw = reinterpret_cast( callout+1 ); //ptr math size_t l_size = 0; for(size_t numT = 0 ; numT < displayTarget; numT++) { // Data is formatted as a callout_ud_t followed by an entity path // Multiple EP are packed together epRaw += l_size; displayCalloutTarget(epRaw,l_size); } if(displayDeconfig) { switch (l_deconfig) { #define case_DECONFIG_STATE(_type) \ case HWAS::_type: CONSOLE::displayf(NULL, " Deconfig State : %s", #_type); break; case_DECONFIG_STATE(NO_DECONFIG) case_DECONFIG_STATE(DECONFIG) case_DECONFIG_STATE(DELAYED_DECONFIG) default: CONSOLE::displayf(NULL, " Deconfig State : UNKNOWN: 0x%X", l_deconfig); break; } // switch deconfigState #undef case_DECONFIG_STATE } if(displayGard) { switch (l_gard) { #define case_GARD_ERROR_TYPE(_type) \ case HWAS::_type: CONSOLE::displayf(NULL, " GARD Error Type : %s", #_type); break; case_GARD_ERROR_TYPE(GARD_NULL) case_GARD_ERROR_TYPE(GARD_User_Manual) case_GARD_ERROR_TYPE(GARD_Unrecoverable) case_GARD_ERROR_TYPE(GARD_Fatal) case_GARD_ERROR_TYPE(GARD_Predictive) case_GARD_ERROR_TYPE(GARD_Power) case_GARD_ERROR_TYPE(GARD_PHYP) case_GARD_ERROR_TYPE(GARD_Reconfig) case_GARD_ERROR_TYPE(GARD_Void) default: CONSOLE::displayf(NULL, " GARD Error Type : UNKNOWN: 0x%X", l_gard); break; } // switch gardState #undef case_GARD_ERROR_TYPE } switch (callout->priority) { #define case_PRIORITY(_type) \ case HWAS::_type: CONSOLE::displayf(NULL, " Priority : %s", #_type); break; case_PRIORITY(SRCI_PRIORITY_NONE) case_PRIORITY(SRCI_PRIORITY_LOW) case_PRIORITY(SRCI_PRIORITY_MEDC) case_PRIORITY(SRCI_PRIORITY_MEDB) case_PRIORITY(SRCI_PRIORITY_MEDA) case_PRIORITY(SRCI_PRIORITY_MED) case_PRIORITY(SRCI_PRIORITY_HIGH) default: CONSOLE::displayf(NULL, " Priority : UNKNOWN: 0x%X", callout->priority); break; } // switch priority #undef case_PRIORITY } } //Display a "Target". This is a misnomer in that HB uses a "target" // User detail section for lots of things. We are only going to look // for HWPF subtypes and display those void ErrLogDisplay::displayTarget(void *data, size_t size) { char *char_buf = reinterpret_cast( data ); // The first part of the buffer is a TargetLabel_t. ERRORLOG::TargetLabel_t *label = reinterpret_cast( char_buf ); if( label->tag == 0xffffffff ) { CONSOLE::displayf(NULL, " MASTER PROCESSOR SENTINEL" ); } else { // The second part of the buffer contains the encoded target. // See Target::targetFFDC for encoding details. // We only care about the HUID and can look up the Target based on that. char_buf += sizeof(ERRORLOG::TargetLabel_t); TARGETING::AttributeTraits::Type *huid = reinterpret_cast::Type*>( char_buf ); CONSOLE::displayf(NULL, " HUID: %08x", *huid ); // Look up the HUID across all targets. for ( TARGETING::TargetIterator ti = TARGETING::targetService().begin(); ti != TARGETING::targetService().end(); ++ti ) { TARGETING::AttributeTraits::Type tmp_huid; if( ti->tryGetAttr( tmp_huid ) && tmp_huid == *huid ) { TARGETING::Target *target = *ti; CONSOLE::displayf(NULL, " Phys path: %s", target->getAttr().toString() ); CONSOLE::displayf(NULL, " Affinity path: %s", target->getAttr().toString()); break; } } } } #ifdef CONFIG_CONSOLE_OUTPUT_FFDCDISPLAY static void printHex(char *i_buf, const size_t i_size) { char byte_str[256] = { 0, }; size_t pos = 0; // Limit dump to first 32 bytes. for ( size_t i = 0; i < std::min( i_size, 32ul ); ++i ) pos += sprintf( byte_str + pos, "%s%02X", (i % 4) == 0 ? " " : "", i_buf[i] ); CONSOLE::displayf( NULL, " %s", byte_str ); } #endif void ErrLogDisplay::displayHwpf(void *data, size_t size, uint8_t i_type) { #ifdef CONFIG_CONSOLE_OUTPUT_FFDCDISPLAY uint32_t *word_buf = reinterpret_cast( data ); switch ( i_type ) { case ERRORLOG::ERRL_UDT_STRING: //this is error code str -- single word of data is HWPF RC CONSOLE::displayf( NULL, "------------------------------------------------" ); const char *rc; const char *desc; fapi2::hbfwErrLookupHwpRc( *word_buf, rc, desc ); CONSOLE::displayf( NULL, " HwpReturnCode : %s", rc ? rc : "Unknown" ); CONSOLE::displayf( NULL, " HWP Error description : %s", desc ? desc : "Unknown" ); break; case ERRORLOG::ERRL_UDT_TARGET: { //this is HWPF FFDC. First word is hash, rest of data is hex //reserve space for 16 words of data with spaces between CONSOLE::displayf( NULL, "------------------------------------------------" ); fapi2::hbfwFfdcType type; uint64_t value; const char *str; int index = 0; char *buf = reinterpret_cast( data ) + sizeof( *word_buf ); size -= sizeof( *word_buf ); while ( fapi2::hbfwErrLookupHwpRcFFDC( *word_buf, index, type, value, str ) ) { if( type == fapi2::HBFW_FFDC_TYPE_HWP_RC_FFDC ) { const char *rc; const char *desc; fapi2::hbfwErrLookupHwpRc( value, rc, desc ); CONSOLE::displayf( NULL, " HwpReturnCode : %s", rc ? rc : "Unknown" ); CONSOLE::displayf( NULL, " FFDC : %s", str ? str : "Unknown" ); printHex(buf, size); size = 0; } else if( type == fapi2::HBFW_FFDC_TYPE_SCOM_FAIL ) { uint64_t val64 = be64toh( *reinterpret_cast( buf ) ); CONSOLE::displayf( NULL, " Failed SCOM address : %#016lX", val64 ); } else if( type == fapi2::HBFW_FFDC_TYPE_PIB_RC ) { uint64_t val32 = be64toh( *reinterpret_cast( buf ) ); CONSOLE::displayf( NULL, " PIB RC : %#08lX", val32 ); } else if( type == fapi2::HBFW_FFDC_TYPE_REGISTER_SET ) { CONSOLE::displayf( NULL, " Register FFDC : %s", str ? str : "Unknown" ); } else if( type == fapi2::HBFW_FFDC_TYPE_CHIP_POSITION && (size >= sizeof(uint32_t)) ) { uint32_t val32 = be32toh( *reinterpret_cast( buf ) ); CONSOLE::displayf( NULL, " Chip Position : %X", val32 ); buf += sizeof(uint32_t); size -= sizeof(uint32_t); } else if( type == fapi2::HBFW_FFDC_TYPE_CFAM_REG && (size >= sizeof(uint32_t)) ) { uint32_t val32 = be32toh( *reinterpret_cast( buf ) ); CONSOLE::displayf( NULL, " CFAM Register : %s", str ? str : "Unknown" ); CONSOLE::displayf( NULL, " %08X", val32 ); buf += sizeof(uint32_t); size -= sizeof(uint32_t); } else if( type == fapi2::HBFW_FFDC_TYPE_SCOM_REG && (size >= sizeof(uint64_t)) ) { uint64_t val64 = be64toh( *reinterpret_cast( buf ) ); CONSOLE::displayf( NULL, " SCOM Register : %s", str ? str : "Unknown" ); CONSOLE::displayf( NULL, " %08llX %08llX", (val64 >> 32) & 0xffffffff, (val64 & 0xffffffff) ); buf += sizeof(uint64_t); size -= sizeof(uint64_t); } index++; } break; } } #endif } // // Display a human-readable form of an error. void ErrLogDisplay::msgDisplay (const errlHndl_t &i_err, compId_t i_committerComp) { TRACDCOMP( g_trac_errldisp, ENTER_MRK "ErrLogDisplay::msgDisplay" ); do { // Decide whether or not to skip the error log if( i_err->getSkipShowingLog() ) { TRACDCOMP( g_trac_errldisp, INFO_MRK"msgDisplay: %.8X is INFORMATIONAL/RECOVERED; skipping...", i_err->eid()); break; } const errLogInfo *info = findErrLogInfo ( i_err->moduleId(), i_err->reasonCode()); CONSOLE::displayf(NULL, "================================================"); CONSOLE::displayf(NULL, "Error reported by %s (0x%04X) PLID 0x%08X", findComponentName( i_committerComp ), i_committerComp, i_err->plid() ); //PRD doesn't follow the rest of the HB conventions // Handle them special if(i_committerComp == PRDF_COMP_ID) { displayPrdf(i_err->getUserData1(), i_err->getUserData2()); } else { CONSOLE::displayf(NULL, " %s", info->descriptString); CONSOLE::displayf(NULL, " ModuleId 0x%02x %s", i_err->moduleId(), info->moduleName); CONSOLE::displayf(NULL, " ReasonCode 0x%04x %s", i_err->reasonCode(), info->reasonString); } CONSOLE::displayf(NULL, " UserData1 %s : 0x%016lx", info->userData1String, i_err->getUserData1()); CONSOLE::displayf(NULL, " UserData2 %s : 0x%016lx", info->userData2String, i_err->getUserData2()); // Loop through and print interesting user data sections. for ( size_t i = 0; i < i_err->iv_SectionVector.size(); ++i ) { ERRORLOG::ErrlUD *user_data = i_err->iv_SectionVector[i]; //HWPF subsections abuse the rules... handle it special if(user_data->iv_header.iv_compId == HWPF_COMP_ID) { displayHwpf( user_data->iv_pData, user_data->iv_Size, user_data->iv_header.iv_sst); } else if(user_data->iv_header.iv_compId == ERRL_COMP_ID) { switch ( user_data->iv_header.iv_sst ) { case ERRORLOG::ERRL_UDT_CALLOUT: displayCallout( user_data->iv_pData, user_data->iv_Size ); break; case ERRORLOG::ERRL_UDT_STRING: CONSOLE::displayf(NULL, "------------------------------------------------"); CONSOLE::displayf(NULL, " %s", reinterpret_cast( user_data->iv_pData ) ); break; } } } CONSOLE::displayf(NULL, "================================================" ); CONSOLE::flush(); }while( 0 ); TRACDCOMP( g_trac_errldisp, EXIT_MRK "ErrLogDisplay::msgDisplay" ); } /** * @brief This is the task entry point. It will register ErrlDisplay module with * the base image Errl module. * * @param[in/out] io_taskRetErrl Errl module to register with ErrlDisplay * instance * * @return None */ static void errLogDisplayEntryPoint (errlHndl_t &io_taskRetErrl) { TRACFCOMP( g_trac_errldisp, ENTER_MRK "ErrLogDisplay::errLogDisplayEntryPoint" ); io_taskRetErrl = Singleton::instance().init(); TRACFCOMP( g_trac_errldisp, EXIT_MRK "ErrLogDisplay::errLogDisplayEntryPoint" ); } TASK_ENTRY_MACRO( errLogDisplayEntryPoint ); errlHndl_t ErrLogDisplay::init() { ERRORLOG::ErrlManager::errlResourceReady(ERRORLOG::ERRLDISP); return NULL; } } // End namespace