diff options
Diffstat (limited to 'src/usr/hwas')
-rw-r--r-- | src/usr/hwas/common/deconfigGard.C | 24 | ||||
-rw-r--r-- | src/usr/hwas/common/hwas.C | 148 | ||||
-rw-r--r-- | src/usr/hwas/common/pgLogic.C | 25 | ||||
-rw-r--r-- | src/usr/hwas/hwasPlat.C | 548 | ||||
-rw-r--r-- | src/usr/hwas/hwasPlatDeconfigGard.C | 3 | ||||
-rw-r--r-- | src/usr/hwas/test/hwas1test.H | 267 | ||||
-rw-r--r-- | src/usr/hwas/test/hwasGardTest.H | 2 |
7 files changed, 936 insertions, 81 deletions
diff --git a/src/usr/hwas/common/deconfigGard.C b/src/usr/hwas/common/deconfigGard.C index 727611eed..89df5b160 100644 --- a/src/usr/hwas/common/deconfigGard.C +++ b/src/usr/hwas/common/deconfigGard.C @@ -42,7 +42,6 @@ #include <targeting/common/targetservice.H> #ifdef __HOSTBOOT_MODULE -#include <config.h> #include <errl/errlmanager.H> #if (!defined(CONFIG_CONSOLE_OUTPUT_TRACE) && defined(CONFIG_CONSOLE)) #include <console/consoleif.H> @@ -174,6 +173,17 @@ errlHndl_t DeconfigGard::applyGardRecord(Target *i_pTarget, // all ok - do the work HWAS_MUTEX_LOCK(iv_mutex); +#if (!defined(CONFIG_CONSOLE_OUTPUT_TRACE) && defined(CONFIG_CONSOLE)) + const char* l_tmpstring = + i_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>().toString(); + CONSOLE::displayf("HWAS", "Applying GARD record for HUID=0x%08X (%s) due to 0x%.8X", + get_huid(i_pTarget), + l_tmpstring, + l_errlogEid); + free((void*)(l_tmpstring)); + l_tmpstring = nullptr; +#endif + // Deconfigure the Target // don't need to check ATTR_DECONFIG_GARDABLE -- if we get // here, it's because of a gard record on this target @@ -643,9 +653,13 @@ errlHndl_t DeconfigGard::deconfigureTargetsFromGardRecordsForIpl( } #if (!defined(CONFIG_CONSOLE_OUTPUT_TRACE) && defined(CONFIG_CONSOLE)) + const char* l_tmpstring = + l_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>().toString(); CONSOLE::displayf("HWAS", "Deconfig HUID 0x%08X, %s", get_huid(l_pTarget), - l_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>().toString()); + l_tmpstring); + free((void*)(l_tmpstring)); + l_tmpstring = nullptr; #endif } // for @@ -912,9 +926,13 @@ errlHndl_t DeconfigGard::deconfigureTargetsFromGardRecordsForIpl( } #if (!defined(CONFIG_CONSOLE_OUTPUT_TRACE) && defined(CONFIG_CONSOLE)) + const char* l_tmpstring = + l_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>().toString(); CONSOLE::displayf("HWAS", "Deconfig HUID 0x%08X, %s", get_huid(l_pTarget), - l_pTarget->getAttr<TARGETING::ATTR_PHYS_PATH>().toString()); + l_tmpstring); + free((void*)(l_tmpstring)); + l_tmpstring = nullptr; #endif l_specDeconfigVector.erase(l_specDeconfigVector.begin()); diff --git a/src/usr/hwas/common/hwas.C b/src/usr/hwas/common/hwas.C index 45a88cf85..94d947dad 100644 --- a/src/usr/hwas/common/hwas.C +++ b/src/usr/hwas/common/hwas.C @@ -41,7 +41,6 @@ #include <stdio.h> // sprintf #ifdef __HOSTBOOT_MODULE -#include <config.h> #include <initservice/initserviceif.H> #endif @@ -569,6 +568,59 @@ errlHndl_t discoverMuxTargetsAndEnable(const Target &i_sysTarget) return l_err; } +/** + * @brief Do presence detect on only PMIC targets and enable HWAS state + * + * @param[in] i_sysTarget the top level target (CLASS_SYS) + * @return errlHndl_t return nullptr if no error, + * else return a handle to an error entry + * + */ +errlHndl_t discoverPmicTargetsAndEnable(const Target &i_sysTarget) +{ + HWAS_INF(ENTER_MRK"discoverPmicTargetsAndEnable"); + + errlHndl_t l_err{nullptr}; + + do + { + // Only get PMIC targets + const PredicateCTM l_pmicPred(CLASS_ASIC, TYPE_PMIC); + TARGETING::PredicatePostfixExpr l_asicPredExpr; + l_asicPredExpr.push(&l_pmicPred); + TargetHandleList l_pPmicCheckPres; + targetService().getAssociated( l_pPmicCheckPres, (&i_sysTarget), + TargetService::CHILD, TargetService::ALL, &l_asicPredExpr); + + // Do the presence detect on only PMIC targets + // NOTE: this function will remove any non-functional targets + // from pPmicCheckPres + l_err = platPresenceDetect(l_pPmicCheckPres); + + // If an issue with platPresenceDetect, then exit, returning + // error back to caller + if (nullptr != l_err) + { + break; + } + + // Enable the HWAS State for the PMICs + const bool l_present(true); + const bool l_functional(true); + const uint32_t l_errlEid(0); + for (TargetHandle_t pTarget : l_pPmicCheckPres) + { + // set HWAS state to show PMIC is present and functional + enableHwasState(pTarget, l_present, l_functional, l_errlEid); + } + } while (0); + + HWAS_INF(EXIT_MRK"discoverPmicTargetsAndEnable exit with %s", + (nullptr == l_err ? "no error" : "error")); + + return l_err; +} + errlHndl_t discoverTargets() { HWAS_DBG("discoverTargets entry"); @@ -643,11 +695,13 @@ errlHndl_t discoverTargets() PredicateCTM predPmic(CLASS_ASIC, TYPE_PMIC); // We can ignore chips of TYPE_I2C_MUX because they // were already detected above in discoverMuxTargetsAndEnable + // Also we can ignore chips of type PMIC because they will be processed + // below. PredicateCTM predMux(CLASS_CHIP, TYPE_I2C_MUX); PredicatePostfixExpr checkExpr; checkExpr.push(&predChip).push(&predDimm).Or().push(&predEnc).Or(). - push(&predMcs).Or().push(&predPmic).Or(). - push(&predMux).Not().And(); + push(&predMcs).Or().push(&predMux).Not().And(). + push(&predPmic).Not().And(); TargetHandleList pCheckPres; targetService().getAssociated( pCheckPres, pSys, @@ -728,19 +782,22 @@ errlHndl_t discoverTargets() MOD_DISCOVER_TARGETS, RC_PARTIAL_GOOD_INFORMATION); - if( (pTarget->getAttr<ATTR_CLASS>() == CLASS_CHIP) && - (l_targetType != TYPE_TPM) && - (l_targetType != TYPE_SP) && - (l_targetType != TYPE_BMC) && - (l_targetType != TYPE_I2C_MUX)) + if( (pTarget->getAttr<ATTR_CLASS>() == CLASS_CHIP) + && (l_targetType != TYPE_TPM) + && (l_targetType != TYPE_SP) + && (l_targetType != TYPE_BMC) + && (l_targetType != TYPE_I2C_MUX)) { // read Chip ID/EC data from these physical chips errl = platReadIDEC(pTarget); if (errl) - { // read of ID/EC failed even tho we THOUGHT we were present. - HWAS_INF("pTarget %.8X - read IDEC failed (eid 0x%X) - bad", - errl->eid(), pTarget->getAttr<ATTR_HUID>()); + { + // read of ID/EC failed even tho we THOUGHT we were present. + HWAS_INF("pTarget 0x%.8X - read IDEC failed " + "(eid 0x%X) - bad", + get_huid(pTarget), errl->eid()); + // chip NOT present and NOT functional, so that FSP doesn't // include this for HB to process chipPresent = false; @@ -758,8 +815,9 @@ errlHndl_t discoverTargets() if (errl) { // read of PG failed even tho we were present.. - HWAS_INF("pTarget %.8X - read PG failed (eid 0x%X)- bad", - errl->eid(), pTarget->getAttr<ATTR_HUID>()); + HWAS_INF("pTarget 0x%.8X - read PG failed " + "(eid 0x%X) - bad", + get_huid(pTarget), errl->eid()); chipFunctional = false; errlEid = errl->eid(); @@ -861,6 +919,16 @@ errlHndl_t discoverTargets() } // for pTarget_it + // After processing all other targets look at the pmics, + // we must wait because we need the SPD cached from the OCMBs + // which occurs when OCMBs go through presence detection above + errl = discoverPmicTargetsAndEnable(*pSys); + + if (errl != NULL) + { + break; // break out of the do/while so that we can return + } + // Check for non-present Procs and if found, trigger // DeconfigGard::_invokeDeconfigureAssocProc() to run by setting // setXAOBusEndpointDeconfigured to true @@ -966,6 +1034,13 @@ bool isChipFunctional(const TARGETING::TargetHandle_t &i_target, uint16_t l_xbus = (l_model == MODEL_NIMBUS) ? VPD_CP00_PG_XBUS_GOOD_NIMBUS : VPD_CP00_PG_XBUS_GOOD_CUMULUS; + uint16_t l_perv = (l_model == MODEL_AXONE) ? + VPD_CP00_PG_PERVASIVE_GOOD_AXONE : VPD_CP00_PG_PERVASIVE_GOOD; + + uint16_t l_n2 = (l_model == MODEL_AXONE) ? + VPD_CP00_PG_N2_GOOD_AXONE : VPD_CP00_PG_N2_GOOD; + + // Check all bits in FSI entry if (i_pgData[VPD_CP00_PG_FSI_INDEX] != VPD_CP00_PG_FSI_GOOD) @@ -981,14 +1056,14 @@ bool isChipFunctional(const TARGETING::TargetHandle_t &i_target, else // Check all bits in PRV entry if (i_pgData[VPD_CP00_PG_PERVASIVE_INDEX] != - VPD_CP00_PG_PERVASIVE_GOOD) + l_perv) { HWAS_INF("pTarget %.8X - Pervasive pgData[%d]: " "actual 0x%04X, expected 0x%04X - bad", i_target->getAttr<ATTR_HUID>(), VPD_CP00_PG_PERVASIVE_INDEX, i_pgData[VPD_CP00_PG_PERVASIVE_INDEX], - VPD_CP00_PG_PERVASIVE_GOOD); + l_perv); l_chipFunctional = false; } else @@ -1018,14 +1093,14 @@ bool isChipFunctional(const TARGETING::TargetHandle_t &i_target, } else // Check all bits in N2 entry - if (i_pgData[VPD_CP00_PG_N2_INDEX] != VPD_CP00_PG_N2_GOOD) + if (i_pgData[VPD_CP00_PG_N2_INDEX] != l_n2) { HWAS_INF("pTarget %.8X - N2 pgData[%d]: " "actual 0x%04X, expected 0x%04X - bad", i_target->getAttr<ATTR_HUID>(), VPD_CP00_PG_N2_INDEX, i_pgData[VPD_CP00_PG_N2_INDEX], - VPD_CP00_PG_N2_GOOD); + l_n2); l_chipFunctional = false; } else @@ -3839,7 +3914,7 @@ errlHndl_t updateProcCompatibilityRiskLevel() "force compatibility of invalid MRW risk level %d", l_risk); - /* + /*@ * @errortype * @severity ERRL_SEV_UNRECOVERABLE * @moduleid MOD_UPDATE_PROC_COMPAT_RISK_LEVEL @@ -3906,7 +3981,7 @@ errlHndl_t updateProcCompatibilityRiskLevel() "force native compatibility of mixed processor levels", " (0x%02X and 0x%02X)", l_firstEc, l_lastEc ); - /* + /*@ * @errortype * @severity ERRL_SEV_UNRECOVERABLE * @moduleid MOD_UPDATE_PROC_COMPAT_RISK_LEVEL @@ -3977,7 +4052,7 @@ errlHndl_t updateProcCompatibilityRiskLevel() "force native compatibility of DD2.3 for risk level %d", l_risk); - /* + /*@ * @errortype * @severity ERRL_SEV_UNRECOVERABLE * @moduleid MOD_UPDATE_PROC_COMPAT_RISK_LEVEL @@ -4064,6 +4139,33 @@ errlHndl_t updateProcCompatibilityRiskLevel() return l_err; } +/** + * @brief Normalize the RISK_LEVEL for Axone to use the upper range + */ +void normalizeRiskLevelForAxone( void ) +{ + // Axone follows Nimbus DD2.3 settings except it can use + // the low or high numbers. Let's normalize it to the + // high range to make things less confusing. + Target* pSys; + targetService().getTopLevelTarget(pSys); + auto l_risk = pSys->getAttr<TARGETING::ATTR_RISK_LEVEL>(); + if( TARGETING::UTIL::P9A_RUGBY_FAVOR_SECURITY_LOWER == l_risk ) + { + l_risk = TARGETING::UTIL::P9A_RUGBY_FAVOR_SECURITY; + } + else if( TARGETING::UTIL::P9A_RUGBY_FAVOR_PERFORMANCE_LOWER == l_risk ) + { + l_risk = TARGETING::UTIL::P9A_RUGBY_FAVOR_PERFORMANCE; + } + else + { + // Nothing to change, just leave + return; + } + pSys->setAttr<TARGETING::ATTR_RISK_LEVEL>(l_risk); +} + errlHndl_t validateProcessorEcLevels() { HWAS_INF("validateProcessorEcLevels entry"); @@ -4109,6 +4211,12 @@ errlHndl_t validateProcessorEcLevels() break; } } + else if(TARGETING::MODEL_AXONE == l_model) + { + // Axone follows Nimbus DD2.3 settings except it can use + // the low or high numbers, going to force one way. + normalizeRiskLevelForAxone(); + } //Loop through all functional procs and create error logs //for any processors whose EC does not match the master diff --git a/src/usr/hwas/common/pgLogic.C b/src/usr/hwas/common/pgLogic.C index 2cc30944f..cd0aa9b19 100644 --- a/src/usr/hwas/common/pgLogic.C +++ b/src/usr/hwas/common/pgLogic.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2018 */ +/* Contributors Listed Below - COPYRIGHT 2018,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -31,6 +31,7 @@ #include <hwas/common/hwasError.H> using namespace HWAS::COMMON; +using namespace HWAS; //needed for trace macros namespace PARTIAL_GOOD { @@ -134,6 +135,7 @@ namespace PARTIAL_GOOD // MC // PG/AG Masks const uint16_t MC_R1_AG_MASK = 0xE0FD; + const uint16_t MC_R1_AG_MASK_AXONE = 0xE03D; const uint16_t MC_R2_PG_MASK = 0x0040; const uint16_t MC_R3_PG_MASK = 0x0020; @@ -257,6 +259,9 @@ namespace PARTIAL_GOOD if (rulesIterator == pgRules_map.end()) { + HWAS_ERR( "No rules found for type %d", + i_target->getAttr<TARGETING::ATTR_TYPE>() ); + // Target is missing from the table. This is an error, so break // out of this section of code and return the appropriate error // below. @@ -344,6 +349,12 @@ namespace PARTIAL_GOOD // the following error if applicable. if ((l_errl == nullptr) && (o_targetPgLogic.size() == 0)) { + HWAS_ERR( "No rule found for Target %.8X of type %d", + get_huid(i_target), + i_target->getAttr<TARGETING::ATTR_TYPE>() ); + uint64_t userdata1 = static_cast<uint64_t>(i_target->getAttr<TARGETING::ATTR_TYPE>()); + userdata1 <<= 32; + userdata1 |= static_cast<uint64_t>(get_huid(i_target)); /*@ * @errortype * @severity ERRL_SEV_UNRECOVERABLE @@ -358,15 +369,16 @@ namespace PARTIAL_GOOD * * @custdesc A problem occured during IPL of the system: * Internal Firmware Error - * @userdata1 target type attribute - * @userdata2 HUID of the target + * @userdata1[00:31] target type attribute + * @userdata1[32:63] HUID of the target + * @userdata2 Number of rules for this target type */ l_errl = hwasError( ERRL_SEV_UNRECOVERABLE, HWAS::MOD_FIND_RULES_FOR_TARGET, HWAS::RC_NO_PG_LOGIC, - i_target->getAttr<TARGETING::ATTR_TYPE>(), - get_huid(i_target)); + userdata1, + pgRules_map.size()); } return l_errl; @@ -481,8 +493,7 @@ namespace PARTIAL_GOOD != TARGETING::OPTICS_CONFIG_MODE_SMP) && ((i_pgData[N3_PG_INDEX] & NPU_R1_PG_MASK) != ALL_OFF_AG_MASK)) { - TRACFCOMP(HWAS::g_trac_imp_hwas, - "pDesc 0x%.8X - OBUS_BRICK pgData[%d]: " + HWAS_INF( "pDesc 0x%.8X - OBUS_BRICK pgData[%d]: " "actual 0x%04X, expected 0x%04X - bad", i_desc->getAttr<TARGETING::ATTR_HUID>(), N3_PG_INDEX, diff --git a/src/usr/hwas/hwasPlat.C b/src/usr/hwas/hwasPlat.C index bea5b4d8f..1cea60415 100644 --- a/src/usr/hwas/hwasPlat.C +++ b/src/usr/hwas/hwasPlat.C @@ -43,13 +43,16 @@ #include <sys/misc.h> #include <pnor/pnorif.H> +#include <fapiwrap/fapiWrapif.H> #include <hwas/common/hwas_reasoncodes.H> #include <targeting/common/utilFilter.H> #include <fsi/fsiif.H> -#include <config.h> #include <targeting/common/targetservice.H> #include <chipids.H> +#include <vpd/spdenums.H> + +#include <map> #ifdef CONFIG_SUPPORT_EEPROM_CACHING #include <i2c/eepromif.H> @@ -85,13 +88,19 @@ errlHndl_t platReadIDEC(const TargetHandle_t &i_target) // Call over to the target-specific layer since every chip can have // unique registers size_t sz = 0; - errlHndl_t l_errl = - DeviceFW::deviceWrite(i_target, - nullptr, - sz, - DEVICE_IDEC_ADDRESS()); + errlHndl_t errl = nullptr; - return l_errl; + // Pass a 1 as va_arg to signal phase 1 of ocmbIDEC to execute. + // Other IDEC functions will ignore this argument. + const uint64_t Phase1 = 1; + errl = DeviceFW::deviceWrite(i_target, + nullptr, + sz, + DEVICE_IDEC_ADDRESS(), + Phase1); + + + return errl; } /** @@ -234,6 +243,70 @@ DEVICE_REGISTER_ROUTE(DeviceFW::WRITE, TARGETING::TYPE_MEMBUF, cfamIDEC); +/** + * @brief During early IPL the OCMB isn't able to be read from so this function, + * executed during discover targets, will read from the SPD and set the + * CHIP_ID, EC, and HDAT_EC attributes with what is found there. + * + * @param[in] i_target Presence detect target + * + * @return errlHndl_t An error log if reading from the SPD failed. + * Otherwise, other errors are predictive and + * committed. So nullptr will be returned in those + * cases and on success. + */ +errlHndl_t ocmbIdecPhase1(const TARGETING::TargetHandle_t& i_target); + +/** + * @brief Once the OCMB is able to be read from the second phase will execute + * and cross-check the data given from the SPD is consistent with what + * was read from the chip itself. If the data is not consistent then the + * CHIP_ID, EC, and HDAT_EC attributes will be updated with what was + * found from the OCMB read since that data would be correct. + * + * @param[in] i_target Presence detect target + * + * @return errlHndl_t An error log if reading from the OCMB ID/EC + * register failed. Otherwise, other errors are + * predictive and committed. So nullptr will be + * returned in those cases and on success. + */ +errlHndl_t ocmbIdecPhase2(const TARGETING::TargetHandle_t& i_target); + +/** + * @brief Read the chipid and EC/DD-level for OCMB chips and set the attributes. + * In this function there are two phases that are executed at different + * times during IPL. The OCMB is held in reset and unable to be read from + * during early IPL. So the first phase, executed during discover + * targets, will read from the SPD and set the attributes with what is + * found there. Once the OCMB is able to be read from the second phase + * will execute and cross-check the data given from the SPD is consistent + * with what was read from the chip itself. If the data is not consistent + * then the attributes will be updated with what was found from the OCMB + * read since that data would be correct. + * + * @param[in] i_opType Operation type, see DeviceFW::OperationType + * in driverif.H + * + * @param[in] i_target Presence detect target + * + * @param[in/out] io_buffer Unused by this function + * + * @param[in/out] io_buflen Unused by this function + * + * @param[in] i_accessType DeviceFW::AccessType enum (userif.H) + * + * @param[in] i_args This is an argument list for DD framework. + * In this function, there is one argument to + * signal which phase to execute. + * + * @return errlHndl_t If there is an issue while reading from the SPD + * or the OCMB chip, or an unexpected memory + * interface type then this function will return an + * error. Otherwise, all other errors are + * predictive and committed. So nullptr will be + * returned in that case or on success. + */ errlHndl_t ocmbIDEC(DeviceFW::OperationType i_opType, TARGETING::Target* i_target, void* io_buffer, @@ -241,16 +314,456 @@ errlHndl_t ocmbIDEC(DeviceFW::OperationType i_opType, int64_t i_accessType, va_list i_args) { - // for now just hardcode the answer to something explicitly invalid - uint8_t l_ec = INVALID__ATTR_EC; - i_target->setAttr<TARGETING::ATTR_EC>(l_ec); - i_target->setAttr<TARGETING::ATTR_HDAT_EC>(l_ec); + errlHndl_t error = nullptr; + + // Determine which phase of this function to run. + uint64_t phase = va_arg(i_args, uint64_t); + + // Execute the correct phase based on the va_arg given. + if (phase == 1) + { + error = ocmbIdecPhase1(i_target); + } + else + { + error = ocmbIdecPhase2(i_target); + } + + + return error; +} + +/** + * @brief This is a small helper function that the ocmb IDEC functions use to + * add all the proper callouts and commit errorlogs. + * + * @param[in] i_target Presence detect target + * + * @param[in] io_error The error log to be committed + * + */ +void ocmbErrlCommit(const TARGETING::TargetHandle_t& i_target, + errlHndl_t& io_error) +{ + io_error->addHwCallout(i_target, + SRCI_PRIORITY_HIGH, + NO_DECONFIG, + GARD_NULL); + + io_error->addPartCallout(i_target, + VPD_PART_TYPE, + SRCI_PRIORITY_MED, + NO_DECONFIG, + GARD_NULL); + + io_error->addProcedureCallout(EPUB_PRC_HB_CODE, + SRCI_PRIORITY_LOW); - // we can assume this is an Explorer chip though - uint32_t l_id = POWER_CHIPID::EXPLORER_16; - i_target->setAttr<TARGETING::ATTR_CHIP_ID>(l_id); + ERRORLOG::errlCommit(io_error, HWAS_COMP_ID); + +} + +/** + * @brief This helper function will lookup the chip id and ec levels of + * a given OCMB based on what is found in a provided SPD buffer. + * The target is passed along for trace information. + * + * @param[in] i_target OCMB target we are looking up IDEC for + * + * @param[in] i_spdBuffer Buffer of at least SPD::OCMB_SPD_EFD_COMBINED_SIZE + * bytes of the given OCMB's SPD + * + * @param[out] o_chipId Chip Id associated with the given OCMB + * (see src/import/chips/common/utils/chipids.H) + * + * @param[out] o_ec EC level associated with the given OCMB + * + * @return nullptr if success, error log otherwise + * + */ +errlHndl_t getOcmbIdecFromSpd(const TARGETING::TargetHandle_t& i_target, + uint8_t * i_spdBuffer, + uint16_t& o_chipId, + uint8_t& o_ec) +{ + errlHndl_t l_errl = nullptr; + // These bytes are used for FFDC and verification purposes. + const size_t SPD_REVISION_OFFSET = 1; + const size_t DRAM_INTERFACE_TYPE_OFFSET = 2; + const size_t MEMORY_MODULE_INTERFACE_TYPE_OFFSET = 3; + + // This is the value that signifies the SPD we read is for a DDIMM. + const uint8_t DDIMM_MEMORY_INTERFACE_TYPE = 0x0A; + + const uint8_t l_spdModuleRevision = + *(i_spdBuffer + SPD_REVISION_OFFSET); + + const uint8_t l_spdDRAMInterfaceType = + *(i_spdBuffer + DRAM_INTERFACE_TYPE_OFFSET); + + const uint8_t l_spdMemoryInterfaceType = + *(i_spdBuffer + MEMORY_MODULE_INTERFACE_TYPE_OFFSET); + + // Byte 1 SPD Module Revision + // Byte 2 DRAM Interface Type Presented or Emulated + // Byte 3 Memory Module Interface Type + const uint32_t SPD_FFDC_BYTES = TWO_UINT16_TO_UINT32( + TWO_UINT8_TO_UINT16(l_spdModuleRevision, l_spdDRAMInterfaceType), + TWO_UINT8_TO_UINT16(l_spdMemoryInterfaceType, 0)); + + do{ + + // Since the byte offsets used to get the IDEC info out of the SPD are + // specific to the DDIMM interface type we must first verify that we + // read from an SPD of that type. + if (DDIMM_MEMORY_INTERFACE_TYPE != l_spdMemoryInterfaceType) + { + HWAS_ERR("getOcmbIdecFromSpd> memory module interface type " + "didn't match the expected type. " + "Expected 0x%.2X, Actual 0x%.2X", + DDIMM_MEMORY_INTERFACE_TYPE, + l_spdMemoryInterfaceType); + + /*@ + * @errortype + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid MOD_OCMB_IDEC + * @reasoncode RC_OCMB_INTERFACE_TYPE_MISMATCH + * @userdata1[0:7] SPD Module Revision + * @userdata1[8:15] DRAM Interface Type Presented or Emulated + * @userdata1[16:23] Memory Module Interface Type + * @userdata1[24:31] Unused + * @userdata1[32:63] Expected memory interface type + * @userdata2 HUID of OCMB target + * @devdesc The memory interface type read from the SPD did + * not match the DDIMM value. Setting the + * appropriate IDEC values for this target cannot + * continue. + * @custdesc Invalid or unsupported memory card installed. + */ + l_errl = hwasError(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + MOD_OCMB_IDEC, + RC_OCMB_INTERFACE_TYPE_MISMATCH, + TWO_UINT32_TO_UINT64(SPD_FFDC_BYTES, + DDIMM_MEMORY_INTERFACE_TYPE), + TARGETING::get_huid(i_target)); + + l_errl->addProcedureCallout(EPUB_PRC_HB_CODE, + SRCI_PRIORITY_LOW); + + l_errl->addHwCallout(i_target, + SRCI_PRIORITY_HIGH, + NO_DECONFIG, + GARD_NULL); + + + break; + } + + // SPD IDEC info is in the following three bytes + const size_t SPD_ID_LEAST_SIGNIFICANT_BYTE_OFFSET = 198; + const size_t SPD_ID_MOST_SIGNIFICANT_BYTE_OFFSET = 199; + const size_t DMB_REV_OFFSET = 200; + + // Get the ID from the SPD and verify that it matches what we read from + // the IDEC register. + uint16_t l_spdId = TWO_UINT8_TO_UINT16( + *(i_spdBuffer + SPD_ID_LEAST_SIGNIFICANT_BYTE_OFFSET), + *(i_spdBuffer + SPD_ID_MOST_SIGNIFICANT_BYTE_OFFSET)); + + // Bytes 200 of the SPD contains the DMB Revision, this is essentially the + // OCMB manufacture's version of the chip. The manufacture can define any + // format for this field and we must add special logic to convert the + // manufacture's DMB_REV to the EC level IBM is familiar with. + uint8_t l_spdDmbRev = *(i_spdBuffer + DMB_REV_OFFSET); + + HWAS_INF("getOcmbIdecFromSpd> OCMB 0x%.8x l_spdId = 0x%.4X l_spdDmbRev = 0x%.2x", + TARGETING::get_huid(i_target), l_spdId, l_spdDmbRev); + + if (DDIMM_DMB_ID::EXPLORER == l_spdId) + { + o_chipId = POWER_CHIPID::EXPLORER_16; + // Must convert Explorer's versioning into IBM-style EC levels. + // Explorer vendor has stated versioning will start at 0xA0 and increment + // 1st nibble for major revisions and 2nd nibble by 1 for minor revisions + // Examples : + // Version 0xA0 = EC 0x10 + // Version 0xA1 = EC 0x11 + // Version 0xB2 = EC 0x22 + + // Resulting formula from pattern in examples above is as follows: + o_ec = (l_spdDmbRev - 0x90); + } + else if (DDIMM_DMB_ID::GEMINI == l_spdId) + { + o_chipId = POWER_CHIPID::GEMINI_16; + + HWAS_ASSERT(l_spdDmbRev == 0x0, + "Invalid Gemini DMB Revision Number, expected to find 0x0 at byte 200 in Gemini SPD"); + + // 0x10 is the only valid EC level for Gemini cards. If we find 0x0 @ byte 200 in + // the Gemini SPD then we will return 0x10 as the EC level + o_ec = 0x10; + } + else + { + HWAS_ERR("getOcmbIdecFromSpd> Unknown OCMB chip type discovered in SPD " + "ID=0x%.4X OCMB HUID 0x%.8x", + l_spdId, + TARGETING::get_huid(i_target)); + + /*@ + * @errortype + * @severity ERRL_SEV_PREDICTIVE + * @moduleid MOD_OCMB_IDEC + * @reasoncode RC_OCMB_UNKNOWN_CHIP_TYPE + * @userdata1[0:7] SPD Module Revision + * @userdata1[8:15] DRAM Interface Type Presented or Emulated + * @userdata1[16:23] Memory Module Interface Type + * @userdata1[24:31] Unused + * @userdata1[32:63] SPD Chip Id + * @userdata2 HUID of OCMB target + * @devdesc The ID read from the SPD didn't match any known + * OCMB chip types. + * @custdesc Unsupported memory installed. + */ + l_errl = hwasError(ERRORLOG::ERRL_SEV_PREDICTIVE, + MOD_OCMB_IDEC_PHASE_1, + RC_OCMB_UNKNOWN_CHIP_TYPE, + TWO_UINT32_TO_UINT64(SPD_FFDC_BYTES, l_spdId), + TARGETING::get_huid(i_target)); + + break; + } + + }while(0); + + return l_errl; + +} + + +errlHndl_t ocmbIdecPhase1(const TARGETING::TargetHandle_t& i_target) +{ + errlHndl_t l_errl = nullptr; + + // Allocate buffer to hold SPD and init to 0 + size_t l_spdBufferSize = SPD::DDIMM_DDR4_SPD_SIZE; + uint8_t* l_spdBuffer = new uint8_t[l_spdBufferSize]; + memset(l_spdBuffer, 0, l_spdBufferSize); + uint16_t l_chipId = 0; + uint8_t l_chipEc = 0; + + do { + + // Read the SPD off the ocmb but skip reading the EFD to save time. + l_errl = deviceRead(i_target, + l_spdBuffer, + l_spdBufferSize, + DEVICE_SPD_ADDRESS(SPD::ENTIRE_SPD_WITHOUT_EFD)); + + // If unable to retrieve the SPD buffer then can't + // extract the IDEC data, so return error. + if (l_errl != nullptr) + { + HWAS_ERR("ocmbIdecPhase1> Error while trying to read " + "ENTIRE SPD from 0x%.08X ", + TARGETING::get_huid(i_target)); + break; + } + + // Make sure we got back the size we were expecting. + assert(l_spdBufferSize == SPD::DDIMM_DDR4_SPD_SIZE, + "ocmbIdecPhase1> OCMB SPD read size %d " + "doesn't match the expected size %d", + l_spdBufferSize, + SPD::DDIMM_DDR4_SPD_SIZE); + + l_errl = getOcmbIdecFromSpd(i_target, + l_spdBuffer, + l_chipId, + l_chipEc); + + // If we were unable to read the IDEC information from the SPD + // then break out early and do not set the associated attributes + if (l_errl != nullptr) + { + HWAS_ERR("ocmbIdecPhase1> Error while trying to parse " + "chip id and ec values from SPD read from OCMB 0x%.08X ", + TARGETING::get_huid(i_target)); + break; + } + + HWAS_INF("ocmbIdecPhase1> Read Chip ID = 0x%x Chip EC = 0x%x from target 0x%.08X", + l_chipId, l_chipEc, TARGETING::get_huid(i_target) ); + + // set the explorer chip EC attributes. + i_target->setAttr<TARGETING::ATTR_EC>(l_chipEc); + i_target->setAttr<TARGETING::ATTR_HDAT_EC>(l_chipEc); + + // set the explorer chip id attribute. + i_target->setAttr<TARGETING::ATTR_CHIP_ID>(l_chipId); + + } while(0); + + delete[] l_spdBuffer; + return l_errl; + +} + +errlHndl_t ocmbIdecPhase2(const TARGETING::TargetHandle_t& i_target) +{ + const uint32_t GEM_IDEC_SCOM_REGISTER = 0x0801240e; + const TARGETING::ATTR_CHIP_ID_type l_chipIdFromSpd = + i_target->getAttr<TARGETING::ATTR_CHIP_ID>(); + + errlHndl_t l_errl = nullptr; + uint64_t l_idec = 0; + size_t l_op_size = sizeof(l_idec); + uint8_t l_ec = 0; + uint16_t l_id = 0; + + do { + + if(l_chipIdFromSpd == POWER_CHIPID::EXPLORER_16) + { + // Call platform independent lookup for Explorer OCMBs + l_errl = FAPIWRAP::explorer_getidec(i_target, l_id, l_ec); + + if (l_errl != nullptr) + { + HWAS_ERR("ocmbIdecPhase2> explorer OCMB 0x%.8X - failed to read ID/EC", + TARGETING::get_huid(i_target)); + + break; + } + } + else + { + // read the register containing IDEC info on Gemini OCMBs + l_errl = DeviceFW::deviceRead(i_target, + &l_idec, + l_op_size, + DEVICE_SCOM_ADDRESS(GEM_IDEC_SCOM_REGISTER)); + + if (l_errl != nullptr) + { + HWAS_ERR("ocmbIdecPhase2> gemini OCMB 0x%.8X - failed to read ID/EC", + TARGETING::get_huid(i_target)); + + break; + } + + // Need to convert Gemini's IDEC register from MmL000CC + // to cfam standard format MLmCC000 + uint32_t l_major = 0xF0000000 & static_cast<uint32_t>(l_idec); + uint32_t l_minor = 0x0F000000 & static_cast<uint32_t>(l_idec); + uint32_t l_location = 0x00F00000 & static_cast<uint32_t>(l_idec); + l_idec = (l_major | (l_location << 4) | (l_minor >> 4) + | ((l_idec & 0x000000FF) << 12)); + // Parse out the information we need + l_ec = POWER_CHIPID::extract_ddlevel(l_idec); + l_id = POWER_CHIPID::extract_chipid16(l_idec); + } + + HWAS_INF("ocmbIdecPhase2> OCMB 0x%.8X - read ID/EC successful. " + "ID = 0x%.4X, EC = 0x%.2X, Full IDEC 0x%x", + TARGETING::get_huid(i_target), + l_id, + l_ec, + l_idec); + + if (l_id != l_chipIdFromSpd) + { + HWAS_ERR("ocmbIdecPhase2> OCMB Chip Id and associated SPD Chip Id " + "don't match: OCMB ID=0x%.4X; SPD ID=0x%.4X;", + l_id, + l_chipIdFromSpd); + + HWAS_ERR("ocmbIdecPhase2> Previous CHIP_ID 0x%.4X was set based on values from " + "SPD read will now be overwritten with values from OCMB IDEC register " + "ID=0x%.4X", + l_chipIdFromSpd, + l_id); + /*@ + * @errortype + * @severity ERRL_SEV_PREDICTIVE + * @moduleid MOD_OCMB_IDEC + * @reasoncode RC_OCMB_CHIP_ID_MISMATCH + * @userdata1[00:31] OCMB IDEC Register ID + * @userdata1[32:63] IDEC ID found in OCMB's SPD + * @userdata2[32:63] HUID of OCMB target + * @devdesc The IDEC info read from the OCMB and SPD + * did not match the expected values. + * @custdesc Firmware Error + */ + l_errl = hwasError(ERRORLOG::ERRL_SEV_PREDICTIVE, + MOD_OCMB_IDEC, + RC_OCMB_CHIP_ID_MISMATCH, + TWO_UINT32_TO_UINT64(l_id, l_chipIdFromSpd), + TARGETING::get_huid(i_target)); + + // Add callouts and commit + ocmbErrlCommit(i_target, l_errl); + + // Since there was an error then the ID values don't agree between + // the OCMB read and the SPD read. Since the OCMB has the correct + // answer, set the attributes to the values read from that instead + // of the SPD. + i_target->setAttr<TARGETING::ATTR_CHIP_ID>(l_id); + } + + const uint8_t l_ecFromSpd = i_target->getAttr<TARGETING::ATTR_EC>(); + + if (l_ec != l_ecFromSpd) + { + HWAS_ERR("ocmbIdecPhase2> OCMB Revision and associated SPD " + "Revision don't match: OCMB EC=0x%.2X; " + "SPD EC=0x%.2X; ", + l_ec, l_ecFromSpd); + + HWAS_ERR("ocmbIdecPhase2> Previous EC and HDAT_EC attributes 0x%.2X," + " which were set with values found in SPD will be overwritten" + " with value from OCMB IDEC register ID=0x%.2X", + l_ecFromSpd, + l_ec); + + /*@ + * @errortype + * @severity ERRL_SEV_PREDICTIVE + * @moduleid MOD_OCMB_IDEC + * @reasoncode RC_OCMB_SPD_REVISION_MISMATCH + * @userdata1[00:31] OCMB IDEC register EC + * @userdata1[32:63] EC found in OCMB's SPD + * @userdata2[00:31] OCMB Chip ID Attribute + * @userdata2[32:63] HUID of OCMB target + * @devdesc The EC (Revision) info read from the OCMB and + * SPD did not match the expected values. + * @custdesc Firmware Error + */ + l_errl = hwasError(ERRORLOG::ERRL_SEV_PREDICTIVE, + MOD_OCMB_IDEC, + RC_OCMB_SPD_REVISION_MISMATCH, + TWO_UINT32_TO_UINT64(l_ec, l_ecFromSpd), + TWO_UINT32_TO_UINT64( + i_target->getAttr<TARGETING::ATTR_CHIP_ID>(), + TARGETING::get_huid(i_target))); + + // Add callouts and commit + ocmbErrlCommit(i_target, l_errl); + + // Since there was an error then the EC values don't agree between + // the OCMB read and the SPD read. Since the OCMB has the correct + // answer, set the attributes to the values read from that instead + // of the SPD. + i_target->setAttr<TARGETING::ATTR_EC>(l_ec); + i_target->setAttr<TARGETING::ATTR_HDAT_EC>(l_ec); + } + + } while(0); + + return l_errl; - return nullptr; } // Register the presence detect function with the device framework @@ -628,7 +1141,10 @@ errlHndl_t platPresenceDetect(TargetHandleList &io_targets) DEVICE_CACHE_EEPROM_ADDRESS(present, EEPROM::VPD_PRIMARY)); errl = deviceRead(pTarget, &present, presentSize, DEVICE_CACHE_EEPROM_ADDRESS(present, EEPROM::VPD_PRIMARY)); - errlCommit(errl, HWAS_COMP_ID); + if( errl ) + { + errlCommit(errl, HWAS_COMP_ID); + } // errl is now null, move on to next target } #endif diff --git a/src/usr/hwas/hwasPlatDeconfigGard.C b/src/usr/hwas/hwasPlatDeconfigGard.C index 0bdbb4c24..3f5a461eb 100644 --- a/src/usr/hwas/hwasPlatDeconfigGard.C +++ b/src/usr/hwas/hwasPlatDeconfigGard.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2018 */ +/* Contributors Listed Below - COPYRIGHT 2013,2019 */ /* [+] Google Inc. */ /* [+] International Business Machines Corp. */ /* */ @@ -41,7 +41,6 @@ #include <vpd/mvpdenums.H> #include <stdio.h> #include <sys/mm.h> -#include <config.h> #include <initservice/istepdispatcherif.H> #include <initservice/initserviceif.H> diff --git a/src/usr/hwas/test/hwas1test.H b/src/usr/hwas/test/hwas1test.H index 6784d4408..306fea006 100644 --- a/src/usr/hwas/test/hwas1test.H +++ b/src/usr/hwas/test/hwas1test.H @@ -48,8 +48,74 @@ #include <targeting/common/commontargeting.H> #include <targeting/common/utilFilter.H> +const uint16_t pgDataAllGoodAxone[HWAS::VPD_CP00_PG_DATA_ENTRIES] = + {(uint16_t)HWAS::VPD_CP00_PG_FSI_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_PERVASIVE_GOOD_AXONE, + (uint16_t)HWAS::VPD_CP00_PG_N0_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_N1_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_N2_GOOD_AXONE, + (uint16_t)HWAS::VPD_CP00_PG_N3_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_XBUS_GOOD_CUMULUS, + (uint16_t)HWAS::VPD_CP00_PG_MCxx_GOOD_AXONE, + (uint16_t)HWAS::VPD_CP00_PG_MCxx_GOOD_AXONE, + (uint16_t)HWAS::VPD_CP00_PG_OBUS_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_OBUS_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_OBUS_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_OBUS_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_PCIx_GOOD[0], + (uint16_t)HWAS::VPD_CP00_PG_PCIx_GOOD[1], + (uint16_t)HWAS::VPD_CP00_PG_PCIx_GOOD[2], + (uint16_t)HWAS::VPD_CP00_PG_EPx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_EPx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_EPx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_EPx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_EPx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_EPx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD, + (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD}; + // Buffer with all good data (CUMULUS chip) -const uint16_t pgDataAllGood[HWAS::VPD_CP00_PG_DATA_ENTRIES] = +const uint16_t pgDataAllGoodCumulus[HWAS::VPD_CP00_PG_DATA_ENTRIES] = {(uint16_t)HWAS::VPD_CP00_PG_FSI_GOOD, (uint16_t)HWAS::VPD_CP00_PG_PERVASIVE_GOOD, (uint16_t)HWAS::VPD_CP00_PG_N0_GOOD, @@ -371,9 +437,20 @@ public: ? (uint16_t)VPD_CP00_PG_RESERVED_GOOD : (uint16_t)VPD_CP00_PG_OBUS_GOOD; uint16_t pgData[VPD_CP00_PG_DATA_ENTRIES]; - memcpy(pgData, - pgDataAllGood, - VPD_CP00_PG_DATA_LENGTH); + + if(MODEL_AXONE == l_model) + { + memcpy(pgData, + pgDataAllGoodAxone, + VPD_CP00_PG_DATA_LENGTH); + } + else + { + memcpy(pgData, + pgDataAllGoodCumulus, + VPD_CP00_PG_DATA_LENGTH); + } + pgData[VPD_CP00_PG_XBUS_INDEX] = l_xbus; pgData[VPD_CP00_PG_OB0_INDEX + 1] = l_obus12; pgData[VPD_CP00_PG_OB0_INDEX + 2] = l_obus12; @@ -460,9 +537,18 @@ public: l_mask); } - // Restore the "all good" data - pgData[VPD_CP00_PG_PERVASIVE_INDEX] = - (uint16_t)VPD_CP00_PG_PERVASIVE_GOOD; + if(MODEL_AXONE == l_model) + { + // Restore the "all good" data + pgData[VPD_CP00_PG_PERVASIVE_INDEX] = + (uint16_t)VPD_CP00_PG_PERVASIVE_GOOD_AXONE; + } + else + { + // Restore the "all good" data + pgData[VPD_CP00_PG_PERVASIVE_INDEX] = + (uint16_t)VPD_CP00_PG_PERVASIVE_GOOD; + } } TS_INFO( "testHWASisChipFunctional: N0 is not functional"); @@ -562,6 +648,19 @@ public: // Restore the "all good" data pgData[VPD_CP00_PG_N2_INDEX] = (uint16_t)VPD_CP00_PG_N2_GOOD; + + if(MODEL_AXONE == l_model) + { + // Restore the "all good" data + pgData[VPD_CP00_PG_N2_INDEX] = + (uint16_t)VPD_CP00_PG_N2_GOOD_AXONE; + } + else + { + // Restore the "all good" data + pgData[VPD_CP00_PG_N2_INDEX] = + (uint16_t)VPD_CP00_PG_N2_GOOD; + } } TS_INFO( "testHWASisChipFunctional: N3 is not functional"); @@ -686,9 +785,20 @@ public: ? (uint16_t)VPD_CP00_PG_RESERVED_GOOD : (uint16_t)VPD_CP00_PG_OBUS_GOOD; uint16_t pgData[VPD_CP00_PG_DATA_ENTRIES]; - memcpy(pgData, - pgDataAllGood, - VPD_CP00_PG_DATA_LENGTH); + + if(MODEL_AXONE == l_model) + { + memcpy(pgData, + pgDataAllGoodAxone, + VPD_CP00_PG_DATA_LENGTH); + } + else + { + memcpy(pgData, + pgDataAllGoodCumulus, + VPD_CP00_PG_DATA_LENGTH); + } + pgData[VPD_CP00_PG_XBUS_INDEX] = l_xbus; pgData[VPD_CP00_PG_OB0_INDEX + 1] = l_obus12; pgData[VPD_CP00_PG_OB0_INDEX + 2] = l_obus12; @@ -1107,9 +1217,19 @@ public: pDesc->getAttr<ATTR_HUID>()); } - // Restore the "all good" data - pgData[l_indexMC] = VPD_CP00_PG_MCxx_GOOD; + if(MODEL_AXONE == l_model) + { + // Restore the "all good" data + pgData[l_indexMC] = + (uint16_t)VPD_CP00_PG_MCxx_GOOD_AXONE; + } + else + { + // Restore the "all good" data + pgData[l_indexMC] = + (uint16_t)VPD_CP00_PG_MCxx_GOOD; + } } break; @@ -1208,8 +1328,18 @@ public: pDesc->getAttr<ATTR_HUID>()); } - // Restore the "all good" data - pgData[l_indexMC] = VPD_CP00_PG_MCxx_GOOD; + if(MODEL_AXONE == l_model) + { + // Restore the "all good" data + pgData[l_indexMC] = + (uint16_t)VPD_CP00_PG_MCxx_GOOD_AXONE; + } + else + { + // Restore the "all good" data + pgData[l_indexMC] = + (uint16_t)VPD_CP00_PG_MCxx_GOOD; + } } break; @@ -1307,8 +1437,18 @@ public: pDesc->getAttr<ATTR_HUID>()); } - // Restore the "all good" data - pgData[l_indexMC] = VPD_CP00_PG_MCxx_GOOD; + if(MODEL_AXONE == l_model) + { + // Restore the "all good" data + pgData[l_indexMC] = + (uint16_t)VPD_CP00_PG_MCxx_GOOD_AXONE; + } + else + { + // Restore the "all good" data + pgData[l_indexMC] = + (uint16_t)VPD_CP00_PG_MCxx_GOOD; + } } break; @@ -1406,8 +1546,18 @@ public: pDesc->getAttr<ATTR_HUID>()); } - // Restore the "all good" data - pgData[l_indexMC] = VPD_CP00_PG_MCxx_GOOD; + if(MODEL_AXONE == l_model) + { + // Restore the "all good" data + pgData[l_indexMC] = + (uint16_t)VPD_CP00_PG_MCxx_GOOD_AXONE; + } + else + { + // Restore the "all good" data + pgData[l_indexMC] = + (uint16_t)VPD_CP00_PG_MCxx_GOOD; + } } break; @@ -1506,8 +1656,18 @@ public: pDesc->getAttr<ATTR_HUID>()); } - // Restore the "all good" data - pgData[l_indexMC] = VPD_CP00_PG_MCxx_GOOD; + if(MODEL_AXONE == l_model) + { + // Restore the "all good" data + pgData[l_indexMC] = + (uint16_t)VPD_CP00_PG_MCxx_GOOD_AXONE; + } + else + { + // Restore the "all good" data + pgData[l_indexMC] = + (uint16_t)VPD_CP00_PG_MCxx_GOOD; + } } break; @@ -1871,9 +2031,18 @@ public: pDesc->getAttr<ATTR_HUID>()); } - // Restore the "all good" data - pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit * 2]] = - (uint16_t)VPD_CP00_PG_MCxx_GOOD; + if(MODEL_AXONE == l_model) + { + // Restore the "all good" data + pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit * 2]] = + (uint16_t)VPD_CP00_PG_MCxx_GOOD_AXONE; + } + else + { + // Restore the "all good" data + pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit * 2]] = + (uint16_t)VPD_CP00_PG_MCxx_GOOD; + } } @@ -1987,9 +2156,18 @@ public: pDesc->getAttr<ATTR_HUID>()); } - // Restore the "all good" data - pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit]] = - (uint16_t)VPD_CP00_PG_MCxx_GOOD; + if(MODEL_AXONE == l_model) + { + // Restore the "all good" data + pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit]] = + (uint16_t)VPD_CP00_PG_MCxx_GOOD_AXONE; + } + else + { + // Restore the "all good" data + pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit]] = + (uint16_t)VPD_CP00_PG_MCxx_GOOD; + } } // TEST WITH BAD MAGIC PORT (MCA0 or MCA4) @@ -2038,8 +2216,18 @@ public: pDesc->getAttr<ATTR_HUID>()); } - pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit / 2]] = - (uint16_t)VPD_CP00_PG_MCxx_GOOD; + if(MODEL_AXONE == l_model) + { + // Restore the "all good" data + pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit / 2]] = + (uint16_t)VPD_CP00_PG_MCxx_GOOD_AXONE; + } + else + { + // Restore the "all good" data + pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit / 2]] = + (uint16_t)VPD_CP00_PG_MCxx_GOOD; + } // Try bad MCA Port setting for MCA2/3 & MCA6/7 if ( VPD_CP00_PG_MCxx_IOMyy[l_chipUnit / 2] != @@ -2147,14 +2335,26 @@ public: } // Restore the "all good" data - pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit * 2]] = - (uint16_t)VPD_CP00_PG_MCxx_GOOD; + if(MODEL_AXONE == l_model) + { + // Restore the "all good" data + pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit * 2]] = + (uint16_t)VPD_CP00_PG_MCxx_GOOD_AXONE; + } + else + { + // Restore the "all good" data + pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit * 2]] = + (uint16_t)VPD_CP00_PG_MCxx_GOOD; + } + } break; case TYPE_OBUS_BRICK: { +#ifndef CONFIG_AXONE //@todo-RTC:208518 - Add Axone OBUS_BRICK rules //Two cases here: //OBUS==SMP --> Target should be present regardless // of PG @@ -2186,7 +2386,7 @@ public: TS_FAIL("testHWAS" "checkPartialGoodForDescendants> " "functional = 0x%x, should be true " - "because" + "because " "OBUS_BRICK is SMP: PG = 0x%04x. " "pDesc HUID 0x%.8x", checkPartialGoodForDescendants( @@ -2211,7 +2411,7 @@ public: TS_FAIL("testHWAS" "checkPartialGoodForDescendants> " "functional = 0x%x, should be " - "false because" + "false because " "OBUS_BRICK is NVLINK: PG = " "0x%04x. " "pDesc HUID 0x%.8x", @@ -2227,10 +2427,12 @@ public: pgData[VPD_CP00_PG_N3_INDEX] = (uint16_t)VPD_CP00_PG_N3_GOOD; +#endif break; } case TYPE_NPU: +#ifndef CONFIG_AXONE //@todo-RTC:208518 - Add Axone NPU rules TS_INFO( "testHWAScheckPartialGoodForDescendants: " "NPU is not functional"); pgData[VPD_CP00_PG_N3_INDEX] |= @@ -2250,6 +2452,7 @@ public: pgData[VPD_CP00_PG_N3_INDEX] = (uint16_t)VPD_CP00_PG_N3_GOOD; +#endif break; case TYPE_PERV: diff --git a/src/usr/hwas/test/hwasGardTest.H b/src/usr/hwas/test/hwasGardTest.H index 01c8d1735..1edc8a445 100644 --- a/src/usr/hwas/test/hwasGardTest.H +++ b/src/usr/hwas/test/hwasGardTest.H @@ -51,7 +51,7 @@ #define DISABLE_EX_UNIT_TESTS 1 //$$#define DISABLE_UNIT_TESTS 0 -#define DISABLE_OMI_UNIT_TESTS 0 +#define DISABLE_OMI_UNIT_TESTS 1 #if DISABLE_OMI_UNIT_TESTS #define ENABLE_OMI_UNIT_TEST_1 0 |