summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCaleb Palmer <cnpalmer@us.ibm.com>2018-01-23 10:18:17 -0600
committerZane C. Shelley <zshelle@us.ibm.com>2018-03-27 15:46:10 -0400
commit92069bbfeb10b93364a9a984564594be3bc251f5 (patch)
tree1c3e681a0a3a83638c8ea63d0701a31e5070b4a7
parent579e63b60e50df4cbef126c306e1aa742d2c9f09 (diff)
downloadtalos-hostboot-92069bbfeb10b93364a9a984564594be3bc251f5.tar.gz
talos-hostboot-92069bbfeb10b93364a9a984564594be3bc251f5.zip
Add get/set functionality for row repair attr
Change-Id: Iec206c04a04297b65be15cf2c87b829964ba29b7 RTC: 174670 CMVC-Prereq: 1049443 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/52555 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> CI-Ready: Zane C. Shelley <zshelle@us.ibm.com> Reviewed-by: Benjamin J. Weisenbeck <bweisenb@us.ibm.com> Reviewed-by: Brian J. Stegmiller <bjs@us.ibm.com> Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com>
-rw-r--r--src/include/usr/fapi2/attribute_service.H38
-rw-r--r--src/usr/fapi2/attribute_service.C138
2 files changed, 175 insertions, 1 deletions
diff --git a/src/include/usr/fapi2/attribute_service.H b/src/include/usr/fapi2/attribute_service.H
index e02053024..88988195e 100644
--- a/src/include/usr/fapi2/attribute_service.H
+++ b/src/include/usr/fapi2/attribute_service.H
@@ -276,6 +276,28 @@ ReturnCode fapiAttrGetBadDqBitmap( const Target<TARGET_TYPE_ALL>& i_fapiTarget,
ReturnCode fapiAttrSetBadDqBitmap( const Target<TARGET_TYPE_ALL>& i_fapiTarget,
ATTR_BAD_DQ_BITMAP_Type (&i_data) );
+///
+/// @brief This function is called by the FAPI_ATTR_GET macro when getting
+/// the Row Repair Data attribute. It should not be called directly.
+///
+/// @param[in] i_fapiDimm DIMM target pointer
+/// @param[out] o_data Row Repair Data
+/// @return ReturnCode. Zero on success, else platform specified error
+///
+ReturnCode getRowRepairData( const Target<TARGET_TYPE_ALL>& i_fapiDimm,
+ ATTR_ROW_REPAIR_DATA_Type (&o_data) );
+
+///
+/// @brief This function is called by the FAPI_ATTR_SET macro when setting
+/// the Row Repair Data attribute. It should not be called directly.
+///
+/// @param[in] i_fapiDimm DIMM target pointer
+/// @param[in] i_data Row Repair Data
+/// @return ReturnCode. Zero on success, else platform specified error
+///
+ReturnCode setRowRepairData( const Target<TARGET_TYPE_ALL>& i_fapiDimm,
+ ATTR_ROW_REPAIR_DATA_Type (&i_data) );
+
/// @brief This function is called by the FAPI_ATTR_GET macro when getting
/// the SECURITY_MODE attribute. It should not be called directly.
///
@@ -604,6 +626,22 @@ fapiToTargeting::ID, sizeof(VAL), &(VAL))
fapi2::platAttrSvc::fapiAttrSetBadDqBitmap(TARGET, VAL)
//------------------------------------------------------------------------------
+// MACRO to route ATTR_ROW_REPAIR_DATA read access to the correct HB function
+//------------------------------------------------------------------------------
+#define ATTR_ROW_REPAIR_DATA_GETMACRO(ID, TARGET, VAL) \
+ AttrOverrideSync::getAttrOverrideFunc(ID, TARGET, &VAL)\
+ ? fapi2::ReturnCode() : \
+ fapi2::platAttrSvc::getRowRepairData(TARGET, VAL)
+
+//------------------------------------------------------------------------------
+// MACRO to route ATTR_ROW_REPAIR_DATA write access to the correct HB function
+//------------------------------------------------------------------------------
+#define ATTR_ROW_REPAIR_DATA_SETMACRO(ID, TARGET, VAL) \
+ AttrOverrideSync::getAttrOverrideFunc(ID, TARGET, &VAL)\
+ ? fapi2::ReturnCode() : \
+ fapi2::platAttrSvc::setRowRepairData(TARGET, VAL)
+
+//------------------------------------------------------------------------------
// MACRO to route ATTR_SECURITY_MODE access to the correct HB function
//------------------------------------------------------------------------------
#define ATTR_SECURITY_MODE_GETMACRO(ID, TARGET, VAL) \
diff --git a/src/usr/fapi2/attribute_service.C b/src/usr/fapi2/attribute_service.C
index 08ed1b877..450280e87 100644
--- a/src/usr/fapi2/attribute_service.C
+++ b/src/usr/fapi2/attribute_service.C
@@ -550,7 +550,9 @@ struct dimmBadDqDataFormat
uint8_t iv_reserved2;
uint8_t iv_reserved3;
uint8_t iv_bitmaps[mss::MAX_RANK_PER_DIMM][mss::BAD_DQ_BYTE_COUNT];
- uint8_t iv_unused[32];
+ uint8_t iv_rowRepairData[mss::MAX_RANK_PER_DIMM]
+ [mss::ROW_REPAIR_BYTE_COUNT];
+ uint8_t iv_unused[16];
};
// constant definitions
@@ -1533,6 +1535,8 @@ ReturnCode fapiAttrSetBadDqBitmap(
dimmBadDqDataFormat l_prevSpdData;
memcpy( &l_prevSpdData, l_badDqData, sizeof(dimmBadDqDataFormat) );
+ memcpy( &l_spdData.iv_rowRepairData, l_prevSpdData.iv_rowRepairData,
+ sizeof(l_spdData.iv_rowRepairData) );
memcpy( &l_spdData.iv_unused, l_prevSpdData.iv_unused,
sizeof(l_spdData.iv_unused) );
@@ -1580,6 +1584,138 @@ ReturnCode fapiAttrSetBadDqBitmap(
}
//******************************************************************************
+// fapi2::platAttrSvc::getRowRepairData function
+//******************************************************************************
+ReturnCode getRowRepairData( const Target<TARGET_TYPE_ALL>& i_fapiDimm,
+ ATTR_ROW_REPAIR_DATA_Type (&o_data) )
+{
+ fapi2::ReturnCode l_rc;
+ errlHndl_t l_errl = nullptr;
+ uint8_t * l_data =
+ static_cast<uint8_t*>( malloc(DIMM_BAD_DQ_SIZE_BYTES) );
+ 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( "getRowRepairData: Error from getTargetingTarget" );
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ break;
+ }
+
+ // Zero callers data.
+ memset(o_data, 0, sizeof(o_data));
+
+ // Read the data
+ l_errl = deviceRead( l_dimm, l_data, DIMM_BAD_DQ_SIZE_BYTES,
+ DEVICE_SPD_ADDRESS(SPD::DIMM_BAD_DQ_DATA) );
+ if ( l_errl )
+ {
+ FAPI_ERR( "getRowRepairData: Failed to call deviceRead to get "
+ "l_data." );
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ break;
+ }
+
+ dimmBadDqDataFormat l_spdData;
+ memcpy( &l_spdData, l_data, sizeof(dimmBadDqDataFormat) );
+
+ // Check the header for correct data.
+ if ( (be32toh(l_spdData.iv_magicNumber) != DIMM_BAD_DQ_MAGIC_NUMBER) ||
+ (l_spdData.iv_version != DIMM_BAD_DQ_VERSION) )
+ {
+ FAPI_INF( "getRowRepairData: DIMM VPD not initialized." );
+ }
+ else
+ {
+ // Get the row repair data.
+ memcpy( &o_data, &l_spdData.iv_rowRepairData,
+ sizeof(ATTR_ROW_REPAIR_DATA_Type) );
+ }
+
+ }while(0);
+
+ if ( l_data != nullptr )
+ {
+ free( l_data );
+ l_data = nullptr;
+ }
+
+ return l_rc;
+}
+
+//******************************************************************************
+// fapi2::platAttrSvc::setRowRepairData function
+//******************************************************************************
+ReturnCode setRowRepairData( const Target<TARGET_TYPE_ALL>& i_fapiDimm,
+ ATTR_ROW_REPAIR_DATA_Type (&i_data) )
+{
+ fapi2::ReturnCode l_rc;
+ errlHndl_t l_errl = nullptr;
+ uint8_t * l_data =
+ static_cast<uint8_t*>( malloc(DIMM_BAD_DQ_SIZE_BYTES) );
+ 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( "setRowRepairData: Error from getTargetingTarget" );
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ break;
+ }
+
+ // Get the original data.
+ l_errl = deviceRead( l_dimm, l_data, DIMM_BAD_DQ_SIZE_BYTES,
+ DEVICE_SPD_ADDRESS(SPD::DIMM_BAD_DQ_DATA) );
+ if ( l_errl )
+ {
+ FAPI_ERR( "setRowRepairData: Failed to call deviceRead to get "
+ "l_data." );
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ break;
+ }
+
+ dimmBadDqDataFormat l_spdData;
+ memcpy( &l_spdData, l_data, sizeof(dimmBadDqDataFormat) );
+
+ // Update the header
+ l_spdData.iv_magicNumber = htobe32( DIMM_BAD_DQ_MAGIC_NUMBER );
+ l_spdData.iv_version = DIMM_BAD_DQ_VERSION;
+ l_spdData.iv_reserved1 = 0;
+ l_spdData.iv_reserved2 = 0;
+ l_spdData.iv_reserved3 = 0;
+
+ // Update the row repair data
+ memcpy( &l_spdData.iv_rowRepairData, i_data,
+ sizeof(ATTR_ROW_REPAIR_DATA_Type) );
+
+ // Write the data back to VPD.
+ l_errl = deviceWrite( l_dimm, &l_spdData, DIMM_BAD_DQ_SIZE_BYTES,
+ DEVICE_SPD_ADDRESS(SPD::DIMM_BAD_DQ_DATA) );
+ if ( l_errl )
+ {
+ FAPI_ERR( "setRowRepairData: Failed to call deviceWrite to set "
+ "l_data." );
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ break;
+ }
+
+ }while(0);
+
+ if ( l_data != nullptr )
+ {
+ free( l_data );
+ l_data = nullptr;
+ }
+
+ return l_rc;
+}
+
+//******************************************************************************
// fapi::platAttrSvc::platGetSecurityMode function
//******************************************************************************
ReturnCode platGetSecurityMode(uint8_t & o_securityMode)
OpenPOWER on IntegriCloud