diff options
Diffstat (limited to 'src/usr')
| -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 |
3 files changed, 198 insertions, 0 deletions
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 // |

