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 }
int32_t CenMbaIplCeStats::collectStats( const CenRank & i_stopRank ) { #define PRDF_FUNC "[CenMbaIplCeStats::collectStats] " int32_t o_rc = SUCCESS; do { MemUtils::MaintSymbols symData; CenSymbol junk; o_rc = MemUtils::collectCeStats( iv_mbaChip, i_stopRank, symData, junk); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC"MemUtils::collectCeStats() failed. MBA:0X%08X", getHuid( iv_mbaChip->GetChipHandle() ) ); break; } // if size of stats collected is zero, it may mean some symbol // has gone beyond maximum value. But this is only valid for DD1 // and has a very low probability. So ignoring this case. for ( uint32_t i = 0; i < symData.size(); i++ ) { uint8_t dimmSlct = i_stopRank.getDimmSlct(); uint8_t dram = symData[i].symbol.getDram(); uint8_t portSlct = symData[i].symbol.getPortSlct(); // Check if analysis is banned. HalfRankKey banKey = { i_stopRank, portSlct }; // Check if the rank has already been banned. Note that [] will // create an entry if one does not exist, so used find() instead to // check for existence in the map. if ( iv_bannedAnalysis.end() != iv_bannedAnalysis.find(banKey) ) continue; // Update iv_ceSymbols with the new symbol data. SymbolKey symkey = { symData[i].symbol }; iv_ceSymbols.push_back (symkey ); // Increment the soft CEs per DRAM. DramKey dramKey = { i_stopRank, dram, portSlct }; iv_dramMap[dramKey] += symData[i].count; // Increment the soft CEs per half rank. HalfRankKey rankKey = { i_stopRank, portSlct }; iv_rankMap[rankKey] += symData[i].count; // In case of dimm select, rank select does not matter CenRank dimmRank( dimmSlct << DIMM_SLCT_PER_MBA ); // Increment the soft CEs per half dimm select. HalfRankKey dsKey = { dimmRank, portSlct }; iv_dsMap[dsKey] += symData[i].count; } } while (0); // We have to clear all stats before giving control back to MDIA.. // This is done by setting up MBSTRQ[53] bit // We are doing cleanup in TdController code, // So not clearing up stats here. return o_rc; #undef PRDF_FUNC }
int32_t getMnfgMemCeTh( ExtensibleChip * i_mbaChip, const CenRank & i_rank, uint16_t & o_cePerDram, uint16_t & o_cePerHalfRank, uint16_t & o_cePerDimm ) { #define PRDF_FUNC "[getMnfgMemCeTh] " int32_t o_rc = SUCCESS; do { // Get base threshold ( 2GB ). uint8_t baseTh = getMnfgCeTh(); // A base threhold of 0 indicates there should be no thresholding. if ( 0 == baseTh ) { o_cePerDram = o_cePerHalfRank = o_cePerDimm = MfgThreshold::INFINITE_LIMIT_THR; break; } // Get DRAM size uint8_t size = 0; o_rc = MemUtils::getDramSize( i_mbaChip, size ); if ( SUCCESS != o_rc ) { PRDF_ERR( PRDF_FUNC "MemUtils::getDramSize() failed" ); break; } // Get number of ranks per DIMM select. uint8_t rankCount = getRanksPerDimm( i_mbaChip->GetChipHandle(), i_rank.getDimmSlct() ); if ( 0 == rankCount ) { PRDF_ERR( PRDF_FUNC "PlatServices::getRanksPerDimm() failed" ); o_rc = FAIL; break; } // Get number of allowed CEs. uint8_t baseAllowed = baseTh - 1; // Calculate CEs per DRAM. // The DRAM size is in MBAXCR[6:7], where 0 = 2Gb, 1 = 4Gb, 2 = 8Gb, // and 3 = 16 Gb. So the allowed CEs per DRAM can be calculated with // the following: // perDram = base * 2^(MBAXCR[6:7]+1) * (9/16) // or, perDram = (base << MBAXCR[6:7]+1) * (9/16) uint32_t computeBase = (baseAllowed << (size+1)) * 9; o_cePerDram = (computeBase + 8) / 16; // Calculate CEs per DIMM. o_cePerDimm = ((computeBase * (2 + rankCount)) + 8) / 16; // Calculate CEs per half-rank. // Same as perDimm where rankCount is 1; o_cePerHalfRank = ((computeBase * (2 + 1)) + 8) / 16; } while (0); return o_rc; #undef PRDF_FUNC }