int32_t calloutBusInterface( ExtensibleChip * i_chip, PRDpriority i_priority, TYPE i_busType, uint32_t i_busPos ) { #define PRDF_FUNC "[CalloutUtil::calloutBusInterface] " int32_t rc = SUCCESS; do { TargetHandle_t rxTrgt = NULL; TargetHandle_t txTrgt = NULL; rc = getBusEndpoints( i_chip, rxTrgt, txTrgt, i_busType, i_busPos ); if ( SUCCESS != rc ) break; rc = calloutBusInterface( rxTrgt, txTrgt, i_priority ); if ( SUCCESS != rc ) break; } while(0); if ( SUCCESS != rc ) { PRDF_ERR( PRDF_FUNC "i_chip:0x%08x i_busType:%d i_busPos:%d " "i_priority:%d", i_chip->GetId(), i_busType, i_busPos, i_priority ); } return rc; #undef PRDF_FUNC }
uint32_t ScomRegister::ForceRead() const { #define PRDF_FUNC "[ScomRegister::ForceRead] " uint32_t o_rc = FAIL; do { // No read allowed if register access attribute is write-only or no // access. if ( ( ACCESS_NONE == iv_operationType ) && ( ACCESS_WO == iv_operationType ) ) { PRDF_ERR( PRDF_FUNC"Write-only register: 0x%08x 0x%016llx", getChip()->GetId(), iv_scomAddress ); break; } // Read hardware. o_rc = Access( readCache(), MopRegisterAccess::READ ); if ( SUCCESS != o_rc ) { // The read failed. Remove the entry from the cache so a subsequent // Read() will attempt to read from hardware again. flushCache( getChip() ); } } while (0); return o_rc; #undef PRDF_FUNC }
int32_t mssIplUeIsolation( TargetHandle_t i_mba, const CenRank & i_rank, CenDqBitmap & o_bitmap ) { #define PRDF_FUNC "[PlatServices::mssIplUeIsolation] " int32_t o_rc = SUCCESS; uint8_t data[PORT_SLCT_PER_MBA][DIMM_DQ_RANK_BITMAP_SIZE]; errlHndl_t errl = NULL; PRD_FAPI_TO_ERRL( errl, mss_IPL_UE_isolation, getFapiTarget(i_mba), i_rank.getMaster(), data ); if ( NULL != errl ) { PRDF_ERR( PRDF_FUNC"mss_IPL_UE_isolation() failed: MBA=0x%08x " "rank=%d", getHuid(i_mba), i_rank.getMaster() ); PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT ); o_rc = FAIL; } else { o_bitmap = CenDqBitmap ( i_mba, i_rank, data ); } return o_rc; #undef PRDF_FUNC }
TargetHandleList getConnectedDimms( TargetHandle_t i_mba, uint8_t i_port ) { #define PRDF_FUNC "[CalloutUtil::getConnectedDimms] " TargetHandleList o_list; TargetHandleList dimmList = getConnectedDimms( i_mba ); for ( TargetHandleList::iterator dimmIt = dimmList.begin(); dimmIt != dimmList.end(); dimmIt++) { uint8_t portSlct; int32_t l_rc = getMbaPort( *dimmIt, portSlct ); if ( SUCCESS != l_rc ) { PRDF_ERR( PRDF_FUNC "getMbaPort(0x%08x) failed", getHuid(*dimmIt) ); continue; } if ( portSlct == i_port ) { o_list.push_back( *dimmIt ); } } return o_list; #undef PRDF_FUNC }
/** * @brief Plugin function called after analysis is complete but before PRD * exits. * @param i_mbaChip A Centaur MBA chip. * @param i_sc The step code data struct. * @note This is especially useful for any analysis that still needs to be * done after the framework clears the FIR bits that were at attention. * @return SUCCESS. */ int32_t PostAnalysis( ExtensibleChip * i_mbaChip, STEP_CODE_DATA_STRUCT & i_sc ) { #define PRDF_FUNC "[Mba::PostAnalysis] " // Send command complete to MDIA. // This must be done in post analysis after attentions have been cleared. TargetHandle_t mbaTarget = i_mbaChip->GetChipHandle(); CenMbaDataBundle * mbadb = getMbaDataBundle( i_mbaChip ); if ( mbadb->iv_sendCmdCompleteMsg ) { mbadb->iv_sendCmdCompleteMsg = false; int32_t l_rc = mdiaSendEventMsg( mbaTarget, mbadb->iv_cmdCompleteMsgData ); if ( SUCCESS != l_rc ) { PRDF_ERR( PRDF_FUNC"PlatServices::mdiaSendEventMsg() failed" ); } } return SUCCESS; // Intentionally return SUCCESS for this plugin #undef PRDF_FUNC }
int32_t mdiaSendEventMsg( TargetHandle_t i_mbaTarget, MDIA::MaintCommandEventType i_eventType ) { #define PRDF_FUNC "[PlatServices::mdiaSendCmdComplete] " int32_t o_rc = SUCCESS; do { if ( !isInMdiaMode() ) break; // no-op // Verify type. TYPE l_type = getTargetType(i_mbaTarget); if ( TYPE_MBA != l_type ) { PRDF_ERR( PRDF_FUNC"unsupported target type %d", l_type ); o_rc = FAIL; break; } // Send command complete to MDIA. MDIA::MaintCommandEvent l_mdiaEvent; l_mdiaEvent.target = i_mbaTarget; l_mdiaEvent.type = i_eventType; errlHndl_t errl = MDIA::processEvent( l_mdiaEvent ); if ( NULL != errl ) { PRDF_ERR( PRDF_FUNC"MDIA::processEvent() failed" ); PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT ); o_rc = FAIL; break; } } while (0); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC"Failed: i_target=0x%08x i_eventType=%d", getHuid(i_mbaTarget), i_eventType ); } return o_rc; #undef PRDF_FUNC }
errlHndl_t SimFspSyncSvc::processMfgTrace(msg_t *i_msg) const { #define PRDF_FUNC "[SimFspSyncSvc::processMfgTrace]" PRDF_ENTER(PRDF_FUNC); errlHndl_t l_errLog = NULL; uint8_t l_mruListCount = 0; uint8_t *l_extraData = NULL; do { l_extraData = reinterpret_cast <uint8_t *> (i_msg->extra_data); l_mruListCount = (i_msg->data[1] / sizeof(PfaMruListStruct)); if(l_mruListCount > MruListLIMIT) { PRDF_ERR(PRDF_FUNC "Invalid MRU count: %d received from Hostboot" " max expected count is: %d", l_mruListCount, MruListLIMIT); /*@ * @errortype * @refcode LIC_REFCODE * @subsys EPUB_FIRMWARE_SP * @reasoncode PRDF_INVALID_CONFIG * * @moduleid PRDF_SYNC_SVC * @userdata1 MRU List Count * @userdata2 Max MRU Count * @userdata3 Line number in file * @devdesc Received invalid MRU count in * MnfgTrace message from Hostboot */ PRDF_CREATE_ERRL(l_errLog, ERRL_SEV_INFORMATIONAL, ERRL_ETYPE_NOT_APPLICABLE, SRCI_ERR_INFO, SRCI_NO_ATTR, PRDF_SYNC_SVC, LIC_REFCODE, PRDF_INVALID_CONFIG, l_mruListCount, MruListLIMIT, __LINE__, 0); break; } if(NULL != l_extraData) { free(l_extraData); } }while(0); return l_errLog; #undef PRDF_FUNC }
uint32_t getIoOscPos( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & io_sc) { #define PRDF_FUNC "[PLL::getIoOscPos] " uint32_t o_oscPos = MAX_PCIE_OSC_PER_NODE; do { int32_t rc = SUCCESS; // START WORKAROUND // TODO: RTC 137711 - This redundant clock code only applies to Brazos // systems. Unfortunately, this code made it into the common // source and we ran into SW324506 where we are unable to SCOM // PCIE_OSC_SWITCH during OP checkstop analysis. We should have // a system attribute that tells us if redundant clock are enabled // but for now just assume anything that is OPAL based will not // have redundant clocks. Note that we still need this code in // Hostboot (not HBRT) because Hostboot is still run on a Brazos // system. if ( isHyprConfigOpal() ) { o_oscPos = 0; break; } // END WORKAROUND SCAN_COMM_REGISTER_CLASS * pcieOscSwitchReg = i_chip->getRegister("PCIE_OSC_SWITCH"); rc = pcieOscSwitchReg->Read(); if (rc != SUCCESS) { PRDF_ERR(PRDF_FUNC "PCIE_OSC_SWITCH read failed" "for 0x%08x", i_chip->GetId()); break; } // [ 16 ] == 1 ( OSC 0 is active ) // [ 16 ] == 0 ( OSC 1 is active ) if(pcieOscSwitchReg->IsBitSet(16)) { o_oscPos = 0; } else { o_oscPos = 1; } } while(0); return o_oscPos; #undef PRDF_FUNC }
int32_t getBusEndpoints( ExtensibleChip * i_chip, TargetHandle_t & o_rxTrgt, TargetHandle_t & o_txTrgt, TYPE i_busType, uint32_t i_busPos ) { #define PRDF_FUNC "[CalloutUtil::getBusEndpoints] " int32_t rc = SUCCESS; o_rxTrgt = NULL; o_txTrgt = NULL; TargetHandle_t chipTrgt = i_chip->GetChipHandle(); TYPE chipType = getTargetType(chipTrgt); if ( TYPE_PROC == chipType ) { o_rxTrgt = getConnectedChild( chipTrgt, i_busType, i_busPos ); if ( TYPE_ABUS == i_busType || TYPE_XBUS == i_busType ) { o_txTrgt = getConnectedPeerTarget( o_rxTrgt ); } else if ( TYPE_MCS == i_busType ) { o_txTrgt = getConnectedChild( o_rxTrgt, TYPE_MEMBUF, 0 ); } } else if ( TYPE_MCS == chipType ) { o_rxTrgt = chipTrgt; o_txTrgt = getConnectedChild( o_rxTrgt, TYPE_MEMBUF, 0 ); } else if ( TYPE_MEMBUF == chipType ) { o_rxTrgt = chipTrgt; o_txTrgt = getConnectedParent( o_rxTrgt, TYPE_MCS ); } // Note that all of the 'getConnected' functions above do proper parameter // checking and will return NULL if anything is wrong. So this is the only // NULL check we actually need in this function. if ( NULL == o_rxTrgt || NULL == o_txTrgt ) { PRDF_ERR( PRDF_FUNC "i_chip:0x%08x o_rxTrgt:0x%08x o_txTrgt:0x%08x " "i_busType:%d i_busPos:%d", getHuid(chipTrgt), getHuid(o_rxTrgt), getHuid(o_txTrgt), i_busType, i_busPos ); rc = FAIL; } return rc; #undef PRDF_FUNC }
void prdfAssert( const char * i_exp, const char * i_file, int i_line ) { PRDF_ERR( "prdfAssert(%s) in %s line %d", i_exp, i_file, i_line ); errlHndl_t errl = NULL; /*@ * @errortype * @subsys EPUB_FIRMWARE_SP * @reasoncode PRDF_CODE_FAIL * @moduleid PRDF_ASSERT * @userdata1 0 * @userdata2 Line number of the assert * @userdata3 0 * @userdata4 PRD Return code * @devdesc PRD assert * @custDesc An internal firmware fault. * @procedure EPUB_PRC_SP_CODE */ PRDF_CREATE_ERRL(errl, ERRL_SEV_PREDICTIVE, // error on diagnostic ERRL_ETYPE_NOT_APPLICABLE, SRCI_ERR_INFO, SRCI_NO_ATTR, PRDF_ASSERT, // module id FSP_DEFAULT_REFCODE, // refcode PRDF_CODE_FAIL, // Reason code 0, // user data word 1 i_line, // user data word 2 0, // user data word 3 PRD_ASSERT); // user data word 4 PRDF_ADD_PROCEDURE_CALLOUT(errl, SRCI_PRIORITY_MED, EPUB_PRC_SP_CODE); PRDF_SET_RC(errl, PRD_ASSERT); PRDF_COLLECT_TRACE(errl, 256); PRDF_SET_TERM_STATE( errl ); PRDF_COMMIT_ERRL(errl, ERRL_ACTION_SA); #ifdef __HOSTBOOT_MODULE assert(0); #else const size_t sz_msg = 160; char msg[sz_msg]; errlslen_t msize = snprintf( msg, sz_msg, "prdfAssert(%s) in %s line %d", i_exp, i_file, i_line ); percAbend(PRDF_COMP_ID, msg, msize+1, 0, 0); abort(); #endif }
/** * @brief Plugin function called after analysis is complete but before PRD * exits. * @param i_chip EQ chip. * @param io_sc The step code data struct. * @note This is especially useful for any analysis that still needs to be * done after the framework clears the FIR bits that were at attention. * @return SUCCESS. */ int32_t PostAnalysis( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & io_sc ) { #ifdef __HOSTBOOT_RUNTIME int32_t l_rc = restartTraceArray(i_chip->GetChipHandle()); if (SUCCESS != l_rc) { PRDF_ERR( "[EQ PostAnalysis HUID: 0x%08x RestartTraceArray failed", i_chip->GetId()); } #endif return SUCCESS; } PRDF_PLUGIN_DEFINE(p9_eq, PostAnalysis);
TargetHandleList getConnectedDimms( TargetHandle_t i_mba ) { TargetHandleList o_list; if ( TYPE_MBA != getTargetType(i_mba) ) { PRDF_ERR( "[CalloutUtil::getConnectedDimms] Invalid target type: " "HUID=0x%08x", getHuid(i_mba) ); } else o_list = getConnected( i_mba, TYPE_DIMM ); return o_list; }
TargetHandleList getConnectedDimms( TargetHandle_t i_mba, const CenRank & i_rank ) { #define PRDF_FUNC "[CalloutUtil::getConnectedDimms] " TargetHandleList o_list; if ( TYPE_MBA != getTargetType(i_mba) ) { PRDF_ERR( PRDF_FUNC "Invalid target type: HUID=0x%08x", getHuid(i_mba) ); } else { TargetHandleList dimmList = getConnected( i_mba, TYPE_DIMM ); for ( TargetHandleList::iterator dimmIt = dimmList.begin(); dimmIt != dimmList.end(); dimmIt++) { uint8_t dimmSlct; int32_t l_rc = getMbaDimm( *dimmIt, dimmSlct ); if ( SUCCESS != l_rc ) { PRDF_ERR( PRDF_FUNC "getMbaDimm(0x%08x) failed", getHuid(*dimmIt) ); continue; } if ( dimmSlct == i_rank.getDimmSlct() ) { o_list.push_back( *dimmIt ); } } } return o_list; #undef PRDF_FUNC }
uint32_t ScomRegister::Write() { #define PRDF_FUNC "[ScomRegister::Write] " uint32_t o_rc = FAIL; do { // No write allowed if register access attribute is read-only or no // access. if ( ( ACCESS_NONE == iv_operationType ) && ( ACCESS_RO == iv_operationType ) ) { PRDF_ERR( PRDF_FUNC"Read-only register: 0x%08x 0x%016llx", getChip()->GetId(), iv_scomAddress ); break; } // Query the cache for an existing entry. if ( !queryCache() ) { // Something bad happened and there was nothing in the cache to // write to hardware. PRDF_ERR( PRDF_FUNC"No entry found in cache: 0x%08x 0x%016llx", getChip()->GetId(), iv_scomAddress ); break; } // Write hardware. o_rc = Access( readCache(), MopRegisterAccess::WRITE ); } while (0); return o_rc; #undef PRDF_FUNC }
/** * @brief Plugin to send a SKIP_MBA message for Memory Diagnositics. * @note Does nothing in non-MDIA mode. * @note Will stop any maintenance commands in progress. * @param i_mbaChip A Centaur MBA chip. * @param i_sc The step code data struct. * @return SUCCESS. */ int32_t SkipMbaMsg( ExtensibleChip * i_mbaChip, STEP_CODE_DATA_STRUCT & i_sc ) { #define PRDF_FUNC "[Mba::SkipMbaMsg] " int32_t l_rc = SUCCESS; TargetHandle_t mbaTrgt = i_mbaChip->GetChipHandle(); l_rc = mdiaSendEventMsg( mbaTrgt, MDIA::SKIP_MBA ); if ( SUCCESS != l_rc ) { PRDF_ERR( PRDF_FUNC"mdiaSendEventMsg(0x%08x, SKIP_MBA) failed", getHuid(mbaTrgt) ); // Keep going. } return SUCCESS; // Intentionally return SUCCESS for this plugin #undef PRDF_FUNC }
int32_t mssRestoreDramRepairs( TargetHandle_t i_mbaTarget, uint8_t & o_repairedRankMask, uint8_t & o_badDimmMask ) { int32_t o_rc = SUCCESS; errlHndl_t errl = NULL; PRD_FAPI_TO_ERRL( errl, mss_restore_DRAM_repairs, fapi::Target(fapi::TARGET_TYPE_MBA_CHIPLET, i_mbaTarget), o_repairedRankMask, o_badDimmMask ); if ( NULL != errl ) { PRDF_ERR( "[PlatServices::mssRestoreDramRepairs] " "mss_restore_dram_repairs() failed. HUID: 0x%08x", getHuid(i_mbaTarget) ); PRDF_COMMIT_ERRL( errl, ERRL_ACTION_REPORT ); o_rc = FAIL; } return o_rc; }
int32_t isPllUnlockCausedByPciOscFo( ExtensibleChip * i_chip, uint32_t i_activeOscPos, bool & o_pciOscSwitchCausedPllError ) { #define PRDF_FUNC "Proc::isPllUnlockCausedByPciOscFo " int32_t o_rc = SUCCESS; o_pciOscSwitchCausedPllError = false; #ifndef __HOSTBOOT_MODULE do { uint32_t u32Data = 0; o_rc = getCfam( i_chip, 0x00002819, u32Data ); if( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "PCI Status register Read failed 0x%08x", i_chip->GetId() ); break; } uint32_t pciOscMask = ( 0 == i_activeOscPos ) ? 0x00000C00 : 0x00000300; if( !(u32Data & pciOscMask) ) { // PLL unlock error has occurred due to problem in secondary or // backup pci osc. o_pciOscSwitchCausedPllError = true; } }while(0); #endif #undef PRDF_FUNC return o_rc; }
errlHndl_t main( ATTENTION_VALUE_TYPE i_attentionType, const AttnList & i_attnList ) { PRDF_ENTER( "PRDF::main() Global attnType=%04X", i_attentionType ); // These have to be outside of system scope lock errlHndl_t retErrl = NULL; bool initiateHwudump = false; TARGETING::TargetHandle_t dumpTrgt = NULL; errlHndl_t dumpErrl = NULL; uint32_t dumpErrlActions = 0; { // system scope lock starts ------------------------------------------ // will unlock when going out of scope PRDF_SYSTEM_SCOPELOCK; g_prd_errlHndl = NULL; uint32_t rc = SUCCESS; // clears all the chips saved to stack during last analysis ServiceDataCollector::clearChipStack(); if(( g_initialized == false)&&(NULL ==systemPtr)) { g_prd_errlHndl = noLock_initialize(); if(g_prd_errlHndl != NULL) rc = PRD_NOT_INITIALIZED; } ServiceDataCollector serviceData; STEP_CODE_DATA_STRUCT sdc; sdc.service_data = &serviceData; SYSTEM_DEBUG_CLASS sysdebug; sysdebug.Reinitialize(i_attnList); //Refresh sysdebug with latest Attn data //////////////////////////////////////////////////////////////////////////// // Normalize global attn type (ie 11,12,13,....) to (CHECKSTOP, RECOVERED, // SPECIAL..) //////////////////////////////////////////////////////////////////////////// if ( i_attentionType == INVALID_ATTENTION_TYPE || i_attentionType >= END_ATTENTION_TYPE ) { rc = PRD_INVALID_ATTENTION_TYPE; PRDF_ERR( "PrdMain: Invalid attention type! Global:%x", i_attentionType ); i_attentionType = RECOVERABLE; // This will prevent RAS service problems } // link to the right service Generator ServiceGeneratorClass & serviceGenerator = ServiceGeneratorClass::ThisServiceGenerator(); // Initialize the SDC error log. Required for GenerateSrcPfa() call below. serviceGenerator.createInitialErrl( i_attentionType ); // check for something wrong if ( g_initialized == false || rc != SUCCESS || systemPtr == NULL ) { if(rc == SUCCESS) { rc = PRD_NOT_INITIALIZED; } PRDF_ERR("PrdMain: PRD failed. RC=%x",rc ); // we are not going to do an analysis - so fill out the Service Data (serviceData.GetErrorSignature())->setSigId(rc); serviceData.SetCallout(SP_CODE); serviceData.SetCallout( NextLevelSupport_ENUM, MRU_LOW ); serviceData.SetThresholdMaskId(0); // Sets AT_THRESHOLD, DEGRADED, // SERVICE_CALL } else // do the analysis { // flush Cache so that SCR reads access hardware RegDataCache::getCachedRegisters().flush(); serviceData.setPrimaryAttnType(i_attentionType); // Set the time in which PRD handled the error. Timer timeOfError; PlatServices::getCurrentTime( timeOfError ); serviceData.SetTOE( timeOfError ); ServiceDataCollector l_tempSdc = serviceData; l_tempSdc.setPrimaryPass(); sdc.service_data = &l_tempSdc; int32_t analyzeRc = systemPtr->Analyze( sdc, i_attentionType ); if( PRD_SCAN_COMM_REGISTER_ZERO == analyzeRc ) { // So, the first pass has failed. Hence, there are no primary // bits set. We must start second pass to see if there are any //secondary bits set. sdc.service_data = &serviceData; #if !defined(__HOSTBOOT_MODULE) && !defined(__HOSTBOOT_RUNTIME) ForceSyncAnalysis( l_tempSdc ); // save SDC till end of primary pass #endif // starting the second pass PRDF_INF( "PRDF::main() No bits found set in first pass," " starting second pass" ); sysdebug.initAttnPendingtatus( ); //for the second pass if( l_tempSdc.isSecondaryErrFound() ) { sdc.service_data->setSecondaryErrFlag(); } analyzeRc = systemPtr->Analyze( sdc, i_attentionType ); // merging capture data of primary pass with capture data of // secondary pass for better FFDC. serviceData.GetCaptureData().mergeData( l_tempSdc.GetCaptureData()); #if !defined(__HOSTBOOT_MODULE) && !defined(__HOSTBOOT_RUNTIME) // save SDC till end of secondary pass ForceSyncAnalysis( serviceData ); #endif } else { serviceData = l_tempSdc; sdc.service_data = &serviceData; } // flush Cache to free up the memory RegDataCache::getCachedRegisters().flush(); ScanFacility & l_scanFac = ScanFacility::Access(); //delete all the wrapper register objects since these were created //just for plugin code l_scanFac.ResetPluginRegister(); if(analyzeRc != SUCCESS && g_prd_errlHndl == NULL) { (serviceData.GetErrorSignature())->setErrCode( (uint16_t)analyzeRc ); serviceData.SetCallout(SP_CODE); serviceData.SetCallout( NextLevelSupport_ENUM, MRU_LOW ); serviceData.SetServiceCall(); // We don't want to gard unless we have a good // return code serviceData.Gard(GardAction::NoGard); } } if(g_prd_errlHndl != NULL) { PRDF_INF("PRDTRACE: PrdMain: g_prd_errlHndl != NULL"); PRDF_ADD_PROCEDURE_CALLOUT( g_prd_errlHndl, SRCI_PRIORITY_MED, EPUB_PRC_SP_CODE ); // This is a precautionary step. There is a possibilty that if // severity for g_prd_errlHndl is Predictve and there is only // EPUB_PRC_SP_CODE callout than it will be changed to tracing event. // So adding EPUB_PRC_LVL_SUPP to avoid this. PRDF_ADD_PROCEDURE_CALLOUT( g_prd_errlHndl, SRCI_PRIORITY_LOW, EPUB_PRC_LVL_SUPP ); // This forces any previous errls to be committed g_prd_errlHndl = NULL; // pw 597903 -- Don't GARD if we got a global error. serviceData.Gard(GardAction::NoGard); } g_prd_errlHndl = serviceGenerator.GenerateSrcPfa( i_attentionType, serviceData, initiateHwudump, dumpTrgt, dumpErrl, dumpErrlActions); // Sleep for 20msec to let attention lines settle if we are at threshold. if ( (g_prd_errlHndl == NULL) && serviceData.IsAtThreshold() ) { PlatServices::milliSleep( 0, 20 ); } retErrl = g_prd_errlHndl.release(); } // system scope lock ends ------------------------------------------ if ( true == initiateHwudump ) { PlatServices::initiateUnitDump( dumpTrgt, dumpErrl, dumpErrlActions ); } PRDF_EXIT( "PRDF::main()" ); return retErrl; }
int32_t cleanupSecondaryFirBits( ExtensibleChip * i_chip, TYPE i_busType, uint32_t i_busPos ) { int32_t l_rc = SUCCESS; TargetHandle_t mcsTgt = NULL; TargetHandle_t mbTgt = NULL; ExtensibleChip * mcsChip = NULL; ExtensibleChip * mbChip = NULL; //In case of spare deployed attention for DMI bus, we need to clear // secondary MBIFIR[10] and MCIFIR[10] bits. do { if ( i_busType == TYPE_MCS ) { mcsTgt = getConnectedChild( i_chip->GetChipHandle(), TYPE_MCS, i_busPos); if (!mcsTgt) break; mcsChip = ( ExtensibleChip * )systemPtr->GetChip( mcsTgt ); if (!mcsChip) break; mbChip = getMcsDataBundle( mcsChip )->getMembChip(); if (!mbChip) break; mbTgt = mbChip->GetChipHandle(); if (!mbTgt) break; } else if ( i_busType == TYPE_MEMBUF ) { mbTgt = i_chip->GetChipHandle(); if (!mbTgt) break; mcsChip = getMembufDataBundle( i_chip )->getMcsChip(); if (!mcsChip) break; mcsTgt = mcsChip->GetChipHandle(); if (!mcsTgt) break; mbChip = i_chip; } else { // We only need to clean secondary FIR bits for DMI bus l_rc = SUCCESS; break; } SCAN_COMM_REGISTER_CLASS * mciAnd = mcsChip->getRegister("MCIFIR_AND"); SCAN_COMM_REGISTER_CLASS * mbiAnd = mbChip->getRegister( "MBIFIR_AND"); mciAnd->setAllBits(); mciAnd->ClearBit(10); mbiAnd->setAllBits(); mbiAnd->ClearBit(10); l_rc = mciAnd->Write(); l_rc |= mbiAnd->Write(); if ( SUCCESS != l_rc ) { PRDF_ERR( "[cleanupSecondaryFirBits] Write() failed on " "MCIFIR/MBIFIR: MCS=0x%08x MEMB=0x%08x", mcsChip->GetId(), mbChip->GetId() ); break; } } while (0); return l_rc; }
/** * @brief calling out active pcie osc connected to this proc * @param i_chip P8 chip * @param i_sc service data collector * @returns Success */ int32_t CalloutPllIo( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & io_sc ) { #define PRDF_FUNC "[Proc::CalloutPllIo] " int32_t rc = SUCCESS; do { uint32_t oscPos = getIoOscPos( i_chip, io_sc ); bool pllUnlockDuetoOscSwitch; rc = isPllUnlockCausedByPciOscFo( i_chip, oscPos, pllUnlockDuetoOscSwitch ); if( SUCCESS != rc ) { PRDF_ERR( PRDF_FUNC "PCI Osc switch analysis failed" ); break; } if( pllUnlockDuetoOscSwitch ) { // PLL unlock has occurred due to PCI OSC switchover. We can ignore // this error. It shall be handled seprately as PC OSC switchover // event. break; } // oscPos will be checked inside getClockId and in case // a connected osc is not found, will use the proc target // this is the hostboot path since it's used the proc // target and clock type. TargetHandle_t connectedOsc = getClockId( i_chip->GetChipHandle(), TYPE_OSCPCICLK, oscPos ); if ( NULL == connectedOsc ) { PRDF_ERR(PRDF_FUNC "Failed to get connected PCIe OSC for " "chip 0x%08x, oscPos: %d",i_chip->GetId(), oscPos ); connectedOsc = i_chip->GetChipHandle(); } PRDF_DTRAC(PRDF_FUNC "PCIe OSC: 0x%08x connected to " "proc: 0x%08x", getHuid(connectedOsc), i_chip->GetId()); // callout the clock source // HB does not have the osc target modeled // so we need to use the proc target with // osc clock type to call out #ifndef __HOSTBOOT_MODULE io_sc.service_data->SetCallout(connectedOsc); #else io_sc.service_data->SetCallout( PRDcallout(connectedOsc, PRDcalloutData::TYPE_PCICLK)); #endif } while(0); return rc; #undef PRDF_FUNC }
/** * @brief Mask the PLL error for P8 Plugin * @param i_chip P8 chip * @param i_sc The step code data struct * @param i_oscPos active osc position * @returns Failure or Success of query. * @note */ int32_t MaskPllIo( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & i_sc, uint32_t i_oscPos ) { #define PRDF_FUNC "[Proc::MaskPllIo] " int32_t rc = SUCCESS; do { if (CHECK_STOP == i_sc.service_data->getPrimaryAttnType()) { break; } if ( i_oscPos >= MAX_PCIE_OSC_PER_NODE ) { PRDF_ERR(PRDF_FUNC "invalid oscPos: %d for chip: " "0x%08x", i_oscPos, i_chip->GetId()); rc = FAIL; break; } uint32_t oscPos = getIoOscPos( i_chip, i_sc ); if ( oscPos != i_oscPos ) { PRDF_DTRAC(PRDF_FUNC "skip masking for chip: 0x%08x, " "oscPos: %d, i_oscPos: %d", i_chip->GetId(), oscPos, i_oscPos); break; } // fence off pci osc error reg bit SCAN_COMM_REGISTER_CLASS * pciConfigReg = i_chip->getRegister("PCI_CONFIG_REG"); rc = pciConfigReg->Read(); if (rc != SUCCESS) { PRDF_ERR(PRDF_FUNC "PCI_CONFIG_REG read failed" "for 0x%08x", i_chip->GetId()); break; } if(!pciConfigReg->IsBitSet(PLL_ERROR_MASK)) { pciConfigReg->SetBit(PLL_ERROR_MASK); rc = pciConfigReg->Write(); if (rc != SUCCESS) { PRDF_ERR(PRDF_FUNC "PCI_CONFIG_REG write failed" "for chip: 0x%08x", i_chip->GetId()); } } // Since TP_LFIR bit is the collection of all of the // pll error reg bits, we can't mask it or we will not // see any PLL errors reported from the error regs } while(0); return rc; #undef PRDF_FUNC }
/** * @brief Clear the PLL error for P8 Plugin * @param i_chip P8 chip * @param i_sc The step code data struct * @returns Failure or Success of query. */ int32_t ClearPllIo( ExtensibleChip * i_chip, STEP_CODE_DATA_STRUCT & i_sc) { #define PRDF_FUNC "[Proc::ClearPllIo] " int32_t rc = SUCCESS; if (CHECK_STOP != i_sc.service_data->getPrimaryAttnType()) { // Clear pci osc error reg bit int32_t tmpRC = SUCCESS; SCAN_COMM_REGISTER_CLASS * pciErrReg = i_chip->getRegister("PCI_ERROR_REG"); tmpRC = pciErrReg->Read(); if (tmpRC != SUCCESS) { PRDF_ERR(PRDF_FUNC "PCI_ERROR_REG read failed" "for chip: 0x%08x", i_chip->GetId()); rc |= tmpRC; } if( pciErrReg->IsBitSet( PLL_ERROR_BIT ) ) { pciErrReg->clearAllBits(); pciErrReg->SetBit(PLL_ERROR_BIT); tmpRC = pciErrReg->Write(); if ( SUCCESS != tmpRC ) { PRDF_ERR( PRDF_FUNC "Write() failed on PCI Error register: " "proc=0x%08x", i_chip->GetId() ); rc |= tmpRC; } } // Clear TP_LFIR SCAN_COMM_REGISTER_CLASS * TP_LFIRand = i_chip->getRegister("TP_LFIR_AND"); TP_LFIRand->setAllBits(); TP_LFIRand->ClearBit(PLL_DETECT_P8); tmpRC = TP_LFIRand->Write(); if (tmpRC != SUCCESS) { PRDF_ERR(PRDF_FUNC "TP_LFIR_AND write failed" "for chip: 0x%08x", i_chip->GetId()); rc |= tmpRC; } SCAN_COMM_REGISTER_CLASS * oscCerrReg = i_chip->getRegister("OSCERR"); tmpRC = oscCerrReg->Read(); if (tmpRC != SUCCESS) { PRDF_ERR(PRDF_FUNC "OSCERR read failed" "for 0x%08x", i_chip->GetId()); rc |= tmpRC; } oscCerrReg->ClearBit(4); oscCerrReg->ClearBit(5); tmpRC = oscCerrReg->Write(); if (tmpRC != SUCCESS) { PRDF_ERR(PRDF_FUNC "oscCerrReg write failed" "for chip: 0x%08x", i_chip->GetId()); rc |= tmpRC; } } if( rc != SUCCESS ) { PRDF_ERR(PRDF_FUNC "failed for proc: 0x%.8X", i_chip->GetId()); } return rc; #undef PRDF_FUNC }
int32_t System::Analyze(STEP_CODE_DATA_STRUCT & serviceData, ATTENTION_TYPE attentionType) { #define PRDF_FUNC "[System::Analyze] " SYSTEM_DEBUG_CLASS sysdebug; Domain * domainAtAttentionPtr = NULL; ServiceDataCollector * l_saved_sdc = NULL; ServiceDataCollector * l_temp_sdc = NULL; int32_t rc = (prioritizedDomains.empty() ? NO_DOMAINS_IN_SYSTEM : SUCCESS); int32_t l_saved_rc = 0; int32_t l_primaryRc = 0; if(rc == SUCCESS) { // IF machine check then check for recoverable errors first // otherwise just check for the given type of attention ATTENTION_TYPE startAttention = attentionType; if((attentionType == MACHINE_CHECK) || (attentionType == UNIT_CS)) startAttention = RECOVERABLE; ATTENTION_TYPE atnType = startAttention; for( atnType = startAttention; domainAtAttentionPtr == NULL && atnType >= attentionType ; --atnType) { DomainContainerType::iterator domainIterator; for( domainIterator = prioritizedDomains.begin(); domainIterator != prioritizedDomains.end() && domainAtAttentionPtr == NULL; ) { bool l_continueInDomain = false; domainAtAttentionPtr = ((*domainIterator)->Query(atnType)) ? (*domainIterator) : NULL; if(domainAtAttentionPtr != NULL) { serviceData.service_data->SetCauseAttentionType(atnType); rc = domainAtAttentionPtr->Analyze(serviceData, atnType); if((rc == PRD_SCAN_COMM_REGISTER_ZERO) || (rc == PRD_POWER_FAULT) ) { // save sdc, and continue if(l_saved_sdc == NULL) { l_saved_sdc = new ServiceDataCollector( *serviceData.service_data); l_saved_rc = rc; } if( ( PRD_SCAN_COMM_REGISTER_ZERO == rc ) && ( serviceData.service_data->isPrimaryPass() ) && serviceData.service_data->isSecondaryErrFound() ) { //So, the chip was reporting attention but none of //the FIR read had any Primary bit set. But some //secondary bits are on though. So, we would like //to investigate if there are other chips in //the domain which are reporting primary attention. l_continueInDomain = true; serviceData.service_data->clearSecondaryErrFlag(); } domainAtAttentionPtr = NULL; if(rc == PRD_POWER_FAULT) { PRDF_ERR( PRDF_FUNC"Power Fault detected!" ); break; } } else if ( ( attentionType == MACHINE_CHECK ) && ( atnType != MACHINE_CHECK ) ) { // We were asked to analyze MACHINE XTOP, but we found // another attention and did analyze that. In this case // we want to add additional signature of MACHINE XSTOP // attention to error log. // l_temp_sdc is not NULL. It is a code bug. Do not do // anything for error isolation pass. if ( NULL != l_temp_sdc ) { PRDF_ERR( PRDF_FUNC"l_temp_sdc is not NULL" ); continue; } // Do a setup for error isolation pass for MACHINE // XTOP. In this pass, we are only interested in // error signature. domainAtAttentionPtr = NULL; l_temp_sdc = new ServiceDataCollector ( *serviceData.service_data ); // Set up Error Isolation Pass Flag. serviceData.service_data->setIsolationOnlyPass(); // Set the outer for loop iteration variable atnType so // that we analyze MACHINE XSTOP in next iteration. atnType = MACHINE_CHECK + 1; // save primary rc. l_primaryRc = rc; break; } } // end domainAtAttentionPtr != NULL //so if a chip of a domain is at attention and gave us dd02, we //would like to see other chips of the domain before moving on //to next domain. if( !l_continueInDomain ) { domainIterator++; } } // end inner for loop } // end outer for loop // if ptr is NULL && we don't have a saved SDC than we have noAttns // if ptr is NULL && we have a saved SDC then we have an attn with no-bits-on // otherwise we are done - aready did the analysis if ( domainAtAttentionPtr == NULL) { if(l_saved_sdc == NULL) { rc = noAttnResolution.Resolve(serviceData); } else { *serviceData.service_data = *l_saved_sdc; sysdebug.CalloutThoseAtAttention(serviceData); rc = l_saved_rc; } } // l_temp_sdc will not be NULL if we go to ERROR ISOLATION ONLY PASS. // In that case get the secondary signature and update this. if ( NULL != l_temp_sdc ) { // Merge SUE flag if( serviceData.service_data->IsSUE() ) { l_temp_sdc->SetSUE(); } // We are having only one secondary signature. Secondary signature // here is mainly used for XSTOP error. XSTOP error can only happen // on Fabric domain. For fabric domain, we use Fabric sorting which // will give us first chip which is root cause for the XSTOP error. // So signature we get after fabric sorting is enough for FFDC // perspective. l_temp_sdc->AddSignatureList( *( serviceData.service_data->GetErrorSignature() )); // merge debug scom data from the two analysis l_temp_sdc->GetCaptureData().mergeData( serviceData.service_data->GetCaptureData()); // merge trace array data from the two analysis l_temp_sdc->getTraceArrayData().mergeData( serviceData.service_data->getTraceArrayData()); *serviceData.service_data = *l_temp_sdc; delete l_temp_sdc; // We will discard any error we get in ERROR ISOLATION ONLY PASS, // and restore rc found in primary pass. rc = l_primaryRc; } if(l_saved_sdc != NULL) delete l_saved_sdc; //dg05a } #undef PRDF_FUNC return(rc); }
int32_t calloutBusInterface( TargetHandle_t i_rxTrgt, TargetHandle_t i_txTrgt, PRDpriority i_priority ) { #define PRDF_FUNC "[CalloutUtil::calloutBusInterface] " int32_t rc = SUCCESS; do { // Check for valid targets. if ( NULL == i_rxTrgt || NULL == i_txTrgt ) { PRDF_ERR( PRDF_FUNC "Given target(s) are NULL" ); rc = FAIL; break; } // Get the HWAS bus type. HWAS::busTypeEnum hwasType; TYPE rxType = getTargetType(i_rxTrgt); TYPE txType = getTargetType(i_txTrgt); if ( TYPE_ABUS == rxType && TYPE_ABUS == txType ) { hwasType = HWAS::A_BUS_TYPE; } else if ( TYPE_XBUS == rxType && TYPE_XBUS == txType ) { hwasType = HWAS::X_BUS_TYPE; } else if ( (TYPE_MCS == rxType && TYPE_MEMBUF == txType) || (TYPE_MEMBUF == rxType && TYPE_MCS == txType) ) { hwasType = HWAS::DMI_BUS_TYPE; } else { PRDF_ERR( PRDF_FUNC "Unsupported target types" ); rc = FAIL; break; } // Get the global error log. errlHndl_t errl = NULL; errl = ServiceGeneratorClass::ThisServiceGenerator().getErrl(); if ( NULL == errl ) { PRDF_ERR( PRDF_FUNC "Failed to get the global error log" ); rc = FAIL; break; } // Callout this bus interface. PRDF_ADD_BUS_CALLOUT( errl, i_rxTrgt, i_txTrgt, hwasType, i_priority ); } while(0); if ( SUCCESS != rc ) { PRDF_ERR( PRDF_FUNC "i_rxTrgt:0x%08x i_txTrgt:0x%08x i_priority:%d", getHuid(i_rxTrgt), getHuid(i_txTrgt), i_priority ); } return rc; #undef PRDF_FUNC }
errlHndl_t main( ATTENTION_VALUE_TYPE i_attentionType, const AttnList & i_attnList ) { PRDF_ENTER( "PRDF::main() Global attnType=%04X", i_attentionType ); // will unlock when going out of scope PRDF_SYSTEM_SCOPELOCK; g_prd_errlHndl = NULL; uint32_t rc = SUCCESS; // clears all the chips saved to stack during last analysis ServiceDataCollector::clearChipStack(); if(( g_initialized == false)&&(NULL ==systemPtr)) { g_prd_errlHndl = noLock_initialize(); if(g_prd_errlHndl != NULL) rc = PRD_NOT_INITIALIZED; } ServiceDataCollector serviceData; STEP_CODE_DATA_STRUCT sdc; sdc.service_data = &serviceData; SYSTEM_DEBUG_CLASS sysdebug; sysdebug.Reinitialize(i_attnList); //Refresh sysdebug with latest Attn data //////////////////////////////////////////////////////////////////////////// // Normalize global attn type (ie 11,12,13,....) to (CHECKSTOP, RECOVERED, // SPECIAL..) //////////////////////////////////////////////////////////////////////////// if ( i_attentionType == INVALID_ATTENTION_TYPE || i_attentionType >= END_ATTENTION_TYPE ) { rc = PRD_INVALID_ATTENTION_TYPE; PRDF_ERR( "PrdMain: Invalid attention type! Global:%x", i_attentionType ); i_attentionType = RECOVERABLE; // This will prevent RAS service problems } // link to the right service Generator ServiceGeneratorClass & serviceGenerator = ServiceGeneratorClass::ThisServiceGenerator(); // Initialize the SDC error log. Required for GenerateSrcPfa() call below. serviceGenerator.createInitialErrl( i_attentionType ); // check for something wrong if ( g_initialized == false || rc != SUCCESS || systemPtr == NULL ) { if(rc == SUCCESS) { rc = PRD_NOT_INITIALIZED; } PRDF_ERR("PrdMain: PRD failed. RC=%x",rc ); // we are not going to do an analysis - so fill out the Service Data (serviceData.GetErrorSignature())->setSigId(rc); serviceData.SetCallout(SP_CODE); serviceData.SetThresholdMaskId(0); // Sets AT_THRESHOLD, DEGRADED, // SERVICE_CALL } else // do the analysis { // flush Cache so that SCR reads access hardware RegDataCache::getCachedRegisters().flush(); serviceData.SetAttentionType(i_attentionType); // capture time of day serviceGenerator.SetErrorTod( i_attentionType, serviceData ); if(serviceGenerator.QueryLoggingBufferFull()) { serviceData.SetFlooding(); } int32_t analyzeRc = systemPtr->Analyze(sdc, i_attentionType); // flush Cache to free up the memory RegDataCache::getCachedRegisters().flush(); ScanFacility & l_scanFac = ScanFacility::Access(); //delete all the wrapper register objects since these were created //just for plugin code l_scanFac.ResetPluginRegister(); SystemSpecific::postAnalysisWorkarounds(sdc); if(analyzeRc != SUCCESS && g_prd_errlHndl == NULL) { // We have a bad RC, but no error log - Fill out SDC and have // service generator make one (serviceData.GetErrorSignature())->setErrCode( (uint16_t)analyzeRc ); serviceData.SetCallout(SP_CODE); serviceData.SetServiceCall(); // We don't want to gard unless we have a good // return code serviceData.Gard(GardAction::NoGard); } } if(g_prd_errlHndl != NULL) { PRDF_INF("PRDTRACE: PrdMain: g_prd_errlHndl != NULL"); PRDF_ADD_PROCEDURE_CALLOUT( g_prd_errlHndl, SRCI_PRIORITY_MED, EPUB_PRC_SP_CODE ); // This forces any previous errls to be committed g_prd_errlHndl = NULL; // pw 597903 -- Don't GARD if we got a global error. serviceData.Gard(GardAction::NoGard); } g_prd_errlHndl = serviceGenerator.GenerateSrcPfa( i_attentionType, serviceData ); // Sleep for 20msec to let attention lines settle if we are at threshold. if ( (g_prd_errlHndl == NULL) && serviceData.IsAtThreshold() ) { PlatServices::milliSleep( 0, 20 ); } RasServices::SetTerminateOnCheckstop(true); PRDF_EXIT( "PRDF::main()" ); return(g_prd_errlHndl.release()); }
int32_t handleLaneRepairEvent( ExtensibleChip * i_chip, TYPE i_busType, uint32_t i_busPos, STEP_CODE_DATA_STRUCT & i_sc, bool i_spareDeployed ) { #define PRDF_FUNC "[LaneRepair::handleLaneRepairEvent] " int32_t l_rc = SUCCESS; TargetHandle_t rxBusTgt = NULL; TargetHandle_t txBusTgt = NULL; bool thrExceeded = true; std::vector<uint8_t> rx_lanes; std::vector<uint8_t> rx_vpdLanes; std::vector<uint8_t> tx_vpdLanes; BitStringBuffer l_vpdLaneMap0to63(64); BitStringBuffer l_vpdLaneMap64to127(64); BitStringBuffer l_newLaneMap0to63(64); BitStringBuffer l_newLaneMap64to127(64); do { #ifdef __HOSTBOOT_MODULE if ( CHECK_STOP == i_sc.service_data->GetAttentionType() ) { // This would only happen on OpenPOWER machines when we are doing // the post IPL analysis. In this case, we do not have the FFDC to // query the IO registers so simply set service call and skip // everything else. i_sc.service_data->SetServiceCall(); return SUCCESS; } #endif // Get the RX and TX targets. l_rc = CalloutUtil::getBusEndpoints( i_chip, rxBusTgt, txBusTgt, i_busType, i_busPos ); if ( SUCCESS != l_rc ) { PRDF_ERR( PRDF_FUNC "getBusEndpoints() failed" ); break; } // Call io_read_erepair l_rc = readErepair(rxBusTgt, rx_lanes); if (SUCCESS != l_rc) { PRDF_ERR( PRDF_FUNC "readErepair() failed: rxBusTgt=0x%08x", getHuid(rxBusTgt) ); break; } // Add newly failed lanes to capture data for (std::vector<uint8_t>::iterator lane = rx_lanes.begin(); lane != rx_lanes.end(); ++lane) { PRDF_INF( PRDF_FUNC "New failed lane on RX HUID 0x%08x: %d", getHuid(rxBusTgt), *lane); if (*lane < 64) l_newLaneMap0to63.Set(*lane); else if (*lane < 127) l_newLaneMap64to127.Set(*lane - 64); else { PRDF_ERR( PRDF_FUNC "Invalid lane number %d: rxBusTgt=0x%08x", *lane, getHuid(rxBusTgt) ); l_rc = FAIL; break; } } if ( SUCCESS != l_rc ) break; // Add failed lane capture data to errorlog i_sc.service_data->GetCaptureData().Add(i_chip->GetChipHandle(), ( Util::hashString("ALL_FAILED_LANES_0TO63") ^ i_chip->getSignatureOffset() ), l_newLaneMap0to63); i_sc.service_data->GetCaptureData().Add(i_chip->GetChipHandle(), ( Util::hashString("ALL_FAILED_LANES_64TO127") ^ i_chip->getSignatureOffset() ), l_newLaneMap64to127); if (!mfgMode()) // Don't read/write VPD in mfg mode { // Read Failed Lanes from VPD l_rc = getVpdFailedLanes(rxBusTgt, rx_vpdLanes, tx_vpdLanes); if (SUCCESS != l_rc) { PRDF_ERR( PRDF_FUNC "getVpdFailedLanes() failed: " "rxBusTgt=0x%08x", getHuid(rxBusTgt) ); break; } // Add VPD lanes to capture data for (std::vector<uint8_t>::iterator lane = rx_vpdLanes.begin(); lane != rx_vpdLanes.end(); ++lane) { if (*lane < 64) l_vpdLaneMap0to63.Set(*lane); else if (*lane < 127) l_vpdLaneMap64to127.Set(*lane - 64); else { PRDF_ERR( PRDF_FUNC "Invalid VPD lane number %d: " "rxBusTgt=0x%08x", *lane, getHuid(rxBusTgt) ); l_rc = FAIL; break; } } if ( SUCCESS != l_rc ) break; // Add failed lane capture data to errorlog i_sc.service_data->GetCaptureData().Add(i_chip->GetChipHandle(), ( Util::hashString("VPD_FAILED_LANES_0TO63") ^ i_chip->getSignatureOffset() ), l_vpdLaneMap0to63); i_sc.service_data->GetCaptureData().Add(i_chip->GetChipHandle(), ( Util::hashString("VPD_FAILED_LANES_64TO127") ^ i_chip->getSignatureOffset() ), l_vpdLaneMap64to127); if (i_spareDeployed) { // Call Erepair to update VPD l_rc = setVpdFailedLanes(rxBusTgt, txBusTgt, rx_lanes, thrExceeded); if (SUCCESS != l_rc) { PRDF_ERR( PRDF_FUNC "setVpdFailedLanes() failed: " "rxBusTgt=0x%08x txBusTgt=0x%08x", getHuid(rxBusTgt), getHuid(txBusTgt) ); break; } if( thrExceeded ) { i_sc.service_data->SetErrorSig( PRDFSIG_ERepair_FWThrExceeded ); } } } if (i_spareDeployed && !thrExceeded) { // Update lists of lanes from VPD rx_vpdLanes.clear(); tx_vpdLanes.clear(); l_rc = getVpdFailedLanes(rxBusTgt, rx_vpdLanes, tx_vpdLanes); if (SUCCESS != l_rc) { PRDF_ERR( PRDF_FUNC "getVpdFailedLanes() before power down " "failed: rxBusTgt=0x%08x", getHuid(rxBusTgt) ); break; } // Power down all lanes that have been saved in VPD l_rc = powerDownLanes(rxBusTgt, rx_vpdLanes, tx_vpdLanes); if (SUCCESS != l_rc) { PRDF_ERR( PRDF_FUNC "powerDownLanes() failed: rxBusTgt=0x%08x", getHuid(rxBusTgt) ); break; } } else { // Make predictive i_sc.service_data->SetServiceCall(); } } while (0); // Clear FIRs if (rxBusTgt) { l_rc |= erepairFirIsolation(rxBusTgt); l_rc |= clearIOFirs(rxBusTgt); } if ( i_spareDeployed ) { l_rc |= cleanupSecondaryFirBits( i_chip, i_busType, i_busPos ); } // This return code gets returned by the plugin code back to the rule code. // So, we do not want to give a return code that the rule code does not // understand. So far, there is no need return a special code, so always // return SUCCESS. if ( SUCCESS != l_rc ) { PRDF_ERR( PRDF_FUNC "i_chip: 0x%08x i_busType:%d i_busPos:%d", i_chip->GetId(), i_busType, i_busPos ); i_sc.service_data->SetErrorSig( PRDFSIG_ERepair_ERROR ); CalloutUtil::defaultError( i_sc ); } return SUCCESS; #undef PRDF_FUNC }
errlHndl_t noLock_initialize() { #define PRDF_FUNC "PRDF::noLock_initialize() " PRDF_ENTER( PRDF_FUNC ); g_prd_errlHndl = NULL; // This forces any previous errls to be committed // Synchronize SCOM access to hardware // Start un-synchronized so hardware is accessed RegDataCache::getCachedRegisters().flush(); if(g_initialized == true && systemPtr != NULL) { // This means we are being re-initialized (and we were in a good state) // so Clean up in preparation for re-build unInitialize(); } if(g_initialized == false) { // Initialize the Service Generator ServiceGeneratorClass & serviceGenerator = ServiceGeneratorClass::ThisServiceGenerator(); serviceGenerator.Initialize(); // Perform platform specific initialization. initPlatSpecific(); CcAutoDeletePointer<Configurator> configuratorPtr (SystemSpecific::getConfiguratorPtr()); errlHndl_t l_errBuild = configuratorPtr->build();//build object model if( NULL != l_errBuild ) { //there is some problem in building RuleMetaData object g_prd_errlHndl = l_errBuild; //object model is either not build or at best incomplete.We must // clean this up .The easiest way is to delete the system which in //in turn shall clean up the constituents. delete systemPtr; systemPtr = NULL; g_initialized = false; PRDF_ERR(PRDF_FUNC"failed to buid object model"); } //systemPtr is populated in configurator else if( systemPtr != NULL ) { systemPtr->Initialize(); // Hardware initialization g_initialized = true; } // Flush rule table cache since objects are all built. Prdr::LoadChipCache::flushCache(); } PRDF_EXIT( PRDF_FUNC ); return (g_prd_errlHndl.release()); #undef PRDF_FUNC }