summaryrefslogtreecommitdiffstats
path: root/src/usr/fapi2/attribute_service.C
diff options
context:
space:
mode:
authorCaleb Palmer <cnpalmer@us.ibm.com>2017-06-05 16:04:27 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-08-28 14:56:12 -0400
commitd520480e52251b3b025bd4697c0af312c6ca21a2 (patch)
tree2757c5a83fb31310de80c0ef8951fecd2322f064 /src/usr/fapi2/attribute_service.C
parent35205d340c890220ce47be78e060c0b0ae5d7de0 (diff)
downloadtalos-hostboot-d520480e52251b3b025bd4697c0af312c6ca21a2.tar.gz
talos-hostboot-d520480e52251b3b025bd4697c0af312c6ca21a2.zip
Setter function for ATTR_BAD_DQ_BITMAP
Change-Id: I04700a5399ad6cd9b508a722c833c602d1b66e78 RTC: 173476 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/41397 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> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/fapi2/attribute_service.C')
-rw-r--r--src/usr/fapi2/attribute_service.C205
1 files changed, 186 insertions, 19 deletions
diff --git a/src/usr/fapi2/attribute_service.C b/src/usr/fapi2/attribute_service.C
index bb8fc94f1..58d5e4b1e 100644
--- a/src/usr/fapi2/attribute_service.C
+++ b/src/usr/fapi2/attribute_service.C
@@ -518,6 +518,27 @@ ReturnCode platGetWOFTableData(const Target<TARGET_TYPE_ALL>& i_fapiTarget,
}
//******************************************************************************
+// ATTR_BAD_DQ_BITMAP getter/setter constant definitions
+//******************************************************************************
+
+// define structure for the format of DIMM_BAD_DQ_DATA
+struct dimmBadDqDataFormat
+{
+ uint32_t iv_magicNumber;
+ uint8_t iv_version;
+ uint8_t iv_reserved1;
+ uint8_t iv_reserved2;
+ uint8_t iv_reserved3;
+ uint8_t iv_bitmaps[mss::MAX_RANK_PER_DIMM][mss::BAD_DQ_BYTE_COUNT];
+};
+
+// constant definitions
+const uint8_t SPARE_DRAM_DQ_BYTE_NUMBER_INDEX = 9;
+const uint32_t DIMM_BAD_DQ_MAGIC_NUMBER = 0xbadd4471;
+const uint8_t DIMM_BAD_DQ_VERSION = 1;
+size_t DIMM_BAD_DQ_SIZE_BYTES = 0x50;
+
+//******************************************************************************
// fapi2::platAttrSvc::__getMcsAndPortSlct function
//******************************************************************************
ReturnCode __getMcsAndPortSlct( const Target<TARGET_TYPE_DIMM>& i_fapiDimm,
@@ -776,7 +797,6 @@ ReturnCode __dimmUpdateDqBitmapSpareByte(
uint8_t (&o_data)[mss::MAX_RANK_PER_DIMM][mss::BAD_DQ_BYTE_COUNT] )
{
ReturnCode l_rc;
- const uint8_t SPARE_DRAM_DQ_BYTE_NUMBER_INDEX = 9;
do
{
@@ -930,22 +950,6 @@ ReturnCode fapiAttrGetBadDqBitmap(
{
FAPI_INF(">>fapiAttrGetBadDqBitmap: Getting bitmap");
- // define structure for the format of DIMM_BAD_DQ_DATA
- struct dimmBadDqDataFormat
- {
- uint32_t iv_magicNumber;
- uint8_t iv_version;
- uint8_t iv_reserved1;
- uint8_t iv_reserved2;
- uint8_t iv_reserved3;
- uint8_t iv_bitmaps[mss::MAX_RANK_PER_DIMM][mss::BAD_DQ_BYTE_COUNT];
- };
-
- // constant definitions
- const uint32_t DIMM_BAD_DQ_MAGIC_NUMBER = 0xbadd4471;
- const uint8_t DIMM_BAD_DQ_VERSION = 1;
- size_t DIMM_BAD_DQ_SIZE_BYTES = 0x50;
-
fapi2::ReturnCode l_rc;
errlHndl_t l_errl = nullptr;
TARGETING::TargetHandle_t l_dimmTarget = nullptr;
@@ -1104,12 +1108,175 @@ ReturnCode fapiAttrGetBadDqBitmap(
// fapi2::platAttrSvc::fapiAttrSetBadDqBitmap function
//******************************************************************************
ReturnCode fapiAttrSetBadDqBitmap(
- const Target<TARGET_TYPE_ALL>& i_mcsFapiTarget,
+ const Target<TARGET_TYPE_ALL>& i_dimmFapiTarget,
ATTR_BAD_DQ_BITMAP_Type (&i_data) )
{
fapi2::ReturnCode l_rc;
+ errlHndl_t l_errl = nullptr;
+ TARGETING::TargetHandle_t l_dimmTarget = nullptr;
+
+ do
+ {
+ l_errl = getTargetingTarget(i_dimmFapiTarget, l_dimmTarget);
+ if ( l_errl )
+ {
+ FAPI_ERR( "fapiAttrSetBadDqBitmap: Error from getTargetingTarget" );
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ break;
+ }
+
+ uint8_t l_wiringData[mss::PORTS_PER_MCS][mss::MAX_DQ_BITS];
+ uint64_t l_allMnfgFlags;
+ uint32_t l_ps = 0;
+
+ l_rc = __badDqBitmapGetHelperAttrs( l_dimmTarget, l_wiringData,
+ l_allMnfgFlags, l_ps );
+
+ // Read current BadDqBitmap into l_prev_data
+ uint8_t l_prev_data[mss::MAX_RANK_PER_DIMM][mss::BAD_DQ_BYTE_COUNT];
+
+ bool badDqSet = false;
+ l_rc = FAPI_ATTR_GET( fapi2::ATTR_BAD_DQ_BITMAP, l_dimmTarget,
+ l_prev_data );
+ if (l_rc)
+ {
+ FAPI_ERR("fapiAttrSetBadDqBitmap: Error getting DQ bitmap");
+ break;
+ }
+
+ // Flag to set if the discrepancies are found
+ bool mfgModeBadBitsPresent = false;
- // TODO RTC 173476
+ // Check if Bad DQ bit set
+ // Loop through all ranks
+ for ( uint8_t i = 0; i < mss::MAX_RANK_PER_DIMM; i++ )
+ {
+ // Loop through all DQs
+ for (uint8_t j = 0; j < mss::BAD_DQ_BYTE_COUNT; j++)
+ {
+ if ( i_data[i][j] != l_prev_data[i][j] )
+ {
+ badDqSet = true;
+ break;
+ }
+ }
+ if ( badDqSet ) break;
+ }
+
+ // Set ATTR_RECONFIGURE_LOOP to indicate a bad DqBitMap was set
+ if ( badDqSet )
+ {
+ FAPI_INF("fapiAttrSetBadDqBitmap: Reconfigure needed, Bad DQ set");
+
+ fapi2::ATTR_RECONFIGURE_LOOP_Type l_reconfigAttr = 0;
+ l_rc = FAPI_ATTR_GET( fapi2::ATTR_RECONFIGURE_LOOP,
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
+ l_reconfigAttr );
+ if ( l_rc )
+ {
+ FAPI_ERR( "fapiAttrSetBadDqBitmap: Error getting "
+ "ATTR_RECONFIGURE_LOOP" );
+ break;
+ }
+
+ // 'OR' values in case of multiple reasons for reconfigure
+ l_reconfigAttr |= fapi2::ENUM_ATTR_RECONFIGURE_LOOP_BAD_DQ_BIT_SET;
+
+ #ifndef CONFIG_VPD_GETMACRO_USE_EFF_ATTR
+ l_rc = FAPI_ATTR_SET( fapi2::ATTR_RECONFIGURE_LOOP,
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
+ l_reconfigAttr );
+ if ( l_rc )
+ {
+ FAPI_ERR( "fapiAttrSetBadDqBitmap: Error setting "
+ "ATTR_RECONFIGURE_LOOP" );
+ break;
+ }
+ #endif
+ }
+
+ // If system is in DISABLE_DRAM_REPAIRS mode
+ if ( l_allMnfgFlags &
+ fapi2::ENUM_ATTR_MNFG_FLAGS_MNFG_DISABLE_DRAM_REPAIRS )
+ {
+
+ uint8_t l_eccSpareBitmap[mss::MAX_RANK_PER_DIMM]
+ [mss::BAD_DQ_BYTE_COUNT];
+
+ l_rc = __compareEccAndSpare( l_dimmTarget, mfgModeBadBitsPresent,
+ i_data, l_eccSpareBitmap );
+ if ( l_rc )
+ {
+ FAPI_ERR( "fapiAttrSetBadDqBitmap: Error comparing "
+ "bitmap with ECC/Spare bits set with "
+ "caller's data." );
+ break;
+ }
+ // Don't write bad dq bitmap if discrepancies are found
+ // Break out of do while loop
+ if ( mfgModeBadBitsPresent ) break;
+ }
+
+ // Set up the data to write to SPD
+ dimmBadDqDataFormat l_spdData;
+ 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;
+ memset( l_spdData.iv_bitmaps, 0, sizeof(l_spdData.iv_bitmaps) );
+
+ // Get the spare byte
+ uint8_t spareByte[mss::MAX_RANK_PER_DIMM];
+ memset( spareByte, 0, sizeof(spareByte) );
+
+ l_rc = __dimmGetDqBitmapSpareByte( l_dimmTarget, spareByte );
+ if ( l_rc )
+ {
+ FAPI_ERR( "fapiAttrSetBadDqBitmap: Error getting spare byte" );
+ break;
+ }
+
+ // Translate bitmap from Centaur DQ to DIMM DQ point of view
+ // for each rank
+ for (uint8_t i = 0; i < mss::MAX_RANK_PER_DIMM; i++)
+ {
+ // Iterate through all the DQ bits in the rank
+ for (uint8_t j = 0; j < mss::MAX_DQ_BITS; j++)
+ {
+ if ((j/8) == SPARE_DRAM_DQ_BYTE_NUMBER_INDEX)
+ {
+ // The spareByte can be one of: 0x00 0x0F 0xF0
+ // 0xFF If a bit is set, then that spare is
+ // unconnected so continue to the next num_dqs,
+ // do not translate
+ if (spareByte[i] & (0x80 >> (j % 8)))
+ {
+ continue;
+ }
+ }
+ if ((i_data[i][j/8]) & (0x80 >> (j % 8)))
+ {
+ // Centaur DQ bit set in callers data.
+ // Set DIMM DQ bit in SPD data.
+ // The wiring data maps Centaur DQ to DIMM DQ
+ uint8_t dBit = l_wiringData[l_ps][j];
+ l_spdData.iv_bitmaps[i][dBit/8] |= (0x80 >> (dBit % 8));
+ }
+ }
+ }
+
+ l_errl = deviceWrite( l_dimmTarget, &l_spdData, DIMM_BAD_DQ_SIZE_BYTES,
+ DEVICE_SPD_ADDRESS(SPD::DIMM_BAD_DQ_DATA) );
+ if ( l_errl )
+ {
+ FAPI_ERR( "fapiAttrSetBadDqBitmap: Failed to write DIMM "
+ "Bad DQ data." );
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl));
+ break;
+ }
+
+ }while(0);
return l_rc;
}
OpenPOWER on IntegriCloud