void PnorFirDataReader::addFfdc( errlHndl_t io_errl ) const { size_t u16 = sizeof(uint16_t); size_t u32 = sizeof(uint32_t); uint32_t trgtFfdcMapCnt = iv_trgtFfdcMap.size(); if ( 0 != trgtFfdcMapCnt || iv_ffdc.full ) { size_t sz_data = u32 + ((u32 + u16) * trgtFfdcMapCnt); uint8_t data[sz_data]; data[0] = iv_ffdc.trgts; data[1] = (iv_ffdc.full ? 1 : 0) << 7; // 1:7 reserved data[2] = 0; // 0:7 reserved data[3] = trgtFfdcMapCnt; uint32_t idx = 4; for ( PnorTrgtFfdcMap::const_iterator it = iv_trgtFfdcMap.begin(); it != iv_trgtFfdcMap.end(); ++it ) { HUID huid = getHuid(it->first); memcpy( &data[idx], &huid, u32 ); idx += u32; memcpy( &data[idx], &(it->second.scomErrs), u16 ); idx += u16; } BIT_STRING_ADDRESS_CLASS bs ( 0, sz_data * 8, (CPU_WORD *)&data ); CaptureData cd; cd.Add( getSystemTarget(), Util::hashString("OCC_CS_FFDC"), bs ); ErrDataService::AddCapData( cd, io_errl ); } }
void CenMbaRceTable::addCapData( CaptureData & io_cd ) { static const size_t sz_word = sizeof(CPU_WORD); static const size_t sz_entryCnt = sizeof( uint8_t ); // entry count // Get the maximum capture data size and adjust the size for endianess. const size_t sz_maxData = ((( iv_table.size() * ENTRY_SIZE + sz_entryCnt )+ sz_word-1) / sz_word) * sz_word; // Initialize to 0. uint8_t data[sz_maxData]; memset( data, 0x00, sz_maxData ); // reserve first index for total entries size_t sz_actData = sz_entryCnt; for ( RceTable::iterator it = iv_table.begin(); it != iv_table.end(); it++ ) { // skip if there is no RCE count if( 0 == it->second.getTotalCount() ) { continue; } uint32_t mrnk = it->first.getMaster(); // 3-bit uint32_t srnk = it->first.getSlave(); // 3-bit uint32_t svld = it->first.isSlaveValid() ? 1 : 0; // 1-bit data[sz_actData] = (mrnk << 5) | (srnk << 2) | (svld << 1); uint32_t count = it->second.getTotalCount(); data[sz_actData + 1] = ( count > 255 ) ? 255 : count; sz_actData += ENTRY_SIZE; } if ( 1 != sz_actData ) { data[0] = sz_actData / ENTRY_SIZE; // Fix endianess issues with non PPC machines. sz_actData = ((sz_actData + sz_word-1) / sz_word) * sz_word; for ( uint32_t i = 0; i < (sz_actData/sz_word); i++ ) ((CPU_WORD*)data)[i] = htonl(((CPU_WORD*)data)[i]); // Add data to capture data. BIT_STRING_ADDRESS_CLASS bs ( 0, sz_actData*8, (CPU_WORD *) &data ); io_cd.Add( iv_mbaTrgt, Util::hashString("MEM_RCE_TABLE"), bs ); } }
void captureDramRepairsVpd( TargetHandle_t i_mbaTrgt, CaptureData & io_cd ) { #define PRDF_FUNC "[captureDramRepairsVpd] " // Get the maximum capture data size. static const size_t sz_rank = sizeof(uint8_t); static const size_t sz_entry = PORT_SLCT_PER_MBA * DIMM_DQ_RANK_BITMAP_SIZE; static const size_t sz_word = sizeof(CPU_WORD); int32_t rc = SUCCESS; do { std::vector<CenRank> masterRanks; 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; } // Get the maximum capture data size. size_t sz_maxData = masterRanks.size() * (sz_rank + sz_entry); // Adjust the size for endianness. sz_maxData = ((sz_maxData + sz_word-1) / sz_word) * sz_word; // Initialize to 0. uint8_t capData[sz_maxData]; memset( capData, 0x00, sz_maxData ); // Iterate all ranks to get VPD data uint32_t idx = 0; for ( std::vector<CenRank>::iterator it = masterRanks.begin(); it != masterRanks.end(); it++ ) { CenDqBitmap bitmap; uint8_t rank = it->getMaster(); if ( SUCCESS != getBadDqBitmap(i_mbaTrgt, *it, bitmap, true) ) { PRDF_ERR( PRDF_FUNC "getBadDqBitmap() failed: MBA=0x%08x" " rank=%d", getHuid(i_mbaTrgt), rank ); continue; // skip this rank } if ( bitmap.badDqs() ) // make sure the data is non-zero { // Add the rank, then the entry data. capData[idx] = rank; idx += sz_rank; memcpy(&capData[idx], bitmap.getData(), sz_entry); idx += sz_entry; } } if( 0 == idx ) break; // Nothing to capture // Fix endianness issues with non PPC machines. size_t sz_capData = idx; sz_capData = ((sz_capData + sz_word-1) / sz_word) * sz_word; for ( uint32_t i = 0; i < (sz_capData/sz_word); i++ ) ((CPU_WORD*)capData)[i] = htonl(((CPU_WORD*)capData)[i]); // Add data to capture data. BIT_STRING_ADDRESS_CLASS bs ( 0, sz_capData*8, (CPU_WORD *) &capData ); io_cd.Add( i_mbaTrgt, Util::hashString("DRAM_REPAIRS_VPD"), bs ); }while(0); if( FAIL == rc ) PRDF_ERR( PRDF_FUNC "Failed for MBA 0x%08X", getHuid( i_mbaTrgt ) ); #undef PRDF_FUNC }
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 }