summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorStephen Cprek <smcprek@us.ibm.com>2013-12-17 15:46:21 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2014-01-16 11:19:10 -0600
commit63f42d36ee3f78e59d0acb19ccdcf1766f0050bd (patch)
tree46c2f3096d795bf28a27979e551f27b1dc7b5e39 /src/usr
parent542d9f0c4bb7e1b37a15823fa0b642e4f3bf7410 (diff)
downloadtalos-hostboot-63f42d36ee3f78e59d0acb19ccdcf1766f0050bd.tar.gz
talos-hostboot-63f42d36ee3f78e59d0acb19ccdcf1766f0050bd.zip
Perform Reconfig Loop on Bad DQ set
Change-Id: I43be1bbab5dca2be6f70d47b747b6b418820bc2b RTC: 92037 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/7773 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/hwas/common/deconfigGard.C25
-rw-r--r--src/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.C677
-rw-r--r--src/usr/hwpf/hwp/system_attributes.xml19
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.C38
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.H11
-rw-r--r--src/usr/targeting/common/xmltohb/attribute_types.xml38
-rw-r--r--src/usr/targeting/common/xmltohb/target_types.xml1
7 files changed, 499 insertions, 310 deletions
diff --git a/src/usr/hwas/common/deconfigGard.C b/src/usr/hwas/common/deconfigGard.C
index 2825b3d0f..fe51d0914 100644
--- a/src/usr/hwas/common/deconfigGard.C
+++ b/src/usr/hwas/common/deconfigGard.C
@@ -5,7 +5,7 @@
/* */
/* IBM CONFIDENTIAL */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2013 */
+/* COPYRIGHT International Business Machines Corp. 2011,2014 */
/* */
/* p1 */
/* */
@@ -116,8 +116,7 @@ DeconfigGard & theDeconfigGard()
//******************************************************************************
DeconfigGard::DeconfigGard()
: iv_platDeconfigGard(NULL),
- iv_XABusEndpointDeconfigured(false),
- iv_deconfigCount(0)
+ iv_XABusEndpointDeconfigured(false)
{
HWAS_DBG("DeconfigGard Constructor");
HWAS_MUTEX_INIT(iv_mutex);
@@ -1286,15 +1285,6 @@ void DeconfigGard::_deconfigureByAssoc(Target & i_target,
} // _deconfigByAssoc
//******************************************************************************
-uint32_t DeconfigGard::getDeconfigureStatus() const
-{
- // no lock needed - just return the value.
- uint32_t l_deconfigCount = iv_deconfigCount;
- HWAS_DBG("getDeconfigureStatus returning %u", l_deconfigCount);
- return l_deconfigCount;
-}
-
-//******************************************************************************
void DeconfigGard::_deconfigureTarget(Target & i_target,
const uint32_t i_errlEid)
{
@@ -1324,8 +1314,15 @@ void DeconfigGard::_deconfigureTarget(Target & i_target,
// if this is a real error, deconfigure
if (i_errlEid & DECONFIGURED_BY_PLID_MASK)
{
- // increment the counter
- iv_deconfigCount++;
+ // Set RECONFIGURE_LOOP attribute to indicate it was caused by
+ // a hw deconfigure
+ TARGETING::Target* l_pTopLevel = NULL;
+ TARGETING::targetService().getTopLevelTarget(l_pTopLevel);
+ TARGETING::ATTR_RECONFIGURE_LOOP_type l_reconfigAttr =
+ l_pTopLevel->getAttr<ATTR_RECONFIGURE_LOOP>();
+ // 'OR' values in case of multiple reasons for reconfigure
+ l_reconfigAttr |= TARGETING::RECONFIGURE_LOOP_DECONFIGURE;
+ l_pTopLevel->setAttr<ATTR_RECONFIGURE_LOOP>(l_reconfigAttr);
}
// Do any necessary Deconfigure Actions
diff --git a/src/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.C b/src/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.C
index a1b4ded14..613b3d731 100644
--- a/src/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.C
+++ b/src/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.C
@@ -20,7 +20,8 @@
/* Origin: 30 */
/* */
/* IBM_PROLOG_END_TAG */
-// $Id: dimmBadDqBitmapAccessHwp.C,v 1.9 2014/01/09 22:48:08 dedahle Exp $
+
+// $Id: dimmBadDqBitmapAccessHwp.C,v 1.12 2014/01/14 22:01:08 mjjones Exp $
/**
* @file dimmBadDqBitmapAccessHwp.C
*
@@ -46,6 +47,8 @@
* connected DQs
* dedahle 01/08/2014 Switch back to reading
* ATTR_VPD_DIMM_SPARE
+ * smcprek 01/14/2014 Perform Reconfig Loop on
+ * Bad DQ set
*/
#include <dimmBadDqBitmapAccessHwp.H>
@@ -66,7 +69,6 @@ struct dimmBadDqDataFormat
uint8_t iv_bitmaps[DIMM_DQ_MAX_DIMM_RANKS][DIMM_DQ_RANK_BITMAP_SIZE];
};
-
extern "C"
{
@@ -153,7 +155,6 @@ fapi::ReturnCode dimmUpdateDqBitmapSpareByte(
return l_rc;
}
-
/**
* @brief Called by dimmBadDqBitmapAccessHwp() to query
* ATTR_SPD_MODULE_MEMORY_BUS_WIDTH in order to determine
@@ -211,39 +212,29 @@ fapi::ReturnCode dimmUpdateDqBitmapEccByte(
return l_rc;
}
-}
-
-extern "C"
-{
+/**
+ * @brief Called by dimmBadDqBitmapAccessHwp() to query ATTR_SPD_BAD_DQ_DATA
+ *
+ *
+ * @param[in] i_mba Reference to MBA Target.
+ * @param[in] i_dimm Reference to DIMM Target.
+ * @param[o] o_data Reference to Bad DQ Bitmap set by this function
+ * @param[in] i_wiringData Reference to Centaur DQ to DIMM Connector
+ * DQ Wiring attribute.
+ * @param[in] i_allMnfgFlags Manufacturing flags bitmap
+ *
+ * @return ReturnCode
+ */
-fapi::ReturnCode dimmBadDqBitmapAccessHwp(
+fapi::ReturnCode dimmBadDqBitmapGet(
const fapi::Target & i_mba,
const fapi::Target & i_dimm,
- uint8_t (&io_data)[DIMM_DQ_MAX_DIMM_RANKS][DIMM_DQ_RANK_BITMAP_SIZE],
- const bool i_get)
+ uint8_t (&o_data)[DIMM_DQ_MAX_DIMM_RANKS][DIMM_DQ_RANK_BITMAP_SIZE],
+ const uint8_t (&i_wiringData)[DIMM_DQ_NUM_DQS],
+ uint64_t i_allMnfgFlags)
{
- if (i_get)
- {
- FAPI_INF(">>dimmBadDqBitmapAccessHwp: Getting bitmap");
- }
- else
- {
- FAPI_INF(">>dimmBadDqBitmapAccessHwp: Setting bitmap");
- }
-
fapi::ReturnCode l_rc;
- // Note the use of heap based arrays to avoid large stack allocations
-
- // Centaur DQ to DIMM Connector DQ Wiring attribute.
- uint8_t (&l_wiringData)[DIMM_DQ_NUM_DQS] =
- *(reinterpret_cast<uint8_t(*)[DIMM_DQ_NUM_DQS]>
- (new uint8_t[DIMM_DQ_NUM_DQS]()));
-
- // memset to avoid known syntax issue with previous compiler versions
- // and ensure zero initialized array.
- memset(l_wiringData, 0, sizeof(l_wiringData));
-
// DQ SPD Attribute
uint8_t (&l_spdData)[DIMM_DQ_SPD_DATA_SIZE] =
*(reinterpret_cast<uint8_t(*)[DIMM_DQ_SPD_DATA_SIZE]>
@@ -262,307 +253,451 @@ fapi::ReturnCode dimmBadDqBitmapAccessHwp(
do
{
- // Manufacturing flags attribute
- uint64_t l_allMnfgFlags = 0;
- // Get the manufacturing flags bitmap to be used in both get and set
- l_rc = FAPI_ATTR_GET(ATTR_MNFG_FLAGS, NULL, l_allMnfgFlags);
- if(l_rc)
- {
- FAPI_ERR("dimmBadDqBitmapAccessHwp: Unable to read attribute"
- " - ATTR_MNFG_FLAGS");
- break;
- }
- // Get the Centaur DQ to DIMM Connector DQ Wiring attribute.
- // Note that for C-DIMMs, this will return a simple 1:1 mapping.
- // This code cannot tell the difference between C-DIMMs and IS-DIMMs.
- l_rc = FAPI_ATTR_GET(ATTR_CEN_DQ_TO_DIMM_CONN_DQ,
- &i_dimm, l_wiringData);
+ // Get the SPD DQ attribute
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_BAD_DQ_DATA, &i_dimm, l_spdData);
if (l_rc)
{
- FAPI_ERR("dimmBadDqBitmapAccessHwp: "
- "Error getting wiring attribute");
+ FAPI_ERR("dimmBadDqBitmapAccessHwp: Error getting SPD data");
break;
}
- if (i_get)
+ // Zero caller's data
+ memset(o_data, 0, sizeof(o_data));
+ // Check the magic number and version number. Note that the
+ // magic number is stored in SPD in big endian format and
+ // platforms of any endianness can access it
+ if ((FAPI_BE32TOH(l_pSpdData->iv_magicNumber) !=
+ DIMM_BAD_DQ_MAGIC_NUMBER) ||
+ (l_pSpdData->iv_version != DIMM_BAD_DQ_VERSION))
{
- // Get the SPD DQ attribute
- l_rc = FAPI_ATTR_GET(ATTR_SPD_BAD_DQ_DATA, &i_dimm, l_spdData);
-
- if (l_rc)
- {
- FAPI_ERR("dimmBadDqBitmapAccessHwp: Error getting SPD data");
- break;
- }
- // Zero caller's data
- memset(io_data, 0, sizeof(io_data));
- // Check the magic number and version number. Note that the
- // magic number is stored in SPD in big endian format and
- // platforms of any endianness can access it
- if ((FAPI_BE32TOH(l_pSpdData->iv_magicNumber) !=
- DIMM_BAD_DQ_MAGIC_NUMBER) ||
- (l_pSpdData->iv_version != DIMM_BAD_DQ_VERSION))
- {
- FAPI_INF("dimmBadDqBitmapAccessHwp: SPD DQ not initialized");
- }
- else
+ FAPI_INF("dimmBadDqBitmapAccessHwp: SPD DQ not initialized");
+ }
+ else
+ {
+ // Translate bitmap from DIMM DQ to Centaur DQ point of view
+ // for each rank
+ for (uint8_t i = 0; i < DIMM_DQ_MAX_DIMM_RANKS; i++)
{
- // Translate bitmap from DIMM DQ to Centaur DQ point of view
- // for each rank
- for (uint8_t i = 0; i < DIMM_DQ_MAX_DIMM_RANKS; i++)
+ // Iterate through all the DQ bits in the rank
+ for (uint8_t j = 0; j < DIMM_DQ_NUM_DQS; j++)
{
- // Iterate through all the DQ bits in the rank
- for (uint8_t j = 0; j < DIMM_DQ_NUM_DQS; j++)
+ // There is a byte for each 8 DQs, j/8 gives the
+ // byte number. The MSB in each byte is the lowest
+ // DQ, (0x80 >> (j % 8)) gives the bit mask
+ // corresponding to the DQ within the byte
+ if ((l_pSpdData->iv_bitmaps[i][j/8]) &
+ (0x80 >> (j % 8)))
{
- // There is a byte for each 8 DQs, j/8 gives the
- // byte number. The MSB in each byte is the lowest
- // DQ, (0x80 >> (j % 8)) gives the bit mask
- // corresponding to the DQ within the byte
- if ((l_pSpdData->iv_bitmaps[i][j/8]) &
- (0x80 >> (j % 8)))
+ // DIMM DQ bit is set in SPD data.
+ // Set Centaur DQ bit in caller's data.
+ // The wiring data maps Centaur DQ to DIMM DQ
+ // Find the Centaur DQ that maps to this DIMM DQ
+ uint8_t k = 0;
+ for (; k < DIMM_DQ_NUM_DQS; k++)
{
- // DIMM DQ bit is set in SPD data.
- // Set Centaur DQ bit in caller's data.
- // The wiring data maps Centaur DQ to DIMM DQ
- // Find the Centaur DQ that maps to this DIMM DQ
- uint8_t k = 0;
- for (; k < DIMM_DQ_NUM_DQS; k++)
+ if (i_wiringData[k] == j)
{
- if (l_wiringData[k] == j)
- {
- io_data[i][k/8] |= (0x80 >> (k % 8));
- break;
- }
+ o_data[i][k/8] |= (0x80 >> (k % 8));
+ break;
}
+ }
- if (k == DIMM_DQ_NUM_DQS)
- {
- FAPI_INF("dimmBadDqBitmapAccessHwp: "
- "Centaur DQ not found for %d!",j);
- }
+ if (k == DIMM_DQ_NUM_DQS)
+ {
+ FAPI_INF("dimmBadDqBitmapAccessHwp: "
+ "Centaur DQ not found for %d!",j);
}
}
}
}
- // Set bits for any unconnected DQs.
- // First, check ECC.
- l_rc = dimmUpdateDqBitmapEccByte(i_dimm, io_data);
+ }
+ // Set bits for any unconnected DQs.
+ // First, check ECC.
+ l_rc = dimmUpdateDqBitmapEccByte(i_dimm, o_data);
+ if (l_rc)
+ {
+ FAPI_ERR("dimmBadDqBitmapAccessHwp: "
+ "Error getting ECC data");
+ break;
+ }
+ // Check spare DRAM
+ l_rc = dimmUpdateDqBitmapSpareByte(i_mba, i_dimm, o_data);
+ if (l_rc)
+ {
+ FAPI_ERR("dimmBadDqBitmapAccessHwp: "
+ "Error getting spare DRAM data");
+ break;
+ }
+ // If system is in DISABLE_DRAM_REPAIRS mode
+ if (i_allMnfgFlags &
+ fapi::ENUM_ATTR_MNFG_FLAGS_MNFG_DISABLE_DRAM_REPAIRS)
+ {
+ // Flag to set if the discrepancies (described below)
+ // are found
+ bool mfgModeBadBitsPresent = false;
+ // Create a local zero-initialized bad dq bitmap
+ l_pBuf = new uint8_t[DIMM_DQ_MAX_DIMM_RANKS]
+ [DIMM_DQ_RANK_BITMAP_SIZE]();
+ uint8_t (&l_data)[DIMM_DQ_MAX_DIMM_RANKS]
+ [DIMM_DQ_RANK_BITMAP_SIZE] =
+ *(reinterpret_cast<uint8_t(*)[DIMM_DQ_MAX_DIMM_RANKS]
+ [DIMM_DQ_RANK_BITMAP_SIZE]>(l_pBuf));
+ // memset to avoid known syntax issue with previous
+ // compiler versions and ensure zero initialized array.
+ memset(l_data, 0, sizeof(l_data));
+
+ // Check ECC.
+ l_rc = dimmUpdateDqBitmapEccByte(i_dimm, l_data);
if (l_rc)
{
FAPI_ERR("dimmBadDqBitmapAccessHwp: "
- "Error getting ECC data");
+ "Error getting ECC data (Mfg mode)");
break;
}
// Check spare DRAM
- l_rc = dimmUpdateDqBitmapSpareByte(i_mba, i_dimm, io_data);
+ l_rc = dimmUpdateDqBitmapSpareByte(i_mba, i_dimm, l_data);
if (l_rc)
{
FAPI_ERR("dimmBadDqBitmapAccessHwp: "
- "Error getting spare DRAM data");
+ "Error getting spare DRAM data (Mfg mode)");
break;
}
- // If system is in DISABLE_DRAM_REPAIRS mode
- if (l_allMnfgFlags &
- fapi::ENUM_ATTR_MNFG_FLAGS_MNFG_DISABLE_DRAM_REPAIRS)
+ // Compare l_data, which represents a bad dq bitmap with the
+ // appropriate spare/ECC bits set (if any) and all other DQ
+ // lines functional, to caller's o_data.
+ // If discrepancies are found, we know this is the result of
+ // a manufacturing mode process and these bits should not be
+ // recorded.
+ for (uint8_t i = 0; i < DIMM_DQ_MAX_DIMM_RANKS; i++)
{
- // Flag to set if the discrepancies (described below)
- // are found
- bool mfgModeBadBitsPresent = false;
- // Create a local zero-initialized bad dq bitmap
- l_pBuf = new uint8_t[DIMM_DQ_MAX_DIMM_RANKS]
- [DIMM_DQ_RANK_BITMAP_SIZE]();
- uint8_t (&l_data)[DIMM_DQ_MAX_DIMM_RANKS]
- [DIMM_DQ_RANK_BITMAP_SIZE] =
- *(reinterpret_cast<uint8_t(*)[DIMM_DQ_MAX_DIMM_RANKS]
- [DIMM_DQ_RANK_BITMAP_SIZE]>(l_pBuf));
- // memset to avoid known syntax issue with previous
- // compiler versions and ensure zero initialized array.
- memset(l_data, 0, sizeof(l_data));
-
- // Check ECC.
- l_rc = dimmUpdateDqBitmapEccByte(i_dimm, l_data);
- if (l_rc)
+ for (uint8_t j = 0; j < (DIMM_DQ_RANK_BITMAP_SIZE); j++)
{
- FAPI_ERR("dimmBadDqBitmapAccessHwp: "
- "Error getting ECC data (Mfg mode)");
- break;
+ if (o_data[i][j] != l_data[i][j])
+ {
+ o_data[i][j] = l_data[i][j];
+ mfgModeBadBitsPresent = true;
+ }
}
- // Check spare DRAM
- l_rc = dimmUpdateDqBitmapSpareByte(i_mba, i_dimm, l_data);
+ }
+ // Create and log fapi error if discrepancies were found
+ if (mfgModeBadBitsPresent)
+ {
+ // Get this DIMM's position
+ uint32_t l_dimmPos = 0;
+ l_rc = FAPI_ATTR_GET(ATTR_POS, &i_dimm, l_dimmPos);
if (l_rc)
{
FAPI_ERR("dimmBadDqBitmapAccessHwp: "
- "Error getting spare DRAM data (Mfg mode)");
- break;
+ "Error getting DIMM position,"
+ " reporting as 0xFFFFFFFF");
+ l_dimmPos = 0xFFFFFFFF;
}
- // Compare l_data, which represents a bad dq bitmap with the
- // appropriate spare/ECC bits set (if any) and all other DQ
- // lines functional, to caller's io_data.
- // If discrepancies are found, we know this is the result of
- // a manufacturing mode process and these bits should not be
- // recorded.
- for (uint8_t i = 0; i < DIMM_DQ_MAX_DIMM_RANKS; i++)
+ FAPI_ERR("dimmBadDqBitmapAccessHwp: Read requested while"
+ " in DISABLE_DRAM_REPAIRS mode found"
+ " extra bad bits set for DIMM: %d",
+ l_dimmPos);
+ const fapi::Target & DIMM = i_dimm;
+ FAPI_SET_HWP_ERROR(l_rc,
+ RC_BAD_DQ_MFG_MODE_BITS_FOUND_DURING_GET);
+ fapiLogError(l_rc);
+ }
+ }
+ } while(0);
+ delete [] &l_spdData;
+ delete [] l_pBuf;
+ return l_rc;
+}
+
+/**
+ * @brief Called by dimmBadDqBitmapAccessHwp() to set ATTR_SPD_BAD_DQ_DATA
+ * Also checks if a bad Dq bit is set by first calling dimmBadDqBitmapGet()
+ * and sets ATTR_RECONFIGURE_LOOP with the 'OR' of the current value and
+ * the fapi enum BAD_DQ_BIT_SET if appropriate
+ *
+ * @param[in] i_mba Reference to MBA Target.
+ * @param[in] i_dimm Reference to DIMM Target.
+ * @param[in] i_data Reference to Bad DQ Bitmap set by the caller
+ * @param[in] i_wiringData Reference to Centaur DQ to DIMM Connector
+ * DQ Wiring attribute.
+ * @param[in] i_allMnfgFlags Manufacturing flags bitmap
+ *
+ * @return ReturnCode
+ */
+
+fapi::ReturnCode dimmBadDqBitmapSet(
+ const fapi::Target & i_mba,
+ const fapi::Target & i_dimm,
+ const uint8_t (&i_data)[DIMM_DQ_MAX_DIMM_RANKS][DIMM_DQ_RANK_BITMAP_SIZE],
+ const uint8_t (&i_wiringData)[DIMM_DQ_NUM_DQS],
+ uint64_t i_allMnfgFlags)
+{
+ fapi::ReturnCode l_rc;
+
+ // Read current BadDqBitmap into l_prev_data
+ uint8_t (l_prev_data)[DIMM_DQ_MAX_DIMM_RANKS]
+ [DIMM_DQ_RANK_BITMAP_SIZE];
+ bool badDQSet = false;
+ dimmBadDqBitmapGet(i_mba, i_dimm, l_prev_data, i_wiringData,
+ i_allMnfgFlags);
+
+ // Check if Bad DQ bit set
+ for (uint8_t i = 0; i < DIMM_DQ_MAX_DIMM_RANKS; i++)
+ {
+ for (uint8_t j = 0; j < (DIMM_DQ_RANK_BITMAP_SIZE); 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("dimmBadDqBitmapAccessHwp: Reconfigure needed, Bad DQ set");
+
+ fapi::ATTR_RECONFIGURE_LOOP_Type l_reconfigAttr = 0;
+ l_rc = FAPI_ATTR_GET(ATTR_RECONFIGURE_LOOP, NULL, l_reconfigAttr);
+ if (l_rc)
+ {
+ FAPI_ERR("dimmBadDqBitmapAccessHwp: Error getting "
+ "ATTR_RECONFIGURE_LOOP");
+ return l_rc;
+ }
+
+ // 'OR' values in case of multiple reasons for reconfigure
+ l_reconfigAttr |= fapi::ENUM_ATTR_RECONFIGURE_LOOP_BAD_DQ_BIT_SET;
+
+ l_rc = FAPI_ATTR_SET(ATTR_RECONFIGURE_LOOP, NULL, l_reconfigAttr);
+ if (l_rc)
+ {
+ FAPI_ERR("dimmBadDqBitmapAccessHwp: Error setting "
+ "ATTR_RECONFIGURE_LOOP");
+ return l_rc;
+ }
+ }
+
+ // DQ SPD Attribute
+ uint8_t (&l_spdData)[DIMM_DQ_SPD_DATA_SIZE] =
+ *(reinterpret_cast<uint8_t(*)[DIMM_DQ_SPD_DATA_SIZE]>
+ (new uint8_t[DIMM_DQ_SPD_DATA_SIZE]()));
+
+ // memset to avoid known syntax issue with previous compiler versions
+ // and ensure zero initialized array.
+ memset(l_spdData, 0, sizeof(l_spdData));
+
+ dimmBadDqDataFormat * l_pSpdData =
+ reinterpret_cast<dimmBadDqDataFormat *>(l_spdData);
+
+ // Pointer which will be used to initialize a clean bitmap during
+ // manufacturing mode
+ uint8_t (*l_pBuf)[DIMM_DQ_RANK_BITMAP_SIZE] = NULL;
+
+ do
+ {
+ // If system is in DISABLE_DRAM_REPAIRS mode
+ if (i_allMnfgFlags &
+ fapi::ENUM_ATTR_MNFG_FLAGS_MNFG_DISABLE_DRAM_REPAIRS)
+ {
+ // Flag to set if the discrepancies (described below)
+ // are found
+ bool mfgModeBadBitsPresent = false;
+ // Create a local zero-initialized bad dq bitmap
+ l_pBuf = new uint8_t[DIMM_DQ_MAX_DIMM_RANKS]
+ [DIMM_DQ_RANK_BITMAP_SIZE]();
+ uint8_t (&l_data)[DIMM_DQ_MAX_DIMM_RANKS]
+ [DIMM_DQ_RANK_BITMAP_SIZE] =
+ *(reinterpret_cast<uint8_t(*)[DIMM_DQ_MAX_DIMM_RANKS]
+ [DIMM_DQ_RANK_BITMAP_SIZE]>(l_pBuf));
+ // memset to avoid known syntax issue with previous
+ // compiler versions and ensure zero initialized array.
+ memset(l_data, 0, sizeof(l_data));
+
+ // Check ECC.
+ l_rc = dimmUpdateDqBitmapEccByte(i_dimm, l_data);
+ if (l_rc)
+ {
+ FAPI_ERR("dimmBadDqBitmapAccessHwp: "
+ "Error getting ECC data (Mfg mode)");
+ break;
+ }
+ // Check spare DRAM
+ l_rc = dimmUpdateDqBitmapSpareByte(i_mba, i_dimm, l_data);
+ if (l_rc)
+ {
+ FAPI_ERR("dimmBadDqBitmapAccessHwp: "
+ "Error getting spare DRAM data (Mfg mode)");
+ break;
+ }
+ // Compare l_data, which represents a bad dq bitmap with the
+ // appropriate spare/ECC bits set (if any) and all other DQ
+ // lines functional, to caller's i_data.
+ // If discrepancies are found, we know this is the result of
+ // a manufacturing mode process and these bits should not be
+ // recorded.
+ for (uint8_t i = 0; i < DIMM_DQ_MAX_DIMM_RANKS; i++)
+ {
+ for (uint8_t j = 0; j < (DIMM_DQ_RANK_BITMAP_SIZE); j++)
{
- for (uint8_t j = 0; j < (DIMM_DQ_RANK_BITMAP_SIZE); j++)
+ if (i_data[i][j] != l_data[i][j])
{
- if (io_data[i][j] != l_data[i][j])
- {
- io_data[i][j] = l_data[i][j];
- mfgModeBadBitsPresent = true;
- }
+ mfgModeBadBitsPresent = true;
+ break;
}
}
- // Create and log fapi error if discrepancies were found
+ // Break out of this section when first
+ // discrepancy is noticed
if (mfgModeBadBitsPresent)
{
- // Get this DIMM's position
- uint32_t l_dimmPos = 0;
- l_rc = FAPI_ATTR_GET(ATTR_POS, &i_dimm, l_dimmPos);
- if (l_rc)
- {
- FAPI_ERR("dimmBadDqBitmapAccessHwp: "
- "Error getting DIMM position,"
- " reporting as 0xFFFFFFFF");
- l_dimmPos = 0xFFFFFFFF;
- }
- FAPI_ERR("dimmBadDqBitmapAccessHwp: Read requested while"
- " in DISABLE_DRAM_REPAIRS mode found"
- " extra bad bits set for DIMM: %d",
- l_dimmPos);
- const fapi::Target & DIMM = i_dimm;
- FAPI_SET_HWP_ERROR(l_rc,
- RC_BAD_DQ_MFG_MODE_BITS_FOUND_DURING_GET);
- fapiLogError(l_rc);
+ break;
}
}
- }// Get
- else
- {
- // If system is in DISABLE_DRAM_REPAIRS mode
- if (l_allMnfgFlags &
- fapi::ENUM_ATTR_MNFG_FLAGS_MNFG_DISABLE_DRAM_REPAIRS)
+ // Create and log fapi error if discrepancies were found
+ if (mfgModeBadBitsPresent)
{
- // Flag to set if the discrepancies (described below)
- // are found
- bool mfgModeBadBitsPresent = false;
- // Create a local zero-initialized bad dq bitmap
- l_pBuf = new uint8_t[DIMM_DQ_MAX_DIMM_RANKS]
- [DIMM_DQ_RANK_BITMAP_SIZE]();
- uint8_t (&l_data)[DIMM_DQ_MAX_DIMM_RANKS]
- [DIMM_DQ_RANK_BITMAP_SIZE] =
- *(reinterpret_cast<uint8_t(*)[DIMM_DQ_MAX_DIMM_RANKS]
- [DIMM_DQ_RANK_BITMAP_SIZE]>(l_pBuf));
- // memset to avoid known syntax issue with previous
- // compiler versions and ensure zero initialized array.
- memset(l_data, 0, sizeof(l_data));
-
- // Check ECC.
- l_rc = dimmUpdateDqBitmapEccByte(i_dimm, l_data);
- if (l_rc)
- {
- FAPI_ERR("dimmBadDqBitmapAccessHwp: "
- "Error getting ECC data (Mfg mode)");
- break;
- }
- // Check spare DRAM
- l_rc = dimmUpdateDqBitmapSpareByte(i_mba, i_dimm, l_data);
+ // Get this DIMM's position
+ uint32_t l_dimmPos = 0;
+ l_rc = FAPI_ATTR_GET(ATTR_POS, &i_dimm, l_dimmPos);
if (l_rc)
{
FAPI_ERR("dimmBadDqBitmapAccessHwp: "
- "Error getting spare DRAM data (Mfg mode)");
- break;
- }
- // Compare l_data, which represents a bad dq bitmap with the
- // appropriate spare/ECC bits set (if any) and all other DQ
- // lines functional, to caller's io_data.
- // If discrepancies are found, we know this is the result of
- // a manufacturing mode process and these bits should not be
- // recorded.
- for (uint8_t i = 0; i < DIMM_DQ_MAX_DIMM_RANKS; i++)
- {
- for (uint8_t j = 0; j < (DIMM_DQ_RANK_BITMAP_SIZE); j++)
- {
- if (io_data[i][j] != l_data[i][j])
- {
- mfgModeBadBitsPresent = true;
- break;
- }
- }
- // Break out of this section when first
- // discrepancy is noticed
- if (mfgModeBadBitsPresent)
- {
- break;
- }
+ "Error getting DIMM position,"
+ " reporting as 0xFFFFFFFF");
+ l_dimmPos = 0xFFFFFFFF;
}
- // Create and log fapi error if discrepancies were found
- if (mfgModeBadBitsPresent)
- {
- // Get this DIMM's position
- uint32_t l_dimmPos = 0;
- l_rc = FAPI_ATTR_GET(ATTR_POS, &i_dimm, l_dimmPos);
- if (l_rc)
- {
- FAPI_ERR("dimmBadDqBitmapAccessHwp: "
- "Error getting DIMM position,"
- " reporting as 0xFFFFFFFF");
- l_dimmPos = 0xFFFFFFFF;
- }
- FAPI_ERR("dimmBadDqBitmapAccessHwp: Write requested while"
- " in DISABLE_DRAM_REPAIRS mode found"
- " extra bad bits set for DIMM: %d",
- l_dimmPos);
- const fapi::Target & DIMM = i_dimm;
- FAPI_SET_HWP_ERROR(l_rc,
- RC_BAD_DQ_MFG_MODE_BITS_FOUND_DURING_SET);
- fapiLogError(l_rc);
- }
- // Don't write bad dq bitmap,
- // Break out of do {...} while(0)
- break;
+ FAPI_ERR("dimmBadDqBitmapAccessHwp: Write requested while"
+ " in DISABLE_DRAM_REPAIRS mode found"
+ " extra bad bits set for DIMM: %d",
+ l_dimmPos);
+ const fapi::Target & DIMM = i_dimm;
+ FAPI_SET_HWP_ERROR(l_rc,
+ RC_BAD_DQ_MFG_MODE_BITS_FOUND_DURING_SET);
+ fapiLogError(l_rc);
}
+ // Don't write bad dq bitmap,
+ // Break out of do {...} while(0)
+ break;
+ }
- // Set up the data to write to SPD
- l_pSpdData->iv_magicNumber = FAPI_HTOBE32(DIMM_BAD_DQ_MAGIC_NUMBER);
- l_pSpdData->iv_version = DIMM_BAD_DQ_VERSION;
- l_pSpdData->iv_reserved1 = 0;
- l_pSpdData->iv_reserved2 = 0;
- l_pSpdData->iv_reserved3 = 0;
- memset(l_pSpdData->iv_bitmaps, 0, sizeof(l_pSpdData->iv_bitmaps));
+ // Set up the data to write to SPD
+ l_pSpdData->iv_magicNumber = FAPI_HTOBE32(DIMM_BAD_DQ_MAGIC_NUMBER);
+ l_pSpdData->iv_version = DIMM_BAD_DQ_VERSION;
+ l_pSpdData->iv_reserved1 = 0;
+ l_pSpdData->iv_reserved2 = 0;
+ l_pSpdData->iv_reserved3 = 0;
+ memset(l_pSpdData->iv_bitmaps, 0, sizeof(l_pSpdData->iv_bitmaps));
- // Translate bitmap from Centaur DQ to DIMM DQ point of view for
- // each rank
- for (uint8_t i = 0; i < DIMM_DQ_MAX_DIMM_RANKS; i++)
+ // Translate bitmap from Centaur DQ to DIMM DQ point of view for
+ // each rank
+ for (uint8_t i = 0; i < DIMM_DQ_MAX_DIMM_RANKS; i++)
+ {
+ // Iterate through all the DQ bits in the rank
+ for (uint8_t j = 0; j < DIMM_DQ_NUM_DQS; j++)
{
- // Iterate through all the DQ bits in the rank
- for (uint8_t j = 0; j < DIMM_DQ_NUM_DQS; j++)
+ if ((i_data[i][j/8]) & (0x80 >> (j % 8)))
{
- if ((io_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[j];
- l_pSpdData->iv_bitmaps[i][dBit/8] |=
- (0x80 >> (dBit % 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 = i_wiringData[j];
+ l_pSpdData->iv_bitmaps[i][dBit/8] |=
+ (0x80 >> (dBit % 8));
}
}
+ }
- // Set the SPD DQ attribute
- l_rc = FAPI_ATTR_SET(ATTR_SPD_BAD_DQ_DATA, &i_dimm, l_spdData);
+ // Set the SPD DQ attribute
+ l_rc = FAPI_ATTR_SET(ATTR_SPD_BAD_DQ_DATA, &i_dimm, l_spdData);
+
+ if (l_rc)
+ {
+ FAPI_ERR("dimmBadDqBitmapAccessHwp: Error setting SPD data");
+ break;
+ }
+ } while(0);
+ delete [] &l_spdData;
+ delete [] l_pBuf;
+ return l_rc;
+}
+
+}
+
+extern "C"
+{
+
+fapi::ReturnCode dimmBadDqBitmapAccessHwp(
+ const fapi::Target & i_mba,
+ const fapi::Target & i_dimm,
+ uint8_t (&io_data)[DIMM_DQ_MAX_DIMM_RANKS][DIMM_DQ_RANK_BITMAP_SIZE],
+ const bool i_get)
+{
+ if (i_get)
+ {
+ FAPI_INF(">>dimmBadDqBitmapAccessHwp: Getting bitmap");
+ }
+ else
+ {
+ FAPI_INF(">>dimmBadDqBitmapAccessHwp: Setting bitmap");
+ }
+
+ fapi::ReturnCode l_rc;
+
+ // Note the use of heap based arrays to avoid large stack allocations
+
+ // Centaur DQ to DIMM Connector DQ Wiring attribute.
+ uint8_t (&l_wiringData)[DIMM_DQ_NUM_DQS] =
+ *(reinterpret_cast<uint8_t(*)[DIMM_DQ_NUM_DQS]>
+ (new uint8_t[DIMM_DQ_NUM_DQS]()));
+
+ // memset to avoid known syntax issue with previous compiler versions
+ // and ensure zero initialized array.
+ memset(l_wiringData, 0, sizeof(l_wiringData));
+
+ do
+ {
+ // Manufacturing flags attribute
+ uint64_t l_allMnfgFlags = 0;
+ // Get the manufacturing flags bitmap to be used in both get and set
+ l_rc = FAPI_ATTR_GET(ATTR_MNFG_FLAGS, NULL, l_allMnfgFlags);
+ if(l_rc)
+ {
+ FAPI_ERR("dimmBadDqBitmapAccessHwp: Unable to read attribute"
+ " - ATTR_MNFG_FLAGS");
+ break;
+ }
+ // Get the Centaur DQ to DIMM Connector DQ Wiring attribute.
+ // Note that for C-DIMMs, this will return a simple 1:1 mapping.
+ // This code cannot tell the difference between C-DIMMs and IS-DIMMs.
+ l_rc = FAPI_ATTR_GET(ATTR_CEN_DQ_TO_DIMM_CONN_DQ,
+ &i_dimm, l_wiringData);
+
+ if (l_rc)
+ {
+ FAPI_ERR("dimmBadDqBitmapAccessHwp: "
+ "Error getting wiring attribute");
+ break;
+ }
+
+ if (i_get)
+ {
+ dimmBadDqBitmapGet(i_mba, i_dimm, io_data, l_wiringData,
+ l_allMnfgFlags);
+ }
+ else
+ {
+ dimmBadDqBitmapSet(i_mba, i_dimm, io_data, l_wiringData,
+ l_allMnfgFlags);
+ }
- if (l_rc)
- {
- FAPI_ERR("dimmBadDqBitmapAccessHwp: Error setting SPD data");
- break;
- }
- }// Set
}while(0);
delete [] &l_wiringData;
- delete [] &l_spdData;
- delete [] l_pBuf;
FAPI_INF("<<dimmBadDqBitmapAccessHwp");
return l_rc;
}
diff --git a/src/usr/hwpf/hwp/system_attributes.xml b/src/usr/hwpf/hwp/system_attributes.xml
index b9503bb18..750824b02 100644
--- a/src/usr/hwpf/hwp/system_attributes.xml
+++ b/src/usr/hwpf/hwp/system_attributes.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- IBM CONFIDENTIAL -->
<!-- -->
-<!-- COPYRIGHT International Business Machines Corp. 2012,2013 -->
+<!-- COPYRIGHT International Business Machines Corp. 2012,2014 -->
<!-- -->
<!-- p1 -->
<!-- -->
@@ -248,7 +248,7 @@
<valueType>uint32</valueType>
<enum>
RL0 = 0x000,
- RL100 = 0x100
+ RL100 = 0x100
</enum>
<platInit/>
</attribute>
@@ -287,4 +287,19 @@
<platInit/>
</attribute>
<!-- ********************************************************************* -->
+ <attribute>
+ <id>ATTR_RECONFIGURE_LOOP</id>
+ <targetType>TARGET_TYPE_SYSTEM</targetType>
+ <description>
+ Used to inidicate if a reconfigure loop is needed
+ </description>
+ <valueType>uint8</valueType>
+ <enum>
+ DECONFIGURE = 0x1,
+ BAD_DQ_BIT_SET = 0x2
+ </enum>
+ <platInit/>
+ <writeable/>
+ </attribute>
+ <!-- ********************************************************************* -->
</attributes>
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C
index cf0718126..90007d6fe 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.C
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C
@@ -257,7 +257,7 @@ errlHndl_t IStepDispatcher::executeAllISteps()
errlHndl_t err = NULL;
uint32_t istep = 0;
uint32_t substep = 0;
- bool l_deconfigs = false;
+ bool l_doReconfig = false;
uint32_t numReconfigs = 0;
const uint32_t MAX_NUM_RECONFIG_ATTEMPTS = 30;
@@ -268,10 +268,10 @@ errlHndl_t IStepDispatcher::executeAllISteps()
substep = 0;
while (substep < g_isteps[istep].numitems)
{
- err = doIstep(istep, substep, l_deconfigs);
+ err = doIstep(istep, substep, l_doReconfig);
- // there were HW deconfigures that happened during the istep
- if (l_deconfigs)
+ // Something occurred that requires a reconfig loop
+ if (l_doReconfig)
{
TRACFCOMP(g_trac_initsvc,
ERR_MRK"executeAllISteps: Deconfigure(s) during IStep %d:%d",
@@ -402,10 +402,10 @@ errlHndl_t IStepDispatcher::executeAllISteps()
// ----------------------------------------------------------------------------
errlHndl_t IStepDispatcher::doIstep(uint32_t i_istep,
uint32_t i_substep,
- bool & o_deconfigs)
+ bool & o_doReconfig)
{
errlHndl_t err = NULL;
- o_deconfigs = false;
+ o_doReconfig = false;
// Get the Task Info for this step
const TaskInfo * theStep = findTaskInfo(i_istep, i_substep);
@@ -463,7 +463,10 @@ errlHndl_t IStepDispatcher::doIstep(uint32_t i_istep,
iv_istepModulesLoaded = i_istep;
}
- uint32_t preDeconfigs = HWAS::theDeconfigGard().getDeconfigureStatus();
+ // Zero ATTR_RECONFIGURE_LOOP
+ TARGETING::Target* l_pTopLevel = NULL;
+ TARGETING::targetService().getTopLevelTarget(l_pTopLevel);
+ l_pTopLevel->setAttr<TARGETING::ATTR_RECONFIGURE_LOOP>(0);
err = InitService::getTheInstance().executeFn(theStep, NULL);
@@ -526,13 +529,13 @@ errlHndl_t IStepDispatcher::doIstep(uint32_t i_istep,
HWAS::theDeconfigGard().processDeferredDeconfig();
}
- uint32_t postDeconfigs = HWAS::theDeconfigGard().getDeconfigureStatus();
-
- if (postDeconfigs != preDeconfigs)
+ // Check if ATTR_RECONFIGURE_LOOP is non-zero
+ TARGETING::ATTR_RECONFIGURE_LOOP_type l_reconfigAttr = l_pTopLevel->getAttr<TARGETING::ATTR_RECONFIGURE_LOOP>();
+ if (l_reconfigAttr)
{
- TRACFCOMP(g_trac_initsvc, ERR_MRK"doIstep: Deconfigs happened, pre:%d, post:%d",
- preDeconfigs, postDeconfigs);
- o_deconfigs = true;
+ TRACFCOMP(g_trac_initsvc, ERR_MRK"doIstep: Reconfigure needed, ATTR_RECONFIGURE_LOOP = %d",
+ l_reconfigAttr);
+ o_doReconfig = true;
}
TRACFCOMP(g_trac_initsvc, EXIT_MRK"doIstep: step %d, substep %d",
@@ -1081,7 +1084,7 @@ void IStepDispatcher::iStepBreakPoint(uint32_t i_info)
void IStepDispatcher::handleIStepRequestMsg(msg_t * & io_pMsg)
{
errlHndl_t err = NULL;
- bool l_deconfigs = false;
+ bool l_doReconfig = false;
// find the step/substep. The step is in the top 32bits, the substep is in
// the bottom 32bits and is a byte
@@ -1101,10 +1104,11 @@ void IStepDispatcher::handleIStepRequestMsg(msg_t * & io_pMsg)
io_pMsg = NULL;
mutex_unlock(&iv_mutex);
- err = doIstep (istep, substep, l_deconfigs);
+ err = doIstep (istep, substep, l_doReconfig);
- // If there was no IStep error, but there were deconfig(s)
- if ((!err) && l_deconfigs)
+ // If there was no IStep error, but something happened that requires a
+ // reconfigure
+ if ((!err) && l_doReconfig)
{
uint8_t newIstep = 0;
uint8_t newSubstep = 0;
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.H b/src/usr/initservice/istepdispatcher/istepdispatcher.H
index c3382fe3b..2cd8000da 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.H
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.H
@@ -193,15 +193,14 @@ private:
/**
* @brief Executes the given istep
*
- * @param[in] i_istep The istep to be executed.
- * @param[in] i_substep The substep to be executed.
- * @param[out] o_deconfigs If error returned then true if HW was
- * deconfigured during the istep
- * @return errlHndl_t
+ * @param[in] i_istep The istep to be executed.
+ * @param[in] i_substep The substep to be executed.
+ * @param[out] o_doReconfig True if something ocurred that requires a
+ * reconfigure, false otherwise
*/
errlHndl_t doIstep(uint32_t i_istep,
uint32_t i_substep,
- bool & o_deconfigs);
+ bool & o_doReconfig);
/**
* @brief Handles all messages from the FSP or SPless user console
diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml
index 7dacc8817..7b2c7bed9 100644
--- a/src/usr/targeting/common/xmltohb/attribute_types.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types.xml
@@ -12872,4 +12872,42 @@ firmware notes: Platforms should initialize this attribute to AUTO (0)</descript
</hwpfToHbAttrMap>
</attribute>
+<attribute>
+ <id>RECONFIGURE_LOOP</id>
+ <description>
+ Used to inidicate if a reconfigure loop is needed.
+ Hostboot clears and sets this during istep dispatching.
+ </description>
+ <simpleType>
+ <uint8_t></uint8_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+ <hwpfToHbAttrMap>
+ <id>ATTR_RECONFIGURE_LOOP</id>
+ <macro>DIRECT</macro>
+ </hwpfToHbAttrMap>
+</attribute>
+
+<enumerationType>
+ <id>RECONFIGURE_LOOP</id>
+ <description>Enumeration of RECONFIGURE_LOOP flags</description>
+ <!-- add enumerators (single bits) for anything that needs a reconfigure loop -->
+ <enumerator>
+ <description>
+ Indicates HW has been deconfigured
+ </description>
+ <name>DECONFIGURE</name>
+ <value>0x01</value>
+ </enumerator>
+ <enumerator>
+ <description>
+ Indicates a bad DQ bit was set in the BadDqBitmap
+ </description>
+ <name>BAD_DQ_BIT_SET</name>
+ <value>0x02</value>
+ </enumerator>
+</enumerationType>
+
</attributes>
diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml
index 0ff71f9ca..46d7d5dcf 100644
--- a/src/usr/targeting/common/xmltohb/target_types.xml
+++ b/src/usr/targeting/common/xmltohb/target_types.xml
@@ -220,6 +220,7 @@
<attribute><id>MRW_DIMM_POWER_CURVE_PERCENT_UPLIFT</id></attribute>
<attribute><id>MRW_MEM_THROTTLE_DENOMINATOR</id></attribute>
<attribute><id>MRW_MAX_DRAM_DATABUS_UTIL</id></attribute>
+ <attribute><id>RECONFIGURE_LOOP</id></attribute>
</targetType>
<targetType>
OpenPOWER on IntegriCloud