summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/usr/hwas/common/hwasCommon.H71
-rw-r--r--src/include/usr/hwas/common/hwas_reasoncodes.H2
-rw-r--r--src/include/usr/hwas/common/pgLogic.H4
-rw-r--r--src/makefile2
-rw-r--r--src/usr/hwas/common/hwas.C560
-rw-r--r--src/usr/hwas/common/pgLogic.C68
6 files changed, 455 insertions, 252 deletions
diff --git a/src/include/usr/hwas/common/hwasCommon.H b/src/include/usr/hwas/common/hwasCommon.H
index 0d168008e..be6d8746e 100644
--- a/src/include/usr/hwas/common/hwasCommon.H
+++ b/src/include/usr/hwas/common/hwasCommon.H
@@ -158,7 +158,7 @@ typedef std::map<const TARGETING::TargetHandle_t, bool> pgState_map;
* from VPD; must be malloc'ed by the caller, and
* must be VPD_CP00_PG_DATA_ENTRIES in size.
*
- * @param[in] io_targetStates Reference to the target state map to prevent
+ * @param[io] io_targetStates Reference to the target state map to prevent
* re-checking targets.
*
* @return bool Returns true if the descendant is functional;
@@ -169,6 +169,75 @@ bool isDescFunctional(const TARGETING::TargetHandle_t &i_desc,
const uint16_t (&i_pgData)[VPD_CP00_PG_DATA_ENTRIES],
pgState_map &io_targetStates);
+
+/**
+ * @brief Checks the PG keyword data to determine if all
+ * of the descendant chiplets are functional. The
+ * caller is responsible for allocating and
+ * de-allocating the PG keyword space.
+ *
+ * @param[in] i_pTarget The target whose descendants need to be
+ * checked. Must not be nullptr.
+ *
+ * @param[in] i_pgData Reference to area holding the PG keyword read
+ * from VPD; must be malloc'ed by the caller, and
+ * must be VPD_CP00_PG_DATA_ENTRIES in size.
+ *
+ * @param[in] i_chipFunctional The functional state of i_pTarget.
+ *
+ * @param[in] i_errlEid Error log ID of the error associated with
+ * i_pTarget, if any.
+ *
+ * @param[io] io_infoErrl The informational error log that contains PG
+ * issues.
+ *
+ * @param[io] io_createInfoLog Determines whether or not PG issues exist and
+ * if the informational log should be created.
+ *
+ * @param[in] i_isTestcase Determines if the code is running from a
+ * testcase and if so will not modify the state
+ * of the system. Defaulted to false.
+ *
+ * @param[out] o_testResult A pointer to the functional state of i_pTarget
+ * if we are running a test. Default nullptr.
+ *
+ * @return Returns an error if encountered, otherwise
+ * nullptr.
+ *
+ */
+errlHndl_t checkPartialGoodForDescendants(
+ const TARGETING::TargetHandle_t &i_pTarget,
+ const uint16_t (&i_pgData)[VPD_CP00_PG_DATA_ENTRIES],
+ const bool i_chipFunctional,
+ const uint32_t i_errlEid,
+ errlHndl_t io_infoErrl,
+ bool &io_createInfoLog,
+ bool i_isTestcase = false,
+ bool* o_testResult = nullptr);
+
+/**
+* @brief This function will propagate a parent's
+* non-functional status down to all functional
+* children since children cannot be considered
+* functional if they have non-functional parents.
+* NOTE: This function will only mark children
+* non-functional if the passed-in parent is
+* non-functional and is in the io_targetStates
+* map. Therefore, if a parent is passsed in that
+* is functional or missing from the
+* io_targetStates map (parent state unknown) this
+* function behaves as a no-op.
+*
+* @param[in] i_desc Pointer to the parent target we're looking
+* at. Must not be nullptr.
+*
+* @param[io] io_targetStates Reference to the pgState_map that will be
+* updated by this function.
+*
+*/
+void markChildrenNonFunctional(const TARGETING::TargetHandle_t &i_parent,
+ pgState_map &io_targetStates);
+
/**
* @deprecated
* @brief platform specific code to determine the PR vector of the input
diff --git a/src/include/usr/hwas/common/hwas_reasoncodes.H b/src/include/usr/hwas/common/hwas_reasoncodes.H
index 7b793ecb3..b60e10032 100644
--- a/src/include/usr/hwas/common/hwas_reasoncodes.H
+++ b/src/include/usr/hwas/common/hwas_reasoncodes.H
@@ -41,6 +41,7 @@ namespace HWAS
MOD_FIND_RULES_FOR_TARGET = 0x0A,
MOD_DISCOVER_TARGETS = 0x0B,
MOD_UPDATE_PROC_COMPAT_RISK_LEVEL = 0x0C,
+ MOD_CHECK_PG_FOR_DESC = 0x0D,
};
enum HwasReasonCode
@@ -78,6 +79,7 @@ namespace HWAS
RC_FORCED_COMPAT_INVALID_LEVEL = HWAS_COMP_ID | 0x1B,
RC_FORCED_NATIVE_INVALID_MIXED_EC = HWAS_COMP_ID | 0x1C,
RC_FORCED_NATIVE_OF_INCOMPATIBLE_RISK = HWAS_COMP_ID | 0x1D,
+ RC_PARTIAL_GOOD_MISSING_TARGET = HWAS_COMP_ID | 0x1E,
};
enum HwasPlatUserDetailsTypes
diff --git a/src/include/usr/hwas/common/pgLogic.H b/src/include/usr/hwas/common/pgLogic.H
index 1adf5509f..8e1ca32ba 100644
--- a/src/include/usr/hwas/common/pgLogic.H
+++ b/src/include/usr/hwas/common/pgLogic.H
@@ -695,14 +695,14 @@ namespace PARTIAL_GOOD
APPLICABLE_TO_ALL,
NO_SPECIAL_RULE
),
- // OBUS Rule 3: pbioo1 unit on chiplet N3 must be checked
+ // OBUS Rule 3: pbioo1 unit on chiplet N1 must be checked
// for Cumulus OBUSes (chip unit 1 and 2).
new PartialGoodRule
(
{&PREDICATE_CUMULUS},
OBUS_R3_PG_MASK,
ALL_OFF_AG_MASK,
- N3_PG_INDEX,
+ N1_PG_INDEX,
OBUS_R3_CU_MASK,
NO_SPECIAL_RULE
),
diff --git a/src/makefile b/src/makefile
index c354622c1..6037d7dd4 100644
--- a/src/makefile
+++ b/src/makefile
@@ -248,7 +248,7 @@ TESTCASE_MODULES += $(if $(CONFIG_EARLY_TESTCASES),,testrtloader)
TESTCASE_MODULES += testsbe
TESTCASE_MODULES += testsbeio
TESTCASE_MODULES += testerrl
-TESTCASE_MODULES += testhwas
+#TESTCASE_MODULES += testhwas
TESTCASE_MODULES += testvpd
TESTCASE_MODULES += testsyslib
TESTCASE_MODULES += testtlsmod
diff --git a/src/usr/hwas/common/hwas.C b/src/usr/hwas/common/hwas.C
index 5dd7240de..f48b80e94 100644
--- a/src/usr/hwas/common/hwas.C
+++ b/src/usr/hwas/common/hwas.C
@@ -75,7 +75,6 @@ TRAC_INIT(&g_trac_dbg_hwas, "HWAS", 1024 );
TRAC_INIT(&g_trac_imp_hwas, "HWAS_I", 1024 );
#endif
-
// SORT functions that we'll use for PR keyword processing
bool compareProcGroup(procRestrict_t t1, procRestrict_t t2)
{
@@ -159,71 +158,6 @@ void enableHwasState(Target *i_target,
}
/**
- * @brief This is a helper function for
- * isDescFunctional. The name for it is slightly
- * misleading because this function will only
- * mark children non-functional if the passed-in
- * parent is non-functional. Therefore, if a
- * parent is passed in that is functional this
- * function behaves as a NOOP. This function will
- * propagate a parent's non-functional status
- * down to all children since children cannot be
- * considered functional if they have
- * non-functional parents.
- *
- * @param[in] i_desc Pointer to the parent target we're looking
- * at. Must not be nullptr.
- *
- * @param[in] i_pgData Reference to area holding the PG keyword read
- * from VPD; must be malloc'ed by the caller, and
- * must be VPD_CP00_PG_DATA_ENTRIES in size.
- *
- * @param[in] io_targetStates Reference to the pgState_map that will to
- * be updated by this function.
- *
- */
-void markChildrenNonFunctional(const TARGETING::TargetHandle_t &i_parent,
- const uint16_t (&i_pgData)
- [VPD_CP00_PG_DATA_ENTRIES],
- pgState_map &io_targetStates)
-{
-
- // Get the state for the parent.
- auto parentState_it = io_targetStates.find(i_parent);
-
- if (!parentState_it->second)
- {
- // Parent is non-functional. So get the list of all children
- // and mark them non-functional as well.
- TargetHandleList l_pDescChildren;
- targetService().getAssociated(l_pDescChildren, i_parent,
- TargetService::CHILD,
- TargetService::ALL);
-
- for(TargetHandleList::const_iterator child_it =
- l_pDescChildren.begin();
- child_it != l_pDescChildren.end(); ++child_it)
- {
- TargetHandle_t child = *child_it;
-
- auto childState_it = io_targetStates.find(child);
-
- if(childState_it != io_targetStates.end())
- {
- childState_it->second = false;
- }
- else
- {
- // Child is missing from the targetStates map. Insert it and
- // mark it non-functional.
- io_targetStates[child] = false;
- }
- }
- }
-}
-
-
-/**
* @brief disable obuses in wrap config.
* Due to fabric limitations, we can only have 2 parallel OBUS
* connections at a time in wrap config.So, deconfigure appropriate
@@ -869,88 +803,14 @@ errlHndl_t discoverTargets()
pTarget->getAttr<ATTR_HUID>(),
chipFunctional ? "" : "NOT ");
- // now need to mark all of this target's physical descendants as
- // present and functional as appropriate
- TargetHandleList pDescList;
- targetService().getAssociated( pDescList, pTarget,
- TargetService::CHILD, TargetService::ALL);
-
- // A map that will keep track of what has already been checked to
- // eliminate re-checking targets. It also holds functional state.
- pgState_map targetStates;
-
- // by default, the descendant's functionality is 'inherited'
- bool descFunctional = chipFunctional;
-
- if (chipFunctional)
- {
- // Check all of the descendants before moving onto setting
- // hwasState. They must be checked before the next loop since a
- // descendant's state can be changed multiple times before
- // arriving at the final state. The reason for that is that a
- // descendant could be marked functional until its parent is
- // checked and then later be updated if the parent is determined
- // to be non-functional.
- for (TargetHandleList::const_iterator pDesc_it =
- pDescList.begin();
- pDesc_it != pDescList.end();
- ++pDesc_it)
- {
- isDescFunctional(*pDesc_it, pgData, targetStates);
- }
- }
-
-
- for (TargetHandleList::const_iterator pDesc_it = pDescList.begin();
- pDesc_it != pDescList.end();
- ++pDesc_it)
- {
-
- TargetHandle_t pDesc = *pDesc_it;
-
- if (chipFunctional)
- {
- // if the chip is functional, then look through the
- // partialGood vector to see if its chiplets
- // are functional.
- //
- // The descendant has been checked already, it will
- // not be checked again here. The result will be returned
- // instead.
- descFunctional = isDescFunctional(pDesc,
- pgData,
- targetStates);
- if(!descFunctional)
- {
- // Add this descendant to the error log.
- hwasErrorAddTargetInfo(infoErrl, *pDesc_it);
- createInfoLog = true;
- }
- }
-
- if (pDesc->getAttr<ATTR_TYPE>() == TYPE_PERV)
- {
- // for sub-parts of PERV, it's always present.
- enableHwasState(pDesc, chipFunctional, descFunctional,
- errlEid);
- HWAS_DBG("pDesc %.8X - marked %spresent, %sfunctional",
- pDesc->getAttr<ATTR_HUID>(),
- "",
- descFunctional ? "" : "NOT ");
- }
- else
- {
- // for other sub-parts, if it's not functional,
- // it's not present.
- enableHwasState(pDesc, descFunctional, descFunctional,
- errlEid);
- HWAS_DBG("pDesc %.8X - marked %spresent, %sfunctional",
- pDesc->getAttr<ATTR_HUID>(),
- descFunctional ? "" : "NOT ",
- descFunctional ? "" : "NOT ");
- }
- }
-
+ // Now determine if the descendants of this target are
+ // present and/or functional
+ checkPartialGoodForDescendants(pTarget,
+ pgData,
+ chipFunctional,
+ errlEid,
+ infoErrl,
+ createInfoLog);
// set HWAS state to show CHIP is present, functional per above
enableHwasState(pTarget, chipPresent, chipFunctional, errlEid);
@@ -1197,78 +1057,32 @@ bool isChipFunctional(const TARGETING::TargetHandle_t &i_target,
return l_chipFunctional;
} // isChipFunctional
-
bool isDescFunctional(const TARGETING::TargetHandle_t &i_desc,
const uint16_t (&i_pgData)[VPD_CP00_PG_DATA_ENTRIES],
pgState_map &io_targetStates)
{
- bool l_functional = false;
- TargetHandleList l_pDescChildren;
- targetService().getAssociated(l_pDescChildren, i_desc,
- TargetService::CHILD,
- TargetService::IMMEDIATE);
+ bool l_functional = true, l_previouslySeen = false;
do {
- // There is a chance that this target has been checked already. Since
- // descendant list isn't ordered.
+ // Look in the targetStates map to see if the target has been given a
+ // state already. If it's not in the map, then continue with the
+ // algorithm. Otherwise, only continue if the state was marked as
+ // functional. Since the list input into isDescFunctional is sorted
+ // where all of the children are first in the array, then if the current
+ // target is found in io_targetStates and it's not functional that means
+ // that it has no functional children and we shouldn't do any further
+ // checking on it.
auto selfState_it = io_targetStates.find(i_desc);
- if (selfState_it != io_targetStates.end())
+ if ((selfState_it != io_targetStates.end())
+ && (selfState_it->second != true))
{
// This target has been seen, return.
+ l_previouslySeen = true;
l_functional = selfState_it->second;
break;
}
- // First, if a target has children at least one must be functional for
- // this target to be considered functional.
- if (l_pDescChildren.size() == 0)
- {
- // Target has no children. So, set l_functional to true so that the
- // check after the loop won't cause the function to exit with a
- // potentially incorrect result.
- l_functional = true;
- }
-
- // Iterate through the list of children and look them up in the
- // io_targetStates map. If at least one is functional then the algorithm
- // will move onto the next set of checks to determine functionality for
- // this target.
- for(TargetHandleList::const_iterator child_it = l_pDescChildren.begin();
- child_it != l_pDescChildren.end(); ++child_it)
- {
- TargetHandle_t child = *child_it;
-
- auto childState = io_targetStates.find(child);
-
- if (childState == io_targetStates.end())
- {
- // The child was not added to the map. This means that it hasn't
- // been checked yet. So, check it before continuing with this
- // target.
- isDescFunctional(child, i_pgData, io_targetStates);
- childState = io_targetStates.find(child);
- }
-
- if (childState->second)
- {
- // One child of this target is functional. So far, that
- // indicates that this target is functional.
- l_functional = true;
- break;
- }
- }
-
- if (!l_functional)
- {
- // No functional children of this target were found. Target is
- // considered not functional.
- HWAS_INF("pDesc 0x%.8X - marked bad because all of "
- "its children were bad.",
- i_desc->getAttr<ATTR_HUID>());
- break;
- }
-
// Since the target has at least one functional child (or no children),
// next we must apply the correct partial good rules to determine
// functionality.
@@ -1332,19 +1146,337 @@ bool isDescFunctional(const TARGETING::TargetHandle_t &i_desc,
} while(0);
- // Record the result in the targetStates map for later use.
- io_targetStates[i_desc] = l_functional;
-
- if ((!l_functional) && (l_pDescChildren.size() != 0))
+ if (!l_previouslySeen)
{
- // Since this target isn't functional and it's a parent,
- // mark the children as non-functional.
- markChildrenNonFunctional(i_desc, i_pgData, io_targetStates);
+ // Record the result in the targetStates map for later use.
+ io_targetStates[i_desc] = l_functional;
}
return l_functional;
-} // isDescFunctional
+}
+
+void markChildrenNonFunctional(const TARGETING::TargetHandle_t &i_parent,
+ pgState_map &io_targetStates)
+{
+
+ // Get the state for the parent.
+ auto parentState_it = io_targetStates.find(i_parent);
+
+ if ((parentState_it != io_targetStates.end()) && !parentState_it->second)
+ {
+ // Parent is non-functional. So get the list of all children
+ // and mark them non-functional as well.
+ TargetHandleList pDescChildren;
+ targetService().getAssociated(pDescChildren, i_parent,
+ TargetService::CHILD,
+ TargetService::IMMEDIATE);
+
+ for(auto child : pDescChildren)
+ {
+ auto childState_it = io_targetStates.find(child);
+
+ if (childState_it != io_targetStates.end())
+ {
+ // Ignore children that are already non-functional because the
+ // first part of the partial good algorithm was done by starting
+ // at the bottom of the target hierarchy and working up to the
+ // top. Since this function is called while operating top-down,
+ // that means if there is a child of this target that is
+ // non-functional which has functional children we don't have to
+ // deal with it now since it will eventually be passed into this
+ // function as the parent target and its functional children
+ // will be taken care of at that time.
+ if (childState_it->second == true)
+ {
+ // Child state is true so change it to false.
+ childState_it->second = false;
+
+ // Since this child's state is true it may have functional
+ // children that need to be marked non-functional. So, we
+ // should check this child's children.
+ TargetHandleList pGrandChildren;
+ targetService().getAssociated(pGrandChildren, child,
+ TargetService::CHILD,
+ TargetService::IMMEDIATE);
+
+ if (!pGrandChildren.empty())
+ {
+ markChildrenNonFunctional(child, io_targetStates);
+ }
+ }
+ }
+ else
+ {
+ // Child is missing from the targetStates map. Insert it and
+ // mark it non-functional.
+ // NOTE: This won't happen during the actual PG algorithm but
+ // is left here to be used for testcases or other uses.
+ io_targetStates[child] = false;
+
+ // Since the child was missing and its state is unknown, check
+ // if it has any children and make those non-functional as well.
+ TargetHandleList pGrandChildren;
+ targetService().getAssociated(pGrandChildren, child,
+ TargetService::CHILD,
+ TargetService::IMMEDIATE);
+
+ if (!pGrandChildren.empty())
+ {
+ markChildrenNonFunctional(child, io_targetStates);
+ }
+ }
+ }
+ }
+}
+
+errlHndl_t checkPartialGoodForDescendants(
+ const TARGETING::TargetHandle_t &i_pTarget,
+ const uint16_t (&i_pgData)[VPD_CP00_PG_DATA_ENTRIES],
+ const bool i_chipFunctional,
+ const uint32_t i_errlEid,
+ errlHndl_t io_infoErrl,
+ bool &io_createInfoLog,
+ bool i_isTestcase /* = false */,
+ bool* o_testResult /* = nullptr */
+ )
+{
+
+ errlHndl_t errl = nullptr;
+
+ // A map that will keep track of what has already been checked to
+ // eliminate re-checking targets. It also holds functional state.
+ pgState_map targetStates;
+
+ // by default, the descendant's functionality is 'inherited'
+ bool descFunctional = i_chipFunctional;
+
+ // Get a list of this target's physical descendants
+ TargetHandleList pDescList;
+
+ targetService().getAssociated( pDescList, i_pTarget,
+ TargetService::CHILD, TargetService::ALL);
+
+ if (i_isTestcase)
+ {
+ // If we are running a testcase then i_pTarget is the target to be
+ // checked and the children of i_pTarget should be checked along with
+ // it. So, add it to the list and the algorithm will check it too.
+ pDescList.push_back(i_pTarget);
+ }
+
+ if (i_chipFunctional)
+ {
+ // Sort the list of descendants such that the largest affinity
+ // paths are first in the list and targets are grouped by
+ // parent.
+ std::sort(pDescList.begin(), pDescList.end(),
+ // Define a lambda comparator function for sorting
+ // criteria.
+ [](const TargetHandle_t a, const TargetHandle_t b)
+ {
+ EntityPath aPath =
+ a->getAttr<ATTR_AFFINITY_PATH>();
+
+ TargetHandle_t aParent =
+ getImmediateParentByAffinity(a);
+
+ EntityPath bPath =
+ b->getAttr<ATTR_AFFINITY_PATH>();
+
+ TargetHandle_t bParent =
+ getImmediateParentByAffinity(b);
+
+
+ // a goes before b if its affinity path is
+ // greater than b's and its parent pointer
+ // is different from b's.
+ bool result = false;
+ if ((aPath.size() > bPath.size())
+ || ((aPath.size() == bPath.size())
+ && (aParent > bParent)))
+ {
+ result = true;
+ }
+
+ return result;
+ });
+
+ // A pointer to a descendant's parent. This will be updated as
+ // the first pass of PG checking occurs.
+ TargetHandle_t parent = nullptr;
+
+ // Assume the parent has no functional children and the
+ // descendant's state is false.
+ bool parentState = false, descState = false;
+
+ // =========== Partial Good Checking First Pass ===========
+ // Now that the list of descendants has been sorted, we can
+ // proceed with the PG algorithm in two passes. In this pass,
+ // the target hierarchy is navigated from the bottom up to the
+ // top.
+ //
+ // This pass will check all children of a parent and when it
+ // encounters a new parent, it will set the previous parent's
+ // state as true or false.
+ // true: the parent has at least one functional child
+ // false: the parent has no functional children.
+ // By setting a parent's state false ahead of time
+ // isDescFunctional is able to skip over that target since,
+ // regardless of PG results, that target will still be
+ // non-functional due to not having functional children.
+ for (auto pDesc : pDescList)
+ {
+ // Check if the parent has changed during iteration. If it
+ // has then all of the children of that parent have been
+ // checked and we now know if it has any functional
+ // children. So, add the parent to targetStates with the
+ // result.
+ if (getImmediateParentByAffinity(pDesc) != parent)
+ {
+ if (parent != nullptr)
+ {
+ // Add parent's state to the targetStates map.
+ // Note: If parentState has remained non-functional then
+ // that means that it had no functional children
+ // which is not allowed. So, PG checks will be
+ // skipped for it when it is passed into
+ // isDescFunctional.
+ targetStates[parent] = parentState;
+
+ if (parentState == false)
+ {
+ // No functional children of this target were found.
+ // Target is considered not functional.
+ HWAS_INF("pDesc parent 0x%.8X - marked bad because "
+ "all of its children were bad.",
+ parent->getAttr<ATTR_HUID>());
+ }
+ }
+ // Update parent pointer to the new parent.
+ parent = getImmediateParentByAffinity(pDesc);
+
+ // Reset parentState to false.
+ parentState = false;
+ }
+
+ descState = isDescFunctional(pDesc,
+ i_pgData,
+ targetStates);
+
+ // If one descendant of the current parent is functional,
+ // then the parent is functional and should be checked by
+ // isDescFunctional for partial good issues.
+ if (descState == true)
+ {
+ parentState = true;
+ }
+ }
+ }
+
+ // =========== Partial Good Checking Second Pass ===========
+ // After the first pass completes, all targets have had PG checks
+ // applied to them (if necessary) and all parents have been checked
+ // to have at least one functional child. Now we iterate through the
+ // list one final time in reverse and propagate all non-functional
+ // parent states down to functional children, since functional
+ // children must not have non-functional parents.
+ //
+ // As the algorithm works its way through the hierarchy in a
+ // top-down fashion, the final hwasState of the current target is
+ // known and can be set as it works through all of the targets this
+ // time.
+ //
+ // NOTE: If the chip is not functional then the first pass will not execute
+ // and this iteration will serve only to mark all descendants
+ // non-functional.
+ TargetHandleList::const_iterator pDescList_rbegin = pDescList.end() - 1;
+ TargetHandleList::const_iterator pDescList_rend = pDescList.begin() - 1;
+
+ for (TargetHandleList::const_iterator pDesc_it = pDescList_rbegin;
+ pDesc_it != pDescList_rend; --pDesc_it)
+ {
+ TargetHandle_t pDesc = *pDesc_it;
+
+ if (i_chipFunctional)
+ {
+
+ // If this descendant is non-functional then
+ // propagate non-functional state down to its children.
+ markChildrenNonFunctional(pDesc,
+ targetStates);
+
+ auto pDesc_mapIt = targetStates.find(pDesc);
+ if (pDesc_mapIt != targetStates.end())
+ {
+ descFunctional = pDesc_mapIt->second;
+ }
+ else
+ {
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid MOD_CHECK_PG_FOR_DESC
+ * @reasoncode RC_PARTIAL_GOOD_MISSING_TARGET
+ * @devdesc A target was not found in the map of
+ * states kept by the PG checking
+ * algorithm. Therefore, it did not have
+ * PG checks run against it.
+ * @custdesc An issue occured during IPL of the
+ * system: Internal Firmware Error
+ * @userdata1 huid of the target
+ */
+ errl = hwasError(ERRL_SEV_UNRECOVERABLE,
+ MOD_CHECK_PG_FOR_DESC,
+ RC_PARTIAL_GOOD_MISSING_TARGET,
+ pDesc->getAttr<ATTR_HUID>());
+ break;
+ }
+
+ if(!descFunctional && !i_isTestcase)
+ {
+ // Add this descendant to the error log.
+ hwasErrorAddTargetInfo(io_infoErrl, pDesc);
+ io_createInfoLog = true;
+ }
+ }
+ // Don't mess with the state of the system if we are doing test cases.
+ if (!i_isTestcase)
+ {
+ if (pDesc->getAttr<ATTR_TYPE>() == TYPE_PERV)
+ {
+ // for sub-parts of PERV, it's always present.
+ enableHwasState(pDesc, i_chipFunctional, descFunctional,
+ i_errlEid);
+ HWAS_DBG("pDesc %.8X - marked %spresent, %sfunctional",
+ pDesc->getAttr<ATTR_HUID>(),
+ i_chipFunctional ? "" : "NOT",
+ descFunctional ? "" : "NOT ");
+ }
+ else
+ {
+ // for other sub-parts, if it's not functional,
+ // it's not present.
+ enableHwasState(pDesc, descFunctional, descFunctional,
+ i_errlEid);
+ HWAS_DBG("pDesc %.8X - marked %spresent, %sfunctional",
+ pDesc->getAttr<ATTR_HUID>(),
+ descFunctional ? "" : "NOT ",
+ descFunctional ? "" : "NOT ");
+ }
+ }
+ }
+
+ // Before we return, if this was run in a testcase then we should set the
+ // o_testResult parameter so the testcase is aware of i_pTarget's state.
+ if (i_isTestcase && (o_testResult != nullptr))
+ {
+ *o_testResult = targetStates[i_pTarget];
+ }
+
+ return errl;
+
+}
void forceEcExEqDeconfig(const TARGETING::TargetHandle_t i_core,
const bool i_present,
diff --git a/src/usr/hwas/common/pgLogic.C b/src/usr/hwas/common/pgLogic.C
index b8f32f714..2cc30944f 100644
--- a/src/usr/hwas/common/pgLogic.C
+++ b/src/usr/hwas/common/pgLogic.C
@@ -257,7 +257,9 @@ namespace PARTIAL_GOOD
if (rulesIterator == pgRules_map.end())
{
- // Target is missing from the table. Return an empty vector.
+ // Target is missing from the table. This is an error, so break
+ // out of this section of code and return the appropriate error
+ // below.
break;
}
@@ -334,41 +336,39 @@ namespace PARTIAL_GOOD
}
}
- // If o_targetPgLogic has no entries then that means that there
- // doesn't exist any PG rules for the given target or another error
- // was encountered. If no other error occurred then return the
- // the following error if applicable.
- if ((l_errl == nullptr) && (o_targetPgLogic.size() == 0))
- {
- /*@
- * @errortype
- * @severity ERRL_SEV_UNRECOVERABLE
- * @moduleid HWAS::MOD_IS_DESCENDANT_FUNCTIONAL
- * @reasoncode HWAS::RC_NO_PG_LOGIC
- * @devdesc To enforce all target types have partial good
- * rules and logic, all targets must be included
- * in the PartialGoodRulesTable. A combination
- * of target type, chip type, and chip unit
- * produced an empty set of logic for the
- * target.
- *
- * @custdesc A problem occured during IPL of the system:
- * Internal Firmware Error
- * @userdata1 target type attribute
- * @userdata2 HUID of the target
- */
- l_errl = hwasError(
- ERRL_SEV_UNRECOVERABLE,
- HWAS::MOD_IS_DESCENDANT_FUNCTIONAL,
- HWAS::RC_NO_PG_LOGIC,
- i_target->getAttr<TARGETING::ATTR_TYPE>(),
- get_huid(i_target));
-
- break;
- }
-
} while(0);
+ // If o_targetPgLogic has no entries then that means that there
+ // doesn't exist any PG rules for the given target or another error
+ // was encountered. If no other error occurred then return the
+ // the following error if applicable.
+ if ((l_errl == nullptr) && (o_targetPgLogic.size() == 0))
+ {
+ /*@
+ * @errortype
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @moduleid HWAS::MOD_FIND_RULES_FOR_TARGET
+ * @reasoncode HWAS::RC_NO_PG_LOGIC
+ * @devdesc To enforce all target types have partial good
+ * rules and logic, all targets must be included
+ * in the PartialGoodRulesTable. A combination
+ * of target type, chip type, and chip unit
+ * produced an empty set of logic for the
+ * target.
+ *
+ * @custdesc A problem occured during IPL of the system:
+ * Internal Firmware Error
+ * @userdata1 target type attribute
+ * @userdata2 HUID of the target
+ */
+ 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));
+ }
+
return l_errl;
}
OpenPOWER on IntegriCloud