summaryrefslogtreecommitdiffstats
path: root/src/usr/hwas
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/hwas')
-rw-r--r--src/usr/hwas/common/deconfigGard.C24
-rw-r--r--src/usr/hwas/common/hwas.C148
-rw-r--r--src/usr/hwas/common/pgLogic.C25
-rw-r--r--src/usr/hwas/hwasPlat.C548
-rw-r--r--src/usr/hwas/hwasPlatDeconfigGard.C3
-rw-r--r--src/usr/hwas/test/hwas1test.H267
-rw-r--r--src/usr/hwas/test/hwasGardTest.H2
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
OpenPOWER on IntegriCloud