summaryrefslogtreecommitdiffstats
path: root/src/import/chips
diff options
context:
space:
mode:
authorAndre Marin <aamarin@us.ibm.com>2017-02-09 12:48:41 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-07-26 00:26:28 -0400
commit7b5b072e03694fa9f9b72cfd761b8b384734541a (patch)
tree47eb7d8b57f122b25a9a5be11fc86410bf63cd02 /src/import/chips
parent59bc3c6833ea12e8775e8184ef72da92dc85c07c (diff)
downloadtalos-hostboot-7b5b072e03694fa9f9b72cfd761b8b384734541a.tar.gz
talos-hostboot-7b5b072e03694fa9f9b72cfd761b8b384734541a.zip
Add initial p9c ddr_phy_reset, dimmBadDqBitmapAccessHwp, slew, & unmask_errors
Change-Id: I277496652e951e67dc2f3815633432cb00a02c62 Original-Change-Id: I1cbe3225208e6ee6c107ff84a9ebbb6248f0c7b8 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/35429 Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: JACOB L. HARVEY <jlharvey@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/43533 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: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips')
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapAccessHwp.C605
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapAccessHwp.H78
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapAccessHwp.mk33
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapFuncs.C186
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapFuncs.H92
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapFuncs.mk33
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr_phy_reset.C717
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr_phy_reset.H55
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr_phy_reset.mk34
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.C2285
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.H161
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.mk32
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/wrapper/p9c_mss_ddr_phy_reset_wrap.C287
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/wrapper/p9c_mss_ddr_phy_reset_wrap.mk29
14 files changed, 4627 insertions, 0 deletions
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapAccessHwp.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapAccessHwp.C
new file mode 100644
index 000000000..92b8eaff3
--- /dev/null
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapAccessHwp.C
@@ -0,0 +1,605 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapAccessHwp.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file p9c_dimmBadDqBitmapAccessHwp.C
+/// @brief FW Team HWP that accesses the Bad DQ Bitmap.
+///
+/// *HWP HWP Owner: Luke Mulkey <lwmulkey@us.ibm.com>
+/// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+/// *HWP Team: Memory
+/// *HWP Level: 2
+/// *HWP Consumed by: HB:CI
+///
+
+#include <fapi2.H>
+#include <p9c_dimmBadDqBitmapAccessHwp.H>
+
+// DQ Data format in DIMM SPD
+enum dq_data : size_t
+{
+ DIMM_BAD_DQ_MAGIC_NUMBER = 0xbadd4471,
+ DIMM_BAD_DQ_VERSION = 1,
+ ECC_DQ_BYTE_NUMBER_INDEX = 8,
+ SPARE_DRAM_DQ_BYTE_NUMBER_INDEX = 9,
+};
+
+///
+/// @class dimmBadDqDataFormat
+/// @brief Structure that holds 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[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE];
+
+ ///
+ /// @brief default ctor
+ ///
+ dimmBadDqDataFormat() = default;
+
+ ///
+ /// @brief default dtor
+ ///
+ ~dimmBadDqDataFormat() = default;
+};
+
+extern "C"
+{
+
+ ///
+ /// @brief Returns bits for unconnected spare DRAM.
+ /// @param[in] i_mba Reference to MBA
+ /// @param[in] i_dimm Reference to DIMM
+ /// @param[out] o_spareByte Reference to the spare byte returned to caller.
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode dimmGetDqBitmapSpareByte(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_mba,
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_dimm,
+ uint8_t (&o_spareByte)[MAX_RANKS_PER_DIMM])
+ {
+ // Spare DRAM Attribute: Returns spare DRAM availability for
+ // all DIMMs associated with the target MBA.
+ uint8_t l_mbaSpare[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT][MAX_RANKS_PER_DIMM] = {};
+ uint8_t l_mbaPort = 0;
+ uint8_t l_dimm = 0;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_VPD_DIMM_SPARE, i_mba, l_mbaSpare));
+ // Find the mba port this dimm is connected to
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_MBA_PORT, i_dimm, l_mbaPort));
+ // Find the dimm number associated with this dimm
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_MBA_DIMM, i_dimm, l_dimm));
+
+ // Iterate through each rank of this DIMM
+ for (uint8_t i = 0; i < MAX_RANKS_PER_DIMM; ++i)
+ {
+ // Handle spare DRAM configuration cases
+ switch (l_mbaSpare[l_mbaPort][l_dimm][i])
+ {
+ case fapi2::ENUM_ATTR_CEN_VPD_DIMM_SPARE_NO_SPARE:
+ // Set DQ bits reflecting unconnected
+ // spare DRAM in caller's data
+ o_spareByte[i] = 0xFF;
+ break;
+
+ case fapi2::ENUM_ATTR_CEN_VPD_DIMM_SPARE_LOW_NIBBLE:
+ o_spareByte[i] = 0x0F;
+ break;
+
+ case fapi2::ENUM_ATTR_CEN_VPD_DIMM_SPARE_HIGH_NIBBLE:
+ o_spareByte[i] = 0xF0;
+ break;
+
+ // As erroneous value will not be encountered.
+ case fapi2::ENUM_ATTR_CEN_VPD_DIMM_SPARE_FULL_BYTE:
+ default:
+ o_spareByte[i] = 0x0;
+ break;
+ }
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Called by dimmBadDqBitmapAccessHwp() to query ATTR_EFF_DIMM_SPARE
+ /// and set bits for unconnected spare DRAM in caller's data.
+ /// @param[in] i_mba Reference to MBA Target
+ /// @param[in] i_dimm Reference to DIMM Target
+ /// @param[out] o_data Reference to Bad DQ Bitmap set by
+ /// the caller. Only the SPARE_DRAM_DQ_BYTE_NUMBER_INDEX
+ /// byte is modified by this function.
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+
+ fapi2::ReturnCode dimmUpdateDqBitmapSpareByte(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_mba,
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_dimm,
+ uint8_t (&o_data)[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE])
+ {
+
+ uint8_t spareByte[MAX_RANKS_PER_DIMM] = {};
+ memset(spareByte, 0, sizeof(spareByte));
+
+ FAPI_TRY(dimmGetDqBitmapSpareByte(i_mba, i_dimm, spareByte));
+
+ for (uint32_t i = 0; i < MAX_RANKS_PER_DIMM; ++i)
+ {
+ o_data[i][SPARE_DRAM_DQ_BYTE_NUMBER_INDEX] |= spareByte[i];
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Called by dimmBadDqBitmapAccessHwp() to query
+ /// ATTR_SPD_MODULE_MEMORY_BUS_WIDTH in order to determine
+ /// ECC support for this DIMM. This function will set
+ /// bits in the caller's data if ECC lines are not present.
+ /// @param[in] i_dimm Reference to DIMM Target<fapi2::TARGET_TYPE_MBA>.
+ /// @param[out] o_data Reference to Bad DQ Bitmap set by
+ /// the caller. Only the ECC_DQ_BYTE_NUMBER_INDEX
+ /// byte is modified by this function.
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ////
+ fapi2::ReturnCode dimmUpdateDqBitmapEccByte( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_dimm,
+ uint8_t (&o_data)[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE])
+ {
+ // Memory Bus Width Attribute
+ uint8_t l_eccBits = 0;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_SPD_MODULE_MEMORY_BUS_WIDTH, i_dimm, l_eccBits));
+
+ // The ATTR_SPD_MODULE_MEMORY_BUS_WIDTH contains ENUM values
+ // for bus widths of 8, 16, 32, and 64 bits both with ECC
+ // and without ECC. WExx ENUMS deonote the ECC extension
+ // is present, and all have bit 3 set. Therefore,
+ // it is only required to check against the WE8 = 0x08 ENUM
+ // value in order to determine if ECC lines are present.
+
+ // If ECCs are disconnected
+ if (!(fapi2::ENUM_ATTR_CEN_SPD_MODULE_MEMORY_BUS_WIDTH_WE8 & l_eccBits))
+ {
+ // Iterate through each rank and set DQ bits in
+ // caller's data.
+ for (uint8_t i = 0; i < MAX_RANKS_PER_DIMM; ++i)
+ {
+ // Set DQ bits in caller's data
+ o_data[i][ECC_DQ_BYTE_NUMBER_INDEX] = 0xFF;
+ }
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @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[out] 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 FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode dimmBadDqBitmapGet(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_mba,
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_dimm,
+ uint8_t (&o_data)[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE],
+ const uint8_t (&i_wiringData)[DIMM_DQ_NUM_DQS],
+ const uint64_t i_allMnfgFlags)
+ {
+
+ // 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] = nullptr;
+
+ // Get the SPD DQ attribute
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_SPD_BAD_DQ_DATA, i_dimm, l_spdData));
+
+ // 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 ((be32toh(l_pSpdData->iv_magicNumber) != DIMM_BAD_DQ_MAGIC_NUMBER) ||
+ (l_pSpdData->iv_version != DIMM_BAD_DQ_VERSION))
+ {
+ FAPI_INF("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 < MAX_RANKS_PER_DIMM; ++i)
+ {
+ // 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
+ const size_t BYTE_NUM = j / 8;
+ const size_t DQ_BIT_MASK = 0x80 >> (j % 8);
+
+ if ((l_pSpdData->iv_bitmaps[i][BYTE_NUM]) & DQ_BIT_MASK)
+ {
+ // 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)
+ {
+ o_data[i][k / 8] |= (0x80 >> (k % 8));
+ break;
+ }
+ }
+
+ if (k == DIMM_DQ_NUM_DQS)
+ {
+ FAPI_INF("Centaur DQ not found for %d!", j);
+ }
+ }
+ }// DIMM_DQ_NUM_DQS
+ } // MAX_RANKS_PER_DIMM
+ }// end else
+
+ // Set bits for any unconnected DQs.
+ // First, check ECC.
+ FAPI_TRY(dimmUpdateDqBitmapEccByte(i_dimm, o_data));
+
+ // Check spare DRAM
+ FAPI_TRY(dimmUpdateDqBitmapSpareByte(i_mba, i_dimm, o_data));
+
+ // If system is in DISABLE_DRAM_REPAIRS mode
+ if (i_allMnfgFlags & fapi2::ENUM_ATTR_MNFG_FLAGS_MNFG_DISABLE_DRAM_REPAIRS)
+ {
+ // Create a local zero-initialized bad dq bitmap
+ l_pBuf = new uint8_t[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE]();
+
+ uint8_t (&l_data)[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE] =
+ *(reinterpret_cast<uint8_t(*)[MAX_RANKS_PER_DIMM][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.
+ FAPI_TRY(dimmUpdateDqBitmapEccByte(i_dimm, l_data));
+ // Check spare DRAM
+ FAPI_TRY(dimmUpdateDqBitmapSpareByte(i_mba, i_dimm, l_data));
+
+ // 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 < MAX_RANKS_PER_DIMM; ++i)
+ {
+ for (uint8_t j = 0; j < (DIMM_DQ_RANK_BITMAP_SIZE); ++j)
+ {
+ // Create and log fapi2 error if discrepancies were found
+ // Get this DIMM's position
+ uint32_t l_dimm_pos = 0;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_POS, i_dimm, l_dimm_pos));
+
+ FAPI_ASSERT_NOEXIT(o_data[i][j] != l_data[i][j],
+ fapi2::CEN_BAD_DQ_MFG_MODE_BITS_FOUND_DURING_GET().
+ set_CLEAN_BAD_DQ_BITMAP_RANK0(l_data[0][j]).
+ set_CLEAN_BAD_DQ_BITMAP_RANK1(l_data[1][j]).
+ set_CLEAN_BAD_DQ_BITMAP_RANK2(l_data[2][j]).
+ set_CLEAN_BAD_DQ_BITMAP_RANK3(l_data[3][j]).
+ set_CURRENT_BAD_DQ_BITMAP_RANK0(o_data[0][j]).
+ set_CURRENT_BAD_DQ_BITMAP_RANK1(o_data[1][j]).
+ set_CURRENT_BAD_DQ_BITMAP_RANK2(o_data[2][j]).
+ set_CURRENT_BAD_DQ_BITMAP_RANK3(o_data[3][j]).
+ set_DIMM(i_dimm),
+ "Read requested while in DISABLE_DRAM_REPAIRS mode found"
+ " extra bad bits set for rank:%d, DQ rank bitmap num:%d, DIMM pos: %d",
+ i, j, l_dimm_pos);
+ }// bitmap size
+ }// ranks
+
+ // correct the output bit map
+ for (uint8_t i = 0; i < MAX_RANKS_PER_DIMM; ++i)
+ {
+ for (uint8_t j = 0; j < (DIMM_DQ_RANK_BITMAP_SIZE); ++j)
+ {
+ o_data[i][j] = l_data[i][j];
+ }
+ }// end for
+ }
+
+ delete [] &l_spdData;
+ delete [] l_pBuf;
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @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 fapi2 enum BAD_DQ_BIT_SET if appropriate
+ /// @param[in] i_mba Reference to MBA Target<fapi2::TARGET_TYPE_MBA>.
+ /// @param[in] i_dimm Reference to DIMM Target<fapi2::TARGET_TYPE_MBA>.
+ /// @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 FAPI2_RC_SUCCESS
+ ///
+
+ fapi2::ReturnCode dimmBadDqBitmapSet( const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_mba,
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_dimm,
+ const uint8_t (&i_data)[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE],
+ const uint8_t (&i_wiringData)[DIMM_DQ_NUM_DQS],
+ const uint64_t i_allMnfgFlags)
+ {
+ // Read current BadDqBitmap into l_prev_data
+ uint8_t l_prev_data[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE] = {};
+ bool badDQSet = false;
+
+ // 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]()));
+
+ fapi2::ATTR_RECONFIGURE_LOOP_Type l_reconfigAttr = 0;
+ 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] = nullptr;
+ uint8_t spareByte[MAX_RANKS_PER_DIMM] = {};
+
+ FAPI_TRY(dimmBadDqBitmapGet(i_mba, i_dimm, l_prev_data, i_wiringData, i_allMnfgFlags));
+
+ // Check if Bad DQ bit set
+ for (uint8_t i = 0; i < MAX_RANKS_PER_DIMM; ++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("Reconfigure needed, Bad DQ set");
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_RECONFIGURE_LOOP, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), l_reconfigAttr));
+
+ // 'OR' values in case of multiple reasons for reconfigure
+ l_reconfigAttr |= fapi2::ENUM_ATTR_RECONFIGURE_LOOP_BAD_DQ_BIT_SET;
+
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_RECONFIGURE_LOOP, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), l_reconfigAttr));
+ }
+
+ // memset to avoid known syntax issue with previous compiler versions
+ // and ensure zero initialized array.
+ memset(l_spdData, 0, sizeof(l_spdData));
+
+ // If system is in DISABLE_DRAM_REPAIRS mode
+ if (i_allMnfgFlags & fapi2::ENUM_ATTR_MNFG_FLAGS_MNFG_DISABLE_DRAM_REPAIRS)
+ {
+ // Create a local zero-initialized bad dq bitmap
+ l_pBuf = new uint8_t[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE]();
+
+ uint8_t (&l_data)[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE] =
+ *(reinterpret_cast<uint8_t(*)[MAX_RANKS_PER_DIMM][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.
+ FAPI_TRY(dimmUpdateDqBitmapEccByte(i_dimm, l_data));
+ // Check spare DRAM
+ FAPI_TRY(dimmUpdateDqBitmapSpareByte(i_mba, i_dimm, l_data));
+
+ // 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 < MAX_RANKS_PER_DIMM; ++i)
+ {
+ for (uint8_t j = 0; j < (DIMM_DQ_RANK_BITMAP_SIZE); ++j)
+ {
+ // Create and log fapi2 error if discrepancies were found
+ // Get this DIMM's position
+ uint32_t l_dimm_pos = 0;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_POS, i_dimm, l_dimm_pos));
+
+ FAPI_ASSERT(i_data[i][j] != l_data[i][j],
+ fapi2::CEN_BAD_DQ_MFG_MODE_BITS_FOUND_DURING_SET().
+ set_CLEAN_BAD_DQ_BITMAP_RANK0(l_data[0][j]).
+ set_CLEAN_BAD_DQ_BITMAP_RANK1(l_data[1][j]).
+ set_CLEAN_BAD_DQ_BITMAP_RANK2(l_data[2][j]).
+ set_CLEAN_BAD_DQ_BITMAP_RANK3(l_data[3][j]).
+ set_UPDATE_BAD_DQ_BITMAP_RANK0(i_data[0][j]).
+ set_UPDATE_BAD_DQ_BITMAP_RANK1(i_data[1][j]).
+ set_UPDATE_BAD_DQ_BITMAP_RANK2(i_data[2][j]).
+ set_UPDATE_BAD_DQ_BITMAP_RANK3(i_data[3][j]).
+ set_DIMM(i_dimm),
+ "Write requested while in DISABLE_DRAM_REPAIRS mode"
+ " extra bad bits set for rank:%d, DQ rank bitmap num:%d, DIMM pos: %d",
+ i, j, l_dimm_pos);
+ }
+ }
+ }
+
+ // Set up the data to write to SPD
+ l_pSpdData->iv_magicNumber = 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));
+
+ // Get the spare byte
+ memset(spareByte, 0, sizeof(spareByte));
+
+ FAPI_TRY(dimmGetDqBitmapSpareByte(i_mba, i_dimm, spareByte));
+
+ // Translate bitmap from Centaur DQ to DIMM DQ point of view for
+ // each rank
+ for (uint8_t i = 0; i < MAX_RANKS_PER_DIMM; ++i)
+ {
+ // Iterate through all the DQ bits in the rank
+ for (uint8_t j = 0; j < DIMM_DQ_NUM_DQS; ++j)
+ {
+ const size_t BYTE_NUM = j / 8;
+ const size_t DQ_BIT_MASK = 0x80 >> (j % 8);
+
+ if ((BYTE_NUM) == 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] & DQ_BIT_MASK)
+ {
+ continue;
+ }
+ }
+
+ if ((i_data[i][BYTE_NUM]) & DQ_BIT_MASK)
+ {
+ // 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));
+ }
+ }// dq
+ }// ranks
+
+ // Set the SPD DQ attribute
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_CEN_SPD_BAD_DQ_DATA, i_dimm, l_spdData));
+
+ fapi_try_exit:
+ delete [] &l_spdData;
+ delete [] l_pBuf;
+
+ return fapi2::current_err;
+ }
+
+ /// @brief FW Team HWP that accesses the Bad DQ Bitmap.
+ /// It accesses the raw data from DIMM SPD and does
+ /// any necessary processing to turn it into a
+ /// bitmap from a Centaur DQ point of view. If the data in SPD is not
+ /// valid then it has never been written and all zeroes are returned (no
+ /// bad DQs).
+ ///
+ /// This HWP should be called by HWP/PLAT code to access the BAD DQ Bitmap
+ ///
+ /// @param[in] i_mba Reference to MBA Target
+ /// @param[in] i_dimm Reference to DIMM Target
+ /// @param[in,out] io_data Reference to bad DQ bitmap data for the DIMM.
+ /// @param[in] i_get True if getting DQ Bitmap data. False if setting data.
+ /// @return FAPI2_RC_SUCCESS iff okay
+ /// @note that the MSB of each byte corresponds to the lowest DQ.
+ /// if (data[1][0] == 0x80) then rank 1, Centaur DQ0 is bad
+ /// if (data[1][0] == 0x40) then rank 1, Centaur DQ1 is bad
+ /// if (data[1][1] == 0x20) then rank 1, Centaur DQ10 is bad
+ ///
+ fapi2::ReturnCode dimmBadDqBitmapAccessHwp(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_mba,
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_dimm,
+ uint8_t (&io_data)[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE],
+ const bool i_get)
+ {
+ // 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));
+
+ // Manufacturing flags attribute
+ uint64_t l_allMnfgFlags = 0;
+
+ // Get the manufacturing flags bitmap to be used in both get and set
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MNFG_FLAGS, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), l_allMnfgFlags));
+
+ // 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.
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_DQ_TO_DIMM_CONN_DQ,
+ i_dimm, l_wiringData));
+
+ if (i_get)
+ {
+ FAPI_INF("Getting bitmap");
+ FAPI_TRY(dimmBadDqBitmapGet(i_mba, i_dimm, io_data, l_wiringData, l_allMnfgFlags));
+ }
+ else
+ {
+ FAPI_INF("Setting bitmap");
+ FAPI_TRY(dimmBadDqBitmapSet(i_mba, i_dimm, io_data, l_wiringData, l_allMnfgFlags));
+ }
+
+ fapi_try_exit:
+ delete [] &l_wiringData;
+ FAPI_DBG("End");
+
+ return fapi2::current_err;
+ }
+
+}// extern C
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapAccessHwp.H b/src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapAccessHwp.H
new file mode 100755
index 000000000..95a837775
--- /dev/null
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapAccessHwp.H
@@ -0,0 +1,78 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapAccessHwp.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file p9c_dimmBadDqBitmapAccessHwp.H
+/// @brief FW Team HWP that accesses the Bad DQ Bitmap.
+///
+/// *HWP HWP Owner: Luke Mulkey <lwmulkey@us.ibm.com>
+/// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+/// *HWP Team: Memory
+/// *HWP Level: 2
+/// *HWP Consumed by: HB
+////
+//
+#ifndef DIMMBADDQBITMAPACCESSHWP_H_
+#define DIMMBADDQBITMAPACCESSHWP_H_
+
+#include <fapi2.H>
+#include <dimmConsts.H>
+
+typedef fapi2::ReturnCode (*p9c_dimmBadDqBitmapAccessHwp_FP_t)(const fapi2::Target<fapi2::TARGET_TYPE_MBA>&,
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&,
+ const uint8_t (&)[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE],
+ const bool);
+
+extern "C"
+{
+
+ ///
+ /// @brief FW Team HWP that accesses the Bad DQ Bitmap.
+ /// It accesses the raw data from DIMM SPD and does
+ /// any necessary processing to turn it into a
+ /// bitmap from a Centaur DQ point of view. If the data in SPD is not
+ /// valid then it has never been written and all zeroes are returned (no
+ /// bad DQs).
+ ///
+ /// This HWP should be called by HWP/PLAT code to access the BAD DQ Bitmap
+ ///
+ /// @param[in] i_mba Reference to MBA Target
+ /// @param[in] i_dimm Reference to DIMM Target
+ /// @param[in,out] io_data Reference to bad DQ bitmap data for the DIMM.
+ /// @param[in] i_get True if getting DQ Bitmap data. False if setting data.
+ /// @return FAPI2_RC_SUCCESS iff okay
+ /// @note that the MSB of each byte corresponds to the lowest DQ.
+ /// if (data[1][0] == 0x80) then rank 1, Centaur DQ0 is bad
+ /// if (data[1][0] == 0x40) then rank 1, Centaur DQ1 is bad
+ /// if (data[1][1] == 0x20) then rank 1, Centaur DQ10 is bad
+ ///
+ fapi2::ReturnCode dimmBadDqBitmapAccessHwp(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_mba,
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_dimm,
+ uint8_t (&io_data)[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE],
+ const bool i_get);
+
+}
+
+#endif
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapAccessHwp.mk b/src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapAccessHwp.mk
new file mode 100755
index 000000000..6535d8ba3
--- /dev/null
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapAccessHwp.mk
@@ -0,0 +1,33 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapAccessHwp.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2016,2017
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+# Include the macros and things for MSS procedures
+-include 01common.mk
+
+PROCEDURE=p9c_dimmBadDqBitmapAccessHwp
+$(eval $(call ADD_MEMORY_INCDIRS,$(PROCEDURE)))
+#lib$(PROCEDURE)_DEPLIBS+=mss
+$(call BUILD_PROCEDURE)
+
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapFuncs.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapFuncs.C
new file mode 100755
index 000000000..d29ebf4d8
--- /dev/null
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapFuncs.C
@@ -0,0 +1,186 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapFuncs.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file p9c_dimmBadDqBitmapFuncs.C
+/// @brief FW Team Utility functions that accesses the Bad DQ Bitmap.
+///
+/// *HWP HWP Owner: Luke Mulkey <lwmulkey@us.ibm.com>
+/// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+/// *HWP Team: Memory
+/// *HWP Level: 2
+/// *HWP Consumed by: HB:CI
+///
+
+#include <p9c_dimmBadDqBitmapFuncs.H>
+#include <p9c_dimmBadDqBitmapAccessHwp.H>
+#include <string.h>
+#include <c_str.H>
+
+
+extern "C"
+{
+ ///
+ /// @brief Utility function to check parameters and find a DIMM target
+ /// @param[in] i_mba mba target
+ /// @param[in] i_port Port number
+ /// @param[in] i_dimm Dimm number
+ /// @param[in] i_rank Rank number
+ /// @param[out] o_dimm Dimm target
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode dimmBadDqCheckParamFindDimm(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_mba,
+ const uint8_t i_port,
+ const uint8_t i_dimm,
+ const uint8_t i_rank,
+ fapi2::Target<fapi2::TARGET_TYPE_DIMM>& o_dimm)
+ {
+ uint8_t l_port = 0;
+ uint8_t l_dimm = 0;
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>> l_dimms;
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>::const_iterator dimmIter;
+
+ FAPI_ASSERT((i_port < MAX_PORTS_PER_MBA) &&
+ (i_dimm < MAX_DIMM_PER_PORT) &&
+ (i_rank < MAX_RANKS_PER_DIMM),
+ fapi2::CEN_BAD_DQ_DIMM_BAD_PARAM().
+ set_FFDC_PORT(i_port).
+ set_FFDC_DIMM(i_dimm).
+ set_FFDC_RANK(i_rank),
+ "dimmBadDqCheckParamFindDimm: %s Bad parameter. %d:%d:%d",
+ mss::c_str(i_mba), i_port, i_dimm, i_rank);
+
+ // Get the functional DIMMs associated with the MBA chiplet
+ l_dimms = i_mba.getChildren<fapi2::TARGET_TYPE_DIMM>();
+ // Find the DIMM with the correct MBA port/dimm
+
+ for (dimmIter = l_dimms.begin(); dimmIter != l_dimms.end(); ++dimmIter)
+ {
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_MBA_PORT, *dimmIter, l_port));
+
+ if (l_port == i_port)
+ {
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_MBA_DIMM, *dimmIter, l_dimm));
+
+ if (l_dimm == i_dimm)
+ {
+ o_dimm = *dimmIter;
+ break;
+ }
+ }
+ }
+
+ FAPI_ASSERT(dimmIter != l_dimms.end(),
+ fapi2::CEN_BAD_DQ_DIMM_NOT_FOUND().
+ set_FFDC_PORT(i_port).
+ set_FFDC_DIMM(i_dimm),
+ "dimmBadDqCheckParamFindDimm: "
+ "Did not find DIMM for %s:%d:%d",
+ mss::c_str(i_mba), i_port, i_dimm);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief FW Team Utility function that gets the Bad DQ Bitmap.
+ /// @param[in] i_mba Reference to MBA Chiplet
+ /// @param[in] i_port MBA port number (0-(MAX_PORTS_PER_MBA - 1))
+ /// @param[in] i_dimm MBA port DIMM number (0-(MAX_DIMM_PER_PORT - 1))
+ /// @param[in] i_rank DIMM rank number (0-(MAX_RANKS_PER_DIMM -1))
+ /// @param[out] o_data Reference to data where Bad DQ bitmap is copied to
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode dimmGetBadDqBitmap(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_mba,
+ const uint8_t i_port,
+ const uint8_t i_dimm,
+ const uint8_t i_rank,
+ uint8_t (&o_data)[DIMM_DQ_RANK_BITMAP_SIZE])
+ {
+ FAPI_INF(">>dimmGetBadDqBitmap. %s:%d:%d:%d", mss::c_str(i_mba), i_port,
+ i_dimm, i_rank);
+
+ // Check parameters and find the DIMM fapi2::Target<fapi2::TARGET_TYPE_MBA>
+ fapi2::Target<fapi2::TARGET_TYPE_DIMM> l_dimm;
+
+ // Get the Bad DQ bitmap by querying ATTR_BAD_DQ_BITMAP.
+ // Use a heap based array to avoid large stack alloc
+ uint8_t (&l_dqBitmap)[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE] =
+ *(reinterpret_cast<uint8_t(*)[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE]>
+ (new uint8_t[MAX_RANKS_PER_DIMM * DIMM_DQ_RANK_BITMAP_SIZE]));
+
+ FAPI_TRY(dimmBadDqCheckParamFindDimm(i_mba, i_port, i_dimm, i_rank, l_dimm));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_BAD_DQ_BITMAP, l_dimm, l_dqBitmap));
+
+ //Write contents of DQ bitmap for specific rank to o_data.
+ memcpy(o_data, l_dqBitmap[i_rank], DIMM_DQ_RANK_BITMAP_SIZE);
+
+ delete [] &l_dqBitmap;
+
+ FAPI_INF("<<dimmGetBadDqBitmap");
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ /// @brief FW Team Utility function that sets the Bad DQ Bitmap.
+ /// @param[in] i_mba Reference to MBA Chiplet
+ /// @param[in] i_port MBA port number (0-(MAX_PORTS_PER_MBA - 1))
+ /// @param[in] i_dimm MBA port DIMM number (0-(MAX_DIMM_PER_PORT - 1))
+ /// @param[in] i_rank DIMM rank number (0-(MAX_RANKS_PER_DIMM -1))
+ /// @param[in] i_data Reference to data where Bad DQ bitmap is copied from
+ /// @return FAPI2_RC_SUCCESS
+ fapi2::ReturnCode dimmSetBadDqBitmap(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_mba,
+ const uint8_t i_port,
+ const uint8_t i_dimm,
+ const uint8_t i_rank,
+ const uint8_t (&i_data)[DIMM_DQ_RANK_BITMAP_SIZE])
+ {
+ FAPI_INF(">>dimmSetBadDqBitmap. %s:%d:%d:%d", mss::c_str(i_mba), i_port, i_dimm, i_rank);
+
+ // Check parameters and find the DIMM fapi2::Target<fapi2::TARGET_TYPE_MBA>
+ fapi2::Target<fapi2::TARGET_TYPE_DIMM> l_dimm;
+
+ // Get the Bad DQ bitmap by querying ATTR_BAD_DQ_BITMAP.
+ // Use a heap based array to avoid large stack alloc
+ uint8_t (&l_dqBitmap)[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE] =
+ *(reinterpret_cast<uint8_t(*)[MAX_RANKS_PER_DIMM][DIMM_DQ_RANK_BITMAP_SIZE]>
+ (new uint8_t[MAX_RANKS_PER_DIMM * DIMM_DQ_RANK_BITMAP_SIZE]));
+
+ FAPI_TRY(dimmBadDqCheckParamFindDimm(i_mba, i_port, i_dimm, i_rank, l_dimm));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_BAD_DQ_BITMAP, l_dimm, l_dqBitmap));
+
+ // Add the rank bitmap to the DIMM bitmap and write the bitmap
+ memcpy(l_dqBitmap[i_rank], i_data, DIMM_DQ_RANK_BITMAP_SIZE);
+
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_CEN_BAD_DQ_BITMAP, l_dimm, l_dqBitmap));
+
+ delete [] &l_dqBitmap;
+
+ FAPI_INF("<<dimmSetBadDqBitmap");
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+} // extern "C"
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapFuncs.H b/src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapFuncs.H
new file mode 100755
index 000000000..eb9e253d3
--- /dev/null
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapFuncs.H
@@ -0,0 +1,92 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapFuncs.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9c_dimmBadDqBitmapFuncs.H
+/// @brief FW Team Utility functions that accesses the Bad DQ Bitmap.
+///
+/// *HWP HWP Owner: Luke Mulkey <lwmulkey@us.ibm.com>
+/// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+/// *HWP Team: Memory
+/// *HWP Level: 2
+/// *HWP Consumed by: HB:CI
+////
+//
+#ifndef DIMMBADDQBITMAPFUNCS_H_
+#define DIMMBADDQBITMAPFUNCS_H_
+
+#include <fapi2.H>
+#include <dimmConsts.H>
+
+extern "C"
+{
+
+ ///
+ /// @brief FW Team Utility function that gets the Bad DQ Bitmap.
+ ///
+ /// This utility functon should be called by a HWP needing to get the Bad DQ
+ /// bitmap for a particular mba, port, dimm and rank.
+ ///
+ /// This function finds the corresponding DIMM fapi2::Target<fapi2::TARGET_TYPE_MBA>, calls
+ /// p9c_dimmBadDqBitmapAccessHwp to get the DQ bitmap and returns the data
+ /// for the specified rank.
+ ///
+ /// @param[in] i_mba Reference to MBA Chiplet
+ /// @param[in] i_port MBA port number (0-(MAX_PORTS_PER_MBA - 1))
+ /// @param[in] i_dimm MBA port DIMM number (0-(MAX_DIMM_PER_PORT - 1))
+ /// @param[in] i_rank DIMM rank number (0-(MAX_RANKS_PER_DIMM -1))
+ /// @param[out] o_data Reference to data where Bad DQ bitmap is copied to
+ /// @return ReturnCode
+ ///
+ fapi2::ReturnCode dimmGetBadDqBitmap(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_mba,
+ const uint8_t i_port,
+ const uint8_t i_dimm,
+ const uint8_t i_rank,
+ uint8_t (&o_data)[DIMM_DQ_RANK_BITMAP_SIZE]);
+
+ ///
+ /// @brief FW Team Utility function that sets the Bad DQ Bitmap.
+ ///
+ /// This utility functon should be called by a HWP needing to set the Bad DQ
+ /// bitmap for a particular mba, port, dimm and rank.
+ ///
+ /// This utility function finds the corresponding DIMM fapi2::Target<fapi2::TARGET_TYPE_MBA>, calls
+ /// dimmBadDqBitmapAccessHwp to get the DQ bitmap, fills in the data for the
+ /// specified rank and calls dimmBadDqBitmapAccessHwp to set the DQ bitmap
+ ///
+ /// @param[in] i_mba Reference to MBA Chiplet
+ /// @param[in] i_port MBA port number (0-(MAX_PORTS_PER_MBA - 1))
+ /// @param[in] i_dimm MBA port DIMM number (0-(MAX_DIMM_PER_PORT - 1))
+ /// @param[in] i_rank DIMM rank number (0-(MAX_RANKS_PER_DIMM -1))
+ /// @param[in] i_data Reference to data where Bad DQ bitmap is copied from
+ /// @return ReturnCode
+ ///
+ fapi2::ReturnCode dimmSetBadDqBitmap(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_mba,
+ const uint8_t i_port,
+ const uint8_t i_dimm,
+ const uint8_t i_rank,
+ const uint8_t (&i_data)[DIMM_DQ_RANK_BITMAP_SIZE]);
+}
+
+#endif
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapFuncs.mk b/src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapFuncs.mk
new file mode 100755
index 000000000..851f0593c
--- /dev/null
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapFuncs.mk
@@ -0,0 +1,33 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/import/chips/centaur/procedures/hwp/memory/p9c_dimmBadDqBitmapFuncs.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2016,2017
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+# Include the macros and things for MSS procedures
+-include 01common.mk
+
+PROCEDURE=p9c_dimmBadDqBitmapFuncs
+$(eval $(call ADD_MEMORY_INCDIRS,$(PROCEDURE)))
+#lib$(PROCEDURE)_DEPLIBS+=mss
+$(call BUILD_PROCEDURE)
+
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr_phy_reset.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr_phy_reset.C
new file mode 100644
index 000000000..efbf25d6f
--- /dev/null
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr_phy_reset.C
@@ -0,0 +1,717 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr_phy_reset.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file p9c_mss_ddr_phy_reset.C
+/// @brief HWP to set up ddr phy
+///
+/// *HWP HWP Owner: Luke Mulkey <lwmulkey@us.ibm.com>
+/// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+/// *HWP Team: Memory
+/// *HWP Level: 2
+/// *HWP Consumed by: HB:CI
+////
+
+#include <fapi2.H>
+#include <cen_gen_scom_addresses.H>
+#include <cen_gen_scom_addresses_fld.H>
+#include <p9c_mss_ddr_phy_reset.H>
+#include <p9c_mss_unmask_errors.H>
+#include <p9c_mss_slew.H>
+#include <p9c_dimmBadDqBitmapFuncs.H>
+#include <c_str.H>
+#include <dimmConsts.H>
+
+enum phy
+{
+ POWERDOWN_1_P0_MASTER_PD_CNTL = CEN_MBA_DDRPHY_PC_POWERDOWN_1_P0_MASTER_PD_CNTL,
+ POWERDOWN_1_P0_WR_FIFO_STAB = CEN_MBA_DDRPHY_PC_POWERDOWN_1_P0_WR_FIFO_STAB,
+
+ FORCE_MCLK_LOW_N = CEN_MBA_CCS_MODEQ_FORCE_MCLK_LOW_N,
+ DDR_DFI_RESET_RECOVER = CEN_MBA_CCS_MODEQ_MCBIST_DDR_DFI_RESET_RECOVER,
+
+ DP18_PLL_LOCK_STATUS = CEN_MBA_DDRPHY_PC_DP18_PLL_LOCK_STATUS_P0_LOCK,
+ DP18_PLL_LOCK_STATUS_LEN = CEN_MBA_DDRPHY_PC_DP18_PLL_LOCK_STATUS_P0_LOCK_LEN,
+
+ AD32S_PLL_LOCK_STATUS = CEN_MBA_DDRPHY_PC_AD32S_PLL_LOCK_STATUS_P0_LOCK,
+ AD32S_PLL_LOCK_STATUS_LEN = CEN_MBA_DDRPHY_PC_AD32S_PLL_LOCK_STATUS_P0_LOCK_LEN,
+
+};
+
+extern "C"
+{
+ // TODO RTC:168629 Segregate API from p9c_ddr_phy_reset.C into a PHY dir
+ // prototypes of functions called in phy reset
+ fapi2::ReturnCode deassert_force_mclk_low (const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target);
+ fapi2::ReturnCode ddr_phy_reset_cloned(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target);
+ fapi2::ReturnCode ddr_phy_flush(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target);
+
+ ///
+ /// @brief Does a soft reset of the DDR PHY logic and lock the DDR PLLs
+ /// @param[in] i_target the MBA target
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode p9c_mss_ddr_phy_reset(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target)
+ {
+ FAPI_TRY(ddr_phy_reset_cloned(i_target), "ddr_phy_reset_cloned failed!");
+ FAPI_TRY(mss_slew_cal(i_target), "mss_slew_cal failed!");
+ FAPI_TRY(ddr_phy_flush(i_target), "ddr_phy_flush failed!");
+
+ // If mss_unmask_ddrphy_errors gets it's own bad rc,
+ // it will commit the passed in rc (if non-zero), and return it's own bad rc.
+ // Else if mss_unmask_ddrphy_errors runs clean,
+ // it will just return the passed in rc.
+ FAPI_TRY(mss_unmask_ddrphy_errors(i_target));
+
+ fapi_try_exit:
+ FAPI_DBG("end");
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief PHY reset cloned
+ /// @param[in] i_target the MBA target
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode ddr_phy_reset_cloned(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target)
+ {
+ // Loop 10 times during PLL lock polling
+ constexpr uint64_t MAX_POLL_LOOPS = 10;
+ constexpr uint64_t DP18_PLL_EXP_LOCK_STATUS = 0xF800; // DP18 PLL lock status
+ constexpr uint64_t AD32S_PLL_EXP_LOCK_STATUS = 0xC000; // AD32S PLL lock status
+
+ uint32_t l_poll_count = 0;
+ uint32_t l_done_polling = 0;
+ uint8_t l_is_simulation = 0;
+ fapi2::buffer<uint64_t> l_data;
+ fapi2::buffer<uint64_t> l_dp_p0_lock_data;
+ fapi2::buffer<uint64_t> l_dp_p1_lock_data;
+ fapi2::buffer<uint64_t> l_ad_p0_lock_data;
+ fapi2::buffer<uint64_t> l_ad_p1_lock_data;
+ uint8_t l_dqBitmap[DIMM_DQ_RANK_BITMAP_SIZE] = {}; // 10 byte array of bad bits
+ uint8_t l_valid_dimms = 0;
+ uint8_t l_valid_dimm[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT];
+ uint8_t l_num_mranks_per_dimm[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {};
+ uint8_t l_port = 0;
+ uint16_t l_actual = 0;
+ uint16_t l_poll = 0;
+ uint8_t l_dimm = 0;
+ uint8_t l_rank = 0;
+ bool l_new_error = false;
+ uint8_t l_continue_on_dp18_pll_lock_failure = 0;
+
+ FAPI_INF("********* mss_ddr_phy_reset start *********");
+
+ //
+ // Here are the specific instructions from section 14.7.3 of the Centaur Chip Specification:
+ //
+ // Run cen_ddr_phy_reset.C prepares the DDR PLLs. These PLLs were previously configured via scan init, but have
+ // been held in reset. At this point the PLL GP bit is deasserted to take the PLLs out of reset.
+ //
+ // The cen_ddr_phy_reset.C now resets the DDR PHY logic. This process will NOT destroy any configuration values
+ // previously loaded via the init file. The intent is for the initialized phase rotator configuration to remain valid after the
+ // soft reset completes. If this assumption fails to hold true, it will require replacing this step with a PHY hard reset,
+ // and then using inband configuration writes to restore all the DDR Configuration Registers.
+ //
+ // The following steps must be performed as part of the PHY reset procedure.
+
+ // PLL Lock cannot happen if mclk low is asserted
+ // this procedure was moved from draminit to:
+ // Deassert Force_mclk_low signal
+ // see CQ 216395 (HW217109)
+ FAPI_TRY(deassert_force_mclk_low(i_target), " deassert_force_mclk_low Failed");
+
+ //
+ // 1. Drive all control signals to the PHY to their inactive state, idle state, or inactive value.
+ // (Note: The chip should already be in this state.)
+ FAPI_DBG("Step 1: All control signals to the PHYs should already be set to their inactive state, idle state, or inactive values.\n");
+
+ //
+ // 2. For DD0: Assert dfi_reset_all (GP4 bit 5 = "1") for at least 32 memory clock cycles. This signal DOES
+ // erradicate all DDR configuration register initialization, thereby requiring the DDR registers to be reprogrammed
+ // via SCOM after the PHY reset sequence completes.
+ // For DD1: Set mcbist_ddr_dfi_reset_recover ="1" (CCS_MODEQ(25) SCOM Addr: 0x030106A7 & 0x03010EA7)
+ // for at least 32 memory clock cycles. This signal does NOT reset the configuration registers
+ // within the PHY.
+ FAPI_DBG("Step 2: MBA CCS_MODEQ(25), Setting mcbist_ddr_dfi_reset_recover = 1 for DDR PHY soft reset.\n");
+ FAPI_TRY(fapi2::getScom( i_target, CEN_MBA_CCS_MODEQ, l_data), "Error reading CCS_MODEQ register.");
+ l_data.setBit<DDR_DFI_RESET_RECOVER>();
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_CCS_MODEQ, l_data));
+ FAPI_TRY(fapi2::delay(DELAY_100NS, DELAY_2000SIMCYCLES)); // wait 2000 simcycles (in sim mode) OR 100 nS (in hw mode)
+
+ //
+ // 3. For DD0: Deassert dfi_reset_all (GP4 bit 5 = "0")
+ // For DD1: Deassert mcbist_ddr_dfi_reset_recover = "0" (CCS_MODEQ(25) SCOM Addr: 0x030106A7 0x03010EA7)
+ FAPI_DBG("Step 3: MBA CCS_MODEQ(25), Setting mcbist_ddr_dfi_reset_recover = 0 to release soft reset.\n");
+ FAPI_TRY(fapi2::getScom( i_target, CEN_MBA_CCS_MODEQ, l_data), "Error reading CCS_MODEQ register.");
+ l_data.clearBit<DDR_DFI_RESET_RECOVER>();
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_CCS_MODEQ, l_data), "Error writing CCS_MODEQ register.");
+
+ //
+ // 4. Write 0x0010 to PC IO PVT N/P FET driver control registers to assert ZCTL reset and enable the internal impedance controller.
+ // (SCOM Addr: 0x8000C0140301143F, 0x8000C0140301183F, 0x8001C0140301143F, 0x8001C0140301183F)
+ FAPI_DBG("Step 4: Write 0x0010 to PC IO PVT N/P FET driver control registers to assert ZCTL reset.\n");
+ l_data = 0x0000000000000010ull;
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_PC_IO_PVT_FET_CONTROL_P0, l_data),
+ "Error writing DPHY01_DDRPHY_PC_IO_PVT_FET_CONTROL_P0 register.");
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_PC_IO_PVT_FET_CONTROL_P1, l_data),
+ "Error writing DPHY01_DDRPHY_PC_IO_PVT_FET_CONTROL_P0 register.");
+
+ //
+ // 5. Write 0x0018 to PC IO PVT N/P FET driver control registers to deassert ZCTL reset while impedance controller is still enabled.
+ // (SCOM Addr: 0x8000C0140301143F, 0x8000C0140301183F, 0x8001C0140301143F, 0x8001C0140301183F)
+ FAPI_DBG("Step 5: Write 0x0018 to PC IO PVT N/P FET driver control registers to deassert ZCTL reset.\n");
+ l_data = 0x0000000000000018ull;
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_PC_IO_PVT_FET_CONTROL_P0, l_data),
+ "Error writing DPHY01_DDRPHY_PC_IO_PVT_FET_CONTROL_P0 register.");
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_PC_IO_PVT_FET_CONTROL_P1, l_data),
+ "Error writing DPHY01_DDRPHY_PC_IO_PVT_FET_CONTROL_P1 register.");
+
+ //
+ // 6. Write 0x0008 to PC IO PVT N/P FET driver control registers to deassert the impedance controller.
+ // (SCOM Addr: 0x8000C0140301143F, 0x8000C0140301183F, 0x8001C0140301143F, 0x8001C0140301183F)
+ FAPI_DBG("Step 6: Write 0x0008 to PC IO PVT N/P FET driver control registers to deassert the impedance controller.\n");
+ l_data = 0x0000000000000008ull;
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_PC_IO_PVT_FET_CONTROL_P0, l_data),
+ "Error writing DPHY01_DDRPHY_PC_IO_PVT_FET_CONTROL_P0 register.");
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_PC_IO_PVT_FET_CONTROL_P1, l_data),
+ "Error writing DPHY01_DDRPHY_PC_IO_PVT_FET_CONTROL_P1 register.");
+
+ //
+ // 7. Write 0x4000 into the PC Resets Registers. This deasserts the PLL_RESET and leaves the SYSCLK_RESET bit active
+ // (SCOM Addr: 0x8000C00E0301143F, 0x8001C00E0301143F, 0x8000C00E0301183F, 0x8001C00E0301183F)
+ FAPI_DBG("Step 7: Write 0x4000 into the PC Resets Regs. This deasserts the PLL_RESET and leaves the SYSCLK_RESET bit active.\n");
+ l_data = 0x0000000000004000ull;
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_PC_RESETS_P0, l_data),
+ "Error writing DPHY01_DDRPHY_PC_RESETS_P0 register.");
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_PC_RESETS_P1, l_data),
+ "Error writing DPHY01_DDRPHY_PC_RESETS_P1 register.");
+
+ //
+ // 8. Wait at least 1 millisecond to allow the PLLs to lock. Otherwise, poll the PC DP18 PLL Lock Status
+ // and the PC AD32S PLL Lock Status to determine if all PLLs have locked.
+ // PC DP18 PLL Lock Status should be 0xF800: (SCOM Addr: 0x8000C0000301143F, 0x8001C0000301143F, 0x8000C0000301183F, 0x8001C0000301183F)
+ // PC AD32S PLL Lock Status should be 0xC000: (SCOM Addr: 0x8000C0010301143F, 0x8001C0010301143F, 0x8000C0010301183F, 0x8001C0010301183F)
+ //------------------------
+ // 8a - Poll for lock bits
+ FAPI_DBG("Step 8: Poll until DP18 and AD32S PLLs have locked....\n");
+
+ do
+ {
+ FAPI_TRY(fapi2::delay(DELAY_1US, DELAY_20000SIMCYCLES)); // wait 20000 simcycles (in sim mode) OR 1 usec (in hw mode)
+ l_done_polling = 1;
+ FAPI_TRY(fapi2::getScom( i_target, CEN_MBA_DDRPHY_PC_DP18_PLL_LOCK_STATUS_P0_ROX, l_dp_p0_lock_data));
+ l_dp_p0_lock_data.extract<DP18_PLL_LOCK_STATUS, DP18_PLL_LOCK_STATUS_LEN>(l_poll);
+
+ if ( l_poll != DP18_PLL_EXP_LOCK_STATUS )
+ {
+ l_done_polling = 0;
+ }
+
+ FAPI_TRY(fapi2::getScom( i_target, CEN_MBA_DDRPHY_PC_DP18_PLL_LOCK_STATUS_P1_ROX, l_dp_p1_lock_data));
+ l_dp_p1_lock_data.extract<DP18_PLL_LOCK_STATUS, DP18_PLL_LOCK_STATUS_LEN>(l_poll);
+
+ if ( l_poll != DP18_PLL_EXP_LOCK_STATUS )
+ {
+ l_done_polling = 0;
+ }
+
+ FAPI_TRY(fapi2::getScom( i_target, CEN_MBA_DDRPHY_PC_AD32S_PLL_LOCK_STATUS_P0_ROX, l_ad_p0_lock_data));
+ l_ad_p0_lock_data.extract<48, 16>(l_poll);
+
+ if ( l_poll != AD32S_PLL_EXP_LOCK_STATUS )
+ {
+ l_done_polling = 0;
+ }
+
+ FAPI_TRY(fapi2::getScom( i_target, CEN_MBA_DDRPHY_PC_AD32S_PLL_LOCK_STATUS_P1_ROX, l_ad_p1_lock_data));
+ l_ad_p1_lock_data.extract<48, 16>(l_poll);
+
+ if ( l_poll != AD32S_PLL_EXP_LOCK_STATUS )
+ {
+ l_done_polling = 0;
+ }
+
+ l_poll_count++;
+ }
+ while ((l_done_polling == 0) && (l_poll_count < MAX_POLL_LOOPS)); // Poll until PLLs are locked.
+
+
+ if (l_poll_count == MAX_POLL_LOOPS)
+ {
+
+ //-------------------------------
+ // Check to see if we should continue even if the DP18 PLL lock fails
+ const auto l_centaurTarget = i_target.getParent<fapi2::TARGET_TYPE_MEMBUF_CHIP>();
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_CENTAUR_EC_FEATURE_MSS_CONTINUE_ON_DP18_PLL_LOCK_FAIL,
+ l_centaurTarget,
+ l_continue_on_dp18_pll_lock_failure));
+
+ FAPI_DBG("Got attribute ATTR_CENTAUR_EC_MSS_CONTINUE_ON_DP18_PLL_LOCK_FAIL: value=%X.\n",
+ l_continue_on_dp18_pll_lock_failure);
+
+ //-------------------------------
+ // 8b - Check Port 0 DP lock bits
+
+ // TODO RTC:168628 Log FFDC in p9c_ddr_phy_reset instead of only printing traces?
+ l_dp_p0_lock_data.extract<48, 16>(l_poll);
+
+ if ( l_poll != DP18_PLL_EXP_LOCK_STATUS )
+ {
+ if ( !l_dp_p0_lock_data.getBit<48>() )
+ {
+ FAPI_INF("Port 0 DP 0 PLL failed to lock!");
+ }
+
+ if ( !l_dp_p0_lock_data.getBit<49>() )
+ {
+ FAPI_INF("Port 0 DP 1 PLL failed to lock!");
+ }
+
+ if ( !l_dp_p0_lock_data.getBit<50>() )
+ {
+ FAPI_INF("Port 0 DP 2 PLL failed to lock!");
+ }
+
+ if ( !l_dp_p0_lock_data.getBit<51>() )
+ {
+ FAPI_INF("Port 0 DP 3 PLL failed to lock!");
+ }
+
+ if ( !l_dp_p0_lock_data.getBit<52>() )
+ {
+ FAPI_INF("Port 0 DP 4 PLL failed to lock!");
+ }
+
+ if (!l_continue_on_dp18_pll_lock_failure)
+ {
+ l_dp_p0_lock_data.extract<48, 16>(l_actual);
+
+ FAPI_ASSERT(false,
+ fapi2::CEN_MSS_DP18_0_PLL_FAILED_TO_LOCK().
+ set_EXPECTED_STATUS(DP18_PLL_EXP_LOCK_STATUS).
+ set_ACTUAL_STATUS(l_actual).
+ set_MBA_IN_ERROR(i_target).
+ set_MEMBUF_CHIP_IN_ERROR(l_centaurTarget),
+ "One or more DP18 port 0 (0x0C000) PLL failed to lock!,DP18 PLL lock failed and this chip does not have the known DP18 lock bug.");
+ }
+
+ // for DD1 parts that have the DP18 lock bug - keep going to initialize any other channels that might be good.
+ FAPI_INF("Continuing anyway to initialize any other channels that might be good...");
+ }
+
+ //-------------------------------
+ // 8c - Check Port 1 DP lock bits
+ l_dp_p1_lock_data.extract< 48, 16>(l_poll);
+
+ if ( l_poll != DP18_PLL_EXP_LOCK_STATUS )
+ {
+ if ( !l_dp_p1_lock_data.getBit<48>() )
+ {
+ FAPI_INF("Port 1 DP 0 PLL failed to lock!");
+ }
+
+ if ( !l_dp_p1_lock_data.getBit<49>() )
+ {
+ FAPI_INF("Port 1 DP 1 PLL failed to lock!");
+ }
+
+ if ( !l_dp_p1_lock_data.getBit<50>() )
+ {
+ FAPI_INF("Port 1 DP 2 PLL failed to lock!");
+ }
+
+ if ( !l_dp_p1_lock_data.getBit<51>() )
+ {
+ FAPI_INF("Port 1 DP 3 PLL failed to lock!");
+ }
+
+ if ( !l_dp_p1_lock_data.getBit<52>() )
+ {
+ FAPI_INF("Port 1 DP 4 PLL failed to lock!");
+ }
+
+ if (!l_continue_on_dp18_pll_lock_failure)
+ {
+ l_dp_p1_lock_data.extract<48, 16>(l_actual);
+
+ FAPI_ASSERT(false,
+ fapi2::CEN_MSS_DP18_1_PLL_FAILED_TO_LOCK().
+ set_EXPECTED_STATUS(DP18_PLL_EXP_LOCK_STATUS).
+ set_ACTUAL_STATUS(l_actual).
+ set_MBA_IN_ERROR(i_target).
+ set_MEMBUF_CHIP_IN_ERROR(l_centaurTarget),
+ "One or more DP18 port 1 (0x0C000) PLL failed to lock!,DP18 PLL lock failed and this chip does not have the known DP18 lock bug.");
+ }
+
+ // for DD1 parts that have the DP18 lock bug - keep going to initialize any other channels that might be good.
+ // FAPI_INF("One or more DP18 port 1 (0x1C000) PLL failed to lock! Lock Status = %04X",l_dp_p1_lock_data.getHalfWord(3));
+ FAPI_INF("Continuing anyway to initialize any other channels that might be good...");
+ }
+
+ //-------------------------------
+ // 8d - Check Port 0 AD lock bits
+ l_ad_p0_lock_data.extract<48, 16>(l_poll);
+ l_ad_p0_lock_data.extract<48, 16>(l_actual);
+
+ FAPI_ASSERT(l_poll == AD32S_PLL_EXP_LOCK_STATUS,
+ fapi2::CEN_MSS_AD32S_0_PLL_FAILED_TO_LOCK().
+ set_EXPECTED_STATUS(AD32S_PLL_EXP_LOCK_STATUS).
+ set_ACTUAL_STATUS(l_actual).
+ set_MBA_IN_ERROR(i_target).
+ set_MEMBUF_CHIP_IN_ERROR(l_centaurTarget),
+ "One or more AD32S port 0 (0x0C001) PLL failed to lock!");
+
+ //-------------------------------
+ // 8e - Check Port 1 AD lock bits
+ l_ad_p1_lock_data.extract<48, 16>(l_poll);
+ l_ad_p1_lock_data.extract<48, 16>(l_actual);
+
+ FAPI_ASSERT( l_poll == AD32S_PLL_EXP_LOCK_STATUS,
+ fapi2::CEN_MSS_AD32S_1_PLL_FAILED_TO_LOCK().
+ set_EXPECTED_STATUS(AD32S_PLL_EXP_LOCK_STATUS).
+ set_ACTUAL_STATUS(l_actual).
+ set_MBA_IN_ERROR(i_target).
+ set_MEMBUF_CHIP_IN_ERROR(l_centaurTarget),
+ "One or more AD32S port 1 (0x0C001) PLL failed to lock!");
+ }
+ else
+ {
+ FAPI_INF("AD32S PLLs are now locked. DP18 PLLs should also be locked.");
+ }
+
+ //
+ // 9.Write '8024'x into the ADR SysClk Phase Rotator Control Registers and into the DP18 SysClk Phase Rotator Control Registers.
+ // This takes the dphy_nclk/SysClk alignment circuit out of reset and puts the dphy_nclk/SysClk alignment circuit into the Continuous Update Mode.
+ // ADR SysClk PR Control Registers : (SCOM Addr: 0x800080320301143F, 0x800084320301143F, 0x800180320301143F, 0x800184320301143F,
+ // 0x800080320301183F, 0x800084320301183F, 0x800180320301183F, 0x800184320301183F)
+ // DP18 SysClk PR Control Registers : (SCOM Addr: 0x800000070301143F, 0x800004070301143F, 0x800008070301143F, 0x80000C070301143F, 0x800010070301143F,
+ // 0x800000070301183F, 0x800004070301183F, 0x800008070301183F, 0x80000C070301183F, 0x800010070301183F,
+ // 0x800100070301143F, 0x800104070301143F, 0x800108070301143F, 0x80010C070301143F, 0x800110070301143F,
+ // 0x800100070301183F, 0x800104070301183F, 0x800108070301183F, 0x80010C070301183F, 0x800110070301183F)
+ FAPI_DBG("Step 9: Write '8024'x into the ADR SysClk Phase Rotator Control Regs and the DP18 SysClk Phase Rotator Control Regs.\n");
+ l_data = 0x0000000000008024ull;
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_ADR_SYSCLK_CNTL_PR_P0_ADR32S0, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_ADR_SYSCLK_CNTL_PR_P1_ADR32S0, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_ADR_SYSCLK_CNTL_PR_P0_ADR32S1, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_ADR_SYSCLK_CNTL_PR_P1_ADR32S1, l_data));
+
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_0, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_0, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_1, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_1, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_2, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_2, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_3, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_3, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_4, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_4, l_data));
+
+ //
+ // 10.Wait at least 5932 memory clock cycles to allow the clock alignment circuit to perform initial alignment.
+ FAPI_DBG("Step 10: Wait at least 5932 memory clock cycles to allow the clock alignment circuit to perform initial alignment.\n");
+
+ // wait 2000000 simcycles (in sim mode) OR 100 usec (in hw mode)
+ FAPI_TRY(fapi2::delay(DELAY_100US, DELAY_2000000SIMCYCLES));
+
+ //
+ // 11.Write 0x0000 into the PC Resets Register. This deasserts the SysClk Reset
+ // (SCOM Addr: 0x8000C00E0301143F, 0x8001C00E0301143F, 0x8000C00E0301183F, 0x8001C00E0301183F)
+ FAPI_DBG("Step 11: Write 0x0000 into the PC Resets Register. This deasserts the SysClk Reset.\n");
+ l_data = 0x0000000000000000ull;
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_PC_RESETS_P0, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_PC_RESETS_P1, l_data));
+
+ //
+ // 12.Write '8020'x into the ADR SysClk Phase Rotator Control Registers and into the DP18 SysClk Phase Rotator Control Registers.
+ // This takes the dphy_nclk/SysClk alignment circuit out of Continuous Update Mode.
+ // ADR SysClk PR Control Registers : (SCOM Addr: 0x800080320301143F, 0x800084320301143F, 0x800180320301143F, 0x800184320301143F,
+ // 0x800080320301183F, 0x800084320301183F, 0x800180320301183F, 0x800184320301183F)
+ // DP18 SysClk PR Control Registers : (SCOM Addr: 0x800000070301143F, 0x800004070301143F, 0x800008070301143F, 0x80000C070301143F, 0x800010070301143F,
+ // 0x800000070301183F, 0x800004070301183F, 0x800008070301183F, 0x80000C070301183F, 0x800010070301183F,
+ // 0x800100070301143F, 0x800104070301143F, 0x800108070301143F, 0x80010C070301143F, 0x800110070301143F,
+ // 0x800100070301183F, 0x800104070301183F, 0x800108070301183F, 0x80010C070301183F, 0x800110070301183F)
+ FAPI_DBG("Step 12: Write '8020'x into the ADR SysClk Phase Rotator Control Regs and the DP18 SysClk Phase Rotator Control Regs.\n");
+ l_data = 0x0000000000008020ull;
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_ADR_SYSCLK_CNTL_PR_P0_ADR32S0, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_ADR_SYSCLK_CNTL_PR_P1_ADR32S0, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_ADR_SYSCLK_CNTL_PR_P0_ADR32S1, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_ADR_SYSCLK_CNTL_PR_P1_ADR32S1, l_data));
+
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_0, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_0, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_1, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_1, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_2, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_2, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_3, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_3, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_4, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_4, l_data));
+
+ // Work-around required to get alignment in simulation
+ // Read the ATTR_IS_SIMULATION attribute
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), l_is_simulation));
+
+ if (l_is_simulation)
+ {
+ FAPI_DBG("Step 12.1 (SIM ONLY): Write '8000'x into the ADR SysClk Phase Rotator Control Regs and the DP18 SysClk Phase Rotator Control Regs.\n");
+ l_data = 0x0000000000008000ull;
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_ADR_SYSCLK_CNTL_PR_P0_ADR32S0, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_ADR_SYSCLK_CNTL_PR_P1_ADR32S0, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_ADR_SYSCLK_CNTL_PR_P0_ADR32S1, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_ADR_SYSCLK_CNTL_PR_P1_ADR32S1, l_data));
+
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_0, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_0, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_1, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_1, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_2, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_2, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_3, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_3, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_4, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_4, l_data));
+
+ FAPI_DBG("Step 12.2 (SIM ONLY): Write '8080'x into the ADR SysClk Phase Rotator Control Regs and the DP18 SysClk Phase Rotator Control Regs.\n");
+ l_data = 0x0000000000008080ull;
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_ADR_SYSCLK_CNTL_PR_P0_ADR32S0, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_ADR_SYSCLK_CNTL_PR_P1_ADR32S0, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_ADR_SYSCLK_CNTL_PR_P0_ADR32S1, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_ADR_SYSCLK_CNTL_PR_P1_ADR32S1, l_data));
+
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_0, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_0, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_1, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_1, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_2, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_2, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_3, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_3, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P0_4, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_DP18_SYSCLK_PR_P1_4, l_data));
+ }
+
+ //
+ // 13.Wait at least 32 memory clock cycles.
+ FAPI_DBG("Step 13: Wait at least 32 memory clock cycles.\n");
+ FAPI_TRY(fapi2::delay(DELAY_100NS, DELAY_2000SIMCYCLES)); // wait 2000 simcycles (in sim mode) OR 100 nS (in hw mode)
+
+ //
+ // 14.Write 0x0018 to PC IO PVT N/P FET driver control register to enable internal ZQ calibration.
+ // This step takes approximately 2112 (64 * 33) memory clock cycles.
+ // (SCOM Addr: 0x8000C0140301143F, 0x8000C0140301183F, 0x8001C0140301143F, 0x8001C0140301183F)
+ FAPI_DBG("Step 14: Write 0x0018 to PC IO PVT N/P FET driver control register to enable internal ZQ calibration.\n");
+ l_data = 0x0000000000000018ull;
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_PC_IO_PVT_FET_CONTROL_P0, l_data));
+ FAPI_TRY(fapi2::putScom( i_target, CEN_MBA_DDRPHY_PC_IO_PVT_FET_CONTROL_P1, l_data));
+
+ //
+ // Now do some error checking and mark bad channels
+ // Check to see if there were any register access problems on DP registers, or corresponding PLLs that did not lock.
+ // If so, mark the DP pairs as bad.
+
+ // Loop through only valid (functional) dimms.
+ // For each valid dimm, loop through all the ranks belonging to that dimm.
+ // If there was either a register access error, or if the PLL did not lock, then mark the DP pair as bad.
+ // Do this by setting the dqBitmap attribute for all dimms and ranks associated with that PLL or register.
+ // Read the dqBitmap first, so that you do not clear values that may already be set.
+ // (Some DP channels may already be marked as bad.)
+
+ // TODO RTC:168627 Find out if we can avoid ATTR_CEN_MSS_EFF_DIMM_FUNCTIONAL_VECTOR
+ // Find out which dimms are functional
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_MSS_EFF_DIMM_FUNCTIONAL_VECTOR, i_target, l_valid_dimms));
+ l_valid_dimm[0][0] = (l_valid_dimms & 0x80);
+ l_valid_dimm[0][1] = (l_valid_dimms & 0x40);
+ l_valid_dimm[1][0] = (l_valid_dimms & 0x08);
+ l_valid_dimm[1][1] = (l_valid_dimms & 0x04);
+
+ // Find out how many ranks are on each dimm
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_NUM_MASTER_RANKS_PER_DIMM, i_target, l_num_mranks_per_dimm));
+
+ // Loop through each PORT (0,1)
+ for(l_port = 0; l_port < MAX_PORTS_PER_MBA; l_port++ )
+ {
+ // Loop through each DIMM:(0,1)
+ for(l_dimm = 0; l_dimm < MAX_DIMM_PER_PORT; l_dimm++ )
+ {
+ if (l_valid_dimm[l_port][l_dimm])
+ {
+ // Ok, this DIMM is functional. So loop through the RANKs of this dimm.
+ for(l_rank = 0; l_rank < l_num_mranks_per_dimm[l_port][l_dimm]; ++l_rank )
+ {
+ // Get the bad DQ Bitmap for l_port, l_dimm, l_rank
+ FAPI_TRY(dimmGetBadDqBitmap(i_target, l_port, l_dimm, l_rank, l_dqBitmap));
+
+ // Mark the bad bits for each register that had problems or PLL that did not lock
+ l_new_error = false;
+
+ if ( l_port == 0 )
+ {
+ if ( !l_dp_p0_lock_data.getBit<48>() )
+ {
+ l_dqBitmap[0] = 0xff;
+ l_dqBitmap[1] = 0xff;
+ l_new_error = true;
+ }
+
+ if ( !l_dp_p0_lock_data.getBit<49>() )
+ {
+ l_dqBitmap[2] = 0xff;
+ l_dqBitmap[3] = 0xff;
+ l_new_error = true;
+ }
+
+ if ( !l_dp_p0_lock_data.getBit<50>() )
+ {
+ l_dqBitmap[4] = 0xff;
+ l_dqBitmap[5] = 0xff;
+ l_new_error = true;
+ }
+
+ if ( !l_dp_p0_lock_data.getBit<51>() )
+ {
+ l_dqBitmap[6] = 0xff;
+ l_dqBitmap[7] = 0xff;
+ l_new_error = true;
+ }
+
+ if ( !l_dp_p0_lock_data.getBit<52>() )
+ {
+ l_dqBitmap[8] = 0xff;
+ l_dqBitmap[9] = 0xff;
+ l_new_error = true;
+ }
+ }
+ else
+ {
+ if ( !l_dp_p1_lock_data.getBit<48>() )
+ {
+ l_dqBitmap[0] = 0xff;
+ l_dqBitmap[1] = 0xff;
+ l_new_error = true;
+ }
+
+ if ( !l_dp_p1_lock_data.getBit<49>() )
+ {
+ l_dqBitmap[2] = 0xff;
+ l_dqBitmap[3] = 0xff;
+ l_new_error = true;
+ }
+
+ if ( !l_dp_p1_lock_data.getBit<50>() )
+ {
+ l_dqBitmap[4] = 0xff;
+ l_dqBitmap[5] = 0xff;
+ l_new_error = true;
+ }
+
+ if ( !l_dp_p1_lock_data.getBit<51>() )
+ {
+ l_dqBitmap[6] = 0xff;
+ l_dqBitmap[7] = 0xff;
+ l_new_error = true;
+ }
+
+ if ( !l_dp_p1_lock_data.getBit<52>() )
+ {
+ l_dqBitmap[8] = 0xff;
+ l_dqBitmap[9] = 0xff;
+ l_new_error = true;
+ }
+ }
+
+ // If there are new errors, write back the bad DQ Bitmap for l_port, l_dimm, l_rank
+ if ( l_new_error )
+ {
+ FAPI_TRY(dimmSetBadDqBitmap(i_target, l_port, l_dimm, l_rank, l_dqBitmap));
+ }
+ } // End of loop over RANKs
+ }
+ } // End of loop over DIMMs
+ } // End of loop over PORTs
+
+ fapi_try_exit:
+ FAPI_INF("********* mss_ddr_phy_reset complete *********");
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief deassert MCLK
+ /// @param[in] i_target the MBA target
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode deassert_force_mclk_low (const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target)
+ {
+ fapi2::buffer<uint64_t> l_data_buffer;
+
+ FAPI_INF( "+++++++++++++++++++++ DEASSERTING FORCE MCLK LOW +++++++++++++++++++++");
+
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_CCS_MODEQ, l_data_buffer));
+ l_data_buffer.setBit<63>();
+ FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_CCS_MODEQ, l_data_buffer));
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Flush DDR PHY
+ /// @param[in] i_target the MBA target
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode ddr_phy_flush(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target)
+ {
+ fapi2::buffer<uint64_t> l_data;
+ fapi2::buffer<uint64_t> l_mask;
+
+ FAPI_INF(" Performing ddr_phy_flush routine");
+
+ FAPI_INF("ADR/DP18 FLUSH: 1) set PC_POWERDOWN_1 register, powerdown enable(48), flush bit(58)");
+ l_data.setBit<48>(); // set MASTER_PD_CNTL bit
+ l_data.setBit<58>(); // set WR_FIFO_STAB bit
+
+ l_mask.setBit<48>(); // set MASTER_PD_CNTL bit
+ l_mask.setBit<58>(); // set WR_FIFO_STAB mask bit
+
+ FAPI_TRY(fapi2::putScomUnderMask(i_target, CEN_MBA_DDRPHY_PC_POWERDOWN_1_P0, l_data, l_mask));
+ FAPI_TRY(fapi2::putScomUnderMask(i_target, CEN_MBA_DDRPHY_PC_POWERDOWN_1_P1, l_data, l_mask));
+ FAPI_TRY(fapi2::delay(DELAY_100NS, DELAY_2000SIMCYCLES)); // wait 2000 simcycles (in sim mode) OR 100 nS (in hw mode)
+
+ FAPI_INF("ADR/DP18 FLUSH: 2) clear PC_POWERDOWN_1 register, powerdown enable(48), flush bit(58)");
+ l_data.flush<0>(); // clear data buffer
+ l_mask.flush<0>(); // clear mask buffer
+ l_mask.setBit<48>(); // set MASTER_PD_CNTL bit
+ l_mask.setBit<58>(); // set WR_FIFO_STAB mask bit
+
+ FAPI_TRY(fapi2::putScomUnderMask(i_target, CEN_MBA_DDRPHY_PC_POWERDOWN_1_P0, l_data, l_mask));
+ FAPI_TRY(fapi2::putScomUnderMask(i_target, CEN_MBA_DDRPHY_PC_POWERDOWN_1_P1, l_data, l_mask));
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+}//end extern C
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr_phy_reset.H b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr_phy_reset.H
new file mode 100644
index 000000000..a4a4ae204
--- /dev/null
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr_phy_reset.H
@@ -0,0 +1,55 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr_phy_reset.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file p9c_mss_ddr_phy_reset.C
+/// @brief HWP header file to set up ddr phy
+///
+/// *HWP HWP Owner: Luke Mulkey <lwmulkey@us.ibm.com>
+/// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+/// *HWP Team: Memory
+/// *HWP Level: 2
+/// *HWP Consumed by: HB:CI
+////
+
+#ifndef MSS_DDR_PHY_RESETHWPB_H_
+#define MSS_DDR_PHY_RESETHWPB_H_
+
+#include <fapi2.H>
+
+typedef fapi2::ReturnCode (*p9c_mss_ddr_phy_reset_FP_t)(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target);
+
+extern "C"
+{
+ ///
+ /// @brief Does a soft reset of the DDR PHY logic and lock the DDR PLLs
+ /// @param[in] i_target the MBA target
+ /// @return FAPI2_RC_SUCCESS iff okay
+ ///
+ fapi2::ReturnCode p9c_mss_ddr_phy_reset(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target);
+
+} // extern "C"
+
+#endif // MSS_DDR_PHY_RESETHWPB_H_
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr_phy_reset.mk b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr_phy_reset.mk
new file mode 100755
index 000000000..3b16d530f
--- /dev/null
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr_phy_reset.mk
@@ -0,0 +1,34 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr_phy_reset.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2016,2017
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+# Include the macros and things for MSS procedures
+-include 01common.mk
+PROCEDURE=p9c_mss_ddr_phy_reset
+OBJS+=p9c_dimmBadDqBitmapFuncs.o
+OBJS+=p9c_mss_unmask_errors.o
+OBJS+=p9c_mss_slew.o
+$(eval $(call ADD_MEMORY_INCDIRS,$(PROCEDURE)))
+#lib$(PROCEDURE)_DEPLIBS+=mss
+$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.C
new file mode 100755
index 000000000..d678d9354
--- /dev/null
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.C
@@ -0,0 +1,2285 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file p9c_mss_unmask_errors.C
+/// @brief Tools for DDR4 DIMMs centaur procedures
+///
+/// *HWP HWP Owner: Luke Mulkey <lwmulkey@us.ibm.com>
+/// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+/// *HWP Team: Memory
+/// *HWP Level: 2
+/// *HWP Consumed by: HB:CI
+//
+//
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+
+#include <p9c_mss_unmask_errors.H>
+#include <cen_gen_scom_addresses.H>
+#include <fapi2.H>
+
+///
+/// @brief Sets action regs and mask settings for pervasive errors to their runtime settings.
+/// @param[in] i_target Centaur target
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+fapi2::ReturnCode mss_unmask_pervasive_errors(const fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP>& i_target)
+{
+ FAPI_INF("ENTER mss_unmask_pervasive_errors()");
+
+ //*************************
+ //*************************
+ // TP_PERV_LFIR
+ //*************************
+ //*************************
+
+ fapi2::buffer<uint64_t> l_tp_perv_lfir_mask_or;
+ fapi2::buffer<uint64_t> l_tp_perv_lfir_mask_and;
+ fapi2::buffer<uint64_t> l_tp_perv_lfir_action0;
+ fapi2::buffer<uint64_t> l_tp_perv_lfir_action1;
+ fapi2::buffer<uint64_t> l_mem_perv_lfir_mask_or;
+ fapi2::buffer<uint64_t> l_mem_perv_lfir_mask_and;
+ fapi2::buffer<uint64_t> l_mem_perv_lfir_action0;
+ fapi2::buffer<uint64_t> l_mem_perv_lfir_action1;
+ fapi2::buffer<uint64_t> l_nest_perv_lfir_mask_or;
+ fapi2::buffer<uint64_t> l_nest_perv_lfir_mask_and;
+ fapi2::buffer<uint64_t> l_nest_perv_lfir_action0;
+ fapi2::buffer<uint64_t> l_nest_perv_lfir_action1;
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ // Read action0
+ FAPI_TRY(fapi2::getScom(i_target, CEN_LOCAL_FIR_ACTION0_PCB, l_tp_perv_lfir_action0));
+
+ // Read action1
+ FAPI_TRY(fapi2::getScom(i_target, CEN_LOCAL_FIR_ACTION1_PCB, l_tp_perv_lfir_action1));
+
+ l_tp_perv_lfir_mask_or.flush<0>();
+ l_tp_perv_lfir_mask_and.flush<1>();
+
+ // 0 CFIR internal parity error recoverable unmask
+ l_tp_perv_lfir_action0.clearBit<0>();
+ l_tp_perv_lfir_action1.setBit<0>();
+ l_tp_perv_lfir_mask_and.clearBit<0>();
+
+ // 1 GPIO (PCB error) recoverable mask (forever)
+ // 2 CC (PCB error) recoverable mask (forever)
+ // 3 CC (OPCG, parity, scan collision) recoverable mask (forever)
+ // 4 PSC (PCB error) recoverable mask (forever)
+ // 5 PSC (parity error) recoverable mask (forever)
+ // 6 Thermal (parity error) recoverable mask (forever)
+ // 7 Thermal (PCB error) recoverable mask (forever)
+ // 8 Thermal (critical Trip error) recoverable mask (forever)
+ // 9 Thermal (fatal Trip error) recoverable mask (forever)
+ // 10 Thermal (Voltage trip error) recoverable mask (forever)
+ // 11 Trace Array recoverable mask (forever)
+ // 12 Trace Array recoverable mask (forever)
+ l_tp_perv_lfir_action0.clearBit<1, 12>();
+ l_tp_perv_lfir_action1.setBit<1, 12>();
+ l_tp_perv_lfir_mask_or.setBit<1, 12>();
+
+ // 13 ITR recoverable unmask
+ l_tp_perv_lfir_action0.clearBit<13>();
+ l_tp_perv_lfir_action1.setBit<13>();
+ l_tp_perv_lfir_mask_and.clearBit<13>();
+
+ // 14 ITR recoverable unmask
+ l_tp_perv_lfir_action0.clearBit<14>();
+ l_tp_perv_lfir_action1.setBit<14>();
+ l_tp_perv_lfir_mask_and.clearBit<14>();
+
+
+ // 15 ITR (itr_tc_pcbsl_slave_fir_err) recoverable mask (forever)
+ // 16 PIB recoverable mask (forever)
+ // 17 PIB recoverable mask (forever)
+ // 18 PIB recoverable mask (forever)
+ l_tp_perv_lfir_action0.clearBit<15, 4>();
+ l_tp_perv_lfir_action1.setBit<15, 4>();
+ l_tp_perv_lfir_mask_or.setBit<15, 4>();
+
+
+ // NOTE: 19 and 20 already cleared and unmasked in cen_mem_pll_setup.C
+ // 19 nest PLLlock recoverable unmask
+ // 20 mem PLLlock recoverable unmask
+
+ // 21:39 unused local errors recoverable mask (forever)
+ // 40 local xstop in another chiplet recoverable mask (forever)
+ l_tp_perv_lfir_action0.clearBit<21, 20>();
+ l_tp_perv_lfir_action1.setBit<21, 20>();
+ l_tp_perv_lfir_mask_or.setBit<21, 20>();
+
+ // 41:63 Reserved not implemented, so won't touch these
+
+
+ // Write action0
+ FAPI_TRY(fapi2::putScom(i_target, CEN_LOCAL_FIR_ACTION0_PCB, l_tp_perv_lfir_action0));
+
+ // Write action1
+ FAPI_TRY(fapi2::putScom(i_target, CEN_LOCAL_FIR_ACTION1_PCB, l_tp_perv_lfir_action1));
+
+ // Write mask OR
+ FAPI_TRY(fapi2::putScom(i_target, CEN_LOCAL_FIR_MASK_PCB2, l_tp_perv_lfir_mask_or));
+
+ // Write mask AND
+ FAPI_TRY(fapi2::putScom(i_target, CEN_LOCAL_FIR_MASK_PCB1, l_tp_perv_lfir_mask_and));
+
+
+ //*************************
+ //*************************
+ // NEST_PERV_LFIR
+ //*************************
+ //*************************
+
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_nest_perv_lfir_action0.flush<0>();
+ l_nest_perv_lfir_action1.flush<0>();
+ l_nest_perv_lfir_mask_or.flush<0>();
+ l_nest_perv_lfir_mask_and.flush<1>();
+
+ // 0 CFIR internal parity error recoverable unmask
+ l_nest_perv_lfir_action0.clearBit<0>();
+ l_nest_perv_lfir_action1.setBit<0>();
+ l_nest_perv_lfir_mask_and.clearBit<0>();
+
+ // 1 GPIO (PCB error) recoverable mask (forever)
+ // 2 CC (PCB error) recoverable mask (forever)
+ // 3 CC (OPCG, parity, scan collision) recoverable mask (forever)
+ // 4 PSC (PCB error) recoverable mask (forever)
+ // 5 PSC (parity error) recoverable mask (forever)
+ // 6 Thermal (parity error) recoverable mask (forever)
+ // 7 Thermal (PCB error) recoverable mask (forever)
+ // 8 Thermal (critical Trip error) recoverable mask (forever)
+ // 9 Thermal (fatal Trip error) recoverable mask (forever)
+ // 10 Thermal (Voltage trip error) recoverable mask (forever)
+ // 11 Trace Array recoverable mask (forever)
+ // 12 Trace Array recoverable mask (forever)
+ // 13:39 unused local errors recoverable mask (forever)
+ // 40 local xstop in another chiplet recoverable mask (forever)
+ l_nest_perv_lfir_action0.clearBit<1, 40>();
+ l_nest_perv_lfir_action1.setBit<1, 40>();
+ l_nest_perv_lfir_mask_or.setBit<1, 40>();
+
+ // 41:63 Reserved not implemented, so won't touch these
+
+ // Write action0
+ FAPI_TRY(fapi2::putScom(i_target, CEN_TCN_LOCAL_FIR_ACTION0_PCB, l_nest_perv_lfir_action0));
+
+ // Write action1
+ FAPI_TRY(fapi2::putScom(i_target, CEN_TCN_LOCAL_FIR_ACTION1_PCB, l_nest_perv_lfir_action1));
+
+ // Write mask OR
+ FAPI_TRY(fapi2::putScom(i_target, CEN_TCN_LOCAL_FIR_MASK_PCB2, l_nest_perv_lfir_mask_or));
+
+ // Write mask AND
+ FAPI_TRY(fapi2::putScom(i_target, CEN_TCN_LOCAL_FIR_MASK_PCB1, l_nest_perv_lfir_mask_and));
+
+ //*************************
+ //*************************
+ // MEM_PERV_LFIR
+ //*************************
+ //*************************
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_mem_perv_lfir_action0.flush<0>();
+ l_mem_perv_lfir_action1.flush<0>();
+ l_mem_perv_lfir_mask_or.flush<0>();
+ l_mem_perv_lfir_mask_and.flush<1>();
+
+ // 0 CFIR internal parity error recoverable unmask
+ l_mem_perv_lfir_action0.clearBit<0>();
+ l_mem_perv_lfir_action1.setBit<0>();
+ l_mem_perv_lfir_mask_and.clearBit<0>();
+
+ // 1 GPIO (PCB error) recoverable mask (forever)
+ // 2 CC (PCB error) recoverable mask (forever)
+ // 3 CC (OPCG, parity, scan collision) recoverable mask (forever)
+ // 4 PSC (PCB error) recoverable mask (forever)
+ // 5 PSC (parity error) recoverable mask (forever)
+ // 6 Thermal (parity error) recoverable mask (forever)
+ // 7 Thermal (PCB error) recoverable mask (forever)
+ // 8 Thermal (critical Trip error) recoverable mask (forever)
+ // 9 Thermal (fatal Trip error) recoverable mask (forever)
+ // 10 Thermal (Voltage trip error) recoverable mask (forever)
+ // 11 mba01 Trace Array recoverable mask (forever)
+ // 12 mba01 Trace Array recoverable mask (forever)
+ // 13 mba23 Trace Array recoverable mask (forever)
+ // 14 mba23 Trace Array recoverable mask (forever)
+ // 15:39 unused local errors recoverable mask (forever)
+ // 40 local xstop in another chiplet recoverable mask (forever)
+ l_mem_perv_lfir_action0.clearBit<1, 40>();
+ l_mem_perv_lfir_action1.setBit<1, 40>();
+ l_mem_perv_lfir_mask_or.setBit<1, 40>();
+
+ // 41:63 Reserved not implemented, so won't touch these
+
+ // Write action0
+ FAPI_TRY(fapi2::putScom(i_target, CEN_TCM_LOCAL_FIR_ACTION0_PCB, l_mem_perv_lfir_action0));
+
+ // Write action1
+ FAPI_TRY(fapi2::putScom(i_target, CEN_TCM_LOCAL_FIR_ACTION1_PCB, l_mem_perv_lfir_action1));
+
+ // Write mask OR
+ FAPI_TRY(fapi2::putScom(i_target, CEN_TCM_LOCAL_FIR_MASK_PCB2, l_mem_perv_lfir_mask_or));
+
+ // Write mask AND
+ FAPI_TRY(fapi2::putScom(i_target, CEN_TCM_LOCAL_FIR_MASK_PCB1, l_mem_perv_lfir_mask_and));
+
+fapi_try_exit:
+ FAPI_INF("EXIT mss_unmask_pervasive_errors()");
+ return fapi2::current_err;
+}
+
+///
+/// @brief Sets action regs and mask settings for inband errors to their runtime settings.
+/// @param[in] i_target Centaur target
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note To be called at the end of cen_mem_startclocks.C
+///
+fapi2::ReturnCode mss_unmask_inband_errors(const fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP>& i_target)
+
+{
+ FAPI_INF("ENTER mss_unmask_inband_errors()");
+
+ //*************************
+ //*************************
+ // MBS_FIR_REG
+ //*************************
+ //*************************
+
+ fapi2::buffer<uint64_t> l_mbs_fir_mask;
+ fapi2::buffer<uint64_t> l_mbs_fir_mask_or;
+ fapi2::buffer<uint64_t> l_mbs_fir_mask_and;
+ fapi2::buffer<uint64_t> l_mbs_fir_action0;
+ fapi2::buffer<uint64_t> l_mbs_fir_action1;
+
+ uint8_t l_dd2_fir_bit_defn_changes = 0;
+
+ // Get attribute that tells us if mbspa 0 cmd complete attention is fixed for dd2
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_CENTAUR_EC_FEATURE_DD2_FIR_BIT_DEFN_CHANGES, i_target,
+ l_dd2_fir_bit_defn_changes),
+ "Error getting ATTR_CEN_CENTAUR_EC_FEATURE_DD2_FIR_BIT_DEFN_CHANGES");
+
+ // Read mask
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBS_FIR_MASK_REG, l_mbs_fir_mask));
+
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_mbs_fir_action0.flush<0>();
+ l_mbs_fir_action1.flush<0>();
+ l_mbs_fir_mask_or.flush<0>();
+ l_mbs_fir_mask_and.flush<1>();
+
+ // 0 host_protocol_error channel checkstop unmask
+ l_mbs_fir_action0.clearBit<0>();
+ l_mbs_fir_action1.clearBit<0>();
+ l_mbs_fir_mask_and.clearBit<0>();
+
+ // 1 int_protocol_error channel checkstop unmask
+ l_mbs_fir_action0.clearBit<1>();
+ l_mbs_fir_action1.clearBit<1>();
+ l_mbs_fir_mask_and.clearBit<1>();
+
+ // 2 invalid_address_error channel checkstop mask (until unmask_fetch_errors)
+ l_mbs_fir_action0.clearBit<2>();
+ l_mbs_fir_action1.clearBit<2>();
+ l_mbs_fir_mask_or.setBit<2>();
+
+ // 3 external_timeout recoverable mask (until unmask_fetch_errors)
+ l_mbs_fir_action0.clearBit<3>();
+ l_mbs_fir_action1.setBit<3>();
+ l_mbs_fir_mask_or.setBit<3>();
+
+ // 4 internal_timeout recoverable mask (until unmask_fetch_errors)
+ l_mbs_fir_action0.clearBit<4>();
+ l_mbs_fir_action1.setBit<4>();
+ l_mbs_fir_mask_or.setBit<4>();
+
+ // 5 int_buffer_ce recoverable unmask
+ l_mbs_fir_action0.clearBit<5>();
+ l_mbs_fir_action1.setBit<5>();
+ l_mbs_fir_mask_and.clearBit<5>();
+
+ // 6 int_buffer_ue channel checkstop unmask
+ // HW278850: 8B ecc UE from SRB,PFB not transformed to SUE when allocating into L4
+ l_mbs_fir_action0.clearBit<6>();
+ l_mbs_fir_action1.clearBit<6>();
+ l_mbs_fir_mask_and.clearBit<6>();
+
+ // 7 int_buffer_sue recoverable mask (forever)
+ l_mbs_fir_action0.clearBit<7>();
+ l_mbs_fir_action1.setBit<7>();
+ l_mbs_fir_mask_or.setBit<7>();
+
+ // 8 int_parity_error channel checkstop unmask
+ l_mbs_fir_action0.clearBit<8>();
+ l_mbs_fir_action1.clearBit<8>();
+ l_mbs_fir_mask_and.clearBit<8>();
+
+ // 9 cache_srw_ce recoverable mask (until unmask_fetch_errors)
+ l_mbs_fir_action0.clearBit<9>();
+ l_mbs_fir_action1.setBit<9>();
+ l_mbs_fir_mask_or.setBit<9>();
+
+ // 10 cache_srw_ue recoverable mask (until unmask_fetch_errors)
+ l_mbs_fir_action0.clearBit<10>();
+ l_mbs_fir_action1.setBit<10>();
+ l_mbs_fir_mask_or.setBit<10>();
+
+ // 11 cache_srw_sue recoverable mask (forever)
+ l_mbs_fir_action0.clearBit<11>();
+ l_mbs_fir_action1.setBit<11>();
+ l_mbs_fir_mask_or.setBit<11>();
+
+ // 12 cache_co_ce recoverable mask (until unmask_fetch_errors)
+ l_mbs_fir_action0.clearBit<12>();
+ l_mbs_fir_action1.setBit<12>();
+ l_mbs_fir_mask_or.setBit<12>();
+
+ // 13 cache_co_ue recoverable mask (until unmask_fetch_errors)
+ l_mbs_fir_action0.clearBit<13>();
+ l_mbs_fir_action1.setBit<13>();
+ l_mbs_fir_mask_or.setBit<13>();
+
+ // 14 cache_co_sue recoverable mask (forever)
+ l_mbs_fir_action0.clearBit<14>();
+ l_mbs_fir_action1.setBit<14>();
+ l_mbs_fir_mask_or.setBit<14>();
+
+ // 15 dir_ce recoverable DD1: mask (forever)
+ // 15 dir_ce recoverable DD2: mask (until unmask_fetch_errors)
+ l_mbs_fir_action0.clearBit<15>();
+ l_mbs_fir_action1.setBit<15>();
+ l_mbs_fir_mask_or.setBit<15>();
+
+ // 16 dir_ue channel checkstop mask (until unmask_fetch_errors)
+ l_mbs_fir_action0.clearBit<16>();
+ l_mbs_fir_action1.clearBit<16>();
+ l_mbs_fir_mask_or.setBit<16>();
+
+ // 17 dir_member_deleted recoverable mask (forever)
+ l_mbs_fir_action0.clearBit<17>();
+ l_mbs_fir_action1.setBit<17>();
+ l_mbs_fir_mask_or.setBit<17>();
+
+ // 18 dir_all_members_deleted channel checkstop mask (until unmask_fetch_errors)
+ l_mbs_fir_action0.clearBit<18>();
+ l_mbs_fir_action1.clearBit<18>();
+ l_mbs_fir_mask_or.setBit<18>();
+
+ // 19 lru_error recoverable mask (until unmask_fetch_errors)
+ l_mbs_fir_action0.clearBit<19>();
+ l_mbs_fir_action1.setBit<19>();
+ l_mbs_fir_mask_or.setBit<19>();
+
+ // 20 eDRAM error channel checkstop mask (until unmask_fetch_errors)
+ l_mbs_fir_action0.clearBit<20>();
+ l_mbs_fir_action1.clearBit<20>();
+ l_mbs_fir_mask_or.setBit<20>();
+
+ // 21 emergency_throttle_set recoverable mask (forever)
+ l_mbs_fir_action0.clearBit<21>();
+ l_mbs_fir_action1.setBit<21>();
+ l_mbs_fir_mask_or.setBit<21>();
+
+ // 22 Host Inband Read Error recoverable mask (forever)
+ l_mbs_fir_action0.clearBit<22>();
+ l_mbs_fir_action1.setBit<22>();
+ l_mbs_fir_mask_or.setBit<22>();
+
+ // 23 Host Inband Write Error recoverable mask (forever)
+ l_mbs_fir_action0.clearBit<23>();
+ l_mbs_fir_action1.setBit<23>();
+ l_mbs_fir_mask_or.setBit<23>();
+
+ // 24 OCC Inband Read Error recoverable mask (forever)
+ l_mbs_fir_action0.clearBit<24>();
+ l_mbs_fir_action1.setBit<24>();
+ l_mbs_fir_mask_or.setBit<24>();
+
+ // 25 OCC Inband Write Error recoverable mask (forever)
+ l_mbs_fir_action0.clearBit<25>();
+ l_mbs_fir_action1.setBit<25>();
+ l_mbs_fir_mask_or.setBit<25>();
+
+ // 26 srb_buffer_ce recoverable mask (until unmask_fetch_errors)
+ l_mbs_fir_action0.clearBit<26>();
+ l_mbs_fir_action1.setBit<26>();
+ l_mbs_fir_mask_or.setBit<26>();
+
+ // 27 srb_buffer_ue recoverable mask (until unmask_fetch_errors)
+ l_mbs_fir_action0.clearBit<27>();
+ l_mbs_fir_action1.setBit<27>();
+ l_mbs_fir_mask_or.setBit<27>();
+
+ // 28 srb_buffer_sue recoverable mask (forever)
+ l_mbs_fir_action0.clearBit<28>();
+ l_mbs_fir_action1.setBit<28>();
+ l_mbs_fir_mask_or.setBit<28>();
+
+ if (l_dd2_fir_bit_defn_changes)
+ {
+ // 29 dir_purge_ce recoverable mask
+ l_mbs_fir_action0.clearBit<29>();
+ l_mbs_fir_action1.setBit<29>();
+ l_mbs_fir_mask_or.setBit<29>();
+
+ // 30 proximal_ce_ue channel checkstop mask (until unmask_fetch_errors)
+ l_mbs_fir_action0.clearBit<30>();
+ l_mbs_fir_action1.clearBit<30>();
+ l_mbs_fir_mask_or.setBit<30>();
+
+ // 31 spare recoverable mask
+ l_mbs_fir_action0.clearBit<31>();
+ l_mbs_fir_action1.setBit<31>();
+ l_mbs_fir_mask_or.setBit<31>();
+
+ // 32 spare recoverable mask
+ l_mbs_fir_action0.clearBit<32>();
+ l_mbs_fir_action1.setBit<32>();
+ l_mbs_fir_mask_or.setBit<33>();
+
+ // 33 internal_scom_error recoverable unmask
+ l_mbs_fir_action0.clearBit<33>();
+ l_mbs_fir_action1.setBit<33>();
+ l_mbs_fir_mask_and.clearBit<33>();
+
+ // 34 internal_scom_error_copy recoverable unmask
+ l_mbs_fir_action0.clearBit<34>();
+ l_mbs_fir_action1.setBit<34>();
+ l_mbs_fir_mask_and.clearBit<34>();
+
+ // 35:63 Reserved not implemented, so won't touch these
+ }
+
+ else
+ {
+ // 29 internal_scom_error recoverable unmask
+ l_mbs_fir_action0.clearBit<29>();
+ l_mbs_fir_action1.setBit<29>();
+ l_mbs_fir_mask_and.clearBit<29>();
+
+ // 30 internal_scom_error_copy recoverable unmask
+ l_mbs_fir_action0.clearBit<30>();
+ l_mbs_fir_action1.setBit<30>();
+ l_mbs_fir_mask_and.clearBit<30>();
+
+ // 31:63 Reserved not implemented, so won't touch these
+ }
+
+ // Write action0
+ FAPI_TRY(fapi2::putScom(i_target, CEN_MBS_FIR_ACTION0_REG_RO, l_mbs_fir_action0));
+ // Write action1
+ FAPI_TRY(fapi2::putScom(i_target, CEN_MBS_FIR_ACTION1_REG_RO, l_mbs_fir_action1));
+
+
+ // Write mask OR
+ FAPI_TRY(fapi2::putScom(i_target, CEN_MBS_FIR_MASK_REG_WO_OR, l_mbs_fir_mask_or));
+ // Write mask AND
+ FAPI_TRY(fapi2::putScom(i_target, CEN_MBS_FIR_MASK_REG_WO_AND, l_mbs_fir_mask_and))
+
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBS_FIR_ACTION0_REG_RO, l_mbs_fir_action0));
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBS_FIR_ACTION1_REG_RO, l_mbs_fir_action1));
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBS_FIR_MASK_REG, l_mbs_fir_mask));
+
+ //************************************************
+
+fapi_try_exit:
+ FAPI_INF("EXIT mss_unmask_inband_errors()");
+ return fapi2::current_err;
+
+}
+
+///
+/// @brief Sets action regs and mask settings for ddr phy errors to runtime settings.
+/// @param[in] i_target MBA target
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note To be called at the end of proc_cen_framelock.C
+///
+fapi2::ReturnCode mss_unmask_ddrphy_errors(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target)
+{
+ FAPI_INF("ENTER mss_unmask ddrphy_errors()");
+
+ //*************************
+ //*************************
+ // DDRPHY_FIR_REG
+ //*************************
+ //*************************
+
+ fapi2::buffer<uint64_t> l_ddrphy_fir_mask;
+ fapi2::buffer<uint64_t> l_ddrphy_fir_mask_or;
+ fapi2::buffer<uint64_t> l_ddrphy_fir_mask_and;
+ fapi2::buffer<uint64_t> l_ddrphy_fir_action0;
+ fapi2::buffer<uint64_t> l_ddrphy_fir_action1;
+ fapi2::buffer<uint64_t> l_mbafir_mask;
+ fapi2::buffer<uint64_t> l_mbafir_mask_or;
+ fapi2::buffer<uint64_t> l_mbafir_mask_and;
+ fapi2::buffer<uint64_t> l_mbafir_action0;
+ fapi2::buffer<uint64_t> l_mbafir_action1;
+
+ uint8_t l_dd2_fir_bit_defn_changes = 0;
+ fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP> l_targetCentaur;
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_ddrphy_fir_action0.flush<0>();
+ l_ddrphy_fir_action1.flush<0>();
+ l_ddrphy_fir_mask_or.flush<0>();
+ l_ddrphy_fir_mask_and.flush<0>();
+ l_ddrphy_fir_mask_and.setBit<48, 16>();
+
+ // 0:47 Reserved not implemented, so won't touch these
+
+ // 48 ddr0_fsm_ckstp channel checkstop unmask
+ l_ddrphy_fir_action0.clearBit<48>();
+ l_ddrphy_fir_action1.clearBit<48>();
+ l_ddrphy_fir_mask_and.clearBit<48>();
+
+ // 49 ddr0_parity_ckstp channel checkstop unmask
+ l_ddrphy_fir_action0.clearBit<49>();
+ l_ddrphy_fir_action1.clearBit<49>();
+ l_ddrphy_fir_mask_and.clearBit<49>();
+
+ // 50 ddr0_calibration_error recoverable mask (forever)
+ l_ddrphy_fir_action0.clearBit<50>();
+ l_ddrphy_fir_action1.setBit<50>();
+ l_ddrphy_fir_mask_or.setBit<50>();
+
+ // 51 ddr0_fsm_err recoverable unmask
+ l_ddrphy_fir_action0.clearBit<51>();
+ l_ddrphy_fir_action1.setBit<51>();
+ l_ddrphy_fir_mask_and.clearBit<51>();
+
+ // 52 ddr0_parity_err recoverable unmask
+ l_ddrphy_fir_action0.clearBit<52>();
+ l_ddrphy_fir_action1.setBit<52>();
+ l_ddrphy_fir_mask_and.clearBit<52>();
+
+ // 53 ddr01_fir_parity_err recoverable unmask
+ l_ddrphy_fir_action0.clearBit<53>();
+ l_ddrphy_fir_action1.setBit<53>();
+ l_ddrphy_fir_mask_and.clearBit<53>();
+
+ // 54 Reserved recoverable mask (forever)
+ l_ddrphy_fir_action0.clearBit<54>();
+ l_ddrphy_fir_action1.setBit<54>();
+ l_ddrphy_fir_mask_or.setBit<54>();
+
+ // 55 Reserved recoverable mask (forever)
+ l_ddrphy_fir_action0.clearBit<55>();
+ l_ddrphy_fir_action1.setBit<55>();
+ l_ddrphy_fir_mask_or.setBit<55>();
+
+ // 56 ddr1_fsm_ckstp channel checkstop unmask
+ l_ddrphy_fir_action0.clearBit<56>();
+ l_ddrphy_fir_action1.clearBit<56>();
+ l_ddrphy_fir_mask_and.clearBit<56>();
+
+ // 57 ddr1_parity_ckstp channel checkstop unmask
+ l_ddrphy_fir_action0.clearBit<57>();
+ l_ddrphy_fir_action1.clearBit<57>();
+ l_ddrphy_fir_mask_and.clearBit<57>();
+
+ // 58 ddr1_calibration_error recoverable mask (forever)
+ l_ddrphy_fir_action0.clearBit<58>();
+ l_ddrphy_fir_action1.setBit<58>();
+ l_ddrphy_fir_mask_or.setBit<58>();
+
+ // 59 ddr1_fsm_err recoverable unmask
+ l_ddrphy_fir_action0.clearBit<59>();
+ l_ddrphy_fir_action1.setBit<59>();
+ l_ddrphy_fir_mask_and.clearBit<59>();
+
+ // 60 ddr1_parity_err recoverable unmask
+ l_ddrphy_fir_action0.clearBit<60>();
+ l_ddrphy_fir_action1.setBit<60>();
+ l_ddrphy_fir_mask_and.clearBit<60>();
+
+ // 61 Reserved recoverable mask (forever)
+ l_ddrphy_fir_action0.clearBit<61>();
+ l_ddrphy_fir_action1.setBit<61>();
+ l_ddrphy_fir_mask_or.setBit<61>();
+
+ // 62 Reserved recoverable mask (forever)
+ l_ddrphy_fir_action0.clearBit<62>();
+ l_ddrphy_fir_action1.setBit<62>();
+ l_ddrphy_fir_mask_or.setBit<62>();
+
+ // 63 Reserved recoverable mask (forever)
+ l_ddrphy_fir_action0.clearBit<63>();
+ l_ddrphy_fir_action1.setBit<63>();
+ l_ddrphy_fir_mask_or.setBit<63>();
+
+ // Write action0
+ FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_PHY01_DDRPHY_FIR_ACTION0_REG_RO, l_ddrphy_fir_action0));
+
+ // Write action1
+ FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_PHY01_DDRPHY_FIR_ACTION1_REG_RO, l_ddrphy_fir_action1));
+
+ // Write mask OR
+ FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_PHY01_DDRPHY_FIR_MASK_REG_WO_OR, l_ddrphy_fir_mask_or));
+ // Write mask AND
+ FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_PHY01_DDRPHY_FIR_MASK_REG_WO_AND, l_ddrphy_fir_mask_and));
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_PHY01_DDRPHY_FIR_ACTION0_REG_RO, l_ddrphy_fir_action0));
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_PHY01_DDRPHY_FIR_ACTION1_REG_RO, l_ddrphy_fir_action1));
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_PHY01_DDRPHY_FIR_MASK_REG, l_ddrphy_fir_mask));
+
+ //************************************************
+
+
+ //*************************
+ //*************************
+ // MBAFIR
+ //*************************
+ //*************************
+
+ // Get Centaur target for the given MBA
+ l_targetCentaur = i_target.getParent<fapi2::TARGET_TYPE_MEMBUF_CHIP>();
+ // Get attribute that tells us if mbspa 0 cmd complete attention is fixed for dd2
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_CENTAUR_EC_FEATURE_DD2_FIR_BIT_DEFN_CHANGES, l_targetCentaur,
+ l_dd2_fir_bit_defn_changes), "Error getting ATTR_CEN_CENTAUR_EC_FEATURE_DD2_FIR_BIT_DEFN_CHANGES");
+
+
+ // Read mask
+ FAPI_TRY(fapi2::getScom(i_target,
+ CEN_MBA_MBAFIRMASK,
+ l_mbafir_mask));
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_mbafir_action0.flush<0>();
+ l_mbafir_action1.flush<0>();
+ l_mbafir_mask_or.flush<0>();
+ l_mbafir_mask_and.flush<1>();
+
+
+ // 0 Invalid_Maint_Cmd recoverable masked (forever)
+ l_mbafir_action0.clearBit<0>();
+ l_mbafir_action1.setBit<0>();
+ l_mbafir_mask_or.setBit<0>();
+
+ // 1 Invalid_Maint_Address recoverable masked (forever)
+ l_mbafir_action0.clearBit<1>();
+ l_mbafir_action1.setBit<1>();
+ l_mbafir_mask_or.setBit<1>();
+
+ // 2 Multi_address_Maint_timeout recoverable masked (until mss_unmask_maint_errors)
+ l_mbafir_action0.clearBit<2>();
+ l_mbafir_action1.setBit<2>();
+ l_mbafir_mask_or.setBit<2>();
+
+ // 3 Internal_fsm_error channel checkstop unmask
+ l_mbafir_action0.clearBit<3>();
+ l_mbafir_action1.clearBit<3>();
+ l_mbafir_mask_and.clearBit<3>();
+
+ // 4 MCBIST_Error recoverable mask (forever)
+ l_mbafir_action0.clearBit<4>();
+ l_mbafir_action1.setBit<4>();
+ l_mbafir_mask_or.setBit<4>();
+
+ // 5 scom_cmd_reg_pe channel checkstop unmask
+ l_mbafir_action0.clearBit<5>();
+ l_mbafir_action1.clearBit<5>();
+ l_mbafir_mask_and.clearBit<5>();
+
+ // 6 channel_chkstp_err channel checkstop unmask
+ l_mbafir_action0.clearBit<6>();
+ l_mbafir_action1.clearBit<6>();
+ l_mbafir_mask_and.clearBit<6>();
+
+ // 7 wrd_caw2_data_ce_ue_err channel checkstop masked (until mss_unmask_maint_errors)
+ l_mbafir_action0.clearBit<7>();
+ l_mbafir_action1.clearBit<7>();
+ l_mbafir_mask_or.setBit<7>();
+
+ if (l_dd2_fir_bit_defn_changes)
+ {
+ // 8 maint_1hot_st_error_dd2 channel checkstop unmask
+ l_mbafir_action0.clearBit<8>();
+ l_mbafir_action1.clearBit<8>();
+ l_mbafir_mask_and.clearBit<8>();
+ }
+ else
+ {
+ // 8 RESERVED recoverable mask (forever)
+ l_mbafir_action0.clearBit<8>();
+ l_mbafir_action1.setBit<8>();
+ l_mbafir_mask_or.setBit<8>();
+ }
+
+ // 9:14 RESERVED recoverable mask (forever)
+ l_mbafir_action0.clearBit<9, 6>();
+ l_mbafir_action1.setBit<9, 6>();
+ l_mbafir_mask_or.setBit<9, 6>();
+
+ // 15 internal scom error recoverable unmask
+ l_mbafir_action0.clearBit<15>();
+ l_mbafir_action1.setBit<15>();
+ l_mbafir_mask_and.clearBit<15>();
+
+ // 16 internal scom error clone recoverable unmask
+ l_mbafir_action0.clearBit<16>();
+ l_mbafir_action1.setBit<16>();
+ l_mbafir_mask_and.clearBit<16>();
+
+
+ // 17:63 RESERVED not implemented, so won't touch these
+
+ // Write action0
+ FAPI_TRY(fapi2::putScom(i_target,
+ CEN_MBA_MBAFIRACT0,
+ l_mbafir_action0));
+
+ // Write action1
+ FAPI_TRY(fapi2::putScom(i_target,
+ CEN_MBA_MBAFIRACT1,
+ l_mbafir_action1));
+
+ // Write mask OR
+ FAPI_TRY(fapi2::putScom(i_target,
+ CEN_MBA_MBAFIRMASK_WO_OR,
+ l_mbafir_mask_or));
+
+
+ // Write mask AND
+ FAPI_TRY(fapi2::putScom(i_target,
+ CEN_MBA_MBAFIRMASK_WO_AND,
+ l_mbafir_mask_and));
+
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ FAPI_TRY(fapi2::getScom(i_target,
+ CEN_MBA_MBAFIRACT0,
+ l_mbafir_action0));
+ FAPI_TRY(fapi2::getScom(i_target,
+ CEN_MBA_MBAFIRACT1,
+ l_mbafir_action1));
+ FAPI_TRY(fapi2::getScom(i_target,
+ CEN_MBA_MBAFIRMASK,
+ l_mbafir_mask));
+
+ //************************************************
+
+fapi_try_exit:
+ FAPI_INF("EXIT mss_unmask_ddrphy_errors()");
+ return fapi2::current_err;
+}
+
+///
+/// @brief Sets MBACALFIR action regs to their runtime settings.
+/// Unmasks errors that are valid for PRD to handle after mss_draminit procedure.
+/// @param[in] i_target MBA target
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note To be called at the end of mss_draminit.C.
+///
+fapi2::ReturnCode mss_unmask_draminit_errors(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target)
+{
+ FAPI_INF("ENTER mss_unmask_draminit_errors()");
+
+ //*************************
+ //*************************
+ // MBACALFIR
+ //*************************
+ //*************************
+
+ fapi2::buffer<uint64_t> l_mbacalfir_mask;
+ fapi2::buffer<uint64_t> l_mbacalfir_mask_or;
+ fapi2::buffer<uint64_t> l_mbacalfir_mask_and;
+ fapi2::buffer<uint64_t> l_mbacalfir_action0;
+ fapi2::buffer<uint64_t> l_mbacalfir_action1;
+
+ uint8_t l_dd2_fir_bit_defn_changes = 0;
+ fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP> l_targetCentaur;
+ uint8_t l_dimm_type = 0;
+
+ // Get Centaur target for the given MBA
+ l_targetCentaur = i_target.getParent<fapi2::TARGET_TYPE_MEMBUF_CHIP>();
+
+ // Get attribute that tells us if mbspa 0 cmd complete attention is fixed for dd2
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_CENTAUR_EC_FEATURE_DD2_FIR_BIT_DEFN_CHANGES, l_targetCentaur,
+ l_dd2_fir_bit_defn_changes), "Error getting ATTR_CEN_CENTAUR_EC_FEATURE_DD2_FIR_BIT_DEFN_CHANGES");
+
+ // Get DIMM type
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DIMM_TYPE, i_target, l_dimm_type), "Error getting ATTR_CEN_EFF_DIMM_TYPE");
+
+ // Read mask
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBACALFIR_MASK, l_mbacalfir_mask));
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_mbacalfir_action0.flush<0>();
+ l_mbacalfir_action1.flush<0>();
+ l_mbacalfir_mask_or.flush<0>();
+ l_mbacalfir_mask_and.flush<1>();
+
+ // 0 MBA Recoverable Error recoverable mask (until after draminit_training)
+ l_mbacalfir_action0.clearBit<0>();
+ l_mbacalfir_action1.setBit<0>();
+ l_mbacalfir_mask_or.setBit<0>();
+
+ // 1 MBA Nonrecoverable Error channel checkstop mask (until after draminit_mc)
+ l_mbacalfir_action0.clearBit<1>();
+ l_mbacalfir_action1.clearBit<1>();
+ l_mbacalfir_mask_or.setBit<1>();
+
+ // 2 Refresh Overrun recoverable mask (until after draminit_mc)
+ l_mbacalfir_action0.clearBit<2>();
+ l_mbacalfir_action1.setBit<2>();
+ l_mbacalfir_mask_or.setBit<2>();
+
+ // 3 WAT error recoverable mask (forever)
+ l_mbacalfir_action0.clearBit<3>();
+ l_mbacalfir_action1.setBit<3>();
+ l_mbacalfir_mask_or.setBit<3>();
+
+ // 4 RCD Parity Error 0 recoverable unmask (if RDIMM or LRDIMM)
+ l_mbacalfir_action0.clearBit<4>();
+ l_mbacalfir_action1.setBit<4>();
+
+ if ((l_dimm_type == fapi2::ENUM_ATTR_CEN_EFF_DIMM_TYPE_RDIMM)
+ || (l_dimm_type == fapi2::ENUM_ATTR_CEN_EFF_DIMM_TYPE_LRDIMM))
+ {
+ l_mbacalfir_mask_and.clearBit<4>();
+ }
+ else
+ {
+ l_mbacalfir_mask_or.setBit<4>();
+ }
+
+ // 5 ddr0_cal_timeout_err recoverable mask (until after draminit_mc)
+ l_mbacalfir_action0.clearBit<5>();
+ l_mbacalfir_action1.setBit<5>();
+ l_mbacalfir_mask_or.setBit<5>();
+
+ // 6 ddr1_cal_timeout_err recoverable mask (until after draminit_mc)
+ l_mbacalfir_action0.clearBit<6>();
+ l_mbacalfir_action1.setBit<6>();
+ l_mbacalfir_mask_or.setBit<6>();
+
+ // 7 RCD Parity Error 1 recoverable unmask (if RDIMM or LRDIMM)
+ l_mbacalfir_action0.clearBit<7>();
+ l_mbacalfir_action1.setBit<7>();
+
+ if ((l_dimm_type == fapi2::ENUM_ATTR_CEN_EFF_DIMM_TYPE_RDIMM)
+ || (l_dimm_type == fapi2::ENUM_ATTR_CEN_EFF_DIMM_TYPE_LRDIMM))
+ {
+ l_mbacalfir_mask_and.clearBit<7>();
+ }
+ else
+ {
+ l_mbacalfir_mask_or.setBit<7>();
+ }
+
+ // 8 mbx to mba par error channel checkstop mask (until after draminit_training_adv)
+ l_mbacalfir_action0.clearBit<8>();
+ l_mbacalfir_action1.clearBit<8>();
+ l_mbacalfir_mask_or.setBit<8>();
+
+ // 9 mba_wrd ue recoverable mask (until mainline traffic)
+ l_mbacalfir_action0.clearBit<9>();
+ l_mbacalfir_action1.setBit<9>();
+ l_mbacalfir_mask_or.setBit<9>();
+
+ // 10 mba_wrd ce recoverable mask (until mainline traffic)
+ l_mbacalfir_action0.clearBit<10>();
+ l_mbacalfir_action1.setBit<10>();
+ l_mbacalfir_mask_or.setBit<10>();
+
+ // 11 mba_maint ue recoverable mask (until after draminit_training_adv)
+ l_mbacalfir_action0.clearBit<11>();
+ l_mbacalfir_action1.setBit<11>();
+ l_mbacalfir_mask_or.setBit<11>();
+
+ // 12 mba_maint ce recoverable mask (until after draminit_training_adv)
+ l_mbacalfir_action0.clearBit<12>();
+ l_mbacalfir_action1.setBit<12>();
+ l_mbacalfir_mask_or.setBit<12>();
+
+ // 13 ddr_cal_reset_timeout channel checkstop unmask
+ l_mbacalfir_action0.clearBit<13>();
+ l_mbacalfir_action1.clearBit<13>();
+ l_mbacalfir_mask_and.clearBit<13>();
+
+ // 14 wrq_data_ce recoverable mask (until mainline traffic)
+ l_mbacalfir_action0.clearBit<14>();
+ l_mbacalfir_action1.setBit<14>();
+ l_mbacalfir_mask_or.setBit<14>();
+
+ // 15 wrq_data_ue recoverable mask (until mainline traffic)
+ l_mbacalfir_action0.clearBit<15>();
+ l_mbacalfir_action1.setBit<15>();
+ l_mbacalfir_mask_or.setBit<15>();
+
+ // 16 wrq_data_sue recoverable mask (forever)
+ l_mbacalfir_action0.clearBit<16>();
+ l_mbacalfir_action1.setBit<16>();
+ l_mbacalfir_mask_or.setBit<16>();
+
+ // 17 wrq_rrq_hang_err recoverable mask (until after draminit_training_adv)
+ l_mbacalfir_action0.clearBit<17>();
+ l_mbacalfir_action1.setBit<17>();
+ l_mbacalfir_mask_or.setBit<17>();
+
+ // 18 sm_1hot_err channel checkstop unmask
+ l_mbacalfir_action0.clearBit<18>();
+ l_mbacalfir_action1.clearBit<18>();
+ l_mbacalfir_mask_and.clearBit<18>();
+
+ // 19 wrd_scom_error recoverable unmask
+ l_mbacalfir_action0.clearBit<19>();
+ l_mbacalfir_action1.setBit<19>();
+ l_mbacalfir_mask_and.clearBit<19>();
+
+ if (l_dd2_fir_bit_defn_changes)
+ {
+ // 20 rhmr_prim_reached_max recoverable mask (forever)
+ l_mbacalfir_action0.clearBit<20>();
+ l_mbacalfir_action1.setBit<20>();
+ l_mbacalfir_mask_or.setBit<20>();
+
+ // 21 rhmr_sec_reached_max recoverable mask (forever)
+ l_mbacalfir_action0.clearBit<21>();
+ l_mbacalfir_action1.setBit<21>();
+ l_mbacalfir_mask_or.setBit<21>();
+
+ // 22 rhmr_sec_already_full recoverable mask (forever)
+ l_mbacalfir_action0.clearBit<22>();
+ l_mbacalfir_action1.setBit<22>();
+ l_mbacalfir_mask_or.setBit<22>();
+
+ // 23 Reserved recoverable mask (forever)
+ l_mbacalfir_action0.clearBit<23>();
+ l_mbacalfir_action1.setBit<23>();
+ l_mbacalfir_mask_or.setBit<23>();
+
+ // 24 internal_scom_error recoverable unmask
+ l_mbacalfir_action0.clearBit<24>();
+ l_mbacalfir_action1.setBit<24>();
+ l_mbacalfir_mask_and.clearBit<24>();
+
+ // 25 internal_scom_error_copy recoverable unmask
+ l_mbacalfir_action0.clearBit<25>();
+ l_mbacalfir_action1.setBit<25>();
+ l_mbacalfir_mask_and.clearBit<25>();
+
+ // 26-63 Reserved not implemented, so won't touch these
+ }
+ else
+ {
+ // 20 internal_scom_error recoverable unmask
+ l_mbacalfir_action0.clearBit<20>();
+ l_mbacalfir_action1.setBit<20>();
+ l_mbacalfir_mask_and.clearBit<20>();
+
+ // 21 internal_scom_error_copy recoverable unmask
+ l_mbacalfir_action0.clearBit<21>();
+ l_mbacalfir_action1.setBit<21>();
+ l_mbacalfir_mask_and.clearBit<21>();
+
+ // 22-63 Reserved not implemented, so won't touch these
+ }
+
+
+ // Write action0
+ FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBACALFIR_ACTION0, l_mbacalfir_action0));
+
+ // Write action1
+ FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBACALFIR_ACTION1, l_mbacalfir_action1));
+
+ // Write mask OR
+ FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBACALFIR_MASK_WO_OR, l_mbacalfir_mask_or));
+
+ // Write mask AND
+ FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBACALFIR_MASK_WO_AND, l_mbacalfir_mask_and));
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBACALFIR_ACTION0, l_mbacalfir_action0));
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBACALFIR_ACTION1, l_mbacalfir_action1));
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBACALFIR_MASK, l_mbacalfir_mask));
+
+ //************************************************
+
+fapi_try_exit:
+ FAPI_INF("EXIT mss_unmask_draminit_errors()");
+ return fapi2::current_err;
+}
+
+///
+/// @brief Unmasks MBACALFIR errors that are valid for PRD to handle after mss_draminit_training
+/// @param[in] i_target MBA target
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note To be called at the end of mss_draminit_training.C.
+///
+fapi2::ReturnCode mss_unmask_draminit_training_errors(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target)
+{
+ FAPI_INF("ENTER mss_unmask_draminit_training_errors()");
+
+ //*************************
+ //*************************
+ // MBACALFIR
+ //*************************
+ //*************************
+
+ fapi2::buffer<uint64_t> l_mbacalfir_mask;
+ fapi2::buffer<uint64_t> l_mbacalfir_mask_and;
+
+ // NOTE: In the IPL sequence, mss_unmask_draminit_errors has already been
+ // called, which has already set the MBACALFIR action regs to their runtime
+ // values, so no need to touch the action regs here.
+
+ // NOTE: In the IPL sequence, mss_unmask_draminit_errors has already been
+ // called, which has already unmasked the approproiate MBACALFIR errors
+ // following mss_draminit. So all we will do here is unmask a few more
+ // errors that would be considered valid after the mss_draminit_training
+ // procedure.
+
+ // Read mask
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBACALFIR_MASK, l_mbacalfir_mask));
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_mbacalfir_mask_and.flush<1>();
+
+ // 0 MBA Recoverable Error recoverable umask
+ FAPI_TRY(l_mbacalfir_mask_and.clearBit(0));
+
+ // Write mask AND
+ FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBACALFIR_MASK_WO_AND, l_mbacalfir_mask_and));
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBACALFIR_MASK, l_mbacalfir_mask));
+
+ //************************************************
+
+fapi_try_exit:
+ FAPI_INF("EXIT mss_unmask_draminit_training_errors()");
+ return fapi2::current_err;
+}
+
+///
+/// @brief Unmasks MBACALFIR errors that are valid for PRD to handle after mss_draminit_training_advanced
+/// @param[in] i_target MBA target
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note To be called at the end of mss_draminit_training_advanced.C.
+///
+fapi2::ReturnCode mss_unmask_draminit_training_advanced_errors(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target)
+{
+ FAPI_INF("ENTER mss_unmask_draminit_training_advanced_errors()");
+
+ //*************************
+ //*************************
+ // MBACALFIR
+ //*************************
+ //*************************
+
+ fapi2::buffer<uint64_t> l_mbacalfir_mask;
+ fapi2::buffer<uint64_t> l_mbacalfir_mask_and;
+ fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP> l_targetCentaur;
+ uint8_t l_mbaPosition = 0; // 0 = mba01, 1 = mba23
+
+ constexpr uint32_t l_mbsfir_mask_address[] =
+ {
+ // port0/1 port2/3
+ CEN_MCBISTS01_MBSFIRMASK, CEN_MCBISTS23_MBSFIRMASK
+ };
+
+ constexpr uint32_t l_mbsfir_mask_or_address[] =
+ {
+ // port0/1 port2/3
+ CEN_MCBISTS01_MBSFIRMASK_WO_OR, CEN_MCBISTS23_MBSFIRMASK_WO_OR
+ };
+
+ constexpr uint32_t l_mbsfir_mask_and_address[] =
+ {
+ // port0/1 port2/3
+ CEN_MCBISTS01_MBSFIRMASK_WO_AND, CEN_MCBISTS23_MBSFIRMASK_WO_AND
+ };
+
+ constexpr uint32_t l_mbsfir_action0_address[] =
+ {
+ // port0/1 port2/3
+ CEN_MCBISTS01_MBSFIRACT0, CEN_MCBISTS23_MBSFIRACT0
+ };
+
+ constexpr uint32_t l_mbsfir_action1_address[] =
+ {
+ // port0/1 port2/3
+ CEN_MCBISTS01_MBSFIRACT1, CEN_MCBISTS23_MBSFIRACT1
+ };
+
+ fapi2::buffer<uint64_t> l_mbsfir_mask;
+ fapi2::buffer<uint64_t> l_mbsfir_mask_or;
+ fapi2::buffer<uint64_t> l_mbsfir_mask_and;
+ fapi2::buffer<uint64_t> l_mbsfir_action0;
+ fapi2::buffer<uint64_t> l_mbsfir_action1;
+
+ // NOTE: In the IPL sequence, mss_unmask_draminit_errors has already been
+ // called, which has already set the MBACALFIR action regs to their runtime
+ // values, so no need to touch the action regs here.
+
+ // NOTE: In the IPL sequence, mss_unmask_draminit_errors and
+ // mss_unmask_draminit_training has already been
+ // called, which has already unmasked the approproiate MBACALFIR errors
+ // following mss_draminit and mss_draminit_training. So all we will do here
+ // is unmask a few more errors that would be considered valid after the
+ // mss_draminit_training_advanced procedure.
+
+ // Read mask
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBACALFIR_MASK, l_mbacalfir_mask));
+
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_mbacalfir_mask_and.flush<1>();
+
+ // 8 mbx to mba par error channel checkstop unmask
+ l_mbacalfir_mask_and.clearBit<8>();
+
+ // 11 mba_maint ue recoverable unmask
+ l_mbacalfir_mask_and.clearBit<11>();
+
+ // 12 mba_maint ce recoverable unmask
+ l_mbacalfir_mask_and.clearBit<12>();
+
+ // 17 wrq_rrq_hang_err recoverable unmask
+ l_mbacalfir_mask_and.clearBit<17>();
+
+
+ // Write mask AND
+ FAPI_TRY(fapi2::putScom(i_target, CEN_MBA_MBACALFIR_MASK_WO_AND, l_mbacalfir_mask_and));
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBA_MBACALFIR_MASK, l_mbacalfir_mask));
+
+ //************************************************
+
+ //*************************
+ //*************************
+ // MBSFIR
+ //*************************
+ //*************************
+
+ // Get Centaur target for the given MBA
+ l_targetCentaur = i_target.getParent<fapi2::TARGET_TYPE_MEMBUF_CHIP>();
+ // Get MBA position: 0 = mba01, 1 = mba23
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, i_target, l_mbaPosition), "Error getting MBA position");
+
+ // Read mask
+ FAPI_TRY(fapi2::getScom(l_targetCentaur,
+ l_mbsfir_mask_address[l_mbaPosition],
+ l_mbsfir_mask));
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_mbsfir_action0.flush<0>();
+ l_mbsfir_action1.flush<0>();
+ l_mbsfir_mask_or.flush<0>();
+ l_mbsfir_mask_and.flush<1>();
+
+ // 0 scom_par_errors channel checkstop unmask
+ l_mbsfir_action0.clearBit<0>();
+ l_mbsfir_action1.clearBit<0>();
+ l_mbsfir_mask_and.clearBit<0>();
+
+ // 1 mbx_par_errors channel checkstop unmask
+ l_mbsfir_action0.clearBit<1>();
+ l_mbsfir_action1.clearBit<1>();
+ l_mbsfir_mask_and.clearBit<1>();
+
+ // 2 DD1: reserved recoverable mask (forever)
+ // 2 DD2: dram_eventn_bit0 recoverable mask (forever)
+ l_mbsfir_action0.clearBit<2>();
+ l_mbsfir_action1.setBit<2>();
+ l_mbsfir_mask_or.setBit<2>();
+
+ // 3 DD1: reserved recoverable mask (forever)
+ // 3 DD2: dram_eventn_bit1 recoverable mask (forever)
+ l_mbsfir_action0.clearBit<3>();
+ l_mbsfir_action1.setBit<3>();
+ l_mbsfir_mask_or.setBit<3>();
+
+ // 4:14 RESERVED recoverable mask (forever)
+ l_mbsfir_action0.clearBit<4, 11>();
+ l_mbsfir_action1.setBit<4, 11>();
+ l_mbsfir_mask_or.setBit<4, 11>();
+
+ // 2:14 RESERVED recoverable mask (forever)
+ l_mbsfir_action0.clearBit<2, 13>();
+ l_mbsfir_action1.setBit<2, 13>();
+ l_mbsfir_mask_or.setBit<2, 13>();
+
+ // 15 internal scom error recoverable unmask
+ l_mbsfir_action0.clearBit<15>();
+ l_mbsfir_action1.setBit<15>();
+ l_mbsfir_mask_and.clearBit<15>();
+
+ // 16 internal scom error clone recoverable unmask
+ l_mbsfir_action0.clearBit<16>();
+ l_mbsfir_action1.setBit<16>();
+ l_mbsfir_mask_and.clearBit<16>();
+
+ // 17:63 RESERVED not implemented, so won't touch these
+
+ // Write action0
+ FAPI_TRY(fapi2::putScom(l_targetCentaur,
+ l_mbsfir_action0_address[l_mbaPosition],
+ l_mbsfir_action0));
+
+ // Write action1
+ FAPI_TRY(fapi2::putScom(l_targetCentaur,
+ l_mbsfir_action1_address[l_mbaPosition],
+ l_mbsfir_action1));
+
+ // Write mask OR
+ FAPI_TRY(fapi2::putScom(l_targetCentaur,
+ l_mbsfir_mask_or_address[l_mbaPosition],
+ l_mbsfir_mask_or));
+
+ // Write mask AND
+ FAPI_TRY(fapi2::putScom(l_targetCentaur,
+ l_mbsfir_mask_and_address[l_mbaPosition],
+ l_mbsfir_mask_and));
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ FAPI_TRY(fapi2::getScom(l_targetCentaur,
+ l_mbsfir_action0_address[l_mbaPosition],
+ l_mbsfir_action0));
+
+ FAPI_TRY(fapi2::getScom(l_targetCentaur,
+ l_mbsfir_action1_address[l_mbaPosition],
+ l_mbsfir_action1));
+
+ FAPI_TRY(fapi2::getScom(l_targetCentaur,
+ l_mbsfir_mask_address[l_mbaPosition],
+ l_mbsfir_mask));
+
+ //************************************************
+
+fapi_try_exit:
+ FAPI_INF("EXIT mss_unmask_draminit_training_advanced_errors()");
+ return fapi2::current_err;
+
+}
+
+///
+/// @brief Sets action regs and unmasks maint errors prior to the maint logic
+/// Being used in memdiags so that PRD will be able to handle them
+/// if they happen during memdiags.
+/// @param[in] i_target MBA target
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note To be called at the end of mss_draminit_mc.C.
+///
+fapi2::ReturnCode mss_unmask_maint_errors(const fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP>& i_target)
+{
+ FAPI_INF("ENTER mss_unmask_maint_errors()");
+
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_MBA>> l_mbaChiplets;
+ uint8_t l_mbaPosition = 0; // 0 = mba01, 1 = mba23
+
+ fapi2::buffer<uint64_t> l_mbacalfir_mask;
+ fapi2::buffer<uint64_t> l_mbacalfir_mask_and;
+
+ fapi2::buffer<uint64_t> l_mbafir_mask;
+ fapi2::buffer<uint64_t> l_mbafir_mask_and;
+
+ fapi2::buffer<uint64_t> l_mbaspa_mask;
+
+ constexpr uint32_t l_mbeccfir_mask_address[] =
+ {
+ // port0/1 port2/3
+ CEN_ECC01_MBECCFIR_MASK, CEN_ECC23_MBECCFIR_MASK
+ };
+
+ constexpr uint32_t l_mbeccfir_mask_or_address[] =
+ {
+ // port0/1 port2/3
+ CEN_ECC01_MBECCFIR_MASK_WO_OR, CEN_ECC23_MBECCFIR_MASK_WO_OR
+ };
+
+ constexpr uint32_t l_mbeccfir_mask_and_address[] =
+ {
+ // port0/1 port2/3
+ CEN_ECC01_MBECCFIR_MASK_WO_AND, CEN_ECC23_MBECCFIR_MASK_WO_AND
+ };
+
+ constexpr uint32_t l_mbeccfir_action0_address[] =
+ {
+ // port0/1 port2/3
+ CEN_ECC01_MBECCFIR_ACTION0_RO, CEN_ECC23_MBECCFIR_ACTION0_RO
+ };
+
+ constexpr uint32_t l_mbeccfir_action1_address[] =
+ {
+ // port0/1 port2/3
+ CEN_ECC01_MBECCFIR_ACTION1_RO, CEN_ECC23_MBECCFIR_ACTION1_RO
+ };
+
+ fapi2::buffer<uint64_t> l_mbeccfir_mask;
+ fapi2::buffer<uint64_t> l_mbeccfir_mask_or;
+ fapi2::buffer<uint64_t> l_mbeccfir_mask_and;
+ fapi2::buffer<uint64_t> l_mbeccfir_action0;
+ fapi2::buffer<uint64_t> l_mbeccfir_action1;
+
+ uint8_t l_mbspa_0_fixed_for_dd2 = 0;
+
+ // Get attribute that tells us if mbspa 0 cmd complete attention is fixed for dd2
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_CENTAUR_EC_FEATURE_HW217608_MBSPA_0_CMD_COMPLETE_ATTN_FIXED, i_target,
+ l_mbspa_0_fixed_for_dd2), "Error getting ATTR_CEN_CENTAUR_EC_FEATURE_HW217608_MBSPA_0_CMD_COMPLETE_ATTN_FIXED");
+
+ // Get associated functional MBAs on this centaur
+ l_mbaChiplets = i_target.getChildren<fapi2::TARGET_TYPE_MBA>();
+
+ // Loop through functional MBAs on this Centaur
+ for (uint32_t i = 0; i < l_mbaChiplets.size(); ++i)
+ {
+
+ // Get MBA position: 0 = mba01, 1 = mba23
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mbaChiplets[i], l_mbaPosition), "Error getting MBA position");
+
+ //*************************
+ //*************************
+ // MBACALFIR
+ //*************************
+ //*************************
+
+ // NOTE: In the IPL sequence, mss_unmask_draminit_errors has already been
+ // called, which has already set the MBACALFIR action regs to their runtime
+ // values, so no need to touch the action regs here.
+
+ // NOTE: In the IPL sequence, mss_unmask_draminit_errors,
+ // mss_unmask_draminit_training and mss_unmask_draminit_training_advanced
+ // have already been called, which have already unmasked the approproiate
+ // MBACALFIR errors following mss_draminit, mss_draminit_training, and
+ // mss_unmask_draminit_training_advanced. So all we will do here
+ // is unmask a few more errors that would be considered valid after the
+ // mss_draminit_mc procedure.
+
+ // Read mask
+ FAPI_TRY(fapi2::getScom(l_mbaChiplets[i],
+ CEN_MBA_MBACALFIR_MASK,
+ l_mbacalfir_mask));
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_mbacalfir_mask_and.flush<1>();
+
+ // 1 MBA Nonrecoverable Error channel checkstop unmask
+ l_mbacalfir_mask_and.clearBit<1>();
+
+ // 2 Refresh Overrun recoverable unmask
+ l_mbacalfir_mask_and.clearBit<2>();
+
+ // 5 ddr0_cal_timeout_err recoverable unmask
+ l_mbacalfir_mask_and.clearBit<5>();
+
+ // 6 ddr1_cal_timeout_err recoverable unmask
+ l_mbacalfir_mask_and.clearBit<6>();
+
+ // Write mask AND
+ FAPI_TRY(fapi2::putScom(l_mbaChiplets[i],
+ CEN_MBA_MBACALFIR_MASK_WO_AND,
+ l_mbacalfir_mask_and));
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ FAPI_TRY(fapi2::getScom(l_mbaChiplets[i],
+ CEN_MBA_MBACALFIR_MASK,
+ l_mbacalfir_mask));
+
+ //************************************************
+
+
+ //*************************
+ //*************************
+ // MBAFIR
+ //*************************
+ //*************************
+
+ // NOTE: In the IPL sequence, mss_unmask_ddr_phy_errors has already been
+ // called, which has already set the MBAFIR action regs to their runtime
+ // values, so no need to touch the action regs here.
+
+ // NOTE: In the IPL sequence, mss_unmask_ddr_phy_errors,
+ // has already been called, which has already unmasked the approproiate
+ // MBAFIR errors following mss_ddr_phy_reset. So all we will do here
+ // is unmask a few more errors that would be considered valid after the
+ // mss_draminit_mc procedure.
+
+ // Read mask
+ FAPI_TRY(fapi2::getScom(l_mbaChiplets[i],
+ CEN_MBA_MBAFIRMASK,
+ l_mbafir_mask));
+
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_mbafir_mask_and.flush<1>();
+
+ // 2 Multi_address_Maint_timeout recoverable unmask
+ l_mbafir_mask_and.clearBit<2>();
+
+
+ // 7 wrd_caw2_data_ce_ue_err channel checkstop unmask
+ l_mbafir_mask_and.clearBit<7>();
+
+ // Write mask AND
+ FAPI_TRY(fapi2::putScom(l_mbaChiplets[i],
+ CEN_MBA_MBAFIRMASK_WO_AND,
+ l_mbafir_mask_and));
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ FAPI_TRY(fapi2::getScom(l_mbaChiplets[i],
+ CEN_MBA_MBAFIRMASK,
+ l_mbafir_mask));
+
+ //************************************************
+
+
+ //*************************
+ //*************************
+ // MBSPA
+ //*************************
+ //*************************
+
+
+ // Read mask
+ FAPI_TRY(fapi2::getScom(l_mbaChiplets[i],
+ CEN_MBA_MBSPAMSKQ,
+ l_mbaspa_mask));
+
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_mbeccfir_action0.flush<0>();
+ l_mbeccfir_action1.flush<0>();
+ l_mbeccfir_mask_or.flush<0>();
+ l_mbeccfir_mask_and.flush<1>();
+
+ // 0:7 Memory MPE Rank 0:7 recoverable mask (until mainline traffic)
+ l_mbeccfir_action0.clearBit<0, 8>();
+ l_mbeccfir_action1.setBit<0, 8>();
+ l_mbeccfir_mask_or.setBit<0, 8>();
+
+ // 8:15 Reserved recoverable mask (forever)
+ l_mbeccfir_action0.clearBit<8, 8>();
+ l_mbeccfir_action1.setBit<8, 8>();
+ l_mbeccfir_mask_or.setBit<8, 8>();
+
+ // 16 Memory NCE recoverable mask (until mainline traffic)
+ l_mbeccfir_action0.clearBit<16>();
+ l_mbeccfir_action1.setBit<16>();
+ l_mbeccfir_mask_or.setBit<16>();
+
+ // 17 Memory RCE recoverable mask (until mainline traffic)
+ l_mbeccfir_action0.clearBit<17>();
+ l_mbeccfir_action1.setBit<17>();
+ l_mbeccfir_mask_or.setBit<17>();
+
+ // 18 Memory SUE recoverable mask (forever)
+ l_mbeccfir_action0.clearBit<18>();
+ l_mbeccfir_action1.setBit<18>();
+ l_mbeccfir_mask_or.setBit<18>();
+
+ // 19 Memory UE recoverable mask (until mainline traffic)
+ l_mbeccfir_action0.clearBit<19>();
+ l_mbeccfir_action1.setBit<19>();
+ l_mbeccfir_mask_or.setBit<19>();
+
+ // 20:27 Maint MPE Rank 0:7 recoverable mask (forever)
+ // NOTE: FW wants to mask these and rely instead on detecting the
+ // cmd complete attention, then checking these manually to see if
+ // they cause the cmd to stop
+ l_mbeccfir_action0.clearBit<20, 8>();
+ l_mbeccfir_action1.setBit<20, 8>();
+ l_mbeccfir_mask_or.setBit<20, 8>();
+
+ // 28:35 Reserved recoverable mask (forever)
+ l_mbeccfir_action0.clearBit<28, 8>();
+ l_mbeccfir_action1.setBit<28, 8>();
+ l_mbeccfir_mask_or.setBit<28, 8>();
+
+ // 36 Maintenance NCE recoverable mask (forever)
+ // NOTE: PRD planning to use maint CE thresholds instead.
+ l_mbeccfir_action0.clearBit<36>();
+ l_mbeccfir_action1.setBit<36>();
+ l_mbeccfir_mask_or.setBit<36>();
+
+ // 37 Maintenance SCE recoverable mask (forever)
+ // NOTE: Don't care if symbol still bad after it's symbol marked.
+ l_mbeccfir_action0.clearBit<37>();
+ l_mbeccfir_action1.setBit<37>();
+ l_mbeccfir_mask_or.setBit<37>();
+
+ // 38 Maintenance MCE recoverable mask (forever)
+ // NOTE: PRD plans to check manually as part of verify chip mark procedure.
+ l_mbeccfir_action0.clearBit<38>();
+ l_mbeccfir_action1.setBit<38>();
+ l_mbeccfir_mask_or.setBit<38>();
+
+ // 39 Maintenance RCE recoverable mask (forever)
+ // NOTE: PRD planning to use maint RCE thresholds instead.
+ l_mbeccfir_action0.clearBit<39>();
+ l_mbeccfir_action1.setBit<39>();
+ l_mbeccfir_mask_or.setBit<39>();
+
+ // 40 Maintenance SUE recoverable mask (forever)
+ l_mbeccfir_action0.clearBit<40>();
+ l_mbeccfir_action1.setBit<40>();
+ l_mbeccfir_mask_or.setBit<40>();
+
+ // 41 Maintenance UE recoverable mask (forever)
+ // NOTE: FW wants to mask these and rely instead on detecting the
+ // cmd complete attention, then checking these manually to see if
+ // they cause the cmd to stop
+ l_mbeccfir_action0.clearBit<41>();
+ l_mbeccfir_action1.setBit<41>();
+ l_mbeccfir_mask_or.setBit<41>();
+
+ // 42 MPE during maintenance mark mode recoverable mask (forever)
+ l_mbeccfir_action0.clearBit<42>();
+ l_mbeccfir_action1.setBit<42>();
+ l_mbeccfir_mask_or.setBit<42>();
+
+ // 43 Prefetch Memory UE recoverable mask (until mainline traffic)
+ l_mbeccfir_action0.clearBit<43>();
+ l_mbeccfir_action1.setBit<43>();
+ l_mbeccfir_mask_or.setBit<43>();
+
+ // 44 Memory RCD parity error recoverable mask (forever)
+ l_mbeccfir_action0.clearBit<44>();
+ l_mbeccfir_action1.setBit<44>();
+ l_mbeccfir_mask_or.setBit<44>();
+
+ // 45 Maint RCD parity error. recoverable mask (forever)
+ l_mbeccfir_action0.clearBit<45>();
+ l_mbeccfir_action1.setBit<45>();
+ l_mbeccfir_mask_or.setBit<45>();
+
+ // 46 Recoverable reg parity recoverable unmask
+ l_mbeccfir_action0.clearBit<46>();
+ l_mbeccfir_action1.setBit<46>();
+ l_mbeccfir_mask_and.clearBit<46>();
+
+
+ // 47 Unrecoverable reg parity channel checkstop unmask
+ l_mbeccfir_action0.clearBit<47>();
+ l_mbeccfir_action1.clearBit<47>();
+ l_mbeccfir_mask_and.clearBit<47>();
+
+ // 48 Maskable reg parity error recoverable unmask
+ l_mbeccfir_action0.clearBit<48>();
+ l_mbeccfir_action1.setBit<48>();
+ l_mbeccfir_mask_and.clearBit<48>();
+
+ // 49 ecc datapath parity error channel checkstop unmask
+ l_mbeccfir_action0.clearBit<49>();
+ l_mbeccfir_action1.clearBit<49>();
+ l_mbeccfir_mask_and.clearBit<49>();
+
+ // 50 internal scom error recovereble unmask
+ l_mbeccfir_action0.clearBit<50>();
+ l_mbeccfir_action1.setBit<50>();
+ l_mbeccfir_mask_and.clearBit<50>();
+
+ // 51 internal scom error clone recovereble unmask
+ l_mbeccfir_action0.clearBit<51>();
+ l_mbeccfir_action1.setBit<51>();
+ l_mbeccfir_mask_and.clearBit<51>();
+
+ // 52:63 Reserved not implemented, so won't touch these
+
+ // Write action0
+ FAPI_TRY(fapi2::putScom(i_target,
+ l_mbeccfir_action0_address[l_mbaPosition],
+ l_mbeccfir_action0));
+
+ // Write action1
+ FAPI_TRY(fapi2::putScom(i_target,
+ l_mbeccfir_action1_address[l_mbaPosition],
+ l_mbeccfir_action1));
+
+
+ // Write mask OR
+ FAPI_TRY(fapi2::putScom(i_target,
+ l_mbeccfir_mask_or_address[l_mbaPosition],
+ l_mbeccfir_mask_or));
+
+ // Write mask AND
+ FAPI_TRY(fapi2::putScom(i_target,
+ l_mbeccfir_mask_and_address[l_mbaPosition],
+ l_mbeccfir_mask_and));
+
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ FAPI_TRY(fapi2::getScom(i_target,
+ l_mbeccfir_action0_address[l_mbaPosition],
+ l_mbeccfir_action0));
+
+ FAPI_TRY(fapi2::getScom(i_target,
+ l_mbeccfir_action1_address[l_mbaPosition],
+ l_mbeccfir_action1));
+
+ FAPI_TRY(fapi2::getScom(i_target,
+ l_mbeccfir_mask_address[l_mbaPosition],
+ l_mbeccfir_mask));
+
+ //************************************************
+
+ } // End for loop through functional MBAs on this Centaur
+
+ FAPI_INF("EXIT mss_unmask_maint_errors()");
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Sets action regs and unmasks fetch errors prior to the start of mainline traffic.
+/// @param[in] i_target Centaur target
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note To be called at the end of mss_draminit_mc.C.
+///
+fapi2::ReturnCode mss_unmask_fetch_errors(const fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP>& i_target)
+{
+ FAPI_INF("ENTER mss_unmask_fetch_errors()");
+
+ uint8_t l_dimm_type = 0;
+ uint8_t l_cfg_wrdone_dly = 0;
+ uint8_t l_cfg_rdtag_dly = 0;
+ uint8_t l_max_cfg_rcd_protection_time = 0;
+
+ fapi2::buffer<uint64_t> l_mba_dsm0;
+ fapi2::buffer<uint64_t> l_mba_farb0;
+
+
+ //*************************
+ //*************************
+ // SCAC_LFIR
+ //*************************
+ //*************************
+
+ fapi2::buffer<uint64_t> l_scac_lfir_mask;
+ fapi2::buffer<uint64_t> l_scac_lfir_mask_or;
+ fapi2::buffer<uint64_t> l_scac_lfir_mask_and;
+ fapi2::buffer<uint64_t> l_scac_lfir_action0;
+ fapi2::buffer<uint64_t> l_scac_lfir_action1;
+ fapi2::buffer<uint64_t> l_mbs_fir_mask;
+ fapi2::buffer<uint64_t> l_mbs_fir_mask_and;
+ uint8_t l_dd2_fir_bit_defn_changes = 0;
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_L4>> l_L4_vector;
+ bool l_L4_functional = false;
+ uint8_t l_mbaPosition = 0; // 0 = mba01, 1 = mba23
+ uint32_t l_mbeccfir_mask_address[] =
+ {
+ // port0/1 port2/3
+ CEN_ECC01_MBECCFIR_MASK, CEN_ECC23_MBECCFIR_MASK
+ };
+
+ uint32_t l_mbeccfir_mask_and_address[] =
+ {
+ // port0/1 port2/3
+ CEN_ECC01_MBECCFIR_MASK_WO_AND, CEN_ECC23_MBECCFIR_MASK_WO_AND
+ };
+
+ fapi2::buffer<uint64_t> l_mbeccfir_mask;
+ fapi2::buffer<uint64_t> l_mbeccfir_mask_and;
+ fapi2::buffer<uint64_t> l_mbacalfir_mask;
+ fapi2::buffer<uint64_t> l_mbacalfir_mask_and;
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_MBA>> l_mbaChiplets;
+
+ // Read mask
+ FAPI_TRY(fapi2::getScom(i_target, CEN_SCAC_FIRMASK, l_scac_lfir_mask));
+
+
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_scac_lfir_action0.flush<0>();
+ l_scac_lfir_action1.flush<0>();
+ l_scac_lfir_mask_or.flush<0>();
+ l_scac_lfir_mask_and.flush<1>();
+
+ // 0 I2CMInvAddr recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<0>();
+ l_scac_lfir_action1.setBit<0>();
+ l_scac_lfir_mask_or.setBit<0>();
+
+ // 1 I2CMInvWrite recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<1>();
+ l_scac_lfir_action1.setBit<1>();
+ l_scac_lfir_mask_or.setBit<1>();
+
+ // 2 I2CMInvRead recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<2>();
+ l_scac_lfir_action1.setBit<2>();
+ l_scac_lfir_mask_or.setBit<2>();
+
+ // 3 I2CMApar recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<3>();
+ l_scac_lfir_action1.setBit<3>();
+ l_scac_lfir_mask_or.setBit<3>();
+
+ // 4 I2CMPar recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<4>();
+ l_scac_lfir_action1.setBit<4>();
+ l_scac_lfir_mask_or.setBit<4>();
+
+ // 5 I2CMLBPar recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<5>();
+ l_scac_lfir_action1.setBit<5>();
+ l_scac_lfir_mask_or.setBit<5>();
+
+ // 6:9 Expansion recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<6, 4>();
+ l_scac_lfir_action1.setBit<6, 4>();
+ l_scac_lfir_mask_or.setBit<6, 4>();
+
+ // 10 I2CMInvCmd recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<10>();
+ l_scac_lfir_action1.setBit<10>();
+ l_scac_lfir_mask_or.setBit<10>();
+
+ // 11 I2CMPErr recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<11>();
+ l_scac_lfir_action1.setBit<11>();
+ l_scac_lfir_mask_or.setBit<11>();
+
+ // 12 I2CMOverrun recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<12>();
+ l_scac_lfir_action1.setBit<12>();
+ l_scac_lfir_mask_or.setBit<12>();
+
+ // 13 I2CMAccess recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<13>();
+ l_scac_lfir_action1.setBit<13>();
+ l_scac_lfir_mask_or.setBit<13>();
+
+ // 14 I2CMArb recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<14>();
+ l_scac_lfir_action1.setBit<14>();
+ l_scac_lfir_mask_or.setBit<14>();
+
+ // 15 I2CMNack recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<15>();
+ l_scac_lfir_action1.setBit<15>();
+ l_scac_lfir_mask_or.setBit<15>();
+
+ // 16 I2CMStop recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<16>();
+ l_scac_lfir_action1.setBit<16>();
+ l_scac_lfir_mask_or.setBit<16>();
+
+ // 17 LocalPib1 recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<17>();
+ l_scac_lfir_action1.setBit<17>();
+ l_scac_lfir_mask_or.setBit<17>();
+
+ // 18 LocalPib2 recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<18>();
+ l_scac_lfir_action1.setBit<18>();
+ l_scac_lfir_mask_or.setBit<18>();
+
+ // 19 LocalPib3 recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<19>();
+ l_scac_lfir_action1.setBit<19>();
+ l_scac_lfir_mask_or.setBit<19>();
+
+ // 20 LocalPib4 recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<20>();
+ l_scac_lfir_action1.setBit<20>();
+ l_scac_lfir_mask_or.setBit<20>();
+
+ // 21 LocalPib5 recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<21>();
+ l_scac_lfir_action1.setBit<21>();
+ l_scac_lfir_mask_or.setBit<21>();
+
+ // 22 LocalPib6 recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<22>();
+ l_scac_lfir_action1.setBit<22>();
+ l_scac_lfir_mask_or.setBit<22>();
+
+ // 23 LocalPib7 recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<23>();
+ l_scac_lfir_action1.setBit<23>();
+ l_scac_lfir_mask_or.setBit<23>();
+
+ // 24 StallError recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<24>();
+ l_scac_lfir_action1.setBit<24>();
+ l_scac_lfir_mask_or.setBit<24>();
+
+ // 25 RegParErr channel checkstop unmask
+ l_scac_lfir_action0.clearBit<25>();
+ l_scac_lfir_action1.clearBit<25>();
+ l_scac_lfir_mask_and.clearBit<25>();
+
+ // 26 RegParErrX channel checkstop unmask
+ l_scac_lfir_action0.clearBit<26>();
+ l_scac_lfir_action1.clearBit<26>();
+ l_scac_lfir_mask_and.clearBit<26>();
+
+ // 27:31 Reserved recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<27, 5>();
+ l_scac_lfir_action1.setBit<27, 5>();
+ l_scac_lfir_mask_or.setBit<27, 5>();
+
+ // 32 SMErr recoverable unmask
+ l_scac_lfir_action0.clearBit<32>();
+ l_scac_lfir_action1.setBit<32>();
+ l_scac_lfir_mask_and.clearBit<32>();
+
+ // 33 RegAccErr recoverable unmask
+ l_scac_lfir_action0.clearBit<33>();
+ l_scac_lfir_action1.setBit<33>();
+ l_scac_lfir_mask_and.clearBit<33>();
+
+ // 34 ResetErr recoverable masked (forever)
+ l_scac_lfir_action0.clearBit<34>();
+ l_scac_lfir_action1.setBit<34>();
+ l_scac_lfir_mask_or.setBit<34>();
+
+ // 35 internal_scom_error recoverable unmask
+ l_scac_lfir_action0.clearBit<35>();
+ l_scac_lfir_action1.setBit<35>();
+ l_scac_lfir_mask_and.clearBit<35>();
+
+ // 36 internal_scom_error_clone recoverable unmask
+ l_scac_lfir_action0.clearBit<36>();
+ l_scac_lfir_action1.setBit<36>();
+ l_scac_lfir_mask_and.clearBit<36>();
+
+ // 37:63 Reserved
+ // Can we write to these bits?
+
+ // Write action0
+ FAPI_TRY(fapi2::putScom(i_target, CEN_SCAC_FIRACTION0_RO, l_scac_lfir_action0));
+
+ // Write action1
+ FAPI_TRY(fapi2::putScom(i_target, CEN_SCAC_FIRACTION1_RO, l_scac_lfir_action1));
+
+ // Write mask OR
+ FAPI_TRY(fapi2::putScom(i_target, CEN_SCAC_FIRMASK_WO_OR, l_scac_lfir_mask_or));
+
+ // Write mask AND
+ FAPI_TRY(fapi2::putScom(i_target, CEN_SCAC_FIRMASK_WO_AND, l_scac_lfir_mask_and));
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ FAPI_TRY(fapi2::getScom(i_target, CEN_SCAC_FIRACTION0_RO, l_scac_lfir_action0));
+ FAPI_TRY(fapi2::getScom(i_target, CEN_SCAC_FIRACTION1_RO, l_scac_lfir_action1));
+ FAPI_TRY(fapi2::getScom(i_target, CEN_SCAC_FIRMASK, l_scac_lfir_mask));
+
+ //************************************************
+
+ //*************************
+ //*************************
+ // MBS_FIR_REG
+ //*************************
+ //*************************
+
+ // NOTE: In the IPL sequence, mss_unmask_inband_errors has already been
+ // called, which has already set the MBS_FIR_REG action regs to their
+ // runtime values, so no need to touch the action regs here.
+
+ // NOTE: In the IPL sequence, mss_unmask_inband_errors,
+ // has already been called, which has already unmasked the approproiate
+ // MBS_FIR_REG errors following mss_unmask_inband_errors. So all we will do
+ // here is unmask errors requiring mainline traffic which would be
+ // considered valid after the mss_thermal_init procedure.
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_CENTAUR_EC_FEATURE_DD2_FIR_BIT_DEFN_CHANGES, i_target,
+ l_dd2_fir_bit_defn_changes),
+ "Error getting ATTR_CEN_CENTAUR_EC_FEATURE_DD2_FIR_BIT_DEFN_CHANGES");
+
+ // Check if L4 is functional
+ l_L4_vector = i_target.getChildren<fapi2::TARGET_TYPE_L4>();
+
+ if (l_L4_vector.size() > 0)
+ {
+ l_L4_functional = true;
+ }
+
+ // Read mask
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBS_FIR_MASK_REG, l_mbs_fir_mask));
+
+
+ l_mbs_fir_mask_and.flush<1>();
+
+ // 2 invalid_address_error channel checkstop unmask
+ l_mbs_fir_mask_and.clearBit<2>();
+
+ // 3 external_timeout recoverable unmask
+ l_mbs_fir_mask_and.clearBit<3>();
+
+ // 4 internal_timeout recoverable unmask
+ l_mbs_fir_mask_and.clearBit<4>();
+
+
+ if (l_L4_functional)
+ {
+ // 9 cache_srw_ce recoverable unmask
+ l_mbs_fir_mask_and.clearBit<9>();
+
+ // 10 cache_srw_ue recoverable unmask
+ l_mbs_fir_mask_and.clearBit<10>();
+
+ // 12 cache_co_ce recoverable unmask
+ l_mbs_fir_mask_and.clearBit<12>();
+
+ // 13 cache_co_ue recoverable unmask
+ l_mbs_fir_mask_and.clearBit<13>();
+
+ // 15 dir_ce
+ if (l_dd2_fir_bit_defn_changes)
+ {
+ // NOTE: SW248520: Known DD1 problem - higher temp causes
+ // L4 Dir CEs. Want to ignore. Unmask for DD2 only
+
+ // recoverable unmask
+ l_mbs_fir_mask_and.clearBit<15>();
+ }
+
+ // 16 dir_ue channel checkstop unmask
+ l_mbs_fir_mask_and.clearBit<16>();
+
+ // 18 dir_all_members_deleted channel checkstop unmask
+ l_mbs_fir_mask_and.clearBit<18>();
+
+ // 19 lru_error recoverable unmask
+ l_mbs_fir_mask_and.clearBit<19>();
+
+ // 20 eDRAM error channel checkstop unmask
+ l_mbs_fir_mask_and.clearBit<20>();
+ }
+
+ // 26 srb_buffer_ce recoverable unmask
+ l_mbs_fir_mask_and.clearBit<26>();
+
+ // 27 srb_buffer_ue recoverable unmask
+ l_mbs_fir_mask_and.clearBit<27>();
+
+ if (l_dd2_fir_bit_defn_changes && l_L4_functional)
+ {
+ // 30 proximal_ce_ue channel checkstop unmask
+ l_mbs_fir_mask_and.clearBit<30>();
+ }
+
+
+ // Write mask AND
+ FAPI_TRY(fapi2::putScom(i_target, CEN_MBS_FIR_MASK_REG_WO_AND, l_mbs_fir_mask_and));
+
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ FAPI_TRY(fapi2::getScom(i_target, CEN_MBS_FIR_MASK_REG, l_mbs_fir_mask));
+
+ //************************************************
+
+
+ // Get associated functional MBAs on this centaur
+ l_mbaChiplets = i_target.getChildren<fapi2::TARGET_TYPE_MBA>();
+
+ // Loop through functional MBAs on this Centaur
+ for (uint32_t i = 0; i < l_mbaChiplets.size(); ++i)
+ {
+
+ // Get MBA position: 0 = mba01, 1 = mba23
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mbaChiplets[i], l_mbaPosition),
+ "Error getting MBA position");
+
+ // Get DIMM type
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DIMM_TYPE, l_mbaChiplets[i], l_dimm_type),
+ "Error getting ATTR_CEN_EFF_DIMM_TYPE");
+
+ // If RDIMM or LRDIMM, load max_cfg_rcd_protection_time and enable RCD recovery
+ if ((l_dimm_type == fapi2::ENUM_ATTR_CEN_EFF_DIMM_TYPE_RDIMM)
+ || (l_dimm_type == fapi2::ENUM_ATTR_CEN_EFF_DIMM_TYPE_LRDIMM))
+ {
+
+ FAPI_TRY(fapi2::getScom(l_mbaChiplets[i], CEN_MBA_MBA_DSM0Q, l_mba_dsm0));
+
+ // Get 24:29 cfg_wrdone_dly
+ l_mba_dsm0.extract < 24, 6, 8 - 6 > (l_cfg_wrdone_dly);
+
+ // Get 36:41 cfg_rdtag_dly
+ l_mba_dsm0.extract < 36, 6, 8 - 6 > (l_cfg_rdtag_dly);
+
+ // Pick lower of the two: cfg_wrdone_dly and cfg_rdtag_dly, and use that for l_max_cfg_rcd_protection_time
+ if (l_cfg_wrdone_dly <= l_cfg_rdtag_dly)
+ {
+ l_max_cfg_rcd_protection_time = l_cfg_wrdone_dly;
+ }
+ else
+ {
+ l_max_cfg_rcd_protection_time = l_cfg_rdtag_dly;
+ }
+
+ // Read FARB0
+ FAPI_TRY(fapi2::getScom(l_mbaChiplets[i], CEN_MBA_MBA_FARB0Q, l_mba_farb0));
+
+ // Load l_max_cfg_rcd_protection_time
+ FAPI_TRY(l_mba_farb0.insert( l_max_cfg_rcd_protection_time, 48, 6, 8 - 6 ));
+
+ // Clear bit 54, cfg_disable_rcd_recovery, to enable RCD recovery
+ l_mba_farb0.clearBit<54>();
+
+ // Write FARB0
+ FAPI_TRY(fapi2::putScom(l_mbaChiplets[i], CEN_MBA_MBA_FARB0Q, l_mba_farb0));
+ }
+
+
+ //*************************
+ //*************************
+ // MBASPA
+ //*************************
+ //*************************
+ // NOTE: FW wants to mask these and rely instead on detecting the
+ // cmd complete attention, then checking these manually to see if
+ // they cause the cmd to stop
+
+ //*************************
+ //*************************
+ // MBECCFIR
+ //*************************
+ //*************************
+
+ // Read mask
+ FAPI_TRY(fapi2::getScom(i_target,
+ l_mbeccfir_mask_address[l_mbaPosition],
+ l_mbeccfir_mask));
+
+ // NOTE: In the IPL sequence, mss_unmask_maint_errors has already been
+ // called, which has already set the MBECCFIR action regs to their runtime
+ // values, so no need to touch the action regs here.
+
+ // NOTE: In the IPL sequence, mss_unmask_maint_errors,
+ // has already been called, which has already unmasked the approproiate
+ // MBECCFIR errors following mss_unmask_maint_errors. So all we will do
+ // here is unmask errors requiring mainline traffic which would be
+ // considered valid after the mss_thermal_init procedure.
+
+ l_mbeccfir_mask_and.flush<1>();
+
+ // 0:7 Memory MPE Rank 0:7 recoverable unmask
+ l_mbeccfir_mask_and.clearBit<0, 8>();
+
+ // 16 Memory NCE recoverable unmask
+ l_mbeccfir_mask_and.clearBit<16>();
+
+ // 17 Memory RCE recoverable unmask
+ l_mbeccfir_mask_and.clearBit<17>();
+
+ // 19 Memory UE recoverable unmask
+ l_mbeccfir_mask_and.clearBit<19>();
+
+#if 0 // Should this be removed - AAM ?
+ // NOTE: FW wants to mask these and rely instead on detecting the
+ // cmd complete attention, then checking these manually to see if
+ // they cause the cmd to stop
+
+ // 20:27 Maint MPE Rank 0:7 recoverable unmask
+ l_mbeccfir_mask_and.clearBit<20, 8>();
+
+ // 41 Maintenance UE recoverable unmask
+ l_mbeccfir_mask_and.clearBit<41>();
+#endif
+
+ // 43 Prefetch Memory UE recoverable unmask
+ l_mbeccfir_mask_and.clearBit<43>();
+
+ // Write mask AND
+ FAPI_TRY(fapi2::putScom(i_target,
+ l_mbeccfir_mask_and_address[l_mbaPosition],
+ l_mbeccfir_mask_and));
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ FAPI_TRY(fapi2::getScom(i_target,
+ l_mbeccfir_mask_address[l_mbaPosition],
+ l_mbeccfir_mask));
+
+ //************************************************
+ }
+
+ //*************************
+ //*************************
+ // MBACALFIR
+ //*************************
+ //*************************
+
+
+ // NOTE: In the IPL sequence, mss_unmask_draminit_errors has already been
+ // called, which has already set the MBACALFIR action regs to their runtime
+ // values, so no need to touch the action regs here.
+
+ // NOTE: In the IPL sequence, various bits have already been unmasked
+ // after the approproiate procedures. So all we will do here is unmask
+ // errors requiring mainline traffic which would be considered valid after
+ // the mss_thermal_init procedure.
+
+ // Loop through functional MBAs on this Centaur
+ for (uint32_t i = 0; i < l_mbaChiplets.size(); ++i)
+ {
+
+ // Read mask
+ FAPI_TRY(fapi2::getScom(l_mbaChiplets[i],
+ CEN_MBA_MBACALFIR_MASK,
+ l_mbacalfir_mask));
+
+
+ l_mbacalfir_mask_and.flush<1>();
+
+ // 9 mba_wrd ue recoverable unmask
+ l_mbacalfir_mask_and.clearBit<9>();
+
+ // 10 mba_wrd ce recoverable unmask
+ l_mbacalfir_mask_and.clearBit<10>();
+
+ // 14 wrq_data_ce recoverable unmask
+ l_mbacalfir_mask_and.clearBit<14>();
+
+ // 15 wrq_data_ue recoverable unmask
+ l_mbacalfir_mask_and.clearBit<15>();
+
+ // Write mask AND
+ FAPI_TRY(fapi2::putScom(l_mbaChiplets[i],
+ CEN_MBA_MBACALFIR_MASK_WO_AND,
+ l_mbacalfir_mask_and));
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ FAPI_TRY(fapi2::getScom(l_mbaChiplets[i],
+ CEN_MBA_MBACALFIR_MASK,
+ l_mbacalfir_mask));
+
+ //************************************************
+ }
+
+fapi_try_exit:
+ FAPI_INF("EXIT mss_unmask_fetch_errors()");
+ return fapi2::current_err;
+}
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.H b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.H
new file mode 100755
index 000000000..002c86d1f
--- /dev/null
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.H
@@ -0,0 +1,161 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9c_mss_unmask_errors.H
+/// @brief Utility functions to set action regs and unmask FIR bits at the end of various mss IPL procedures.
+/// *HWP HWP Owner: Luke Mulkey <lwmulkey@us.ibm.com>
+/// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
+/// *HWP Team: Memory
+/// *HWP Level: 2
+/// *HWP Consumed by: Memtools
+//
+//
+
+
+#ifndef _MSS_UNMASK_ERRORS_H
+#define _MSS_UNMASK_ERRORS_H
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi2.H>
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_pervasive_errors
+//------------------------------------------------------------------------------
+
+///
+/// @brief Sets action regs and mask settings for pervasive errors to their runtime settings.
+/// @param[in] i_target Centaur target
+/// @return FAPI2_RC_SUCCESS iff okay
+////
+fapi2::ReturnCode mss_unmask_pervasive_errors( const fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP>& i_target);
+
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_inband_errors
+//------------------------------------------------------------------------------
+
+
+///
+/// @brief Sets action regs and mask settings for inband errors to their runtime settings.
+/// @param[in] i_target Centaur target
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note To be called at the end of cen_mem_startclocks.C
+///
+fapi2::ReturnCode mss_unmask_inband_errors( const fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP>& i_target);
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_ddrphy_errors
+//------------------------------------------------------------------------------
+
+
+///
+/// @brief Sets action regs and mask settings for ddr phy errors to runtime settings.
+/// @param[in] i_target MBA target
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note To be called at the end of proc_cen_framelock.C
+///
+fapi2::ReturnCode mss_unmask_ddrphy_errors( const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target);
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_draminit_errors
+//------------------------------------------------------------------------------
+
+
+///
+/// @brief Sets MBACALFIR action regs to their runtime settings.
+/// Unmasks errors that are valid for PRD to handle after mss_draminit procedure.
+/// @param[in] i_target MBA target
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note To be called at the end of mss_draminit.C.
+///
+fapi2::ReturnCode mss_unmask_draminit_errors( const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target);
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_draminit_training_errors
+//------------------------------------------------------------------------------
+
+
+///
+/// @brief Unmasks MBACALFIR errors that are valid for PRD to handle after mss_draminit_training
+/// @param[in] i_target MBA target
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note To be called at the end of mss_draminit_training.C.
+fapi2::ReturnCode mss_unmask_draminit_training_errors(
+ const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target);
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_draminit_training_advanced_errors
+//------------------------------------------------------------------------------
+
+
+///
+/// @brief Unmasks MBACALFIR errors that are valid for PRD to handle after mss_draminit_training_advanced
+/// @param[in] i_target MBA target
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note To be called at the end of mss_draminit_training_advanced.C.
+///
+fapi2::ReturnCode mss_unmask_draminit_training_advanced_errors(
+ const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target);
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_maint_errors
+//------------------------------------------------------------------------------
+
+
+///
+/// @brief Sets action regs and unmasks maint errors prior to the maint logic
+/// Being used in memdiags so that PRD will be able to handle them
+/// if they happen during memdiags.
+/// @param[in] i_target MBA target
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note To be called at the end of mss_draminit_mc.C.
+///
+fapi2::ReturnCode mss_unmask_maint_errors(const fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP>& i_target);
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_fetch_errors
+//------------------------------------------------------------------------------
+
+
+///
+/// @brief Sets action regs and unmasks fetch errors prior to the start of mainline traffic.
+/// @param[in] i_target Centaur target
+/// @return FAPI2_RC_SUCCESS iff okay
+/// @note To be called at the end of mss_draminit_mc.C.
+///
+fapi2::ReturnCode mss_unmask_fetch_errors(const fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP>& i_target);
+
+
+#endif //// _MSS_UNMASK_ERRORS_H ////
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.mk b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.mk
new file mode 100755
index 000000000..79bc9e413
--- /dev/null
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.mk
@@ -0,0 +1,32 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/import/chips/centaur/procedures/hwp/memory/p9c_mss_unmask_errors.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2016,2017
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+# Include the macros and things for MSS procedures
+-include 01common.mk
+
+PROCEDURE=p9c_mss_unmask_errors
+$(eval $(call ADD_MEMORY_INCDIRS,$(PROCEDURE)))
+#lib$(PROCEDURE)_DEPLIBS+=mss
+$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/centaur/procedures/hwp/memory/wrapper/p9c_mss_ddr_phy_reset_wrap.C b/src/import/chips/centaur/procedures/hwp/memory/wrapper/p9c_mss_ddr_phy_reset_wrap.C
new file mode 100644
index 000000000..686d6137e
--- /dev/null
+++ b/src/import/chips/centaur/procedures/hwp/memory/wrapper/p9c_mss_ddr_phy_reset_wrap.C
@@ -0,0 +1,287 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/centaur/procedures/hwp/memory/wrapper/p9c_mss_ddr_phy_reset_wrap.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file p9c_mss_ddr_phy_reset_wrap.C
+/// @brief FW Team Utility functions that accesses the Bad DQ Bitmap.
+///
+/// *HWP HWP Owner: Luke Mulkey <lwmulkey@us.ibm.com>
+/// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
+/// *HWP Team: Memory
+/// *HWP Level: 2
+/// *HWP Consumed by: HB
+////
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <prcdUtils.H>
+
+#include <croClientCapi.H>
+#include <ecmdClientCapi.H>
+#include <ecmdDataBuffer.H>
+#include <ecmdUtils.H>
+#include <ecmdSharedUtils.H>
+#include <fapi2.H>
+#include <fapi2ClientCapi.H>
+#include <fapi2SharedUtils.H>
+
+#include <p9c_mss_ddr_phy_reset.H>
+
+
+//------------------------------------------------------------------------------
+// Function definitions
+//------------------------------------------------------------------------------
+
+// display help message
+void help()
+{
+ // procedure constants
+ std::string PROCEDURE = "p9c_mss_ddr_phy_reset_wrap";
+ std::string REVISION = "$Revision: 1.8 $";
+
+ // build help message
+ char outstr[256];
+ snprintf(outstr, sizeof(outstr), "\nThis is the help text for the procedure %s (%s).\n",
+ PROCEDURE.c_str(), REVISION.c_str());
+ ecmdOutput(outstr);
+ ecmdOutput(" [-h] [-k#] [-n#] [-s#] [-p#] [-d] [-quiet] [-verif]\n");
+ ecmdOutput("\n");
+ ecmdOutput("Additional options:\n");
+ ecmdOutput(" -h Display this help message.\n");
+
+ ecmdOutput(" -k# Specify which cage to act on (default = 0).\n");
+ ecmdOutput(" -n# Specify which node to act on (default = 0).\n");
+ ecmdOutput(" -s# Specify which slot to act on (default = 0).\n");
+ ecmdOutput(" -p# Specify which chip position to act on (default = 0).\n");
+ ecmdOutput(" -quiet Suppress printing of eCMD DLL/procedure information (default = false).\n");
+ ecmdOutput(" -verif Run procedure in sim verification mode (default = false).\n");
+ return;
+}
+
+// main function
+int
+main(int argc, char* argv[])
+{
+ // procedure constants
+ const std::string PROCEDURE = "mss_ddr_phy_reset_wrap";
+ const std::string REVISION = "$Revision: 1.8 $";
+
+ // from prcdUtils
+ extern bool GLOBAL_SIM_MODE;
+ extern bool GLOBAL_VERIF_MODE;
+
+ // flow/control variables
+ uint32_t rc = ECMD_SUCCESS;
+ fapi2::ReturnCode rc_fapi;
+ ecmdDllInfo DLLINFO;
+ ecmdLooperData node_looper;
+ ecmdChipTarget node_target;
+ char outstr[256];
+
+ // required parameters & optional flags
+
+ // load and initialize the eCMD Dll
+ // if left NULL, which DLL to load is determined by the ECMD_DLL_FILE
+ // environment variable if set to a specific value, the specified DLL
+ // will be loaded
+ rc = ecmdLoadDll("");
+
+ if (rc)
+ {
+ return rc;
+ }
+
+ do
+ {
+ // initalize FAPI extension
+ rc = fapi2InitExtension();
+
+ if (rc)
+ {
+ ecmdOutputError("Error initializing FAPI extension!\n");
+ break;
+ }
+
+ // establish if this is a simulation run or not
+ rc = ecmdQueryDllInfo(DLLINFO);
+
+ if (rc)
+ {
+ ecmdOutput("Error querying DLL!\n");
+ break;
+ }
+
+ if (DLLINFO.dllEnv == ECMD_DLL_ENV_SIM)
+ {
+ GLOBAL_SIM_MODE = true;
+ }
+
+ // show help message
+ if (ecmdParseOption(&argc, &argv, "-h"))
+ {
+ help();
+ break;
+ }
+
+
+ // run procedure in sim verification mode
+ if (ecmdParseOption(&argc, &argv, "-verif"))
+ {
+ GLOBAL_VERIF_MODE = true;
+ }
+
+ // parse out common eCMD args like -p0, -c0, -coe, etc..
+ // any found args will be removed from arg list upon return
+ rc = ecmdCommandArgs(&argc, &argv);
+
+ if (rc)
+ {
+ ecmdOutputError("Error parsing eCMD arguments\n");
+ break;
+ }
+
+ // unsupported arguments left over?
+ if (argc != 1)
+ {
+ ecmdOutputError("Unknown/unsupported arguments specified!\n");
+ help();
+ rc = ECMD_INVALID_ARGS;
+ break;
+ }
+
+ // print procedure information header
+ if (!ecmdGetGlobalVar(ECMD_GLOBALVAR_QUIETMODE))
+ {
+ // print informational message
+ snprintf(outstr, sizeof(outstr), "Procedure %s: %s\n",
+ PROCEDURE.c_str(), REVISION.c_str());
+ ecmdOutput(outstr);
+
+ // always print the DLL info to the screen, unless in quiet mode
+ rc = ecmdDisplayDllInfo();
+
+ if (rc)
+ {
+ ecmdOutputError("Error displaying DLL info!");
+ break;
+ }
+ }
+
+ // configure looper to iterate over all nodes
+ node_target.cageState = ECMD_TARGET_FIELD_WILDCARD;
+ node_target.nodeState = ECMD_TARGET_FIELD_WILDCARD;
+ node_target.slotState = ECMD_TARGET_FIELD_UNUSED;
+ node_target.posState = ECMD_TARGET_FIELD_UNUSED;
+ node_target.coreState = ECMD_TARGET_FIELD_UNUSED;
+ node_target.threadState = ECMD_TARGET_FIELD_UNUSED;
+ rc = ecmdConfigLooperInit(node_target, ECMD_SELECTED_TARGETS_LOOP_DEFALL, node_looper);
+
+ if (rc)
+ {
+ ecmdOutputError("Error initializing node looper!\n");
+ break;
+ }
+
+ // loop over specified configured nodes
+ while (ecmdConfigLooperNext(node_target, node_looper))
+ {
+ ecmdLooperData cen_looper;
+ ecmdChipTarget cen_target;
+
+ if (!ecmdGetGlobalVar(ECMD_GLOBALVAR_QUIETMODE))
+ {
+ snprintf(outstr, sizeof(outstr), "Processing %s\n",
+ ecmdWriteTarget(node_target).c_str());
+ ecmdOutput(outstr);
+ }
+
+ cen_target.chipType = "cen";
+ cen_target.chipTypeState = ECMD_TARGET_FIELD_VALID;
+ cen_target.chipUnitType = "mba";
+ cen_target.chipUnitTypeState = ECMD_TARGET_FIELD_VALID;
+
+ cen_target.cage = node_target.cage;
+ cen_target.node = node_target.node;
+
+ cen_target.cageState = ECMD_TARGET_FIELD_VALID;
+ cen_target.nodeState = ECMD_TARGET_FIELD_VALID;
+ cen_target.slotState = ECMD_TARGET_FIELD_WILDCARD;
+ cen_target.posState = ECMD_TARGET_FIELD_WILDCARD;
+ cen_target.coreState = ECMD_TARGET_FIELD_UNUSED;
+ cen_target.threadState = ECMD_TARGET_FIELD_UNUSED;
+ cen_target.chipUnitNumState = ECMD_TARGET_FIELD_WILDCARD;
+
+ rc = ecmdConfigLooperInit(cen_target, ECMD_SELECTED_TARGETS_LOOP_DEFALL, cen_looper);
+
+ if (rc)
+ {
+ ecmdOutputError("Error initializing chip looper!\n");
+ break;
+ }
+
+ // loop over configured positions inside current node
+ while(ecmdConfigLooperNext(cen_target, cen_looper))
+ {
+ if (!ecmdGetGlobalVar(ECMD_GLOBALVAR_QUIETMODE))
+ {
+ snprintf(outstr, sizeof(outstr), "Going to call %s on %s\n",
+ PROCEDURE.c_str(),
+ ecmdWriteTarget(cen_target).c_str());
+ ecmdOutput(outstr);
+ }
+
+ // invoke FAPI procedure core
+ fapi2::Target<fapi2::TARGET_TYPE_MBA> fapi_target(&cen_target);
+ FAPI_EXEC_HWP(rc_fapi,
+ p9c_mss_ddr_phy_reset,
+ fapi_target);
+ rc = (uint32_t) rc_fapi;
+
+ if (rc)
+ {
+ snprintf(outstr, sizeof(outstr), "ERROR: %s FAPI call exited with bad return code = %s 0x%08x\n",
+ PROCEDURE.c_str(),
+ ecmdParseReturnCode(rc).c_str(), rc);
+ ecmdOutputError(outstr);
+ break;
+ }
+ }
+
+ if (rc)
+ {
+ break;
+ }
+ }
+
+ if (rc)
+ {
+ break;
+ }
+ }
+ while(0);
+
+ ecmdUnloadDll();
+ return rc;
+}
diff --git a/src/import/chips/centaur/procedures/hwp/memory/wrapper/p9c_mss_ddr_phy_reset_wrap.mk b/src/import/chips/centaur/procedures/hwp/memory/wrapper/p9c_mss_ddr_phy_reset_wrap.mk
new file mode 100755
index 000000000..2c7f5bf6f
--- /dev/null
+++ b/src/import/chips/centaur/procedures/hwp/memory/wrapper/p9c_mss_ddr_phy_reset_wrap.mk
@@ -0,0 +1,29 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/import/chips/centaur/procedures/hwp/memory/wrapper/p9c_mss_ddr_phy_reset_wrap.mk $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2017
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+WRAPPER=p9c_mss_ddr_phy_reset_wrap
+$(WRAPPER)_USELIBS+=p9c_mss_ddr_phy_reset
+$(WRAPPER)_DEPLIBS+=cen
+$(call BUILD_WRAPPER)
OpenPOWER on IntegriCloud