From 44180ef7b2b455b54f268a36c40ee7ee94246423 Mon Sep 17 00:00:00 2001 From: Caleb Palmer Date: Mon, 18 Jun 2018 15:56:52 -0500 Subject: Add translation to Row Repair DRAM position Change-Id: I4b0466d72331aa3153178b821a5e68d7452e7455 RTC: 195426 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/61212 Tested-by: Jenkins Server Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Tested-by: FSP CI Jenkins Reviewed-by: Benjamin J. Weisenbeck Reviewed-by: Brian J. Stegmiller Reviewed-by: Matt Derksen Reviewed-by: Zane C. Shelley --- src/usr/fapi2/attribute_service.C | 224 +++++++++++++++++++++++++++++++++++++- 1 file changed, 223 insertions(+), 1 deletion(-) (limited to 'src/usr') diff --git a/src/usr/fapi2/attribute_service.C b/src/usr/fapi2/attribute_service.C index f90f18cf4..7ae603acf 100644 --- a/src/usr/fapi2/attribute_service.C +++ b/src/usr/fapi2/attribute_service.C @@ -1727,6 +1727,206 @@ ReturnCode fapiAttrSetBadDqBitmap( return l_rc; } +//****************************************************************************** +// fapi2::platAttrSvc::__isX4Dram function +//****************************************************************************** +ReturnCode __isX4Dram( const Target& i_fapiDimm, + bool & o_isX4Dram ) +{ + fapi2::ReturnCode l_rc; + + do + { + TARGETING::ATTR_MODEL_type procType = __getChipModel(); + + // Get if drams are x4 or x8 + if ( TARGETING::MODEL_NIMBUS == procType ) + { + // Nimbus only supports x4 DRAMs + o_isX4Dram = true; + } + else if ( TARGETING::MODEL_CUMULUS == procType ) + { + // Get the MBA + Target l_fapiMba = + i_fapiDimm.getParent(); + TARGETING::TargetHandle_t l_mbaTrgt = nullptr; + errlHndl_t l_errl = getTargetingTarget( l_fapiMba, l_mbaTrgt ); + if ( l_errl ) + { + FAPI_ERR( "__isX4Dram: Error from " + "getTargetingTarget getting MBA." ); + l_rc.setPlatDataPtr(reinterpret_cast (l_errl)); + break; + } + o_isX4Dram = ( TARGETING::CEN_EFF_DRAM_WIDTH_X4 == + l_mbaTrgt->getAttr() ); + } + else + { + FAPI_ERR( "__isX4Dram: Invalid procType" ); + assert(false); + } + }while(0); + + return l_rc; +} +//****************************************************************************** +// fapi2::platAttrSvc::__dramToDq function +//****************************************************************************** +ReturnCode __dramToDq( const Target& i_fapiDimm, + uint8_t i_dram, uint8_t & o_dq ) +{ + fapi2::ReturnCode l_rc; + + do + { + // Convert dram pos to symbol + // Get if drams are x4 or x8 + bool l_isX4 = false; + l_rc = __isX4Dram( i_fapiDimm, l_isX4 ); + if ( l_rc ) + { + FAPI_ERR( "__dramToDq: Error from __isX4Dram." ); + break; + } + + o_dq = i_dram * ( l_isX4 ? 4 : 8 ); + + }while(0); + + return l_rc; +} + +//****************************************************************************** +// fapi2::platAttrSvc::__dqToDram function +//****************************************************************************** +ReturnCode __dqToDram( const Target& i_fapiDimm, + uint8_t i_dq, uint8_t & o_dram ) +{ + fapi2::ReturnCode l_rc; + + do + { + // Convert symbol to dram pos + // Get if drams are x4 or x8 + bool l_isX4 = false; + l_rc = __isX4Dram( i_fapiDimm, l_isX4 ); + if ( l_rc ) + { + FAPI_ERR( "__dqToDram: Error from __isX4Dram." ); + break; + } + + o_dram = i_dq / ( l_isX4 ? 4 : 8 ); + + }while(0); + + return l_rc; +} + +//****************************************************************************** +// fapi2::platAttrSvc::__rowRepairTranslateDramPos function +//****************************************************************************** +ReturnCode __rowRepairTranslateDramPos( + const Target& i_fapiDimm, + bool i_mcLogicalToDimmDq, + ATTR_ROW_REPAIR_DATA_Type & io_translatedData ) +{ + fapi2::ReturnCode l_rc; + errlHndl_t l_errl = nullptr; + wiringData l_wiringData; + uint64_t l_allMnfgFlags; + uint32_t l_ps = 0; + + do + { + // Get targeting target for the dimm + TARGETING::TargetHandle_t l_dimm = nullptr; + l_errl = getTargetingTarget( i_fapiDimm, l_dimm ); + if ( l_errl ) + { + FAPI_ERR( "__rowRepairTranslateDramPos: Error from " + "getTargetingTarget" ); + l_rc.setPlatDataPtr(reinterpret_cast (l_errl)); + break; + } + + // Get the wiring data and port select for translation. + l_rc = __badDqBitmapGetHelperAttrs( l_dimm, l_wiringData, + l_allMnfgFlags, l_ps ); + if ( l_rc ) + { + FAPI_ERR( "__rowRepairTranslateDramPos: Error from " + "__badDqBitmapGetHelperAttrs." ); + break; + } + + // Loop through each rank. + for ( uint8_t rank = 0; rank < mss::MAX_RANK_PER_DIMM; rank++ ) + { + // The first 5 bits of the stored row repair are the dram position + // that needs to be translated. The next three are the slave rank. + uint8_t l_dramPosAndSrank = io_translatedData[rank][0]; + uint8_t l_dramPos = (l_dramPosAndSrank >> 3) & 0x1f; + uint8_t l_srank = l_dramPosAndSrank & 0x07; + + uint8_t l_dq = 0; + l_rc = __dramToDq( i_fapiDimm, l_dramPos, l_dq ); + if ( l_rc ) + { + FAPI_ERR( "__rowRepairTranslateDramPos: Error from " + "__dramToDq" ); + break; + } + + uint8_t l_translatedDq = 0; + + if ( i_mcLogicalToDimmDq ) + { + l_rc = __mcLogicalToDimmDqHelper( i_fapiDimm, l_wiringData, + l_ps, l_dq, l_translatedDq ); + if ( l_rc ) + { + FAPI_ERR( "__rowRepairTranslateDramPos: Error from " + "__mcLogicalToDimmDqHelper" ); + break; + } + } + else + { + uint64_t l_tmp = 0; + + l_rc = __dimmDqToMcLogicalHelper( i_fapiDimm, l_wiringData, + l_ps, l_dq, l_tmp ); + if ( l_rc ) + { + FAPI_ERR( "__rowRepairTranslateDramPos: Error from " + "__dimmDqToMcLogicalHelper" ); + break; + } + l_translatedDq = static_cast(l_tmp); + } + + uint8_t l_translatedDram = 0; + l_rc = __dqToDram( i_fapiDimm, l_translatedDq, l_translatedDram ); + if ( l_rc ) + { + FAPI_ERR( "__rowRepairTranslateDramPos: Error from " + "__dqToDram" ); + break; + } + + uint8_t l_updatedData = (l_translatedDram << 3) | l_srank; + + io_translatedData[rank][0] = l_updatedData; + + } + }while(0); + + return l_rc; +} + //****************************************************************************** // fapi2::platAttrSvc::getRowRepairData function //****************************************************************************** @@ -1777,6 +1977,16 @@ ReturnCode getRowRepairData( const Target& i_fapiDimm, // Get the row repair data. memcpy( &o_data, &l_spdData.iv_rowRepairData, sizeof(ATTR_ROW_REPAIR_DATA_Type) ); + + // Translate the DRAM position in the row repair data + l_rc = __rowRepairTranslateDramPos( i_fapiDimm, false, + o_data ); + if ( l_rc ) + { + FAPI_ERR( "getRowRepairData: Error from " + "__rowRepairTranslateDramPos" ); + break; + } } }while(0); @@ -1833,8 +2043,20 @@ ReturnCode setRowRepairData( const Target& i_fapiDimm, l_spdData.iv_reserved2 = 0; l_spdData.iv_reserved3 = 0; + // Translate the input data + ATTR_ROW_REPAIR_DATA_Type l_translatedData; + memcpy( &l_translatedData, i_data, sizeof(ATTR_ROW_REPAIR_DATA_Type) ); + l_rc = __rowRepairTranslateDramPos( i_fapiDimm, true, + l_translatedData ); + if ( l_rc ) + { + FAPI_ERR( "setRowRepairData: Error from " + "__rowRepairTranslateDramPos" ); + break; + } + // Update the row repair data - memcpy( &l_spdData.iv_rowRepairData, i_data, + memcpy( &l_spdData.iv_rowRepairData, l_translatedData, sizeof(ATTR_ROW_REPAIR_DATA_Type) ); // Write the data back to VPD. -- cgit v1.2.1