diff options
| author | crgeddes <crgeddes@us.ibm.com> | 2017-01-13 20:42:01 -0600 |
|---|---|---|
| committer | Christian R. Geddes <crgeddes@us.ibm.com> | 2017-01-14 10:14:22 -0500 |
| commit | 29684ba50d2cfefea4e20ec954d1b64c3b247974 (patch) | |
| tree | 237f1a08a92a4fc2a3f07d83fd2818cd75f0129f /src | |
| parent | 200e13aff211133665601c5378ec6e09741a6262 (diff) | |
| download | talos-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.H | 3 | ||||
| -rw-r--r-- | src/include/usr/hwas/common/hwas.H | 11 | ||||
| -rw-r--r-- | src/include/usr/hwas/common/hwasCommon.H | 33 | ||||
| -rw-r--r-- | src/include/usr/hwas/hwasplatreasoncodes.H | 4 | ||||
| -rw-r--r-- | src/usr/hwas/common/hwas.C | 83 | ||||
| -rw-r--r-- | src/usr/hwas/hwasPlat.C | 76 | ||||
| -rw-r--r-- | src/usr/hwas/test/hwas1test.H | 39 |
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 // |

