| From 403b5b351e0ee82fa0b7147ea924b455384cf39d Mon Sep 17 00:00:00 2001 |
| From: Bilicon Patil <bilpatil@in.ibm.com> |
| Date: Fri, 5 Dec 2014 07:25:24 -0600 |
| Subject: [PATCH 2/6] eRepair MBVPD size check for CDIMM and ISDIMM |
| |
| The eRepair VPD size for DMI Bus is bigger in systems with ISDIMMs because |
| the VPD accounts for all the Centaurs. The current check in the code is |
| for each Centaur which is applicable for systems with CDIMMs. |
| |
| The fix also includes a change to do restore of eRepair records noted |
| in the VPD when the system had a non-fips830 driver. |
| |
| Change-Id: Ibaaf98c5be3e26474ee0eede6081f506f4bb7ec3 |
| RTC: 119532 |
| Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/14727 |
| Tested-by: Jenkins Server |
| Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> |
| Reviewed-by: Prem Shanker Jha <premjha2@in.ibm.com> |
| Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com> |
| (cherry picked from commit db9b6fed621390d10459834300924e0fafd6fa04) |
| --- |
| .../hwp/bus_training/erepairGetFailedLanesHwp.C | 194 +++++++++++++++----- |
| .../hwp/bus_training/erepairSetFailedLanesHwp.C | 73 +++++++- |
| 2 files changed, 215 insertions(+), 52 deletions(-) |
| |
| diff --git a/src/usr/hwpf/hwp/bus_training/erepairGetFailedLanesHwp.C b/src/usr/hwpf/hwp/bus_training/erepairGetFailedLanesHwp.C |
| index a4db160..33ec195 100644 |
| --- a/src/usr/hwpf/hwp/bus_training/erepairGetFailedLanesHwp.C |
| +++ b/src/usr/hwpf/hwp/bus_training/erepairGetFailedLanesHwp.C |
| @@ -5,7 +5,7 @@ |
| /* */ |
| /* OpenPOWER HostBoot Project */ |
| /* */ |
| -/* Contributors Listed Below - COPYRIGHT 2013,2014 */ |
| +/* Contributors Listed Below - COPYRIGHT 2013,2015 */ |
| /* [+] International Business Machines Corp. */ |
| /* */ |
| /* */ |
| @@ -38,6 +38,8 @@ |
| |
| #include <erepairGetFailedLanesHwp.H> |
| |
| +using namespace EREPAIR; |
| + |
| extern "C" |
| { |
| |
| @@ -62,10 +64,10 @@ extern "C" |
| * |
| * @return ReturnCode |
| */ |
| -fapi::ReturnCode retrieveRepairData(const fapi::Target &i_tgtHandle, |
| - EREPAIR::erepairVpdType i_vpdType, |
| - std::vector<uint8_t> &o_txFailLanes, |
| - std::vector<uint8_t> &o_rxFailLanes); |
| +fapi::ReturnCode retrieveRepairData(const fapi::Target &i_tgtHandle, |
| + erepairVpdType i_vpdType, |
| + 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 |
| @@ -92,15 +94,25 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target &i_tgtHandle, |
| 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_tgtHandle Reference to X-Bus or A-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 |
| + */ |
| +fapi::ReturnCode getDimmType(const fapi::Target &i_tgtHandle, |
| + uint8_t &o_customDimm); |
| + |
| /****************************************************************************** |
| * Accessor HWP |
| *****************************************************************************/ |
| |
| -fapi::ReturnCode erepairGetFailedLanesHwp( |
| - const fapi::Target &i_tgtHandle, |
| - EREPAIR::erepairVpdType i_vpdType, |
| - std::vector<uint8_t> &o_txFailLanes, |
| - std::vector<uint8_t> &o_rxFailLanes) |
| +fapi::ReturnCode erepairGetFailedLanesHwp(const fapi::Target &i_tgtHandle, |
| + erepairVpdType i_vpdType, |
| + std::vector<uint8_t> &o_txFailLanes, |
| + std::vector<uint8_t> &o_rxFailLanes) |
| { |
| fapi::ReturnCode l_rc; |
| fapi::Target l_processorTgt; |
| @@ -147,15 +159,16 @@ fapi::ReturnCode erepairGetFailedLanesHwp( |
| return l_rc; |
| } |
| |
| -fapi::ReturnCode retrieveRepairData(const fapi::Target &i_tgtHandle, |
| - EREPAIR::erepairVpdType i_vpdType, |
| - std::vector<uint8_t> &o_txFailLanes, |
| - std::vector<uint8_t> &o_rxFailLanes) |
| +fapi::ReturnCode retrieveRepairData(const fapi::Target &i_tgtHandle, |
| + erepairVpdType i_vpdType, |
| + std::vector<uint8_t> &o_txFailLanes, |
| + std::vector<uint8_t> &o_rxFailLanes) |
| { |
| fapi::ReturnCode l_rc; |
| uint8_t *l_retBuf = NULL; |
| uint32_t l_bufSize = 0; |
| fapi::Target l_procTarget; |
| + uint8_t l_customDimm; |
| |
| FAPI_DBG(">> retrieveRepairData"); |
| |
| @@ -165,7 +178,7 @@ fapi::ReturnCode retrieveRepairData(const fapi::Target &i_tgtHandle, |
| { |
| fapi::MBvpdRecord l_vpdRecord = fapi::MBVPD_RECORD_VEIR; |
| |
| - if(i_vpdType == EREPAIR::EREPAIR_VPD_MNFG) |
| + if(i_vpdType == EREPAIR_VPD_MNFG) |
| { |
| l_vpdRecord = fapi::MBVPD_RECORD_MER0; |
| } |
| @@ -184,12 +197,34 @@ fapi::ReturnCode retrieveRepairData(const fapi::Target &i_tgtHandle, |
| break; |
| } |
| |
| - 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))) |
| + // Check whether we have Memory on a CDIMM |
| + l_rc = getDimmType(i_tgtHandle, l_customDimm); |
| + |
| + if(l_rc) |
| + { |
| + FAPI_ERR("Error (0x%x) during DIMM type check", |
| + static_cast<uint32_t> (l_rc)); |
| + break; |
| + } |
| + |
| + if(l_customDimm == fapi::ENUM_ATTR_SPD_CUSTOM_YES) |
| { |
| + 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_SET_HWP_ERROR(l_rc, |
| + RC_ACCESSOR_HWP_INVALID_MEM_VPD_SIZE); |
| + break; |
| + } |
| + } |
| + else if(l_bufSize == 0) |
| + { |
| + // TODO RTC: 119531. Add upper bound checking for l_bufSize |
| + // This size check will depend on whether the Lane eRepair data |
| + // is stored on the Planar VPD or on the Riser card VPD. |
| FAPI_SET_HWP_ERROR(l_rc, RC_ACCESSOR_HWP_INVALID_MEM_VPD_SIZE); |
| break; |
| } |
| @@ -230,7 +265,7 @@ fapi::ReturnCode retrieveRepairData(const fapi::Target &i_tgtHandle, |
| |
| fapi::MvpdRecord l_vpdRecord = fapi::MVPD_RECORD_VWML; |
| |
| - if(i_vpdType == EREPAIR::EREPAIR_VPD_MNFG) |
| + if(i_vpdType == EREPAIR_VPD_MNFG) |
| { |
| l_vpdRecord = fapi::MVPD_RECORD_MER0; |
| } |
| @@ -250,10 +285,10 @@ fapi::ReturnCode retrieveRepairData(const fapi::Target &i_tgtHandle, |
| } |
| |
| if((l_bufSize == 0) || |
| - ((i_vpdType == EREPAIR::EREPAIR_VPD_FIELD) && |
| - (l_bufSize > EREPAIR::EREPAIR_P8_MODULE_VPD_FIELD_SIZE)) || |
| - ((i_vpdType == EREPAIR::EREPAIR_VPD_MNFG) && |
| - (l_bufSize > EREPAIR::EREPAIR_P8_MODULE_VPD_MNFG_SIZE))) |
| + ((i_vpdType == EREPAIR_VPD_FIELD) && |
| + (l_bufSize > EREPAIR_P8_MODULE_VPD_FIELD_SIZE)) || |
| + ((i_vpdType == EREPAIR_VPD_MNFG) && |
| + (l_bufSize > EREPAIR_P8_MODULE_VPD_MNFG_SIZE))) |
| { |
| FAPI_SET_HWP_ERROR(l_rc, |
| RC_ACCESSOR_HWP_INVALID_FABRIC_VPD_SIZE); |
| @@ -323,6 +358,7 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target &i_tgtHandle, |
| fapi::Target l_mcsTarget; |
| fapi::Target l_tgtHandle; |
| fapi::ReturnCode l_rc; |
| + uint8_t l_customDimm; |
| fapi::ATTR_CHIP_UNIT_POS_Type l_busNum; |
| |
| FAPI_DBG(">> determineRepairLanes"); |
| @@ -394,21 +430,18 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target &i_tgtHandle, |
| l_fabricBus->interface = (l_temp & 0x0F); |
| #endif |
| |
| - // Check if we have the correct Processor ID |
| - if(l_chipPosition != l_fabricBus->device.processor_id) |
| - { |
| - continue; |
| - } |
| + // 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 == fapi::TARGET_TYPE_ABUS_ENDPOINT) && |
| - (l_fabricBus->type != EREPAIR::PROCESSOR_EDI)) |
| + (l_fabricBus->type != PROCESSOR_EDI)) |
| { |
| continue; |
| } |
| |
| if((l_tgtType == fapi::TARGET_TYPE_XBUS_ENDPOINT) && |
| - (l_fabricBus->type != EREPAIR::PROCESSOR_EI4)) |
| + (l_fabricBus->type != PROCESSOR_EI4)) |
| { |
| continue; |
| } |
| @@ -428,17 +461,17 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target &i_tgtHandle, |
| } |
| |
| // Check if we have valid fail lane numbers |
| - if(l_fabricBus->failBit == EREPAIR::INVALID_FAIL_LANE_NUMBER) |
| + if(l_fabricBus->failBit == INVALID_FAIL_LANE_NUMBER) |
| { |
| continue; |
| } |
| |
| // Copy the fail lane numbers in the vectors |
| - if(l_fabricBus->interface == EREPAIR::PBUS_DRIVER) |
| + if(l_fabricBus->interface == PBUS_DRIVER) |
| { |
| o_txFailLanes.push_back(l_fabricBus->failBit); |
| } |
| - else if(l_fabricBus->interface == EREPAIR::PBUS_RECEIVER) |
| + else if(l_fabricBus->interface == PBUS_RECEIVER) |
| { |
| o_rxFailLanes.push_back(l_fabricBus->failBit); |
| } |
| @@ -468,6 +501,19 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target &i_tgtHandle, |
| l_tgtHandle = l_mcsTarget; |
| } |
| |
| + if(l_tgtType == fapi::TARGET_TYPE_MEMBUF_CHIP) |
| + { |
| + // Check whether we have Memory on a CDIMM |
| + l_rc = getDimmType(i_tgtHandle, l_customDimm); |
| + |
| + if(l_rc) |
| + { |
| + FAPI_ERR("Error (0x%x) during DIMM type check", |
| + static_cast<uint32_t> (l_rc)); |
| + break; |
| + } |
| + } |
| + |
| // Read Power bus eRepair data and get the failed lane numbers |
| for(l_loop = 0; |
| l_loop < l_numRepairs; |
| @@ -491,14 +537,20 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target &i_tgtHandle, |
| l_memBus->interface = (l_temp & 0x0F); |
| #endif |
| |
| - // Check if we have the correct Processor/Centaur ID |
| - if(l_chipPosition != l_memBus->device.proc_centaur_id) |
| + // 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 != fapi::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 != EREPAIR::MEMORY_EDI) |
| + if(l_memBus->type != MEMORY_EDI) |
| { |
| continue; |
| } |
| @@ -518,7 +570,7 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target &i_tgtHandle, |
| } |
| |
| // Check if we have valid fail lane numbers |
| - if(l_memBus->failBit == EREPAIR::INVALID_FAIL_LANE_NUMBER) |
| + if(l_memBus->failBit == INVALID_FAIL_LANE_NUMBER) |
| { |
| continue; |
| } |
| @@ -526,22 +578,22 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target &i_tgtHandle, |
| // Copy the fail lane numbers in the vectors |
| if(l_tgtType == fapi::TARGET_TYPE_MCS_CHIPLET) |
| { |
| - if(l_memBus->interface == EREPAIR::DMI_MCS_DRIVE) |
| + if(l_memBus->interface == DMI_MCS_DRIVE) |
| { |
| o_txFailLanes.push_back(l_memBus->failBit); |
| } |
| - else if(l_memBus->interface == EREPAIR::DMI_MCS_RECEIVE) |
| + else if(l_memBus->interface == DMI_MCS_RECEIVE) |
| { |
| o_rxFailLanes.push_back(l_memBus->failBit); |
| } |
| } |
| else if(l_tgtType == fapi::TARGET_TYPE_MEMBUF_CHIP) |
| { |
| - if(l_memBus->interface == EREPAIR::DMI_MEMBUF_DRIVE) |
| + if(l_memBus->interface == DMI_MEMBUF_DRIVE) |
| { |
| o_txFailLanes.push_back(l_memBus->failBit); |
| } |
| - else if(l_memBus->interface == EREPAIR::DMI_MEMBUF_RECEIVE) |
| + else if(l_memBus->interface == DMI_MEMBUF_RECEIVE) |
| { |
| o_rxFailLanes.push_back(l_memBus->failBit); |
| } |
| @@ -551,10 +603,64 @@ fapi::ReturnCode determineRepairLanes(const fapi::Target &i_tgtHandle, |
| |
| }while(0); |
| |
| - FAPI_INF("<< No.of Fail Lanes: tx: %d, rx: %d", |
| + FAPI_INF("<< No.of Fail Lanes: tx: %zd, rx: %zd", |
| o_txFailLanes.size(), o_rxFailLanes.size()); |
| |
| return(l_rc); |
| } |
| |
| +fapi::ReturnCode getDimmType(const fapi::Target &i_tgtHandle, |
| + uint8_t &o_customDimm) |
| +{ |
| + fapi::ReturnCode l_rc; |
| + std::vector<fapi::Target> l_mbaChiplets; |
| + fapi::Target l_mbaTarget; |
| + |
| + do |
| + { |
| + // Get the connected MBA chiplet and determine whether we have CDIMM |
| + l_rc = fapiGetChildChiplets(i_tgtHandle, |
| + fapi::TARGET_TYPE_MBA_CHIPLET, |
| + l_mbaChiplets, |
| + fapi::TARGET_STATE_FUNCTIONAL); |
| + if(l_rc || (0 == l_mbaChiplets.size())) |
| + { |
| + FAPI_ERR("Error (0x%x) during get child MBA targets", |
| + static_cast<uint32_t> (l_rc)); |
| + break; |
| + } |
| + |
| + l_mbaTarget = l_mbaChiplets[0]; |
| + std::vector<fapi::Target> l_target_dimm_array; |
| + |
| + l_rc = fapiGetAssociatedDimms(l_mbaTarget, l_target_dimm_array); |
| + |
| + if(l_rc) |
| + { |
| + FAPI_ERR("Error (0x%x), from fapiGetAssociatedDimms", |
| + static_cast<uint32_t>(l_rc)); |
| + break; |
| + } |
| + |
| + if(0 != l_target_dimm_array.size()) |
| + { |
| + l_rc = FAPI_ATTR_GET(ATTR_SPD_CUSTOM, |
| + &l_target_dimm_array[0], |
| + o_customDimm); |
| + if(l_rc) |
| + { |
| + FAPI_ERR("Error (0x%x), from FAPI_ATTR_GET", |
| + static_cast<uint32_t>(l_rc)); |
| + break; |
| + } |
| + } |
| + else |
| + { |
| + o_customDimm = fapi::ENUM_ATTR_SPD_CUSTOM_NO; |
| + } |
| + }while(0); |
| + |
| + return l_rc; |
| +} |
| + |
| }// endof extern "C" |
| diff --git a/src/usr/hwpf/hwp/bus_training/erepairSetFailedLanesHwp.C b/src/usr/hwpf/hwp/bus_training/erepairSetFailedLanesHwp.C |
| index a59d9e5..b0724f9 100755 |
| --- a/src/usr/hwpf/hwp/bus_training/erepairSetFailedLanesHwp.C |
| +++ b/src/usr/hwpf/hwp/bus_training/erepairSetFailedLanesHwp.C |
| @@ -5,7 +5,7 @@ |
| /* */ |
| /* OpenPOWER HostBoot Project */ |
| /* */ |
| -/* Contributors Listed Below - COPYRIGHT 2013,2014 */ |
| +/* Contributors Listed Below - COPYRIGHT 2013,2015 */ |
| /* [+] International Business Machines Corp. */ |
| /* */ |
| /* */ |
| @@ -173,6 +173,9 @@ ReturnCode writeRepairDataToVPD(const Target &i_tgtHandle, |
| uint8_t *l_retBuf = NULL; |
| uint32_t l_bufSize = 0; |
| Target l_procTarget; |
| + uint8_t l_customDimm; |
| + std::vector<fapi::Target> l_mbaChiplets; |
| + fapi::Target l_mbaTarget; |
| |
| FAPI_DBG(">> writeRepairDataToVPD"); |
| |
| @@ -202,12 +205,66 @@ ReturnCode writeRepairDataToVPD(const Target &i_tgtHandle, |
| break; |
| } |
| |
| - 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))) |
| + // Get the connected MBA chiplet and determine whether we have CDIMM |
| + l_rc = fapiGetChildChiplets(i_tgtHandle, |
| + fapi::TARGET_TYPE_MBA_CHIPLET, |
| + l_mbaChiplets, |
| + fapi::TARGET_STATE_FUNCTIONAL); |
| + |
| + if(l_rc || (0 == l_mbaChiplets.size())) |
| + { |
| + FAPI_ERR("Error (0x%x) during get child MBA targets", |
| + static_cast<uint32_t> (l_rc)); |
| + break; |
| + } |
| + |
| + l_mbaTarget = l_mbaChiplets[0]; |
| + std::vector<fapi::Target> l_target_dimm_array; |
| + |
| + l_rc = fapiGetAssociatedDimms(l_mbaTarget, l_target_dimm_array); |
| + |
| + if(l_rc) |
| + { |
| + FAPI_ERR("Error (0x%x), from fapiGetAssociatedDimms", |
| + static_cast<uint32_t>(l_rc)); |
| + break; |
| + } |
| + |
| + if(0 != l_target_dimm_array.size()) |
| + { |
| + l_rc = FAPI_ATTR_GET(ATTR_SPD_CUSTOM, |
| + &l_target_dimm_array[0], |
| + l_customDimm); |
| + if(l_rc) |
| + { |
| + FAPI_ERR("Error (0x%x), from FAPI_ATTR_GET", |
| + static_cast<uint32_t>(l_rc)); |
| + break; |
| + } |
| + } |
| + else |
| + { |
| + l_customDimm = fapi::ENUM_ATTR_SPD_CUSTOM_NO; |
| + } |
| + |
| + if(l_customDimm == fapi::ENUM_ATTR_SPD_CUSTOM_YES) |
| + { |
| + 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_SET_HWP_ERROR(l_rc, |
| + RC_ACCESSOR_HWP_INVALID_MEM_VPD_SIZE); |
| + break; |
| + } |
| + } |
| + else if(l_bufSize == 0) |
| { |
| + // TODO RTC: 119531. Add upper bound checking for l_bufSize |
| + // This size check will depend on whether the Lane eRepair data |
| + // is stored on the Planar VPD or on the Riser card VPD. |
| FAPI_SET_HWP_ERROR(l_rc, RC_ACCESSOR_HWP_INVALID_MEM_VPD_SIZE); |
| break; |
| } |
| @@ -221,7 +278,7 @@ ReturnCode writeRepairDataToVPD(const Target &i_tgtHandle, |
| break; |
| } |
| |
| - // Retrieve the eRepair data from the Centaur FRU VPD |
| + // Retrieve the Field eRepair data from the Centaur FRU VPD |
| l_rc = fapiGetMBvpdField(l_vpdRecord, |
| MBVPD_KEYWORD_PDI, |
| i_tgtHandle, |
| @@ -315,7 +372,7 @@ ReturnCode writeRepairDataToVPD(const Target &i_tgtHandle, |
| break; |
| } |
| |
| - // Retrieve the eRepair data from the MVPD |
| + // Retrieve the Field eRepair data from the MVPD |
| l_rc = fapiGetMvpdField(l_vpdRecord, |
| MVPD_KEYWORD_PDI, |
| l_procTarget, |
| -- |
| 1.7.4.1 |
| |