summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorcrgeddes <crgeddes@us.ibm.com>2017-01-13 20:42:01 -0600
committerChristian R. Geddes <crgeddes@us.ibm.com>2017-01-14 10:14:22 -0500
commit29684ba50d2cfefea4e20ec954d1b64c3b247974 (patch)
tree237f1a08a92a4fc2a3f07d83fd2818cd75f0129f /src
parent200e13aff211133665601c5378ec6e09741a6262 (diff)
downloadtalos-hostboot-29684ba50d2cfefea4e20ec954d1b64c3b247974.tar.gz
talos-hostboot-29684ba50d2cfefea4e20ec954d1b64c3b247974.zip
Disable bad MCAs based on CRP0:Lx keyword data
The CRP0 record has 8 records (L1-L8) that correspond to the 8 ports (MCA targets) for the chip. One of the fields inside the keyword indicates if the port is disabled. This field marks the MCA as non-functional, but the MCA remains present. Change-Id: Iccc943ad477a90a25aeaff67572b66126c759913 RTC:166354 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/34885 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com> Reviewed-by: Dean Sanner <dsanner@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/hwas/common/deconfigGard.H3
-rw-r--r--src/include/usr/hwas/common/hwas.H11
-rw-r--r--src/include/usr/hwas/common/hwasCommon.H33
-rw-r--r--src/include/usr/hwas/hwasplatreasoncodes.H4
-rw-r--r--src/usr/hwas/common/hwas.C83
-rw-r--r--src/usr/hwas/hwasPlat.C76
-rw-r--r--src/usr/hwas/test/hwas1test.H39
7 files changed, 245 insertions, 4 deletions
diff --git a/src/include/usr/hwas/common/deconfigGard.H b/src/include/usr/hwas/common/deconfigGard.H
index 7efb854cd..0c133f427 100644
--- a/src/include/usr/hwas/common/deconfigGard.H
+++ b/src/include/usr/hwas/common/deconfigGard.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -163,6 +163,7 @@ public:
DECONFIGURED_BY_PEC_DECONFIG, // BASE | 0x13
DECONFIGURED_BY_NO_CHILD_MCS, // BASE | 0x14
DECONFIGURED_BY_NO_PARENT_MCBIST, // BASE | 0x15
+ DECONFIGURED_BY_DISABLED_PORT, // BASE | 0x16
// mask - these bits mean it's a PLID and not an enum
DECONFIGURED_BY_PLID_MASK = 0xFFFF0000,
diff --git a/src/include/usr/hwas/common/hwas.H b/src/include/usr/hwas/common/hwas.H
index 891af5e3d..138a51887 100644
--- a/src/include/usr/hwas/common/hwas.H
+++ b/src/include/usr/hwas/common/hwas.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -201,6 +201,15 @@ void setChipletGardsOnProc(TARGETING::Target * i_procTarget);
*/
void calculateEffectiveEC();
+
+/**
+ * @brief Mark any MCA units that are present but have a disabled port as
+ * non-functional
+ *
+ * @return error log handle
+ */
+errlHndl_t markDisabledMcas();
+
}; // end namespace
#endif
diff --git a/src/include/usr/hwas/common/hwasCommon.H b/src/include/usr/hwas/common/hwasCommon.H
index b3fc5e17b..1aa4f12b1 100644
--- a/src/include/usr/hwas/common/hwasCommon.H
+++ b/src/include/usr/hwas/common/hwasCommon.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -263,6 +263,37 @@ errlHndl_t platReadPR(const TARGETING::TargetHandle_t &i_target,
// constants the platReadPR will use for looking at the VPD data
const uint32_t VPD_VINI_PR_DATA_LENGTH = 8; //@deprecrated
+
+/**
+ * @brief platform specific code to determine the Lx vector of the input
+ * target. The platform specific code is responsible for returning the
+ * vector. The caller is responsible for allocating and de-allocating the
+ * space.
+ *
+ * @param[in] i_proc processor target to read the Lx keyword from
+ * @param[in] i_mca MCA target indicating which Lx keyword to read
+ * @param[out] o_lxData pointer to area that will hold the Lx keyword
+ * read from VPD; must be malloc'ed by the caller,
+ * and must be VPD_CRP0_LX_DATA_LENGTH in size.
+ *
+ * @return errlHndl_t valid errlHndl_t handle if there was an error
+ * NULL if no errors;
+ */
+errlHndl_t platReadLx(const TARGETING::TargetHandle_t &i_proc,
+ const TARGETING::TargetHandle_t &i_mca,
+ void *o_lxData);
+
+// constants the platReadLx will use for looking at the VPD data
+const uint32_t VPD_CRP0_LX_HDR_LENGTH = 1;
+const uint32_t VPD_CRP0_LX_DATA_LENGTH = 256;
+
+const uint32_t VPD_CRP0_LX_FREQ_INDEP_INDEX = 8;
+const uint32_t VPD_CRP0_LX_PORT_DISABLED = 0;
+
+const uint8_t VPD_CRP0_LX_MIN_X = 1;
+const uint8_t VPD_CRP0_LX_MAX_X = 8;
+
+
/**
* @brief platform specific code to read the Field Core Override
*
diff --git a/src/include/usr/hwas/hwasplatreasoncodes.H b/src/include/usr/hwas/hwasplatreasoncodes.H
index 3ffcb9abb..9e6ea9611 100644
--- a/src/include/usr/hwas/hwasplatreasoncodes.H
+++ b/src/include/usr/hwas/hwasplatreasoncodes.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2016 */
+/* Contributors Listed Below - COPYRIGHT 2014,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -37,6 +37,7 @@ namespace HWAS
MOD_HOST_DISCOVER_TARGETS = 0x80,
MOD_PLAT_DECONFIG_GARD = 0x81,
MOD_PLAT_READIDEC = 0x82,
+ MOD_PLAT_READLX = 0x83,
};
enum HwasPlatReasonCode
@@ -47,6 +48,7 @@ namespace HWAS
RC_TARGET_NOT_GARDABLE = HWAS_COMP_ID | 0x81,
RC_GARD_REPOSITORY_FULL = HWAS_COMP_ID | 0x82,
RC_BAD_CHIPID = HWAS_COMP_ID | 0x83,
+ RC_BAD_LX = HWAS_COMP_ID | 0x84,
};
};
diff --git a/src/usr/hwas/common/hwas.C b/src/usr/hwas/common/hwas.C
index fa0c16882..c9955b5fd 100644
--- a/src/usr/hwas/common/hwas.C
+++ b/src/usr/hwas/common/hwas.C
@@ -455,6 +455,15 @@ errlHndl_t discoverTargets()
break;
}
+ // Mark any MCA units that are present but have a disabled port
+ // as non-functional
+ errl = markDisabledMcas();
+ if (errl)
+ {
+ HWAS_ERR("discoverTargets: markDisabledMcas failed");
+ break;
+ }
+
// call invokePresentByAssoc() to obtain functional MCSs, MEMBUFs, and
// DIMMs for non-direct memory or MCSs, MCAs, and DIMMs for direct
// memory. Call algorithm function presentByAssoc() to determine
@@ -2449,4 +2458,78 @@ void calculateEffectiveEC()
} //calculateEffectiveEC
+errlHndl_t markDisabledMcas()
+{
+ errlHndl_t l_errl = nullptr;
+ uint8_t lxData[HWAS::VPD_CRP0_LX_DATA_LENGTH];
+
+ HWAS_INF("markDisabledMcas entry");
+
+ do
+ {
+ //Get all functional chips
+ TARGETING::TargetHandleList l_procList;
+ getAllChips(l_procList, TYPE_PROC);
+
+ //Loop through all functional procs
+ for(auto l_proc : l_procList)
+ {
+ //Get the functional MCAs for this proc
+ TargetHandleList l_mcaList;
+ getChildChiplets(l_mcaList, l_proc, TYPE_MCA, true);
+
+ for (auto l_mca : l_mcaList)
+ {
+ // fill the Lx data buffer with zeros
+ memset(lxData, 0x00, VPD_CRP0_LX_DATA_LENGTH);
+
+#ifdef __HOSTBOOT_MODULE
+ //@TODO RTC:167294 Need to remove conditional after
+ // additional implementation
+ //Read Lx keyword for associated proc and MCA
+ l_errl = platReadLx(l_proc,
+ l_mca,
+ lxData);
+#endif
+
+ if (l_errl)
+ {
+ // commit the error but keep going
+ errlCommit(l_errl, HWAS_COMP_ID);
+ }
+
+ if (lxData[VPD_CRP0_LX_FREQ_INDEP_INDEX
+ + VPD_CRP0_LX_PORT_DISABLED] != 0)
+ {
+ // Since port is disabled, MCA is not functional, but
+ // it's present.
+ enableHwasState(l_mca,
+ true, // present
+ false, // not functional
+ DeconfigGard::DECONFIGURED_BY_DISABLED_PORT
+ );
+ HWAS_DBG("MCA %.8X - marked present, not functional",
+ l_mca->getAttr<ATTR_HUID>());
+
+ TargetInfo l_TargetInfo;
+ l_TargetInfo.affinityPath =
+ l_mca->getAttr<ATTR_AFFINITY_PATH>();
+ l_TargetInfo.pThisTarget = l_mca;
+ l_TargetInfo.type = l_mca->getAttr<ATTR_TYPE>();
+ l_TargetInfo.reason =
+ DeconfigGard::DECONFIGURED_BY_DISABLED_PORT;
+
+ // Deconfigure child targets for this MCA
+ deconfigPresentByAssoc(l_TargetInfo);
+ }
+ }
+ }
+
+ }while(0);
+
+ HWAS_INF("markDisabledMcas exit");
+ return l_errl;
+
+} //markDisabledMcas
+
}; // end namespace
diff --git a/src/usr/hwas/hwasPlat.C b/src/usr/hwas/hwasPlat.C
index 38618e3e7..57a2e9ef6 100644
--- a/src/usr/hwas/hwasPlat.C
+++ b/src/usr/hwas/hwasPlat.C
@@ -303,6 +303,82 @@ errlHndl_t platReadPR(const TargetHandle_t &i_target,
} // platReadPR
//******************************************************************************
+// platReadLx function
+//******************************************************************************
+errlHndl_t platReadLx(const TargetHandle_t &i_proc,
+ const TargetHandle_t &i_mca,
+ void *o_lxData)
+{
+ errlHndl_t errl = nullptr;
+ uint8_t l_chip_unit = i_mca->getAttr<TARGETING::ATTR_CHIP_UNIT>();
+ uint8_t l_x = VPD_CRP0_LX_MIN_X + l_chip_unit;
+
+ HWAS_DBG( "i_proc %.8X, i_mca %.8X, Lx = L%1d",
+ i_proc->getAttr<ATTR_HUID>(),
+ i_mca->getAttr<ATTR_HUID>(),
+ l_x);
+
+ //Look for an invalid x value
+ if( l_x > VPD_CRP0_LX_MAX_X)
+ {
+ HWAS_ERR("Invalid Lx with x=%1d for MCA %.8X on %.8X",
+ l_x,
+ i_mca->getAttr<ATTR_HUID>(),
+ i_proc->getAttr<ATTR_HUID>());
+ /*@
+ * @errortype ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid HWAS::MOD_PLAT_READLX
+ * @reasoncode HWAS::RC_BAD_LX
+ * @userdata1[0:31] Target proc HUID
+ * @userdata1[32:63] Target MCA HUID
+ * @userdata2 Value of x for Lx keyword
+ * @devdesc platReadLx> Invalid Lx keyword
+ */
+ errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ HWAS::MOD_PLAT_READLX,
+ HWAS::RC_BAD_LX,
+ TWO_UINT32_TO_UINT64(
+ TARGETING::get_huid(i_proc),
+ TARGETING::get_huid(i_mca)),
+ l_x);
+
+ // make code the highest callout
+ errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ }
+
+ if (errl == nullptr)
+ { // no error, so we got a valid chip unit value back
+ // call deviceRead() to find the Lx record
+ uint8_t lxRaw[VPD_CRP0_LX_HDR_LENGTH + VPD_CRP0_LX_DATA_LENGTH];
+ size_t lxSize = sizeof(lxRaw);
+
+ errl = deviceRead(i_proc, lxRaw, lxSize,
+ DEVICE_MVPD_ADDRESS(MVPD::CRP0,
+ MVPD::L1 + l_chip_unit));
+
+ if (errl != nullptr)
+ { // trace the error condition
+ HWAS_INF( "i_proc %.8X, i_mca %.8X - failed L%1d read",
+ i_proc->getAttr<ATTR_HUID>(),
+ i_mca->getAttr<ATTR_HUID>(),
+ l_x);
+ }
+ else
+ {
+ // skip past the header
+ void *lxData = static_cast<void *>(&lxRaw[0]);
+ HWAS_DBG_BIN("Lx record", lxData, VPD_CRP0_LX_DATA_LENGTH);
+ // copy the data back into the caller's buffer
+ memcpy(o_lxData, lxData, VPD_CRP0_LX_DATA_LENGTH);
+ }
+ }
+
+ return errl;
+} // platReadLx
+
+//******************************************************************************
// platGetFCO function
//******************************************************************************
errlHndl_t platGetFCO(const TargetHandle_t &i_node,
diff --git a/src/usr/hwas/test/hwas1test.H b/src/usr/hwas/test/hwas1test.H
index 7dd7b70ed..cf7461623 100644
--- a/src/usr/hwas/test/hwas1test.H
+++ b/src/usr/hwas/test/hwas1test.H
@@ -1627,6 +1627,45 @@ public:
TS_INFO( "testHWASpervStates exit" );
}
+
+ /**
+ * @brief test platReadLx
+ */
+ void testHWASplatReadLx()
+ {
+ using namespace TARGETING;
+
+ TS_INFO( "testHWASplatReadLx entry" );
+
+ // call platReadLx with target that isn't in the VPD
+ errlHndl_t l_errl;
+
+ Target* pSys;
+ targetService().getTopLevelTarget(pSys);
+
+ TARGETING::TargetHandleList l_procList;
+ getAllChips(l_procList, TYPE_PROC);
+
+ TargetHandleList l_mcaList;
+ getChildChiplets(l_mcaList, *(l_procList.begin()), TYPE_MCA, true);
+
+ uint8_t lxData[HWAS::VPD_CRP0_LX_DATA_LENGTH];
+
+ l_errl = HWAS::platReadLx(pSys, *(l_mcaList.begin()), lxData);
+
+ if (l_errl)
+ {
+ // error log is expected case, delete it
+ delete l_errl;
+ }
+ else
+ {
+ TS_FAIL("testHWASplatReadLx>"
+ "No error from platReadLx(pSys, *(l_mcaList.begin()).");
+ }
+
+ TS_INFO( "testHWASplatReadLx exit" );
+ }
};
#endif //
OpenPOWER on IntegriCloud