diff options
-rw-r--r-- | src/usr/hwpf/hwp/bus_training/erepairGetFailedLanesHwp.C | 194 | ||||
-rwxr-xr-x | src/usr/hwpf/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 a4db16036..33ec195a1 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 a59d9e5a4..b0724f903 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, |