summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Kumar <sumit_kumar@in.ibm.com>2018-05-01 00:33:59 -0500
committerWilliam G. Hoffa <wghoffa@us.ibm.com>2018-05-16 09:42:26 -0400
commit6855bca779b8435856b0f6881480d7a4ed205b6b (patch)
tree38da6f0d36af4df08408ea58c10b8137bd2e6672
parentb0a9477ec9a6d2b297d71cc271d06282163d3963 (diff)
downloadtalos-hostboot-6855bca779b8435856b0f6881480d7a4ed205b6b.tar.gz
talos-hostboot-6855bca779b8435856b0f6881480d7a4ed205b6b.zip
Erepair HWP - Include target type DMI
- Centaur/DMI codes made fapi2 compliant - Refactored templated functions framework - Removed 'using namespace' from header files Change-Id: I690b24e5fdf9ff7413b128efb6f2fc4043bf739a Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/58065 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com> Reviewed-by: Benjamin J. Weisenbeck <bweisenb@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/58067 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
-rwxr-xr-xsrc/import/chips/p9/procedures/hwp/io/p9_io_erepairAccessorHwpFuncs.C1177
-rwxr-xr-xsrc/import/chips/p9/procedures/hwp/io/p9_io_erepairAccessorHwpFuncs.H1126
-rwxr-xr-xsrc/import/chips/p9/procedures/hwp/io/p9_io_erepairConsts.H44
-rwxr-xr-xsrc/import/chips/p9/procedures/hwp/io/p9_io_erepairGetFailedLanesHwp.C688
-rwxr-xr-xsrc/import/chips/p9/procedures/hwp/io/p9_io_erepairGetFailedLanesHwp.H970
-rw-r--r--src/import/chips/p9/procedures/hwp/io/p9_io_erepairGetFailedLanesHwp.mk27
-rwxr-xr-xsrc/import/chips/p9/procedures/hwp/io/p9_io_erepairSetFailedLanesHwp.C1134
-rwxr-xr-xsrc/import/chips/p9/procedures/hwp/io/p9_io_erepairSetFailedLanesHwp.H2182
-rw-r--r--src/import/chips/p9/procedures/hwp/io/p9_io_erepairSetFailedLanesHwp.mk27
-rw-r--r--src/usr/diag/prdf/prdf_hb_only.mk2
-rw-r--r--src/usr/isteps/istep09/makefile2
11 files changed, 4248 insertions, 3131 deletions
diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_erepairAccessorHwpFuncs.C b/src/import/chips/p9/procedures/hwp/io/p9_io_erepairAccessorHwpFuncs.C
index 4646a3a92..5814e3cc0 100755
--- a/src/import/chips/p9/procedures/hwp/io/p9_io_erepairAccessorHwpFuncs.C
+++ b/src/import/chips/p9/procedures/hwp/io/p9_io_erepairAccessorHwpFuncs.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -28,77 +28,13 @@
///
//----------------------------------------------------------------------------
#include <fapi2.H>
-#include <p9_io_erepairAccessorHwpFuncs.H>
#include <string.h>
#include <p9_io_erepairConsts.H>
-#include <p9_io_erepairSetFailedLanesHwp.H>
-#include <p9_io_erepairGetFailedLanesHwp.H>
using namespace EREPAIR;
using namespace fapi2;
-/** Forward Declarations **/
-
-/**
- * @brief: This function reads the field VPD data to check if there is any
- * eRepair data. This function will be called during Mnfg mode IPL
- * during which we need to make sure that the Field VPD is clear.
- * The Field VPD needs to be clear to enable customers to have
- * eRepair capability.
- *
- * @param [in] i_endp1_target Target of one end the connecting bus
- * @param [in] i_endp2_target Target of the other end of the connecting bus
- * The VPD of the passed targets are read for
- * checking the VPD contents
- * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
- *
- * @return ReturnCode
- */
-template<fapi2::TargetType K, fapi2::TargetType J>
-fapi2::ReturnCode mnfgCheckFieldVPD(
- const fapi2::Target < K >& i_endp1_target,
- const fapi2::Target < J >& i_endp2_target,
- const uint8_t i_clkGroup);
-
-
-/**
- * @brief: This Function reads the specified VPD (Mnfg or Field) of the passed
- * targets and verifies whether there are matching eRepair records.
- * The matching eRepair lanes are returned in the passed references
- * for vectors.
- *
- * @param [in] i_endp1_target Target of one end the connecting bus
- * @param [in] i_endp2_target Target of the other end of the connecting
- * bus
- * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
- * @param [out] o_endp1_txFaillanes Reference to vector which will have fail
- * lane numbers on Tx side of target passed
- * as first param
- * @param [out] o_endp1_rxFaillanes Reference to vector which will have fail
- * lane numbers on Rx side of target passed
- * as first param
- * @param [out] o_endp2_txFaillanes Reference to vector which will have fail
- * lane numbers on Tx side of target passed
- * as fourth param
- * @param [out] o_endp2_rxFaillanes Reference to vector which will have fail
- * lane numbers on Rx side of target passed
- * as fourth param
- * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
- * @param [in] i_vpdType Indicates whether to read Mnfg VPD or
- * Field VPD
- *
- * @return ReturnCode
- */
-template<fapi2::TargetType K, fapi2::TargetType J>
-fapi2::ReturnCode getVerifiedRepairLanes(
- const fapi2::Target < K >& i_endp1_target,
- const fapi2::Target < J >& i_endp2_target,
- const uint8_t i_clkGroup,
- std::vector<uint8_t>& o_endp1_txFaillanes,
- std::vector<uint8_t>& o_endp1_rxFaillanes,
- std::vector<uint8_t>& o_endp2_txFaillanes,
- std::vector<uint8_t>& o_endp2_rxFaillanes,
- const erepairVpdType i_vpdType);
+/***** Function definitions *****/
/**
* @brief This function checks to see if the passed vectors have matching
@@ -121,793 +57,6 @@ fapi2::ReturnCode getVerifiedRepairLanes(
void invalidateNonMatchingFailLanes(std::vector<uint8_t>& io_endp1_txFaillanes,
std::vector<uint8_t>& io_endp2_rxFaillanes,
bool& o_invalidFails_inTx_Ofendp1,
- bool& o_invalidFails_inRx_Ofendp2);
-
-/**
- * @brief This function gets the eRepair threshold value of the passed target
- * for the particular IPL type.
- *
- * @param [in] i_endp_target The target for whose type the threshold value
- * is needed
- * @param [in] i_mfgModeIPL If TRUE, indicates that this is a MnfgMode IPL
- * If FALSE, indicates that this is a Normal IPL
- * @param [out] o_threshold The threshold return value
- *
- * @return ReturnCode
- */
-template<fapi2::TargetType K>
-fapi2::ReturnCode geteRepairThreshold(
- const fapi2::Target < K >& i_endp_target,
- const bool i_mfgModeIPL,
- uint8_t& o_threshold);
-
-/**
- * @brief This function determines the lane numbers that needs to be spared
- * to support Corner testing.
- *
- * @param [in] i_tgtType The target type(XBus or OBus or DMIBus) for
- * which the lanes that need to be spared are
- * determined
- * @param [out] o_endp1_txFailLanes The reference to the vector which will
- * have the Tx side of lanes that need to be
- * spared for endp1
- * @param [out] o_endp1_rxFailLanes The reference to the vector which will
- * have the Rx side of lanes that need to be
- * spared for endp1
- * @param [out] o_endp2_txFailLanes The reference to the vector which will
- * have the Tx side of lanes that need to be
- * spared for endp2
- * @param [out] o_endp2_rxFailLanes The reference to the vector which will
- * have the Rx side of lanes that need to be
- * spared for endp2
- *
- * @return void
- */
-template<fapi2::TargetType K>
-void getCornerTestingLanes(
- const fapi2::Target < K >& i_tgtType,
- std::vector<uint8_t>& o_endp1_txFailLanes,
- std::vector<uint8_t>& o_endp1_rxFailLanes,
- std::vector<uint8_t>& o_endp2_txFailLanes,
- std::vector<uint8_t>& o_endp2_rxFailLanes);
-
-/**
- * @brief This function combines the eRepair lane numbers read from
- * Manufacturing VPD and Field VPD
- *
- * @param [in] i_mnfgFaillanes The eRepair lane numbers read from the
- * Manufacturing VPD
- * @param [in] i_fieldFaillanes The eRepair lane numbers read from the
- * Field VPD
- * @param [out] o_allFaillanes The eRepair lane numbers which is the union
- * of the Field and Manufacturing eRepair lanes
- * passed as first iand second params
- *
- * @return void
- */
-void combineFieldandMnfgLanes(std::vector<uint8_t>& i_mnfgFaillanes,
- std::vector<uint8_t>& i_fieldFaillanes,
- std::vector<uint8_t>& o_allFailLanes);
-
-
-/***** Function definitions *****/
-
-template<fapi2::TargetType K, fapi2::TargetType J>
-fapi2::ReturnCode erepairGetRestoreLanes(
- const fapi2::Target < K >& i_endp1_target,
- const fapi2::Target < J >& i_endp2_target,
- const uint8_t i_clkGroup,
- std::vector<uint8_t>& o_endp1_txFaillanes,
- std::vector<uint8_t>& o_endp1_rxFaillanes,
- std::vector<uint8_t>& o_endp2_txFaillanes,
- std::vector<uint8_t>& o_endp2_rxFaillanes)
-{
- fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- std::vector<uint8_t> l_endp1_txFieldFaillanes;
- std::vector<uint8_t> l_endp1_rxFieldFaillanes;
- std::vector<uint8_t> l_endp1_txMnfgFaillanes;
- std::vector<uint8_t> l_endp1_rxMnfgFaillanes;
-
- std::vector<uint8_t> l_endp2_txFieldFaillanes;
- std::vector<uint8_t> l_endp2_rxFieldFaillanes;
- std::vector<uint8_t> l_endp2_txMnfgFaillanes;
- std::vector<uint8_t> l_endp2_rxMnfgFaillanes;
-
- bool l_mnfgModeIPL = false;
- bool l_enableDmiSpares = false;
- bool l_enableFabricSpares = false;
- bool l_disableFabricERepair = false;
- bool l_disableMemoryERepair = false;
- bool l_thresholdExceed = false;
- uint8_t l_threshold = 0;
- uint64_t l_allMnfgFlags = 0;
- uint32_t l_numTxFailLanes = 0;
- uint32_t l_numRxFailLanes = 0;
- fapi2::TargetType l_endp1_tgtType = fapi2::TARGET_TYPE_NONE;
- fapi2::TargetType l_endp2_tgtType = fapi2::TARGET_TYPE_NONE;
-
- FAPI_INF(">>erepairGetRestoreLanes");
-
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MNFG_FLAGS,
- fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
- l_allMnfgFlags));
-
- // Check if MNFG_DISABLE_FABRIC_EREPAIR is enabled
- l_disableFabricERepair = false;
-
- if(l_allMnfgFlags &
- fapi2::ENUM_ATTR_MNFG_FLAGS_MNFG_DISABLE_FABRIC_eREPAIR)
- {
- l_disableFabricERepair = true;
- }
-
- // Check if MNFG_DISABLE_MEMORY_EREPAIR is enabled
- l_disableMemoryERepair = false;
-
- if(l_allMnfgFlags &
- fapi2::ENUM_ATTR_MNFG_FLAGS_MNFG_DISABLE_MEMORY_eREPAIR)
- {
- l_disableMemoryERepair = true;
- }
-
- // Check if this is Manufacturing mode IPL.
- l_mnfgModeIPL = false;
-
- if(l_allMnfgFlags & fapi2::ENUM_ATTR_MNFG_FLAGS_MNFG_THRESHOLDS)
- {
- l_mnfgModeIPL = true;
- }
-
- // Get the type of passed targets
- l_endp1_tgtType = i_endp1_target.getType();
- l_endp2_tgtType = i_endp2_target.getType();
-
- // Check if the correct target types are passed
- if(l_endp1_tgtType == fapi2::TARGET_TYPE_XBUS_ENDPOINT ||
- l_endp1_tgtType == fapi2::TARGET_TYPE_OBUS)
- {
- FAPI_ASSERT(l_endp1_tgtType == l_endp2_tgtType,
- fapi2::P9_EREPAIR_RESTORE_INVALID_TARGET_PAIR()
- .set_TARGET1(l_endp1_tgtType)
- .set_TARGET2(l_endp2_tgtType),
- "ERROR:erepairGetRestoreLanes: Invalid endpoint target pair");
-
- // Check for enablement of Fabric eRepair
- if(l_mnfgModeIPL && l_disableFabricERepair)
- {
- // Fabric eRepair has been disabled using the
- // Manufacturing policy flags
- FAPI_INF("erepairGetRestoreLanes: Fabric eRepair is disabled");
- goto fapi_try_exit;
- }
- }
- else if(l_endp1_tgtType == fapi2::TARGET_TYPE_MCS_CHIPLET ||
- l_endp1_tgtType == fapi2::TARGET_TYPE_MEMBUF_CHIP)
- {
- FAPI_ASSERT( ((l_endp1_tgtType == fapi2::TARGET_TYPE_MCS_CHIPLET) &&
- (l_endp2_tgtType == fapi2::TARGET_TYPE_MEMBUF_CHIP)) ||
- ((l_endp1_tgtType == fapi2::TARGET_TYPE_MEMBUF_CHIP) &&
- (l_endp2_tgtType == fapi2::TARGET_TYPE_MCS_CHIPLET)),
- fapi2::P9_EREPAIR_RESTORE_INVALID_TARGET_PAIR()
- .set_TARGET1(l_endp1_tgtType)
- .set_TARGET2(l_endp2_tgtType),
- "ERROR:erepairGetRestoreLanes: Invalid endpoint target pair");
-
- // Check for enablement of Memory eRepair
- if(l_mnfgModeIPL && l_disableMemoryERepair)
- {
- // Memory eRepair has been disabled using the
- // Manufacturing policy flags
- FAPI_INF("erepairGetRestoreLanes: Memory eRepair is disabled");
- goto fapi_try_exit;
- }
- }
-
- if(l_mnfgModeIPL)
- {
- /***** Check Field VPD *****/
-
- // Do not allow eRepair data in Field VPD during Mfg Mode IPL
- l_rc = mnfgCheckFieldVPD(i_endp1_target,
- i_endp2_target,
- i_clkGroup);
-
- if(l_rc)
- {
- FAPI_DBG("erepairGetRestoreLanes:Error from mnfgCheckFieldVPD");
- fapi2::current_err = l_rc;
- goto fapi_try_exit;
- }
-
- /***** Read Manufacturing VPD *****/
- FAPI_TRY( getVerifiedRepairLanes(
- i_endp1_target,
- i_endp2_target,
- i_clkGroup,
- o_endp1_txFaillanes,
- o_endp1_rxFaillanes,
- o_endp2_txFaillanes,
- o_endp2_rxFaillanes,
- EREPAIR_VPD_MNFG),
- "getVerifiedRepairLanes(Mnfg) mnfg mode ipl failed w/rc=0x%x",
- (uint64_t)current_err );
- }
- else
- {
- /***** Normal Mode IPL *****/
- // During Normal mode IPL we read both Mnfg and Field VPD
- // for restoring eRepair lanes
-
- /***** Read Manufacturing VPD *****/
- FAPI_TRY( getVerifiedRepairLanes(
- i_endp1_target,
- i_endp2_target,
- i_clkGroup,
- l_endp1_txMnfgFaillanes,
- l_endp1_rxMnfgFaillanes,
- l_endp2_txMnfgFaillanes,
- l_endp2_rxMnfgFaillanes,
- EREPAIR_VPD_MNFG),
- "getVerifiedRepairLanes(Mnfg) normal mode ipl failed w/rc=0x%x",
- (uint64_t)current_err );
-
- /***** Read Field VPD *****/
- FAPI_TRY( getVerifiedRepairLanes(
- i_endp1_target,
- i_endp2_target,
- i_clkGroup,
- l_endp1_txFieldFaillanes,
- l_endp1_rxFieldFaillanes,
- l_endp2_txFieldFaillanes,
- l_endp2_rxFieldFaillanes,
- EREPAIR_VPD_FIELD),
- "getVerifiedRepairLanes(Field) normal mode ipl failed w/rc=0x%x",
- (uint64_t)current_err );
-
- /***** Combine the Mnfg and Field eRepair lanes *****/
-
- // Combine the Tx side fail lanes of endp1
- combineFieldandMnfgLanes(l_endp1_txMnfgFaillanes,
- l_endp1_txFieldFaillanes,
- o_endp1_txFaillanes);
-
- // Combine the Rx side fail lanes of endp1
- combineFieldandMnfgLanes(l_endp1_rxMnfgFaillanes,
- l_endp1_rxFieldFaillanes,
- o_endp1_rxFaillanes);
-
- // Combine the Tx side fail lanes of endp2
- combineFieldandMnfgLanes(l_endp2_txMnfgFaillanes,
- l_endp2_txFieldFaillanes,
- o_endp2_txFaillanes);
-
- // Combine the Rx side fail lanes of endp1
- combineFieldandMnfgLanes(l_endp2_rxMnfgFaillanes,
- l_endp2_rxFieldFaillanes,
- o_endp2_rxFaillanes);
-
- } // end of else block of "if(l_mnfgModeIPL)"
-
-
- /***** Check for threshold exceed conditions *****/
-
- // Get the eRepair threshold limit
- l_threshold = 0;
- FAPI_TRY( geteRepairThreshold(
- i_endp1_target,
- l_mnfgModeIPL,
- l_threshold),
- "geteRepairThreshold() failed w/rc=0x%x",
- (uint64_t)current_err );
-
- // Check if the eRepair threshold has exceeded for Tx side of endp1
- if(o_endp1_txFaillanes.size() > l_threshold)
- {
- l_thresholdExceed = true;
- l_numTxFailLanes = o_endp1_txFaillanes.size();
-
- FAPI_DBG("erepairGetRestoreLanes: eRepair threshold exceed error"
- " seen in Tx of endp1 target. No.of lanes: %d", l_numTxFailLanes);
- }
-
- // Check if the eRepair threshold has exceeded for Rx side of endp1
- if(o_endp1_rxFaillanes.size() > l_threshold)
- {
- l_thresholdExceed = true;
- l_numRxFailLanes = o_endp1_rxFaillanes.size();
-
- FAPI_DBG("erepairGetRestoreLanes: eRepair threshold exceed error"
- " seen in Rx of endp1 target. No.of lanes: %d", l_numRxFailLanes);
- }
-
- // Check if the eRepair threshold has exceeded for Tx side of endp2
- if(o_endp2_txFaillanes.size() > l_threshold)
- {
- l_thresholdExceed = true;
- l_numTxFailLanes = o_endp2_txFaillanes.size();
-
- FAPI_DBG("erepairGetRestoreLanes: eRepair threshold exceed error"
- " seen in Tx of endp2 target. No.of lanes: %d",
- l_numTxFailLanes);
- }
-
- // Check if the eRepair threshold has exceeded for Rx side of endp2
- if(o_endp2_rxFaillanes.size() > l_threshold)
- {
- l_thresholdExceed = true;
- l_numRxFailLanes = o_endp2_rxFaillanes.size();
-
- FAPI_DBG("erepairGetRestoreLanes: eRepair threshold exceed error"
- " seen in Rx of endp2 target. No.of lanes: %d",
- l_numRxFailLanes);
- }
-
- FAPI_ASSERT(l_thresholdExceed == false,
- fapi2::P9_EREPAIR_THRESHOLD_EXCEED()
- .set_TX_NUM_LANES(l_numTxFailLanes)
- .set_RX_NUM_LANES(l_numTxFailLanes)
- .set_THRESHOLD(l_threshold),
- "ERROR:The threshold limit for eRepair has been crossed");
-
- if(l_mnfgModeIPL)
- {
- // Check if MNFG_DMI_DEPLOY_LANE_SPARES is enabled
- l_enableDmiSpares = false;
-
- if(l_allMnfgFlags &
- fapi2::ENUM_ATTR_MNFG_FLAGS_MNFG_DMI_DEPLOY_LANE_SPARES)
- {
- l_enableDmiSpares = true;
- }
-
- // Check if MNFG_FABRIC_DEPLOY_LANE_SPARES is enabled
- l_enableFabricSpares = false;
-
- if(l_allMnfgFlags &
- fapi2::ENUM_ATTR_MNFG_FLAGS_MNFG_FABRIC_DEPLOY_LANE_SPARES)
- {
- l_enableFabricSpares = true;
- }
-
- if(l_enableDmiSpares || l_enableFabricSpares)
- {
- // This is a Corner testing IPL.
- // eRepair Restore the pre-determined memory lanes
- getCornerTestingLanes(i_endp1_target,
- o_endp1_txFaillanes,
- o_endp1_rxFaillanes,
- o_endp2_txFaillanes,
- o_endp2_rxFaillanes);
- }
- } // end of if(l_mnfgModeIPL)
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-template ReturnCode erepairGetRestoreLanes<TARGET_TYPE_XBUS, TARGET_TYPE_XBUS>(
- const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_endp1_target,
- const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_endp2_target,
- const uint8_t i_clkGroup,
- std::vector<uint8_t>& o_endp1_txFaillanes,
- std::vector<uint8_t>& o_endp1_rxFaillanes,
- std::vector<uint8_t>& o_endp2_txFaillanes,
- std::vector<uint8_t>& o_endp2_rxFaillanes);
-
-
-void combineFieldandMnfgLanes(std::vector<uint8_t>& i_mnfgFaillanes,
- std::vector<uint8_t>& i_fieldFaillanes,
- std::vector<uint8_t>& o_allFaillanes)
-{
- std::vector<uint8_t>::iterator l_it;
-
- // Merge the Field and Mnfg fail lanes
- l_it = o_allFaillanes.begin();
- o_allFaillanes.insert(l_it,
- i_mnfgFaillanes.begin(),
- i_mnfgFaillanes.end());
-
- l_it = o_allFaillanes.end();
- o_allFaillanes.insert(l_it,
- i_fieldFaillanes.begin(),
- i_fieldFaillanes.end());
-
- // Check if Mfg VPD and Field VPD have same fail lanes.
- // If found, erase them
- std::sort(o_allFaillanes.begin(), o_allFaillanes.end());
-
- o_allFaillanes.erase(std::unique(o_allFaillanes.begin(),
- o_allFaillanes.end()),
- o_allFaillanes.end());
-
-}
-
-template<fapi2::TargetType K>
-void getCornerTestingLanes(
- const fapi2::Target < K >& i_tgtType,
- std::vector<uint8_t>& o_endp1_txFaillanes,
- std::vector<uint8_t>& o_endp1_rxFaillanes,
- std::vector<uint8_t>& o_endp2_txFaillanes,
- std::vector<uint8_t>& o_endp2_rxFaillanes)
-{
- std::vector<uint8_t>::iterator l_it;
- uint8_t l_deployIndx = 0;
- uint8_t l_maxDeploys = 0;
- uint8_t* l_deployPtr = NULL;
-
- uint8_t l_xDeployLanes[XBUS_MAXSPARES_IN_HW] = {XBUS_SPARE_DEPLOY_LANE_1};
- uint8_t l_oDeployLanes[OBUS_MAXSPARES_IN_HW] = {OBUS_SPARE_DEPLOY_LANE_1,
- OBUS_SPARE_DEPLOY_LANE_2
- };
-
- uint8_t l_dmiDeployLanes[DMIBUS_MAXSPARES_IN_HW] =
- {
- DMIBUS_SPARE_DEPLOY_LANE_1,
- DMIBUS_SPARE_DEPLOY_LANE_2
- };
-
- // Idea is to push_back the pre-determined lanes into the Tx and Rx
- // vectors of endpoint1 and endpoint2
- switch(i_tgtType.getType())
- {
- case fapi2::TARGET_TYPE_XBUS_ENDPOINT:
- l_maxDeploys = XBUS_MAXSPARES_IN_HW;
- l_deployPtr = l_xDeployLanes;
- break;
-
- case fapi2::TARGET_TYPE_OBUS:
- l_maxDeploys = OBUS_MAXSPARES_IN_HW;
- l_deployPtr = l_oDeployLanes;
- break;
-
- case fapi2::TARGET_TYPE_MCS_CHIPLET:
- case fapi2::TARGET_TYPE_MEMBUF_CHIP:
- l_maxDeploys = DMIBUS_MAXSPARES_IN_HW;
- l_deployPtr = l_dmiDeployLanes;
- break;
-
- default:
- FAPI_ASSERT(false,
- fapi2::P9_EREPAIR_RESTORE_INVALID_TARGET()
- .set_TARGET(i_tgtType),
- "ERROR:getCornerTestingLanes: Invalid target type");
- break;
- };
-
- std::sort(o_endp1_txFaillanes.begin(), o_endp1_txFaillanes.end());
-
- std::sort(o_endp1_rxFaillanes.begin(), o_endp1_rxFaillanes.end());
-
- for(l_deployIndx = 0;
- ((l_deployIndx < l_maxDeploys) &&
- (o_endp1_txFaillanes.size() < l_maxDeploys));
- l_deployIndx++)
- {
- l_it = std::find(o_endp1_txFaillanes.begin(),
- o_endp1_txFaillanes.end(),
- l_deployPtr[l_deployIndx]);
-
- if(l_it == o_endp1_txFaillanes.end())
- {
- o_endp1_txFaillanes.push_back(l_deployPtr[l_deployIndx]);
- }
- }
-
- for(l_deployIndx = 0;
- ((o_endp1_rxFaillanes.size() < l_maxDeploys) &&
- (l_deployIndx < l_maxDeploys));
- l_deployIndx++)
- {
- l_it = std::find(o_endp1_rxFaillanes.begin(),
- o_endp1_rxFaillanes.end(),
- l_deployPtr[l_deployIndx]);
-
- if(l_it == o_endp1_rxFaillanes.end())
- {
- o_endp1_rxFaillanes.push_back(l_deployPtr[l_deployIndx]);
- }
- }
-
- // We can cassign the lanes of endpoint1 to endpoint2 because any
- // existing faillanes in endpoint2 have already been matched with
- // endpoint1. This means that there cannot be any faillanes in
- // endpoint2 that do not have equivalent lanes in endpoint1.
- o_endp2_txFaillanes = o_endp1_txFaillanes;
- o_endp2_rxFaillanes = o_endp1_rxFaillanes;
-
-fapi_try_exit:
- return;
-}
-
-template<fapi2::TargetType K>
-fapi2::ReturnCode geteRepairThreshold(
- const fapi2::Target < K >& i_endp_target,
- const bool i_mfgModeIPL,
- uint8_t& o_threshold)
-{
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
- fapi2::TargetType l_tgtType = fapi2::TARGET_TYPE_NONE;
-
- o_threshold = 0;
- l_tgtType = i_endp_target.getType();
-
- if(i_mfgModeIPL)
- {
- switch(l_tgtType)
- {
- case fapi2::TARGET_TYPE_XBUS_ENDPOINT:
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_X_EREPAIR_THRESHOLD_MNFG,
- fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
- o_threshold));
- break;
-
- case fapi2::TARGET_TYPE_OBUS:
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_O_EREPAIR_THRESHOLD_MNFG,
- fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
- o_threshold));
- break;
-
- case fapi2::TARGET_TYPE_MCS_CHIPLET:
- case fapi2::TARGET_TYPE_MEMBUF_CHIP:
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_DMI_EREPAIR_THRESHOLD_MNFG,
- fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
- o_threshold));
- break;
-
- default:
- FAPI_ASSERT(false,
- fapi2::P9_EREPAIR_RESTORE_INVALID_TARGET()
- .set_TARGET(l_tgtType),
- "ERROR:geteRepairThreshold: Invalid target type");
- break;
- };
- }
- else
- {
- switch(l_tgtType)
- {
- case fapi2::TARGET_TYPE_XBUS_ENDPOINT:
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_X_EREPAIR_THRESHOLD_FIELD,
- fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
- o_threshold));
- break;
-
- case fapi2::TARGET_TYPE_OBUS:
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_O_EREPAIR_THRESHOLD_FIELD,
- fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
- o_threshold));
- break;
-
- case fapi2::TARGET_TYPE_MCS_CHIPLET:
- case fapi2::TARGET_TYPE_MEMBUF_CHIP:
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_DMI_EREPAIR_THRESHOLD_FIELD,
- fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
- o_threshold));
- break;
-
- default:
- FAPI_ASSERT(false,
- fapi2::P9_EREPAIR_RESTORE_INVALID_TARGET()
- .set_TARGET(l_tgtType),
- "ERROR:geteRepairThreshold: Invalid target type");
- break;
- };
- }
-
-fapi_try_exit:
- FAPI_INF("geteRepairThreshold: o_threshold = %d", o_threshold);
- return fapi2::current_err;
-}
-
-template<fapi2::TargetType K, fapi2::TargetType J>
-fapi2::ReturnCode mnfgCheckFieldVPD(
- const fapi2::Target < K >& i_endp1_target,
- const fapi2::Target < J >& i_endp2_target,
- const uint8_t i_clkGroup)
-{
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
- std::vector<uint8_t> l_endp1_txFaillanes;
- std::vector<uint8_t> l_endp1_rxFaillanes;
- std::vector<uint8_t> l_endp2_txFaillanes;
- std::vector<uint8_t> l_endp2_rxFaillanes;
- bool l_fieldVPDClear = true;
-
- l_fieldVPDClear = true;
-
- /***** Read Field VPD *****/
-
- // During Mfg mode IPL, field VPD need to be clear.
-
- // Get failed lanes for endp1
- FAPI_TRY( erepairGetFieldFailedLanes(
- i_endp1_target,
- i_clkGroup,
- l_endp1_txFaillanes,
- l_endp1_rxFaillanes),
- "erepairGetFieldFailedLanes endp1 target failed w/rc=0x%x",
- (uint64_t)current_err );
-
- // If there are fail lanes in Field VPD on endpoint1, create an
- // error log and return
- if(l_endp1_txFaillanes.size() ||
- l_endp1_rxFaillanes.size())
- {
- l_fieldVPDClear = false;
- FAPI_DBG("mnfgCheckFieldVPD: eRepair records found in Field VPD in Tx during Manufacturing mode IPL");
- }
-
- // Get failed lanes for endp2
- FAPI_TRY( erepairGetFieldFailedLanes(
- i_endp2_target,
- i_clkGroup,
- l_endp2_txFaillanes,
- l_endp2_rxFaillanes),
- "erepairGetFieldFailedLanes endp2 target failed w/rc=0x%x",
- (uint64_t)current_err );
-
- // If there are fail lanes in Field VPD on endpoint2, create an
- // error log and return
- if(l_endp2_txFaillanes.size() ||
- l_endp2_rxFaillanes.size())
- {
- l_fieldVPDClear = false;
- FAPI_DBG("mnfgCheckFieldVPD: eRepair records found in Field VPD in Rx during Manufacturing mode IPL");
- }
-
- FAPI_ASSERT(l_fieldVPDClear == true,
- fapi2::P9_EREPAIR_RESTORE_FIELD_VPD_NOT_CLEAR()
- .set_TARGET1(i_endp1_target)
- .set_TARGET2(i_endp2_target),
- "ERROR: mnfgCheckFieldVPD: Field VPD need to be clear during Mnfg mode IPL");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-template<fapi2::TargetType K, fapi2::TargetType J>
-fapi2::ReturnCode getVerifiedRepairLanes(
- const fapi2::Target < K >& i_endp1_target,
- const fapi2::Target < J >& i_endp2_target,
- const uint8_t i_clkGroup,
- std::vector<uint8_t>& o_endp1_txFaillanes,
- std::vector<uint8_t>& o_endp1_rxFaillanes,
- std::vector<uint8_t>& o_endp2_txFaillanes,
- std::vector<uint8_t>& o_endp2_rxFaillanes,
- const erepairVpdType i_vpdType)
-{
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- getLanes_t<K> l_getLanes = NULL;
- setLanes_t<K> l_setLanes = NULL;
-
- fapi2::Target < K > l_target[2] = {i_endp1_target, i_endp2_target};
- bool l_invalidFails_inTx_OfTgt[2] = {false, false};
- bool l_invalidFails_inRx_OfTgt[2] = {false, false};
- uint8_t l_tgtIndx = 0;
-
- std::vector<uint8_t> l_emptyVector;
- std::vector<uint8_t> l_txFaillanes;
- std::vector<uint8_t> l_rxFaillanes;
-
- FAPI_INF(">> getVerifiedRepairLanes: vpdType: %s",
- i_vpdType == EREPAIR_VPD_FIELD ? "Field" : "Mnfg");
-
- /***** Read VPD *****/
-
- if(i_vpdType == EREPAIR_VPD_FIELD)
- {
- l_getLanes = &erepairGetFieldFailedLanes;
- l_setLanes = &erepairSetFieldFailedLanes;
- }
- else if(i_vpdType == EREPAIR_VPD_MNFG)
- {
- l_getLanes = &erepairGetMnfgFailedLanes;
- l_setLanes = &erepairSetMnfgFailedLanes;
- }
-
- for(l_tgtIndx = 0; l_tgtIndx < 2; l_tgtIndx++)
- {
- // Get failed lanes for endp1 and endp2
- FAPI_TRY( l_getLanes(
- l_target[l_tgtIndx],
- i_clkGroup,
- l_txFaillanes,
- l_rxFaillanes),
- "getVerifiedRepairLanes() from Accessor HWP failed w/rc=0x%x",
- (uint64_t)current_err );
-
- if(l_tgtIndx == 0)
- {
- o_endp1_txFaillanes = l_txFaillanes;
- o_endp1_rxFaillanes = l_rxFaillanes;
- }
- else
- {
- o_endp2_txFaillanes = l_txFaillanes;
- o_endp2_rxFaillanes = l_rxFaillanes;
- }
-
- l_txFaillanes.clear();
- l_rxFaillanes.clear();
- } // end of for(l_tgtIndx)
-
- // Check if matching fail lanes exists on the sub-interfaces
- // connecting the two end points
- if(o_endp1_txFaillanes.size() || o_endp2_rxFaillanes.size())
- {
- invalidateNonMatchingFailLanes(o_endp1_txFaillanes,
- o_endp2_rxFaillanes,
- l_invalidFails_inTx_OfTgt[0],
- l_invalidFails_inRx_OfTgt[1]);
- }
-
- if(o_endp2_txFaillanes.size() || o_endp1_rxFaillanes.size())
- {
- invalidateNonMatchingFailLanes(o_endp2_txFaillanes,
- o_endp1_rxFaillanes,
- l_invalidFails_inTx_OfTgt[1],
- l_invalidFails_inRx_OfTgt[0]);
- }
-
- /***** Correct eRepair data of endp1 in VPD *****/
-
- for(l_tgtIndx = 0; l_tgtIndx < 2; l_tgtIndx++)
- {
- if(l_tgtIndx == 0)
- {
- l_txFaillanes = o_endp1_txFaillanes;
- l_rxFaillanes = o_endp1_rxFaillanes;
- }
- else
- {
- l_txFaillanes = o_endp2_txFaillanes;
- l_rxFaillanes = o_endp2_rxFaillanes;
- }
-
- // Update endp1 and endp2 VPD to invalidate fail lanes that do
- // not have matching fail lanes on the other end
- if(l_invalidFails_inTx_OfTgt[l_tgtIndx] &&
- l_invalidFails_inRx_OfTgt[l_tgtIndx])
- {
- FAPI_TRY( l_setLanes(
- l_target[l_tgtIndx],
- i_clkGroup,
- l_txFaillanes,
- l_rxFaillanes),
- "getVerifiedRepairLanes() tx/rx from Accessor HWP failed w/rc=0x%x",
- (uint64_t)current_err );
- }
- else if(l_invalidFails_inTx_OfTgt[l_tgtIndx])
- {
- FAPI_TRY( l_setLanes(
- l_target[l_tgtIndx],
- i_clkGroup,
- l_txFaillanes,
- l_emptyVector),
- "getVerifiedRepairLanes() tx from Accessor HWP failed w/rc=0x%x",
- (uint64_t)current_err );
- }
- else if(l_invalidFails_inRx_OfTgt[l_tgtIndx])
- {
- FAPI_TRY( l_setLanes(
- l_target[l_tgtIndx],
- i_clkGroup,
- l_emptyVector,
- l_rxFaillanes),
- "getVerifiedRepairLanes() rx from Accessor HWP failed w/rc=0x%x",
- (uint64_t)current_err );
- }
- } // end of for loop
-
-fapi_try_exit:
- return current_err;
-}
-
-void invalidateNonMatchingFailLanes(std::vector<uint8_t>& io_endp1_txFaillanes,
- std::vector<uint8_t>& io_endp2_rxFaillanes,
- bool& o_invalidFails_inTx_Ofendp1,
bool& o_invalidFails_inRx_Ofendp2)
{
std::vector<uint8_t>::iterator l_it;
@@ -980,302 +129,44 @@ void invalidateNonMatchingFailLanes(std::vector<uint8_t>& io_endp1_txFaillanes,
}
}
-
-template<fapi2::TargetType K>
-fapi2::ReturnCode erepairGetFailedLanes(
- const fapi2::Target < K >& i_endp_target,
- const uint8_t i_clkGroup,
- std::vector<uint8_t>& o_txFailLanes,
- std::vector<uint8_t>& o_rxFailLanes)
+/**
+ * @brief This function combines the eRepair lane numbers read from
+ * Manufacturing VPD and Field VPD
+ *
+ * @param [in] i_mnfgFaillanes The eRepair lane numbers read from the
+ * Manufacturing VPD
+ * @param [in] i_fieldFaillanes The eRepair lane numbers read from the
+ * Field VPD
+ * @param [out] o_allFaillanes The eRepair lane numbers which is the union
+ * of the Field and Manufacturing eRepair lanes
+ * passed as first iand second params
+ *
+ * @return void
+ */
+void combineFieldandMnfgLanes(std::vector<uint8_t>& i_mnfgFaillanes,
+ std::vector<uint8_t>& i_fieldFaillanes,
+ std::vector<uint8_t>& o_allFaillanes)
{
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
- std::vector<uint8_t> l_txFailLanes;
- std::vector<uint8_t> l_rxFailLanes;
std::vector<uint8_t>::iterator l_it;
- FAPI_INF(">> erepairGetFailedLaness");
-
- // Get the erepair lanes from Field VPD
- FAPI_TRY( erepairGetFieldFailedLanes(
- i_endp_target,
- i_clkGroup,
- l_txFailLanes,
- l_rxFailLanes),
- "erepairGetFieldFailedLanes() failed w/rc=0x%x",
- (uint64_t)current_err );
-
- o_txFailLanes = l_txFailLanes;
- o_rxFailLanes = l_rxFailLanes;
-
- // Get the erepair lanes from Manufacturing VPD
- l_txFailLanes.clear();
- l_rxFailLanes.clear();
- FAPI_TRY( erepairGetMnfgFailedLanes(
- i_endp_target,
- i_clkGroup,
- l_txFailLanes,
- l_rxFailLanes),
- "erepairGetMnfgFailedLanes() failed w/rc=0x%x",
- (uint64_t)current_err );
-
- // Merge the Mnfg lanes with the Field lanes
- l_it = o_txFailLanes.end();
- o_txFailLanes.insert(l_it, l_txFailLanes.begin(), l_txFailLanes.end());
-
- l_it = o_rxFailLanes.end();
- o_rxFailLanes.insert(l_it, l_rxFailLanes.begin(), l_rxFailLanes.end());
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-template fapi2::ReturnCode erepairGetFailedLanes<TARGET_TYPE_XBUS>(
- const fapi2::Target < TARGET_TYPE_XBUS >& i_endp_target,
- const uint8_t i_clkGroup,
- std::vector<uint8_t>& o_txFailLanes,
- std::vector<uint8_t>& o_rxFailLanes);
-
-
-template<fapi2::TargetType K>
-fapi2::ReturnCode erepairGetFieldFailedLanes(
- const fapi2::Target < K >& i_endp_target,
- const uint8_t i_clkGroup,
- std::vector<uint8_t>& o_txFailLanes,
- std::vector<uint8_t>& o_rxFailLanes)
-{
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- FAPI_DBG(">> erepairGetFieldFailedLanes");
-
- // Execute the Accessor HWP to retrieve the failed lanes from the VPD
- FAPI_TRY( p9_io_erepairGetFailedLanesHwp(
- i_endp_target,
- EREPAIR_VPD_FIELD,
- i_clkGroup,
- o_txFailLanes,
- o_rxFailLanes),
- "erepairGetFieldFailedLanes() from Accessor HWP failed w/rc=0x%x",
- (uint64_t)current_err );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-template<fapi2::TargetType K>
-fapi2::ReturnCode erepairGetMnfgFailedLanes(
- const fapi2::Target < K >& i_endp_target,
- const uint8_t i_clkGroup,
- std::vector<uint8_t>& o_txFailLanes,
- std::vector<uint8_t>& o_rxFailLanes)
-{
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- FAPI_DBG(">> erepairGetMnfgFailedLanes");
-
- // Execute the Accessor HWP to retrieve the failed lanes from the VPD
- FAPI_TRY( p9_io_erepairGetFailedLanesHwp(
- i_endp_target,
- EREPAIR_VPD_MNFG,
- i_clkGroup,
- o_txFailLanes,
- o_rxFailLanes),
- "erepairGetMnfgFailedLanes() from Accessor HWP failed w/rc=0x%x",
- (uint64_t)current_err );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-template<fapi2::TargetType K, fapi2::TargetType J>
-fapi2::ReturnCode erepairSetFailedLanes(
- const fapi2::Target < K >& i_txEndp_target,
- const fapi2::Target < J >& i_rxEndp_target,
- const uint8_t i_clkGroup,
- const std::vector<uint8_t>& i_rxFailLanes,
- bool& o_thresholdExceed)
-{
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
- uint64_t l_allMnfgFlags = 0;
- bool l_mnfgModeIPL = false;
- uint8_t l_threshold = 0;
- setLanes_t<K> l_setLanes = NULL;
- getLanes_t<K> l_getLanes = NULL;
- std::vector<uint8_t> l_txFaillanes;
- std::vector<uint8_t> l_rxFaillanes;
- std::vector<uint8_t> l_emptyVector;
- std::vector<uint8_t> l_throwAway;
-
- FAPI_INF(">> erepairSetFailedLanes");
-
- o_thresholdExceed = false;
-
- // Get the Manufacturing Policy flags
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MNFG_FLAGS,
- fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
- l_allMnfgFlags),
- "erepairSetFailedLanes: Unable to read attribute ATTR_MNFG_FLAGS");
-
- // Check if this is a Mnfg mode IPL
- if(l_allMnfgFlags & fapi2::ENUM_ATTR_MNFG_FLAGS_MNFG_THRESHOLDS)
- {
- l_mnfgModeIPL = true;
- }
-
- if(l_mnfgModeIPL)
- {
- l_setLanes = &erepairSetMnfgFailedLanes;
- l_getLanes = &erepairGetMnfgFailedLanes;
- }
- else
- {
- l_setLanes = &erepairSetFieldFailedLanes;
- l_getLanes = &erepairGetFieldFailedLanes;
- }
-
- /*** Check if we have crossed the repair threshold ***/
- // Get the eRepair threshold limit
- l_threshold = 0;
- FAPI_TRY( geteRepairThreshold(
- i_rxEndp_target,
- l_mnfgModeIPL,
- l_threshold),
- "geteRepairThreshold() from Accessor HWP failed w/rc=0x%x",
- (uint64_t)current_err );
-
- // Check if the new fails have crossed the threshold
- if(i_rxFailLanes.size() > l_threshold)
- {
- o_thresholdExceed = true;
- goto fapi_try_exit;
- }
-
- // Get existing fail lanes that are in the VPD of rx endpoint
- FAPI_TRY( l_getLanes(
- i_rxEndp_target,
- i_clkGroup,
- l_throwAway,
- l_rxFaillanes),
- "rx l_getLanes() from Accessor HWP failed w/rc=0x%x",
- (uint64_t)current_err );
-
- // Get existing fail lanes that are in the VPD of tx endpoint
- FAPI_TRY( l_getLanes(
- i_txEndp_target,
- i_clkGroup,
- l_txFaillanes,
- l_throwAway),
- "tx l_getLanes() from Accessor HWP failed w/rc=0x%x",
- (uint64_t)current_err );
-
- // Lets combine the new and old fail lanes of Rx side
- l_rxFaillanes.insert(l_rxFaillanes.end(),
- i_rxFailLanes.begin(),
- i_rxFailLanes.end());
-
- // Remove duplicate lanes if any on the Rx side
- std::sort(l_rxFaillanes.begin(), l_rxFaillanes.end());
-
- l_rxFaillanes.erase(std::unique(l_rxFaillanes.begin(),
- l_rxFaillanes.end()),
- l_rxFaillanes.end());
-
- // Lets combine the new and old fail lanes of Tx side
- l_txFaillanes.insert(l_txFaillanes.end(),
- i_rxFailLanes.begin(),
- i_rxFailLanes.end());
-
- // Remove duplicate lanes if any on the Tx side
- std::sort(l_txFaillanes.begin(), l_txFaillanes.end());
-
- l_txFaillanes.erase(std::unique(l_txFaillanes.begin(),
- l_txFaillanes.end()),
- l_txFaillanes.end());
-
- // Check if the sum of old and new fail lanes have crossed the threshold
- if((l_txFaillanes.size() > l_threshold) ||
- (l_rxFaillanes.size() > l_threshold))
- {
- o_thresholdExceed = true;
- goto fapi_try_exit;
- }
-
- /*** Update the VPD ***/
-
- // Lets write the VPD of endpoint1 with faillanes on Rx side
- FAPI_TRY( l_setLanes(
- i_rxEndp_target,
- i_clkGroup,
- l_emptyVector,
- l_rxFaillanes),
- "rx l_setLanes() from Accessor HWP failed w/rc=0x%x",
- (uint64_t)current_err );
-
- // Lets write the VPD of endpoint2 with faillanes on Tx side
- FAPI_TRY( l_setLanes(
- i_txEndp_target,
- i_clkGroup,
- l_txFaillanes,
- l_emptyVector),
- "tx l_setLanes() from Accessor HWP failed w/rc=0x%x",
- (uint64_t)current_err );
-
-fapi_try_exit:
- FAPI_INF("<< erepairSetFailedLanes");
- return fapi2::current_err;
-}
-
-template ReturnCode erepairSetFailedLanes<TARGET_TYPE_XBUS, TARGET_TYPE_XBUS>(
- const fapi2::Target < TARGET_TYPE_XBUS >& i_txEndp_target,
- const fapi2::Target < TARGET_TYPE_XBUS >& i_rxEndp_target,
- const uint8_t i_clkGroup,
- const std::vector<uint8_t>& i_rxFailLanes,
- bool& o_thresholdExceed);
-
-
-template<fapi2::TargetType K>
-fapi2::ReturnCode erepairSetFieldFailedLanes(
- const fapi2::Target < K >& i_endp_target,
- const uint8_t i_clkGroup,
- const std::vector<uint8_t>& i_txFailLanes,
- const std::vector<uint8_t>& i_rxFailLanes)
-{
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- // Execute the Accessor HWP to write the fail lanes to Field VPD
- FAPI_TRY( p9_io_erepairSetFailedLanesHwp(
- i_endp_target,
- EREPAIR_VPD_FIELD,
- i_clkGroup,
- i_txFailLanes,
- i_rxFailLanes),
- "erepairSetFieldFailedLanes() from Accessor HWP failed w/rc=0x%x",
- (uint64_t)current_err );
+ // Merge the Field and Mnfg fail lanes
+ l_it = o_allFaillanes.begin();
+ o_allFaillanes.insert(l_it,
+ i_mnfgFaillanes.begin(),
+ i_mnfgFaillanes.end());
-fapi_try_exit:
- return fapi2::current_err;
-}
+ l_it = o_allFaillanes.end();
+ o_allFaillanes.insert(l_it,
+ i_fieldFaillanes.begin(),
+ i_fieldFaillanes.end());
-template<fapi2::TargetType K>
-fapi2::ReturnCode erepairSetMnfgFailedLanes(
- const fapi2::Target < K >& i_endp_target,
- const uint8_t i_clkGroup,
- const std::vector<uint8_t>& i_txFailLanes,
- const std::vector<uint8_t>& i_rxFailLanes)
-{
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ // Check if Mfg VPD and Field VPD have same fail lanes.
+ // If found, erase them
+ std::sort(o_allFaillanes.begin(), o_allFaillanes.end());
- // Execute the Accessor HWP to write the fail lanes to Mnfg VPD
- FAPI_TRY( p9_io_erepairSetFailedLanesHwp(
- i_endp_target,
- EREPAIR_VPD_MNFG,
- i_clkGroup,
- i_txFailLanes,
- i_rxFailLanes),
- "erepairSetMnfgFailedLanes() from Accessor HWP failed w/rc=0x%x",
- (uint64_t)current_err );
+ o_allFaillanes.erase(std::unique(o_allFaillanes.begin(),
+ o_allFaillanes.end()),
+ o_allFaillanes.end());
-fapi_try_exit:
- return fapi2::current_err;
}
diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_erepairAccessorHwpFuncs.H b/src/import/chips/p9/procedures/hwp/io/p9_io_erepairAccessorHwpFuncs.H
index 246857af3..f23c079b8 100755
--- a/src/import/chips/p9/procedures/hwp/io/p9_io_erepairAccessorHwpFuncs.H
+++ b/src/import/chips/p9/procedures/hwp/io/p9_io_erepairAccessorHwpFuncs.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -28,14 +28,16 @@
///
//----------------------------------------------------------------------------
-
#ifndef P9_IO_EREPAIRACCESSORHWPFUNCS_H_
#define P9_IO_EREPAIRACCESSORHWPFUNCS_H_
#include <fapi2.H>
-#include <algorithm>
+#include <string.h>
+#include <p9_io_erepairConsts.H>
+#include <p9_io_erepairSetFailedLanesHwp.H>
+#include <p9_io_erepairGetFailedLanesHwp.H>
-const uint8_t EREPAIR_MAX_CENTAUR_PER_MCS = 1;
+const uint8_t EREPAIR_MAX_CENTAUR_PER_DMI = 1;
template<fapi2::TargetType K>
using getLanes_t = fapi2::ReturnCode (*)(
@@ -52,26 +54,218 @@ using setLanes_t = fapi2::ReturnCode (*)(
const std::vector<uint8_t>& o_rxFailLanes);
+/***** Function definitions *****/
+
/**
- * @brief FW Team Utility function that gets eRepair data from the VPD
- * This function gets the eRepair data from both the Field VPD
- * and the Manufacturing VPD.
+ * @brief This function determines the lane numbers that needs to be spared
+ * to support Corner testing.
*
- * @param[in] i_endp_target Reference to X-Bus or O-Bus or MCS or memBuf Target
- * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
- * @param[out] o_txFailLanes Reference to a Vector that will contain the fail
- * lanes read from the VPD for Drive side
- * @param[out] o_rxFailLanes Reference to a Vector that will contain the fail
- * lanes read from the VPD for Receive side
- * @return ReturnCode
+ * @param [in] i_tgtType The target type(XBus or OBus or DMIBus) for
+ * which the lanes that need to be spared are
+ * determined
+ * @param [out] o_endp1_txFailLanes The reference to the vector which will
+ * have the Tx side of lanes that need to be
+ * spared for endp1
+ * @param [out] o_endp1_rxFailLanes The reference to the vector which will
+ * have the Rx side of lanes that need to be
+ * spared for endp1
+ * @param [out] o_endp2_txFailLanes The reference to the vector which will
+ * have the Tx side of lanes that need to be
+ * spared for endp2
+ * @param [out] o_endp2_rxFailLanes The reference to the vector which will
+ * have the Rx side of lanes that need to be
+ * spared for endp2
*
+ * @return void
*/
template<fapi2::TargetType K>
-fapi2::ReturnCode erepairGetFailedLanes(
- const fapi2::Target < K >& i_endp_target,
- const uint8_t i_clkGroup,
- std::vector<uint8_t>& o_txFailLanes,
- std::vector<uint8_t>& o_rxFailLanes);
+void getCornerTestingLanes(
+ const fapi2::Target < K >& i_tgtType,
+ std::vector<uint8_t>& o_endp1_txFaillanes,
+ std::vector<uint8_t>& o_endp1_rxFaillanes,
+ std::vector<uint8_t>& o_endp2_txFaillanes,
+ std::vector<uint8_t>& o_endp2_rxFaillanes)
+{
+ std::vector<uint8_t>::iterator l_it;
+ uint8_t l_deployIndx = 0;
+ uint8_t l_maxDeploys = 0;
+ uint8_t* l_deployPtr = NULL;
+
+ uint8_t l_xDeployLanes[EREPAIR::XBUS_MAXSPARES_IN_HW] = {EREPAIR::XBUS_SPARE_DEPLOY_LANE_1};
+ uint8_t l_oDeployLanes[EREPAIR::OBUS_MAXSPARES_IN_HW] = {EREPAIR::OBUS_SPARE_DEPLOY_LANE_1,
+ EREPAIR::OBUS_SPARE_DEPLOY_LANE_2
+ };
+
+ uint8_t l_dmiDeployLanes[EREPAIR::DMIBUS_MAXSPARES_IN_HW] =
+ {
+ EREPAIR::DMIBUS_SPARE_DEPLOY_LANE_1,
+ EREPAIR::DMIBUS_SPARE_DEPLOY_LANE_2
+ };
+
+ // Idea is to push_back the pre-determined lanes into the Tx and Rx
+ // vectors of endpoint1 and endpoint2
+ switch(i_tgtType.getType())
+ {
+ case fapi2::TARGET_TYPE_XBUS_ENDPOINT:
+ l_maxDeploys = EREPAIR::XBUS_MAXSPARES_IN_HW;
+ l_deployPtr = l_xDeployLanes;
+ break;
+
+ case fapi2::TARGET_TYPE_OBUS:
+ l_maxDeploys = EREPAIR::OBUS_MAXSPARES_IN_HW;
+ l_deployPtr = l_oDeployLanes;
+ break;
+
+ case fapi2::TARGET_TYPE_MEMBUF_CHIP:
+ case fapi2::TARGET_TYPE_DMI:
+ l_maxDeploys = EREPAIR::DMIBUS_MAXSPARES_IN_HW;
+ l_deployPtr = l_dmiDeployLanes;
+ break;
+
+ default:
+ FAPI_ASSERT(false,
+ fapi2::P9_EREPAIR_RESTORE_INVALID_TARGET()
+ .set_TARGET(i_tgtType),
+ "ERROR:getCornerTestingLanes: Invalid target type");
+ break;
+ };
+
+ std::sort(o_endp1_txFaillanes.begin(), o_endp1_txFaillanes.end());
+
+ std::sort(o_endp1_rxFaillanes.begin(), o_endp1_rxFaillanes.end());
+
+ for(l_deployIndx = 0;
+ ((l_deployIndx < l_maxDeploys) &&
+ (o_endp1_txFaillanes.size() < l_maxDeploys));
+ l_deployIndx++)
+ {
+ l_it = std::find(o_endp1_txFaillanes.begin(),
+ o_endp1_txFaillanes.end(),
+ l_deployPtr[l_deployIndx]);
+
+ if(l_it == o_endp1_txFaillanes.end())
+ {
+ o_endp1_txFaillanes.push_back(l_deployPtr[l_deployIndx]);
+ }
+ }
+
+ for(l_deployIndx = 0;
+ ((o_endp1_rxFaillanes.size() < l_maxDeploys) &&
+ (l_deployIndx < l_maxDeploys));
+ l_deployIndx++)
+ {
+ l_it = std::find(o_endp1_rxFaillanes.begin(),
+ o_endp1_rxFaillanes.end(),
+ l_deployPtr[l_deployIndx]);
+
+ if(l_it == o_endp1_rxFaillanes.end())
+ {
+ o_endp1_rxFaillanes.push_back(l_deployPtr[l_deployIndx]);
+ }
+ }
+
+ // We can cassign the lanes of endpoint1 to endpoint2 because any
+ // existing faillanes in endpoint2 have already been matched with
+ // endpoint1. This means that there cannot be any faillanes in
+ // endpoint2 that do not have equivalent lanes in endpoint1.
+ o_endp2_txFaillanes = o_endp1_txFaillanes;
+ o_endp2_rxFaillanes = o_endp1_rxFaillanes;
+
+fapi_try_exit:
+ return;
+}
+
+/**
+ * @brief This function gets the eRepair threshold value of the passed target
+ * for the particular IPL type.
+ *
+ * @param [in] i_endp_target The target for whose type the threshold value
+ * is needed
+ * @param [in] i_mfgModeIPL If TRUE, indicates that this is a MnfgMode IPL
+ * If FALSE, indicates that this is a Normal IPL
+ * @param [out] o_threshold The threshold return value
+ *
+ * @return ReturnCode
+ */
+template<fapi2::TargetType K>
+fapi2::ReturnCode geteRepairThreshold(
+ const fapi2::Target < K >& i_endp_target,
+ const bool i_mfgModeIPL,
+ uint8_t& o_threshold)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::TargetType l_tgtType = fapi2::TARGET_TYPE_NONE;
+
+ o_threshold = 0;
+ l_tgtType = i_endp_target.getType();
+
+ if(i_mfgModeIPL)
+ {
+ switch(l_tgtType)
+ {
+ case fapi2::TARGET_TYPE_XBUS_ENDPOINT:
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_X_EREPAIR_THRESHOLD_MNFG,
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
+ o_threshold));
+ break;
+
+ case fapi2::TARGET_TYPE_OBUS:
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_O_EREPAIR_THRESHOLD_MNFG,
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
+ o_threshold));
+ break;
+
+ case fapi2::TARGET_TYPE_MEMBUF_CHIP:
+ case fapi2::TARGET_TYPE_DMI:
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_DMI_EREPAIR_THRESHOLD_MNFG,
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
+ o_threshold));
+ break;
+
+ default:
+ FAPI_ASSERT(false,
+ fapi2::P9_EREPAIR_RESTORE_INVALID_TARGET()
+ .set_TARGET(l_tgtType),
+ "ERROR:geteRepairThreshold: Invalid target type");
+ break;
+ };
+ }
+ else
+ {
+ switch(l_tgtType)
+ {
+ case fapi2::TARGET_TYPE_XBUS_ENDPOINT:
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_X_EREPAIR_THRESHOLD_FIELD,
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
+ o_threshold));
+ break;
+
+ case fapi2::TARGET_TYPE_OBUS:
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_O_EREPAIR_THRESHOLD_FIELD,
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
+ o_threshold));
+ break;
+
+ case fapi2::TARGET_TYPE_MEMBUF_CHIP:
+ case fapi2::TARGET_TYPE_DMI:
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_DMI_EREPAIR_THRESHOLD_FIELD,
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
+ o_threshold));
+ break;
+
+ default:
+ FAPI_ASSERT(false,
+ fapi2::P9_EREPAIR_RESTORE_INVALID_TARGET()
+ .set_TARGET(l_tgtType),
+ "ERROR:geteRepairThreshold: Invalid target type");
+ break;
+ };
+ }
+
+fapi_try_exit:
+ FAPI_INF("geteRepairThreshold: o_threshold = %d", o_threshold);
+ return fapi2::current_err;
+}
/**
* @brief FW Team Utility function that gets eRepair data
@@ -90,10 +284,146 @@ fapi2::ReturnCode erepairGetFailedLanes(
*/
template<fapi2::TargetType K>
fapi2::ReturnCode erepairGetFieldFailedLanes(
- const fapi2::Target < K >& i_endp_target,
+ const fapi2::Target < K >& i_endp_target,
const uint8_t i_clkGroup,
std::vector<uint8_t>& o_txFailLanes,
- std::vector<uint8_t>& o_rxFailLanes);
+ std::vector<uint8_t>& o_rxFailLanes)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_DBG(">> erepairGetFieldFailedLanes");
+
+ // Execute the Accessor HWP to retrieve the failed lanes from the VPD
+ FAPI_TRY( p9_io_erepairGetFailedLanesHwp(
+ i_endp_target,
+ EREPAIR::EREPAIR_VPD_FIELD,
+ i_clkGroup,
+ o_txFailLanes,
+ o_rxFailLanes),
+ "erepairGetFieldFailedLanes() from Accessor HWP failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/**
+ * @brief FW Team Utility function that sets eRepair data in Field VPD
+ *
+ * This is a wrapper function for the Accessor HWP which writes failed lane
+ * numbers to the Field VPD
+ *
+ * @param[in] i_endp_target Reference to X-Bus or O-Bus or MCS or memBuf Target
+ * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
+ * @param[in] i_txFailLanes Vector that will contain the fail lane
+ * to be written to Field VPD for Drive side
+ * @param[in] i_rxFailLanes Vector that will contain the fail lanes
+ * to be written to Field VPD for Receive side
+ *
+ * @return ReturnCode
+ */
+template<fapi2::TargetType K>
+fapi2::ReturnCode erepairSetFieldFailedLanes(
+ const fapi2::Target < K >& i_endp_target,
+ const uint8_t i_clkGroup,
+ const std::vector<uint8_t>& i_txFailLanes,
+ const std::vector<uint8_t>& i_rxFailLanes)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // Execute the Accessor HWP to write the fail lanes to Field VPD
+ FAPI_TRY( p9_io_erepairSetFailedLanesHwp(
+ i_endp_target,
+ EREPAIR::EREPAIR_VPD_FIELD,
+ i_clkGroup,
+ i_txFailLanes,
+ i_rxFailLanes),
+ "erepairSetFieldFailedLanes() from Accessor HWP failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/**
+ * @brief: This function reads the field VPD data to check if there is any
+ * eRepair data. This function will be called during Mnfg mode IPL
+ * during which we need to make sure that the Field VPD is clear.
+ * The Field VPD needs to be clear to enable customers to have
+ * eRepair capability.
+ *
+ * @param [in] i_endp1_target Target of one end the connecting bus
+ * @param [in] i_endp2_target Target of the other end of the connecting bus
+ * The VPD of the passed targets are read for
+ * checking the VPD contents
+ * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
+ *
+ * @return ReturnCode
+ */
+template<fapi2::TargetType K, fapi2::TargetType J>
+fapi2::ReturnCode mnfgCheckFieldVPD(
+ const fapi2::Target < K >& i_endp1_target,
+ const fapi2::Target < J >& i_endp2_target,
+ const uint8_t i_clkGroup)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ std::vector<uint8_t> l_endp1_txFaillanes;
+ std::vector<uint8_t> l_endp1_rxFaillanes;
+ std::vector<uint8_t> l_endp2_txFaillanes;
+ std::vector<uint8_t> l_endp2_rxFaillanes;
+ bool l_fieldVPDClear = true;
+
+ l_fieldVPDClear = true;
+
+ /***** Read Field VPD *****/
+
+ // During Mfg mode IPL, field VPD need to be clear.
+
+ // Get failed lanes for endp1
+ FAPI_TRY( erepairGetFieldFailedLanes(
+ i_endp1_target,
+ i_clkGroup,
+ l_endp1_txFaillanes,
+ l_endp1_rxFaillanes),
+ "erepairGetFieldFailedLanes endp1 target failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ // If there are fail lanes in Field VPD on endpoint1, create an
+ // error log and return
+ if(l_endp1_txFaillanes.size() ||
+ l_endp1_rxFaillanes.size())
+ {
+ l_fieldVPDClear = false;
+ FAPI_DBG("mnfgCheckFieldVPD: eRepair records found in Field VPD in Tx during Manufacturing mode IPL");
+ }
+
+ // Get failed lanes for endp2
+ FAPI_TRY( erepairGetFieldFailedLanes(
+ i_endp2_target,
+ i_clkGroup,
+ l_endp2_txFaillanes,
+ l_endp2_rxFaillanes),
+ "erepairGetFieldFailedLanes endp2 target failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ // If there are fail lanes in Field VPD on endpoint2, create an
+ // error log and return
+ if(l_endp2_txFaillanes.size() ||
+ l_endp2_rxFaillanes.size())
+ {
+ l_fieldVPDClear = false;
+ FAPI_DBG("mnfgCheckFieldVPD: eRepair records found in Field VPD in Rx during Manufacturing mode IPL");
+ }
+
+ FAPI_ASSERT(l_fieldVPDClear == true,
+ fapi2::P9_EREPAIR_RESTORE_FIELD_VPD_NOT_CLEAR()
+ .set_TARGET1(i_endp1_target)
+ .set_TARGET2(i_endp2_target),
+ "ERROR: mnfgCheckFieldVPD: Field VPD need to be clear during Mnfg mode IPL");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
/**
* @brief FW Team Utility function that gets eRepair data
@@ -115,7 +445,292 @@ fapi2::ReturnCode erepairGetMnfgFailedLanes(
const fapi2::Target < K >& i_endp_target,
const uint8_t i_clkGroup,
std::vector<uint8_t>& o_txFailLanes,
- std::vector<uint8_t>& o_rxFailLanes);
+ std::vector<uint8_t>& o_rxFailLanes)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_DBG(">> erepairGetMnfgFailedLanes");
+
+ // Execute the Accessor HWP to retrieve the failed lanes from the VPD
+ FAPI_TRY( p9_io_erepairGetFailedLanesHwp(
+ i_endp_target,
+ EREPAIR::EREPAIR_VPD_MNFG,
+ i_clkGroup,
+ o_txFailLanes,
+ o_rxFailLanes),
+ "erepairGetMnfgFailedLanes() from Accessor HWP failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/**
+ * @brief FW Team Utility function that sets eRepair data in Manufacturing VPD
+ *
+ * This is a wrapper function for the Accessor HWP which writes failed lane
+ * numbers to the Manufacturing VPD
+ *
+ * @param[in] i_endp_target Reference to X-Bus or O-Bus or MCS or memBuf Target
+ * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
+ * @param[in] i_txFailLanes Vector that will contain the fail lane
+ * to be written to Mnfg VPD for Drive side
+ * @param[in] i_rxFailLanes Vector that will contain the fail lanes
+ * to be written to Mnfg VPD for Receive side
+ *
+ * @return ReturnCode
+ */
+template<fapi2::TargetType K>
+fapi2::ReturnCode erepairSetMnfgFailedLanes(
+ const fapi2::Target < K >& i_endp_target,
+ const uint8_t i_clkGroup,
+ const std::vector<uint8_t>& i_txFailLanes,
+ const std::vector<uint8_t>& i_rxFailLanes)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ // Execute the Accessor HWP to write the fail lanes to Mnfg VPD
+ FAPI_TRY( p9_io_erepairSetFailedLanesHwp(
+ i_endp_target,
+ EREPAIR::EREPAIR_VPD_MNFG,
+ i_clkGroup,
+ i_txFailLanes,
+ i_rxFailLanes),
+ "erepairSetMnfgFailedLanes() from Accessor HWP failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/**
+ * @brief: This Function reads the specified VPD (Mnfg or Field) of the passed
+ * targets and verifies whether there are matching eRepair records.
+ * The matching eRepair lanes are returned in the passed references
+ * for vectors.
+ *
+ * @param [in] i_endp1_target Target of one end the connecting bus
+ * @param [in] i_endp2_target Target of the other end of the connecting
+ * bus
+ * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
+ * @param [out] o_endp1_txFaillanes Reference to vector which will have fail
+ * lane numbers on Tx side of target passed
+ * as first param
+ * @param [out] o_endp1_rxFaillanes Reference to vector which will have fail
+ * lane numbers on Rx side of target passed
+ * as first param
+ * @param [out] o_endp2_txFaillanes Reference to vector which will have fail
+ * lane numbers on Tx side of target passed
+ * as fourth param
+ * @param [out] o_endp2_rxFaillanes Reference to vector which will have fail
+ * lane numbers on Rx side of target passed
+ * as fourth param
+ * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
+ * @param [in] i_vpdType Indicates whether to read Mnfg VPD or
+ * Field VPD
+ *
+ * @return ReturnCode
+ */
+template<fapi2::TargetType K, fapi2::TargetType J>
+fapi2::ReturnCode getVerifiedRepairLanes(
+ const fapi2::Target < K >& i_endp1_target,
+ const fapi2::Target < J >& i_endp2_target,
+ const uint8_t i_clkGroup,
+ std::vector<uint8_t>& o_endp1_txFaillanes,
+ std::vector<uint8_t>& o_endp1_rxFaillanes,
+ std::vector<uint8_t>& o_endp2_txFaillanes,
+ std::vector<uint8_t>& o_endp2_rxFaillanes,
+ const EREPAIR::erepairVpdType i_vpdType)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ getLanes_t<K> l_getLanes = NULL;
+ setLanes_t<K> l_setLanes = NULL;
+
+ fapi2::Target < K > l_target[2] = {i_endp1_target, i_endp2_target};
+ bool l_invalidFails_inTx_OfTgt[2] = {false, false};
+ bool l_invalidFails_inRx_OfTgt[2] = {false, false};
+ uint8_t l_tgtIndx = 0;
+
+ std::vector<uint8_t> l_emptyVector;
+ std::vector<uint8_t> l_txFaillanes;
+ std::vector<uint8_t> l_rxFaillanes;
+
+ FAPI_INF(">> getVerifiedRepairLanes: vpdType: %s",
+ i_vpdType == EREPAIR::EREPAIR_VPD_FIELD ? "Field" : "Mnfg");
+
+ /***** Read VPD *****/
+
+ if(i_vpdType == EREPAIR::EREPAIR_VPD_FIELD)
+ {
+ l_getLanes = &erepairGetFieldFailedLanes;
+ l_setLanes = &erepairSetFieldFailedLanes;
+ }
+ else if(i_vpdType == EREPAIR::EREPAIR_VPD_MNFG)
+ {
+ l_getLanes = &erepairGetMnfgFailedLanes;
+ l_setLanes = &erepairSetMnfgFailedLanes;
+ }
+
+ for(l_tgtIndx = 0; l_tgtIndx < 2; l_tgtIndx++)
+ {
+ // Get failed lanes for endp1 and endp2
+ FAPI_TRY( l_getLanes(
+ l_target[l_tgtIndx],
+ i_clkGroup,
+ l_txFaillanes,
+ l_rxFaillanes),
+ "getVerifiedRepairLanes() from Accessor HWP failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ if(l_tgtIndx == 0)
+ {
+ o_endp1_txFaillanes = l_txFaillanes;
+ o_endp1_rxFaillanes = l_rxFaillanes;
+ }
+ else
+ {
+ o_endp2_txFaillanes = l_txFaillanes;
+ o_endp2_rxFaillanes = l_rxFaillanes;
+ }
+
+ l_txFaillanes.clear();
+ l_rxFaillanes.clear();
+ } // end of for(l_tgtIndx)
+
+ // Check if matching fail lanes exists on the sub-interfaces
+ // connecting the two end points
+ if(o_endp1_txFaillanes.size() || o_endp2_rxFaillanes.size())
+ {
+ invalidateNonMatchingFailLanes(o_endp1_txFaillanes,
+ o_endp2_rxFaillanes,
+ l_invalidFails_inTx_OfTgt[0],
+ l_invalidFails_inRx_OfTgt[1]);
+ }
+
+ if(o_endp2_txFaillanes.size() || o_endp1_rxFaillanes.size())
+ {
+ invalidateNonMatchingFailLanes(o_endp2_txFaillanes,
+ o_endp1_rxFaillanes,
+ l_invalidFails_inTx_OfTgt[1],
+ l_invalidFails_inRx_OfTgt[0]);
+ }
+
+ /***** Correct eRepair data of endp1 in VPD *****/
+
+ for(l_tgtIndx = 0; l_tgtIndx < 2; l_tgtIndx++)
+ {
+ if(l_tgtIndx == 0)
+ {
+ l_txFaillanes = o_endp1_txFaillanes;
+ l_rxFaillanes = o_endp1_rxFaillanes;
+ }
+ else
+ {
+ l_txFaillanes = o_endp2_txFaillanes;
+ l_rxFaillanes = o_endp2_rxFaillanes;
+ }
+
+ // Update endp1 and endp2 VPD to invalidate fail lanes that do
+ // not have matching fail lanes on the other end
+ if(l_invalidFails_inTx_OfTgt[l_tgtIndx] &&
+ l_invalidFails_inRx_OfTgt[l_tgtIndx])
+ {
+ FAPI_TRY( l_setLanes(
+ l_target[l_tgtIndx],
+ i_clkGroup,
+ l_txFaillanes,
+ l_rxFaillanes),
+ "getVerifiedRepairLanes() tx/rx from Accessor HWP failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ }
+ else if(l_invalidFails_inTx_OfTgt[l_tgtIndx])
+ {
+ FAPI_TRY( l_setLanes(
+ l_target[l_tgtIndx],
+ i_clkGroup,
+ l_txFaillanes,
+ l_emptyVector),
+ "getVerifiedRepairLanes() tx from Accessor HWP failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ }
+ else if(l_invalidFails_inRx_OfTgt[l_tgtIndx])
+ {
+ FAPI_TRY( l_setLanes(
+ l_target[l_tgtIndx],
+ i_clkGroup,
+ l_emptyVector,
+ l_rxFaillanes),
+ "getVerifiedRepairLanes() rx from Accessor HWP failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ }
+ } // end of for loop
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/**
+ * @brief FW Team Utility function that gets eRepair data from the VPD
+ * This function gets the eRepair data from both the Field VPD
+ * and the Manufacturing VPD.
+ *
+ * @param[in] i_endp_target Reference to X-Bus or O-Bus or MCS or memBuf Target
+ * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
+ * @param[out] o_txFailLanes Reference to a Vector that will contain the fail
+ * lanes read from the VPD for Drive side
+ * @param[out] o_rxFailLanes Reference to a Vector that will contain the fail
+ * lanes read from the VPD for Receive side
+ * @return ReturnCode
+ *
+ */
+template<fapi2::TargetType K>
+fapi2::ReturnCode erepairGetFailedLanes(
+ const fapi2::Target < K >& i_endp_target,
+ const uint8_t i_clkGroup,
+ std::vector<uint8_t>& o_txFailLanes,
+ std::vector<uint8_t>& o_rxFailLanes)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ std::vector<uint8_t> l_txFailLanes;
+ std::vector<uint8_t> l_rxFailLanes;
+ std::vector<uint8_t>::iterator l_it;
+
+ FAPI_INF(">> erepairGetFailedLaness");
+
+ // Get the erepair lanes from Field VPD
+ FAPI_TRY( erepairGetFieldFailedLanes(
+ i_endp_target,
+ i_clkGroup,
+ l_txFailLanes,
+ l_rxFailLanes),
+ "erepairGetFieldFailedLanes() failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ o_txFailLanes = l_txFailLanes;
+ o_rxFailLanes = l_rxFailLanes;
+
+ // Get the erepair lanes from Manufacturing VPD
+ l_txFailLanes.clear();
+ l_rxFailLanes.clear();
+ FAPI_TRY( erepairGetMnfgFailedLanes(
+ i_endp_target,
+ i_clkGroup,
+ l_txFailLanes,
+ l_rxFailLanes),
+ "erepairGetMnfgFailedLanes() failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ // Merge the Mnfg lanes with the Field lanes
+ l_it = o_txFailLanes.end();
+ o_txFailLanes.insert(l_it, l_txFailLanes.begin(), l_txFailLanes.end());
+
+ l_it = o_rxFailLanes.end();
+ o_rxFailLanes.insert(l_it, l_rxFailLanes.begin(), l_rxFailLanes.end());
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
/**
* @brief FW Team Utility function that sets eRepair data in the VPD.
@@ -131,9 +746,9 @@ fapi2::ReturnCode erepairGetMnfgFailedLanes(
* @param[in] i_rxEndp_target Reference to X-Bus or O-Bus or MCS or memBuf
* Target. This is the target on which the
* badlanes were found
+ * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
* @param[in] i_rxFailLanes Vector that will contain the fail lanes
* to be written to VPD for Receive side
- * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
* @param[out] o_thresholdExceed If TRUE, indicates that the eRepair threshold
* has exceeded, FALSE otherwise.
*
@@ -145,51 +760,137 @@ fapi2::ReturnCode erepairSetFailedLanes(
const fapi2::Target < J >& i_rxEndp_target,
const uint8_t i_clkGroup,
const std::vector<uint8_t>& i_rxFailLanes,
- bool& o_thresholdExceed);
+ bool& o_thresholdExceed)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ uint64_t l_allMnfgFlags = 0;
+ bool l_mnfgModeIPL = false;
+ uint8_t l_threshold = 0;
+ setLanes_t<K> l_setLanes = NULL;
+ getLanes_t<K> l_getLanes = NULL;
+ std::vector<uint8_t> l_txFaillanes;
+ std::vector<uint8_t> l_rxFaillanes;
+ std::vector<uint8_t> l_emptyVector;
+ std::vector<uint8_t> l_throwAway;
-/**
- * @brief FW Team Utility function that sets eRepair data in Field VPD
- *
- * This is a wrapper function for the Accessor HWP which writes failed lane
- * numbers to the Field VPD
- *
- * @param[in] i_endp_target Reference to X-Bus or O-Bus or MCS or memBuf Target
- * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
- * @param[in] i_txFailLanes Vector that will contain the fail lane
- * to be written to Field VPD for Drive side
- * @param[in] i_rxFailLanes Vector that will contain the fail lanes
- * to be written to Field VPD for Receive side
- *
- * @return ReturnCode
- */
-template<fapi2::TargetType K>
-fapi2::ReturnCode erepairSetFieldFailedLanes(
- const fapi2::Target < K >& i_endp_target,
- const uint8_t i_clkGroup,
- const std::vector<uint8_t>& i_txFailLanes,
- const std::vector<uint8_t>& i_rxFailLanes);
+ FAPI_INF(">> erepairSetFailedLanes");
-/**
- * @brief FW Team Utility function that sets eRepair data in Manufacturing VPD
- *
- * This is a wrapper function for the Accessor HWP which writes failed lane
- * numbers to the Manufacturing VPD
- *
- * @param[in] i_endp_target Reference to X-Bus or O-Bus or MCS or memBuf Target
- * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
- * @param[in] i_txFailLanes Vector that will contain the fail lane
- * to be written to Mnfg VPD for Drive side
- * @param[in] i_rxFailLanes Vector that will contain the fail lanes
- * to be written to Mnfg VPD for Receive side
- *
- * @return ReturnCode
- */
-template<fapi2::TargetType K>
-fapi2::ReturnCode erepairSetMnfgFailedLanes(
- const fapi2::Target < K >& i_endp_target,
- const uint8_t i_clkGroup,
- const std::vector<uint8_t>& i_txFailLanes,
- const std::vector<uint8_t>& i_rxFailLanes);
+ o_thresholdExceed = false;
+
+ // Get the Manufacturing Policy flags
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MNFG_FLAGS,
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
+ l_allMnfgFlags),
+ "erepairSetFailedLanes: Unable to read attribute ATTR_MNFG_FLAGS");
+
+ // Check if this is a Mnfg mode IPL
+ if(l_allMnfgFlags & fapi2::ENUM_ATTR_MNFG_FLAGS_MNFG_THRESHOLDS)
+ {
+ l_mnfgModeIPL = true;
+ }
+
+ if(l_mnfgModeIPL)
+ {
+ l_setLanes = &erepairSetMnfgFailedLanes;
+ l_getLanes = &erepairGetMnfgFailedLanes;
+ }
+ else
+ {
+ l_setLanes = &erepairSetFieldFailedLanes;
+ l_getLanes = &erepairGetFieldFailedLanes;
+ }
+
+ /*** Check if we have crossed the repair threshold ***/
+ // Get the eRepair threshold limit
+ l_threshold = 0;
+ FAPI_TRY( geteRepairThreshold(
+ i_rxEndp_target,
+ l_mnfgModeIPL,
+ l_threshold),
+ "geteRepairThreshold() from Accessor HWP failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ // Check if the new fails have crossed the threshold
+ if(i_rxFailLanes.size() > l_threshold)
+ {
+ o_thresholdExceed = true;
+ goto fapi_try_exit;
+ }
+
+ // Get existing fail lanes that are in the VPD of rx endpoint
+ FAPI_TRY( l_getLanes(
+ i_rxEndp_target,
+ i_clkGroup,
+ l_throwAway,
+ l_rxFaillanes),
+ "rx l_getLanes() from Accessor HWP failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ // Get existing fail lanes that are in the VPD of tx endpoint
+ FAPI_TRY( l_getLanes(
+ i_txEndp_target,
+ i_clkGroup,
+ l_txFaillanes,
+ l_throwAway),
+ "tx l_getLanes() from Accessor HWP failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ // Lets combine the new and old fail lanes of Rx side
+ l_rxFaillanes.insert(l_rxFaillanes.end(),
+ i_rxFailLanes.begin(),
+ i_rxFailLanes.end());
+
+ // Remove duplicate lanes if any on the Rx side
+ std::sort(l_rxFaillanes.begin(), l_rxFaillanes.end());
+
+ l_rxFaillanes.erase(std::unique(l_rxFaillanes.begin(),
+ l_rxFaillanes.end()),
+ l_rxFaillanes.end());
+
+ // Lets combine the new and old fail lanes of Tx side
+ l_txFaillanes.insert(l_txFaillanes.end(),
+ i_rxFailLanes.begin(),
+ i_rxFailLanes.end());
+
+ // Remove duplicate lanes if any on the Tx side
+ std::sort(l_txFaillanes.begin(), l_txFaillanes.end());
+
+ l_txFaillanes.erase(std::unique(l_txFaillanes.begin(),
+ l_txFaillanes.end()),
+ l_txFaillanes.end());
+
+ // Check if the sum of old and new fail lanes have crossed the threshold
+ if((l_txFaillanes.size() > l_threshold) ||
+ (l_rxFaillanes.size() > l_threshold))
+ {
+ o_thresholdExceed = true;
+ goto fapi_try_exit;
+ }
+
+ /*** Update the VPD ***/
+
+ // Lets write the VPD of endpoint1 with faillanes on Rx side
+ FAPI_TRY( l_setLanes(
+ i_rxEndp_target,
+ i_clkGroup,
+ l_emptyVector,
+ l_rxFaillanes),
+ "rx l_setLanes() from Accessor HWP failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ // Lets write the VPD of endpoint2 with faillanes on Tx side
+ FAPI_TRY( l_setLanes(
+ i_txEndp_target,
+ i_clkGroup,
+ l_txFaillanes,
+ l_emptyVector),
+ "tx l_setLanes() from Accessor HWP failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+fapi_try_exit:
+ FAPI_INF("<< erepairSetFailedLanes");
+ return fapi2::current_err;
+}
/**
* @brief Function which retrieves the lanes that need to be restored for the
@@ -233,9 +934,294 @@ fapi2::ReturnCode erepairGetRestoreLanes(
const fapi2::Target < K >& i_endp1_target,
const fapi2::Target < J >& i_endp2_target,
const uint8_t i_clkGroup,
- std::vector<uint8_t>& o_endp1_txFaillanes,
- std::vector<uint8_t>& o_endp1_rxFaillanes,
- std::vector<uint8_t>& o_endp2_txFaillanes,
- std::vector<uint8_t>& o_endp2_rxFaillanes);
+ std::vector<uint8_t>& o_endp1_txFaillanes,
+ std::vector<uint8_t>& o_endp1_rxFaillanes,
+ std::vector<uint8_t>& o_endp2_txFaillanes,
+ std::vector<uint8_t>& o_endp2_rxFaillanes)
+{
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ std::vector<uint8_t> l_endp1_txFieldFaillanes;
+ std::vector<uint8_t> l_endp1_rxFieldFaillanes;
+ std::vector<uint8_t> l_endp1_txMnfgFaillanes;
+ std::vector<uint8_t> l_endp1_rxMnfgFaillanes;
+
+ std::vector<uint8_t> l_endp2_txFieldFaillanes;
+ std::vector<uint8_t> l_endp2_rxFieldFaillanes;
+ std::vector<uint8_t> l_endp2_txMnfgFaillanes;
+ std::vector<uint8_t> l_endp2_rxMnfgFaillanes;
+
+ bool l_mnfgModeIPL = false;
+ bool l_enableDmiSpares = false;
+ bool l_enableFabricSpares = false;
+ bool l_disableFabricERepair = false;
+ bool l_disableMemoryERepair = false;
+ bool l_thresholdExceed = false;
+ uint8_t l_threshold = 0;
+ uint64_t l_allMnfgFlags = 0;
+ uint32_t l_numTxFailLanes = 0;
+ uint32_t l_numRxFailLanes = 0;
+ fapi2::TargetType l_endp1_tgtType = fapi2::TARGET_TYPE_NONE;
+ fapi2::TargetType l_endp2_tgtType = fapi2::TARGET_TYPE_NONE;
+
+ FAPI_INF(">>erepairGetRestoreLanes");
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MNFG_FLAGS,
+ fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
+ l_allMnfgFlags));
+
+ // Check if MNFG_DISABLE_FABRIC_EREPAIR is enabled
+ l_disableFabricERepair = false;
+
+ if(l_allMnfgFlags &
+ fapi2::ENUM_ATTR_MNFG_FLAGS_MNFG_DISABLE_FABRIC_eREPAIR)
+ {
+ l_disableFabricERepair = true;
+ }
+
+ // Check if MNFG_DISABLE_MEMORY_EREPAIR is enabled
+ l_disableMemoryERepair = false;
+
+ if(l_allMnfgFlags &
+ fapi2::ENUM_ATTR_MNFG_FLAGS_MNFG_DISABLE_MEMORY_eREPAIR)
+ {
+ l_disableMemoryERepair = true;
+ }
+
+ // Check if this is Manufacturing mode IPL.
+ l_mnfgModeIPL = false;
+
+ if(l_allMnfgFlags & fapi2::ENUM_ATTR_MNFG_FLAGS_MNFG_THRESHOLDS)
+ {
+ l_mnfgModeIPL = true;
+ }
+
+ // Get the type of passed targets
+ l_endp1_tgtType = i_endp1_target.getType();
+ l_endp2_tgtType = i_endp2_target.getType();
+
+ // Check if the correct target types are passed
+ if(l_endp1_tgtType == fapi2::TARGET_TYPE_XBUS_ENDPOINT ||
+ l_endp1_tgtType == fapi2::TARGET_TYPE_OBUS)
+ {
+ FAPI_ASSERT(l_endp1_tgtType == l_endp2_tgtType,
+ fapi2::P9_EREPAIR_RESTORE_INVALID_TARGET_PAIR()
+ .set_TARGET1(l_endp1_tgtType)
+ .set_TARGET2(l_endp2_tgtType),
+ "ERROR:erepairGetRestoreLanes: Invalid endpoint target pair");
+
+ // Check for enablement of Fabric eRepair
+ if(l_mnfgModeIPL && l_disableFabricERepair)
+ {
+ // Fabric eRepair has been disabled using the
+ // Manufacturing policy flags
+ FAPI_INF("erepairGetRestoreLanes: Fabric eRepair is disabled");
+ goto fapi_try_exit;
+ }
+ }
+ else if(l_endp1_tgtType == fapi2::TARGET_TYPE_MEMBUF_CHIP ||
+ l_endp1_tgtType == fapi2::TARGET_TYPE_DMI)
+ {
+ FAPI_ASSERT( ((l_endp1_tgtType == fapi2::TARGET_TYPE_MEMBUF_CHIP) &&
+ (l_endp2_tgtType == fapi2::TARGET_TYPE_DMI)) ||
+ ((l_endp1_tgtType == fapi2::TARGET_TYPE_DMI) &&
+ (l_endp2_tgtType == fapi2::TARGET_TYPE_MEMBUF_CHIP)),
+ fapi2::P9_EREPAIR_RESTORE_INVALID_TARGET_PAIR()
+ .set_TARGET1(l_endp1_tgtType)
+ .set_TARGET2(l_endp2_tgtType),
+ "ERROR:erepairGetRestoreLanes: Invalid endpoint target pair");
+
+ // Check for enablement of Memory eRepair
+ if(l_mnfgModeIPL && l_disableMemoryERepair)
+ {
+ // Memory eRepair has been disabled using the
+ // Manufacturing policy flags
+ FAPI_INF("erepairGetRestoreLanes: Memory eRepair is disabled");
+ goto fapi_try_exit;
+ }
+ }
+
+ if(l_mnfgModeIPL)
+ {
+ /***** Check Field VPD *****/
+
+ // Do not allow eRepair data in Field VPD during Mfg Mode IPL
+ l_rc = mnfgCheckFieldVPD(i_endp1_target,
+ i_endp2_target,
+ i_clkGroup);
+
+ if(l_rc)
+ {
+ FAPI_DBG("erepairGetRestoreLanes:Error from mnfgCheckFieldVPD");
+ fapi2::current_err = l_rc;
+ goto fapi_try_exit;
+ }
+
+ /***** Read Manufacturing VPD *****/
+ FAPI_TRY( getVerifiedRepairLanes(
+ i_endp1_target,
+ i_endp2_target,
+ i_clkGroup,
+ o_endp1_txFaillanes,
+ o_endp1_rxFaillanes,
+ o_endp2_txFaillanes,
+ o_endp2_rxFaillanes,
+ EREPAIR::EREPAIR_VPD_MNFG),
+ "getVerifiedRepairLanes(Mnfg) mnfg mode ipl failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ }
+ else
+ {
+ /***** Normal Mode IPL *****/
+ // During Normal mode IPL we read both Mnfg and Field VPD
+ // for restoring eRepair lanes
+
+ /***** Read Manufacturing VPD *****/
+ FAPI_TRY( getVerifiedRepairLanes(
+ i_endp1_target,
+ i_endp2_target,
+ i_clkGroup,
+ l_endp1_txMnfgFaillanes,
+ l_endp1_rxMnfgFaillanes,
+ l_endp2_txMnfgFaillanes,
+ l_endp2_rxMnfgFaillanes,
+ EREPAIR::EREPAIR_VPD_MNFG),
+ "getVerifiedRepairLanes(Mnfg) normal mode ipl failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ /***** Read Field VPD *****/
+ FAPI_TRY( getVerifiedRepairLanes(
+ i_endp1_target,
+ i_endp2_target,
+ i_clkGroup,
+ l_endp1_txFieldFaillanes,
+ l_endp1_rxFieldFaillanes,
+ l_endp2_txFieldFaillanes,
+ l_endp2_rxFieldFaillanes,
+ EREPAIR::EREPAIR_VPD_FIELD),
+ "getVerifiedRepairLanes(Field) normal mode ipl failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ /***** Combine the Mnfg and Field eRepair lanes *****/
+
+ // Combine the Tx side fail lanes of endp1
+ combineFieldandMnfgLanes(l_endp1_txMnfgFaillanes,
+ l_endp1_txFieldFaillanes,
+ o_endp1_txFaillanes);
+
+ // Combine the Rx side fail lanes of endp1
+ combineFieldandMnfgLanes(l_endp1_rxMnfgFaillanes,
+ l_endp1_rxFieldFaillanes,
+ o_endp1_rxFaillanes);
+
+ // Combine the Tx side fail lanes of endp2
+ combineFieldandMnfgLanes(l_endp2_txMnfgFaillanes,
+ l_endp2_txFieldFaillanes,
+ o_endp2_txFaillanes);
+
+ // Combine the Rx side fail lanes of endp1
+ combineFieldandMnfgLanes(l_endp2_rxMnfgFaillanes,
+ l_endp2_rxFieldFaillanes,
+ o_endp2_rxFaillanes);
+
+ } // end of else block of "if(l_mnfgModeIPL)"
+
+
+ /***** Check for threshold exceed conditions *****/
+
+ // Get the eRepair threshold limit
+ l_threshold = 0;
+ FAPI_TRY( geteRepairThreshold(
+ i_endp1_target,
+ l_mnfgModeIPL,
+ l_threshold),
+ "geteRepairThreshold() failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ // Check if the eRepair threshold has exceeded for Tx side of endp1
+ if(o_endp1_txFaillanes.size() > l_threshold)
+ {
+ l_thresholdExceed = true;
+ l_numTxFailLanes = o_endp1_txFaillanes.size();
+
+ FAPI_DBG("erepairGetRestoreLanes: eRepair threshold exceed error"
+ " seen in Tx of endp1 target. No.of lanes: %d", l_numTxFailLanes);
+ }
+
+ // Check if the eRepair threshold has exceeded for Rx side of endp1
+ if(o_endp1_rxFaillanes.size() > l_threshold)
+ {
+ l_thresholdExceed = true;
+ l_numRxFailLanes = o_endp1_rxFaillanes.size();
+
+ FAPI_DBG("erepairGetRestoreLanes: eRepair threshold exceed error"
+ " seen in Rx of endp1 target. No.of lanes: %d", l_numRxFailLanes);
+ }
+
+ // Check if the eRepair threshold has exceeded for Tx side of endp2
+ if(o_endp2_txFaillanes.size() > l_threshold)
+ {
+ l_thresholdExceed = true;
+ l_numTxFailLanes = o_endp2_txFaillanes.size();
+
+ FAPI_DBG("erepairGetRestoreLanes: eRepair threshold exceed error"
+ " seen in Tx of endp2 target. No.of lanes: %d",
+ l_numTxFailLanes);
+ }
+
+ // Check if the eRepair threshold has exceeded for Rx side of endp2
+ if(o_endp2_rxFaillanes.size() > l_threshold)
+ {
+ l_thresholdExceed = true;
+ l_numRxFailLanes = o_endp2_rxFaillanes.size();
+
+ FAPI_DBG("erepairGetRestoreLanes: eRepair threshold exceed error"
+ " seen in Rx of endp2 target. No.of lanes: %d",
+ l_numRxFailLanes);
+ }
+
+ FAPI_ASSERT(l_thresholdExceed == false,
+ fapi2::P9_EREPAIR_THRESHOLD_EXCEED()
+ .set_TX_NUM_LANES(l_numTxFailLanes)
+ .set_RX_NUM_LANES(l_numTxFailLanes)
+ .set_THRESHOLD(l_threshold),
+ "ERROR:The threshold limit for eRepair has been crossed");
+
+ if(l_mnfgModeIPL)
+ {
+ // Check if MNFG_DMI_DEPLOY_LANE_SPARES is enabled
+ l_enableDmiSpares = false;
+
+ if(l_allMnfgFlags &
+ fapi2::ENUM_ATTR_MNFG_FLAGS_MNFG_DMI_DEPLOY_LANE_SPARES)
+ {
+ l_enableDmiSpares = true;
+ }
+
+ // Check if MNFG_FABRIC_DEPLOY_LANE_SPARES is enabled
+ l_enableFabricSpares = false;
+
+ if(l_allMnfgFlags &
+ fapi2::ENUM_ATTR_MNFG_FLAGS_MNFG_FABRIC_DEPLOY_LANE_SPARES)
+ {
+ l_enableFabricSpares = true;
+ }
+
+ if(l_enableDmiSpares || l_enableFabricSpares)
+ {
+ // This is a Corner testing IPL.
+ // eRepair Restore the pre-determined memory lanes
+ getCornerTestingLanes(i_endp1_target,
+ o_endp1_txFaillanes,
+ o_endp1_rxFaillanes,
+ o_endp2_txFaillanes,
+ o_endp2_rxFaillanes);
+ }
+ } // end of if(l_mnfgModeIPL)
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
#endif
diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_erepairConsts.H b/src/import/chips/p9/procedures/hwp/io/p9_io_erepairConsts.H
index 024beab69..134714929 100755
--- a/src/import/chips/p9/procedures/hwp/io/p9_io_erepairConsts.H
+++ b/src/import/chips/p9/procedures/hwp/io/p9_io_erepairConsts.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -174,4 +174,46 @@ struct eRepairMemBus
uint32_t failBit : 24; // Bit stream value: Bit 0:Lane 0; Bit 1:Lane 1 ...
};
+/**
+ * @brief This function combines the eRepair lane numbers read from
+ * Manufacturing VPD and Field VPD
+ *
+ * @param [in] i_mnfgFaillanes The eRepair lane numbers read from the
+ * Manufacturing VPD
+ * @param [in] i_fieldFaillanes The eRepair lane numbers read from the
+ * Field VPD
+ * @param [out] o_allFaillanes The eRepair lane numbers which is the union
+ * of the Field and Manufacturing eRepair lanes
+ * passed as first iand second params
+ *
+ * @return void
+ */
+void combineFieldandMnfgLanes(std::vector<uint8_t>& i_mnfgFaillanes,
+ std::vector<uint8_t>& i_fieldFaillanes,
+ std::vector<uint8_t>& o_allFailLanes);
+
+
+/**
+ * @brief This function checks to see if the passed vectors have matching
+ * fail lane numbers. If no matching lane number is found, such lane
+ * value will be invalidated in the vector
+ *
+ * @param [in] io_endp1_txFaillanes Reference to vector which has fail
+ * lane numbers of Tx side
+ * @param [in] io_endp2_rxFaillanes Reference to vector which has fail
+ * lane numbers of Rx side
+ * @param [out] o_invalidFails_inTx_Ofendp1 If TRUE, indicates that Tx has fail
+ * lane numbers for which there is no
+ * matching entry on Rx side
+ * @param [out] o_invalidFails_inRx_Ofendp2 If TRUE, indicates that Tx has fail
+ * lane numbers for which there is no
+ * matching entry on Tx side
+ *
+ * @return void
+ */
+void invalidateNonMatchingFailLanes(std::vector<uint8_t>& io_endp1_txFaillanes,
+ std::vector<uint8_t>& io_endp2_rxFaillanes,
+ bool& o_invalidFails_inTx_Ofendp1,
+ bool& o_invalidFails_inRx_Ofendp2);
+
#endif
diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_erepairGetFailedLanesHwp.C b/src/import/chips/p9/procedures/hwp/io/p9_io_erepairGetFailedLanesHwp.C
deleted file mode 100755
index 8f89f58ec..000000000
--- a/src/import/chips/p9/procedures/hwp/io/p9_io_erepairGetFailedLanesHwp.C
+++ /dev/null
@@ -1,688 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/io/p9_io_erepairGetFailedLanesHwp.C $ */
-/* */
-/* 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 */
-///
-/// @file p9_io_erepairGetFailedLanesHwp.C
-/// @brief FW Team HWP that accesses the fail lanes of Fabric and Memory buses.
-///
-//----------------------------------------------------------------------------
-// *HWP HWP Owner : Chris Steffen <cwsteffen@us.ibm.com>
-// *HWP HWP Backup Owner: Gary Peterson <garyp@us.ibm.com>
-// *HWP FW Owner : Sumit Kumar <sumit_kumar@in.ibm.com>
-// *HWP Team : IO
-// *HWP Level : 2
-// *HWP Consumed by : FSP:HB
-//----------------------------------------------------------------------------
-#include <fapi2.H>
-#include <p9_io_erepairConsts.H>
-#include <p9_io_erepairGetFailedLanesHwp.H>
-#include <mvpd_access.H>
-
-using namespace EREPAIR;
-using namespace fapi2;
-
-/******************************************************************************
- * Forward Declarations
- *****************************************************************************/
-
-/**
- * @brief Function called by the FW Team HWP that reads the data from Field VPD.
- * This function makes the actual calls to read the VPD
- * It determines the size of the buffer to be read, allocates memory
- * of the determined size, calls fapiGetMvpdField to read the eRepair
- * records. This buffer is further passed to another routine for
- * parsing.
- *
- * @param[in] i_target Reference to X-Bus or O-Bus or MCS target
- * @param[in] i_vpdType Specifies which VPD (MNFG or Field) to access.
- * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
- * @param[o] o_txFailLanes Reference to a vector that will hold eRepair fail
- * lane numbers of the Tx sub-interface.
- * @param[o] o_rxFailLanes Reference to a vector that will hold eRepair fail
- * lane numbers of the Rx sub-interface.
- *
- * @return ReturnCode
- */
-template<fapi2::TargetType K>
-fapi2::ReturnCode retrieveRepairData(
- const fapi2::Target < K >& i_target,
- erepairVpdType i_vpdType,
- const uint8_t i_clkGroup,
- std::vector<uint8_t>& o_txFailLanes,
- std::vector<uint8_t>& o_rxFailLanes);
-
-/**
- * @brief Function called by the FW Team HWP that parses the data read from
- * Field VPD. This function matches each eRepair record read from the VPD
- * and matches it against the attributes of the passed target.
- * If a match is found, the corresponding eRepair record is copied into
- * the respective failLane vectors to be returned to the caller.
- *
- * @param[in] i_target Reference to X-Bus or O-Bus or MCS target
- * @param[in] i_buf This is the buffer that has the eRepair records
- * read from the VPD
- * @param[in] i_bufSz This is the size of passed buffer in terms of bytes
- * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
- * @param[o] o_txFailLanes Reference to a vector that will hold eRepair fail
- * lane numbers of the Tx sub-interface.
- * @param[o] o_rxFailLanes Reference to a vector that will hold eRepair fail
- * lane numbers of the Rx sub-interface.
- *
- * @return ReturnCode
- */
-template<fapi2::TargetType K>
-fapi2::ReturnCode determineRepairLanes(
- const fapi2::Target < K >& i_target,
- uint8_t* i_buf,
- uint32_t i_bufSz,
- const uint8_t i_clkGroup,
- std::vector<uint8_t>& o_txFailLanes,
- std::vector<uint8_t>& o_rxFailLanes);
-
-
-/**
- * @brief Function to check if the system has Custom DIMM type (CDIMM).
- * Attribute ATTR_EFF_CUSTOM_DIMM is read to determine the type.
- * @param[in] i_target Reference to X-Bus or O-Bus or MCS target
- * @param[o] o_customDimm Return value - ENUM_ATTR_EFF_CUSTOM_DIMM_NO
- * or ENUM_ATTR_EFF_CUSTOM_DIMM_YES
- * @return ReturnCode
- */
-template<fapi2::TargetType K>
-fapi2::ReturnCode getDimmType(
- const fapi2::Target < K >& i_target,
- uint8_t& o_customDimm);
-
-
-/**
- * @brief Function called by the HWP that parses the data read from VPD.
- * This function scans through failBit field bit pattern and checks
- * for all bits that are set. For bits SET the corresponding bit positions
- * marks the failed lane number and is copied into
- * the respective failLane vectors to be returned to the caller.
- *
- * @param[in] i_target Reference to X-Bus or O-Bus or MCS target type
- * @param[in] i_busInterface Reference to target sub interface
- * @param[in] i_failBit This is the failBit field from the eRepair records
- * read from the VPD
- * @param[o] o_FailLanes Reference to a vector that will hold eRepair fail
- * lane numbers of the Rx/Tx sub-interface.
- *
- * @return ReturnCode
- */
-template<fapi2::TargetType K>
-fapi2::ReturnCode decodeFailedLanes(
- const fapi2::Target < K >& i_target,
- uint8_t i_busInterface,
- uint32_t i_failBit,
- std::vector<uint8_t>& o_FailLanes);
-
-/******************************************************************************
- * Accessor HWP
- *****************************************************************************/
-
-template<fapi2::TargetType K>
-fapi2::ReturnCode p9_io_erepairGetFailedLanesHwp(
- const fapi2::Target < K >& i_target,
- erepairVpdType i_vpdType,
- const uint8_t i_clkGroup,
- std::vector<uint8_t>& o_txFailLanes,
- std::vector<uint8_t>& o_rxFailLanes)
-{
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- FAPI_INF(">> erepairGetFailedLanesHwp");
-
- o_txFailLanes.clear();
- o_rxFailLanes.clear();
-
- // Retrieve the Field eRepair lane numbers from the VPD
- FAPI_TRY( retrieveRepairData(
- i_target,
- i_vpdType,
- i_clkGroup,
- o_txFailLanes,
- o_rxFailLanes),
- "p9_io_erepairGetFailedLanesHwp() failed w/rc=0x%x",
- (uint64_t)current_err );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-template ReturnCode p9_io_erepairGetFailedLanesHwp<TARGET_TYPE_XBUS>(
- const fapi2::Target <TARGET_TYPE_XBUS>& i_target,
- erepairVpdType i_vpdType,
- const uint8_t i_clkGroup,
- std::vector<uint8_t>& o_txFailLanes,
- std::vector<uint8_t>& o_rxFailLanes);
-
-template<fapi2::TargetType K>
-fapi2::ReturnCode retrieveRepairData(
- const fapi2::Target < K >& i_target,
- erepairVpdType i_vpdType,
- const uint8_t i_clkGroup,
- std::vector<uint8_t>& o_txFailLanes,
- std::vector<uint8_t>& o_rxFailLanes)
-{
- fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
- uint8_t* l_retBuf = NULL;
- uint32_t l_bufSize = 0;
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_procTarget;
-#ifdef P9_CUMULUS
- uint8_t l_customDimm;
-#endif
-
- FAPI_DBG(">> retrieveRepairData");
-
- if(i_target.getType() == fapi2::TARGET_TYPE_MEMBUF_CHIP)
- {
-#ifdef P9_CUMULUS
- fapi2::MBvpdRecord l_vpdRecord = fapi2::MBVPD_RECORD_VEIR;
-
- if(i_vpdType == EREPAIR_VPD_MNFG)
- {
- l_vpdRecord = fapi2::MBVPD_RECORD_MER0;
- }
-
- // Determine the size of the eRepair data in the VPD
- FAPI_TRY( getMBvpdField(
- l_vpdRecord,
- fapi2::MBVPD_KEYWORD_PDI,
- i_target,
- NULL,
- l_bufSize),
- "VPD size read failed w/rc=0x%x",
- (uint64_t)current_err );
-
- // Check whether we have Memory on a CDIMM
- l_rc = getDimmType(i_target, l_customDimm);
-
- FAPI_ASSERT((uint64_t)l_rc == 0x0,
- fapi2::P9_EREPAIR_DIMM_TYPE_CHECK_ERR()
- .set_ERROR(l_rc),
- "ERROR: DIMM type check");
-
- if( (l_customDimm == fapi2::ENUM_ATTR_SPD_CUSTOM_YES) || (l_bufSize == 0) )
- {
- if((l_bufSize == 0) ||
- ((i_vpdType == EREPAIR_VPD_FIELD) &&
- (l_bufSize > EREPAIR_MEM_FIELD_VPD_SIZE_PER_CENTAUR)) ||
- ((i_vpdType == EREPAIR_VPD_MNFG) &&
- (l_bufSize > EREPAIR_MEM_MNFG_VPD_SIZE_PER_CENTAUR)))
- {
- FAPI_ASSERT(false,
- fapi2::P9_EREPAIR_ACCESSOR_HWP_INVALID_MEM_VPD_SIZE_ERR()
- .set_ERROR(l_rc),
- "ERROR: Invalid MEM VPD size");
- }
- }
-
- // Allocate memory for buffer
- l_retBuf = new uint8_t[l_bufSize];
-
- FAPI_ASSERT(l_retBuf != NULL,
- fapi2::P9_EREPAIR_ACCESSOR_HWP_MEMORY_ALLOC_FAIL_ERR()
- .set_BUF_SIZE(l_bufSize),
- "ERROR: Failed to allocate memory size");
-
- // Retrieve the Field eRepair data from the PNOR
- FAPI_TRY( getMBvpdField(
- l_vpdRecord,
- fapi2::MBVPD_KEYWORD_PDI,
- i_target,
- l_retBuf,
- l_bufSize),
- "VPD read failed w/rc=0x%x",
- (uint64_t)current_err );
-#endif
- }
- else
- {
- // Determine the Processor target
- l_procTarget = i_target.template getParent<TARGET_TYPE_PROC_CHIP>();
-
- fapi2::MvpdRecord l_vpdRecord = fapi2::MVPD_RECORD_VWML;
-
- if(i_vpdType == EREPAIR_VPD_MNFG)
- {
- l_vpdRecord = fapi2::MVPD_RECORD_MER0;
- }
-
- // Determine the size of the eRepair data in the VPD
- FAPI_TRY( getMvpdField(
- l_vpdRecord,
- fapi2::MVPD_KEYWORD_PDI,
- l_procTarget,
- NULL,
- l_bufSize),
- "VPD size read failed w/rc=0x%x",
- (uint64_t)current_err );
-
- if((l_bufSize == 0) ||
- ((i_vpdType == EREPAIR_VPD_FIELD) &&
- (l_bufSize > EREPAIR_P9_MODULE_VPD_FIELD_SIZE)) ||
- ((i_vpdType == EREPAIR_VPD_MNFG) &&
- (l_bufSize > EREPAIR_P9_MODULE_VPD_MNFG_SIZE)))
- {
- FAPI_ASSERT(false,
- fapi2::P9_EREPAIR_ACCESSOR_HWP_INVALID_FABRIC_VPD_SIZE_ERR()
- .set_ERROR(current_err),
- "ERROR: Invalid Fabric VPD size");
- }
-
- // Allocate memory for buffer
- l_retBuf = new uint8_t[l_bufSize];
-
- FAPI_ASSERT(l_retBuf != NULL,
- fapi2::P9_EREPAIR_ACCESSOR_HWP_MEMORY_ALLOC_FAIL_ERR()
- .set_BUF_SIZE(l_bufSize),
- "ERROR: Failed to allocate memory size");
-
- // Retrieve the Field eRepair data from the PNOR
- FAPI_TRY( getMvpdField(
- l_vpdRecord,
- fapi2::MVPD_KEYWORD_PDI,
- l_procTarget,
- l_retBuf,
- l_bufSize),
- "VPD read failed w/rc=0x%x",
- (uint64_t)current_err );
- }
-
- // Parse the buffer to determine eRepair lanes and copy the
- // fail lane numbers to the return vector
- FAPI_TRY( determineRepairLanes(
- i_target,
- l_retBuf,
- l_bufSize,
- i_clkGroup,
- o_txFailLanes,
- o_rxFailLanes),
- "Call to determineRepairLanes failed w/rc=0x%x",
- (uint64_t)current_err );
-
- // Delete the buffer which has Field eRepair data
- delete[] l_retBuf;
-
- FAPI_DBG("<< retrieveRepairData");
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-template<fapi2::TargetType K>
-fapi2::ReturnCode determineRepairLanes(
- const fapi2::Target < K >& i_target,
- uint8_t* i_buf,
- uint32_t i_bufSz,
- const uint8_t i_clkGroup,
- std::vector<uint8_t>& o_txFailLanes,
- std::vector<uint8_t>& o_rxFailLanes)
-{
- uint32_t l_numRepairs = 0;
- uint8_t* l_vpdPtr = NULL;
- eRepairHeader* l_vpdHeadPtr = NULL;
- uint32_t l_loop = 0;
- uint32_t l_bytesParsed = 0;
- const uint32_t l_fabricRepairDataSz = sizeof(eRepairPowerBus);
-#ifdef P9_CUMULUS
- const uint32_t l_memRepairDataSz = sizeof(eRepairMemBus);
- uint8_t l_customDimm;
-#endif
- fapi2::TargetType l_tgtType = fapi2::TARGET_TYPE_NONE;
- fapi2::Target<fapi2::TARGET_TYPE_MCS> l_mcsTarget;
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_chipTarget;
- fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
- fapi2::ATTR_CHIP_UNIT_POS_Type l_busNum;
- bool l_bClkGroupFound = false;
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- FAPI_DBG(">> determineRepairLanes");
-
- l_tgtType = i_target.getType();
-
- // Get the parent chip target
- l_chipTarget = i_target.template getParent<TARGET_TYPE_PROC_CHIP>();
-
- // Get the chip position
- uint32_t l_chipPosition;
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_POS,
- l_chipTarget,
- l_chipPosition));
-
- // Read the header and count information
- l_vpdPtr = i_buf; // point to the start of header data
- l_vpdHeadPtr = reinterpret_cast<eRepairHeader*> (l_vpdPtr);
-
- l_numRepairs = l_vpdHeadPtr->availNumRecord;
-
- l_bytesParsed = sizeof(eRepairHeader); // we've read the header data
- l_vpdPtr += sizeof(eRepairHeader); // point to the start of repair data
-
- // Parse for Power bus data
- if((l_tgtType == fapi2::TARGET_TYPE_XBUS) ||
- (l_tgtType == fapi2::TARGET_TYPE_OBUS))
- {
- eRepairPowerBus* l_fabricBus;
-
- // Read Power bus eRepair data and get the failed lane numbers
- for(l_loop = 0;
- l_loop < l_numRepairs;
- l_loop++, (l_vpdPtr += l_fabricRepairDataSz))
- {
- // Make sure we are not parsing more data than the passed size
- l_bytesParsed += l_fabricRepairDataSz;
-
- if(l_bytesParsed > i_bufSz)
- {
- break;
- }
-
- l_fabricBus = reinterpret_cast<eRepairPowerBus*>(l_vpdPtr);
-
-#ifndef _BIG_ENDIAN
- // We are on a Little Endian system.
- // Need to swap the nibbles of the structure - eRepairPowerBus
-
- uint8_t l_temp = l_vpdPtr[2];
- l_fabricBus->type = (l_temp >> 4);
- l_fabricBus->interface = (l_temp & 0x0F);
-#endif
-
- // We do not need the check of processor ID because
- // a MVPD read is specific to a Processor
-
- // Check if we have the matching the Fabric Bus types
- if((l_tgtType == fapi2::TARGET_TYPE_OBUS) &&
- (l_fabricBus->type != PROCESSOR_OPT))
- {
- continue;
- }
-
- if((l_tgtType == fapi2::TARGET_TYPE_XBUS) &&
- (l_fabricBus->type != PROCESSOR_EDIP))
- {
- continue;
- }
-
- // Check if we have the matching fabric bus interface
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
- i_target,
- l_busNum));
-
- if(l_fabricBus->device.fabricBus != l_busNum)
- {
- continue;
- }
-
- if(i_clkGroup > 0 && !l_bClkGroupFound)
- {
- l_vpdPtr += l_fabricRepairDataSz;
- l_bClkGroupFound = true;
- continue;
- }
-
- // Copy the fail lane numbers in the vectors
- if(l_fabricBus->interface == PBUS_DRIVER)
- {
- decodeFailedLanes(i_target, l_fabricBus->interface,
- l_fabricBus->failBit, o_txFailLanes);
- }
- else if(l_fabricBus->interface == PBUS_RECEIVER)
- {
- decodeFailedLanes(i_target, l_fabricBus->interface,
- l_fabricBus->failBit, o_rxFailLanes);
- }
- } // end of for loop
- } // end of if(l_tgtType is XBus or OBus)
- else if((l_tgtType == fapi2::TARGET_TYPE_MCS_CHIPLET) ||
- (l_tgtType == fapi2::TARGET_TYPE_MEMBUF_CHIP))
- {
-#ifdef P9_CUMULUS
- // Parse for Memory bus data
- eRepairMemBus* l_memBus;
-
- if(l_tgtType == fapi2::TARGET_TYPE_MEMBUF_CHIP)
- {
- l_rc = fapiGetOtherSideOfMemChannel(
- i_target,
- l_mcsTarget,
- fapi2::TARGET_STATE_FUNCTIONAL);
-
- FAPI_ASSERT((uint64_t)l_rc == 0x0,
- fapi2::P9_EREPAIR_UNABLE_CONNECT_MCS_TARGET_ERR()
- .set_ERROR(l_rc),
- "ERROR: determineRepairLanes: Unable to get the connected to MCS target");
-
- // Check whether we have Memory on a CDIMM
- l_rc = getDimmType(i_target, l_customDimm);
-
- FAPI_ASSERT((uint64_t)l_rc == 0x0,
- fapi2::P9_EREPAIR_DIMM_TYPE_CHECK_ERR()
- .set_ERROR(l_rc),
- "ERROR: DIMM type check");
- }
-
- // Read Power bus eRepair data and get the failed lane numbers
- for(l_loop = 0;
- l_loop < l_numRepairs;
- l_loop++, (l_vpdPtr += l_memRepairDataSz))
- {
- // Make sure we are not parsing more data than the passed size
- l_bytesParsed += l_memRepairDataSz;
-
- if(l_bytesParsed > i_bufSz)
- {
- break;
- }
-
- l_memBus = reinterpret_cast<eRepairMemBus*>(l_vpdPtr);
-
-#ifndef _BIG_ENDIAN
- // We are on a Little Endian system.
- // Need to swap the nibbles of the structure - eRepairMemBus
-
- uint8_t l_temp = l_vpdPtr[2];
- l_memBus->type = (l_temp >> 4);
- l_memBus->interface = (l_temp & 0x0F);
-#endif
-
- // Check if we have the correct Centaur ID
- // NOTE: We do not prefer to make the check of Centaur ID if the
- // system is known to have CDIMMs. This check is applicable
- // only for systems with ISDIMM because in the ISDIMM systems
- // the Lane eRepair data for multiple Centaurs is maintained in
- // a common VPD.
-
- if((l_tgtType == fapi2::TARGET_TYPE_MEMBUF_CHIP) &&
- (l_customDimm != fapi2::ENUM_ATTR_SPD_CUSTOM_YES) &&
- (l_chipPosition != l_memBus->device.proc_centaur_id))
- {
- continue;
- }
-
- // Check if we have the matching the Memory Bus types
- if(l_memBus->type != MEMORY_EDIP)
- {
- continue;
- }
-
- // Check if we have the matching memory bus interface
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
- l_mcsTarget,
- l_busNum));
-
- if(l_memBus->device.memChannel != l_busNum)
- {
- continue;
- }
-
- // Copy the fail lane numbers in the vectors
- if(l_tgtType == fapi2::TARGET_TYPE_MCS_CHIPLET)
- {
- if(l_memBus->interface == DMI_MCS_DRIVE)
- {
- decodeFailedLanes(i_target, l_memBus->interface,
- l_memBus->failBit, o_txFailLanes);
- }
- else if(l_memBus->interface == DMI_MCS_RECEIVE)
- {
- decodeFailedLanes(i_target, l_memBus->interface,
- l_memBus->failBit, o_rxFailLanes);
- }
- }
- else if(l_tgtType == fapi2::TARGET_TYPE_MEMBUF_CHIP)
- {
- if(l_memBus->interface == DMI_MEMBUF_DRIVE)
- {
- decodeFailedLanes(i_target, l_memBus->interface,
- l_memBus->failBit, o_txFailLanes);
- }
- else if(l_memBus->interface == DMI_MEMBUF_RECEIVE)
- {
- decodeFailedLanes(i_target, l_memBus->interface,
- l_memBus->failBit, o_rxFailLanes);
- }
- }
- } // end of for loop
-
-#endif
- } // end of if(l_tgtType is MCS)
-
- FAPI_INF("<< No.of Fail Lanes: tx: %zd, rx: %zd",
- o_txFailLanes.size(), o_rxFailLanes.size());
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-template<fapi2::TargetType K>
-fapi2::ReturnCode getDimmType(
- const fapi2::Target < K >& i_target,
- uint8_t& o_customDimm)
-{
- fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
-#ifdef P9_CUMULUS
- std::vector<fapi2::Target<fapi2::TARGET_TYPE_MBA_CHIPLET>> l_mbaChiplets;
- fapi2::Target<fapi2::TARGET_TYPE_MBA> l_mbaTarget;
- std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>> l_target_dimm_array;
-
- o_customDimm = fapi2::ENUM_ATTR_SPD_CUSTOM_NO;
-
- // Get the connected MBA chiplet and determine whether we have CDIMM
- l_rc = fapiGetChildChiplets(i_target,
- fapi2::TARGET_TYPE_MBA_CHIPLET,
- l_mbaChiplets,
- fapi2::TARGET_STATE_FUNCTIONAL);
-
- FAPI_ASSERT( ((uint64_t)l_rc == 0x0) || (0 != l_mbaChiplets.size()),
- fapi2::P9_EREPAIR_CHILD_MBA_TARGETS_ERR()
- .set_ERROR(l_rc),
- "ERROR: During get child MBA targets");
-
- l_mbaTarget = l_mbaChiplets[0];
- l_rc = fapiGetAssociatedDimms(l_mbaTarget, l_target_dimm_array);
-
- FAPI_ASSERT( (uint64_t)l_rc == 0x0,
- fapi2::P9_EREPAIR_GET_ASSOCIATE_DIMMS_ERR()
- .set_ERROR(l_rc),
- "ERROR: from fapiGetAssociatedDimms");
-
- if(0 != l_target_dimm_array.size())
- {
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SPD_CUSTOM,
- l_target_dimm_array[0],
- o_customDimm));
- }
- else
- {
- o_customDimm = fapi2::ENUM_ATTR_SPD_CUSTOM_NO;
- }
-
-fapi_try_exit:
-#endif
- return l_rc;
-}
-
-template<fapi2::TargetType K>
-fapi2::ReturnCode decodeFailedLanes(
- const fapi2::Target < K >& i_target,
- uint8_t i_busInterface,
- uint32_t i_failBit,
- std::vector<uint8_t>& o_FailLanes)
-{
- fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
- uint8_t loop;
- uint8_t maxBusLanes = 0;
- uint32_t checkBitPosition = (0x80000000);
-
- FAPI_DBG(">> decodeFailedLanes");
-
- // Check for target type and corresponding sub interface
- // to get max lanes supported per interface
- if(i_target.getType() == fapi2::TARGET_TYPE_OBUS)
- {
- maxBusLanes = OBUS_MAX_LANE_WIDTH; //OBUS
- }
- else if(i_target.getType() == fapi2::TARGET_TYPE_XBUS)
- {
- maxBusLanes = XBUS_MAX_LANE_WIDTH; //XBUS
- }
- else if((i_target.getType() == fapi2::TARGET_TYPE_MEMBUF_CHIP) ||
- (i_target.getType() == fapi2::TARGET_TYPE_MCS_CHIPLET) ||
- (i_target.getType() == fapi2::TARGET_TYPE_MCS)) //DMI
- {
- if( (i_busInterface == DMI_MCS_RECEIVE) ||
- (i_busInterface == DMI_MEMBUF_DRIVE) )
- {
- maxBusLanes = DMIBUS_DNSTREAM_MAX_LANE_WIDTH;
- }
- else if( (i_busInterface == DMI_MCS_DRIVE) ||
- (i_busInterface == DMI_MEMBUF_RECEIVE) )
- {
- maxBusLanes = DMIBUS_UPSTREAM_MAX_LANE_WIDTH;
- }
- }
-
- //Check for all the failed bit SET in the bit stream and update the vector
- //And print the failed lanes
- FAPI_INF("No. of Failed Lanes:");
-
- for( loop = 0;
- loop < maxBusLanes;
- loop++ )
- {
- if( i_failBit & ( checkBitPosition >> loop ) )
- {
- o_FailLanes.push_back(loop);
- FAPI_INF("%d", loop);
- }
- }
-
- FAPI_DBG("<< decodeFailedLanes");
- return l_rc;
-}
-
diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_erepairGetFailedLanesHwp.H b/src/import/chips/p9/procedures/hwp/io/p9_io_erepairGetFailedLanesHwp.H
index b79f8aff8..0a545fb7f 100755
--- a/src/import/chips/p9/procedures/hwp/io/p9_io_erepairGetFailedLanesHwp.H
+++ b/src/import/chips/p9/procedures/hwp/io/p9_io_erepairGetFailedLanesHwp.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,26 +40,147 @@
#include <fapi2.H>
#include <p9_io_erepairConsts.H>
+#include <mvpd_access.H>
+#include <fapi2_mbvpd_access.H>
+/******************************************************************************
+ * Accessor HWP
+ *****************************************************************************/
+
+/**
+ * @brief Function to check if the system has Custom DIMM type (CDIMM).
+ * Attribute ATTR_EFF_CUSTOM_DIMM is read to determine the type.
+ * @param[in] i_target Reference to X-Bus or O-Bus or DMI target
+ * @param[o] o_customDimm Return value - ENUM_ATTR_EFF_CUSTOM_DIMM_NO
+ * or ENUM_ATTR_EFF_CUSTOM_DIMM_YES
+ * @return ReturnCode
+ */
template<fapi2::TargetType K>
-using p9_io_erepairGetFailedLanesHwp_FP_t = fapi2::ReturnCode (*)(
- const fapi2::Target < K >& i_target,
- EREPAIR::erepairVpdType i_vpdType,
- const uint8_t i_clkGroup,
- std::vector<uint8_t>& o_txFailLanes,
- std::vector<uint8_t>& o_rxFailLanes);
+fapi2::ReturnCode getDimmType(
+ const fapi2::Target < K >& i_target,
+ uint8_t& o_customDimm)
+{
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_MBA_CHIPLET>> l_mbaChiplets;
+ fapi2::Target<fapi2::TARGET_TYPE_MBA> l_mbaTarget;
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>> l_target_dimm_array;
+
+ o_customDimm = fapi2::ENUM_ATTR_CEN_SPD_CUSTOM_NO;
+
+ // Get the connected MBA chiplet and determine whether we have CDIMM
+ l_mbaChiplets = i_target.template getChildren<fapi2::TARGET_TYPE_MBA_CHIPLET>
+ (fapi2::TARGET_STATE_FUNCTIONAL);
+ FAPI_ASSERT( 0 != l_mbaChiplets.size(),
+ fapi2::P9_EREPAIR_CHILD_MBA_TARGETS_ERR()
+ .set_ERROR(l_mbaChiplets),
+ "ERROR: During get child MBA targets");
+
+ l_mbaTarget = l_mbaChiplets[0];
+ l_target_dimm_array = l_mbaTarget.getChildren<fapi2::TARGET_TYPE_DIMM>
+ (fapi2::TARGET_STATE_FUNCTIONAL);
+
+ if(0 != l_target_dimm_array.size())
+ {
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_SPD_CUSTOM,
+ l_target_dimm_array[0],
+ o_customDimm));
+ }
+ else
+ {
+ o_customDimm = fapi2::ENUM_ATTR_CEN_SPD_CUSTOM_NO;
+ }
+
+fapi_try_exit:
+ return l_rc;
+}
/**
- * @brief FW Team HWP that retrieves the eRepair fail lanes.
- * It retrieves the eRepair data from the P9 MVPD and the Centaur FRU
- * VPD sections depending on the passed target type. It then parses the
- * eRepair data to determine the fail lane numbers on the sub-interfaces
- * (Tx and Rx) of the passed bus target.
+ * @brief Function called by the HWP that parses the data read from VPD.
+ * This function scans through failBit field bit pattern and checks
+ * for all bits that are set. For bits SET the corresponding bit positions
+ * marks the failed lane number and is copied into
+ * the respective failLane vectors to be returned to the caller.
*
- * @param[in] i_tgtHandle Reference to X-Bus or A-Bus or MCS or memBuf Target
- * @param[in] i_vpdType Specifies which VPD (MNFG or Field) to access.
+ * @param[in] i_target Reference to X-Bus or O-Bus or DMI target type
+ * @param[in] i_busInterface Reference to target sub interface
+ * @param[in] i_failBit This is the failBit field from the eRepair records
+ * read from the VPD
+ * @param[o] o_FailLanes Reference to a vector that will hold eRepair fail
+ * lane numbers of the Rx/Tx sub-interface.
+ *
+ * @return ReturnCode
+ */
+template<fapi2::TargetType K>
+fapi2::ReturnCode decodeFailedLanes(
+ const fapi2::Target < K >& i_target,
+ uint8_t i_busInterface,
+ uint32_t i_failBit,
+ std::vector<uint8_t>& o_FailLanes)
+{
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ uint8_t loop;
+ uint8_t maxBusLanes = 0;
+ uint32_t checkBitPosition = (0x80000000);
+
+ FAPI_DBG(">> decodeFailedLanes");
+
+ // Check for target type and corresponding sub interface
+ // to get max lanes supported per interface
+ if(i_target.getType() == fapi2::TARGET_TYPE_OBUS)
+ {
+ maxBusLanes = EREPAIR::OBUS_MAX_LANE_WIDTH; //OBUS
+ }
+ else if(i_target.getType() == fapi2::TARGET_TYPE_XBUS)
+ {
+ maxBusLanes = EREPAIR::XBUS_MAX_LANE_WIDTH; //XBUS
+ }
+ else if((i_target.getType() == fapi2::TARGET_TYPE_MEMBUF_CHIP) ||
+ (i_target.getType() == fapi2::TARGET_TYPE_DMI))
+ {
+ if( (i_busInterface == EREPAIR::DMI_MCS_RECEIVE) ||
+ (i_busInterface == EREPAIR::DMI_MEMBUF_DRIVE) )
+ {
+ maxBusLanes = EREPAIR::DMIBUS_DNSTREAM_MAX_LANE_WIDTH;
+ }
+ else if( (i_busInterface == EREPAIR::DMI_MCS_DRIVE) ||
+ (i_busInterface == EREPAIR::DMI_MEMBUF_RECEIVE) )
+ {
+ maxBusLanes = EREPAIR::DMIBUS_UPSTREAM_MAX_LANE_WIDTH;
+ }
+ }
+
+ //Check for all the failed bit SET in the bit stream and update the vector
+ //And print the failed lanes
+ FAPI_INF("No. of Failed Lanes:");
+
+ for( loop = 0;
+ loop < maxBusLanes;
+ loop++ )
+ {
+ if( i_failBit & ( checkBitPosition >> loop ) )
+ {
+ o_FailLanes.push_back(loop);
+ FAPI_INF("%d", loop);
+ }
+ }
+
+ FAPI_DBG("<< decodeFailedLanes");
+ return l_rc;
+}
+
+/**
+ * @brief Function called by the FW Team HWP that parses the data read from
+ * Field VPD. This function matches each eRepair record read from the VPD
+ * and matches it against the attributes of the passed target.
+ * If a match is found, the corresponding eRepair record is copied into
+ * the respective failLane vectors to be returned to the caller.
+ * (For Proc)
+ * @param[in] i_target Reference to X-Bus or O-Bus target
+ * @param[in] i_buf This is the buffer that has the eRepair records
+ * read from the VPD
+ * @param[in] i_bufSz This is the size of passed buffer in terms of bytes
* @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
* @param[o] o_txFailLanes Reference to a vector that will hold eRepair fail
* lane numbers of the Tx sub-interface.
@@ -67,15 +188,828 @@ using p9_io_erepairGetFailedLanesHwp_FP_t = fapi2::ReturnCode (*)(
* lane numbers of the Rx sub-interface.
*
* @return ReturnCode
+ */
+template<fapi2::TargetType K>
+fapi2::ReturnCode determineRepairLanesProc(
+ const fapi2::Target < K >& i_target,
+ uint8_t* i_buf,
+ uint32_t i_bufSz,
+ const uint8_t i_clkGroup,
+ std::vector<uint8_t>& o_txFailLanes,
+ std::vector<uint8_t>& o_rxFailLanes)
+{
+ uint32_t l_numRepairs = 0;
+ uint8_t* l_vpdPtr = NULL;
+ eRepairHeader* l_vpdHeadPtr = NULL;
+ uint32_t l_loop = 0;
+ uint32_t l_bytesParsed = 0;
+ const uint32_t l_fabricRepairDataSz = sizeof(eRepairPowerBus);
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_chipTarget;
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::ATTR_CHIP_UNIT_POS_Type l_busNum;
+ bool l_bClkGroupFound = false;
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_DBG(">> determineRepairLanesProc");
+
+ // Get the parent chip target
+ l_chipTarget = i_target.template getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
+
+ // Get the chip position
+ uint32_t l_chipPosition;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_POS,
+ l_chipTarget,
+ l_chipPosition));
+
+ // Read the header and count information
+ l_vpdPtr = i_buf; // point to the start of header data
+ l_vpdHeadPtr = reinterpret_cast<eRepairHeader*> (l_vpdPtr);
+
+ l_numRepairs = l_vpdHeadPtr->availNumRecord;
+
+ l_bytesParsed = sizeof(eRepairHeader); // we've read the header data
+ l_vpdPtr += sizeof(eRepairHeader); // point to the start of repair data
+
+ // Parse for Power bus data
+ {
+ eRepairPowerBus* l_fabricBus;
+
+ // Read Power bus eRepair data and get the failed lane numbers
+ for(l_loop = 0;
+ l_loop < l_numRepairs;
+ l_loop++, (l_vpdPtr += l_fabricRepairDataSz))
+ {
+ // Make sure we are not parsing more data than the passed size
+ l_bytesParsed += l_fabricRepairDataSz;
+
+ if(l_bytesParsed > i_bufSz)
+ {
+ break;
+ }
+
+ l_fabricBus = reinterpret_cast<eRepairPowerBus*>(l_vpdPtr);
+
+#ifndef _BIG_ENDIAN
+ // We are on a Little Endian system.
+ // Need to swap the nibbles of the structure - eRepairPowerBus
+
+ uint8_t l_temp = l_vpdPtr[2];
+ l_fabricBus->type = (l_temp >> 4);
+ l_fabricBus->interface = (l_temp & 0x0F);
+#endif
+
+ // We do not need the check of processor ID because
+ // a MVPD read is specific to a Processor
+
+ // Check if we have the matching the Fabric Bus types
+ //if((l_tgtType == fapi2::TARGET_TYPE_OBUS) &&
+ // (l_fabricBus->type != PROCESSOR_OPT))
+ //{
+ // continue;
+ //}
+
+ if(l_fabricBus->type != EREPAIR::PROCESSOR_EDIP)
+ {
+ continue;
+ }
+
+ // Check if we have the matching fabric bus interface
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
+ i_target,
+ l_busNum));
+
+ if(l_fabricBus->device.fabricBus != l_busNum)
+ {
+ continue;
+ }
+
+ if(i_clkGroup > 0 && !l_bClkGroupFound)
+ {
+ l_vpdPtr += l_fabricRepairDataSz;
+ l_bClkGroupFound = true;
+ continue;
+ }
+
+ // Copy the fail lane numbers in the vectors
+ if(l_fabricBus->interface == EREPAIR::PBUS_DRIVER)
+ {
+ decodeFailedLanes(i_target, l_fabricBus->interface,
+ l_fabricBus->failBit, o_txFailLanes);
+ }
+ else if(l_fabricBus->interface == EREPAIR::PBUS_RECEIVER)
+ {
+ decodeFailedLanes(i_target, l_fabricBus->interface,
+ l_fabricBus->failBit, o_rxFailLanes);
+ }
+ } // end of for loop
+ } // end of if(l_tgtType is XBus or OBus)
+
+ FAPI_INF("<< No.of Fail Lanes: tx: %zd, rx: %zd",
+ o_txFailLanes.size(), o_rxFailLanes.size());
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/**
+ * @brief Function called by the FW Team HWP that parses the data read from
+ * Field VPD. This function matches each eRepair record read from the VPD
+ * and matches it against the attributes of the passed target.
+ * If a match is found, the corresponding eRepair record is copied into
+ * the respective failLane vectors to be returned to the caller.
+ * (For MemBuf)
+ * @param[in] i_target Reference to MEMBUF target
+ * @param[in] i_buf This is the buffer that has the eRepair records
+ * read from the VPD
+ * @param[in] i_bufSz This is the size of passed buffer in terms of bytes
+ * @param[o] o_txFailLanes Reference to a vector that will hold eRepair fail
+ * lane numbers of the Tx sub-interface.
+ * @param[o] o_rxFailLanes Reference to a vector that will hold eRepair fail
+ * lane numbers of the Rx sub-interface.
+ *
+ * @return ReturnCode
+ */
+template<fapi2::TargetType K>
+fapi2::ReturnCode determineRepairLanesMemBuf(
+ const fapi2::Target < K >& i_target,
+ uint8_t* i_buf,
+ uint32_t i_bufSz,
+ std::vector<uint8_t>& o_txFailLanes,
+ std::vector<uint8_t>& o_rxFailLanes)
+{
+ uint32_t l_numRepairs = 0;
+ uint8_t* l_vpdPtr = NULL;
+ eRepairHeader* l_vpdHeadPtr = NULL;
+ uint32_t l_loop = 0;
+ uint32_t l_bytesParsed = 0;
+ const uint32_t l_memRepairDataSz = sizeof(eRepairMemBus);
+ uint8_t l_customDimm;
+ fapi2::Target<fapi2::TARGET_TYPE_DMI> l_dmiTarget;
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::ATTR_CHIP_UNIT_POS_Type l_busNum;
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_DBG(">> determineRepairLanesMemBuf");
+
+ // Get the chip position
+ uint32_t l_chipPosition;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_POS,
+ i_target,
+ l_chipPosition));
+
+ // Read the header and count information
+ l_vpdPtr = i_buf; // point to the start of header data
+ l_vpdHeadPtr = reinterpret_cast<eRepairHeader*> (l_vpdPtr);
+
+ l_numRepairs = l_vpdHeadPtr->availNumRecord;
+
+ l_bytesParsed = sizeof(eRepairHeader); // we've read the header data
+ l_vpdPtr += sizeof(eRepairHeader); // point to the start of repair data
+
+ // Parse for Memory bus data
+ {
+ eRepairMemBus* l_memBus;
+
+ l_dmiTarget = i_target.template getParent<fapi2::TARGET_TYPE_DMI>();
+
+ // Check whether we have Memory on a CDIMM
+ l_rc = getDimmType(i_target, l_customDimm);
+
+ FAPI_ASSERT((uint64_t)l_rc == 0x0,
+ fapi2::P9_EREPAIR_DIMM_TYPE_CHECK_ERR()
+ .set_ERROR(l_rc),
+ "ERROR: DIMM type check");
+
+ // Read Power bus eRepair data and get the failed lane numbers
+ for(l_loop = 0;
+ l_loop < l_numRepairs;
+ l_loop++, (l_vpdPtr += l_memRepairDataSz))
+ {
+ // Make sure we are not parsing more data than the passed size
+ l_bytesParsed += l_memRepairDataSz;
+
+ if(l_bytesParsed > i_bufSz)
+ {
+ break;
+ }
+
+ l_memBus = reinterpret_cast<eRepairMemBus*>(l_vpdPtr);
+
+#ifndef _BIG_ENDIAN
+ // We are on a Little Endian system.
+ // Need to swap the nibbles of the structure - eRepairMemBus
+
+ uint8_t l_temp = l_vpdPtr[2];
+ l_memBus->type = (l_temp >> 4);
+ l_memBus->interface = (l_temp & 0x0F);
+#endif
+
+ // Check if we have the correct Centaur ID
+ // NOTE: We do not prefer to make the check of Centaur ID if the
+ // system is known to have CDIMMs. This check is applicable
+ // only for systems with ISDIMM because in the ISDIMM systems
+ // the Lane eRepair data for multiple Centaurs is maintained in
+ // a common VPD.
+
+ if((l_customDimm != fapi2::ENUM_ATTR_CEN_SPD_CUSTOM_YES) &&
+ (l_chipPosition != l_memBus->device.proc_centaur_id))
+ {
+ continue;
+ }
+
+ // Check if we have the matching the Memory Bus types
+ if(l_memBus->type != EREPAIR::MEMORY_EDIP)
+ {
+ continue;
+ }
+
+ // Check if we have the matching memory bus interface
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
+ l_dmiTarget,
+ l_busNum));
+
+ if(l_memBus->device.memChannel != l_busNum)
+ {
+ continue;
+ }
+
+ // Copy the fail lane numbers in the vectors
+ {
+ if(l_memBus->interface == EREPAIR::DMI_MEMBUF_DRIVE)
+ {
+ decodeFailedLanes(i_target, l_memBus->interface,
+ l_memBus->failBit, o_txFailLanes);
+ }
+ else if(l_memBus->interface == EREPAIR::DMI_MEMBUF_RECEIVE)
+ {
+ decodeFailedLanes(i_target, l_memBus->interface,
+ l_memBus->failBit, o_rxFailLanes);
+ }
+ }
+ } // end of for loop
+ } // end of if(l_tgtType is DMI)
+
+ FAPI_INF("<< No.of Fail Lanes: tx: %zd, rx: %zd",
+ o_txFailLanes.size(), o_rxFailLanes.size());
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+/**
+ * @brief Function called by the FW Team HWP that parses the data read from
+ * Field VPD. This function matches each eRepair record read from the VPD
+ * and matches it against the attributes of the passed target.
+ * If a match is found, the corresponding eRepair record is copied into
+ * the respective failLane vectors to be returned to the caller.
+ * (For Memory)
+ * @param[in] i_target Reference to DMI target
+ * @param[in] i_buf This is the buffer that has the eRepair records
+ * read from the VPD
+ * @param[in] i_bufSz This is the size of passed buffer in terms of bytes
+ * @param[o] o_txFailLanes Reference to a vector that will hold eRepair fail
+ * lane numbers of the Tx sub-interface.
+ * @param[o] o_rxFailLanes Reference to a vector that will hold eRepair fail
+ * lane numbers of the Rx sub-interface.
*
+ * @return ReturnCode
*/
template<fapi2::TargetType K>
-fapi2::ReturnCode p9_io_erepairGetFailedLanesHwp(
+fapi2::ReturnCode determineRepairLanesDMI(
const fapi2::Target < K >& i_target,
- EREPAIR::erepairVpdType i_vpdType,
- const uint8_t i_clkGroup,
+ uint8_t* i_buf,
+ uint32_t i_bufSz,
std::vector<uint8_t>& o_txFailLanes,
- std::vector<uint8_t>& o_rxFailLanes);
+ std::vector<uint8_t>& o_rxFailLanes)
+{
+ uint32_t l_numRepairs = 0;
+ uint8_t* l_vpdPtr = NULL;
+ eRepairHeader* l_vpdHeadPtr = NULL;
+ uint32_t l_loop = 0;
+ uint32_t l_bytesParsed = 0;
+ const uint32_t l_memRepairDataSz = sizeof(eRepairMemBus);
+ fapi2::Target<fapi2::TARGET_TYPE_DMI> l_dmiTarget;
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_chipTarget;
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::ATTR_CHIP_UNIT_POS_Type l_busNum;
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_DBG(">> determineRepairLanesMemDMI");
+
+ // Get the parent chip target
+ l_chipTarget = i_target.template getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
+
+ // Get the chip position
+ uint32_t l_chipPosition;
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_POS,
+ l_chipTarget,
+ l_chipPosition));
+
+ // Read the header and count information
+ l_vpdPtr = i_buf; // point to the start of header data
+ l_vpdHeadPtr = reinterpret_cast<eRepairHeader*> (l_vpdPtr);
+
+ l_numRepairs = l_vpdHeadPtr->availNumRecord;
+
+ l_bytesParsed = sizeof(eRepairHeader); // we've read the header data
+ l_vpdPtr += sizeof(eRepairHeader); // point to the start of repair data
+
+ // Parse for Memory bus data
+ {
+ eRepairMemBus* l_memBus;
+
+ // Read Power bus eRepair data and get the failed lane numbers
+ for(l_loop = 0;
+ l_loop < l_numRepairs;
+ l_loop++, (l_vpdPtr += l_memRepairDataSz))
+ {
+ // Make sure we are not parsing more data than the passed size
+ l_bytesParsed += l_memRepairDataSz;
+
+ if(l_bytesParsed > i_bufSz)
+ {
+ break;
+ }
+
+ l_memBus = reinterpret_cast<eRepairMemBus*>(l_vpdPtr);
+
+#ifndef _BIG_ENDIAN
+ // We are on a Little Endian system.
+ // Need to swap the nibbles of the structure - eRepairMemBus
+
+ uint8_t l_temp = l_vpdPtr[2];
+ l_memBus->type = (l_temp >> 4);
+ l_memBus->interface = (l_temp & 0x0F);
+#endif
+
+ // Check if we have the correct Centaur ID
+ // NOTE: We do not prefer to make the check of Centaur ID if the
+ // system is known to have CDIMMs. This check is applicable
+ // only for systems with ISDIMM because in the ISDIMM systems
+ // the Lane eRepair data for multiple Centaurs is maintained in
+ // a common VPD.
+
+ // Check if we have the matching the Memory Bus types
+ if(l_memBus->type != EREPAIR::MEMORY_EDIP)
+ {
+ continue;
+ }
+
+ // Check if we have the matching memory bus interface
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
+ l_dmiTarget,
+ l_busNum));
+
+ if(l_memBus->device.memChannel != l_busNum)
+ {
+ continue;
+ }
+
+ // Copy the fail lane numbers in the vectors
+ if(l_memBus->interface == EREPAIR::DMI_MCS_DRIVE)
+ {
+ decodeFailedLanes(i_target, l_memBus->interface,
+ l_memBus->failBit, o_txFailLanes);
+ }
+ else if(l_memBus->interface == EREPAIR::DMI_MCS_RECEIVE)
+ {
+ decodeFailedLanes(i_target, l_memBus->interface,
+ l_memBus->failBit, o_rxFailLanes);
+ }
+ } // end of for loop
+ } // end of if(l_tgtType is DMI)
+
+ FAPI_INF("<< No.of Fail Lanes: tx: %zd, rx: %zd",
+ o_txFailLanes.size(), o_rxFailLanes.size());
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+/**
+ * @brief Function called by the FW Team HWP that reads the data from Field VPD.
+ * This function makes the actual calls to read the VPD
+ * It determines the size of the buffer to be read, allocates memory
+ * of the determined size, calls fapiGetMvpdField to read the eRepair
+ * records. This buffer is further passed to another routine for
+ * parsing. (For Proc)
+ *
+ * @param[in] i_target Reference to X-Bus or O-Bus target
+ * @param[in] i_vpdType Specifies which VPD (MNFG or Field) to access.
+ * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
+ * @param[o] o_txFailLanes Reference to a vector that will hold eRepair fail
+ * lane numbers of the Tx sub-interface.
+ * @param[o] o_rxFailLanes Reference to a vector that will hold eRepair fail
+ * lane numbers of the Rx sub-interface.
+ *
+ * @return ReturnCode
+ */
+template<fapi2::TargetType K>
+fapi2::ReturnCode retrieveRepairDataProc(
+ const fapi2::Target < K >& i_target,
+ EREPAIR::erepairVpdType i_vpdType,
+ const uint8_t i_clkGroup,
+ std::vector<uint8_t>& o_txFailLanes,
+ std::vector<uint8_t>& o_rxFailLanes)
+{
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ uint8_t* l_retBuf = NULL;
+ uint32_t l_bufSize = 0;
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_procTarget;
+
+ FAPI_DBG(">> retrieveRepairDataProc");
+
+ {
+ // Determine the Processor target
+ l_procTarget = i_target.template getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
+
+ fapi2::MvpdRecord l_vpdRecord = fapi2::MVPD_RECORD_VWML;
+
+ if(i_vpdType == EREPAIR::EREPAIR_VPD_MNFG)
+ {
+ l_vpdRecord = fapi2::MVPD_RECORD_MER0;
+ }
+
+ // Determine the size of the eRepair data in the VPD
+ FAPI_TRY( getMvpdField(
+ l_vpdRecord,
+ fapi2::MVPD_KEYWORD_PDI,
+ l_procTarget,
+ NULL,
+ l_bufSize),
+ "VPD size read failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ if((l_bufSize == 0) ||
+ ((i_vpdType == EREPAIR::EREPAIR_VPD_FIELD) &&
+ (l_bufSize > EREPAIR::EREPAIR_P9_MODULE_VPD_FIELD_SIZE)) ||
+ ((i_vpdType == EREPAIR::EREPAIR_VPD_MNFG) &&
+ (l_bufSize > EREPAIR::EREPAIR_P9_MODULE_VPD_MNFG_SIZE)))
+ {
+ FAPI_ASSERT(false,
+ fapi2::P9_EREPAIR_ACCESSOR_HWP_INVALID_FABRIC_VPD_SIZE_ERR()
+ .set_ERROR(fapi2::current_err),
+ "ERROR: Invalid Fabric VPD size");
+ }
+
+ // Allocate memory for buffer
+ l_retBuf = new uint8_t[l_bufSize];
+
+ FAPI_ASSERT(l_retBuf != NULL,
+ fapi2::P9_EREPAIR_ACCESSOR_HWP_MEMORY_ALLOC_FAIL_ERR()
+ .set_BUF_SIZE(l_bufSize),
+ "ERROR: Failed to allocate memory size");
+
+ // Retrieve the Field eRepair data from the PNOR
+ FAPI_TRY( getMvpdField(
+ l_vpdRecord,
+ fapi2::MVPD_KEYWORD_PDI,
+ l_procTarget,
+ l_retBuf,
+ l_bufSize),
+ "VPD read failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ // Parse the buffer to determine eRepair lanes and copy the
+ // fail lane numbers to the return vector
+ FAPI_TRY( determineRepairLanesProc(
+ i_target,
+ l_retBuf,
+ l_bufSize,
+ i_clkGroup,
+ o_txFailLanes,
+ o_rxFailLanes),
+ "Call to determineRepairLanes failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ }
+
+ // Delete the buffer which has Field eRepair data
+ delete[] l_retBuf;
+
+ FAPI_DBG("<< retrieveRepairDataProc");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+/**
+ * @brief Function called by the FW Team HWP that reads the data from Field VPD.
+ * This function makes the actual calls to read the VPD
+ * It determines the size of the buffer to be read, allocates memory
+ * of the determined size, calls fapiGetMBvpdField to read the eRepair
+ * records. This buffer is further passed to another routine for
+ * parsing. (For Memory)
+ *
+ * @param[in] i_target Reference to MEMBUF or DMI target
+ * @param[in] i_vpdType Specifies which VPD (MNFG or Field) to access.
+ * @param[o] o_txFailLanes Reference to a vector that will hold eRepair fail
+ * lane numbers of the Tx sub-interface.
+ * @param[o] o_rxFailLanes Reference to a vector that will hold eRepair fail
+ * lane numbers of the Rx sub-interface.
+ *
+ * @return ReturnCode
+ */
+template<fapi2::TargetType K>
+fapi2::ReturnCode retrieveRepairDataMemBuf(
+ const fapi2::Target < K >& i_target,
+ EREPAIR::erepairVpdType i_vpdType,
+ std::vector<uint8_t>& o_txFailLanes,
+ std::vector<uint8_t>& o_rxFailLanes)
+{
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ uint8_t* l_retBuf = NULL;
+ uint32_t l_bufSize = 0;
+ size_t l_mBufSize = 0;
+ uint8_t l_customDimm;
+
+ FAPI_DBG(">> retrieveRepairDataMemBuf");
+
+ {
+ fapi2::MBvpdRecord l_vpdRecord = fapi2::MBVPD_RECORD_VEIR;
+
+ if(i_vpdType == EREPAIR::EREPAIR_VPD_MNFG)
+ {
+ l_vpdRecord = fapi2::MBVPD_RECORD_MER0;
+ }
+
+ // Determine the size of the eRepair data in the VPD
+ FAPI_TRY( getMBvpdField(
+ l_vpdRecord,
+ fapi2::MBVPD_KEYWORD_PDI,
+ i_target,
+ NULL,
+ l_mBufSize),
+ "VPD size read failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ // Check whether we have Memory on a CDIMM
+ l_rc = getDimmType(i_target, l_customDimm);
+
+ FAPI_ASSERT((uint64_t)l_rc == 0x0,
+ fapi2::P9_EREPAIR_DIMM_TYPE_CHECK_ERR()
+ .set_ERROR(l_rc),
+ "ERROR: DIMM type check");
+
+ if( (l_customDimm == fapi2::ENUM_ATTR_CEN_SPD_CUSTOM_YES) || (l_bufSize == 0) )
+ {
+ if((l_bufSize == 0) ||
+ ((i_vpdType == EREPAIR::EREPAIR_VPD_FIELD) &&
+ (l_bufSize > EREPAIR::EREPAIR_MEM_FIELD_VPD_SIZE_PER_CENTAUR)) ||
+ ((i_vpdType == EREPAIR::EREPAIR_VPD_MNFG) &&
+ (l_bufSize > EREPAIR::EREPAIR_MEM_MNFG_VPD_SIZE_PER_CENTAUR)))
+ {
+ FAPI_ASSERT(false,
+ fapi2::P9_EREPAIR_ACCESSOR_HWP_INVALID_MEM_VPD_SIZE_ERR()
+ .set_ERROR(l_rc),
+ "ERROR: Invalid MEM VPD size");
+ }
+ }
+
+ // Allocate memory for buffer
+ l_retBuf = new uint8_t[l_bufSize];
+
+ FAPI_ASSERT(l_retBuf != NULL,
+ fapi2::P9_EREPAIR_ACCESSOR_HWP_MEMORY_ALLOC_FAIL_ERR()
+ .set_BUF_SIZE(l_bufSize),
+ "ERROR: Failed to allocate memory size");
+
+ // Retrieve the Field eRepair data from the PNOR
+ FAPI_TRY( getMBvpdField(
+ l_vpdRecord,
+ fapi2::MBVPD_KEYWORD_PDI,
+ i_target,
+ l_retBuf,
+ l_mBufSize),
+ "VPD read failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ // Parse the buffer to determine eRepair lanes and copy the
+ // fail lane numbers to the return vector
+ FAPI_TRY( determineRepairLanesMemBuf(
+ i_target,
+ l_retBuf,
+ l_mBufSize,
+ o_txFailLanes,
+ o_rxFailLanes),
+ "Call to determineRepairLanes failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ }
+
+ // Delete the buffer which has Field eRepair data
+ delete[] l_retBuf;
+
+ FAPI_DBG("<< retrieveRepairDataMemBuf");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+/**
+ * @brief Function called by the FW Team HWP that reads the data from Field VPD.
+ * This function makes the actual calls to read the VPD
+ * It determines the size of the buffer to be read, allocates memory
+ * of the determined size, calls fapiGetMvpdField to read the eRepair
+ * records. This buffer is further passed to another routine for
+ * parsing. (For DMI)
+ *
+ * @param[in] i_target Reference to DMI target
+ * @param[in] i_vpdType Specifies which VPD (MNFG or Field) to access.
+ * @param[o] o_txFailLanes Reference to a vector that will hold eRepair fail
+ * lane numbers of the Tx sub-interface.
+ * @param[o] o_rxFailLanes Reference to a vector that will hold eRepair fail
+ * lane numbers of the Rx sub-interface.
+ *
+ * @return ReturnCode
+ */
+template<fapi2::TargetType K>
+fapi2::ReturnCode retrieveRepairDataDMI(
+ const fapi2::Target < K >& i_target,
+ EREPAIR::erepairVpdType i_vpdType,
+ std::vector<uint8_t>& o_txFailLanes,
+ std::vector<uint8_t>& o_rxFailLanes)
+{
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ uint8_t* l_retBuf = NULL;
+ uint32_t l_bufSize = 0;
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_procTarget;
+
+ FAPI_DBG(">> retrieveRepairDataDMI");
+
+ {
+ // Determine the Processor target
+ l_procTarget = i_target.template getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
+
+ fapi2::MvpdRecord l_vpdRecord = fapi2::MVPD_RECORD_VWML;
+
+ if(i_vpdType == EREPAIR::EREPAIR_VPD_MNFG)
+ {
+ l_vpdRecord = fapi2::MVPD_RECORD_MER0;
+ }
+
+ // Determine the size of the eRepair data in the VPD
+ FAPI_TRY( getMvpdField(
+ l_vpdRecord,
+ fapi2::MVPD_KEYWORD_PDI,
+ l_procTarget,
+ NULL,
+ l_bufSize),
+ "VPD size read failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ if((l_bufSize == 0) ||
+ ((i_vpdType == EREPAIR::EREPAIR_VPD_FIELD) &&
+ (l_bufSize > EREPAIR::EREPAIR_P9_MODULE_VPD_FIELD_SIZE)) ||
+ ((i_vpdType == EREPAIR::EREPAIR_VPD_MNFG) &&
+ (l_bufSize > EREPAIR::EREPAIR_P9_MODULE_VPD_MNFG_SIZE)))
+ {
+ FAPI_ASSERT(false,
+ fapi2::P9_EREPAIR_ACCESSOR_HWP_INVALID_FABRIC_VPD_SIZE_ERR()
+ .set_ERROR(fapi2::current_err),
+ "ERROR: Invalid Fabric VPD size");
+ }
+
+ // Allocate memory for buffer
+ l_retBuf = new uint8_t[l_bufSize];
+
+ FAPI_ASSERT(l_retBuf != NULL,
+ fapi2::P9_EREPAIR_ACCESSOR_HWP_MEMORY_ALLOC_FAIL_ERR()
+ .set_BUF_SIZE(l_bufSize),
+ "ERROR: Failed to allocate memory size");
+
+ // Retrieve the Field eRepair data from the PNOR
+ FAPI_TRY( getMvpdField(
+ l_vpdRecord,
+ fapi2::MVPD_KEYWORD_PDI,
+ l_procTarget,
+ l_retBuf,
+ l_bufSize),
+ "VPD read failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ // Parse the buffer to determine eRepair lanes and copy the
+ // fail lane numbers to the return vector
+ FAPI_TRY( determineRepairLanesDMI(
+ i_target,
+ l_retBuf,
+ l_bufSize,
+ o_txFailLanes,
+ o_rxFailLanes),
+ "Call to determineRepairLanes failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ }
+
+ // Delete the buffer which has Field eRepair data
+ delete[] l_retBuf;
+
+ FAPI_DBG("<< retrieveRepairDataDMI");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+/**
+ * @brief Function called by the FW Team HWP that reads the failed lanes
+ * from VPD. This function calls the retrieveRepairData() that makes
+ * the actual calls to read the VPD and perform the necessary actions.
+ *
+ * @param[in] i_target Reference to X-Bus or O-Bus or DMI target
+ * @param[in] i_vpdType Specifies which VPD (MNFG or Field) to access.
+ * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
+ * @param[o] o_txFailLanes Reference to a vector that will hold eRepair fail
+ * lane numbers of the Tx sub-interface.
+ * @param[o] o_rxFailLanes Reference to a vector that will hold eRepair fail
+ * lane numbers of the Rx sub-interface.
+ *
+ * @return ReturnCode
+ */
+fapi2::ReturnCode p9_io_erepairGetFailedLanesHwp(
+ const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target,
+ EREPAIR::erepairVpdType i_vpdType,
+ const uint8_t i_clkGroup,
+ std::vector<uint8_t>& o_txFailLanes,
+ std::vector<uint8_t>& o_rxFailLanes)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_INF(">> erepairGetFailedLanesHwp - XBUS");
+
+ o_txFailLanes.clear();
+ o_rxFailLanes.clear();
+
+ // Retrieve the Field eRepair lane numbers from the VPD
+ FAPI_TRY( retrieveRepairDataProc(
+ i_target,
+ i_vpdType,
+ i_clkGroup,
+ o_txFailLanes,
+ o_rxFailLanes),
+ "p9_io_erepairGetFailedLanesHwp() failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+fapi2::ReturnCode p9_io_erepairGetFailedLanesHwp(
+ const fapi2::Target < fapi2::TARGET_TYPE_MEMBUF_CHIP >& i_target,
+ EREPAIR::erepairVpdType i_vpdType,
+ const uint8_t i_clkGroup,
+ std::vector<uint8_t>& o_txFailLanes,
+ std::vector<uint8_t>& o_rxFailLanes)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_INF(">> erepairGetFailedLanesHwp - MemBuf");
+
+ o_txFailLanes.clear();
+ o_rxFailLanes.clear();
+
+ // Retrieve the Field eRepair lane numbers from the VPD
+ FAPI_TRY( retrieveRepairDataMemBuf(
+ i_target,
+ i_vpdType,
+ o_txFailLanes,
+ o_rxFailLanes),
+ "p9_io_erepairGetFailedLanesHwp() failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+fapi2::ReturnCode p9_io_erepairGetFailedLanesHwp(
+ const fapi2::Target < fapi2::TARGET_TYPE_DMI >& i_target,
+ EREPAIR::erepairVpdType i_vpdType,
+ const uint8_t i_clkGroup,
+ std::vector<uint8_t>& o_txFailLanes,
+ std::vector<uint8_t>& o_rxFailLanes)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_INF(">> erepairGetFailedLanesHwp - DMI");
+
+ o_txFailLanes.clear();
+ o_rxFailLanes.clear();
+
+ // Retrieve the Field eRepair lane numbers from the VPD
+ FAPI_TRY( retrieveRepairDataDMI(
+ i_target,
+ i_vpdType,
+ o_txFailLanes,
+ o_rxFailLanes),
+ "p9_io_erepairGetFailedLanesHwp() failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+fapi_try_exit:
+ return fapi2::current_err;
+}
#endif
diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_erepairGetFailedLanesHwp.mk b/src/import/chips/p9/procedures/hwp/io/p9_io_erepairGetFailedLanesHwp.mk
deleted file mode 100644
index 554d5ecd0..000000000
--- a/src/import/chips/p9/procedures/hwp/io/p9_io_erepairGetFailedLanesHwp.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-# IBM_PROLOG_BEGIN_TAG
-# This is an automatically generated prolog.
-#
-# $Source: src/import/chips/p9/procedures/hwp/io/p9_io_erepairGetFailedLanesHwp.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
-
-PROCEDURE=p9_io_erepairGetFailedLanesHwp
-$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_erepairSetFailedLanesHwp.C b/src/import/chips/p9/procedures/hwp/io/p9_io_erepairSetFailedLanesHwp.C
deleted file mode 100755
index 7b32a9766..000000000
--- a/src/import/chips/p9/procedures/hwp/io/p9_io_erepairSetFailedLanesHwp.C
+++ /dev/null
@@ -1,1134 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/io/p9_io_erepairSetFailedLanesHwp.C $ */
-/* */
-/* 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 */
-///
-/// @file p9_io_erepairSetFailedLanesHwp.C
-/// @brief FW Team HWP that accesses the fail lanes of Fabric and Memory buses.
-///
-//----------------------------------------------------------------------------
-// *HWP HWP Owner : Chris Steffen <cwsteffen@us.ibm.com>
-// *HWP HWP Backup Owner: Gary Peterson <garyp@us.ibm.com>
-// *HWP FW Owner : Sumit Kumar <sumit_kumar@in.ibm.com>
-// *HWP Team : IO
-// *HWP Level : 2
-// *HWP Consumed by : FSP:HB
-//----------------------------------------------------------------------------
-
-#include <fapi2.H>
-#include <p9_io_erepairConsts.H>
-#include <p9_io_erepairSetFailedLanesHwp.H>
-#include <mvpd_access.H>
-
-using namespace EREPAIR;
-using namespace fapi2;
-
-/******************************************************************************
- * Forward Declarations
- *****************************************************************************/
-
-/**
- * @brief Function called by the FW Team HWP that writes the data to Field VPD.
- * This function calls fapiSetMvpdField to write the VPD.
- *
- * @param[in] i_target Reference to X-Bus or O-Bus or MCS target
- * @param[in] i_vpdType Specifies which VPD (MNFG or Field) to access.
- * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
- * @param[in] i_txFailLanes Reference to a vector that has eRepair fail
- * lane numbers of the Tx sub-interface.
- * @param[in] i_rxFailLanes Reference to a vector that has eRepair fail
- * lane numbers of the Rx sub-interface.
- *
- * @return ReturnCode
- */
-template<fapi2::TargetType K>
-fapi2::ReturnCode writeRepairDataToVPD(
- const fapi2::Target < K >& i_target,
- erepairVpdType i_vpdType,
- const uint8_t i_clkGroup,
- const std::vector<uint8_t>& i_txFailLanes,
- const std::vector<uint8_t>& i_rxFailLanes);
-
-/**
- * @brief Function called by the FW Team HWP that updates the passed buffer
- * with the eRepair faillane numbers.
- *
- * @param[in] i_target Reference to X-Bus or O-Bus or MCS target
- * @param[in] i_txFailLanes Reference to a vector that has the Tx side faillane
- * numbers that need to be updated to the o_buf buffer
- * @param[in] i_rxFailLanes Reference to a vector that has the Rx side faillane
- * numbers that need to be updated to the o_buf buffer
- * @param[in] i_bufSz This is the size of passed buffer in terms of bytes
- * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
- * @param[o] o_buf This is the buffer that has the eRepair records
- * that needs to be written to the VPD
- *
- * @return ReturnCode
- */
-template<fapi2::TargetType K>
-fapi2::ReturnCode writeRepairLanesToBuf(
- const fapi2::Target < K >& i_target,
- const std::vector<uint8_t>& i_txFailLanes,
- const std::vector<uint8_t>& i_rxFailLanes,
- const uint32_t i_bufSz,
- const uint8_t i_clkGroup,
- uint8_t* o_buf);
-
-/**
- * @brief Function called by the FW Team HWP that updates the passed buffer
- * with the eRepair faillane numbers of a specified interface.
- *
- * @param[in] i_target Reference to X-Bus or O-Bus or MCS target
- * @param[in] i_interface This indicates the sub-interface type the passed
- * faillane vector represents
- * @param[in] i_bufSz This is the size of passed buffer in terms of bytes
- * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
- * @param[in] i_failLanes Reference to a vector that has the faillane numbers
- * that need to be updated to the o_buf buffer
- * @param[o] o_buf This is the buffer that has the eRepair records
- * that needs to be written to the VPD
- *
- * @return ReturnCode
- */
-template<fapi2::TargetType K>
-fapi2::ReturnCode updateRepairLanesToBuf(
- const fapi2::Target < K >& i_target,
- const interfaceType i_interface,
- const uint32_t i_bufSz,
- const uint8_t i_clkGroup,
- const std::vector<uint8_t>& i_failLanes,
- uint8_t* o_buf);
-
-/**
- * @brief Function called by the FW Team HWP that updates the passed buffer
- * with the eRepair faillane numbers of a specified interface.
- *
- * @param[in] i_target Reference to X-Bus or O-Bus or MCS target
- * @param[in] i_busInterface This indicates the sub-interface type the passed
- * faillane vector represents
- * @param[in] i_repairLane Reference to the faillane number
- * that need to be updated to fail bits field
- * @param[o] o_failBit This is the failed lanes data that maintains the
- * eRepair record that needs to be updated with fail
- * lane number
- *
- * @return ReturnCode
- */
-template<fapi2::TargetType K>
-fapi2::ReturnCode gatherRepairLanes(
- const fapi2::Target < K >& i_target,
- uint8_t i_busInterface,
- uint8_t i_repairLane,
- uint32_t* o_failBit);
-
-
-/******************************************************************************
- * Accessor HWP
- *****************************************************************************/
-
-template<fapi2::TargetType K>
-fapi2::ReturnCode p9_io_erepairSetFailedLanesHwp(
- const fapi2::Target < K >& i_target,
- erepairVpdType i_vpdType,
- const uint8_t i_clkGroup,
- const std::vector<uint8_t>& i_txFailLanes,
- const std::vector<uint8_t>& i_rxFailLanes)
-{
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
- fapi2::Target<fapi2::TARGET_TYPE_MCS> l_mcsTgt;
-
- FAPI_INF(">> erepairSetFailedLanesHwp");
-
- FAPI_ASSERT(( (i_txFailLanes.size() != 0) || (i_rxFailLanes.size() != 0) ),
- fapi2::P9_EREPAIR_NO_RX_TX_FAILED_LANES_ERR()
- .set_TX_LANE(i_txFailLanes.size()).set_RX_LANE(i_rxFailLanes.size()),
- "ERROR: No Tx/Rx fail lanes were provided");
-
- FAPI_TRY( writeRepairDataToVPD(
- i_target,
- i_vpdType,
- i_clkGroup,
- i_txFailLanes,
- i_rxFailLanes),
- "p9_io_erepairSetFailedLanesHwp() failed w/rc=0x%x",
- (uint64_t)current_err );
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-template ReturnCode p9_io_erepairSetFailedLanesHwp<TARGET_TYPE_XBUS>(
- const fapi2::Target <TARGET_TYPE_XBUS>& i_target,
- erepairVpdType i_vpdType,
- const uint8_t i_clkGroup,
- const std::vector<uint8_t>& o_txFailLanes,
- const std::vector<uint8_t>& o_rxFailLanes);
-
-template<fapi2::TargetType K>
-fapi2::ReturnCode writeRepairDataToVPD(
- const fapi2::Target < K >& i_target,
- erepairVpdType i_vpdType,
- const uint8_t i_clkGroup,
- const std::vector<uint8_t>& i_txFailLanes,
- const std::vector<uint8_t>& i_rxFailLanes)
-{
- fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_procTarget;
- std::vector<fapi2::Target<fapi2::TARGET_TYPE_MBA_CHIPLET>> l_mbaChiplets;
- fapi2::Target<fapi2::TARGET_TYPE_MBA> l_mbaTarget;
-
- uint8_t* l_retBuf = NULL;
- uint32_t l_bufSize = 0;
-#ifdef P9_CUMULUS
- uint8_t l_customDimm;
-#endif
- FAPI_DBG(">> writeRepairDataToVPD");
-
- if(i_target.getType() == TARGET_TYPE_MEMBUF_CHIP)
- {
-#ifdef P9_CUMULUS
- fapi2::MBvpdRecord l_vpdRecord = MBVPD_RECORD_VEIR;
-
- if(i_vpdType == EREPAIR_VPD_MNFG)
- {
- l_vpdRecord = MBVPD_RECORD_MER0;
- }
-
- /*** Read the data from the FRU VPD ***/
-
- // Determine the size of the eRepair data in the Centaur VPD
- FAPI_TRY( getMBvpdField(
- l_vpdRecord,
- MBVPD_KEYWORD_PDI,
- i_target,
- NULL,
- l_bufSize),
- "VPD size read failed w/rc=0x%x",
- (uint64_t)current_err );
-
- // Get the connected MBA chiplet and determine whether we have CDIMM
- l_rc = fapiGetChildChiplets(i_target,
- fapi2::TARGET_TYPE_MBA_CHIPLET,
- l_mbaChiplets,
- fapi2::TARGET_STATE_FUNCTIONAL);
-
- FAPI_ASSERT( ((uint64_t)l_rc == 0x0) || (0 != l_mbaChiplets.size()),
- fapi2::P9_EREPAIR_CHILD_MBA_TARGETS_ERR()
- .set_ERROR(l_rc),
- "ERROR: During get child MBA targets");
-
- l_mbaTarget = l_mbaChiplets[0];
- std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>> l_target_dimm_array;
-
- FAPI_TRY( fapiGetAssociatedDimms(
- l_mbaTarget,
- l_target_dimm_array),
- "fapiGetAssociatedDimms() failed w/rc=0x%x",
- (uint64_t)current_err );
-
- if(0 != l_target_dimm_array.size())
- {
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SPD_CUSTOM,
- l_target_dimm_array[0],
- l_customDimm));
- }
- else
- {
- l_customDimm = fapi2::ENUM_ATTR_SPD_CUSTOM_NO;
- }
-
- if( (l_customDimm == fapi2::ENUM_ATTR_SPD_CUSTOM_YES) || (l_bufSize == 0) )
- {
- if((l_bufSize == 0) ||
- ((i_vpdType == EREPAIR_VPD_FIELD) &&
- (l_bufSize > EREPAIR_MEM_FIELD_VPD_SIZE_PER_CENTAUR)) ||
- ((i_vpdType == EREPAIR_VPD_MNFG) &&
- (l_bufSize > EREPAIR_MEM_MNFG_VPD_SIZE_PER_CENTAUR)))
- {
- FAPI_ASSERT(false,
- fapi2::P9_EREPAIR_ACCESSOR_HWP_INVALID_MEM_VPD_SIZE_ERR()
- .set_ERROR(current_err),
- "ERROR: Invalid MEM VPD size");
- }
- }
-
- // Allocate memory for buffer
- l_retBuf = new uint8_t[l_bufSize];
-
- FAPI_ASSERT(l_retBuf != NULL,
- fapi2::P9_EREPAIR_ACCESSOR_HWP_MEMORY_ALLOC_FAIL_ERR()
- .set_BUF_SIZE(l_bufSize),
- "ERROR: Failed to allocate memory size");
-
- // Retrieve the Field eRepair data from the Centaur FRU VPD
- FAPI_TRY( getMBvpdField(
- l_vpdRecord,
- MBVPD_KEYWORD_PDI,
- i_target,
- l_retBuf,
- l_bufSize),
- "Centaur FRU VPD read failed w/rc=0x%x",
- (uint64_t)current_err );
-
- /*** Update the new eRepair data to the buffer ***/
- FAPI_TRY( writeRepairLanesToBuf(
- i_target,
- i_txFailLanes,
- i_rxFailLanes,
- l_bufSize,
- i_clkGroup,
- l_retBuf),
- "Update erepair data to buffer failed w/rc=0x%x",
- (uint64_t)current_err );
-
- /*** Write the updated eRepair buffer back to Centaur FRU VPD ***/
- FAPI_TRY( setMBvpdField(
- l_vpdRecord,
- MBVPD_KEYWORD_PDI,
- i_target,
- l_retBuf,
- l_bufSize),
- "Update erepair data to VPD failed w/rc=0x%x",
- (uint64_t)current_err );
-#endif
- } // end of(targetType == MEMBUF)
- else
- {
- // Determine the Processor target
- l_procTarget = i_target.template getParent<TARGET_TYPE_PROC_CHIP>();
-
- fapi2::MvpdRecord l_vpdRecord = MVPD_RECORD_VWML;
-
- if(i_vpdType == EREPAIR_VPD_MNFG)
- {
- l_vpdRecord = MVPD_RECORD_MER0;
- }
-
- /*** Read the data from the Module VPD ***/
-
- // Determine the size of the eRepair data in the VPD
- FAPI_TRY( getMvpdField(
- l_vpdRecord,
- MVPD_KEYWORD_PDI,
- l_procTarget,
- NULL,
- l_bufSize),
- "VPD size read failed w/rc=0x%x",
- (uint64_t)current_err );
-
- if((l_bufSize == 0) ||
- ((i_vpdType == EREPAIR_VPD_FIELD) &&
- (l_bufSize > EREPAIR_P9_MODULE_VPD_FIELD_SIZE)) ||
- ((i_vpdType == EREPAIR_VPD_MNFG) &&
- (l_bufSize > EREPAIR_P9_MODULE_VPD_MNFG_SIZE)))
- {
- FAPI_ASSERT(false,
- fapi2::P9_EREPAIR_ACCESSOR_HWP_INVALID_FABRIC_VPD_SIZE_ERR()
- .set_ERROR(current_err),
- "ERROR: Invalid Fabric VPD size");
- }
-
- // Allocate memory for buffer
- l_retBuf = new uint8_t[l_bufSize];
-
- FAPI_ASSERT(l_retBuf != NULL,
- fapi2::P9_EREPAIR_ACCESSOR_HWP_MEMORY_ALLOC_FAIL_ERR()
- .set_BUF_SIZE(l_bufSize),
- "ERROR: Failed to allocate memory size");
-
- // Retrieve the Field eRepair data from the MVPD
- FAPI_TRY( getMvpdField(
- l_vpdRecord,
- MVPD_KEYWORD_PDI,
- l_procTarget,
- l_retBuf,
- l_bufSize),
- "VPD read failed w/rc=0x%x",
- (uint64_t)current_err );
-
- /*** Update the new eRepair data to the buffer ***/
- FAPI_TRY( writeRepairLanesToBuf(
- i_target,
- i_txFailLanes,
- i_rxFailLanes,
- l_bufSize,
- i_clkGroup,
- l_retBuf),
- "writeRepairLanesToBuf() failed w/rc=0x%x",
- (uint64_t)current_err );
-
- /*** Write the updated eRepair buffer back to MVPD ***/
- FAPI_TRY( setMvpdField(
- l_vpdRecord,
- MVPD_KEYWORD_PDI,
- l_procTarget,
- l_retBuf,
- l_bufSize),
- "setMvpdField()-Update erepair data to VPD failed w/rc=0x%x",
- (uint64_t)current_err );
- }
-
- // Delete the buffer which has Field eRepair data
- delete[] l_retBuf;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-
-template<fapi2::TargetType K>
-fapi2::ReturnCode writeRepairLanesToBuf(
- const fapi2::Target < K >& i_target,
- const std::vector<uint8_t>& i_txFailLanes,
- const std::vector<uint8_t>& i_rxFailLanes,
- const uint32_t i_bufSz,
- const uint8_t i_clkGroup,
- uint8_t* o_buf)
-{
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
-
- FAPI_DBG(">> writeRepairLanesToBuf");
-
- if(i_txFailLanes.size())
- {
- /*** Lets update the tx side fail lane vector to the VPD ***/
- FAPI_TRY( updateRepairLanesToBuf(
- i_target,
- DRIVE,
- i_bufSz,
- i_clkGroup,
- i_txFailLanes,
- o_buf),
- "updateRepairLanesToBuf(DRIVE) failed w/rc=0x%x",
- (uint64_t)current_err );
- }
-
- if(i_rxFailLanes.size())
- {
- /*** Lets update the rx side fail lane vector to the VPD ***/
- FAPI_TRY( updateRepairLanesToBuf(
- i_target,
- RECEIVE,
- i_bufSz,
- i_clkGroup,
- i_rxFailLanes,
- o_buf),
- "updateRepairLanesToBuf(RECEIVE) failed w/rc=0x%x",
- (uint64_t)current_err );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-template<fapi2::TargetType K>
-fapi2::ReturnCode updateRepairLanesToBuf(
- const fapi2::Target < K >& i_target,
- const interfaceType i_interface,
- const uint32_t i_bufSz,
- const uint8_t i_clkGroup,
- const std::vector<uint8_t>& i_failLanes,
- uint8_t* o_buf)
-{
- fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
- uint32_t l_numRepairs = 0;
- uint32_t l_newNumRepairs = 0;
- uint32_t l_repairCnt = 0;
- uint32_t l_bytesParsed = 0;
- uint8_t l_repairLane = 0;
- uint32_t l_repairDataSz = 0;
- uint8_t* l_vpdPtr = NULL;
- uint8_t* l_vpdDataPtr = NULL;
- uint8_t* l_vpdWritePtr = NULL;
- eRepairHeader* l_vpdHeadPtr = NULL;
- eRepairPowerBus* l_overWritePtr = NULL;
- bool l_overWrite = false;
- uint8_t l_chipNum = 0;
- uint32_t l_chipPosition = 0;
- bool l_bClkGroupFound = false;
-#ifdef P9_CUMULUS
- fapi2::Target<fapi2::TARGET_TYPE_MCS> l_mcsTarget;
-#endif
- std::vector<uint8_t>::const_iterator l_it;
- ATTR_CHIP_UNIT_POS_Type l_busNum;
-
- FAPI_DBG(">> updateRepairLanesToBuf, interface: %s",
- i_interface == DRIVE ? "Drive" : "Receive");
-
- {
- l_repairDataSz = sizeof(eRepairPowerBus); // Size of memory Bus and
- // fabric Bus eRepair data
- // is same.
- // Read the header and count information
- l_vpdPtr = o_buf; // point to the start of header data
- l_vpdHeadPtr = reinterpret_cast<eRepairHeader*> (l_vpdPtr);
-
- l_numRepairs = l_newNumRepairs = l_vpdHeadPtr->availNumRecord;
-
- // We've read the header data, increment bytes parsed
- l_bytesParsed = sizeof(eRepairHeader);
-
- // Get a pointer to the start of repair data
- l_vpdPtr += sizeof(eRepairHeader);
-
- if(i_target.getType() == fapi2::TARGET_TYPE_MEMBUF_CHIP)
- {
-#ifdef P9_CUMULUS
- FAPI_TRY( fapiGetOtherSideOfMemChannel(
- i_target,
- l_mcsTarget,
- fapi2::TARGET_STATE_FUNCTIONAL),
- "fapiGetOtherSideOfMemChannel() failed w/rc=0x%x",
- (uint64_t)current_err );
-
- // Get the bus number
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
- l_mcsTarget,
- l_busNum));
-#endif
- }
- else
- {
- // Get the bus number
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
- i_target,
- l_busNum));
- }
-
- // Get the chip target
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_chipTarget;
- l_chipTarget = i_target.template getParent<TARGET_TYPE_PROC_CHIP>();
-
- // Get the chip number
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_POS,
- l_chipTarget,
- l_chipPosition));
-
-
- // This is needed because we can only store and compare a uint8_t
- // value. For our purpose the value in l_chipPosition (Proc Position and
- // Centaur Position) will always be within the range of uint8_t
- l_chipNum = l_chipPosition;
-
- /*** Lets update the fail lane vector to the Buffer ***/
- // Create a structure of eRepair data that we will be matching
- // in the buffer.
- struct erepairDataMatch
- {
- interfaceType intType;
- fapi2::TargetType tgtType;
- union repairData
- {
- eRepairPowerBus fabBus;
- eRepairMemBus memBus;
- } bus;
- };
-
- // Create an array of the above match structure to have all the
- // combinations of Fabric and Memory repair data
- erepairDataMatch l_repairMatch[14] =
- {
- {
- // index 0 - X0A (clock group 0)
- DRIVE,
- TARGET_TYPE_XBUS_ENDPOINT,
- {
- // repairData
- {
- // fabBus
- {
- // device
- l_chipNum,// processor_id
- l_busNum, // fabricBus
- },
- PROCESSOR_EDIP, // type
- PBUS_DRIVER, // interface
- },
- },
- },
- {
- // index 1 - X0A (clock group 0)
- RECEIVE,
- TARGET_TYPE_XBUS_ENDPOINT,
- {
- // repairData
- {
- // fabBus
- {
- // device
- l_chipNum,// processor_id
- l_busNum, // fabricBus
- },
- PROCESSOR_EDIP, // type
- PBUS_RECEIVER, // interface
- },
- },
- },
- {
- // index 2 - X0A (clock group 1)
- DRIVE,
- TARGET_TYPE_XBUS_ENDPOINT,
- {
- // repairData
- {
- // fabBus
- {
- // device
- l_chipNum,// processor_id
- l_busNum, // fabricBus
- },
- PROCESSOR_EDIP, // type
- PBUS_DRIVER, // interface
- },
- },
- },
- {
- // index 3 - X0A (clock group 1)
- RECEIVE,
- TARGET_TYPE_XBUS_ENDPOINT,
- {
- // repairData
- {
- // fabBus
- {
- // device
- l_chipNum,// processor_id
- l_busNum, // fabricBus
- },
- PROCESSOR_EDIP, // type
- PBUS_RECEIVER, // interface
- },
- },
- },
- {
- // index 4 - X1A (clock group 0)
- DRIVE,
- TARGET_TYPE_XBUS_ENDPOINT,
- {
- // repairData
- {
- // fabBus
- {
- // device
- l_chipNum,// processor_id
- l_busNum, // fabricBus
- },
- PROCESSOR_EDIP, // type
- PBUS_DRIVER, // interface
- },
- },
- },
- {
- // index 5 - X1A (clock group 0)
- RECEIVE,
- TARGET_TYPE_XBUS_ENDPOINT,
- {
- // repairData
- {
- // fabBus
- {
- // device
- l_chipNum,// processor_id
- l_busNum, // fabricBus
- },
- PROCESSOR_EDIP, // type
- PBUS_RECEIVER, // interface
- },
- },
- },
- {
- // index 6 - X1A (clock group 1)
- DRIVE,
- TARGET_TYPE_XBUS_ENDPOINT,
- {
- // repairData
- {
- // fabBus
- {
- // device
- l_chipNum,// processor_id
- l_busNum, // fabricBus
- },
- PROCESSOR_EDIP, // type
- PBUS_DRIVER, // interface
- },
- },
- },
- {
- // index 7 - X1A (clock group 1)
- RECEIVE,
- TARGET_TYPE_XBUS_ENDPOINT,
- {
- // repairData
- {
- // fabBus
- {
- // device
- l_chipNum,// processor_id
- l_busNum, // fabricBus
- },
- PROCESSOR_EDIP, // type
- PBUS_RECEIVER, // interface
- },
- },
- },
- {
- // index 8
- DRIVE,
- TARGET_TYPE_OBUS,
- {
- // repairData
- {
- // fabBus
- {
- // device
- l_chipNum,// processor_id
- l_busNum, // fabricBus
- },
- PROCESSOR_OPT, // type
- PBUS_DRIVER, // interface
- },
- },
- },
- {
- // index 9
- RECEIVE,
- TARGET_TYPE_OBUS,
- {
- // repairData
- {
- // fabBus
- {
- // device
- l_chipNum,// processor_id
- l_busNum, // fabricBus
- },
- PROCESSOR_OPT, // type
- PBUS_RECEIVER, // interface
- },
- },
- },
- {
- // index 10
- DRIVE,
- TARGET_TYPE_MCS_CHIPLET,
- {
- // repairData
- {
- // fabBus
- {
- // device
- l_chipNum,// proc_centaur_id
- l_busNum, // memChannel
- },
- MEMORY_EDIP, // type
- DMI_MCS_DRIVE,// interface
- },
- },
- },
- {
- // index 11
- DRIVE,
- TARGET_TYPE_MEMBUF_CHIP,
- {
- // repairData
- {
- // memBus
- {
- // device
- l_chipNum,// proc_centaur_id
- l_busNum, // memChannel
- },
- MEMORY_EDIP, // type
- DMI_MEMBUF_DRIVE,// interface
- },
- },
- },
- {
- // index 12
- RECEIVE,
- TARGET_TYPE_MCS_CHIPLET,
- {
- // repairData
- {
- // memBus
- {
- // device
- l_chipNum,// proc_centaur_id
- l_busNum, // memChannel
- },
- MEMORY_EDIP, // type
- DMI_MCS_RECEIVE, // interface
- },
- },
- },
- {
- // index 13
- RECEIVE,
- TARGET_TYPE_MEMBUF_CHIP,
- {
- // repairData
- {
- // memBus
- {
- // device
- l_chipNum,// proc_centaur_id
- l_busNum, // memChannel
- },
- MEMORY_EDIP, // type
- DMI_MEMBUF_RECEIVE, // interface
- },
- },
- }
- };
-
- l_vpdDataPtr = l_vpdPtr;
- l_repairCnt = 0;
-
- // Pick each faillane for copying into buffer
- for(l_it = i_failLanes.begin();
- l_it != i_failLanes.end();
- l_it++, (l_vpdDataPtr += l_repairDataSz))
- {
- l_repairLane = *l_it;
- l_overWrite = false;
- l_vpdWritePtr = NULL;
-
- // Parse the VPD for fabric and memory eRepair records
- for(;
- (l_repairCnt < l_numRepairs) && (l_bytesParsed <= i_bufSz);
- l_repairCnt++, (l_vpdDataPtr += l_repairDataSz))
- {
- l_overWritePtr =
- reinterpret_cast<eRepairPowerBus*> (l_vpdDataPtr);
-
- // Lets find the matching fabric
- for(uint8_t l_loop = 0; l_loop < 14; l_loop++)
- {
- if((i_target.getType() == TARGET_TYPE_XBUS) ||
- (i_target.getType() == TARGET_TYPE_OBUS))
- {
- if((i_interface == l_repairMatch[l_loop].intType) &&
- (i_target.getType() == l_repairMatch[l_loop].tgtType) &&
- ((l_overWritePtr->device).processor_id ==
- l_repairMatch[l_loop].bus.fabBus.device.processor_id) &&
- (l_overWritePtr->type ==
- l_repairMatch[l_loop].bus.fabBus.type) &&
- (l_overWritePtr->interface ==
- l_repairMatch[l_loop].bus.fabBus.interface) &&
- (l_overWritePtr->device.fabricBus ==
- l_repairMatch[l_loop].bus.fabBus.device.fabricBus))
- {
- if(i_clkGroup > 0 && !l_bClkGroupFound)
- {
- l_bClkGroupFound = true;
- continue;
- }
-
- // update the failBit number
- {
- uint32_t temp = (uint32_t)(l_overWritePtr->failBit);
- uint32_t* tptr = &temp;
- FAPI_TRY( gatherRepairLanes(
- i_target,
- l_overWritePtr->interface,
- l_repairLane,
- tptr),
- "gatherRepairLanes() failed w/rc=0x%x",
- (uint64_t)current_err );
- l_overWritePtr->failBit = temp;
- }
-
- // Increment the count of parsed bytes
- l_bytesParsed += l_repairDataSz;
-
- l_repairCnt++;
- l_overWrite = true;
-
- break;
- }
- }
- else if((i_target.getType() == TARGET_TYPE_MCS_CHIPLET) ||
- (i_target.getType() == TARGET_TYPE_MEMBUF_CHIP) )
- {
- if((i_interface == l_repairMatch[l_loop].intType) &&
- (i_target.getType() == l_repairMatch[l_loop].tgtType) &&
- ((l_overWritePtr->device).processor_id ==
- l_repairMatch[l_loop].bus.memBus.device.proc_centaur_id) &&
- (l_overWritePtr->type ==
- l_repairMatch[l_loop].bus.memBus.type) &&
- (l_overWritePtr->interface ==
- l_repairMatch[l_loop].bus.memBus.interface) &&
- (l_overWritePtr->device.fabricBus ==
- l_repairMatch[l_loop].bus.memBus.device.memChannel))
- {
- // update the failBit number
- {
- uint32_t temp = (uint32_t)(l_overWritePtr->failBit);
- uint32_t* tptr = &temp;
- FAPI_TRY( gatherRepairLanes(
- i_target,
- l_overWritePtr->interface,
- l_repairLane,
- tptr),
- "gatherRepairLanes() failed w/rc=0x%x",
- (uint64_t)current_err );
- l_overWritePtr->failBit = temp;
- }
-
- // Increment the count of parsed bytes
- l_bytesParsed += l_repairDataSz;
-
- l_repairCnt++;
- l_overWrite = true;
-
- break;
- }
- }
- } // end of for(l_loop < 14)
-
- if(l_overWrite == true)
- {
- // Go for the next repairLane
- break;
- }
- } // end of for(vpd Parsing)
-
- // Check if we have parsed more bytes than the passed size
- if((l_vpdWritePtr == NULL) &&
- (l_bytesParsed > i_bufSz) &&
- (l_repairCnt < l_numRepairs))
- {
- FAPI_ASSERT(false,
- fapi2::P9_EREPAIR_MVPD_FULL_ERR()
- .set_VAL_BYTE_PARSED(l_bytesParsed)
- .set_VAL_BUF_SIZE(i_bufSz)
- .set_VAL_REPAIR_CNT(l_repairCnt)
- .set_VAL_NUM_REPAIR(l_numRepairs),
- "ERROR: from updateRepairLanesToBuf - MVPD full");
- }
-
- // Add at the end
- if(l_overWrite == false)
- {
- if(l_vpdWritePtr == NULL)
- {
- // We are writing at the end
- l_vpdWritePtr = l_vpdDataPtr;
- }
-
- if((i_target.getType() == TARGET_TYPE_XBUS) ||
- (i_target.getType() == TARGET_TYPE_OBUS))
- {
- // Make sure we are not writing more records than the size
- // allocated in the VPD
- FAPI_ASSERT(l_bytesParsed <= i_bufSz,
- fapi2::P9_EREPAIR_MVPD_FULL_ERR()
- .set_VAL_BYTE_PARSED(l_bytesParsed)
- .set_VAL_BUF_SIZE(i_bufSz)
- .set_VAL_REPAIR_CNT(l_repairCnt)
- .set_VAL_NUM_REPAIR(l_numRepairs),
- "ERROR: from updateRepairLanesToBuf - MVPD full");
-
- eRepairPowerBus* l_fabricBus =
- reinterpret_cast<eRepairPowerBus*>(l_vpdWritePtr);
-
- l_fabricBus->device.processor_id = l_chipNum;
- l_fabricBus->device.fabricBus = l_busNum;
-
- if(i_interface == DRIVE)
- {
- l_fabricBus->interface = PBUS_DRIVER;
- }
- else if(i_interface == RECEIVE)
- {
- l_fabricBus->interface = PBUS_RECEIVER;
- }
-
- if(i_target.getType() == TARGET_TYPE_XBUS)
- {
- l_fabricBus->type = PROCESSOR_EDIP;
- }
- else if(i_target.getType() == TARGET_TYPE_OBUS)
- {
- l_fabricBus->type = PROCESSOR_OPT;
- }
-
- {
- uint32_t temp = (uint32_t)(l_fabricBus->failBit);
- uint32_t* tptr = &temp;
- FAPI_TRY( gatherRepairLanes(
- i_target,
- l_fabricBus->interface,
- l_repairLane,
- tptr),
- "gatherRepairLanes() failed w/rc=0x%x",
- (uint64_t)current_err );
- l_fabricBus->failBit = temp;
- }
-
- l_newNumRepairs++;
-
- // Increment the count of parsed bytes
- l_bytesParsed += l_repairDataSz;
-#ifndef _BIG_ENDIAN
- // We are on a Little Endian system.
- // Need to swap the nibbles of structure - eRepairPowerBus
-
- l_vpdWritePtr[2] = ((l_vpdWritePtr[2] >> 4) |
- (l_vpdWritePtr[2] << 4));
-#endif
- }
- else if((i_target.getType() == TARGET_TYPE_MCS_CHIPLET) ||
- (i_target.getType() == TARGET_TYPE_MEMBUF_CHIP) )
- {
- // Make sure we are not writing more records than the size
- // allocated in the VPD
- FAPI_ASSERT(l_bytesParsed == i_bufSz,
- fapi2::P9_EREPAIR_MBVPD_FULL_ERR()
- .set_ERROR(l_bytesParsed),
- "ERROR: from updateRepairLanesToBuf - MBVPD full");
-
- eRepairMemBus* l_memBus =
- reinterpret_cast<eRepairMemBus*>(l_vpdWritePtr);
-
- l_memBus->device.proc_centaur_id = l_chipNum;
- l_memBus->device.memChannel = l_busNum;
- l_memBus->type = MEMORY_EDIP;
-
- if(i_interface == DRIVE)
- {
- if(i_target.getType() == TARGET_TYPE_MCS_CHIPLET)
- {
- l_memBus->interface = DMI_MCS_DRIVE;
- }
- else if(i_target.getType() == TARGET_TYPE_MEMBUF_CHIP)
- {
- l_memBus->interface = DMI_MEMBUF_DRIVE;
- }
- }
- else if(i_interface == RECEIVE)
- {
- if(i_target.getType() == TARGET_TYPE_MCS_CHIPLET)
- {
- l_memBus->interface = DMI_MCS_RECEIVE;
- }
- else if(i_target.getType() == TARGET_TYPE_MEMBUF_CHIP)
- {
- l_memBus->interface = DMI_MEMBUF_RECEIVE;
- }
- }
-
- {
- uint32_t temp = (uint32_t)(l_memBus->failBit);
- uint32_t* tptr = &temp;
- FAPI_TRY( gatherRepairLanes(
- i_target,
- l_memBus->interface,
- l_repairLane,
- tptr),
- "gatherRepairLanes() failed w/rc=0x%x",
- (uint64_t)current_err );
- l_memBus->failBit = temp;
- }
-
- l_newNumRepairs++;
-
- // Increment the count of parsed bytes
- l_bytesParsed += l_repairDataSz;
-#ifndef _BIG_ENDIAN
- // We are on a Little Endian system.
- // Need to swap the nibbles of structure - eRepairMemBus
-
- l_vpdWritePtr[2] = ((l_vpdWritePtr[2] >> 4) |
- (l_vpdWritePtr[2] << 4));
-#endif
- }
- } // end of if(l_overWrite == false)
- } // end of for(failLanes)
- }
- // Update the eRepair count
- l_vpdHeadPtr->availNumRecord = l_newNumRepairs;
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-template<fapi2::TargetType K>
-fapi2::ReturnCode gatherRepairLanes(
- const fapi2::Target < K >& i_target,
- uint8_t i_busInterface,
- uint8_t i_repairLane,
- uint32_t* o_failBit)
-{
- fapi2::ReturnCode l_rc;
- uint8_t maxBusLanes = 0;
- uint32_t setBitPosition = (0x80000000);
-
- FAPI_DBG(">> setRepairLanes");
-
- // Check for target type and corresponding sub interface
- // to get max lanes supported per interface
- if(i_target.getType() == fapi2::TARGET_TYPE_OBUS)
- {
- maxBusLanes = OBUS_MAX_LANE_WIDTH; //OBUS
- }
- else if(i_target.getType() == fapi2::TARGET_TYPE_XBUS)
- {
- maxBusLanes = XBUS_MAX_LANE_WIDTH; //XBUS
- }
- else if((i_target.getType() == fapi2::TARGET_TYPE_MEMBUF_CHIP) ||
- (i_target.getType() == fapi2::TARGET_TYPE_MCS_CHIPLET)) //DMI
- {
- if( (i_busInterface == DMI_MCS_RECEIVE) ||
- (i_busInterface == DMI_MEMBUF_DRIVE) )
- {
- maxBusLanes = DMIBUS_DNSTREAM_MAX_LANE_WIDTH;
- }
- else if( (i_busInterface == DMI_MCS_DRIVE) ||
- (i_busInterface == DMI_MEMBUF_RECEIVE) )
- {
- maxBusLanes = DMIBUS_UPSTREAM_MAX_LANE_WIDTH;
- }
- }
-
- // Make sure repair lane value passed is within valid range as per the target type
- FAPI_ASSERT(i_repairLane < maxBusLanes,
- fapi2::P9_EREPAIR_INVALID_LANE_VALUE_ERR()
- .set_ERROR(i_repairLane)
- .set_TARGET(i_target),
- "ERROR: Invalid erepair lane value");
-
- // Update the fail bits data with the repair lane number failed
- *o_failBit |= (setBitPosition >> i_repairLane);
-
- // Get the failed lanes
- FAPI_INF("Updated Fail Lanes:%x", *o_failBit);
-
- FAPI_DBG("<< setRepairLanes");
-
-fapi_try_exit:
- return l_rc;
-}
-
diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_erepairSetFailedLanesHwp.H b/src/import/chips/p9/procedures/hwp/io/p9_io_erepairSetFailedLanesHwp.H
index ba51290cd..bf4897201 100755
--- a/src/import/chips/p9/procedures/hwp/io/p9_io_erepairSetFailedLanesHwp.H
+++ b/src/import/chips/p9/procedures/hwp/io/p9_io_erepairSetFailedLanesHwp.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -40,40 +40,2184 @@
#include <fapi2.H>
#include <p9_io_erepairConsts.H>
+#include <mvpd_access.H>
+#include <fapi2_mbvpd_access.H>
+
+/******************************************************************************
+ * Accessor HWP
+ *****************************************************************************/
+
+/**
+ * @brief Function called by the FW Team HWP that updates the passed buffer
+ * with the eRepair faillane numbers of a specified interface.
+ *
+ * @param[in] i_target Reference to X-Bus or O-Bus or DMI target
+ * @param[in] i_busInterface This indicates the sub-interface type the passed
+ * faillane vector represents
+ * @param[in] i_repairLane Reference to the faillane number
+ * that need to be updated to fail bits field
+ * @param[o] o_failBit This is the failed lanes data that maintains the
+ * eRepair record that needs to be updated with fail
+ * lane number
+ *
+ * @return ReturnCode
+ */
+template<fapi2::TargetType K>
+fapi2::ReturnCode gatherRepairLanes(
+ const fapi2::Target < K >& i_target,
+ uint8_t i_busInterface,
+ uint8_t i_repairLane,
+ uint32_t* o_failBit)
+{
+ fapi2::ReturnCode l_rc;
+ uint8_t maxBusLanes = 0;
+ uint32_t setBitPosition = (0x80000000);
+
+ FAPI_DBG(">> setRepairLanes");
+
+ // Check for target type and corresponding sub interface
+ // to get max lanes supported per interface
+ if(i_target.getType() == fapi2::TARGET_TYPE_OBUS)
+ {
+ maxBusLanes = EREPAIR::OBUS_MAX_LANE_WIDTH; //OBUS
+ }
+ else if(i_target.getType() == fapi2::TARGET_TYPE_XBUS)
+ {
+ maxBusLanes = EREPAIR::XBUS_MAX_LANE_WIDTH; //XBUS
+ }
+ else if((i_target.getType() == fapi2::TARGET_TYPE_MEMBUF_CHIP) ||
+ (i_target.getType() == fapi2::TARGET_TYPE_DMI))
+ {
+ if( (i_busInterface == EREPAIR::DMI_MCS_RECEIVE) ||
+ (i_busInterface == EREPAIR::DMI_MEMBUF_DRIVE) )
+ {
+ maxBusLanes = EREPAIR::DMIBUS_DNSTREAM_MAX_LANE_WIDTH;
+ }
+ else if( (i_busInterface == EREPAIR::DMI_MCS_DRIVE) ||
+ (i_busInterface == EREPAIR::DMI_MEMBUF_RECEIVE) )
+ {
+ maxBusLanes = EREPAIR::DMIBUS_UPSTREAM_MAX_LANE_WIDTH;
+ }
+ }
+
+ // Make sure repair lane value passed is within valid range as per the target type
+ FAPI_ASSERT(i_repairLane < maxBusLanes,
+ fapi2::P9_EREPAIR_INVALID_LANE_VALUE_ERR()
+ .set_ERROR(i_repairLane)
+ .set_TARGET(i_target),
+ "ERROR: Invalid erepair lane value");
+
+ // Update the fail bits data with the repair lane number failed
+ *o_failBit |= (setBitPosition >> i_repairLane);
+
+ // Get the failed lanes
+ FAPI_INF("Updated Fail Lanes:%x", *o_failBit);
+
+ FAPI_DBG("<< setRepairLanes");
+
+fapi_try_exit:
+ return l_rc;
+}
+
+/**
+ * @brief Function called by the FW Team HWP that updates the passed buffer
+ * with the eRepair faillane numbers of a specified interface.
+ *
+ * @param[in] i_target Reference to X-Bus target
+ * @param[in] i_interface This indicates the sub-interface type the passed
+ * faillane vector represents
+ * @param[in] i_bufSz This is the size of passed buffer in terms of bytes
+ * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
+ * @param[in] i_failLanes Reference to a vector that has the faillane numbers
+ * that need to be updated to the o_buf buffer
+ * @param[o] o_buf This is the buffer that has the eRepair records
+ * that needs to be written to the VPD
+ * (For Proc)
+ * @return ReturnCode
+ */
+template<fapi2::TargetType K>
+fapi2::ReturnCode updateRepairLanesToBufProc(
+ const fapi2::Target < K >& i_target,
+ const EREPAIR::interfaceType i_interface,
+ const uint32_t i_bufSz,
+ const uint8_t i_clkGroup,
+ const std::vector<uint8_t>& i_failLanes,
+ uint8_t* o_buf)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ uint32_t l_numRepairs = 0;
+ uint32_t l_newNumRepairs = 0;
+ uint32_t l_repairCnt = 0;
+ uint32_t l_bytesParsed = 0;
+ uint8_t l_repairLane = 0;
+ uint32_t l_repairDataSz = 0;
+ uint8_t* l_vpdPtr = NULL;
+ uint8_t* l_vpdDataPtr = NULL;
+ uint8_t* l_vpdWritePtr = NULL;
+ eRepairHeader* l_vpdHeadPtr = NULL;
+ eRepairPowerBus* l_overWritePtr = NULL;
+ bool l_overWrite = false;
+ uint8_t l_chipNum = 0;
+ uint32_t l_chipPosition = 0;
+ bool l_bClkGroupFound = false;
+ fapi2::Target<fapi2::TARGET_TYPE_DMI> l_dmiTarget;
+ std::vector<uint8_t>::const_iterator l_it;
+ fapi2::ATTR_CHIP_UNIT_POS_Type l_busNum;
+
+ FAPI_DBG(">> updateRepairLanesToBuf(XBUS), interface: %s",
+ i_interface == EREPAIR::DRIVE ? "Drive" : "Receive");
+
+ {
+ l_repairDataSz = sizeof(eRepairPowerBus); // Size of memory Bus and
+ // fabric Bus eRepair data
+ // is same.
+ // Read the header and count information
+ l_vpdPtr = o_buf; // point to the start of header data
+ l_vpdHeadPtr = reinterpret_cast<eRepairHeader*> (l_vpdPtr);
+
+ l_numRepairs = l_newNumRepairs = l_vpdHeadPtr->availNumRecord;
+
+ // We've read the header data, increment bytes parsed
+ l_bytesParsed = sizeof(eRepairHeader);
+
+ // Get a pointer to the start of repair data
+ l_vpdPtr += sizeof(eRepairHeader);
+
+ // Get the bus number
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
+ i_target,
+ l_busNum));
+
+ // Get the chip target
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_chipTarget;
+ l_chipTarget = i_target.template getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
+
+ // Get the chip number
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_POS,
+ l_chipTarget,
+ l_chipPosition));
+
+
+ // This is needed because we can only store and compare a uint8_t
+ // value. For our purpose the value in l_chipPosition (Proc Position and
+ // Centaur Position) will always be within the range of uint8_t
+ l_chipNum = l_chipPosition;
+
+ /*** Lets update the fail lane vector to the Buffer ***/
+ // Create a structure of eRepair data that we will be matching
+ // in the buffer.
+ struct erepairDataMatch
+ {
+ EREPAIR::interfaceType intType;
+ fapi2::TargetType tgtType;
+ union repairData
+ {
+ eRepairPowerBus fabBus;
+ eRepairMemBus memBus;
+ } bus;
+ };
+
+ // Create an array of the above match structure to have all the
+ // combinations of Fabric and Memory repair data
+ erepairDataMatch l_repairMatch[14] =
+ {
+ {
+ // index 0 - X0A (clock group 0)
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_DRIVER, // interface
+ },
+ },
+ },
+ {
+ // index 1 - X0A (clock group 0)
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_RECEIVER, // interface
+ },
+ },
+ },
+ {
+ // index 2 - X0A (clock group 1)
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_DRIVER, // interface
+ },
+ },
+ },
+ {
+ // index 3 - X0A (clock group 1)
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_RECEIVER, // interface
+ },
+ },
+ },
+ {
+ // index 4 - X1A (clock group 0)
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_DRIVER, // interface
+ },
+ },
+ },
+ {
+ // index 5 - X1A (clock group 0)
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_RECEIVER, // interface
+ },
+ },
+ },
+ {
+ // index 6 - X1A (clock group 1)
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_DRIVER, // interface
+ },
+ },
+ },
+ {
+ // index 7 - X1A (clock group 1)
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_RECEIVER, // interface
+ },
+ },
+ },
+ {
+ // index 8
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_OBUS,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_OPT, // type
+ EREPAIR::PBUS_DRIVER, // interface
+ },
+ },
+ },
+ {
+ // index 9
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_OBUS,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_OPT, // type
+ EREPAIR::PBUS_RECEIVER, // interface
+ },
+ },
+ },
+ {
+ // index 10
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_DMI,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// proc_centaur_id
+ l_busNum, // memChannel
+ },
+ EREPAIR::MEMORY_EDIP, // type
+ EREPAIR::DMI_MCS_DRIVE,// interface
+ },
+ },
+ },
+ {
+ // index 11
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_MEMBUF_CHIP,
+ {
+ // repairData
+ {
+ // memBus
+ {
+ // device
+ l_chipNum,// proc_centaur_id
+ l_busNum, // memChannel
+ },
+ EREPAIR::MEMORY_EDIP, // type
+ EREPAIR::DMI_MEMBUF_DRIVE,// interface
+ },
+ },
+ },
+ {
+ // index 12
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_DMI,
+ {
+ // repairData
+ {
+ // memBus
+ {
+ // device
+ l_chipNum,// proc_centaur_id
+ l_busNum, // memChannel
+ },
+ EREPAIR::MEMORY_EDIP, // type
+ EREPAIR::DMI_MCS_RECEIVE, // interface
+ },
+ },
+ },
+ {
+ // index 13
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_MEMBUF_CHIP,
+ {
+ // repairData
+ {
+ // memBus
+ {
+ // device
+ l_chipNum,// proc_centaur_id
+ l_busNum, // memChannel
+ },
+ EREPAIR::MEMORY_EDIP, // type
+ EREPAIR::DMI_MEMBUF_RECEIVE, // interface
+ },
+ },
+ }
+ };
+
+ l_vpdDataPtr = l_vpdPtr;
+ l_repairCnt = 0;
+
+ // Pick each faillane for copying into buffer
+ for(l_it = i_failLanes.begin();
+ l_it != i_failLanes.end();
+ l_it++, (l_vpdDataPtr += l_repairDataSz))
+ {
+ l_repairLane = *l_it;
+ l_overWrite = false;
+ l_vpdWritePtr = NULL;
+
+ // Parse the VPD for fabric and memory eRepair records
+ for(;
+ (l_repairCnt < l_numRepairs) && (l_bytesParsed <= i_bufSz);
+ l_repairCnt++, (l_vpdDataPtr += l_repairDataSz))
+ {
+ l_overWritePtr =
+ reinterpret_cast<eRepairPowerBus*> (l_vpdDataPtr);
+
+ // Lets find the matching fabric
+ for(uint8_t l_loop = 0; l_loop < 14; l_loop++)
+ {
+ {
+ if((i_interface == l_repairMatch[l_loop].intType) &&
+ (i_target.getType() == l_repairMatch[l_loop].tgtType) &&
+ ((l_overWritePtr->device).processor_id ==
+ l_repairMatch[l_loop].bus.fabBus.device.processor_id) &&
+ (l_overWritePtr->type ==
+ l_repairMatch[l_loop].bus.fabBus.type) &&
+ (l_overWritePtr->interface ==
+ l_repairMatch[l_loop].bus.fabBus.interface) &&
+ (l_overWritePtr->device.fabricBus ==
+ l_repairMatch[l_loop].bus.fabBus.device.fabricBus))
+ {
+ if(i_clkGroup > 0 && !l_bClkGroupFound)
+ {
+ l_bClkGroupFound = true;
+ continue;
+ }
+
+ // update the failBit number
+ {
+ uint32_t temp = (uint32_t)(l_overWritePtr->failBit);
+ uint32_t* tptr = &temp;
+ FAPI_TRY( gatherRepairLanes(
+ i_target,
+ l_overWritePtr->interface,
+ l_repairLane,
+ tptr),
+ "gatherRepairLanes() failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ l_overWritePtr->failBit = temp;
+ }
+
+ // Increment the count of parsed bytes
+ l_bytesParsed += l_repairDataSz;
+
+ l_repairCnt++;
+ l_overWrite = true;
+
+ break;
+ }
+ }
+ } // end of for(l_loop < 14)
+
+ if(l_overWrite == true)
+ {
+ // Go for the next repairLane
+ break;
+ }
+ } // end of for(vpd Parsing)
+
+ // Check if we have parsed more bytes than the passed size
+ if((l_vpdWritePtr == NULL) &&
+ (l_bytesParsed > i_bufSz) &&
+ (l_repairCnt < l_numRepairs))
+ {
+ FAPI_ASSERT(false,
+ fapi2::P9_EREPAIR_MVPD_FULL_ERR()
+ .set_VAL_BYTE_PARSED(l_bytesParsed)
+ .set_VAL_BUF_SIZE(i_bufSz)
+ .set_VAL_REPAIR_CNT(l_repairCnt)
+ .set_VAL_NUM_REPAIR(l_numRepairs),
+ "ERROR: from updateRepairLanesToBuf - MVPD full");
+ }
+
+ // Add at the end
+ if(l_overWrite == false)
+ {
+ if(l_vpdWritePtr == NULL)
+ {
+ // We are writing at the end
+ l_vpdWritePtr = l_vpdDataPtr;
+ }
+
+ {
+ // Make sure we are not writing more records than the size
+ // allocated in the VPD
+ FAPI_ASSERT(l_bytesParsed <= i_bufSz,
+ fapi2::P9_EREPAIR_MVPD_FULL_ERR()
+ .set_VAL_BYTE_PARSED(l_bytesParsed)
+ .set_VAL_BUF_SIZE(i_bufSz)
+ .set_VAL_REPAIR_CNT(l_repairCnt)
+ .set_VAL_NUM_REPAIR(l_numRepairs),
+ "ERROR: from updateRepairLanesToBuf - MVPD full");
+
+ eRepairPowerBus* l_fabricBus =
+ reinterpret_cast<eRepairPowerBus*>(l_vpdWritePtr);
+
+ l_fabricBus->device.processor_id = l_chipNum;
+ l_fabricBus->device.fabricBus = l_busNum;
+
+ if(i_interface == EREPAIR::DRIVE)
+ {
+ l_fabricBus->interface = EREPAIR::PBUS_DRIVER;
+ }
+ else if(i_interface == EREPAIR::RECEIVE)
+ {
+ l_fabricBus->interface = EREPAIR::PBUS_RECEIVER;
+ }
+
+ if(i_target.getType() == fapi2::TARGET_TYPE_XBUS)
+ {
+ l_fabricBus->type = EREPAIR::PROCESSOR_EDIP;
+ }
+ else if(i_target.getType() == fapi2::TARGET_TYPE_OBUS)
+ {
+ l_fabricBus->type = EREPAIR::PROCESSOR_OPT;
+ }
+
+ {
+ uint32_t temp = (uint32_t)(l_fabricBus->failBit);
+ uint32_t* tptr = &temp;
+ FAPI_TRY( gatherRepairLanes(
+ i_target,
+ l_fabricBus->interface,
+ l_repairLane,
+ tptr),
+ "gatherRepairLanes() failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ l_fabricBus->failBit = temp;
+ }
+
+ l_newNumRepairs++;
+
+ // Increment the count of parsed bytes
+ l_bytesParsed += l_repairDataSz;
+#ifndef _BIG_ENDIAN
+ // We are on a Little Endian system.
+ // Need to swap the nibbles of structure - eRepairPowerBus
+
+ l_vpdWritePtr[2] = ((l_vpdWritePtr[2] >> 4) |
+ (l_vpdWritePtr[2] << 4));
+#endif
+ }
+ } // end of if(l_overWrite == false)
+ } // end of for(failLanes)
+ }
+ // Update the eRepair count
+ l_vpdHeadPtr->availNumRecord = l_newNumRepairs;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/**
+ * @brief Function called by the FW Team HWP that updates the passed buffer
+ * with the eRepair faillane numbers of a specified interface.
+ *
+ * @param[in] i_target Reference to MEMBUF target
+ * @param[in] i_interface This indicates the sub-interface type the passed
+ * faillane vector represents
+ * @param[in] i_bufSz This is the size of passed buffer in terms of bytes
+ * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
+ * @param[in] i_failLanes Reference to a vector that has the faillane numbers
+ * that need to be updated to the o_buf buffer
+ * @param[o] o_buf This is the buffer that has the eRepair records
+ * that needs to be written to the VPD
+ * (For MemBuf)
+ * @return ReturnCode
+ */
template<fapi2::TargetType K>
-using p9_io_erepairSetFailedLanesHwp_FP_t = fapi2::ReturnCode (*)(
- const fapi2::Target < K >& i_target,
- EREPAIR::erepairVpdType i_vpdType,
- const uint8_t i_clkGroup,
- const std::vector<uint8_t>& i_txFailLanes,
- const std::vector<uint8_t>& i_rxFailLanes);
+fapi2::ReturnCode updateRepairLanesToBufMemBuf(
+ const fapi2::Target < K >& i_target,
+ const EREPAIR::interfaceType i_interface,
+ const uint32_t i_bufSz,
+ const uint8_t i_clkGroup,
+ const std::vector<uint8_t>& i_failLanes,
+ uint8_t* o_buf)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ uint32_t l_numRepairs = 0;
+ uint32_t l_newNumRepairs = 0;
+ uint32_t l_repairCnt = 0;
+ uint32_t l_bytesParsed = 0;
+ uint8_t l_repairLane = 0;
+ uint32_t l_repairDataSz = 0;
+ uint8_t* l_vpdPtr = NULL;
+ uint8_t* l_vpdDataPtr = NULL;
+ uint8_t* l_vpdWritePtr = NULL;
+ eRepairHeader* l_vpdHeadPtr = NULL;
+ eRepairPowerBus* l_overWritePtr = NULL;
+ bool l_overWrite = false;
+ uint8_t l_chipNum = 0;
+ uint32_t l_chipPosition = 0;
+ fapi2::Target<fapi2::TARGET_TYPE_DMI> l_dmiTarget;
+ std::vector<uint8_t>::const_iterator l_it;
+ fapi2::ATTR_CHIP_UNIT_POS_Type l_busNum;
+
+ FAPI_DBG(">> updateRepairLanesToBuf(MemBuf), interface: %s",
+ i_interface == EREPAIR::DRIVE ? "Drive" : "Receive");
+
+ {
+ l_repairDataSz = sizeof(eRepairPowerBus); // Size of memory Bus and
+ // fabric Bus eRepair data
+ // is same.
+ // Read the header and count information
+ l_vpdPtr = o_buf; // point to the start of header data
+ l_vpdHeadPtr = reinterpret_cast<eRepairHeader*> (l_vpdPtr);
+
+ l_numRepairs = l_newNumRepairs = l_vpdHeadPtr->availNumRecord;
+
+ // We've read the header data, increment bytes parsed
+ l_bytesParsed = sizeof(eRepairHeader);
+
+ // Get a pointer to the start of repair data
+ l_vpdPtr += sizeof(eRepairHeader);
+
+ {
+ l_dmiTarget = i_target.template getParent<fapi2::TARGET_TYPE_DMI>();
+
+ // Get the bus number
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
+ l_dmiTarget,
+ l_busNum));
+ }
+
+ // Get the chip number
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_POS,
+ i_target,
+ l_chipPosition));
+
+
+ // This is needed because we can only store and compare a uint8_t
+ // value. For our purpose the value in l_chipPosition (Proc Position and
+ // Centaur Position) will always be within the range of uint8_t
+ l_chipNum = l_chipPosition;
+
+ /*** Lets update the fail lane vector to the Buffer ***/
+ // Create a structure of eRepair data that we will be matching
+ // in the buffer.
+ struct erepairDataMatch
+ {
+ EREPAIR::interfaceType intType;
+ fapi2::TargetType tgtType;
+ union repairData
+ {
+ eRepairPowerBus fabBus;
+ eRepairMemBus memBus;
+ } bus;
+ };
+
+ // Create an array of the above match structure to have all the
+ // combinations of Fabric and Memory repair data
+ erepairDataMatch l_repairMatch[14] =
+ {
+ {
+ // index 0 - X0A (clock group 0)
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_DRIVER, // interface
+ },
+ },
+ },
+ {
+ // index 1 - X0A (clock group 0)
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_RECEIVER, // interface
+ },
+ },
+ },
+ {
+ // index 2 - X0A (clock group 1)
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_DRIVER, // interface
+ },
+ },
+ },
+ {
+ // index 3 - X0A (clock group 1)
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_RECEIVER, // interface
+ },
+ },
+ },
+ {
+ // index 4 - X1A (clock group 0)
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_DRIVER, // interface
+ },
+ },
+ },
+ {
+ // index 5 - X1A (clock group 0)
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_RECEIVER, // interface
+ },
+ },
+ },
+ {
+ // index 6 - X1A (clock group 1)
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_DRIVER, // interface
+ },
+ },
+ },
+ {
+ // index 7 - X1A (clock group 1)
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_RECEIVER, // interface
+ },
+ },
+ },
+ {
+ // index 8
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_OBUS,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_OPT, // type
+ EREPAIR::PBUS_DRIVER, // interface
+ },
+ },
+ },
+ {
+ // index 9
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_OBUS,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_OPT, // type
+ EREPAIR::PBUS_RECEIVER, // interface
+ },
+ },
+ },
+ {
+ // index 10
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_DMI,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// proc_centaur_id
+ l_busNum, // memChannel
+ },
+ EREPAIR::MEMORY_EDIP, // type
+ EREPAIR::DMI_MCS_DRIVE,// interface
+ },
+ },
+ },
+ {
+ // index 11
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_MEMBUF_CHIP,
+ {
+ // repairData
+ {
+ // memBus
+ {
+ // device
+ l_chipNum,// proc_centaur_id
+ l_busNum, // memChannel
+ },
+ EREPAIR::MEMORY_EDIP, // type
+ EREPAIR::DMI_MEMBUF_DRIVE,// interface
+ },
+ },
+ },
+ {
+ // index 12
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_DMI,
+ {
+ // repairData
+ {
+ // memBus
+ {
+ // device
+ l_chipNum,// proc_centaur_id
+ l_busNum, // memChannel
+ },
+ EREPAIR::MEMORY_EDIP, // type
+ EREPAIR::DMI_MCS_RECEIVE, // interface
+ },
+ },
+ },
+ {
+ // index 13
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_MEMBUF_CHIP,
+ {
+ // repairData
+ {
+ // memBus
+ {
+ // device
+ l_chipNum,// proc_centaur_id
+ l_busNum, // memChannel
+ },
+ EREPAIR::MEMORY_EDIP, // type
+ EREPAIR::DMI_MEMBUF_RECEIVE, // interface
+ },
+ },
+ }
+ };
+
+ l_vpdDataPtr = l_vpdPtr;
+ l_repairCnt = 0;
+
+ // Pick each faillane for copying into buffer
+ for(l_it = i_failLanes.begin();
+ l_it != i_failLanes.end();
+ l_it++, (l_vpdDataPtr += l_repairDataSz))
+ {
+ l_repairLane = *l_it;
+ l_overWrite = false;
+ l_vpdWritePtr = NULL;
+
+ // Parse the VPD for fabric and memory eRepair records
+ for(;
+ (l_repairCnt < l_numRepairs) && (l_bytesParsed <= i_bufSz);
+ l_repairCnt++, (l_vpdDataPtr += l_repairDataSz))
+ {
+ l_overWritePtr =
+ reinterpret_cast<eRepairPowerBus*> (l_vpdDataPtr);
+ // Lets find the matching fabric
+ for(uint8_t l_loop = 0; l_loop < 14; l_loop++)
+ {
+ {
+ if((i_interface == l_repairMatch[l_loop].intType) &&
+ (i_target.getType() == l_repairMatch[l_loop].tgtType) &&
+ ((l_overWritePtr->device).processor_id ==
+ l_repairMatch[l_loop].bus.memBus.device.proc_centaur_id) &&
+ (l_overWritePtr->type ==
+ l_repairMatch[l_loop].bus.memBus.type) &&
+ (l_overWritePtr->interface ==
+ l_repairMatch[l_loop].bus.memBus.interface) &&
+ (l_overWritePtr->device.fabricBus ==
+ l_repairMatch[l_loop].bus.memBus.device.memChannel))
+ {
+ // update the failBit number
+ {
+ uint32_t temp = (uint32_t)(l_overWritePtr->failBit);
+ uint32_t* tptr = &temp;
+ FAPI_TRY( gatherRepairLanes(
+ i_target,
+ l_overWritePtr->interface,
+ l_repairLane,
+ tptr),
+ "gatherRepairLanes() failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ l_overWritePtr->failBit = temp;
+ }
+
+ // Increment the count of parsed bytes
+ l_bytesParsed += l_repairDataSz;
+
+ l_repairCnt++;
+ l_overWrite = true;
+
+ break;
+ }
+ }
+ } // end of for(l_loop < 14)
+
+ if(l_overWrite == true)
+ {
+ // Go for the next repairLane
+ break;
+ }
+ } // end of for(vpd Parsing)
+
+ // Check if we have parsed more bytes than the passed size
+ if((l_vpdWritePtr == NULL) &&
+ (l_bytesParsed > i_bufSz) &&
+ (l_repairCnt < l_numRepairs))
+ {
+ FAPI_ASSERT(false,
+ fapi2::P9_EREPAIR_MVPD_FULL_ERR()
+ .set_VAL_BYTE_PARSED(l_bytesParsed)
+ .set_VAL_BUF_SIZE(i_bufSz)
+ .set_VAL_REPAIR_CNT(l_repairCnt)
+ .set_VAL_NUM_REPAIR(l_numRepairs),
+ "ERROR: from updateRepairLanesToBuf - MVPD full");
+ }
+
+ // Add at the end
+ if(l_overWrite == false)
+ {
+ if(l_vpdWritePtr == NULL)
+ {
+ // We are writing at the end
+ l_vpdWritePtr = l_vpdDataPtr;
+ }
+
+ {
+ // Make sure we are not writing more records than the size
+ // allocated in the VPD
+ FAPI_ASSERT(l_bytesParsed == i_bufSz,
+ fapi2::P9_EREPAIR_MBVPD_FULL_ERR()
+ .set_ERROR(l_bytesParsed),
+ "ERROR: from updateRepairLanesToBuf - MBVPD full");
+
+ eRepairMemBus* l_memBus =
+ reinterpret_cast<eRepairMemBus*>(l_vpdWritePtr);
+
+ l_memBus->device.proc_centaur_id = l_chipNum;
+ l_memBus->device.memChannel = l_busNum;
+ l_memBus->type = EREPAIR::MEMORY_EDIP;
+
+ if(i_interface == EREPAIR::DRIVE)
+ {
+ if(i_target.getType() == fapi2::TARGET_TYPE_DMI)
+ {
+ l_memBus->interface = EREPAIR::DMI_MCS_DRIVE;
+ }
+ else if(i_target.getType() == fapi2::TARGET_TYPE_MEMBUF_CHIP)
+ {
+ l_memBus->interface = EREPAIR::DMI_MEMBUF_DRIVE;
+ }
+ }
+ else if(i_interface == EREPAIR::RECEIVE)
+ {
+ if(i_target.getType() == fapi2::TARGET_TYPE_DMI)
+ {
+ l_memBus->interface = EREPAIR::DMI_MCS_RECEIVE;
+ }
+ else if(i_target.getType() == fapi2::TARGET_TYPE_MEMBUF_CHIP)
+ {
+ l_memBus->interface = EREPAIR::DMI_MEMBUF_RECEIVE;
+ }
+ }
+
+ {
+ uint32_t temp = (uint32_t)(l_memBus->failBit);
+ uint32_t* tptr = &temp;
+ FAPI_TRY( gatherRepairLanes(
+ i_target,
+ l_memBus->interface,
+ l_repairLane,
+ tptr),
+ "gatherRepairLanes() failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ l_memBus->failBit = temp;
+ }
+
+ l_newNumRepairs++;
+
+ // Increment the count of parsed bytes
+ l_bytesParsed += l_repairDataSz;
+#ifndef _BIG_ENDIAN
+ // We are on a Little Endian system.
+ // Need to swap the nibbles of structure - eRepairMemBus
+
+ l_vpdWritePtr[2] = ((l_vpdWritePtr[2] >> 4) |
+ (l_vpdWritePtr[2] << 4));
+#endif
+ }
+ } // end of if(l_overWrite == false)
+ } // end of for(failLanes)
+ }
+ // Update the eRepair count
+ l_vpdHeadPtr->availNumRecord = l_newNumRepairs;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
/**
- * @brief FW Team HWP that writes the eRepair fail lanes to the VPD.
- * The fail lanes will be written to either the P9 MVPD or the
- * Centaur FRU VPD depending on the passed target type.
+ * @brief Function called by the FW Team HWP that updates the passed buffer
+ * with the eRepair faillane numbers of a specified interface.
*
- * @param[in] i_target Reference to X-Bus or O-Bus or MCS or memBuf Target
+ * @param[in] i_target Reference to DMI target
+ * @param[in] i_interface This indicates the sub-interface type the passed
+ * faillane vector represents
+ * @param[in] i_bufSz This is the size of passed buffer in terms of bytes
+ * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
+ * @param[in] i_failLanes Reference to a vector that has the faillane numbers
+ * that need to be updated to the o_buf buffer
+ * @param[o] o_buf This is the buffer that has the eRepair records
+ * that needs to be written to the VPD
+ * (For DMI)
+ * @return ReturnCode
+ */
+template<fapi2::TargetType K>
+fapi2::ReturnCode updateRepairLanesToBufDMI(
+ const fapi2::Target < K >& i_target,
+ const EREPAIR::interfaceType i_interface,
+ const uint32_t i_bufSz,
+ const uint8_t i_clkGroup,
+ const std::vector<uint8_t>& i_failLanes,
+ uint8_t* o_buf)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ uint32_t l_numRepairs = 0;
+ uint32_t l_newNumRepairs = 0;
+ uint32_t l_repairCnt = 0;
+ uint32_t l_bytesParsed = 0;
+ uint8_t l_repairLane = 0;
+ uint32_t l_repairDataSz = 0;
+ uint8_t* l_vpdPtr = NULL;
+ uint8_t* l_vpdDataPtr = NULL;
+ uint8_t* l_vpdWritePtr = NULL;
+ eRepairHeader* l_vpdHeadPtr = NULL;
+ eRepairPowerBus* l_overWritePtr = NULL;
+ bool l_overWrite = false;
+ uint8_t l_chipNum = 0;
+ uint32_t l_chipPosition = 0;
+ fapi2::Target<fapi2::TARGET_TYPE_DMI> l_dmiTarget;
+ std::vector<uint8_t>::const_iterator l_it;
+ fapi2::ATTR_CHIP_UNIT_POS_Type l_busNum;
+
+ FAPI_DBG(">> updateRepairLanesToBuf(DMI), interface: %s",
+ i_interface == EREPAIR::DRIVE ? "Drive" : "Receive");
+
+ {
+ l_repairDataSz = sizeof(eRepairPowerBus); // Size of memory Bus and
+ // fabric Bus eRepair data
+ // is same.
+ // Read the header and count information
+ l_vpdPtr = o_buf; // point to the start of header data
+ l_vpdHeadPtr = reinterpret_cast<eRepairHeader*> (l_vpdPtr);
+
+ l_numRepairs = l_newNumRepairs = l_vpdHeadPtr->availNumRecord;
+
+ // We've read the header data, increment bytes parsed
+ l_bytesParsed = sizeof(eRepairHeader);
+
+ // Get a pointer to the start of repair data
+ l_vpdPtr += sizeof(eRepairHeader);
+
+ // Get the bus number
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
+ i_target,
+ l_busNum));
+
+ // Get the chip target
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_chipTarget;
+ l_chipTarget = i_target.template getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
+
+ // Get the chip number
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_POS,
+ l_chipTarget,
+ l_chipPosition));
+
+
+ // This is needed because we can only store and compare a uint8_t
+ // value. For our purpose the value in l_chipPosition (Proc Position and
+ // Centaur Position) will always be within the range of uint8_t
+ l_chipNum = l_chipPosition;
+
+ /*** Lets update the fail lane vector to the Buffer ***/
+ // Create a structure of eRepair data that we will be matching
+ // in the buffer.
+ struct erepairDataMatch
+ {
+ EREPAIR::interfaceType intType;
+ fapi2::TargetType tgtType;
+ union repairData
+ {
+ eRepairPowerBus fabBus;
+ eRepairMemBus memBus;
+ } bus;
+ };
+
+ // Create an array of the above match structure to have all the
+ // combinations of Fabric and Memory repair data
+ erepairDataMatch l_repairMatch[14] =
+ {
+ {
+ // index 0 - X0A (clock group 0)
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_DRIVER, // interface
+ },
+ },
+ },
+ {
+ // index 1 - X0A (clock group 0)
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_RECEIVER, // interface
+ },
+ },
+ },
+ {
+ // index 2 - X0A (clock group 1)
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_DRIVER, // interface
+ },
+ },
+ },
+ {
+ // index 3 - X0A (clock group 1)
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_RECEIVER, // interface
+ },
+ },
+ },
+ {
+ // index 4 - X1A (clock group 0)
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_DRIVER, // interface
+ },
+ },
+ },
+ {
+ // index 5 - X1A (clock group 0)
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_RECEIVER, // interface
+ },
+ },
+ },
+ {
+ // index 6 - X1A (clock group 1)
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_DRIVER, // interface
+ },
+ },
+ },
+ {
+ // index 7 - X1A (clock group 1)
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_XBUS_ENDPOINT,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_EDIP, // type
+ EREPAIR::PBUS_RECEIVER, // interface
+ },
+ },
+ },
+ {
+ // index 8
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_OBUS,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_OPT, // type
+ EREPAIR::PBUS_DRIVER, // interface
+ },
+ },
+ },
+ {
+ // index 9
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_OBUS,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// processor_id
+ l_busNum, // fabricBus
+ },
+ EREPAIR::PROCESSOR_OPT, // type
+ EREPAIR::PBUS_RECEIVER, // interface
+ },
+ },
+ },
+ {
+ // index 10
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_DMI,
+ {
+ // repairData
+ {
+ // fabBus
+ {
+ // device
+ l_chipNum,// proc_centaur_id
+ l_busNum, // memChannel
+ },
+ EREPAIR::MEMORY_EDIP, // type
+ EREPAIR::DMI_MCS_DRIVE,// interface
+ },
+ },
+ },
+ {
+ // index 11
+ EREPAIR::DRIVE,
+ fapi2::TARGET_TYPE_MEMBUF_CHIP,
+ {
+ // repairData
+ {
+ // memBus
+ {
+ // device
+ l_chipNum,// proc_centaur_id
+ l_busNum, // memChannel
+ },
+ EREPAIR::MEMORY_EDIP, // type
+ EREPAIR::DMI_MEMBUF_DRIVE,// interface
+ },
+ },
+ },
+ {
+ // index 12
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_DMI,
+ {
+ // repairData
+ {
+ // memBus
+ {
+ // device
+ l_chipNum,// proc_centaur_id
+ l_busNum, // memChannel
+ },
+ EREPAIR::MEMORY_EDIP, // type
+ EREPAIR::DMI_MCS_RECEIVE, // interface
+ },
+ },
+ },
+ {
+ // index 13
+ EREPAIR::RECEIVE,
+ fapi2::TARGET_TYPE_MEMBUF_CHIP,
+ {
+ // repairData
+ {
+ // memBus
+ {
+ // device
+ l_chipNum,// proc_centaur_id
+ l_busNum, // memChannel
+ },
+ EREPAIR::MEMORY_EDIP, // type
+ EREPAIR::DMI_MEMBUF_RECEIVE, // interface
+ },
+ },
+ }
+ };
+
+ l_vpdDataPtr = l_vpdPtr;
+ l_repairCnt = 0;
+
+ // Pick each faillane for copying into buffer
+ for(l_it = i_failLanes.begin();
+ l_it != i_failLanes.end();
+ l_it++, (l_vpdDataPtr += l_repairDataSz))
+ {
+ l_repairLane = *l_it;
+ l_overWrite = false;
+ l_vpdWritePtr = NULL;
+
+ // Parse the VPD for fabric and memory eRepair records
+ for(;
+ (l_repairCnt < l_numRepairs) && (l_bytesParsed <= i_bufSz);
+ l_repairCnt++, (l_vpdDataPtr += l_repairDataSz))
+ {
+ l_overWritePtr =
+ reinterpret_cast<eRepairPowerBus*> (l_vpdDataPtr);
+
+ // Lets find the matching fabric
+ for(uint8_t l_loop = 0; l_loop < 14; l_loop++)
+ {
+ {
+ if((i_interface == l_repairMatch[l_loop].intType) &&
+ (i_target.getType() == l_repairMatch[l_loop].tgtType) &&
+ ((l_overWritePtr->device).processor_id ==
+ l_repairMatch[l_loop].bus.memBus.device.proc_centaur_id) &&
+ (l_overWritePtr->type ==
+ l_repairMatch[l_loop].bus.memBus.type) &&
+ (l_overWritePtr->interface ==
+ l_repairMatch[l_loop].bus.memBus.interface) &&
+ (l_overWritePtr->device.fabricBus ==
+ l_repairMatch[l_loop].bus.memBus.device.memChannel))
+ {
+ // update the failBit number
+ {
+ uint32_t temp = (uint32_t)(l_overWritePtr->failBit);
+ uint32_t* tptr = &temp;
+ FAPI_TRY( gatherRepairLanes(
+ i_target,
+ l_overWritePtr->interface,
+ l_repairLane,
+ tptr),
+ "gatherRepairLanes() failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ l_overWritePtr->failBit = temp;
+ }
+
+ // Increment the count of parsed bytes
+ l_bytesParsed += l_repairDataSz;
+
+ l_repairCnt++;
+ l_overWrite = true;
+
+ break;
+ }
+ }
+ } // end of for(l_loop < 14)
+
+ if(l_overWrite == true)
+ {
+ // Go for the next repairLane
+ break;
+ }
+ } // end of for(vpd Parsing)
+
+ // Check if we have parsed more bytes than the passed size
+ if((l_vpdWritePtr == NULL) &&
+ (l_bytesParsed > i_bufSz) &&
+ (l_repairCnt < l_numRepairs))
+ {
+ FAPI_ASSERT(false,
+ fapi2::P9_EREPAIR_MVPD_FULL_ERR()
+ .set_VAL_BYTE_PARSED(l_bytesParsed)
+ .set_VAL_BUF_SIZE(i_bufSz)
+ .set_VAL_REPAIR_CNT(l_repairCnt)
+ .set_VAL_NUM_REPAIR(l_numRepairs),
+ "ERROR: from updateRepairLanesToBuf - MVPD full");
+ }
+
+ // Add at the end
+ if(l_overWrite == false)
+ {
+ if(l_vpdWritePtr == NULL)
+ {
+ // We are writing at the end
+ l_vpdWritePtr = l_vpdDataPtr;
+ }
+
+ {
+ // Make sure we are not writing more records than the size
+ // allocated in the VPD
+ FAPI_ASSERT(l_bytesParsed == i_bufSz,
+ fapi2::P9_EREPAIR_MBVPD_FULL_ERR()
+ .set_ERROR(l_bytesParsed),
+ "ERROR: from updateRepairLanesToBuf - MBVPD full");
+
+ eRepairMemBus* l_memBus =
+ reinterpret_cast<eRepairMemBus*>(l_vpdWritePtr);
+
+ l_memBus->device.proc_centaur_id = l_chipNum;
+ l_memBus->device.memChannel = l_busNum;
+ l_memBus->type = EREPAIR::MEMORY_EDIP;
+
+ if(i_interface == EREPAIR::DRIVE)
+ {
+ if(i_target.getType() == fapi2::TARGET_TYPE_DMI)
+ {
+ l_memBus->interface = EREPAIR::DMI_MCS_DRIVE;
+ }
+ else if(i_target.getType() == fapi2::TARGET_TYPE_MEMBUF_CHIP)
+ {
+ l_memBus->interface = EREPAIR::DMI_MEMBUF_DRIVE;
+ }
+ }
+ else if(i_interface == EREPAIR::RECEIVE)
+ {
+ if(i_target.getType() == fapi2::TARGET_TYPE_DMI)
+ {
+ l_memBus->interface = EREPAIR::DMI_MCS_RECEIVE;
+ }
+ else if(i_target.getType() == fapi2::TARGET_TYPE_MEMBUF_CHIP)
+ {
+ l_memBus->interface = EREPAIR::DMI_MEMBUF_RECEIVE;
+ }
+ }
+
+ {
+ uint32_t temp = (uint32_t)(l_memBus->failBit);
+ uint32_t* tptr = &temp;
+ FAPI_TRY( gatherRepairLanes(
+ i_target,
+ l_memBus->interface,
+ l_repairLane,
+ tptr),
+ "gatherRepairLanes() failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ l_memBus->failBit = temp;
+ }
+
+ l_newNumRepairs++;
+
+ // Increment the count of parsed bytes
+ l_bytesParsed += l_repairDataSz;
+#ifndef _BIG_ENDIAN
+ // We are on a Little Endian system.
+ // Need to swap the nibbles of structure - eRepairMemBus
+
+ l_vpdWritePtr[2] = ((l_vpdWritePtr[2] >> 4) |
+ (l_vpdWritePtr[2] << 4));
+#endif
+ }
+ } // end of if(l_overWrite == false)
+ } // end of for(failLanes)
+ }
+ // Update the eRepair count
+ l_vpdHeadPtr->availNumRecord = l_newNumRepairs;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/**
+ * @brief Function called by the FW Team HWP that writes the data to Field VPD.
+ * This function calls fapiSetMvpdField to write the VPD.
+ *
+ * @param[in] i_target Reference to X-Bus target
* @param[in] i_vpdType Specifies which VPD (MNFG or Field) to access.
* @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
- * @param[in] i_txFailLanes Reference to a vector that has the Tx side
- * (of i_tgtHandle) fail lane numbers that need
- * to be written to the VPD
- * @param[in] i_rxFailLanes Reference to a vector that has the Rx side
- * (of i_tgtHandle) fail lane numbers that need
- * to be written to the VPD
+ * @param[in] i_txFailLanes Reference to a vector that has eRepair fail
+ * lane numbers of the Tx sub-interface.
+ * @param[in] i_rxFailLanes Reference to a vector that has eRepair fail
+ * lane numbers of the Rx sub-interface.
+ * (For Proc)
+ * @return ReturnCode
+ */
+template<fapi2::TargetType K>
+fapi2::ReturnCode writeRepairDataToVPDProc(
+ const fapi2::Target < K >& i_target,
+ EREPAIR::erepairVpdType i_vpdType,
+ const uint8_t i_clkGroup,
+ const std::vector<uint8_t>& i_txFailLanes,
+ const std::vector<uint8_t>& i_rxFailLanes)
+{
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_procTarget;
+
+ uint8_t* l_retBuf = NULL;
+ uint32_t l_bufSize = 0;
+ FAPI_DBG(">> writeRepairDataToVPD - Proc");
+
+ {
+ // Determine the Processor target
+ l_procTarget = i_target.template getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
+
+ fapi2::MvpdRecord l_vpdRecord = fapi2::MVPD_RECORD_VWML;
+
+ if(i_vpdType == EREPAIR::EREPAIR_VPD_MNFG)
+ {
+ l_vpdRecord = fapi2::MVPD_RECORD_MER0;
+ }
+
+ /*** Read the data from the Module VPD ***/
+
+ // Determine the size of the eRepair data in the VPD
+ FAPI_TRY( getMvpdField(
+ l_vpdRecord,
+ fapi2::MVPD_KEYWORD_PDI,
+ l_procTarget,
+ NULL,
+ l_bufSize),
+ "VPD size read failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ if((l_bufSize == 0) ||
+ ((i_vpdType == EREPAIR::EREPAIR_VPD_FIELD) &&
+ (l_bufSize > EREPAIR::EREPAIR_P9_MODULE_VPD_FIELD_SIZE)) ||
+ ((i_vpdType == EREPAIR::EREPAIR_VPD_MNFG) &&
+ (l_bufSize > EREPAIR::EREPAIR_P9_MODULE_VPD_MNFG_SIZE)))
+ {
+ FAPI_ASSERT(false,
+ fapi2::P9_EREPAIR_ACCESSOR_HWP_INVALID_FABRIC_VPD_SIZE_ERR()
+ .set_ERROR(fapi2::current_err),
+ "ERROR: Invalid Fabric VPD size");
+ }
+
+ // Allocate memory for buffer
+ l_retBuf = new uint8_t[l_bufSize];
+
+ FAPI_ASSERT(l_retBuf != NULL,
+ fapi2::P9_EREPAIR_ACCESSOR_HWP_MEMORY_ALLOC_FAIL_ERR()
+ .set_BUF_SIZE(l_bufSize),
+ "ERROR: Failed to allocate memory size");
+
+ // Retrieve the Field eRepair data from the MVPD
+ FAPI_TRY( getMvpdField(
+ l_vpdRecord,
+ fapi2::MVPD_KEYWORD_PDI,
+ l_procTarget,
+ l_retBuf,
+ l_bufSize),
+ "VPD read failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ if(i_txFailLanes.size())
+ {
+ /*** Lets update the tx side fail lane vector to the VPD ***/
+ FAPI_TRY( updateRepairLanesToBufProc(
+ i_target,
+ EREPAIR::DRIVE,
+ l_bufSize,
+ i_clkGroup,
+ i_txFailLanes,
+ l_retBuf),
+ "updateRepairLanesToBuf(DRIVE) failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ }
+
+ if(i_rxFailLanes.size())
+ {
+ /*** Lets update the rx side fail lane vector to the VPD ***/
+ FAPI_TRY( updateRepairLanesToBufProc(
+ i_target,
+ EREPAIR::RECEIVE,
+ l_bufSize,
+ i_clkGroup,
+ i_rxFailLanes,
+ l_retBuf),
+ "updateRepairLanesToBuf(RECEIVE) failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ }
+
+ /*** Write the updated eRepair buffer back to MVPD ***/
+ FAPI_TRY( setMvpdField(
+ l_vpdRecord,
+ fapi2::MVPD_KEYWORD_PDI,
+ l_procTarget,
+ l_retBuf,
+ l_bufSize),
+ "setMvpdField()-Update erepair data to VPD failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ }
+
+ // Delete the buffer which has Field eRepair data
+ delete[] l_retBuf;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/**
+ * @brief Function called by the FW Team HWP that writes the data to Field VPD.
+ * This function calls fapiSetMvpdField to write the VPD.
*
+ * @param[in] i_target Reference to MEMBUF target
+ * @param[in] i_vpdType Specifies which VPD (MNFG or Field) to access.
+ * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
+ * @param[in] i_txFailLanes Reference to a vector that has eRepair fail
+ * lane numbers of the Tx sub-interface.
+ * @param[in] i_rxFailLanes Reference to a vector that has eRepair fail
+ * lane numbers of the Rx sub-interface.
+ * (For MemBuf)
* @return ReturnCode
+ */
+template<fapi2::TargetType K>
+fapi2::ReturnCode writeRepairDataToVPDMemBuf(
+ const fapi2::Target < K >& i_target,
+ EREPAIR::erepairVpdType i_vpdType,
+ const uint8_t i_clkGroup,
+ const std::vector<uint8_t>& i_txFailLanes,
+ const std::vector<uint8_t>& i_rxFailLanes)
+{
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_MBA_CHIPLET>> l_mbaChiplets;
+ fapi2::Target<fapi2::TARGET_TYPE_MBA> l_mbaTarget;
+
+ uint8_t* l_retBuf = NULL;
+ uint32_t l_bufSize = 0;
+ size_t l_mBufSize = 0;
+ uint8_t l_customDimm;
+ FAPI_DBG(">> writeRepairDataToVPD - MemBuf");
+
+ {
+ fapi2::MBvpdRecord l_vpdRecord = fapi2::MBVPD_RECORD_VEIR;
+
+ if(i_vpdType == EREPAIR::EREPAIR_VPD_MNFG)
+ {
+ l_vpdRecord = fapi2::MBVPD_RECORD_MER0;
+ }
+
+ /*** Read the data from the FRU VPD ***/
+
+ // Determine the size of the eRepair data in the Centaur VPD
+ FAPI_TRY( getMBvpdField(
+ l_vpdRecord,
+ fapi2::MBVPD_KEYWORD_PDI,
+ i_target,
+ NULL,
+ l_mBufSize),
+ "VPD size read failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ // Get the connected MBA chiplet and determine whether we have CDIMM
+ l_mbaChiplets = i_target.template getChildren<fapi2::TARGET_TYPE_MBA_CHIPLET>
+ (fapi2::TARGET_STATE_FUNCTIONAL);
+
+ FAPI_ASSERT( 0 != l_mbaChiplets.size(),
+ fapi2::P9_EREPAIR_CHILD_MBA_TARGETS_ERR()
+ .set_ERROR(l_mbaChiplets),
+ "ERROR: During get child MBA targets");
+
+ l_mbaTarget = l_mbaChiplets[0];
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>> l_target_dimm_array;
+
+ l_target_dimm_array = l_mbaTarget.getChildren<fapi2::TARGET_TYPE_DIMM>
+ (fapi2::TARGET_STATE_FUNCTIONAL);
+
+ if(0 != l_target_dimm_array.size())
+ {
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_SPD_CUSTOM,
+ l_target_dimm_array[0],
+ l_customDimm));
+ }
+ else
+ {
+ l_customDimm = fapi2::ENUM_ATTR_CEN_SPD_CUSTOM_NO;
+ }
+
+ if( (l_customDimm == fapi2::ENUM_ATTR_CEN_SPD_CUSTOM_YES) || (l_bufSize == 0) )
+ {
+ if((l_bufSize == 0) ||
+ ((i_vpdType == EREPAIR::EREPAIR_VPD_FIELD) &&
+ (l_bufSize > EREPAIR::EREPAIR_MEM_FIELD_VPD_SIZE_PER_CENTAUR)) ||
+ ((i_vpdType == EREPAIR::EREPAIR_VPD_MNFG) &&
+ (l_bufSize > EREPAIR::EREPAIR_MEM_MNFG_VPD_SIZE_PER_CENTAUR)))
+ {
+ FAPI_ASSERT(false,
+ fapi2::P9_EREPAIR_ACCESSOR_HWP_INVALID_MEM_VPD_SIZE_ERR()
+ .set_ERROR(fapi2::current_err),
+ "ERROR: Invalid MEM VPD size");
+ }
+ }
+
+ // Allocate memory for buffer
+ l_retBuf = new uint8_t[l_mBufSize];
+
+ FAPI_ASSERT(l_retBuf != NULL,
+ fapi2::P9_EREPAIR_ACCESSOR_HWP_MEMORY_ALLOC_FAIL_ERR()
+ .set_BUF_SIZE(l_bufSize),
+ "ERROR: Failed to allocate memory size");
+
+ // Retrieve the Field eRepair data from the Centaur FRU VPD
+ FAPI_TRY( getMBvpdField(
+ l_vpdRecord,
+ fapi2::MBVPD_KEYWORD_PDI,
+ i_target,
+ l_retBuf,
+ l_mBufSize),
+ "Centaur FRU VPD read failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ if(i_txFailLanes.size())
+ {
+ /*** Lets update the tx side fail lane vector to the VPD ***/
+ FAPI_TRY( updateRepairLanesToBufMemBuf(
+ i_target,
+ EREPAIR::DRIVE,
+ l_mBufSize,
+ i_clkGroup,
+ i_txFailLanes,
+ l_retBuf),
+ "updateRepairLanesToBuf(DRIVE) failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ }
+
+ if(i_rxFailLanes.size())
+ {
+ /*** Lets update the rx side fail lane vector to the VPD ***/
+ FAPI_TRY( updateRepairLanesToBufMemBuf(
+ i_target,
+ EREPAIR::RECEIVE,
+ l_mBufSize,
+ i_clkGroup,
+ i_rxFailLanes,
+ l_retBuf),
+ "updateRepairLanesToBuf(RECEIVE) failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ }
+
+ /*** Write the updated eRepair buffer back to Centaur FRU VPD ***/
+ FAPI_TRY( setMBvpdField(
+ l_vpdRecord,
+ fapi2::MBVPD_KEYWORD_PDI,
+ i_target,
+ l_retBuf,
+ l_mBufSize),
+ "Update erepair data to VPD failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ } // end of(targetType == MEMBUF)
+
+ // Delete the buffer which has Field eRepair data
+ delete[] l_retBuf;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/**
+ * @brief Function called by the FW Team HWP that writes the data to Field VPD.
+ * This function calls fapiSetMvpdField to write the VPD.
*
+ * @param[in] i_target Reference to DMI target
+ * @param[in] i_vpdType Specifies which VPD (MNFG or Field) to access.
+ * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
+ * @param[in] i_txFailLanes Reference to a vector that has eRepair fail
+ * lane numbers of the Tx sub-interface.
+ * @param[in] i_rxFailLanes Reference to a vector that has eRepair fail
+ * lane numbers of the Rx sub-interface.
+ * (For DMI)
+ * @return ReturnCode
*/
template<fapi2::TargetType K>
+fapi2::ReturnCode writeRepairDataToVPDDMI(
+ const fapi2::Target < K >& i_target,
+ EREPAIR::erepairVpdType i_vpdType,
+ const uint8_t i_clkGroup,
+ const std::vector<uint8_t>& i_txFailLanes,
+ const std::vector<uint8_t>& i_rxFailLanes)
+{
+ fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_procTarget;
+
+ uint8_t* l_retBuf = NULL;
+ uint32_t l_bufSize = 0;
+ FAPI_DBG(">> writeRepairDataToVPD - DMI");
+
+ {
+ // Determine the Processor target
+ l_procTarget = i_target.template getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
+
+ fapi2::MvpdRecord l_vpdRecord = fapi2::MVPD_RECORD_VWML;
+
+ if(i_vpdType == EREPAIR::EREPAIR_VPD_MNFG)
+ {
+ l_vpdRecord = fapi2::MVPD_RECORD_MER0;
+ }
+
+ /*** Read the data from the Module VPD ***/
+
+ // Determine the size of the eRepair data in the VPD
+ FAPI_TRY( getMvpdField(
+ l_vpdRecord,
+ fapi2::MVPD_KEYWORD_PDI,
+ l_procTarget,
+ NULL,
+ l_bufSize),
+ "VPD size read failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ if((l_bufSize == 0) ||
+ ((i_vpdType == EREPAIR::EREPAIR_VPD_FIELD) &&
+ (l_bufSize > EREPAIR::EREPAIR_P9_MODULE_VPD_FIELD_SIZE)) ||
+ ((i_vpdType == EREPAIR::EREPAIR_VPD_MNFG) &&
+ (l_bufSize > EREPAIR::EREPAIR_P9_MODULE_VPD_MNFG_SIZE)))
+ {
+ FAPI_ASSERT(false,
+ fapi2::P9_EREPAIR_ACCESSOR_HWP_INVALID_FABRIC_VPD_SIZE_ERR()
+ .set_ERROR(fapi2::current_err),
+ "ERROR: Invalid Fabric VPD size");
+ }
+
+ // Allocate memory for buffer
+ l_retBuf = new uint8_t[l_bufSize];
+
+ FAPI_ASSERT(l_retBuf != NULL,
+ fapi2::P9_EREPAIR_ACCESSOR_HWP_MEMORY_ALLOC_FAIL_ERR()
+ .set_BUF_SIZE(l_bufSize),
+ "ERROR: Failed to allocate memory size");
+
+ // Retrieve the Field eRepair data from the MVPD
+ FAPI_TRY( getMvpdField(
+ l_vpdRecord,
+ fapi2::MVPD_KEYWORD_PDI,
+ l_procTarget,
+ l_retBuf,
+ l_bufSize),
+ "VPD read failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+ if(i_txFailLanes.size())
+ {
+ /*** Lets update the tx side fail lane vector to the VPD ***/
+ FAPI_TRY( updateRepairLanesToBufDMI(
+ i_target,
+ EREPAIR::DRIVE,
+ l_bufSize,
+ i_clkGroup,
+ i_txFailLanes,
+ l_retBuf),
+ "updateRepairLanesToBuf(DRIVE) failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ }
+
+ if(i_rxFailLanes.size())
+ {
+ /*** Lets update the rx side fail lane vector to the VPD ***/
+ FAPI_TRY( updateRepairLanesToBufDMI(
+ i_target,
+ EREPAIR::RECEIVE,
+ l_bufSize,
+ i_clkGroup,
+ i_rxFailLanes,
+ l_retBuf),
+ "updateRepairLanesToBuf(RECEIVE) failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ }
+
+ /*** Write the updated eRepair buffer back to MVPD ***/
+ FAPI_TRY( setMvpdField(
+ l_vpdRecord,
+ fapi2::MVPD_KEYWORD_PDI,
+ l_procTarget,
+ l_retBuf,
+ l_bufSize),
+ "setMvpdField()-Update erepair data to VPD failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+ }
+
+ // Delete the buffer which has Field eRepair data
+ delete[] l_retBuf;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/**
+ * @brief Function called by the FW Team HWP that sets the failed lanes to VPD.
+ *
+ * @param[in] i_target Reference to X-Bus DMI target
+ * @param[in] i_vpdType Specifies which VPD (MNFG or Field) to access.
+ * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
+ * @param[in] i_txFailLanes Reference to a vector that has eRepair fail
+ * lane numbers of the Tx sub-interface.
+ * @param[in] i_rxFailLanes Reference to a vector that has eRepair fail
+ * lane numbers of the Rx sub-interface.
+ * (For Proc)
+ * @return ReturnCode
+ */
+fapi2::ReturnCode p9_io_erepairSetFailedLanesHwp(
+ const fapi2::Target < fapi2::TARGET_TYPE_XBUS >& i_target,
+ EREPAIR::erepairVpdType i_vpdType,
+ const uint8_t i_clkGroup,
+ const std::vector<uint8_t>& i_txFailLanes,
+ const std::vector<uint8_t>& i_rxFailLanes)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_INF(">> erepairSetFailedLanesHwp for XBUS");
+
+ FAPI_ASSERT(( (i_txFailLanes.size() != 0) || (i_rxFailLanes.size() != 0) ),
+ fapi2::P9_EREPAIR_NO_RX_TX_FAILED_LANES_ERR()
+ .set_TX_LANE(i_txFailLanes.size()).set_RX_LANE(i_rxFailLanes.size()),
+ "ERROR: No Tx/Rx fail lanes were provided");
+
+ FAPI_TRY( writeRepairDataToVPDProc(
+ i_target,
+ i_vpdType,
+ i_clkGroup,
+ i_txFailLanes,
+ i_rxFailLanes),
+ "p9_io_erepairSetFailedLanesHwp() failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/**
+ * @brief Function called by the FW Team HWP that sets the failed lanes to VPD.
+ *
+ * @param[in] i_target Reference to MEMBuf target
+ * @param[in] i_vpdType Specifies which VPD (MNFG or Field) to access.
+ * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
+ * @param[in] i_txFailLanes Reference to a vector that has eRepair fail
+ * lane numbers of the Tx sub-interface.
+ * @param[in] i_rxFailLanes Reference to a vector that has eRepair fail
+ * lane numbers of the Rx sub-interface.
+ * (For MemBuf)
+ * @return ReturnCode
+ */
+fapi2::ReturnCode p9_io_erepairSetFailedLanesHwp(
+ const fapi2::Target < fapi2::TARGET_TYPE_MEMBUF_CHIP >& i_target,
+ EREPAIR::erepairVpdType i_vpdType,
+ const uint8_t i_clkGroup,
+ const std::vector<uint8_t>& i_txFailLanes,
+ const std::vector<uint8_t>& i_rxFailLanes)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_INF(">> erepairSetFailedLanesHwp for MemBuf");
+
+ FAPI_ASSERT(( (i_txFailLanes.size() != 0) || (i_rxFailLanes.size() != 0) ),
+ fapi2::P9_EREPAIR_NO_RX_TX_FAILED_LANES_ERR()
+ .set_TX_LANE(i_txFailLanes.size()).set_RX_LANE(i_rxFailLanes.size()),
+ "ERROR: No Tx/Rx fail lanes were provided");
+
+ FAPI_TRY( writeRepairDataToVPDMemBuf(
+ i_target,
+ i_vpdType,
+ i_clkGroup,
+ i_txFailLanes,
+ i_rxFailLanes),
+ "p9_io_erepairSetFailedLanesHwp() failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/**
+ * @brief Function called by the FW Team HWP that sets the failed lanes to VPD.
+ *
+ * @param[in] i_target Reference to DMI target
+ * @param[in] i_vpdType Specifies which VPD (MNFG or Field) to access.
+ * @param[in] i_clkGroup Specifies clock group 0:[XOA, X1A,..] 1:[X0B, X1B,..]
+ * @param[in] i_txFailLanes Reference to a vector that has eRepair fail
+ * lane numbers of the Tx sub-interface.
+ * @param[in] i_rxFailLanes Reference to a vector that has eRepair fail
+ * lane numbers of the Rx sub-interface.
+ *
+ * @return ReturnCode
+ */
fapi2::ReturnCode p9_io_erepairSetFailedLanesHwp(
- const fapi2::Target < K >& i_target,
+ const fapi2::Target < fapi2::TARGET_TYPE_DMI >& i_target,
EREPAIR::erepairVpdType i_vpdType,
const uint8_t i_clkGroup,
const std::vector<uint8_t>& i_txFailLanes,
- const std::vector<uint8_t>& i_rxFailLanes);
+ const std::vector<uint8_t>& i_rxFailLanes)
+{
+ fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
+
+ FAPI_INF(">> erepairSetFailedLanesHwp for DMI");
+
+ FAPI_ASSERT(( (i_txFailLanes.size() != 0) || (i_rxFailLanes.size() != 0) ),
+ fapi2::P9_EREPAIR_NO_RX_TX_FAILED_LANES_ERR()
+ .set_TX_LANE(i_txFailLanes.size()).set_RX_LANE(i_rxFailLanes.size()),
+ "ERROR: No Tx/Rx fail lanes were provided");
+
+ FAPI_TRY( writeRepairDataToVPDDMI(
+ i_target,
+ i_vpdType,
+ i_clkGroup,
+ i_txFailLanes,
+ i_rxFailLanes),
+ "p9_io_erepairSetFailedLanesHwp() failed w/rc=0x%x",
+ (uint64_t)fapi2::current_err );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
#endif
diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_erepairSetFailedLanesHwp.mk b/src/import/chips/p9/procedures/hwp/io/p9_io_erepairSetFailedLanesHwp.mk
deleted file mode 100644
index 03988f13d..000000000
--- a/src/import/chips/p9/procedures/hwp/io/p9_io_erepairSetFailedLanesHwp.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-# IBM_PROLOG_BEGIN_TAG
-# This is an automatically generated prolog.
-#
-# $Source: src/import/chips/p9/procedures/hwp/io/p9_io_erepairSetFailedLanesHwp.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
-
-PROCEDURE=p9_io_erepairSetFailedLanesHwp
-$(call BUILD_PROCEDURE)
diff --git a/src/usr/diag/prdf/prdf_hb_only.mk b/src/usr/diag/prdf/prdf_hb_only.mk
index eb1fecde6..9c3b9a4b7 100644
--- a/src/usr/diag/prdf/prdf_hb_only.mk
+++ b/src/usr/diag/prdf/prdf_hb_only.mk
@@ -162,8 +162,6 @@ CLEAN_TARGETS += ${MFG_THRES_PATH}
################################################################################
prd_vpath += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/io/
prd_obj_no_sim += p9_io_erepairAccessorHwpFuncs.o
-prd_obj_no_sim += p9_io_erepairGetFailedLanesHwp.o
-prd_obj_no_sim += p9_io_erepairSetFailedLanesHwp.o
prd_obj_no_sim += p9_io_xbus_read_erepair.o
prd_vpath += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/perv/
prd_obj_no_sim += p9_proc_gettracearray.o
diff --git a/src/usr/isteps/istep09/makefile b/src/usr/isteps/istep09/makefile
index 64dfd3700..409263562 100644
--- a/src/usr/isteps/istep09/makefile
+++ b/src/usr/isteps/istep09/makefile
@@ -53,8 +53,6 @@ include ${ROOTPATH}/procedure.rules.mk
# fabric_erepair
include ${PROCEDURES_PATH}/hwp/io/p9_io_xbus_restore_erepair.mk
include ${PROCEDURES_PATH}/hwp/io/p9_io_erepairAccessorHwpFuncs.mk
-include ${PROCEDURES_PATH}/hwp/io/p9_io_erepairGetFailedLanesHwp.mk
-include ${PROCEDURES_PATH}/hwp/io/p9_io_erepairSetFailedLanesHwp.mk
#Skipping p9_io_xbus_pdwn_lanes, already included by libprdf.so
# fabric_io_dccal
OpenPOWER on IntegriCloud