Merge pull request #91 from geissonator/master
Add patch in to support erepair on OpenPower systems
diff --git a/openpower/package/hostboot/hostboot-0011-eRepair-MBVPD-size-check-for-CDIMM-and-ISDIMM.patch b/openpower/package/hostboot/hostboot-0011-eRepair-MBVPD-size-check-for-CDIMM-and-ISDIMM.patch
new file mode 100644
index 0000000..55c94f0
--- /dev/null
+++ b/openpower/package/hostboot/hostboot-0011-eRepair-MBVPD-size-check-for-CDIMM-and-ISDIMM.patch
@@ -0,0 +1,504 @@
+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
+