diff options
author | Stephen Cprek <smcprek@us.ibm.com> | 2013-12-17 15:46:21 -0600 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2014-01-16 11:19:10 -0600 |
commit | 63f42d36ee3f78e59d0acb19ccdcf1766f0050bd (patch) | |
tree | 46c2f3096d795bf28a27979e551f27b1dc7b5e39 /src/usr | |
parent | 542d9f0c4bb7e1b37a15823fa0b642e4f3bf7410 (diff) | |
download | talos-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.C | 25 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/dimmBadDqBitmapAccessHwp.C | 677 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/system_attributes.xml | 19 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/istepdispatcher.C | 38 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/istepdispatcher.H | 11 | ||||
-rw-r--r-- | src/usr/targeting/common/xmltohb/attribute_types.xml | 38 | ||||
-rw-r--r-- | src/usr/targeting/common/xmltohb/target_types.xml | 1 |
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> |