summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorCaleb Palmer <cnpalmer@us.ibm.com>2018-06-18 15:56:52 -0500
committerZane C. Shelley <zshelle@us.ibm.com>2018-06-27 12:52:46 -0400
commit44180ef7b2b455b54f268a36c40ee7ee94246423 (patch)
tree0322bb6404fe2fac2add8e2d95490eb9d5d32b16 /src/usr
parent353567d4b17828b597a7b3bd1f7dcd20e9378466 (diff)
downloadtalos-hostboot-44180ef7b2b455b54f268a36c40ee7ee94246423.tar.gz
talos-hostboot-44180ef7b2b455b54f268a36c40ee7ee94246423.zip
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 <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Benjamin J. Weisenbeck <bweisenb@us.ibm.com> Reviewed-by: Brian J. Stegmiller <bjs@us.ibm.com> Reviewed-by: Matt Derksen <mderkse1@us.ibm.com> Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/fapi2/attribute_service.C224
1 files changed, 223 insertions, 1 deletions
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
@@ -1728,6 +1728,206 @@ ReturnCode fapiAttrSetBadDqBitmap(
}
//******************************************************************************
+// fapi2::platAttrSvc::__isX4Dram function
+//******************************************************************************
+ReturnCode __isX4Dram( const Target<TARGET_TYPE_ALL>& 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<TARGET_TYPE_MBA> l_fapiMba =
+ i_fapiDimm.getParent<TARGET_TYPE_MBA>();
+ 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<void *> (l_errl));
+ break;
+ }
+ o_isX4Dram = ( TARGETING::CEN_EFF_DRAM_WIDTH_X4 ==
+ l_mbaTrgt->getAttr<TARGETING::ATTR_CEN_EFF_DRAM_WIDTH>() );
+ }
+ else
+ {
+ FAPI_ERR( "__isX4Dram: Invalid procType" );
+ assert(false);
+ }
+ }while(0);
+
+ return l_rc;
+}
+//******************************************************************************
+// fapi2::platAttrSvc::__dramToDq function
+//******************************************************************************
+ReturnCode __dramToDq( const Target<TARGET_TYPE_ALL>& 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<TARGET_TYPE_ALL>& 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<TARGET_TYPE_ALL>& 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<void *> (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<uint8_t>(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
//******************************************************************************
ReturnCode getRowRepairData( const Target<TARGET_TYPE_ALL>& i_fapiDimm,
@@ -1777,6 +1977,16 @@ ReturnCode getRowRepairData( const Target<TARGET_TYPE_ALL>& 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<TARGET_TYPE_ALL>& 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.
OpenPOWER on IntegriCloud