summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authorMatt Raybuck <mraybuc@us.ibm.com>2018-10-25 13:57:53 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-12-03 12:33:22 -0600
commit8b6b1b256035236d5434760729a1263305939a1f (patch)
tree4674a7415f369b36dfb885eb119b066aef47e66e /src/include
parenteb8d14930c5e77bc2d0d0ef9f6861514c04d775d (diff)
downloadtalos-hostboot-8b6b1b256035236d5434760729a1263305939a1f.tar.gz
talos-hostboot-8b6b1b256035236d5434760729a1263305939a1f.zip
Remove hardcoding of partial good logic (2/2)
The original pg logic was a hard-coded criss-crossed jumble of logic that was difficult to understand. It has now been generalized to an algorithm that applies the correct logic based on a set of rules kept in a table. This should make it easier to understand and maintain going forward. Change-Id: I51435cc2ca6bbfa9ebc8a3d52d4ebf23b5bd2730 RTC:193270 CMVC-Prereq: 1072559 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/68232 Reviewed-by: Ilya Smirnov <ismirno@us.ibm.com> Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/include')
-rw-r--r--src/include/usr/hwas/common/hwasCommon.H37
-rw-r--r--src/include/usr/hwas/common/hwas_reasoncodes.H2
-rw-r--r--src/include/usr/hwas/common/pgLogic.H854
3 files changed, 883 insertions, 10 deletions
diff --git a/src/include/usr/hwas/common/hwasCommon.H b/src/include/usr/hwas/common/hwasCommon.H
index 82ca18730..7a02b9595 100644
--- a/src/include/usr/hwas/common/hwasCommon.H
+++ b/src/include/usr/hwas/common/hwasCommon.H
@@ -32,6 +32,8 @@
#ifndef HWASCOMMON_H_
#define HWASCOMMON_H_
+#include<map>
+
// 'system' headers
#include <stdint.h>
#include <targeting/common/target.H>
@@ -244,22 +246,37 @@ bool isChipFunctional(const TARGETING::TargetHandle_t &i_target,
const uint16_t i_pgData[VPD_CP00_PG_DATA_LENGTH]);
+// This map is used to track the state of previously checked targets in the
+// isDescFunctional method. This is used instead of directly looking at
+// hwasState to keep the isDescFunctional logic self-contained and work around
+// a limitation with the unit testing. Since hwasState can't be changed during
+// testing the only other way to verify the algorithm works is by modifing this
+// to match the test conditions.
+typedef std::map<const TARGETING::TargetHandle_t, bool> pgState_map;
+
/**
- * @brief Checks the PG keyword data to determine if the descendant chiplet is
- * functional. The caller is responsible for allocating and de-allocating the
- * PG keyword space.
+ * @brief Checks the PG keyword data to determine if the
+ * descendant chiplet is functional. The caller
+ * is responsible for allocating and
+ * de-allocating the PG keyword space.
*
- * @param[in] i_desc pointer to descendant of target we're looking at
- * @param[in] i_pgData pointer to area holding the PG keyword read from
- * VPD; must be malloc'ed by the caller, and must be
- * VPD_CP00_PG_DATA_LENGTH in size.
+ * @param[in] i_desc Pointer to descendant of 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 target state map to prevent
+ * re-checking targets.
*
- * @return bool Return true if the descendant is functional; false if not.
+ * @return bool Returns true if the descendant is functional;
+ * False if not.
*
*/
bool isDescFunctional(const TARGETING::TargetHandle_t &i_desc,
- const uint16_t i_pgData[VPD_CP00_PG_DATA_LENGTH]);
-
+ const uint16_t (&i_pgData)[VPD_CP00_PG_DATA_ENTRIES],
+ pgState_map &io_targetStates);
/**
* @deprecated
diff --git a/src/include/usr/hwas/common/hwas_reasoncodes.H b/src/include/usr/hwas/common/hwas_reasoncodes.H
index c81904c6d..012188d25 100644
--- a/src/include/usr/hwas/common/hwas_reasoncodes.H
+++ b/src/include/usr/hwas/common/hwas_reasoncodes.H
@@ -37,6 +37,7 @@ namespace HWAS
MOD_RUNTIME_DECONFIG = 0x06,
MOD_DISABLE_OBUS = 0x07,
MOD_UPDATE_PROC_MEM_TO_USE = 0x08,
+ MOD_IS_DESCENDANT_FUNCTIONAL = 0x09
};
enum HwasReasonCode
@@ -66,6 +67,7 @@ namespace HWAS
RC_NULL_TARGET = HWAS_COMP_ID | 0x13,
RC_ONLY_TWO_OBUS_SHOULD_BE_CONFIGURED = HWAS_COMP_ID | 0x14,
RC_NO_UPDATE_WHEN_MEM_MISSING = HWAS_COMP_ID | 0x15,
+ RC_NO_PG_LOGIC = HWAS_COMP_ID | 0x16
};
};
diff --git a/src/include/usr/hwas/common/pgLogic.H b/src/include/usr/hwas/common/pgLogic.H
index 9f4910cf1..394350d74 100644
--- a/src/include/usr/hwas/common/pgLogic.H
+++ b/src/include/usr/hwas/common/pgLogic.H
@@ -22,3 +22,857 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+#ifndef PG_LOGIC_H
+#define PG_LOGIC_H
+
+/* @file pgLogic.H
+ *
+ * Defines the necessary logic for checking the Partial Good data read from the
+ * VPD. This logic is used in hwas.C isDescFunctional
+ */
+
+#include <map>
+#include <targeting/common/target.H>
+#include <targeting/common/commontargeting.H>
+
+namespace PARTIAL_GOOD
+{
+ // These constants are used for the applicableChipTypes in a PartialGoodRule
+ // A combination of them can be pushed onto applicableChipTypes' expr stack.
+ extern const TARGETING::PredicateCTM PREDICATE_NIMBUS;
+
+ extern const TARGETING::PredicateCTM PREDICATE_CUMULUS;
+
+ extern const TARGETING::PredicateCTM PREDICATE_AXONE;
+
+ extern const TARGETING::PredicateCTM PREDICATE_NA;
+
+ typedef std::vector<const TARGETING::PredicateCTM * > predicates_t;
+
+ extern const predicates_t PREDICATE_P9;
+
+ // Partial Good Rule extern constants for Target Types
+ // Naming convention for masks is as follows:
+ // TargetType_RuleNumber_MaskType_MASK
+ //
+ // Mask Types: PG = Partial Good
+ // AG = All Good
+ // CU = Applicable Chip Units
+
+ // Special Masks that are applicable to many rules
+
+ // This mask is common to many rules because in most cases we are checking
+ // specific bits and don't care about the rest. To detect a problem with
+ // only those bits we provide an AG mask of all zeroes.
+ extern const uint16_t ALL_OFF_AG_MASK;
+
+ // This mask is common to many rules because there are target types that
+ // cover a set of bits where all must checked at one time instead of just a
+ // subset of bits to determine functionality.
+ extern const uint16_t ALL_ON_PG_MASK;
+
+ // Used in place of a chip unit mask to indicate that the rule is applicable
+ // for all values a chip unit can take.
+ extern const size_t APPLICABLE_TO_ALL;
+
+ // The following three masks are common among a few PG Rules and have been
+ // defined as special masks. Each mask applies to the chip unit that the
+ // name suggests. Zero bit for chip unit 0, etc.
+ extern const size_t ZERO_BIT_CU_MASK;
+ extern const size_t ONE_BIT_CU_MASK;
+ extern const size_t TWO_BIT_CU_MASK;
+
+
+ // Used in place of a PG index to indicate that the target's associated
+ // chiplet id is the correct way to index the PG vector.
+ extern const uint8_t USE_CHIPLET_ID;
+
+ // Used when a target type has no applicable partial good checking logic.
+ // Instead of omitting that target type from the map of rules, it will have:
+ // pgMask == MASK_NA
+ // agMask == MASK_NA
+ // pgIndex == INDEX_NA
+ // This will ensure that the algorithm in isDescFunctional() will execute
+ // successfully and serve to enforce that all targets be defined in the
+ // rules map.
+ extern const uint16_t MASK_NA;
+ extern const uint8_t INDEX_NA;
+
+ // Target Type Masks
+ // PG Masks are created such that:
+ // pgData[ pgIndex ] & pgMask
+ // produces the AG Mask defined for that rule. They are defined to cover the
+ // set of bits that a target type covers. The AG masks were defined either
+ // by directly using the provided AG mask listed in the MVPD PG Mapping
+ // Table or were chosen to check the specific bits a target type covers.
+
+ // EQ
+ // PG/AG Masks
+ extern const uint16_t EQ_R1_PG_MASK;
+ extern const uint16_t EQ_R1_AG_MASK;
+
+ // EX
+ // PG/AG Masks
+ extern const uint16_t EX_R1_PG_MASK;
+ extern const uint16_t EX_R2_PG_MASK;
+
+ // Applicable Chip Units
+ // Rule 1 only applies to even chip unit values
+ extern const size_t EX_R1_CU_MASK;
+ // Rule 2 only applies to odd chip unit values
+ extern const size_t EX_R2_CU_MASK;
+
+ // EC
+ // PG/AG Masks
+ extern const uint16_t EC_R1_AG_MASK;
+
+ // MC
+ // PG/AG Masks
+ extern const uint16_t MC_R1_AG_MASK;
+ extern const uint16_t MC_R2_PG_MASK;
+ extern const uint16_t MC_R3_PG_MASK;
+
+ // MCA
+ // PG/AG Masks
+ extern const uint16_t MCA_R1_PG_MASK;
+ extern const uint16_t MCA_R2_PG_MASK;
+
+ // Applicable Chip Units
+ extern const size_t MCA_R2_CU_MASK;
+
+ // MCBIST
+ // PG/AG Masks
+ // There is a special rule for MCBIST targets where a specific MCA is
+ // required to be functional for it to be functional. To condense that rule
+ // into a single rule the bit that needs to be checked has been included in
+ // the PG mask. The PG mask excluding that bit would have been FCFF.
+ extern const uint16_t MCBIST_R1_PG_MASK;
+ extern const uint16_t MCBIST_R1_AG_MASK;
+
+ // MCS
+ // PG/AG Masks
+ extern const uint16_t MCS_R1_PG_MASK;
+ extern const uint16_t MCS_R2_PG_MASK;
+ extern const uint16_t MCS_R3_PG_MASK;
+ extern const uint16_t MCS_R4_PG_MASK;
+
+ extern const uint16_t MCS_ALL_GOOD_MASK;
+
+ // Applicable Chip Units
+ // Rule 1 only applies to chip units 0 & 1
+ extern const size_t MCS_R1_CU_MASK;
+ // Rule 2 only applies to chip units 2 & 3
+ extern const size_t MCS_R2_CU_MASK;
+
+ // NPU
+ // PG/AG Masks
+ extern const uint16_t NPU_R1_PG_MASK;
+
+ // OBUS
+ // PG/AG Masks
+ extern const uint16_t OBUS_R1_AG_MASK;
+ extern const uint16_t OBUS_R2_PG_MASK;
+ extern const uint16_t OBUS_R3_PG_MASK;
+
+ // Applicable Chip Units
+ // Rule 3 only applies to Cumulus OBUS's 1 and 2
+ extern const size_t OBUS_R3_CU_MASK;
+
+ // PEC
+ // PG/AG Masks
+ extern const uint16_t PEC_R1_AG_MASK;
+ extern const uint16_t PEC_R2_AG_MASK;
+ extern const uint16_t PEC_R3_AG_MASK;
+
+ // PERV
+ // PG/AG Masks
+ extern const uint16_t PERV_R1_PG_MASK;
+
+ // XBUS
+ // PG/AG Masks
+ extern const uint16_t XBUS_R1_PG_MASK;
+ extern const uint16_t XBUS_R2_PG_MASK;
+ extern const uint16_t XBUS_R3_PG_MASK;
+
+
+ // Partial Good Vector Indexes
+ extern const uint16_t N1_PG_INDEX;
+ extern const uint16_t N3_PG_INDEX;
+
+ // The struct PartialGoodRule uses a function pointer to indicate that a
+ // special rule for handling PG checking exists and that the function
+ // pointed to will handle that rule.
+ //
+ // The special rule function should always return a boolean indicating
+ // whether the given target is functional or not depending if the function
+ // verified the rule successfully.
+ typedef bool (*specialRuleFuncPtr_t)(
+ const TARGETING::TargetHandle_t &i_desc,
+ const uint16_t i_pgData[]);
+ extern const specialRuleFuncPtr_t NO_SPECIAL_RULE;
+
+ // This struct represents a "row" in the partial good rules map. It contains
+ // all the information necessary to verify one or more rules for a target.
+ struct PartialGoodRule
+ {
+
+ /**
+ * @brief This constructor should be used when adding a rule to
+ * the PartialGoodRulesTable that either doesn't have any
+ * PG checking logic or the only rule is that the target
+ * must have a functional parent. It's a requirement in the
+ * algorithm for isDescFunctional that a target have a
+ * functional parent to be considered functional. However,
+ * it is not necessary that a special rule be defined to
+ * enforce this requirement. The algorithm will mark any
+ * target with this rule as functional on a first pass but
+ * upon checking the target's parent will update the child
+ * with the correct status when the parent's status is
+ * determined.
+ *
+ */
+ PartialGoodRule();
+
+ /**
+ * @brief This constructor should always be used when adding new
+ * rules to the partial good rules map whenever there is
+ * PG checking logic for a target. Since copy and
+ * assignment are disabled for iv_applicableChipTypes, the
+ * only way to initialize its expr stack is to pass in a
+ * vector of PredicateCTMs and push them onto the stack.
+ *
+ * @param[in] i_preds The vector of PredicateCTMs to be
+ * pushed onto iv_applicableChipTypes
+ * expr stack.
+ *
+ * @param[in] i_pgMask The partial good mask for this rule.
+ *
+ * @param[in] i_agMask The all good mask for this rule.
+ *
+ * @param[in] i_pgIndex Where to index into the partial good
+ * vector.
+ *
+ * @param[in] i_appChipUnits The chip unit values of a target
+ * that this rule applies to.
+ *
+ * @param[in] specialRuleFuncPtr_t The special rule associated with
+ * this target that isn't represented
+ * in isDescFunctional. Since every
+ * PartialGoodRule is checked for a
+ * special rule it's only necessary to
+ * point to a unique special rule once.
+ */
+ PartialGoodRule(predicates_t i_preds, uint16_t i_pgMask,
+ uint16_t i_agMask, uint8_t i_pgIndex,
+ size_t i_appChipUnits,
+ specialRuleFuncPtr_t rule);
+
+ // A predicate expression that indicates what processor chip types this
+ // parital good rule applies to. Only logical Or() should be used for
+ // multiple applicable chip types.
+ //
+ TARGETING::PredicatePostfixExpr iv_applicableChipTypes;
+
+ // partial good mask
+ // The mask to be applied to the partial good vector.
+ uint16_t iv_pgMask;
+
+ // all good mask
+ // This mask is the expected result after the pgMask has been
+ // bit-wise & with an entry in the partial good vector.
+ uint16_t iv_agMask;
+
+ // partial good index
+ // Used to index into the partial good vector read from VPD.
+ // For cases where the chiplet id should be used as an index into the
+ // partial good vector it will be set to USE_CHIPLET_ID.
+ uint8_t iv_pgIndex;
+
+ // This represents the applicable chip unit for a target instance that
+ // this rule applies to. It is encoded such that each bit starting from
+ // the right-most position represents a chip unit value for a target
+ // instance.
+ //
+ // Ex: 1010 => represents values for chip units c3, c2, c1, c0. A 1 in
+ // positions c3 and c1 signify that those are the applicable
+ // chip units for this PartialGoodRule.
+ //
+ // For cases where a rule applies to a target type & chip type
+ // combination regardless of chip unit value it will be set to
+ // APPLICABLE_TO_ALL
+ size_t iv_applicableChipUnits;
+
+ // A function pointer to a special case rule that cannot be covered by
+ // the algorithm in HWAS::isDescFunctional(). This will almost always be
+ // a nullptr. It should be used sparingly and only when absolutely
+ // necessary.
+ specialRuleFuncPtr_t iv_specialRule;
+
+ /**
+ * @brief This is a helper function to encode a chip unit value to match
+ * the encoding of the applicableChipUnits member and return
+ * whether the PartialGoodRule is applicable for the given chip
+ * unit value.
+ *
+ * @param[in] i_chipUnit the chip unit of a target to encode
+ *
+ * @return bool Whether or not the PG rule applies to this chip unit
+ */
+ bool isApplicableToChipUnit(uint8_t i_chipUnit) const;
+
+ /**
+ * @brief This is a helper function to determine if a target's chiplet
+ * id is the correct pg index for this rule.
+ *
+ * @return bool Evaluates to true when target's chiplet id is the
+ * correct pg index for this rule.
+ */
+ bool useChipletIdAsIndex() const;
+
+ private:
+ TARG_DISABLE_COPY_AND_ASSIGNMENT_OPERATORS(PartialGoodRule);
+ };
+
+ // The subset of logic required to check the pg vector. Since copy and
+ // assignment of PredicatePostfixExpr have been disabled, it is much simpler
+ // to create and pass around this struct than it is a PartialGoodRule.
+ struct PartialGoodLogic
+ {
+ PartialGoodLogic(): iv_pgMask(MASK_NA), iv_agMask(MASK_NA),
+ iv_pgIndex(INDEX_NA),
+ iv_specialRule(NO_SPECIAL_RULE)
+ {};
+
+ // partial good mask
+ // The mask to be applied to the partial good vector.
+ uint16_t iv_pgMask;
+
+ // all good mask
+ // This mask is the expected result after the pgMask has been
+ // bit-wise & with an entry in the partial good vector.
+ uint16_t iv_agMask;
+
+ // partial good index
+ // Used to index into the partial good vector read from VPD.
+ uint8_t iv_pgIndex;
+
+ // special rule
+ // A function pointer that will be used when there is PG logic that
+ // can't work in the algorithm found in HWAS::isDescFunctional()
+ specialRuleFuncPtr_t iv_specialRule;
+
+ };
+
+ typedef std::vector<PartialGoodRule*> pgRules_t;
+ typedef std::vector<PartialGoodLogic> pgLogic_t;
+
+ /*
+ * @brief A special rule function for Perv targets. This doesn't have any
+ * additional special logic. It will just set the ATTR_PG for the
+ * Perv target to be the applicable row of partial good data.
+ *
+ * @param[in] i_desc A pointer to the current target that this
+ * function has been called for.
+ *
+ * @param[in] i_pgData The partial good data
+ *
+ * @return bool Always returns true since this isn't checking
+ * logic it's just a required additional step.
+ */
+ bool PervSpecialRule(const TARGETING::TargetHandle_t &i_desc,
+ const uint16_t i_pgData[]);
+
+ /*
+ * @brief A special rule function for Obus Brick targets. This will check
+ * if the NPU is functional and whether or not the Obus is in SMP
+ * mode.
+ *
+ * @param[in] i_desc A pointer to the current target that this
+ * function has been called for.
+ *
+ * @param[in] i_pgData The partial good data.
+ *
+ * @return bool This returns false when in non-SMP mode and
+ * the NPU is non-functional.
+ */
+ bool ObusBrickSpecialRule(const TARGETING::TargetHandle_t &i_desc,
+ const uint16_t i_pgData[]);
+
+ /*
+ * @brief A special rule function for EQ targets. This will check the
+ * L3/L2/REFR triplets in the PG EPx data.
+ *
+ * @param[in] i_desc A pointer to the current target that this
+ * function has been called for.
+ *
+ * @param[in] i_pgData The partial good data.
+ *
+ * @return bool The triplets are valid if they are all 0 or
+ * all 1.
+ */
+ bool EQSpecialRule(const TARGETING::TargetHandle_t &i_desc,
+ const uint16_t i_pgData[]);
+
+ struct PartialGoodRulesTable
+ {
+
+ ~PartialGoodRulesTable();
+
+ /**
+ * @brief This function will lookup the list of applicable rules for the
+ * given target and return them as a vector of PartialGoodLogic.
+ * This function should always return a vector of size >= 1. An
+ * empty vector indicates that the target isn't represented in
+ * the rules table which is an error of omission.
+ *
+ * @param[in] i_target The target to find pg rules for.
+ *
+ * @return vector_pgLogic_t A vector of PartialGoodLogic structs
+ * representing the list of applicable rules
+ * used to verify if a target is functional
+ * or not.
+ */
+ pgLogic_t
+ findRulesForTarget(const TARGETING::TargetHandle_t &i_target) const;
+
+ private:
+ // A map that will hold all of the PG rules for all targets. If a target
+ // doesn't have a pg checking logic or special rules it will still be
+ // represented in this map because the generic algorithm will consider
+ // an empty returned array to be an error. This will ensure that the
+ // pgRules_map is kept up-to-date.
+ // KEY: The target type for which the PG rules apply to.
+ // VALUE: A vector of PartialGoodRule structs.
+ //
+ std::map<TARGETING::TYPE, pgRules_t> pgRules_map
+ {
+ // This is the form of a Partial Good Rule definition in the map.
+ // Since PredicatePostfixExpr has assignment disabled, the
+ // applicable chip types for a rule must be supplied as a vector of
+ // pointers to constant defined PredicateCTMs. The constructor for
+ // PartialGoodRule will handle adding them to the expr stack for its
+ // iv_applicableChipTypes member.
+ { TARGETING::TYPE_CORE,
+ {// Start of pgRules_t vector
+ // EC Rule 1: Check all bits in the ECxx entry.
+ new PartialGoodRule
+ (
+ // The first parameter to the PartialGoodRule
+ // constructor is the vector of PredicateCTM references.
+ // In this case this rule applies to all power 9
+ // processors. So it's the vector of all P9 predicates.
+ PREDICATE_P9, // Applicable Chip Types.
+ ALL_ON_PG_MASK, // Partial Good Mask
+ EC_R1_AG_MASK, // All Good Mask
+ USE_CHIPLET_ID, // Partial Good Index
+ APPLICABLE_TO_ALL, // Applicable Chip Units
+ NO_SPECIAL_RULE // Special Rule Function Ptr
+ ),
+ }// End of PG Rules for EC Target
+ },
+ // DMI: This target doesn't have any PG checking logic. It is
+ // considered functional if its parent is functional. However,
+ // it must still be represented in the map. So we create a
+ // pgRules_t with a single element using the PartialGoodRule()
+ // constructor that will create a rule that is essentially a
+ // NOOP. When this target type is encountered in
+ // HWAS::isDescFunctional, a lookup will return this rule which
+ // will cause the function to execute successfully.
+ { TARGETING::TYPE_DMI, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_EQ,
+ {
+ // EQ Rule 1: Check all bits in the EPx entry. This rule has
+ // a special rule to validate the triplets in the
+ // partial good region.
+ new PartialGoodRule
+ (
+ PREDICATE_P9,
+ EQ_R1_PG_MASK,
+ EQ_R1_AG_MASK,
+ USE_CHIPLET_ID,
+ APPLICABLE_TO_ALL,
+ EQSpecialRule
+ ),
+ }// End of PG Rules for EQ Target
+ },
+ { TARGETING::TYPE_EX,
+ {
+ // EX Rule 1: Only applicable to even numbered chip units
+ new PartialGoodRule
+ (
+ PREDICATE_P9,
+ EX_R1_PG_MASK,
+ ALL_OFF_AG_MASK,
+ USE_CHIPLET_ID,
+ EX_R1_CU_MASK,
+ NO_SPECIAL_RULE
+ ),
+ // EX Rule 2: Only applicable to odd numbered chip units
+ new PartialGoodRule
+ (
+ PREDICATE_P9,
+ EX_R2_PG_MASK,
+ ALL_OFF_AG_MASK,
+ USE_CHIPLET_ID,
+ EX_R2_CU_MASK,
+ NO_SPECIAL_RULE
+ ),
+ }// End of PG Rules for EX Target
+ },
+ { TARGETING::TYPE_MC,
+ {
+ // MC Rule 1
+ new PartialGoodRule
+ (
+ {&PREDICATE_CUMULUS, &PREDICATE_AXONE},
+ ALL_ON_PG_MASK,
+ MC_R1_AG_MASK,
+ USE_CHIPLET_ID,
+ APPLICABLE_TO_ALL,
+ NO_SPECIAL_RULE
+ ),
+ // MC Rule 2: Chiplet N1 must be checked for chip unit 1
+ new PartialGoodRule
+ (
+ {&PREDICATE_CUMULUS, &PREDICATE_AXONE},
+ MC_R2_PG_MASK,
+ ALL_OFF_AG_MASK,
+ N1_PG_INDEX,
+ ONE_BIT_CU_MASK,
+ NO_SPECIAL_RULE
+ ),
+ // MC Rule 3: Chiplet N3 must be checked for chip unit 0
+ new PartialGoodRule
+ (
+ {&PREDICATE_CUMULUS, &PREDICATE_AXONE},
+ MC_R3_PG_MASK,
+ ALL_OFF_AG_MASK,
+ N3_PG_INDEX,
+ ZERO_BIT_CU_MASK,
+ NO_SPECIAL_RULE
+ ),
+ }// End of PG Rules for MC Target
+ },
+ { TARGETING::TYPE_MCA,
+ {
+ // MCA Rule 1: For chip units 0-3
+ // However, since there is a special requirement
+ // that the first MCA (mca0 or mca4) must be
+ // functional it is applicable to all chip units
+ new PartialGoodRule
+ (
+ {&PREDICATE_NIMBUS},
+ MCA_R1_PG_MASK,
+ ALL_OFF_AG_MASK,
+ USE_CHIPLET_ID,
+ APPLICABLE_TO_ALL,
+ NO_SPECIAL_RULE
+ ),
+ // MCA Rule 2: For chip units 4-7
+ new PartialGoodRule
+ (
+ {&PREDICATE_NIMBUS},
+ MCA_R2_PG_MASK,
+ ALL_OFF_AG_MASK,
+ USE_CHIPLET_ID,
+ MCA_R2_CU_MASK,
+ NO_SPECIAL_RULE
+ ),
+ }// End of PG Rules for MCA Target
+ },
+ { TARGETING::TYPE_MCBIST,
+ {
+ // MCBIST Rule 1
+ new PartialGoodRule
+ (
+ {&PREDICATE_NIMBUS},
+ MCBIST_R1_PG_MASK,
+ MCBIST_R1_AG_MASK,
+ USE_CHIPLET_ID,
+ APPLICABLE_TO_ALL,
+ NO_SPECIAL_RULE
+ ),
+ }// End of PG Rules for MCBIST Target
+ },
+ { TARGETING::TYPE_MCC, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_MCS,
+ {
+ // MCS Rule 1: For chip units 0 and 1. Check MCS01
+ new PartialGoodRule
+ (
+ {&PREDICATE_NIMBUS},
+ MCS_R1_PG_MASK,
+ ALL_OFF_AG_MASK,
+ N3_PG_INDEX,
+ MCS_R1_CU_MASK,
+ NO_SPECIAL_RULE
+ ),
+ // MCS Rule 1: For chip units 2 and 3. Check MCS23
+ new PartialGoodRule
+ (
+ {&PREDICATE_NIMBUS},
+ MCS_R2_PG_MASK,
+ ALL_OFF_AG_MASK,
+ N1_PG_INDEX,
+ MCS_R2_CU_MASK,
+ NO_SPECIAL_RULE
+ ),
+ // MCS Rule 3: For chip units 0 and 1. Check bits in the
+ // MCxx entry including specific IOM bit, but
+ // not the other bits in the partial good
+ // region.
+ new PartialGoodRule
+ (
+ {&PREDICATE_NIMBUS},
+ MCS_R3_PG_MASK,
+ MCS_ALL_GOOD_MASK,
+ USE_CHIPLET_ID,
+ MCS_R1_CU_MASK,
+ NO_SPECIAL_RULE
+ ),
+ // MCS Rule 4: For chip units 2 and 3. Check bits in the
+ // MCxx entry including specific IOM bit, but
+ // not the other bits in the partial good
+ // region.
+ new PartialGoodRule
+ (
+ {&PREDICATE_NIMBUS},
+ MCS_R4_PG_MASK,
+ MCS_ALL_GOOD_MASK,
+ USE_CHIPLET_ID,
+ MCS_R2_CU_MASK,
+ NO_SPECIAL_RULE
+ ),
+ }// End of PG Rules for MCS Target
+ },
+ { TARGETING::TYPE_MI, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_NPU,
+ {
+ // NPU Rule 1: This logic is for Cumulus and Nimbus only.
+ new PartialGoodRule
+ (
+ {&PREDICATE_CUMULUS, &PREDICATE_NIMBUS},
+ NPU_R1_PG_MASK,
+ ALL_OFF_AG_MASK,
+ USE_CHIPLET_ID,
+ APPLICABLE_TO_ALL,
+ NO_SPECIAL_RULE
+ ),
+ }// End of PG Rules for NPU Target
+ },
+ { TARGETING::TYPE_OBUS,
+ {
+ // OBUS Rule 1
+ new PartialGoodRule
+ (
+ PREDICATE_P9,
+ ALL_ON_PG_MASK,
+ OBUS_R1_AG_MASK,
+ USE_CHIPLET_ID,
+ APPLICABLE_TO_ALL,
+ NO_SPECIAL_RULE
+ ),
+ // OBUS Rule 2: pbioo0 unit on chiplet N1 must be
+ // checked for all OBUSes
+ new PartialGoodRule
+ (
+ PREDICATE_P9,
+ OBUS_R2_PG_MASK,
+ ALL_OFF_AG_MASK,
+ N1_PG_INDEX,
+ APPLICABLE_TO_ALL,
+ NO_SPECIAL_RULE
+ ),
+ // OBUS Rule 3: pbioo1 unit on chiplet N3 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,
+ OBUS_R3_CU_MASK,
+ NO_SPECIAL_RULE
+ ),
+ }// End of PG Rules for OBUS Target
+ },
+ { TARGETING::TYPE_OBUS_BRICK,
+ {
+ // OBUS BRICK Rule 1: This applies only to Nimbus and
+ // Cumulus. OBUS BRICK is considered
+ // non-functional if the NPU is
+ // non-functional and if OBUS is
+ // in non-SMP mode.
+ // The Obus Brick also requires a
+ // functional parent Obus to be
+ // considered functional. However,
+ // HWAS::markChildrenNonFunctional() will
+ // take care of that requirement instead
+ // of that rule being explictly defined
+ // here.
+ new PartialGoodRule
+ (
+ {&PREDICATE_CUMULUS, &PREDICATE_NIMBUS},
+ MASK_NA,
+ MASK_NA,
+ INDEX_NA,
+ APPLICABLE_TO_ALL,
+ ObusBrickSpecialRule
+ ),
+ }// End of PG Rules for OBUS BRICK Target
+ },
+ { TARGETING::TYPE_OMI, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_OMIC, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_PEC,
+ {
+ // PEC Rule 1: Applies to chip unit 0. Check PCI0
+ new PartialGoodRule
+ (
+ PREDICATE_P9,
+ ALL_ON_PG_MASK,
+ PEC_R1_AG_MASK,
+ USE_CHIPLET_ID,
+ ZERO_BIT_CU_MASK,
+ NO_SPECIAL_RULE
+ ),
+ // PEC Rule 2: Applies to chip unit 1. Check PCI1
+ new PartialGoodRule
+ (
+ PREDICATE_P9,
+ ALL_ON_PG_MASK,
+ PEC_R2_AG_MASK,
+ USE_CHIPLET_ID,
+ ONE_BIT_CU_MASK,
+ NO_SPECIAL_RULE
+ ),
+ // PEC Rule 3: Applies to chip unit 2. Check PCI2
+ new PartialGoodRule
+ (
+ PREDICATE_P9,
+ ALL_ON_PG_MASK,
+ PEC_R3_AG_MASK,
+ USE_CHIPLET_ID,
+ TWO_BIT_CU_MASK,
+ NO_SPECIAL_RULE
+ ),
+ }
+ },
+ { TARGETING::TYPE_PERV,
+ {
+ // PERV Rule 1: Check Vital bit
+ new PartialGoodRule
+ (
+ PREDICATE_P9,
+ PERV_R1_PG_MASK,
+ ALL_OFF_AG_MASK,
+ USE_CHIPLET_ID,
+ APPLICABLE_TO_ALL,
+ PervSpecialRule
+ ),
+ }// End of PG Rules for PERV Target
+ },
+ { TARGETING::TYPE_PHB, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_XBUS,
+ {
+ // XBUS Rule 1: Applies to chip unit 0 which is not
+ // present on Nimbus.
+ new PartialGoodRule
+ (
+ {&PREDICATE_CUMULUS},
+ XBUS_R1_PG_MASK,
+ ALL_OFF_AG_MASK,
+ USE_CHIPLET_ID,
+ ZERO_BIT_CU_MASK,
+ NO_SPECIAL_RULE
+ ),
+ // XBUS Rule 2: Applies to chip unit 1
+ new PartialGoodRule
+ (
+ PREDICATE_P9,
+ XBUS_R2_PG_MASK,
+ ALL_OFF_AG_MASK,
+ USE_CHIPLET_ID,
+ ONE_BIT_CU_MASK,
+ NO_SPECIAL_RULE
+ ),
+ // XBUS Rule 3: Applies to chip unit 2
+ new PartialGoodRule
+ (
+ PREDICATE_P9,
+ XBUS_R3_PG_MASK,
+ ALL_OFF_AG_MASK,
+ USE_CHIPLET_ID,
+ TWO_BIT_CU_MASK,
+ NO_SPECIAL_RULE
+ ),
+ }// End of PG Rules for XBUS Target
+ },
+ { TARGETING::TYPE_NA, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_SYS, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_NODE, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_DIMM, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_MEMBUF, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_PROC, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_L2, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_L3, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_L4, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_MBA, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_ABUS, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_PCI, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_DPSS, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_APSS, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_OCC, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_PSI, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_FSP, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_PNOR, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_OSC, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_TODCLK, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_CONTROL_NODE, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_OSCREFCLK, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_OSCPCICLK, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_REFCLKENDPT, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_PCICLKENDPT, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_NX, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_PORE, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_PCIESWITCH, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_CAPP, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_FSI, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_SBE, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_PPE, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_SYSREFCLKENDPT, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_MFREFCLKENDPT, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_TPM, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_SP, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_UART, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_PS, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_FAN, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_VRM, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_USB, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_ETH, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_PANEL, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_BMC, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_FLASH, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_SEEPROM, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_TMP, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_GPIO_EXPANDER, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_POWER_SEQUENCER, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_RTC, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_FANCTLR, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_TEST_FAIL, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_MFREFCLK, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_SMPGROUP, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_OCMB_CHIP, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_MEM_PORT, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_I2C_MUX, {new PartialGoodRule(),}},
+ { TARGETING::TYPE_LAST_IN_RANGE, {new PartialGoodRule(),}},
+ // End of pgRules_map Rules
+ };
+ };
+
+ // Due to the size of the PartialGoodRulesTable a static version is declared
+ // to reduce overhead associated with creating one.
+ extern const PartialGoodRulesTable pgTable;
+
+}
+
+#endif
OpenPOWER on IntegriCloud