diff options
author | Bilicon Patil <bilpatil@in.ibm.com> | 2013-04-04 06:06:34 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-05-08 09:25:18 -0500 |
commit | 8e8dbe99d13d923536353afd96b9b003382b7f2c (patch) | |
tree | 06ddd905db79c197fc0e9fe94cb28674a7b2ee94 /src/usr/hwpf | |
parent | 0b8a07b09265dd48c2881caca24e150a948272a0 (diff) | |
download | talos-hostboot-8e8dbe99d13d923536353afd96b9b003382b7f2c.tar.gz talos-hostboot-8e8dbe99d13d923536353afd96b9b003382b7f2c.zip |
Set Accessor HWP to write repair data to VPD and Support for Centaur targets.
Change-Id: I57eee26a677c213317beaa6b84c79a73cccf34a5
RTC: 22646
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/3864
Tested-by: Jenkins Server
Reviewed-by: Zane Shelley <zshelle@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/hwpf')
-rw-r--r-- | src/usr/hwpf/hwp/bus_training/erepairAccessorHwpFuncs.C | 462 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/bus_training/erepairGetFailedLanesHwp.C | 203 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/bus_training/erepairGetMnfgFailedLanesHwp.C | 215 | ||||
-rwxr-xr-x | src/usr/hwpf/hwp/bus_training/erepairSetFailedLanesHwp.C | 801 | ||||
-rwxr-xr-x | src/usr/hwpf/hwp/bus_training/erepairSetMnfgFailedLanesHwp.C | 808 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/bus_training/erepair_errors.xml | 61 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/bus_training/makefile | 4 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/dmi_training/dmi_training.C | 49 |
8 files changed, 2279 insertions, 324 deletions
diff --git a/src/usr/hwpf/hwp/bus_training/erepairAccessorHwpFuncs.C b/src/usr/hwpf/hwp/bus_training/erepairAccessorHwpFuncs.C index dbca7cb0a..b31f9bada 100644 --- a/src/usr/hwpf/hwp/bus_training/erepairAccessorHwpFuncs.C +++ b/src/usr/hwpf/hwp/bus_training/erepairAccessorHwpFuncs.C @@ -289,25 +289,19 @@ fapi::ReturnCode erepairGetRestoreLanes(const fapi::Target &i_endp1_target, // Check if MNFG_DISABLE_FABRIC_EREPAIR is enabled l_disableFabricERepair = false; - // TODO: This Mnfg flag is not defined yet. RTC: 59532 - /* if(l_allMnfgFlags & - fapi::ENUM_ATTR_MNFG_FLAGS_MNFG_DISABLE_FABRIC_EREPAIR) + fapi::ENUM_ATTR_MNFG_FLAGS_MNFG_DISABLE_FABRIC_eREPAIR) { l_disableFabricERepair = true; } - */ // Check if MNFG_DISABLE_MEMORY_EREPAIR is enabled l_disableMemoryERepair = false; - // TODO: This Mnfg flag is not defined yet. RTC: 59532 - /* if(l_allMnfgFlags & - fapi::ENUM_ATTR_MNFG_FLAGS_MNFG_DISABLE_MEMORY_EREPAIR) + fapi::ENUM_ATTR_MNFG_FLAGS_MNFG_DISABLE_MEMORY_eREPAIR) { l_disableMemoryERepair = true; } - */ // Check if this is Manufacturing mode IPL. l_mnfgModeIPL = false; @@ -333,7 +327,7 @@ fapi::ReturnCode erepairGetRestoreLanes(const fapi::Target &i_endp1_target, break; } - if(l_disableFabricERepair) + if(l_mnfgModeIPL && l_disableFabricERepair) { // Fabric eRepair has been disabled using the // Manufacturing policy flags @@ -352,7 +346,7 @@ fapi::ReturnCode erepairGetRestoreLanes(const fapi::Target &i_endp1_target, FAPI_SET_HWP_ERROR(l_rc, RC_EREPAIR_RESTORE_INVALID_TARGET_PAIR); break; } - else if(l_disableMemoryERepair) + else if(l_mnfgModeIPL && l_disableMemoryERepair) { // Memory eRepair has been disabled using the // Manufacturing policy flags @@ -360,33 +354,6 @@ fapi::ReturnCode erepairGetRestoreLanes(const fapi::Target &i_endp1_target, break; } - // TODO: Target Type of fapi::TARGET_TYPE_MEMBUF_CHIP will be supported - // when HWSV will provide the device driver to read the - // Centaur FRU VPD. RTC Task 51234, Depends on Story 44009 - // This is a temporary workaround for December PON. Delete this block. - fapi::Target l_endp1_target, l_endp2_target; - if(l_endp1_tgtType == fapi::TARGET_TYPE_MEMBUF_CHIP) - { - l_endp1_target = l_endp2_target = i_endp2_target; - - FAPI_INF(">>erepairGetRestoreLanes: PON Workaround: endp1 = %s," - " endp2 = %s", l_endp1_target.toEcmdString(), - l_endp2_target.toEcmdString()); - } - else if(l_endp2_tgtType == fapi::TARGET_TYPE_MEMBUF_CHIP) - { - l_endp1_target = l_endp2_target = i_endp1_target; - - FAPI_INF(">>erepairGetRestoreLanes: PON Workaround: endp1 = %s," - " endp2 = %s", l_endp1_target.toEcmdString(), - l_endp2_target.toEcmdString()); - } - else - { - l_endp1_target = i_endp1_target; - l_endp2_target = i_endp2_target; - } - #ifndef __HOSTBOOT_MODULE // TODO: Check if this is CHARM mode IPL. RTC: 59493 // l_charmModeIPL = <read_TBD> @@ -406,8 +373,8 @@ fapi::ReturnCode erepairGetRestoreLanes(const fapi::Target &i_endp1_target, /***** Check Field VPD *****/ // Do not allow eRepair data in Field VPD during Mfg Mode IPL - l_rc = mnfgCheckFieldVPD(l_endp1_target, - l_endp2_target); + l_rc = mnfgCheckFieldVPD(i_endp1_target, + i_endp2_target); if(l_rc) { FAPI_ERR("erepairGetRestoreLanes:Error from mnfgCheckFieldVPD"); @@ -415,15 +382,10 @@ fapi::ReturnCode erepairGetRestoreLanes(const fapi::Target &i_endp1_target, } /***** Read Manufacturing VPD *****/ - // TODO: This is a temporary workaround until HWSV gets - // the MER0 records into PNOR. As per Dean, the - // Manufacturing support is needed by Feb-2013 - // RTC Task: 60517 - /* // Uncomment this block when MER0 is available - l_rc = getVerifiedRepairLanes(l_endp1_target, + l_rc = getVerifiedRepairLanes(i_endp1_target, o_endp1_txFaillanes, o_endp1_rxFaillanes, - l_endp2_target, + i_endp2_target, o_endp2_txFaillanes, o_endp2_rxFaillanes, l_charmModeIPL, @@ -434,7 +396,6 @@ fapi::ReturnCode erepairGetRestoreLanes(const fapi::Target &i_endp1_target, " getVerifiedRepairLanes(Mnfg)"); break; } - */ } else { /***** Normal Mode IPL *****/ @@ -444,14 +405,10 @@ fapi::ReturnCode erepairGetRestoreLanes(const fapi::Target &i_endp1_target, /***** Read Manufacturing VPD *****/ - // TODO: This is a temporary workaround until HWSV gets - // the MER0 records into PNOR - // RTC Task: 60517 - /* // Uncomment this block when MER0 is available - l_rc = getVerifiedRepairLanes(l_endp1_target, + l_rc = getVerifiedRepairLanes(i_endp1_target, l_endp1_txMnfgFaillanes, l_endp1_rxMnfgFaillanes, - l_endp2_target, + i_endp2_target, l_endp2_txMnfgFaillanes, l_endp2_rxMnfgFaillanes, l_charmModeIPL, @@ -462,14 +419,13 @@ fapi::ReturnCode erepairGetRestoreLanes(const fapi::Target &i_endp1_target, " getVerifiedRepairLanes(Mnfg)"); break; } - */ /***** Read Field VPD *****/ - l_rc = getVerifiedRepairLanes(l_endp1_target, + l_rc = getVerifiedRepairLanes(i_endp1_target, l_endp1_txFieldFaillanes, l_endp1_rxFieldFaillanes, - l_endp2_target, + i_endp2_target, l_endp2_txFieldFaillanes, l_endp2_rxFieldFaillanes, l_charmModeIPL, @@ -540,7 +496,7 @@ fapi::ReturnCode erepairGetRestoreLanes(const fapi::Target &i_endp1_target, // Get the eRepair threshold limit l_threshold = 0; - l_rc = geteRepairThreshold(l_endp1_target, l_mnfgModeIPL, l_threshold); + l_rc = geteRepairThreshold(i_endp1_target, l_mnfgModeIPL, l_threshold); if(l_rc) { @@ -548,6 +504,9 @@ fapi::ReturnCode erepairGetRestoreLanes(const fapi::Target &i_endp1_target, break; } + /*** We want to create eRepair threshold exceed error logs for ***/ + /*** each of the Tx and Rx sub-interfaces of both the end-points ***/ + // Check if the eRepair threshold has exceeded for Tx side of endp1 if(o_endp1_txFaillanes.size() > l_threshold) { @@ -556,10 +515,14 @@ fapi::ReturnCode erepairGetRestoreLanes(const fapi::Target &i_endp1_target, FAPI_ERR("erepairGetRestoreLanes: eRepair threshold exceed error" " seen in Tx of endp1 target. No.of lanes: %d", o_endp1_txFaillanes.size()); - // TODO: RTC 60623 - // Need to provide FFDC data that has - - // End point targets, Sub-interface type and fail lanes causing - // threshold exceed + + fapi::ReturnCode l_rcLog; + const fapi::Target &FFDC_ENDP_TARGET = i_endp1_target; + const interfaceType &FFDC_SUB_IFACE = DRIVE; + const uint32_t &FFDC_LANES = o_endp1_txFaillanes.size(); + FAPI_SET_HWP_ERROR(l_rcLog, RC_EREPAIR_RESTORE_THRESHOLD_EXCEED); + + fapiLogError(l_rcLog); } // Check if the eRepair threshold has exceeded for Rx side of endp1 @@ -570,10 +533,14 @@ fapi::ReturnCode erepairGetRestoreLanes(const fapi::Target &i_endp1_target, FAPI_ERR("erepairGetRestoreLanes: eRepair threshold exceed error" " seen in Rx of endp1 target. No.of lanes: %d", o_endp1_rxFaillanes.size()); - // TODO: RTC 60623 - // Need to provide FFDC data that has - - // End point targets, Sub-interface type and fail lanes causing - // threshold exceed + + fapi::ReturnCode l_rcLog; + const fapi::Target &FFDC_ENDP_TARGET = i_endp1_target; + const interfaceType &FFDC_SUB_IFACE = RECEIVE; + const uint32_t &FFDC_LANES = o_endp1_rxFaillanes.size(); + FAPI_SET_HWP_ERROR(l_rcLog, RC_EREPAIR_RESTORE_THRESHOLD_EXCEED); + + fapiLogError(l_rcLog); } // Check if the eRepair threshold has exceeded for Tx side of endp2 @@ -584,10 +551,14 @@ fapi::ReturnCode erepairGetRestoreLanes(const fapi::Target &i_endp1_target, FAPI_ERR("erepairGetRestoreLanes: eRepair threshold exceed error" " seen in Tx of endp2 target. No.of lanes: %d", o_endp2_txFaillanes.size()); - // TODO: RTC 60623 - // Need to provide FFDC data that has - - // End point targets, Sub-interface type and fail lanes causing - // threshold exceed + + fapi::ReturnCode l_rcLog; + const fapi::Target &FFDC_ENDP_TARGET = i_endp2_target; + const interfaceType &FFDC_SUB_IFACE = DRIVE; + const uint32_t &FFDC_LANES = o_endp2_txFaillanes.size(); + FAPI_SET_HWP_ERROR(l_rcLog, RC_EREPAIR_RESTORE_THRESHOLD_EXCEED); + + fapiLogError(l_rcLog); } // Check if the eRepair threshold has exceeded for Rx side of endp2 @@ -598,17 +569,21 @@ fapi::ReturnCode erepairGetRestoreLanes(const fapi::Target &i_endp1_target, FAPI_ERR("erepairGetRestoreLanes: eRepair threshold exceed error" " seen in Rx of endp2 target. No.of lanes: %d", o_endp2_rxFaillanes.size()); - // TODO: RTC 60623 - // Need to provide FFDC data that has - - // End point targets, Sub-interface type and fail lanes causing - // threshold exceed + + fapi::ReturnCode l_rcLog; + const fapi::Target &FFDC_ENDP_TARGET = i_endp2_target; + const interfaceType &FFDC_SUB_IFACE = RECEIVE; + const uint32_t &FFDC_LANES = o_endp2_rxFaillanes.size(); + FAPI_SET_HWP_ERROR(l_rcLog, RC_EREPAIR_RESTORE_THRESHOLD_EXCEED); + + fapiLogError(l_rcLog); } if(l_thresholdExceed) { FAPI_ERR("erepairGetRestoreLanes: Threshold has Exceeded"); - FAPI_SET_HWP_ERROR(l_rc, RC_EREPAIR_RESTORE_THRESHOLD_EXCEED); + FAPI_SET_HWP_ERROR(l_rc, RC_EREPAIR_THRESHOLD_EXCEED); break; } @@ -642,7 +617,7 @@ fapi::ReturnCode erepairGetRestoreLanes(const fapi::Target &i_endp1_target, if(o_endp1_txFaillanes.size() || o_endp1_rxFaillanes.size()) { l_sparesFound = false; - l_rc = removeSpareLanes(l_endp1_target, + l_rc = removeSpareLanes(i_endp1_target, o_endp1_txFaillanes, o_endp1_rxFaillanes, l_sparesFound); @@ -661,39 +636,11 @@ fapi::ReturnCode erepairGetRestoreLanes(const fapi::Target &i_endp1_target, } } - // TODO: Delete the below block after uncommenting the next block - // Check if the fail lanes of endp2 are spare lanes. RTC: 51234 - if(o_endp2_rxFaillanes.size() || o_endp2_txFaillanes.size()) - { - l_sparesFound = false; - l_rc = removeSpareLanes(l_endp2_target, - o_endp2_rxFaillanes, - o_endp2_txFaillanes, - l_sparesFound); - - if(l_rc) - { - FAPI_ERR("erepairGetRestoreLanes: Error from" - " removeSpareLanes(endp2)"); - break; - } - - if(l_sparesFound) - { - FAPI_SET_HWP_ERROR(l_rc, RC_EREPAIR_RESTORE_SPARE_LANES_IN_VPD); - fapiLogError(l_rc); - } - } - - // TODO: This is a workaround for Jan-2013 PON. - // Need to uncomment the below block when there is - // support for MemBuf chips. RTC: 51234 // Check if the fail lanes of endp2 are spare lanes - /* - if(o_endp2_txFaillanes.size() || o_endp2_rxFaillanes.size()) + if(o_endp2_rxFaillanes.size() || o_endp2_txFaillanes.size()) { l_sparesFound = false; - l_rc = removeSpareLanes(l_endp2_target, + l_rc = removeSpareLanes(i_endp2_target, o_endp2_txFaillanes, o_endp2_rxFaillanes, l_sparesFound); @@ -711,31 +658,24 @@ fapi::ReturnCode erepairGetRestoreLanes(const fapi::Target &i_endp1_target, fapiLogError(l_rc); } } - */ if(l_mnfgModeIPL) { - // Check if MNFG_DMI_DEPLOY_SPARE_LANES is enabled + // Check if MNFG_DMI_DEPLOY_LANE_SPARES is enabled l_enableDmiSpares = false; - // TODO: This Mnfg flag is not defined yet. RTC: 59532 - /* if(l_allMnfgFlags & - fapi::ENUM_ATTR_MNFG_FLAGS_MNFG_DMI_DEPLOY_SPARE_LANES) + fapi::ENUM_ATTR_MNFG_FLAGS_MNFG_DMI_DEPLOY_LANE_SPARES) { l_enableDmiSpares = true; } - */ // Check if MNFG_FABRIC_DEPLOY_LANE_SPARES is enabled l_enableFabricSpares = false; - // TODO: This Mnfg flag is not defined yet. RTC: 59532 - /* if(l_allMnfgFlags & - fapi::ENUM_ATTR_MNFG_FLAGS_MNFG_FABRIC_DEPLOY_SPARE_LANES) + fapi::ENUM_ATTR_MNFG_FLAGS_MNFG_FABRIC_DEPLOY_LANE_SPARES) { l_enableFabricSpares = true; } - */ if(l_enableDmiSpares || l_enableFabricSpares) { @@ -1004,6 +944,7 @@ fapi::ReturnCode geteRepairThreshold(const fapi::Target &i_endp_target, do { + o_threshold = 0; l_tgtType = i_endp_target.getType(); if(i_mfgModeIPL) @@ -1011,32 +952,28 @@ fapi::ReturnCode geteRepairThreshold(const fapi::Target &i_endp_target, switch(l_tgtType) { case fapi::TARGET_TYPE_XBUS_ENDPOINT: - o_threshold = 1; // This is a temp value used during PON - // TODO: RTC: 50284 - // l_rc=FAPI_ATTR_GET(<ATTR_x-erepair-threshold-mnfg>, - // &<systemTarget>, - // o_threshold) + l_rc = FAPI_ATTR_GET(ATTR_X_EREPAIR_THRESHOLD_MNFG, + NULL, + o_threshold); break; case fapi::TARGET_TYPE_ABUS_ENDPOINT: - o_threshold = 0; // This is a temp value used during PON - // l_rc=FAPI_ATTR_GET(<ATTR_a-erepair-threshold-mnfg>, - // &<systemTarget>, - // o_threshold) + l_rc = FAPI_ATTR_GET(ATTR_A_EREPAIR_THRESHOLD_MNFG, + NULL, + o_threshold); break; case fapi::TARGET_TYPE_MCS_CHIPLET: - o_threshold = 1; // This is a temp value used during PON - // l_rc=FAPI_ATTR_GET(<ATTR_dmi-erepair-threshold-mnfg>, - // &<systemTarget>, - // o_threshold) - FAPI_INF("geteRepairThreshold: Mnfg VPD, PON Workaround:" - " o_threshold = %d", o_threshold); + case fapi::TARGET_TYPE_MEMBUF_CHIP: + l_rc = FAPI_ATTR_GET(ATTR_DMI_EREPAIR_THRESHOLD_MNFG, + NULL, + o_threshold); break; default: FAPI_ERR("geteRepairThreshold: Invalid target type %d", l_tgtType); + FAPI_SET_HWP_ERROR(l_rc, RC_EREPAIR_RESTORE_INVALID_TARGET); break; }; } @@ -1045,31 +982,28 @@ fapi::ReturnCode geteRepairThreshold(const fapi::Target &i_endp_target, switch(l_tgtType) { case fapi::TARGET_TYPE_XBUS_ENDPOINT: - o_threshold = 1; // This is a temp value used during PON - // l_rc=FAPI_ATTR_GET(<ATTR_x-erepair-threshold-field>, - // &<systemTarget>, - // o_threshold) + l_rc = FAPI_ATTR_GET(ATTR_X_EREPAIR_THRESHOLD_FIELD, + NULL, + o_threshold); break; case fapi::TARGET_TYPE_ABUS_ENDPOINT: - o_threshold = 1; // This is a temp value used during PON - // l_rc=FAPI_ATTR_GET(<ATTR_a-erepair-threshold-field>, - // &<systemTarget>, - // o_threshold) + l_rc = FAPI_ATTR_GET(ATTR_A_EREPAIR_THRESHOLD_FIELD, + NULL, + o_threshold); break; case fapi::TARGET_TYPE_MCS_CHIPLET: - o_threshold = 1; // This is a temp value used during PON - // l_rc=FAPI_ATTR_GET(<ATTR_dmi-erepair-threshold-field>>, - // &<systemTarget>, - // o_threshold) - FAPI_INF("geteRepairThreshold: Field VPD, PON Workaround:" - " o_threshold = %d", o_threshold); + case fapi::TARGET_TYPE_MEMBUF_CHIP: + l_rc = FAPI_ATTR_GET(ATTR_DMI_EREPAIR_THRESHOLD_FIELD, + NULL, + o_threshold); break; default: FAPI_ERR("geteRepairThreshold: Invalid target type %d", l_tgtType); + FAPI_SET_HWP_ERROR(l_rc, RC_EREPAIR_RESTORE_INVALID_TARGET); break; }; } @@ -1117,7 +1051,7 @@ fapi::ReturnCode mnfgCheckFieldVPD(const fapi::Target &i_endp1_target, l_fieldVPDClear = false; FAPI_ERR("mnfgCheckFieldVPD: eRepair records found in" - " Field VPD of %s during Manufacturing mode IPL", + " Field VPD, in Tx of %s during Manufacturing mode IPL", i_endp1_target.toEcmdString()); } @@ -1141,7 +1075,7 @@ fapi::ReturnCode mnfgCheckFieldVPD(const fapi::Target &i_endp1_target, l_fieldVPDClear = false; FAPI_ERR("mnfgCheckFieldVPD: eRepair records found in" - " Field VPD of %s during Manufacturing mode IPL", + " Field VPD, in Rx of %s during Manufacturing mode IPL", i_endp2_target.toEcmdString()); } @@ -1169,17 +1103,15 @@ fapi::ReturnCode getVerifiedRepairLanes( { fapi::ReturnCode l_rc; - bool l_invalidFails_inTx_Ofendp1 = false; - bool l_invalidFails_inRx_Ofendp1 = false; - bool l_invalidFails_inTx_Ofendp2 = false; - bool l_invalidFails_inRx_Ofendp2 = false; - std::vector<uint8_t> l_emptyVector; - getLanes_t l_getLanes = NULL; setLanes_t l_setLanes = NULL; fapi::Target l_target[2] = {i_endp1_target, i_endp2_target}; - uint8_t l_tgtIndx = 0; + 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; @@ -1215,6 +1147,7 @@ fapi::ReturnCode getVerifiedRepairLanes( l_target[l_tgtIndx].toEcmdString()); break; } + if(l_tgtIndx == 0) { o_endp1_txFaillanes = l_txFaillanes; @@ -1228,7 +1161,7 @@ fapi::ReturnCode getVerifiedRepairLanes( l_txFaillanes.clear(); l_rxFaillanes.clear(); - } + } // end of for(l_tgtIndx) if(l_rc) { @@ -1247,25 +1180,20 @@ fapi::ReturnCode getVerifiedRepairLanes( // Check if matching fail lanes exists on the sub-interfaces // connecting the two end points - l_invalidFails_inTx_Ofendp1 = false; - l_invalidFails_inRx_Ofendp2 = false; - l_invalidFails_inRx_Ofendp1 = false; - l_invalidFails_inTx_Ofendp2 = false; - if(o_endp1_txFaillanes.size() || o_endp2_rxFaillanes.size()) { invalidateNonMatchingFailLanes(o_endp1_txFaillanes, o_endp2_rxFaillanes, - l_invalidFails_inTx_Ofendp1, - l_invalidFails_inRx_Ofendp2); + 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_Ofendp2, - l_invalidFails_inRx_Ofendp1); + l_invalidFails_inTx_OfTgt[1], + l_invalidFails_inRx_OfTgt[0]); } /***** Correct eRepair data of endp1 in VPD *****/ @@ -1285,7 +1213,8 @@ fapi::ReturnCode getVerifiedRepairLanes( // Update endp1 and endp2 VPD to invalidate fail lanes that do // not have matching fail lanes on the other end - if(l_invalidFails_inTx_Ofendp1 && l_invalidFails_inRx_Ofendp1) + if(l_invalidFails_inTx_OfTgt[l_tgtIndx] && + l_invalidFails_inRx_OfTgt[l_tgtIndx]) { l_rc = l_setLanes(l_target[l_tgtIndx], l_txFaillanes, @@ -1298,7 +1227,7 @@ fapi::ReturnCode getVerifiedRepairLanes( break; } } - else if(l_invalidFails_inTx_Ofendp1) + else if(l_invalidFails_inTx_OfTgt[l_tgtIndx]) { l_rc = l_setLanes(l_target[l_tgtIndx], l_txFaillanes, @@ -1311,7 +1240,7 @@ fapi::ReturnCode getVerifiedRepairLanes( break; } } - else if(l_invalidFails_inRx_Ofendp1) + else if(l_invalidFails_inRx_OfTgt[l_tgtIndx]) { l_rc = l_setLanes(l_target[l_tgtIndx], l_emptyVector, @@ -1417,6 +1346,7 @@ fapi::ReturnCode erepairGetFailedLanes(const fapi::Target &i_endp_target, do { + // Get the erepair lanes from Field VPD l_rc = erepairGetFieldFailedLanes(i_endp_target, l_txFailLanes, l_rxFailLanes); @@ -1430,6 +1360,7 @@ fapi::ReturnCode erepairGetFailedLanes(const fapi::Target &i_endp_target, o_txFailLanes = l_txFailLanes; o_rxFailLanes = l_rxFailLanes; + // Get the erepair lanes from Manufacturing VPD l_txFailLanes.clear(); l_rxFailLanes.clear(); l_rc = erepairGetMnfgFailedLanes(i_endp_target, @@ -1442,7 +1373,7 @@ fapi::ReturnCode erepairGetFailedLanes(const fapi::Target &i_endp_target, break; } - // Merge the Mnfg lanes with the Field lanes read previously + // Merge the Mnfg lanes with the Field lanes l_it = o_txFailLanes.end(); o_txFailLanes.insert(l_it, l_txFailLanes.begin(), l_txFailLanes.end()); @@ -1505,7 +1436,6 @@ fapi::ReturnCode erepairGetMnfgFailedLanes(const fapi::Target &i_endp_target, FAPI_INF(">> erepairGetMnfgFailedLanes for %s", i_endp_target.toEcmdString()); - do { // Execute the Accessor HWP to retrieve the failed lanes from the VPD @@ -1540,43 +1470,209 @@ fapi::ReturnCode erepairGetMnfgFailedLanes(const fapi::Target &i_endp_target, return l_rc; } -// TODO: RTC: 59554 -// This functionality will be completed when the Accessor HWP will have -// write capability fapi::ReturnCode erepairSetFailedLanes( - const fapi::Target &i_endp_target, - const std::vector<uint8_t> &i_txFailLanes, - const std::vector<uint8_t> &i_rxFailLanes) + const fapi::Target &i_txEndp_target, + const fapi::Target &i_rxEndp_target, + const std::vector<uint8_t> &i_rxFailLanes, + bool &o_thresholdExceed) { fapi::ReturnCode l_rc; + uint64_t l_allMnfgFlags = 0; + bool l_mnfgModeIPL = false; + uint8_t l_threshold = 0; + setLanes_t l_setLanes = NULL; + getLanes_t 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: %s-%s", + i_rxEndp_target.toEcmdString(), i_txEndp_target.toEcmdString()); + + do + { + o_thresholdExceed = false; + + // Get the Manufacturing Policy flags + l_rc = FAPI_ATTR_GET(ATTR_MNFG_FLAGS, NULL, l_allMnfgFlags); + + if(l_rc) + { + FAPI_ERR("erepairSetFailedLanes: Unable to read attribute" + "ATTR_MNFG_FLAGS"); + break; + } + + // Check if this is a Mnfg mode IPL + if(l_allMnfgFlags & fapi::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; + l_rc = geteRepairThreshold(i_rxEndp_target, l_mnfgModeIPL, l_threshold); + + if(l_rc) + { + FAPI_ERR("erepairSetFailedLanes: Error (0x%x) from" + " geteRepairThreshold", static_cast<uint32_t> (l_rc)); + break; + } + + // Check if the new fails have crossed the threshold + if(i_rxFailLanes.size() > l_threshold) + { + o_thresholdExceed = true; + break; + } + + // Get existing fail lanes that are in the VPD of rx endpoint + l_rc = l_getLanes(i_rxEndp_target, l_throwAway, l_rxFaillanes); + + if(l_rc) + { + FAPI_ERR("erepairSetFailedLanes: Error (0x%x) from" + " l_getLanes for %s", static_cast<uint32_t> (l_rc), + i_rxEndp_target.toEcmdString()); + break; + } + + // Get existing fail lanes that are in the VPD of tx endpoint + l_rc = l_getLanes(i_txEndp_target, l_txFaillanes, l_throwAway); + + if(l_rc) + { + FAPI_ERR("erepairSetFailedLanes: Error (0x%x) from" + " l_getLanes for %s", static_cast<uint32_t> (l_rc), + i_txEndp_target.toEcmdString()); + break; + } + + // 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; + break; + } + + /*** Update the VPD ***/ + + // Lets write the VPD of endpoint1 with faillanes on Rx side + l_rc = l_setLanes(i_rxEndp_target, l_emptyVector, l_rxFaillanes); + if(l_rc) + { + FAPI_ERR("Error from l_setLanes for %s", + i_rxEndp_target.toEcmdString()); + break; + } + + // Lets write the VPD of endpoint2 with faillanes on Tx side + l_rc = l_setLanes(i_txEndp_target, l_txFaillanes, l_emptyVector); + if(l_rc) + { + FAPI_ERR("Error from l_setLanes for %s", + i_txEndp_target.toEcmdString()); + break; + } + }while(0); + + FAPI_INF("<< erepairSetFailedLanes"); return l_rc; } -// TODO: RTC: 59554 -// This functionality will be completed when the Accessor HWP will have -// write capability fapi::ReturnCode erepairSetFieldFailedLanes( - const fapi::Target &i_endp_target, + const fapi::Target &i_endp_target, const std::vector<uint8_t> &i_txFailLanes, const std::vector<uint8_t> &i_rxFailLanes) { - fapi::ReturnCode l_rc; + fapi::ReturnCode l_rc; + std::vector<uint8_t> l_txFailedLanes; + std::vector<uint8_t> l_rxFailedLanes; + + do + { + // Execute the Accessor HWP to write the fail lanes to Field VPD + FAPI_EXEC_HWP(l_rc, + erepairSetFailedLanesHwp, + i_endp_target, + i_txFailLanes, + i_rxFailLanes); + + if(l_rc) + { + FAPI_ERR("erepairSetFieldFailedLanes: Error from Accessor HWP:" + "erepairSetFailedLanesHwp"); + break; + } + }while(0); + return l_rc; } -// TODO: RTC: 59554 -// This functionality will be completed when the Accessor HWP will have -// write capability fapi::ReturnCode erepairSetMnfgFailedLanes( const fapi::Target &i_endp_target, const std::vector<uint8_t> &i_txFailLanes, const std::vector<uint8_t> &i_rxFailLanes) { fapi::ReturnCode l_rc; + + do + { + // Execute the Accessor HWP to write the fail lanes to Mnfg VPD + FAPI_EXEC_HWP(l_rc, + erepairSetMnfgFailedLanesHwp, + i_endp_target, + i_txFailLanes, + i_rxFailLanes); + + if(l_rc) + { + FAPI_ERR("erepairSetMnfgFailedLanes: Error from Accessor HWP:" + "erepairSetMnfgFailedLanesHwp"); + break; + } + }while(0); + return l_rc; } - #ifndef __HOSTBOOT_MODULE bool charmModeThresholdExceed(std::vector<uint8_t> &i_endp1_txFaillanes, std::vector<uint8_t> &i_endp1_rxFaillanes, diff --git a/src/usr/hwpf/hwp/bus_training/erepairGetFailedLanesHwp.C b/src/usr/hwpf/hwp/bus_training/erepairGetFailedLanesHwp.C index 153eb17fe..ddc54e0f4 100644 --- a/src/usr/hwpf/hwp/bus_training/erepairGetFailedLanesHwp.C +++ b/src/usr/hwpf/hwp/bus_training/erepairGetFailedLanesHwp.C @@ -51,10 +51,6 @@ extern "C" * parsing. * * @param[in] i_tgtHandle Reference to X-Bus or A-Bus or MCS target - * @param[in] i_procTgt Reference to the Processor target associated with - * passed i_tgtHandle - * @param[in] i_recordType This is the VPD record type that is used to query - * the VPD data * @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 @@ -63,8 +59,6 @@ extern "C" * @return ReturnCode */ fapi::ReturnCode retrieveRepairData(const fapi::Target &i_tgtHandle, - const fapi::Target &i_procTgt, - fapi::MvpdRecord i_recordType, std::vector<uint8_t> &o_txFailLanes, std::vector<uint8_t> &o_rxFailLanes); @@ -103,7 +97,6 @@ fapi::ReturnCode erepairGetFailedLanesHwp(const fapi::Target &i_tgtHandle, { fapi::ReturnCode l_rc; fapi::Target l_processorTgt; - fapi::MvpdRecord l_fieldRecord; fapi::TargetType l_tgtType = fapi::TARGET_TYPE_NONE; std::vector<fapi::Target> l_mcsChiplets; @@ -119,10 +112,8 @@ fapi::ReturnCode erepairGetFailedLanesHwp(const fapi::Target &i_tgtHandle, l_tgtType = i_tgtHandle.getType(); // Verify if the correct target type is passed - // TODO: l_tgtType of fapi::TARGET_TYPE_MEMBUF_CHIP will be supported - // when HWSV will provide the device driver to read the - // Centaur FRU VPD. RTC Task 51234, Depends on Story 44009 if((l_tgtType != fapi::TARGET_TYPE_MCS_CHIPLET) && + (l_tgtType != fapi::TARGET_TYPE_MEMBUF_CHIP) && (l_tgtType != fapi::TARGET_TYPE_XBUS_ENDPOINT) && (l_tgtType != fapi::TARGET_TYPE_ABUS_ENDPOINT)) { @@ -132,27 +123,15 @@ fapi::ReturnCode erepairGetFailedLanesHwp(const fapi::Target &i_tgtHandle, break; } - // Determine the Processor target - l_rc = fapiGetParentChip(i_tgtHandle, l_processorTgt); - if(l_rc) - { - FAPI_ERR("Error (0x%x) from fapiGetParentChip", - static_cast<uint32_t>(l_rc)); - break; - } - // Retrieve the Field eRepair lane numbers from the VPD - l_fieldRecord = fapi::MVPD_RECORD_VWML; l_rc = retrieveRepairData(i_tgtHandle, - l_processorTgt, - l_fieldRecord, o_txFailLanes, o_rxFailLanes); if(l_rc) { FAPI_ERR("Error (0x%x) during retrieval of Field records", - static_cast<uint32_t>(l_rc)); + static_cast<uint32_t>(l_rc)); break; } }while(0); @@ -162,37 +141,42 @@ fapi::ReturnCode erepairGetFailedLanesHwp(const fapi::Target &i_tgtHandle, return l_rc; } - fapi::ReturnCode retrieveRepairData(const fapi::Target &i_tgtHandle, - const fapi::Target &i_procTgt, - fapi::MvpdRecord i_recordType, std::vector<uint8_t> &o_txFailLanes, std::vector<uint8_t> &o_rxFailLanes) { - uint8_t *l_retBuf = NULL; - uint32_t l_bufSize = 0; fapi::ReturnCode l_rc; + uint8_t *l_retBuf = NULL; + uint32_t l_bufSize = 0; + fapi::Target l_procTarget; - FAPI_INF(">> retrieveRepairData: i_procTgt: %s", i_procTgt.toEcmdString()); + FAPI_INF(">> retrieveRepairData"); do { - // Determine the size of the eRepair data in the VPD - l_rc = fapiGetMvpdField(i_recordType, - fapi::MVPD_KEYWORD_PDI, - i_procTgt, - NULL, - l_bufSize); - - if(l_rc) + if(i_tgtHandle.getType() == fapi::TARGET_TYPE_MEMBUF_CHIP) { - FAPI_ERR("Error (0x%x) from fapiGetMvpdField", - static_cast<uint32_t> (l_rc)); - break; - } + // Determine the size of the eRepair data in the VPD + l_rc = fapiGetMBvpdField(fapi::MBVPD_RECORD_VEIR, + fapi::MBVPD_KEYWORD_PDI, + i_tgtHandle, + NULL, + l_bufSize); + + if(l_rc) + { + FAPI_ERR("Error (0x%x) during VPD size read", + static_cast<uint32_t> (l_rc)); + break; + } + + if((l_bufSize == 0) || + (l_bufSize > EREPAIR::EREPAIR_MEM_FIELD_VPD_SIZE_PER_CENTAUR)) + { + FAPI_SET_HWP_ERROR(l_rc, RC_ACCESSOR_HWP_INVALID_MEM_VPD_SIZE); + break; + } - if(l_bufSize != 0) - { // Allocate memory for buffer l_retBuf = new uint8_t[l_bufSize]; if(l_retBuf == NULL) @@ -203,32 +187,88 @@ fapi::ReturnCode retrieveRepairData(const fapi::Target &i_tgtHandle, } // Retrieve the Field eRepair data from the PNOR - l_rc = fapiGetMvpdField(i_recordType, + l_rc = fapiGetMBvpdField(fapi::MBVPD_RECORD_VEIR, + fapi::MBVPD_KEYWORD_PDI, + i_tgtHandle, + l_retBuf, + l_bufSize); + + if(l_rc) + { + FAPI_ERR("Error (0x%x) during VPD read", + static_cast<uint32_t> (l_rc)); + break; + } + } + else + { + // Determine the Processor target + l_rc = fapiGetParentChip(i_tgtHandle, l_procTarget); + if(l_rc) + { + FAPI_ERR("Error (0x%x) from fapiGetParentChip", + static_cast<uint32_t>(l_rc)); + break; + } + + // Determine the size of the eRepair data in the VPD + l_rc = fapiGetMvpdField(fapi::MVPD_RECORD_VWML, fapi::MVPD_KEYWORD_PDI, - i_procTgt, - l_retBuf, + l_procTarget, + NULL, l_bufSize); if(l_rc) { - FAPI_ERR("Error (0x%x) from fapiGetMvpdField", + FAPI_ERR("Error (0x%x) during VPD size read", static_cast<uint32_t> (l_rc)); break; } - // Parse the buffer to determine eRepair lanes and copy the - // fail lane numbers to the return vector - l_rc = determineRepairLanes(i_tgtHandle, - l_retBuf, - l_bufSize, - o_txFailLanes, - o_rxFailLanes); + if((l_bufSize == 0) || + (l_bufSize > EREPAIR::EREPAIR_P8_MODULE_VPD_FIELD_SIZE)) + { + FAPI_SET_HWP_ERROR(l_rc, + RC_ACCESSOR_HWP_INVALID_FABRIC_VPD_SIZE); + break; + } + + // Allocate memory for buffer + l_retBuf = new uint8_t[l_bufSize]; + if(l_retBuf == NULL) + { + FAPI_ERR("Failed to allocate memory size of %d", l_bufSize); + FAPI_SET_HWP_ERROR(l_rc, RC_ACCESSOR_HWP_MEMORY_ALLOC_FAIL); + break; + } + + // Retrieve the Field eRepair data from the PNOR + l_rc = fapiGetMvpdField(fapi::MVPD_RECORD_VWML, + fapi::MVPD_KEYWORD_PDI, + l_procTarget, + l_retBuf, + l_bufSize); + if(l_rc) { - FAPI_ERR("determineRepairLanes failed"); + FAPI_ERR("Error (0x%x) during VPD read", + static_cast<uint32_t> (l_rc)); break; } } + + // Parse the buffer to determine eRepair lanes and copy the + // fail lane numbers to the return vector + l_rc = determineRepairLanes(i_tgtHandle, + l_retBuf, + l_bufSize, + o_txFailLanes, + o_rxFailLanes); + if(l_rc) + { + FAPI_ERR("determineRepairLanes failed"); + break; + } }while(0); // Delete the buffer which has Field eRepair data @@ -253,6 +293,8 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target &i_tgtHandle, const uint32_t l_memRepairDataSz = sizeof(eRepairMemBus); const uint32_t l_fabricRepairDataSz = sizeof(eRepairPowerBus); fapi::TargetType l_tgtType = fapi::TARGET_TYPE_NONE; + fapi::Target l_mcsTarget; + fapi::Target l_tgtHandle; fapi::ReturnCode l_rc; fapi::ATTR_CHIP_UNIT_POS_Type l_busNum; @@ -290,6 +332,9 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target &i_tgtHandle, break; } + // TODO: RTC task 71260 + // Investigate if there is an Endianess issue with + // the memcpy and fix it. memcpy(&l_fabricBus, l_vpdPtr, l_fabricRepairDataSz); // Check if we have the correct Processor ID @@ -335,10 +380,29 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target &i_tgtHandle, } } // end of for loop } // end of if(l_tgtType is XBus or ABus) - else if(l_tgtType == fapi::TARGET_TYPE_MCS_CHIPLET) + else if((l_tgtType == fapi::TARGET_TYPE_MCS_CHIPLET) || + (l_tgtType == fapi::TARGET_TYPE_MEMBUF_CHIP)) { // Parse for Memory bus data eRepairMemBus l_memBus; + l_tgtHandle = i_tgtHandle; + + if(l_tgtType == fapi::TARGET_TYPE_MEMBUF_CHIP) + { + l_rc = fapiGetOtherSideOfMemChannel( + i_tgtHandle, + l_mcsTarget, + fapi::TARGET_STATE_FUNCTIONAL); + + if(l_rc) + { + FAPI_ERR("determineRepairLanes: Unable to get the connected" + " MCS target"); + break; + } + + l_tgtHandle = l_mcsTarget; + } // Read Power bus eRepair data and get the failed lane numbers for(l_loop = 0; @@ -352,6 +416,9 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target &i_tgtHandle, break; } + // TODO: RTC task 71260 + // Investigate if there is an Endianess issue with + // the memcpy and fix it. memcpy(&l_memBus, l_vpdPtr, l_memRepairDataSz); // Check if we have the correct Processor ID @@ -366,7 +433,7 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target &i_tgtHandle, } // Check if we have the matching memory bus interface - l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS,&i_tgtHandle,l_busNum); + l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS,&l_tgtHandle,l_busNum); if(l_rc) { FAPI_ERR("Error (0x%x), from ATTR_CHIP_UNIT_POS", @@ -386,13 +453,27 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target &i_tgtHandle, } // Copy the fail lane numbers in the vectors - if(l_memBus.interface == EREPAIR::DMI_MCS_DRIVE) + if(l_tgtType == fapi::TARGET_TYPE_MCS_CHIPLET) { - o_txFailLanes.push_back(l_memBus.failBit); + if(l_memBus.interface == EREPAIR::DMI_MCS_DRIVE) + { + o_txFailLanes.push_back(l_memBus.failBit); + } + else if(l_memBus.interface == EREPAIR::DMI_MCS_RECEIVE) + { + o_rxFailLanes.push_back(l_memBus.failBit); + } } - else if(l_memBus.interface == EREPAIR::DMI_MCS_RECEIVE) + else if(l_tgtType == fapi::TARGET_TYPE_MEMBUF_CHIP) { - o_rxFailLanes.push_back(l_memBus.failBit); + if(l_memBus.interface == EREPAIR::DMI_MEMBUF_DRIVE) + { + o_txFailLanes.push_back(l_memBus.failBit); + } + else if(l_memBus.interface == EREPAIR::DMI_MEMBUF_RECEIVE) + { + o_rxFailLanes.push_back(l_memBus.failBit); + } } } // end of for loop } // end of if(l_tgtType is MCS) diff --git a/src/usr/hwpf/hwp/bus_training/erepairGetMnfgFailedLanesHwp.C b/src/usr/hwpf/hwp/bus_training/erepairGetMnfgFailedLanesHwp.C index 1c9ab547a..b026c2074 100644 --- a/src/usr/hwpf/hwp/bus_training/erepairGetMnfgFailedLanesHwp.C +++ b/src/usr/hwpf/hwp/bus_training/erepairGetMnfgFailedLanesHwp.C @@ -39,7 +39,10 @@ extern "C" { -/****************************************************************************** +// TODO: RTC Task: 69592. Refactor eRepair code to remove this file and change +// the erepairGetFailedLanesHwp.C file to read Manufacturing VPD + +/*****************************************************************************e * Forward Declarations *****************************************************************************/ @@ -52,10 +55,6 @@ extern "C" * parsing. * * @param[in] i_tgtHandle Reference to X-Bus or A-Bus or MCS target - * @param[in] i_procTgt Reference to the Processor target associated with - * passed i_tgtHandle - * @param[in] i_recordType This is the VPD record type that is used to query - * the VPD data * @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 @@ -64,8 +63,6 @@ extern "C" * @return ReturnCode */ fapi::ReturnCode retrieveMnfgRepairData(const fapi::Target &i_tgtHandle, - const fapi::Target &i_procTgt, - fapi::MvpdRecord i_recordType, std::vector<uint8_t> &o_txFailLanes, std::vector<uint8_t> &o_rxFailLanes); @@ -103,7 +100,6 @@ fapi::ReturnCode erepairGetMnfgFailedLanesHwp(const fapi::Target &i_tgtHandle, std::vector<uint8_t> &o_rxFailLanes) { fapi::ReturnCode l_rc; - fapi::Target l_processorTgt; fapi::TargetType l_tgtType = fapi::TARGET_TYPE_NONE; std::vector<fapi::Target> l_mcsChiplets; @@ -119,10 +115,8 @@ fapi::ReturnCode erepairGetMnfgFailedLanesHwp(const fapi::Target &i_tgtHandle, l_tgtType = i_tgtHandle.getType(); // Verify if the correct target type is passed - // TODO: l_tgtType of fapi::TARGET_TYPE_MEMBUF_CHIP will be supported - // when HWSV will provide the device driver to read the - // Centaur FRU VPD. RTC Task 51234, Depends on Story 44009 if((l_tgtType != fapi::TARGET_TYPE_MCS_CHIPLET) && + (l_tgtType != fapi::TARGET_TYPE_MEMBUF_CHIP) && (l_tgtType != fapi::TARGET_TYPE_XBUS_ENDPOINT) && (l_tgtType != fapi::TARGET_TYPE_ABUS_ENDPOINT)) { @@ -132,34 +126,17 @@ fapi::ReturnCode erepairGetMnfgFailedLanesHwp(const fapi::Target &i_tgtHandle, break; } - // Determine the Processor target - l_rc = fapiGetParentChip(i_tgtHandle, l_processorTgt); - if(l_rc) - { - FAPI_ERR("Error (0x%x) from fapiGetParentChip", - static_cast<uint32_t>(l_rc)); - break; - } - // Retrieve the Manufacturing eRepair lane numbers from the VPD - // TODO: Uncomment this block when the support for Mnfg VPD is - // available by HWSV in PNOR - /* - fapi::MvpdRecord l_mfgRecord; - l_mfgRecord = fapi::MVPD_RECORD_MER0; l_rc = retrieveMnfgRepairData(i_tgtHandle, - l_processorTgt, - l_mfgRecord, - o_txFailLanes, - o_rxFailLanes); + o_txFailLanes, + o_rxFailLanes); if(l_rc) { FAPI_ERR("Error (0x%x) during retrieval of Mfg records", - static_cast<uint32_t>(l_rc)); + static_cast<uint32_t>(l_rc)); break; } - */ }while(0); FAPI_INF("<< erepairGetMnfgFailedLanesHwp"); @@ -169,36 +146,41 @@ fapi::ReturnCode erepairGetMnfgFailedLanesHwp(const fapi::Target &i_tgtHandle, fapi::ReturnCode retrieveMnfgRepairData(const fapi::Target &i_tgtHandle, - const fapi::Target &i_procTgt, - fapi::MvpdRecord i_recordType, std::vector<uint8_t> &o_txFailLanes, std::vector<uint8_t> &o_rxFailLanes) { - uint8_t *l_retBuf = NULL; - uint32_t l_bufSize = 0; fapi::ReturnCode l_rc; + uint8_t *l_retBuf = NULL; + uint32_t l_bufSize = 0; + fapi::Target l_procTarget; - FAPI_INF(">> retrieveMnfgRepairData: i_procTgt: %s", - i_procTgt.toEcmdString()); + FAPI_INF(">> retrieveMnfgRepairData"); do { - // Determine the size of the eRepair data in the VPD - l_rc = fapiGetMvpdField(i_recordType, - fapi::MVPD_KEYWORD_PDI, - i_procTgt, - NULL, - l_bufSize); - - if(l_rc) + if(i_tgtHandle.getType() == fapi::TARGET_TYPE_MEMBUF_CHIP) { - FAPI_ERR("Error (0x%x) from fapiGetMvpdField", - static_cast<uint32_t> (l_rc)); - break; - } + // Determine the size of the eRepair data in the VPD + l_rc = fapiGetMBvpdField(fapi::MBVPD_RECORD_MER0, + fapi::MBVPD_KEYWORD_PDI, + i_tgtHandle, + NULL, + l_bufSize); + + if(l_rc) + { + FAPI_ERR("Error (0x%x) from fapiGetMBvpdField", + static_cast<uint32_t> (l_rc)); + break; + } + + if((l_bufSize == 0) || + (l_bufSize > EREPAIR::EREPAIR_MEM_MNFG_VPD_SIZE_PER_CENTAUR)) + { + FAPI_SET_HWP_ERROR(l_rc, RC_ACCESSOR_HWP_INVALID_MEM_VPD_SIZE); + break; + } - if(l_bufSize != 0) - { // Allocate memory for buffer l_retBuf = new uint8_t[l_bufSize]; if(l_retBuf == NULL) @@ -209,10 +191,35 @@ fapi::ReturnCode retrieveMnfgRepairData(const fapi::Target &i_tgtHandle, } // Retrieve the Field eRepair data from the PNOR - l_rc = fapiGetMvpdField(i_recordType, + l_rc = fapiGetMBvpdField(fapi::MBVPD_RECORD_MER0, + fapi::MBVPD_KEYWORD_PDI, + i_tgtHandle, + l_retBuf, + l_bufSize); + + if(l_rc) + { + FAPI_ERR("Error (0x%x) from fapiGetMBvpdField", + static_cast<uint32_t> (l_rc)); + break; + } + } + else + { + // Determine the Processor target + l_rc = fapiGetParentChip(i_tgtHandle, l_procTarget); + if(l_rc) + { + FAPI_ERR("Error (0x%x) from fapiGetParentChip", + static_cast<uint32_t>(l_rc)); + break; + } + + // Determine the size of the eRepair data in the VPD + l_rc = fapiGetMvpdField(fapi::MVPD_RECORD_MER0, fapi::MVPD_KEYWORD_PDI, - i_procTgt, - l_retBuf, + l_procTarget, + NULL, l_bufSize); if(l_rc) @@ -222,19 +229,50 @@ fapi::ReturnCode retrieveMnfgRepairData(const fapi::Target &i_tgtHandle, break; } - // Parse the buffer to determine eRepair lanes and copy the - // fail lane numbers to the return vector - l_rc = determineMnfgRepairLanes(i_tgtHandle, - l_retBuf, - l_bufSize, - o_txFailLanes, - o_rxFailLanes); + if((l_bufSize == 0) || + (l_bufSize > EREPAIR::EREPAIR_P8_MODULE_VPD_MNFG_SIZE)) + { + FAPI_SET_HWP_ERROR(l_rc, + RC_ACCESSOR_HWP_INVALID_FABRIC_VPD_SIZE); + break; + } + + // Allocate memory for buffer + l_retBuf = new uint8_t[l_bufSize]; + if(l_retBuf == NULL) + { + FAPI_ERR("Failed to allocate memory size of %d", l_bufSize); + FAPI_SET_HWP_ERROR(l_rc, RC_ACCESSOR_HWP_MEMORY_ALLOC_FAIL); + break; + } + + // Retrieve the Field eRepair data from the PNOR + l_rc = fapiGetMvpdField(fapi::MVPD_RECORD_MER0, + fapi::MVPD_KEYWORD_PDI, + l_procTarget, + l_retBuf, + l_bufSize); + if(l_rc) { - FAPI_ERR("determineRepairLanes failed"); + FAPI_ERR("Error (0x%x) from fapiGetMvpdField", + static_cast<uint32_t> (l_rc)); break; } } + + // Parse the buffer to determine eRepair lanes and copy the + // fail lane numbers to the return vector + l_rc = determineMnfgRepairLanes(i_tgtHandle, + l_retBuf, + l_bufSize, + o_txFailLanes, + o_rxFailLanes); + if(l_rc) + { + FAPI_ERR("determineRepairLanes failed"); + break; + } }while(0); // Delete the buffer which has Field eRepair data @@ -259,6 +297,8 @@ fapi::ReturnCode determineMnfgRepairLanes(const fapi::Target &i_tgtHandle, const uint32_t l_memRepairDataSz = sizeof(eRepairMemBus); const uint32_t l_fabricRepairDataSz = sizeof(eRepairPowerBus); fapi::TargetType l_tgtType = fapi::TARGET_TYPE_NONE; + fapi::Target l_mcsTarget; + fapi::Target l_tgtHandle; fapi::ReturnCode l_rc; fapi::ATTR_CHIP_UNIT_POS_Type l_busNum; @@ -296,6 +336,9 @@ fapi::ReturnCode determineMnfgRepairLanes(const fapi::Target &i_tgtHandle, break; } + // TODO: RTC task 71260 + // Investigate if there is an Endianess issue with + // the memcpy and fix it. memcpy(&l_fabricBus, l_vpdPtr, l_fabricRepairDataSz); // Check if we have the correct Processor ID @@ -341,10 +384,29 @@ fapi::ReturnCode determineMnfgRepairLanes(const fapi::Target &i_tgtHandle, } } // end of for loop } // end of if(l_tgtType is XBus or ABus) - else if(l_tgtType == fapi::TARGET_TYPE_MCS_CHIPLET) + else if((l_tgtType == fapi::TARGET_TYPE_MCS_CHIPLET) || + (l_tgtType == fapi::TARGET_TYPE_MEMBUF_CHIP)) { // Parse for Memory bus data eRepairMemBus l_memBus; + l_tgtHandle = i_tgtHandle; + + if(l_tgtType == fapi::TARGET_TYPE_MEMBUF_CHIP) + { + l_rc = fapiGetOtherSideOfMemChannel( + i_tgtHandle, + l_mcsTarget, + fapi::TARGET_STATE_FUNCTIONAL); + + if(l_rc) + { + FAPI_ERR("determineMnfgRepairLanes: Unable to get the" + " connected MCS target"); + break; + } + + l_tgtHandle = l_mcsTarget; + } // Read Power bus eRepair data and get the failed lane numbers for(l_loop = 0; @@ -358,6 +420,9 @@ fapi::ReturnCode determineMnfgRepairLanes(const fapi::Target &i_tgtHandle, break; } + // TODO: RTC task 71260 + // Investigate if there is an Endianess issue with + // the memcpy and fix it. memcpy(&l_memBus, l_vpdPtr, l_memRepairDataSz); // Check if we have the correct Processor ID @@ -372,7 +437,7 @@ fapi::ReturnCode determineMnfgRepairLanes(const fapi::Target &i_tgtHandle, } // Check if we have the matching memory bus interface - l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS,&i_tgtHandle,l_busNum); + l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS,&l_tgtHandle,l_busNum); if(l_rc) { FAPI_ERR("Error (0x%x), from ATTR_CHIP_UNIT_POS", @@ -392,13 +457,27 @@ fapi::ReturnCode determineMnfgRepairLanes(const fapi::Target &i_tgtHandle, } // Copy the fail lane numbers in the vectors - if(l_memBus.interface == EREPAIR::DMI_MCS_DRIVE) + if(l_tgtType == fapi::TARGET_TYPE_MCS_CHIPLET) { - o_txFailLanes.push_back(l_memBus.failBit); + if(l_memBus.interface == EREPAIR::DMI_MCS_DRIVE) + { + o_txFailLanes.push_back(l_memBus.failBit); + } + else if(l_memBus.interface == EREPAIR::DMI_MCS_RECEIVE) + { + o_rxFailLanes.push_back(l_memBus.failBit); + } } - else if(l_memBus.interface == EREPAIR::DMI_MCS_RECEIVE) + if(l_tgtType == fapi::TARGET_TYPE_MEMBUF_CHIP) { - o_rxFailLanes.push_back(l_memBus.failBit); + if(l_memBus.interface == EREPAIR::DMI_MEMBUF_DRIVE) + { + o_txFailLanes.push_back(l_memBus.failBit); + } + else if(l_memBus.interface == EREPAIR::DMI_MEMBUF_RECEIVE) + { + o_rxFailLanes.push_back(l_memBus.failBit); + } } } // end of for loop } // end of if(l_tgtType is MCS) diff --git a/src/usr/hwpf/hwp/bus_training/erepairSetFailedLanesHwp.C b/src/usr/hwpf/hwp/bus_training/erepairSetFailedLanesHwp.C new file mode 100755 index 000000000..dfc2b0a34 --- /dev/null +++ b/src/usr/hwpf/hwp/bus_training/erepairSetFailedLanesHwp.C @@ -0,0 +1,801 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/bus_training/erepairSetFailedLanesHwp.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file erepairSetFailedLanesHwp.C + * + * @brief FW Team HWP that accesses the fail lanes of Fabric and Memory buses. + */ + +/* + * Change Log ****************************************************************** + * Flag Defect/Feature User Date Description + * ------ -------------- ---------- ----------- ---------------------------- + * bilicon 13-JAN-2013 Created. + */ + +#include <erepairSetFailedLanesHwp.H> + +using namespace EREPAIR; +using namespace fapi; + +extern "C" +{ + +/****************************************************************************** + * 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_tgtHandle Reference to X-Bus or A-Bus or MCS target + * @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 + */ +ReturnCode writeRepairDataToVPD(const Target &i_tgtHandle, + 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_tgtHandle Reference to X-Bus or A-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[o] o_buf This is the buffer that has the eRepair records + * that needs to be written to the VPD + * + * @return ReturnCode + */ +ReturnCode writeRepairLanesToBuf(const Target &i_tgtHandle, + const std::vector<uint8_t> &i_txFailLanes, + const std::vector<uint8_t> &i_rxFailLanes, + const uint32_t i_bufSz, + 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_tgtHandle Reference to X-Bus or A-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_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 + */ +ReturnCode updateRepairLanesToBuf(const Target &i_tgtHandle, + const interfaceType i_interface, + const uint32_t i_bufSz, + const std::vector<uint8_t> &i_failLanes, + uint8_t *o_buf); + +/****************************************************************************** + * Accessor HWP + *****************************************************************************/ + +ReturnCode erepairSetFailedLanesHwp(const Target &i_tgtHandle, + const std::vector<uint8_t> &i_txFailLanes, + const std::vector<uint8_t> &i_rxFailLanes) +{ + ReturnCode l_rc; + Target l_mcsTgt; + TargetType l_tgtType = TARGET_TYPE_NONE; + + FAPI_INF(">> erepairSetFailedLanesHwp: i_tgtHandle: %s", + i_tgtHandle.toEcmdString()); + + do + { + if((i_txFailLanes.size() == 0) && (i_rxFailLanes.size() == 0)) + { + FAPI_INF("erepairSetFailedLanesHwp: No fail lanes were provided"); + break; + } + + // Determine the type of target + l_tgtType = i_tgtHandle.getType(); + + // Verify if the correct target type is passed + if((l_tgtType != TARGET_TYPE_MCS_CHIPLET) && + (l_tgtType != TARGET_TYPE_MEMBUF_CHIP) && + (l_tgtType != TARGET_TYPE_XBUS_ENDPOINT) && + (l_tgtType != TARGET_TYPE_ABUS_ENDPOINT)) + { + FAPI_ERR("erepairSetFailedLanesHwp: Invalid Target type %d", + l_tgtType); + FAPI_SET_HWP_ERROR(l_rc, RC_ACCESSOR_HWP_INVALID_TARGET_TYPE); + break; + } + + l_rc = writeRepairDataToVPD(i_tgtHandle, + i_txFailLanes, + i_rxFailLanes); + + if(l_rc) + { + FAPI_ERR("Error (0x%x) during write of Field records", + static_cast<uint32_t>(l_rc)); + break; + } + }while(0); + + FAPI_INF("<< erepairSetFailedLanesHwp"); + + return l_rc; +} + + +ReturnCode writeRepairDataToVPD(const Target &i_tgtHandle, + const std::vector<uint8_t> &i_txFailLanes, + const std::vector<uint8_t> &i_rxFailLanes) +{ + ReturnCode l_rc; + uint8_t *l_retBuf = NULL; + uint32_t l_bufSize = 0; + Target l_procTarget; + + FAPI_INF(">> writeRepairDataToVPD"); + + do + { + if(i_tgtHandle.getType() == TARGET_TYPE_MEMBUF_CHIP) + { + /*** Read the data from the FRU VPD ***/ + + // Determine the size of the eRepair data in the Centaur VPD + l_rc = fapiGetMBvpdField(MBVPD_RECORD_VEIR, + MBVPD_KEYWORD_PDI, + i_tgtHandle, + NULL, + l_bufSize); + if(l_rc) + { + FAPI_ERR("Error (0x%x) from fapiGetMBvpdField", + static_cast<uint32_t> (l_rc)); + break; + } + + if((l_bufSize == 0) || + (l_bufSize > EREPAIR_MEM_FIELD_VPD_SIZE_PER_CENTAUR)) + { + FAPI_SET_HWP_ERROR(l_rc, RC_ACCESSOR_HWP_INVALID_MEM_VPD_SIZE); + break; + } + + // Allocate memory for buffer + l_retBuf = new uint8_t[l_bufSize]; + if(l_retBuf == NULL) + { + FAPI_ERR("Failed to allocate memory size of %d", l_bufSize); + FAPI_SET_HWP_ERROR(l_rc, RC_ACCESSOR_HWP_MEMORY_ALLOC_FAIL); + break; + } + + // Retrieve the Field eRepair data from the Centaur FRU VPD + l_rc = fapiGetMBvpdField(MBVPD_RECORD_VEIR, + MBVPD_KEYWORD_PDI, + i_tgtHandle, + l_retBuf, + l_bufSize); + + if(l_rc) + { + FAPI_ERR("Error (0x%x) from fapiGetMBvpdField", + static_cast<uint32_t> (l_rc)); + break; + } + + /*** Update the new eRepair data to the buffer ***/ + l_rc = writeRepairLanesToBuf(i_tgtHandle, + i_txFailLanes, + i_rxFailLanes, + l_bufSize, + l_retBuf); + + if(l_rc) + { + FAPI_ERR("Error (0x%x) from writeRepairLanesToBuf", + static_cast<uint32_t> (l_rc)); + break; + } + + /*** Write the updated eRepair buffer back to Centaru FRU VPD ***/ + l_rc = fapiSetMBvpdField(MBVPD_RECORD_VEIR, + MBVPD_KEYWORD_PDI, + i_tgtHandle, + l_retBuf, + l_bufSize); + if(l_rc) + { + FAPI_ERR("Error (0x%x) from fapiSetMBvpdField", + static_cast<uint32_t> (l_rc)); + break; + } + } // end of(targetType == MEMBUF) + else + { + // Determine the Processor target + l_rc = fapiGetParentChip(i_tgtHandle, l_procTarget); + if(l_rc) + { + FAPI_ERR("Error (0x%x) from fapiGetParentChip", + static_cast<uint32_t>(l_rc)); + break; + } + + /*** Read the data from the Module VPD ***/ + + // Determine the size of the eRepair data in the VPD + l_rc = fapiGetMvpdField(MVPD_RECORD_VWML, + MVPD_KEYWORD_PDI, + l_procTarget, + NULL, + l_bufSize); + if(l_rc) + { + FAPI_ERR("Error (0x%x) from fapiGetMvpdField", + static_cast<uint32_t> (l_rc)); + break; + } + + if((l_bufSize == 0) || + (l_bufSize > EREPAIR_P8_MODULE_VPD_FIELD_SIZE)) + { + FAPI_SET_HWP_ERROR(l_rc, + RC_ACCESSOR_HWP_INVALID_FABRIC_VPD_SIZE); + break; + } + + // Allocate memory for buffer + l_retBuf = new uint8_t[l_bufSize]; + if(l_retBuf == NULL) + { + FAPI_ERR("Failed to allocate memory size of %d", l_bufSize); + FAPI_SET_HWP_ERROR(l_rc, RC_ACCESSOR_HWP_MEMORY_ALLOC_FAIL); + break; + } + + // Retrieve the Field eRepair data from the MVPD + l_rc = fapiGetMvpdField(MVPD_RECORD_VWML, + MVPD_KEYWORD_PDI, + l_procTarget, + l_retBuf, + l_bufSize); + + if(l_rc) + { + FAPI_ERR("Error (0x%x) from fapiGetMvpdField", + static_cast<uint32_t> (l_rc)); + break; + } + + /*** Update the new eRepair data to the buffer ***/ + l_rc = writeRepairLanesToBuf(i_tgtHandle, + i_txFailLanes, + i_rxFailLanes, + l_bufSize, + l_retBuf); + + if(l_rc) + { + FAPI_ERR("Error (0x%x) from writeRepairLanesToBuf", + static_cast<uint32_t> (l_rc)); + break; + } + + /*** Write the updated eRepair buffer back to MVPD ***/ + l_rc = fapiSetMvpdField(MVPD_RECORD_VWML, + MVPD_KEYWORD_PDI, + l_procTarget, + l_retBuf, + l_bufSize); + if(l_rc) + { + FAPI_ERR("Error (0x%x) from fapiSetMvpdField", + static_cast<uint32_t> (l_rc)); + break; + } + } + }while(0); + + // Delete the buffer which has Field eRepair data + delete[] l_retBuf; + + FAPI_INF("<< writeRepairDataToVPD"); + + return (l_rc); +} + +ReturnCode writeRepairLanesToBuf(const Target &i_tgtHandle, + const std::vector<uint8_t> &i_txFailLanes, + const std::vector<uint8_t> &i_rxFailLanes, + const uint32_t i_bufSz, + uint8_t *o_buf) +{ + ReturnCode l_rc; + + FAPI_INF(">> writeRepairLanesToBuf"); + + do + { + if(i_txFailLanes.size()) + { + /*** Lets update the tx side fail lane vector to the VPD ***/ + l_rc = updateRepairLanesToBuf(i_tgtHandle, + DRIVE, + i_bufSz, + i_txFailLanes, + o_buf); + + if(l_rc) + { + FAPI_ERR("Error (0x%x), from updateRepairLanesToBuf(DRIVE)"); + break; + } + } + + if(i_rxFailLanes.size()) + { + /*** Lets update the rx side fail lane vector to the VPD ***/ + l_rc = updateRepairLanesToBuf(i_tgtHandle, + RECEIVE, + i_bufSz, + i_rxFailLanes, + o_buf); + + if(l_rc) + { + FAPI_ERR("Error (0x%x), from updateRepairLanesToBuf(RECEIVE)"); + break; + } + } + }while(0); + + FAPI_INF("<< writeRepairLanesToBuf"); + return (l_rc); +} + +ReturnCode updateRepairLanesToBuf(const Target &i_tgtHandle, + const interfaceType i_interface, + const uint32_t i_bufSz, + const std::vector<uint8_t> &i_failLanes, + uint8_t *o_buf) +{ + ReturnCode l_rc; + 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; + eRepairHeader *l_vpdHeadPtr = NULL; + eRepairPowerBus *l_overWritePtr = NULL; + bool l_overWrite = false; + TargetType l_tgtType = TARGET_TYPE_NONE; + Target l_mcsTarget; + Target l_tgtHandle; + std::vector<const uint8_t>::iterator l_it; + ATTR_CHIP_UNIT_POS_Type l_busNum; + + FAPI_INF(">> updateRepairLanesToBuf, interface: %d", i_interface); + + do + { + 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->numRecords; + + // 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_tgtType = i_tgtHandle.getType(); + + l_tgtHandle = i_tgtHandle; + if(l_tgtType == TARGET_TYPE_MEMBUF_CHIP) + { + l_rc = fapiGetOtherSideOfMemChannel(i_tgtHandle, + l_mcsTarget, + TARGET_STATE_FUNCTIONAL); + + if(l_rc) + { + FAPI_ERR("updateRepairLanesToBuf: unable to get the connected" + " MCS target"); + break; + } + + l_tgtHandle = l_mcsTarget; + } + + // Get the bus number + l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &l_tgtHandle, l_busNum); + if(l_rc) + { + FAPI_ERR("Error (0x%x), from FAPI_ATTR_GET", + static_cast<uint32_t>(l_rc)); + break; + } + + /*** 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; + 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[8] = + { + { // index 0 + DRIVE, + TARGET_TYPE_XBUS_ENDPOINT, + { // repairData + { // fabBus + { // device + 0, // processor_id + l_busNum, // fabricBus + }, + PROCESSOR_EI4, // type + PBUS_DRIVER, // interface + }, + }, + }, + { // index 1 + DRIVE, + TARGET_TYPE_ABUS_ENDPOINT, + { // repairData + { // fabBus + { // device + 0, // processor_id + l_busNum, // fabricBus + }, + PROCESSOR_EDI, // type + PBUS_DRIVER, // interface + }, + }, + }, + { // index 2 + RECEIVE, + TARGET_TYPE_XBUS_ENDPOINT, + { // repairData + { // fabBus + { // device + 0, // processor_id + l_busNum, // fabricBus + }, + PROCESSOR_EI4, // type + PBUS_RECEIVER, // interface + }, + }, + }, + { // index 3 + RECEIVE, + TARGET_TYPE_ABUS_ENDPOINT, + { // repairData + { // fabBus + { // device + 0, // processor_id + l_busNum, // fabricBus + }, + PROCESSOR_EDI, // type + PBUS_RECEIVER, // interface + }, + }, + }, + { // index 4 + DRIVE, + TARGET_TYPE_MCS_CHIPLET, + { // repairData + { // fabBus + { // device + 0, // proc_centaur_id + l_busNum, // memChannel + }, + MEMORY_EDI, // type + DMI_MCS_DRIVE,// interface + }, + }, + }, + { // index 5 + DRIVE, + TARGET_TYPE_MEMBUF_CHIP, + { // repairData + { // memBus + { // device + 0, // proc_centaur_id + l_busNum, // memChannel + }, + MEMORY_EDI, // type + DMI_MEMBUF_DRIVE,// interface + }, + }, + }, + { // index 6 + RECEIVE, + TARGET_TYPE_MCS_CHIPLET, + { // repairData + { // memBus + { // device + 0, // proc_centaur_id + l_busNum, // memChannel + }, + MEMORY_EDI, // type + DMI_MCS_RECEIVE, // interface + }, + }, + }, + { // index 7 + RECEIVE, + TARGET_TYPE_MEMBUF_CHIP, + { // repairData + { // memBus + { // device + 0, // proc_centaur_id + l_busNum, // memChannel + }, + MEMORY_EDI, // 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; + + // 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 < 8; l_loop++) + { + if((l_tgtType == TARGET_TYPE_XBUS_ENDPOINT) || + (l_tgtType == TARGET_TYPE_ABUS_ENDPOINT)) + { + if((i_interface == l_repairMatch[l_loop].intType) && + (l_tgtType == l_repairMatch[l_loop].tgtType) && + (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)) + { + // update the failBit number + l_overWritePtr->failBit = l_repairLane; + + // Increment the count of parsed bytes + l_bytesParsed += l_repairDataSz; + + l_repairCnt++; + l_overWrite = true; + + break; + } + } + else if((l_tgtType == TARGET_TYPE_MCS_CHIPLET) || + (l_tgtType == TARGET_TYPE_MEMBUF_CHIP) ) + { + if((i_interface == l_repairMatch[l_loop].intType) && + (l_tgtType == l_repairMatch[l_loop].tgtType) && + (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 + l_overWritePtr->failBit = l_repairLane; + + // Increment the count of parsed bytes + l_bytesParsed += l_repairDataSz; + + l_repairCnt++; + l_overWrite = true; + + break; + } + } + } + + 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_bytesParsed > i_bufSz) && (l_repairCnt < l_numRepairs)) + { + if((l_tgtType == TARGET_TYPE_XBUS_ENDPOINT) || + (l_tgtType == TARGET_TYPE_ABUS_ENDPOINT)) + { + FAPI_SET_HWP_ERROR(l_rc, RC_EREPAIR_MVPD_FULL); + } + else if((l_tgtType == TARGET_TYPE_MCS_CHIPLET) || + (l_tgtType == TARGET_TYPE_MEMBUF_CHIP) ) + { + FAPI_SET_HWP_ERROR(l_rc, RC_EREPAIR_MBVPD_FULL); + } + break; + } + + // Add at the end + if(l_overWrite == false) + { + if((l_tgtType == TARGET_TYPE_XBUS_ENDPOINT) || + (l_tgtType == TARGET_TYPE_ABUS_ENDPOINT)) + { + // Make sure we are not writing more records than the size + // allocated in the VPD + if(l_bytesParsed == i_bufSz) + { + FAPI_SET_HWP_ERROR(l_rc, RC_EREPAIR_MVPD_FULL); + break; + } + + eRepairPowerBus l_fabricBus; + + l_fabricBus.device.processor_id = 0; + l_fabricBus.device.fabricBus = l_busNum; + l_fabricBus.failBit = l_repairLane; + + if(i_interface == DRIVE) + { + l_fabricBus.interface = PBUS_DRIVER; + } + else if(i_interface == RECEIVE) + { + l_fabricBus.interface = PBUS_RECEIVER; + } + + if(l_tgtType == TARGET_TYPE_XBUS_ENDPOINT) + { + l_fabricBus.type = PROCESSOR_EI4; + } + else if(l_tgtType == TARGET_TYPE_ABUS_ENDPOINT) + { + l_fabricBus.type = PROCESSOR_EDI; + } + + // TODO: RTC task 71260 + // Investigate if there is an Endianess issue with + // the memcpy and fix it. + memcpy(l_vpdDataPtr, &l_fabricBus, l_repairDataSz); + l_newNumRepairs++; + + // Increment the count of parsed bytes + l_bytesParsed += l_repairDataSz; + } + else if((l_tgtType == TARGET_TYPE_MCS_CHIPLET) || + (l_tgtType == TARGET_TYPE_MEMBUF_CHIP) ) + { + // Make sure we are not writing more records than the size + // allocated in the VPD + if(l_bytesParsed == i_bufSz) + { + FAPI_SET_HWP_ERROR(l_rc, RC_EREPAIR_MBVPD_FULL); + break; + } + + eRepairMemBus l_memBus; + + l_memBus.device.proc_centaur_id = 0; + l_memBus.device.memChannel = l_busNum; + l_memBus.type = MEMORY_EDI; + l_memBus.failBit = l_repairLane; + + if(i_interface == DRIVE) + { + if(l_tgtType == TARGET_TYPE_MCS_CHIPLET) + { + l_memBus.interface = DMI_MCS_DRIVE; + } + else if(l_tgtType == TARGET_TYPE_MEMBUF_CHIP) + { + l_memBus.interface = DMI_MEMBUF_DRIVE; + } + } + else if(i_interface == RECEIVE) + { + if(l_tgtType == TARGET_TYPE_MCS_CHIPLET) + { + l_memBus.interface = DMI_MCS_RECEIVE; + } + else if(l_tgtType == TARGET_TYPE_MEMBUF_CHIP) + { + l_memBus.interface = DMI_MEMBUF_RECEIVE; + } + } + + // TODO: RTC task 71260 + // Investigate if there is an Endianess issue with + // the memcpy and fix it. + memcpy(l_vpdDataPtr, &l_memBus, l_repairDataSz); + l_newNumRepairs++; + + // Increment the count of parsed bytes + l_bytesParsed += l_repairDataSz; + } + } // end of if(l_overWrite == false) + } // end of for(failLanes) + + // Update the eRepair count + l_vpdHeadPtr->numRecords = l_newNumRepairs; + + }while(0); + + FAPI_INF("<< updateRepairLanesToBuf"); + + return(l_rc); +} + +}// endof extern "C" diff --git a/src/usr/hwpf/hwp/bus_training/erepairSetMnfgFailedLanesHwp.C b/src/usr/hwpf/hwp/bus_training/erepairSetMnfgFailedLanesHwp.C new file mode 100755 index 000000000..6cb77a9f3 --- /dev/null +++ b/src/usr/hwpf/hwp/bus_training/erepairSetMnfgFailedLanesHwp.C @@ -0,0 +1,808 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/bus_training/erepairSetMnfgFailedLanesHwp.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file erepairSetMnfgFailedLanesHwp.C + * + * @brief FW Team HWP that accesses the fail lanes of Fabric and Memory buses. + */ + +/* + * Change Log ****************************************************************** + * Flag Defect/Feature User Date Description + * ------ -------------- ---------- ----------- ---------------------------- + * bilicon 13-JAN-2013 Created. + */ + +#include <erepairSetMnfgFailedLanesHwp.H> + +using namespace EREPAIR; +using namespace fapi; + +extern "C" +{ + +// TODO: RTC Task: 69592. Refactor eRepair code to remove this file and change +// the erepairSetFailedLanesHwp.C file to write Manufacturing VPD + +/****************************************************************************** + * Forward Declarations + *****************************************************************************/ + +/** + * @brief Function called by the FW Team HWP that writes the data to Mnfg VPD. + * This function calls fapiSetMvpdField to write the VPD. + * + * @param[in] i_tgtHandle Reference to X-Bus or A-Bus or MCS target + * @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 + */ +ReturnCode writeMnfgRepairDataToVPD(const Target &i_tgtHandle, + 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_tgtHandle Reference to X-Bus or A-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[o] o_buf This is the buffer that has the eRepair records + * that needs to be written to the VPD + * + * @return ReturnCode + */ +ReturnCode writeMnfgRepairLanesToBuf(const Target &i_tgtHandle, + const std::vector<uint8_t> &i_txFailLanes, + const std::vector<uint8_t> &i_rxFailLanes, + const uint32_t i_bufSz, + 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_tgtHandle Reference to X-Bus or A-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_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 + */ +ReturnCode updateMnfgRepairLanesToBuf(const Target &i_tgtHandle, + const interfaceType i_interface, + const uint32_t i_bufSz, + const std::vector<uint8_t> &i_failLanes, + uint8_t *o_buf); + +/****************************************************************************** + * Accessor HWP + *****************************************************************************/ + +ReturnCode erepairSetMnfgFailedLanesHwp( + const Target &i_tgtHandle, + const std::vector<uint8_t> &i_txFailLanes, + const std::vector<uint8_t> &i_rxFailLanes) +{ + ReturnCode l_rc; + TargetType l_tgtType = TARGET_TYPE_NONE; + + FAPI_INF(">> erepairSetMnfgFailedLanesHwp: i_tgtHandle: %s", + i_tgtHandle.toEcmdString()); + + do + { + if((i_txFailLanes.size() == 0) && (i_rxFailLanes.size() == 0)) + { + FAPI_INF("erepairSetMnfgFailedLanesHwp: No fail lanes were provided."); + break; + } + + // Determine the type of target + l_tgtType = i_tgtHandle.getType(); + + // Verify if the correct target type is passed + if((l_tgtType != TARGET_TYPE_MCS_CHIPLET) && + (l_tgtType != TARGET_TYPE_MEMBUF_CHIP) && + (l_tgtType != TARGET_TYPE_XBUS_ENDPOINT) && + (l_tgtType != TARGET_TYPE_ABUS_ENDPOINT)) + { + FAPI_ERR("erepairSetMnfgFailedLanesHwp: Invalid Target type %d", + l_tgtType); + FAPI_SET_HWP_ERROR(l_rc, RC_ACCESSOR_HWP_INVALID_TARGET_TYPE); + break; + } + + l_rc = writeMnfgRepairDataToVPD(i_tgtHandle, + i_txFailLanes, + i_rxFailLanes); + + if(l_rc) + { + FAPI_ERR("Error (0x%x) during write of Field records", + static_cast<uint32_t>(l_rc)); + break; + } + }while(0); + + FAPI_INF("<< erepairSetMnfgFailedLanesHwp"); + + return l_rc; +} + + +ReturnCode writeMnfgRepairDataToVPD(const Target &i_tgtHandle, + const std::vector<uint8_t> &i_txFailLanes, + const std::vector<uint8_t> &i_rxFailLanes) +{ + ReturnCode l_rc; + uint8_t *l_retBuf = NULL; + uint32_t l_bufSize = 0; + Target l_procTarget; + + FAPI_INF(">> writeMnfgRepairDataToVPD"); + + do + { + if(i_tgtHandle.getType() == TARGET_TYPE_MEMBUF_CHIP) + { + /*** Read the data from the FRU VPD ***/ + + // Determine the size of the eRepair data in the Centaur VPD + l_rc = fapiGetMBvpdField(MBVPD_RECORD_MER0, + MBVPD_KEYWORD_PDI, + i_tgtHandle, + NULL, + l_bufSize); + if(l_rc) + { + FAPI_ERR("Error (0x%x) from fapiGetMBvpdField", + static_cast<uint32_t> (l_rc)); + break; + } + + if((l_bufSize == 0) || + (l_bufSize > EREPAIR_MEM_MNFG_VPD_SIZE_PER_CENTAUR)) + { + FAPI_SET_HWP_ERROR(l_rc, RC_ACCESSOR_HWP_INVALID_MEM_VPD_SIZE); + break; + } + + // Allocate memory for buffer + l_retBuf = new uint8_t[l_bufSize]; + if(l_retBuf == NULL) + { + FAPI_ERR("Failed to allocate memory size of %d", l_bufSize); + FAPI_SET_HWP_ERROR(l_rc, RC_ACCESSOR_HWP_MEMORY_ALLOC_FAIL); + break; + } + + // Retrieve the Field eRepair data from the Centaur FRU VPD + l_rc = fapiGetMBvpdField(MBVPD_RECORD_MER0, + MBVPD_KEYWORD_PDI, + i_tgtHandle, + l_retBuf, + l_bufSize); + + if(l_rc) + { + FAPI_ERR("Error (0x%x) from fapiGetMBvpdField", + static_cast<uint32_t> (l_rc)); + break; + } + + /*** Update the new eRepair data to the buffer ***/ + l_rc = writeMnfgRepairLanesToBuf(i_tgtHandle, + i_txFailLanes, + i_rxFailLanes, + l_bufSize, + l_retBuf); + + if(l_rc) + { + FAPI_ERR("Error (0x%x) from writeMnfgRepairLanesToBuf", + static_cast<uint32_t> (l_rc)); + break; + } + + /*** Write the updated eRepair buffer back to MVPD ***/ + l_rc = fapiSetMBvpdField(MBVPD_RECORD_MER0, + MBVPD_KEYWORD_PDI, + i_tgtHandle, + l_retBuf, + l_bufSize); + if(l_rc) + { + FAPI_ERR("Error (0x%x) from fapiSetMBvpdField", + static_cast<uint32_t> (l_rc)); + break; + } + } // end of(targetType == MEMBUF) + else + { + // Determine the Processor target + l_rc = fapiGetParentChip(i_tgtHandle, l_procTarget); + if(l_rc) + { + FAPI_ERR("Error (0x%x) from fapiGetParentChip", + static_cast<uint32_t>(l_rc)); + break; + } + + /*** Read the data from the Module VPD ***/ + + // Determine the size of the eRepair data in the VPD + l_rc = fapiGetMvpdField(MVPD_RECORD_MER0, + MVPD_KEYWORD_PDI, + l_procTarget, + NULL, + l_bufSize); + if(l_rc) + { + FAPI_ERR("Error (0x%x) from fapiGetMvpdField", + static_cast<uint32_t> (l_rc)); + break; + } + + if((l_bufSize == 0) || + (l_bufSize > EREPAIR_P8_MODULE_VPD_MNFG_SIZE)) + { + FAPI_SET_HWP_ERROR(l_rc, + RC_ACCESSOR_HWP_INVALID_FABRIC_VPD_SIZE); + break; + } + + // Allocate memory for buffer + l_retBuf = new uint8_t[l_bufSize]; + if(l_retBuf == NULL) + { + FAPI_ERR("Failed to allocate memory size of %d", l_bufSize); + FAPI_SET_HWP_ERROR(l_rc, RC_ACCESSOR_HWP_MEMORY_ALLOC_FAIL); + break; + } + + // Retrieve the Field eRepair data from the MVPD + l_rc = fapiGetMvpdField(MVPD_RECORD_MER0, + MVPD_KEYWORD_PDI, + l_procTarget, + l_retBuf, + l_bufSize); + + if(l_rc) + { + FAPI_ERR("Error (0x%x) from fapiGetMvpdField", + static_cast<uint32_t> (l_rc)); + break; + } + + /*** Update the new eRepair data to the buffer ***/ + l_rc = writeMnfgRepairLanesToBuf(i_tgtHandle, + i_txFailLanes, + i_rxFailLanes, + l_bufSize, + l_retBuf); + + if(l_rc) + { + FAPI_ERR("Error (0x%x) from writeMnfgRepairLanesToBuf", + static_cast<uint32_t> (l_rc)); + break; + } + + /*** Write the updated eRepair buffer back to MVPD ***/ + l_rc = fapiSetMvpdField(MVPD_RECORD_MER0, + MVPD_KEYWORD_PDI, + l_procTarget, + l_retBuf, + l_bufSize); + if(l_rc) + { + FAPI_ERR("Error (0x%x) from fapiSetMvpdField", + static_cast<uint32_t> (l_rc)); + break; + } + } + }while(0); + + // Delete the buffer which has Field eRepair data + delete[] l_retBuf; + + FAPI_INF("<< writeMnfgRepairDataToVPD"); + + return (l_rc); +} + +ReturnCode writeMnfgRepairLanesToBuf(const Target &i_tgtHandle, + const std::vector<uint8_t> &i_txFailLanes, + const std::vector<uint8_t> &i_rxFailLanes, + const uint32_t i_bufSz, + uint8_t *o_buf) +{ + ReturnCode l_rc; + + FAPI_INF(">> writeMnfgRepairLanesToBuf"); + + do + { + if(i_txFailLanes.size()) + { + /*** Lets update the tx side fail lane vector to the VPD ***/ + l_rc = updateMnfgRepairLanesToBuf(i_tgtHandle, + DRIVE, + i_bufSz, + i_txFailLanes, + o_buf); + + if(l_rc) + { + FAPI_ERR("Error (0x%x), from" + " updateMnfgRepairLanesToBuf(DRIVE)"); + break; + } + } + + if(i_rxFailLanes.size()) + { + /*** Lets update the rx side fail lane vector to the VPD ***/ + l_rc = updateMnfgRepairLanesToBuf(i_tgtHandle, + RECEIVE, + i_bufSz, + i_rxFailLanes, + o_buf); + + if(l_rc) + { + FAPI_ERR("Error (0x%x), from" + " updateMnfgRepairLanesToBuf(RECEIVE)"); + break; + } + } + + }while(0); + + FAPI_INF("<< writeMnfgRepairLanesToBuf"); + return (l_rc); +} + +ReturnCode updateMnfgRepairLanesToBuf(const Target &i_tgtHandle, + const interfaceType i_interface, + const uint32_t i_bufSz, + const std::vector<uint8_t> &i_failLanes, + uint8_t *o_buf) +{ + ReturnCode l_rc; + 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; + eRepairHeader *l_vpdHeadPtr = NULL; + eRepairPowerBus *l_overWritePtr = NULL; + bool l_overWrite = false; + TargetType l_tgtType = TARGET_TYPE_NONE; + Target l_mcsTarget; + Target l_tgtHandle; + std::vector<const uint8_t>::iterator l_it; + ATTR_CHIP_UNIT_POS_Type l_busNum; + + FAPI_INF(">> updateMnfgRepairLanesToBuf, interface: %d", i_interface); + + do + { + 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->numRecords; + + // 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_tgtType = i_tgtHandle.getType(); + + l_tgtHandle = i_tgtHandle; + if(l_tgtType == TARGET_TYPE_MEMBUF_CHIP) + { + l_rc = fapiGetOtherSideOfMemChannel(i_tgtHandle, + l_mcsTarget, + TARGET_STATE_FUNCTIONAL); + + if(l_rc) + { + FAPI_ERR("updateMnfgRepairLanesToBuf: unable to get the" + " connected MCS target"); + break; + } + + l_tgtHandle = l_mcsTarget; + } + + // Get the bus number + l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &l_tgtHandle, l_busNum); + if(l_rc) + { + FAPI_ERR("Error (0x%x), from FAPI_ATTR_GET", + static_cast<uint32_t>(l_rc)); + break; + } + + /*** 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; + 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[8] = + { + { // index 0 + DRIVE, + TARGET_TYPE_XBUS_ENDPOINT, + { // repairData + { // fabBus + { // device + 0, // processor_id + l_busNum, // fabricBus + }, + PROCESSOR_EI4, // type + PBUS_DRIVER, // interface + }, + }, + }, + { // index 1 + DRIVE, + TARGET_TYPE_ABUS_ENDPOINT, + { // repairData + { // fabBus + { // device + 0, // processor_id + l_busNum, // fabricBus + }, + PROCESSOR_EDI, // type + PBUS_DRIVER, // interface + }, + }, + }, + { // index 2 + RECEIVE, + TARGET_TYPE_XBUS_ENDPOINT, + { // repairData + { // fabBus + { // device + 0, // processor_id + l_busNum, // fabricBus + }, + PROCESSOR_EI4, // type + PBUS_RECEIVER, // interface + }, + }, + }, + { // index 3 + RECEIVE, + TARGET_TYPE_ABUS_ENDPOINT, + { // repairData + { // fabBus + { // device + 0, // processor_id + l_busNum, // fabricBus + }, + PROCESSOR_EDI, // type + PBUS_RECEIVER, // interface + }, + }, + }, + { // index 4 + DRIVE, + TARGET_TYPE_MCS_CHIPLET, + { // repairData + { // fabBus + { // device + 0, // proc_centaur_id + l_busNum, // memChannel + }, + MEMORY_EDI, // type + DMI_MCS_DRIVE,// interface + }, + }, + }, + { // index 5 + DRIVE, + TARGET_TYPE_MEMBUF_CHIP, + { // repairData + { // memBus + { // device + 0, // proc_centaur_id + l_busNum, // memChannel + }, + MEMORY_EDI, // type + DMI_MEMBUF_DRIVE,// interface + }, + }, + }, + { // index 6 + RECEIVE, + TARGET_TYPE_MCS_CHIPLET, + { // repairData + { // memBus + { // device + 0, // proc_centaur_id + l_busNum, // memChannel + }, + MEMORY_EDI, // type + DMI_MCS_RECEIVE, // interface + }, + }, + }, + { // index 7 + RECEIVE, + TARGET_TYPE_MEMBUF_CHIP, + { // repairData + { // memBus + { // device + 0, // proc_centaur_id + l_busNum, // memChannel + }, + MEMORY_EDI, // 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; + + // 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 < 8; l_loop++) + { + if((l_tgtType == TARGET_TYPE_XBUS_ENDPOINT) || + (l_tgtType == TARGET_TYPE_ABUS_ENDPOINT)) + { + if((i_interface == l_repairMatch[l_loop].intType) && + (l_tgtType == l_repairMatch[l_loop].tgtType) && + (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)) + { + // update the failBit number + l_overWritePtr->failBit = l_repairLane; + + // Increment the count of parsed bytes + l_bytesParsed += l_repairDataSz; + + l_repairCnt++; + l_overWrite = true; + + break; + } + } + else if((l_tgtType == TARGET_TYPE_MCS_CHIPLET) || + (l_tgtType == TARGET_TYPE_MEMBUF_CHIP) ) + { + if((i_interface == l_repairMatch[l_loop].intType) && + (l_tgtType == l_repairMatch[l_loop].tgtType) && + (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 + l_overWritePtr->failBit = l_repairLane; + + // Increment the count of parsed bytes + l_bytesParsed += l_repairDataSz; + + l_repairCnt++; + l_overWrite = true; + + break; + } + } + } + + 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_bytesParsed > i_bufSz) && (l_repairCnt < l_numRepairs)) + { + if((l_tgtType == TARGET_TYPE_XBUS_ENDPOINT) || + (l_tgtType == TARGET_TYPE_ABUS_ENDPOINT)) + { + FAPI_SET_HWP_ERROR(l_rc, RC_EREPAIR_MVPD_FULL); + } + else if((l_tgtType == TARGET_TYPE_MCS_CHIPLET) || + (l_tgtType == TARGET_TYPE_MEMBUF_CHIP) ) + { + FAPI_SET_HWP_ERROR(l_rc, RC_EREPAIR_MBVPD_FULL); + } + break; + } + + // Add at the end + if(l_overWrite == false) + { + if((l_tgtType == TARGET_TYPE_XBUS_ENDPOINT) || + (l_tgtType == TARGET_TYPE_ABUS_ENDPOINT)) + { + // Make sure we are not writing more records than the size + // allocated in the VPD + if(l_bytesParsed == i_bufSz) + { + FAPI_SET_HWP_ERROR(l_rc, RC_EREPAIR_MVPD_FULL); + break; + } + + eRepairPowerBus l_fabricBus; + + l_fabricBus.device.processor_id = 0; + l_fabricBus.device.fabricBus = l_busNum; + l_fabricBus.failBit = l_repairLane; + + if(i_interface == DRIVE) + { + l_fabricBus.interface = PBUS_DRIVER; + } + else if(i_interface == RECEIVE) + { + l_fabricBus.interface = PBUS_RECEIVER; + } + + if(l_tgtType == TARGET_TYPE_XBUS_ENDPOINT) + { + l_fabricBus.type = PROCESSOR_EI4; + } + else if(l_tgtType == TARGET_TYPE_ABUS_ENDPOINT) + { + l_fabricBus.type = PROCESSOR_EDI; + } + + // TODO: RTC task 71260 + // Investigate if there is an Endianess issue with + // the memcpy and fix it. + memcpy(l_vpdDataPtr, &l_fabricBus, l_repairDataSz); + l_newNumRepairs++; + + // Increment the count of parsed bytes + l_bytesParsed += l_repairDataSz; + } + else if((l_tgtType == TARGET_TYPE_MCS_CHIPLET) || + (l_tgtType == TARGET_TYPE_MEMBUF_CHIP) ) + { + // Make sure we are not writing more records than the size + // allocated in the VPD + if(l_bytesParsed == i_bufSz) + { + FAPI_SET_HWP_ERROR(l_rc, RC_EREPAIR_MBVPD_FULL); + break; + } + + eRepairMemBus l_memBus; + + l_memBus.device.proc_centaur_id = 0; + l_memBus.device.memChannel = l_busNum; + l_memBus.type = MEMORY_EDI; + l_memBus.failBit = l_repairLane; + + if(i_interface == DRIVE) + { + if(l_tgtType == TARGET_TYPE_MCS_CHIPLET) + { + l_memBus.interface = DMI_MCS_DRIVE; + } + else if(l_tgtType == TARGET_TYPE_MEMBUF_CHIP) + { + l_memBus.interface = DMI_MEMBUF_DRIVE; + } + } + else if(i_interface == RECEIVE) + { + if(l_tgtType == TARGET_TYPE_MCS_CHIPLET) + { + l_memBus.interface = DMI_MCS_RECEIVE; + } + else if(l_tgtType == TARGET_TYPE_MEMBUF_CHIP) + { + l_memBus.interface = DMI_MEMBUF_RECEIVE; + } + } + + // TODO: RTC task 71260 + // Investigate if there is an Endianess issue with + // the memcpy and fix it. + memcpy(l_vpdDataPtr, &l_memBus, l_repairDataSz); + l_newNumRepairs++; + + // Increment the count of parsed bytes + l_bytesParsed += l_repairDataSz; + } + } // end of if(l_overWrite == false) + } // end of for(failLanes) + + // Update the eRepair count + l_vpdHeadPtr->numRecords = l_newNumRepairs; + + }while(0); + + FAPI_INF("<< updateMnfgRepairLanesToBuf"); + + return(l_rc); +} + +}// endof extern "C" diff --git a/src/usr/hwpf/hwp/bus_training/erepair_errors.xml b/src/usr/hwpf/hwp/bus_training/erepair_errors.xml index e805c06cc..a61ec27ee 100644 --- a/src/usr/hwpf/hwp/bus_training/erepair_errors.xml +++ b/src/usr/hwpf/hwp/bus_training/erepair_errors.xml @@ -21,21 +21,21 @@ <!-- --> <!-- IBM_PROLOG_END_TAG --> <hwpErrors> - <!-- *********************************************************************** --> + <!-- ********************************************************************* --> <hwpError> <rc>RC_ACCESSOR_HWP_INVALID_TARGET_TYPE</rc> <description> Invalid input parameter: Valid target types are - XBUS, ABUS, MCS </description> </hwpError> - <!-- *********************************************************************** --> + <!-- ********************************************************************* --> <hwpError> <rc>RC_ACCESSOR_HWP_MEMORY_ALLOC_FAIL</rc> <description> Failed to allocate run time memory from the heap </description> </hwpError> - <!-- *********************************************************************** --> + <!-- ********************************************************************* --> <hwpError> <rc>RC_EREPAIR_RESTORE_INVALID_TARGET_PAIR</rc> <description> @@ -43,33 +43,78 @@ MCS-MEMBUF </description> </hwpError> - <!-- *********************************************************************** --> + <!-- ********************************************************************* --> <hwpError> <rc>RC_EREPAIR_RESTORE_FIELD_VPD_NOT_CLEAR</rc> <description> Field VPD needs to be clear during Manufacturing Mode eRepair restore </description> </hwpError> - <!-- *********************************************************************** --> + <!-- ********************************************************************* --> <hwpError> <rc>RC_EREPAIR_RESTORE_THRESHOLD_EXCEED</rc> <description> The threshold limit for eRepair has been crossed </description> + <ffdc>FFDC_ENDP_TARGET</ffdc> + <ffdc>FFDC_SUB_IFACE</ffdc> + <ffdc>FFDC_LANES</ffdc> </hwpError> - <!-- *********************************************************************** --> + <!-- ********************************************************************* --> <hwpError> <rc>RC_EREPAIR_RESTORE_CHARM_THRESHOLD_EXCEED</rc> <description> The threshold limit for eRepair has been crossed during CHARM operation </description> </hwpError> - <!-- *********************************************************************** --> + <!-- ********************************************************************* --> <hwpError> <rc>RC_EREPAIR_RESTORE_SPARE_LANES_IN_VPD</rc> <description> There are spare lanes in the VPD. Spare lanes cannot be restored. </description> </hwpError> - <!-- *********************************************************************** --> + <!-- ********************************************************************* --> + <hwpError> + <rc>RC_EREPAIR_RESTORE_INVALID_TARGET</rc> + <description> + Invalid input parameter: Invalid target type + </description> + </hwpError> + <!-- ********************************************************************* --> + <hwpError> + <rc>RC_EREPAIR_THRESHOLD_EXCEED</rc> + <description> + The threshold limit for eRepair has been crossed + </description> + </hwpError> + <!-- ********************************************************************* --> + <hwpError> + <rc>RC_EREPAIR_MVPD_FULL</rc> + <description> + eRepair data limit in the Processor Module VPD has been reached + </description> + </hwpError> + <!-- ********************************************************************* --> + <hwpError> + <rc>RC_EREPAIR_MBVPD_FULL</rc> + <description> + eRepair data limit in the Memory Buffer FRU VPD has been reached + </description> + </hwpError> + <!-- ********************************************************************* --> + <hwpError> + <rc>RC_ACCESSOR_HWP_INVALID_MEM_VPD_SIZE</rc> + <description> + Invalid Memory VPD size has been returned by platform + </description> + </hwpError> + <!-- ********************************************************************* --> + <hwpError> + <rc>RC_ACCESSOR_HWP_INVALID_FABRIC_VPD_SIZE</rc> + <description> + Invalid Fabric VPD size has been returned by platform + </description> + </hwpError> + <!-- ********************************************************************* --> </hwpErrors> diff --git a/src/usr/hwpf/hwp/bus_training/makefile b/src/usr/hwpf/hwp/bus_training/makefile index ba956e0f6..c32d387ba 100644 --- a/src/usr/hwpf/hwp/bus_training/makefile +++ b/src/usr/hwpf/hwp/bus_training/makefile @@ -43,7 +43,9 @@ OBJS = gcr_funcs.o io_funcs.o io_run_training.o pbusLinkSvc.o proc_fab_smp.o \ io_restore_erepair.o \ erepairAccessorHwpFuncs.o \ erepairGetFailedLanesHwp.o \ - erepairGetMnfgFailedLanesHwp.o + erepairGetMnfgFailedLanesHwp.o \ + erepairSetFailedLanesHwp.o \ + erepairSetMnfgFailedLanesHwp.o ## NOTE: add a new directory onto the vpaths when you add a new HWP diff --git a/src/usr/hwpf/hwp/dmi_training/dmi_training.C b/src/usr/hwpf/hwp/dmi_training/dmi_training.C index bd338e90e..c18461029 100644 --- a/src/usr/hwpf/hwp/dmi_training/dmi_training.C +++ b/src/usr/hwpf/hwp/dmi_training/dmi_training.C @@ -424,6 +424,8 @@ void* call_dmi_erepair( void *io_pArgs ) std::vector<uint8_t> l_endp1_rxFaillanes; std::vector<uint8_t> l_endp2_txFaillanes; std::vector<uint8_t> l_endp2_rxFaillanes; + uint32_t l_count = 0; + fapi::TargetType l_tgtType = fapi::TARGET_TYPE_NONE; TargetHandleList l_mcsTargetList; TargetHandleList l_memTargetList; @@ -554,7 +556,28 @@ void* call_dmi_erepair( void *io_pArgs ) errlCommit(l_errPtr, HWPF_COMP_ID); break; } - } + + l_tgtType = l_fapi_endp1_target.getType(); + for(l_count = 0; l_count < l_endp1_txFaillanes.size(); l_count++) + { + TRACDCOMP(ISTEPS_TRACE::g_trac_isteps_trace,"Successfully" + " restored Tx lane %d, of %s, of endpoint %s", + l_endp1_txFaillanes[l_count], + l_tgtType == TARGET_TYPE_XBUS_ENDPOINT ? "X-Bus" : + l_tgtType == TARGET_TYPE_ABUS_ENDPOINT ? "A-Bus" : + "DMI-Bus", l_fapi_endp1_target.toEcmdString()); + } + + for(l_count = 0; l_count < l_endp1_rxFaillanes.size(); l_count++) + { + TRACDCOMP(ISTEPS_TRACE::g_trac_isteps_trace,"Successfully" + " restored Rx lane %d, of %s, of endpoint %s", + l_endp1_txFaillanes[l_count], + l_tgtType == TARGET_TYPE_XBUS_ENDPOINT ? "X-Bus" : + l_tgtType == TARGET_TYPE_ABUS_ENDPOINT ? "A-Bus" : + "DMI-Bus", l_fapi_endp1_target.toEcmdString()); + } + } // end of if(l_endp1_txFaillanes.size() || l_endp1_rxFaillanes.size()) if(l_endp2_txFaillanes.size() || l_endp2_rxFaillanes.size()) { @@ -567,7 +590,6 @@ void* call_dmi_erepair( void *io_pArgs ) l_fapi_endp2_target.toEcmdString(), l_mcsNum, l_memNum ); - FAPI_INVOKE_HWP(l_errPtr, io_restore_erepair, l_fapi_endp2_target, @@ -603,7 +625,28 @@ void* call_dmi_erepair( void *io_pArgs ) errlCommit(l_errPtr, HWPF_COMP_ID); break; } - } + + l_tgtType = l_fapi_endp2_target.getType(); + for(l_count = 0; l_count < l_endp2_txFaillanes.size(); l_count++) + { + TRACDCOMP(ISTEPS_TRACE::g_trac_isteps_trace,"Successfully" + " restored Tx lane %d, of %s, of endpoint %s", + l_endp2_txFaillanes[l_count], + l_tgtType == TARGET_TYPE_XBUS_ENDPOINT ? "X-Bus" : + l_tgtType == TARGET_TYPE_ABUS_ENDPOINT ? "A-Bus" : + "DMI-Bus", l_fapi_endp2_target.toEcmdString()); + } + + for(l_count = 0; l_count < l_endp2_rxFaillanes.size(); l_count++) + { + TRACDCOMP(ISTEPS_TRACE::g_trac_isteps_trace,"Successfully" + " restored Rx lane %d, of %s, of endpoint %s", + l_endp2_txFaillanes[l_count], + l_tgtType == TARGET_TYPE_XBUS_ENDPOINT ? "X-Bus" : + l_tgtType == TARGET_TYPE_ABUS_ENDPOINT ? "A-Bus" : + "DMI-Bus", l_fapi_endp2_target.toEcmdString()); + } + } // end of if(l_endp2_txFaillanes.size() || l_endp2_rxFaillanes.size()) } // end for l_mcs_target TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_dmi_erepair exit" ); |