void calloutMark( TargetHandle_t i_mba, const CenRank & i_rank, const CenMark & i_mark, STEP_CODE_DATA_STRUCT & io_sc, PRDpriority i_priority ) { if ( i_mark.getCM().isValid() ) { MemoryMru memmru ( i_mba, i_rank, i_mark.getCM() ); io_sc.service_data->SetCallout( memmru, i_priority ); } if ( i_mark.getSM().isValid() ) { MemoryMru memmru ( i_mba, i_rank, i_mark.getSM() ); io_sc.service_data->SetCallout( memmru, i_priority ); } }
void captureDramRepairsData( TARGETING::TargetHandle_t i_mbaTrgt, CaptureData & io_cd ) { #define PRDF_FUNC "[CenMbaCaptureData::captureDramRepairsData] " using namespace fapi; // for spare config int32_t rc = SUCCESS; DramRepairMbaData mbaData; mbaData.header.isSpareDram = false; std::vector<CenRank> masterRanks; do { rc = getMasterRanks( i_mbaTrgt, masterRanks ); if ( SUCCESS != rc ) { PRDF_ERR( PRDF_FUNC "getMasterRanks() failed" ); break; } if( masterRanks.empty() ) { PRDF_ERR( PRDF_FUNC "Master Rank list size is 0"); break;; } uint8_t spareConfig = ENUM_ATTR_VPD_DIMM_SPARE_NO_SPARE; // check for spare DRAM. Port does not matter. // Also this configuration is same for all ranks on MBA. rc = getDimmSpareConfig( i_mbaTrgt, masterRanks[0], 0, spareConfig ); if( SUCCESS != rc ) { PRDF_ERR( PRDF_FUNC "getDimmSpareConfig() failed" ); break; } if( ENUM_ATTR_VPD_DIMM_SPARE_NO_SPARE != spareConfig ) mbaData.header.isSpareDram = true; // Iterate all ranks to get DRAM repair data for ( std::vector<CenRank>::iterator it = masterRanks.begin(); it != masterRanks.end(); it++ ) { // Get chip/symbol marks CenMark mark; rc = mssGetMarkStore( i_mbaTrgt, *it, mark ); if ( SUCCESS != rc ) { PRDF_ERR( PRDF_FUNC "mssGetMarkStore() Failed"); continue; } // Get DRAM spares CenSymbol sp0, sp1, ecc; rc = mssGetSteerMux( i_mbaTrgt, *it, sp0, sp1, ecc ); if ( SUCCESS != rc ) { PRDF_ERR( PRDF_FUNC "mssGetSteerMux() failed"); continue; } // Add data DramRepairRankData rankData = { (*it).getMaster(), mark.getCM().getSymbol(), mark.getSM().getSymbol(), sp0.getSymbol(), sp1.getSymbol(), ecc.getSymbol() }; if ( rankData.valid() ) { mbaData.rankDataList.push_back(rankData); } } // If MBA had some DRAM repair data, add header information if( mbaData.rankDataList.size() > 0 ) { mbaData.header.rankCount = mbaData.rankDataList.size(); mbaData.header.isX4Dram = isDramWidthX4( i_mbaTrgt ); UtilMem dramStream; dramStream << mbaData; #ifndef PPC // Fix endianness issues with non PPC machines. // This is a workaround. Though UtilMem takes care of endianness, // It seems with capture data its not working const size_t sz_word = sizeof(uint32_t); // Align data with 32 bit boundary for (uint32_t i = 0; i < ( dramStream.size()%sz_word ); i++) { uint8_t dummy = 0; dramStream << dummy; } for ( uint32_t i = 0; i < ( dramStream.size()/sz_word); i++ ) { ((uint32_t*)dramStream.base())[i] = htonl(((uint32_t*)dramStream.base())[i]); } #endif // Allocate space for the capture data. BIT_STRING_ADDRESS_CLASS dramRepairData ( 0,( dramStream.size() )*8, (CPU_WORD *) dramStream.base() ); io_cd.Add( i_mbaTrgt, Util::hashString("DRAM_REPAIRS_DATA"), dramRepairData ); } }while(0); if( FAIL == rc ) PRDF_ERR( PRDF_FUNC "Failed for MBA 0x%08X", getHuid( i_mbaTrgt ) ); #undef PRDF_FUNC }
/** * @brief MBSECCFIR[0:7] - Fetch Mark Placed Event (MPE). * @param i_membChip A Centaur chip. * @param i_sc The step code data struct. * @param i_mbaPos The MBA position. * @param i_rank The target rank. * @return SUCCESS */ int32_t AnalyzeFetchMpe( ExtensibleChip * i_membChip, STEP_CODE_DATA_STRUCT & i_sc, uint32_t i_mbaPos, uint8_t i_rank ) { #define PRDF_FUNC "[AnalyzeFetchMpe] " int32_t l_rc = SUCCESS; ExtensibleChip * mbaChip = NULL; do { CenMembufDataBundle * membdb = getMembufDataBundle( i_membChip ); mbaChip = membdb->getMbaChip( i_mbaPos ); if ( NULL == mbaChip ) { PRDF_ERR( PRDF_FUNC"getMbaChip() returned NULL" ); l_rc = FAIL; break; } CenMbaDataBundle * mbadb = getMbaDataBundle( mbaChip ); TargetHandle_t mbaTrgt = mbaChip->GetChipHandle(); CenAddr addr; l_rc = getCenReadAddr( i_membChip, i_mbaPos, READ_MPE_ADDR, addr ); if ( SUCCESS != l_rc ) { PRDF_ERR( PRDF_FUNC"getCenReadAddr() failed" ); break; } // If the address does not match the rank that reported the attention, // there are multiple MPE attentions and the address was overwritten. // In this case, add an invalid dummy address to the UE table. if ( addr.getRank().getMaster() != i_rank ) { addr = CenAddr( i_rank, 0, 0xffffffff, 0xffffffff, 0xffffffff ); } mbadb->iv_ueTable.addEntry( UE_TABLE::FETCH_MPE, addr ); // Get the current mark in hardware. CenRank rank ( addr.getRank() ); CenMark mark; l_rc = mssGetMarkStore( mbaTrgt, rank, mark ); if ( SUCCESS != l_rc ) { PRDF_ERR( PRDF_FUNC"mssGetMarkStore() failed"); break; } if ( !mark.getCM().isValid() ) { PRDF_ERR( PRDF_FUNC"FIR bit set but no valid chip mark" ); l_rc = FAIL; break; } // Callout the mark. CalloutUtil::calloutMark( mbaTrgt, rank, mark, i_sc ); // Tell TD controller to handle VCM event. l_rc = mbadb->iv_tdCtlr.handleTdEvent( i_sc, rank, CenMbaTdCtlrCommon::VCM_EVENT ); if ( SUCCESS != l_rc ) { PRDF_ERR( PRDF_FUNC"handleTdEvent() failed." ); break; } } while (0); // Add ECC capture data for FFDC. if ( NULL != mbaChip ) CenMbaCaptureData::addMemEccData( mbaChip, i_sc ); if ( SUCCESS != l_rc ) { PRDF_ERR( PRDF_FUNC"Failed: i_membChip=0x%08x i_mbaPos=%d i_rank=%d", i_membChip->GetId(), i_mbaPos, i_rank ); CalloutUtil::defaultError( i_sc ); } return SUCCESS; // Intentionally return SUCCESS for this plugin #undef PRDF_FUNC }